| 382 | using unsigned_type = typename std::make_unsigned<value_type>::type; |
| 383 | |
| 384 | bool Convert(const ARROW_TYPE&, const char* s, size_t length, value_type* out) { |
| 385 | static constexpr auto max_positive = |
| 386 | static_cast<unsigned_type>(std::numeric_limits<value_type>::max()); |
| 387 | // Assuming two's complement |
| 388 | static constexpr unsigned_type max_negative = max_positive + 1; |
| 389 | bool negative = false; |
| 390 | unsigned_type unsigned_value = 0; |
| 391 | |
| 392 | if (ARROW_PREDICT_FALSE(length == 0)) { |
| 393 | return false; |
| 394 | } |
| 395 | // If it starts with 0x then its hex |
| 396 | if (length > 2 && s[0] == '0' && ((s[1] == 'x') || (s[1] == 'X'))) { |
| 397 | length -= 2; |
| 398 | s += 2; |
| 399 | |
| 400 | if (!ARROW_PREDICT_TRUE(ParseHex(s, length, &unsigned_value))) { |
| 401 | return false; |
| 402 | } |
| 403 | *out = static_cast<value_type>(unsigned_value); |
| 404 | return true; |
| 405 | } |
| 406 | |
| 407 | if (*s == '-') { |
| 408 | negative = true; |
| 409 | s++; |
| 410 | if (--length == 0) { |
| 411 | return false; |
| 412 | } |
| 413 | } |
| 414 | // Skip leading zeros |
| 415 | while (length > 0 && *s == '0') { |
| 416 | length--; |
| 417 | s++; |
| 418 | } |
| 419 | if (!ARROW_PREDICT_TRUE(ParseUnsigned(s, length, &unsigned_value))) { |
| 420 | return false; |
| 421 | } |
| 422 | if (negative) { |
| 423 | if (ARROW_PREDICT_FALSE(unsigned_value > max_negative)) { |
| 424 | return false; |
| 425 | } |
| 426 | // To avoid both compiler warnings (with unsigned negation) |
| 427 | // and undefined behaviour (with signed negation overflow), |
| 428 | // use the expanded formula for 2's complement negation. |
| 429 | *out = static_cast<value_type>(~unsigned_value + 1); |
| 430 | } else { |
| 431 | if (ARROW_PREDICT_FALSE(unsigned_value > max_positive)) { |
| 432 | return false; |
| 433 | } |
| 434 | *out = static_cast<value_type>(unsigned_value); |
| 435 | } |
| 436 | return true; |
| 437 | } |
| 438 | }; |
| 439 | |
| 440 | template <> |
nothing calls this directly
no test coverage detected