| 554 | } |
| 555 | |
| 556 | static inline bool ParseSubSeconds(const char* s, size_t length, TimeUnit::type unit, |
| 557 | uint32_t* out) { |
| 558 | // The decimal point has been peeled off at this point |
| 559 | |
| 560 | // Fail if number of decimal places provided exceeds what the unit can hold. |
| 561 | // Calculate how many trailing decimal places are omitted for the unit |
| 562 | // e.g. if 4 decimal places are provided and unit is MICRO, 2 are missing |
| 563 | size_t omitted = 0; |
| 564 | switch (unit) { |
| 565 | case TimeUnit::MILLI: |
| 566 | if (ARROW_PREDICT_FALSE(length > 3)) { |
| 567 | return false; |
| 568 | } |
| 569 | if (length < 3) { |
| 570 | omitted = 3 - length; |
| 571 | } |
| 572 | break; |
| 573 | case TimeUnit::MICRO: |
| 574 | if (ARROW_PREDICT_FALSE(length > 6)) { |
| 575 | return false; |
| 576 | } |
| 577 | if (length < 6) { |
| 578 | omitted = 6 - length; |
| 579 | } |
| 580 | break; |
| 581 | case TimeUnit::NANO: |
| 582 | if (ARROW_PREDICT_FALSE(length > 9)) { |
| 583 | return false; |
| 584 | } |
| 585 | if (length < 9) { |
| 586 | omitted = 9 - length; |
| 587 | } |
| 588 | break; |
| 589 | default: |
| 590 | return false; |
| 591 | } |
| 592 | |
| 593 | if (ARROW_PREDICT_TRUE(omitted == 0)) { |
| 594 | return ParseUnsigned(s, length, out); |
| 595 | } else { |
| 596 | uint32_t subseconds = 0; |
| 597 | bool success = ParseUnsigned(s, length, &subseconds); |
| 598 | if (ARROW_PREDICT_TRUE(success)) { |
| 599 | switch (omitted) { |
| 600 | case 1: |
| 601 | *out = subseconds * 10; |
| 602 | break; |
| 603 | case 2: |
| 604 | *out = subseconds * 100; |
| 605 | break; |
| 606 | case 3: |
| 607 | *out = subseconds * 1000; |
| 608 | break; |
| 609 | case 4: |
| 610 | *out = subseconds * 10000; |
| 611 | break; |
| 612 | case 5: |
| 613 | *out = subseconds * 100000; |
no test coverage detected