| 13622 | JSON_HEDLEY_NON_NULL(1) |
| 13623 | JSON_HEDLEY_RETURNS_NON_NULL |
| 13624 | inline char* format_buffer(char* buf, int len, int decimal_exponent, |
| 13625 | int min_exp, int max_exp) |
| 13626 | { |
| 13627 | assert(min_exp < 0); |
| 13628 | assert(max_exp > 0); |
| 13629 | |
| 13630 | const int k = len; |
| 13631 | const int n = len + decimal_exponent; |
| 13632 | |
| 13633 | // v = buf * 10^(n-k) |
| 13634 | // k is the length of the buffer (number of decimal digits) |
| 13635 | // n is the position of the decimal point relative to the start of the buffer. |
| 13636 | |
| 13637 | if (k <= n and n <= max_exp) |
| 13638 | { |
| 13639 | // digits[000] |
| 13640 | // len <= max_exp + 2 |
| 13641 | |
| 13642 | std::memset(buf + k, '0', static_cast<size_t>(n - k)); |
| 13643 | // Make it look like a floating-point number (#362, #378) |
| 13644 | buf[n + 0] = '.'; |
| 13645 | buf[n + 1] = '0'; |
| 13646 | return buf + (n + 2); |
| 13647 | } |
| 13648 | |
| 13649 | if (0 < n and n <= max_exp) |
| 13650 | { |
| 13651 | // dig.its |
| 13652 | // len <= max_digits10 + 1 |
| 13653 | |
| 13654 | assert(k > n); |
| 13655 | |
| 13656 | std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n)); |
| 13657 | buf[n] = '.'; |
| 13658 | return buf + (k + 1); |
| 13659 | } |
| 13660 | |
| 13661 | if (min_exp < n and n <= 0) |
| 13662 | { |
| 13663 | // 0.[000]digits |
| 13664 | // len <= 2 + (-min_exp - 1) + max_digits10 |
| 13665 | |
| 13666 | std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k)); |
| 13667 | buf[0] = '0'; |
| 13668 | buf[1] = '.'; |
| 13669 | std::memset(buf + 2, '0', static_cast<size_t>(-n)); |
| 13670 | return buf + (2 + (-n) + k); |
| 13671 | } |
| 13672 | |
| 13673 | if (k == 1) |
| 13674 | { |
| 13675 | // dE+123 |
| 13676 | // len <= 1 + 5 |
| 13677 | |
| 13678 | buf += 1; |
| 13679 | } |
| 13680 | else |
| 13681 | { |
no test coverage detected