From 4f1e2df4099e65618af54f7608bedb1731a1f1de Mon Sep 17 00:00:00 2001 From: Yixin Dong Date: Sat, 25 May 2024 17:53:10 -0700 Subject: [PATCH] [picojson] Let objects be ordered when serializing (#17027) This PR changes the serialization logic of objects to follow the insertion order of elements to keep the output consistent across different platforms. --- 3rdparty/picojson/picojson.h | 19 +++++++++++++++++++ 3rdparty/picojson/test_picojson.cpp | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/3rdparty/picojson/picojson.h b/3rdparty/picojson/picojson.h index 542b527ca7d9..5ecffa9a8f30 100644 --- a/3rdparty/picojson/picojson.h +++ b/3rdparty/picojson/picojson.h @@ -727,6 +727,24 @@ void value::_serialize(Iter oi, int indent) const { if (indent != -1) { ++indent; } + +#if PICOJSON_USE_ORDERED_OBJECT + for (auto i = u_.object_->ordered_keys().begin(); i != u_.object_->ordered_keys().end(); + ++i) { + if (i != u_.object_->ordered_keys().begin()) { + *oi++ = ','; + } + if (indent != -1) { + _indent(oi, indent); + } + serialize_str(*i, oi); + *oi++ = ':'; + if (indent != -1) { + *oi++ = ' '; + } + u_.object_->at(*i)._serialize(oi, indent); + } +#else for (object::const_iterator i = u_.object_->begin(); i != u_.object_->end(); ++i) { if (i != u_.object_->begin()) { *oi++ = ','; @@ -741,6 +759,7 @@ void value::_serialize(Iter oi, int indent) const { } i->second._serialize(oi, indent); } +#endif if (indent != -1) { --indent; if (!u_.object_->empty()) { diff --git a/3rdparty/picojson/test_picojson.cpp b/3rdparty/picojson/test_picojson.cpp index b648702b4bbb..0984aee20f37 100644 --- a/3rdparty/picojson/test_picojson.cpp +++ b/3rdparty/picojson/test_picojson.cpp @@ -58,8 +58,21 @@ void test_modifier() { assert((obj.ordered_keys() == std::vector{})); } +void test_serializer() { + picojson::object obj; + + obj["bar"] = picojson::value(static_cast(10)); + obj["baz"] = picojson::value(10.5); + obj["foo"] = picojson::value(true); + + picojson::value v(obj); + + assert((v.serialize(false) == "{\"bar\":10,\"baz\":10.5,\"foo\":true}")); +} + int main() { test_constructor(); test_modifier(); + test_serializer(); return 0; }