| 396 | } |
| 397 | |
| 398 | bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) |
| 399 | { |
| 400 | int64_t mantissa = 0; |
| 401 | int64_t exponent = 0; |
| 402 | int mantissa_tzeros = 0; |
| 403 | bool mantissa_sign = false; |
| 404 | bool exponent_sign = false; |
| 405 | int ptr = 0; |
| 406 | int end = val.size(); |
| 407 | int point_ofs = 0; |
| 408 | |
| 409 | if (ptr < end && val[ptr] == '-') { |
| 410 | mantissa_sign = true; |
| 411 | ++ptr; |
| 412 | } |
| 413 | if (ptr < end) |
| 414 | { |
| 415 | if (val[ptr] == '0') { |
| 416 | /* pass single 0 */ |
| 417 | ++ptr; |
| 418 | } else if (val[ptr] >= '1' && val[ptr] <= '9') { |
| 419 | while (ptr < end && IsDigit(val[ptr])) { |
| 420 | if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) |
| 421 | return false; /* overflow */ |
| 422 | ++ptr; |
| 423 | } |
| 424 | } else return false; /* missing expected digit */ |
| 425 | } else return false; /* empty string or loose '-' */ |
| 426 | if (ptr < end && val[ptr] == '.') |
| 427 | { |
| 428 | ++ptr; |
| 429 | if (ptr < end && IsDigit(val[ptr])) |
| 430 | { |
| 431 | while (ptr < end && IsDigit(val[ptr])) { |
| 432 | if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros)) |
| 433 | return false; /* overflow */ |
| 434 | ++ptr; |
| 435 | ++point_ofs; |
| 436 | } |
| 437 | } else return false; /* missing expected digit */ |
| 438 | } |
| 439 | if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E')) |
| 440 | { |
| 441 | ++ptr; |
| 442 | if (ptr < end && val[ptr] == '+') |
| 443 | ++ptr; |
| 444 | else if (ptr < end && val[ptr] == '-') { |
| 445 | exponent_sign = true; |
| 446 | ++ptr; |
| 447 | } |
| 448 | if (ptr < end && IsDigit(val[ptr])) { |
| 449 | while (ptr < end && IsDigit(val[ptr])) { |
| 450 | if (exponent > (UPPER_BOUND / 10LL)) |
| 451 | return false; /* overflow */ |
| 452 | exponent = exponent * 10 + val[ptr] - '0'; |
| 453 | ++ptr; |
| 454 | } |
| 455 | } else return false; /* missing expected digit */ |