| 657 | } |
| 658 | |
| 659 | bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) |
| 660 | { |
| 661 | int64_t mantissa = 0; |
| 662 | int64_t exponent = 0; |
| 663 | int mantissa_tzeros = 0; |
| 664 | bool mantissa_sign = false; |
| 665 | bool exponent_sign = false; |
| 666 | int ptr = 0; |
| 667 | int end = val.size(); |
| 668 | int point_ofs = 0; |
| 669 | |
| 670 | if (ptr < end && val[ptr] == '-') { |
| 671 | mantissa_sign = true; |
| 672 | ++ptr; |
| 673 | } |
| 674 | if (ptr < end) |
| 675 | { |
| 676 | if (val[ptr] == '0') { |
| 677 | /* pass single 0 */ |
| 678 | ++ptr; |
| 679 | } else if (val[ptr] >= '1' && val[ptr] <= '9') { |
| 680 | while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { |
| 681 | if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) |
| 682 | return false; /* overflow */ |
| 683 | ++ptr; |
| 684 | } |
| 685 | } else return false; /* missing expected digit */ |
| 686 | } else return false; /* empty string or loose '-' */ |
| 687 | if (ptr < end && val[ptr] == '.') |
| 688 | { |
| 689 | ++ptr; |
| 690 | if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') |
| 691 | { |
| 692 | while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { |
| 693 | if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) |
| 694 | return false; /* overflow */ |
| 695 | ++ptr; |
| 696 | ++point_ofs; |
| 697 | } |
| 698 | } else return false; /* missing expected digit */ |
| 699 | } |
| 700 | if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E')) |
| 701 | { |
| 702 | ++ptr; |
| 703 | if (ptr < end && val[ptr] == '+') |
| 704 | ++ptr; |
| 705 | else if (ptr < end && val[ptr] == '-') { |
| 706 | exponent_sign = true; |
| 707 | ++ptr; |
| 708 | } |
| 709 | if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { |
| 710 | while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') { |
| 711 | if (exponent > (UPPER_BOUND / 10LL)) |
| 712 | return false; /* overflow */ |
| 713 | exponent = exponent * 10 + val[ptr] - '0'; |
| 714 | ++ptr; |
| 715 | } |
| 716 | } else return false; /* missing expected digit */ |
no test coverage detected