From c0d8921a6797497f3fbd2a8c2a2b29aaca9704c3 Mon Sep 17 00:00:00 2001 From: Julian Becker Date: Sat, 15 Sep 2018 12:00:53 +0200 Subject: [PATCH] BSON: support objects with int64 members --- .../nlohmann/detail/input/binary_reader.hpp | 10 ++++++ .../nlohmann/detail/output/binary_writer.hpp | 26 ++++++++++---- single_include/nlohmann/json.hpp | 36 +++++++++++++++---- test/src/unit-bson.cpp | 23 ++++++++++++ 4 files changed, 83 insertions(+), 12 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index f11e164e..d135a4c2 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -213,6 +213,16 @@ class binary_reader sax->number_integer(static_cast(value)); } break; + case 0x12: // int64 + { + string_t key; + get_bson_cstr(key); + sax->key(key); + std::int64_t value; + get_number_little_endian(value); + sax->number_integer(static_cast(value)); + } + break; case 0x0A: // null { string_t key; diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index ed59b7c2..24426d48 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -723,14 +723,28 @@ class binary_writer std::size_t write_bson_integer(const typename BasicJsonType::string_t& name, const BasicJsonType& j) { - oa->write_character(static_cast(0x10)); // int32 - oa->write_characters( - reinterpret_cast(name.c_str()), - name.size() + 1u); + if (j.m_value.number_integer <= static_cast((std::numeric_limits::max)())) + { + oa->write_character(static_cast(0x10)); // int32 + oa->write_characters( + reinterpret_cast(name.c_str()), + name.size() + 1u); - write_number_little_endian(static_cast(j.m_value.number_integer)); + write_number_little_endian(static_cast(j.m_value.number_integer)); - return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int32_t); + return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int32_t); + } + else + { + oa->write_character(static_cast(0x12)); // int64 + oa->write_characters( + reinterpret_cast(name.c_str()), + name.size() + 1u); + + write_number_little_endian(static_cast(j.m_value.number_integer)); + + return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int64_t); + } } std::size_t write_bson_object_entry(const typename BasicJsonType::string_t& name, const BasicJsonType& j) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index d0cce8a1..c564e57f 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6197,6 +6197,16 @@ class binary_reader sax->number_integer(static_cast(value)); } break; + case 0x12: // int64 + { + string_t key; + get_bson_cstr(key); + sax->key(key); + std::int64_t value; + get_number_little_endian(value); + sax->number_integer(static_cast(value)); + } + break; case 0x0A: // null { string_t key; @@ -8547,14 +8557,28 @@ class binary_writer std::size_t write_bson_integer(const typename BasicJsonType::string_t& name, const BasicJsonType& j) { - oa->write_character(static_cast(0x10)); // int32 - oa->write_characters( - reinterpret_cast(name.c_str()), - name.size() + 1u); + if (j.m_value.number_integer <= static_cast((std::numeric_limits::max)())) + { + oa->write_character(static_cast(0x10)); // int32 + oa->write_characters( + reinterpret_cast(name.c_str()), + name.size() + 1u); - write_number_little_endian(static_cast(j.m_value.number_integer)); + write_number_little_endian(static_cast(j.m_value.number_integer)); - return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int32_t); + return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int32_t); + } + else + { + oa->write_character(static_cast(0x12)); // int64 + oa->write_characters( + reinterpret_cast(name.c_str()), + name.size() + 1u); + + write_number_little_endian(static_cast(j.m_value.number_integer)); + + return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int64_t); + } } std::size_t write_bson_object_entry(const typename BasicJsonType::string_t& name, const BasicJsonType& j) diff --git a/test/src/unit-bson.cpp b/test/src/unit-bson.cpp index 266dd12a..73989769 100644 --- a/test/src/unit-bson.cpp +++ b/test/src/unit-bson.cpp @@ -255,6 +255,29 @@ TEST_CASE("BSON") CHECK(json::from_bson(result, true, false) == j); } + SECTION("non-empty object with integer (64-bit) member") + { + json j = + { + { "entry", std::int64_t{0x1234567804030201} } + }; + + std::vector expected = + { + 0x14, 0x00, 0x00, 0x00, // size (little endian) + 0x12, /// entry: int64 + 'e', 'n', 't', 'r', 'y', '\x00', + 0x01, 0x02, 0x03, 0x04, 0x78, 0x56, 0x34, 0x12, + 0x00 // end marker + }; + + const auto result = json::to_bson(j); + CHECK(result == expected); + + // roundtrip + CHECK(json::from_bson(result) == j); + CHECK(json::from_bson(result, true, false) == j); + } } }