From 9b80ee0046591416366a1d0144ada70033396040 Mon Sep 17 00:00:00 2001 From: Nikolay Osintsev Date: Fri, 3 May 2024 03:18:24 +0300 Subject: [PATCH] json: implement JOSN_PRESERVE_ZERO_FRACTION in json_encode() --- runtime/json-functions.cpp | 17 +++++++++++++++-- runtime/json-functions.h | 6 +++--- runtime/json-writer.h | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/runtime/json-functions.cpp b/runtime/json-functions.cpp index 79c958ca04..ec3446a360 100644 --- a/runtime/json-functions.cpp +++ b/runtime/json-functions.cpp @@ -275,12 +275,25 @@ bool JsonEncoder::encode(double d) noexcept { if (vk::any_of_equal(std::fpclassify(d), FP_INFINITE, FP_NAN)) { php_warning("%s: strange double %lf in function json_encode", json_path_.to_string().c_str(), d); if (options_ & JSON_PARTIAL_OUTPUT_ON_ERROR) { - static_SB.append("0", 1); + if (options_ & JSON_PRESERVE_ZERO_FRACTION) { + static_SB.append("0.0", 3); + } else { + static_SB.append("0", 1); + } } else { return false; } } else { - static_SB << (simple_encode_ ? f$number_format(d, 6, string{"."}, string{}) : string{d}); + if (simple_encode_) { + static_SB << f$number_format(d, 6, string{"."}, string{}); + } else { + static_SB << string{d}; + if (options_ & JSON_PRESERVE_ZERO_FRACTION) { + if (double dummy = 0.0; std::modf(d, &dummy) == 0.0) { + static_SB.append(".0", 2); + } + } + } } return true; } diff --git a/runtime/json-functions.h b/runtime/json-functions.h index 8754d73dd5..4a6c7eb77d 100644 --- a/runtime/json-functions.h +++ b/runtime/json-functions.h @@ -11,12 +11,12 @@ constexpr int64_t JSON_UNESCAPED_UNICODE = 1; constexpr int64_t JSON_FORCE_OBJECT = 16; -constexpr int64_t JSON_PRETTY_PRINT = 128; // TODO: add actual support to untyped +constexpr int64_t JSON_PRETTY_PRINT = 128; constexpr int64_t JSON_PARTIAL_OUTPUT_ON_ERROR = 512; constexpr int64_t JSON_PRESERVE_ZERO_FRACTION = 1024; -constexpr int64_t JSON_AVAILABLE_OPTIONS = JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PARTIAL_OUTPUT_ON_ERROR; -constexpr int64_t JSON_AVAILABLE_FLAGS_TYPED = JSON_PRETTY_PRINT | JSON_PRESERVE_ZERO_FRACTION; +constexpr int64_t JSON_AVAILABLE_OPTIONS = JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION; +constexpr int64_t JSON_AVAILABLE_FLAGS_TYPED = JSON_PRETTY_PRINT; struct JsonPath { constexpr static int MAX_DEPTH = 8; diff --git a/runtime/json-writer.h b/runtime/json-writer.h index 76bfd8601b..a22eb99d60 100644 --- a/runtime/json-writer.h +++ b/runtime/json-writer.h @@ -52,7 +52,7 @@ class JsonWriter : vk::not_copyable { array stack_; string error_; - std::size_t double_precision_{0}; + std::size_t double_precision_{0}; // unused const bool pretty_print_{false}; const bool preserve_zero_fraction_{false}; bool has_root_{false};