From 4de8d715e6241a379ce51cb55e5d5264c5616b9c Mon Sep 17 00:00:00 2001 From: Maya Warrier Date: Wed, 13 Sep 2023 21:07:40 -0400 Subject: [PATCH] Add json fmt test --- include/fast_float/ascii_number.h | 21 +++++++++-------- tests/CMakeLists.txt | 2 ++ tests/json_fmt.cpp | 38 +++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 tests/json_fmt.cpp diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index 417b88b..f9680ec 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -312,9 +312,11 @@ parsed_number_string_t parse_number_string(UC const *p, UC const * pend, par UC const * const end_of_integer_part = p; int64_t digit_count = int64_t(end_of_integer_part - start_digits); answer.integer = span(start_digits, size_t(digit_count)); - // disallow leading zeros - if (fmt == chars_format::json && start_digits[0] == UC('0') && digit_count > 1) { - return answer; + if (fmt == chars_format::json) { + // at least 1 digit in integer part, without leading zeros + if (digit_count == 0 || (start_digits[0] == UC('0') && digit_count > 1)) { + return answer; + } } int64_t exponent = 0; @@ -335,12 +337,13 @@ parsed_number_string_t parse_number_string(UC const *p, UC const * pend, par answer.fraction = span(before, size_t(p - before)); digit_count -= exponent; } - // we must have encountered at least one integer! - if (digit_count == 0) { - return answer; - } - // or at least two if a decimal point exists, with json rules - else if (fmt == chars_format::json && has_decimal_point && digit_count == 1) { + if (fmt == chars_format::json) { + // at least 1 digit in fractional part + if (has_decimal_point && exponent == 0) { + return answer; + } + } + else if (digit_count == 0) { // we must have encountered at least one integer! return answer; } int64_t exp_number = 0; // explicit exponential part diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 37f6c7f..e58bea8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -72,6 +72,8 @@ fast_float_add_cpp_test(long_test) fast_float_add_cpp_test(powersoffive_hardround) fast_float_add_cpp_test(string_test) +fast_float_add_cpp_test(json_fmt) + option(FASTFLOAT_EXHAUSTIVE "Exhaustive tests" OFF) diff --git a/tests/json_fmt.cpp b/tests/json_fmt.cpp new file mode 100644 index 0000000..0c1c365 --- /dev/null +++ b/tests/json_fmt.cpp @@ -0,0 +1,38 @@ + +#include +#include +#include + +#include "fast_float/fast_float.h" + +int main() +{ + const std::vector expected{ -0.2, 0.02, 0.002, 1., 0. }; + const std::vector accept{ "-0.2", "0.02", "0.002", "1e+0000", "0e-2" }; + const std::vector reject{ "-.2", "00.02", "0.e+1", "00.e+1", ".25"}; + const auto fmt = fast_float::chars_format::json; + + for (std::size_t i = 0; i < accept.size(); ++i) + { + const auto& f = accept[i]; + double result; + auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result, fmt); + if (answer.ec != std::errc() || result != expected[i]) { + std::cerr << "json fmt rejected valid json " << f << std::endl; + return EXIT_FAILURE; + } + } + + for (std::size_t i = 0; i < reject.size(); ++i) + { + const auto& f = reject[i]; + double result; + auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result, fmt); + if (answer.ec == std::errc()) { + std::cerr << "json fmt accepted invalid json " << f << std::endl; + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} \ No newline at end of file