| 454 | } |
| 455 | |
| 456 | bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) |
| 457 | { |
| 458 | int64_t mantissa = 0; |
| 459 | int64_t exponent = 0; |
| 460 | int mantissa_tzeros = 0; |
| 461 | bool mantissa_sign = false; |
| 462 | bool exponent_sign = false; |
| 463 | int ptr = 0; |
| 464 | int end = val.size(); |
| 465 | int point_ofs = 0; |
| 466 | |
| 467 | if (ptr < end && val[ptr] == '-') { |
| 468 | mantissa_sign = true; |
| 469 | ++ptr; |
| 470 | } |
| 471 | if (ptr < end) |
| 472 | { |
| 473 | if (val[ptr] == '0') { |
| 474 | /* pass single 0 */ |
| 475 | ++ptr; |
| 476 | } else if (val[ptr] >= '1' && val[ptr] <= '9') { |
| 477 | while (ptr < end && IsDigit(val[ptr])) { |
| 478 | if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) |
| 479 | return false; /* overflow */ |
| 480 | ++ptr; |
| 481 | } |
| 482 | } else return false; /* missing expected digit */ |
| 483 | } else return false; /* empty string or loose '-' */ |
| 484 | if (ptr < end && val[ptr] == '.') |
| 485 | { |
| 486 | ++ptr; |
| 487 | if (ptr < end && IsDigit(val[ptr])) |
| 488 | { |
| 489 | while (ptr < end && IsDigit(val[ptr])) { |
| 490 | if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) |
| 491 | return false; /* overflow */ |
| 492 | ++ptr; |
| 493 | ++point_ofs; |
| 494 | } |
| 495 | } else return false; /* missing expected digit */ |
| 496 | } |
| 497 | if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E')) |
| 498 | { |
| 499 | ++ptr; |
| 500 | if (ptr < end && val[ptr] == '+') |
| 501 | ++ptr; |
| 502 | else if (ptr < end && val[ptr] == '-') { |
| 503 | exponent_sign = true; |
| 504 | ++ptr; |
| 505 | } |
| 506 | if (ptr < end && IsDigit(val[ptr])) { |
| 507 | while (ptr < end && IsDigit(val[ptr])) { |
| 508 | if (exponent > (UPPER_BOUND / 10LL)) |
| 509 | return false; /* overflow */ |
| 510 | exponent = exponent * 10 + val[ptr] - '0'; |
| 511 | ++ptr; |
| 512 | } |
| 513 | } else return false; /* missing expected digit */ |