From 7ee361f7ad3806258e3c9a7ea2fc8dce5fdb54bc Mon Sep 17 00:00:00 2001 From: Julian Becker Date: Sat, 15 Sep 2018 11:54:17 +0200 Subject: [PATCH] BSON: support objects with int32 members --- .../nlohmann/detail/input/binary_reader.hpp | 10 ++++++++ .../nlohmann/detail/output/binary_writer.hpp | 14 +++++++++++ single_include/nlohmann/json.hpp | 24 +++++++++++++++++++ test/src/unit-bson.cpp | 24 +++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 3fd6cc20..f11e164e 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -203,6 +203,16 @@ class binary_reader sax->boolean(static_cast(get())); } break; + case 0x10: // int32 + { + string_t key; + get_bson_cstr(key); + sax->key(key); + std::int32_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 966d8c22..ed59b7c2 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -721,6 +721,18 @@ class binary_writer return /*id*/ 1ul + name.size() + 1ul; } + 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); + + write_number_little_endian(static_cast(j.m_value.number_integer)); + + return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int32_t); + } + std::size_t write_bson_object_entry(const typename BasicJsonType::string_t& name, const BasicJsonType& j) { switch (j.type()) @@ -732,6 +744,8 @@ class binary_writer return write_bson_boolean(name, j); case value_t::number_float: return write_bson_double(name, j); + case value_t::number_integer: + return write_bson_integer(name, j); case value_t::string: return write_bson_string(name, j); case value_t::null: diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index faeaf214..d0cce8a1 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6187,6 +6187,16 @@ class binary_reader sax->boolean(static_cast(get())); } break; + case 0x10: // int32 + { + string_t key; + get_bson_cstr(key); + sax->key(key); + std::int32_t value; + get_number_little_endian(value); + sax->number_integer(static_cast(value)); + } + break; case 0x0A: // null { string_t key; @@ -8535,6 +8545,18 @@ class binary_writer return /*id*/ 1ul + name.size() + 1ul; } + 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); + + write_number_little_endian(static_cast(j.m_value.number_integer)); + + return /*id*/ 1ul + name.size() + 1ul + sizeof(std::int32_t); + } + std::size_t write_bson_object_entry(const typename BasicJsonType::string_t& name, const BasicJsonType& j) { switch (j.type()) @@ -8546,6 +8568,8 @@ class binary_writer return write_bson_boolean(name, j); case value_t::number_float: return write_bson_double(name, j); + case value_t::number_integer: + return write_bson_integer(name, j); case value_t::string: return write_bson_string(name, j); case value_t::null: diff --git a/test/src/unit-bson.cpp b/test/src/unit-bson.cpp index e83e112a..266dd12a 100644 --- a/test/src/unit-bson.cpp +++ b/test/src/unit-bson.cpp @@ -231,6 +231,30 @@ TEST_CASE("BSON") CHECK(json::from_bson(result, true, false) == j); } + SECTION("non-empty object with integer (32-bit) member") + { + json j = + { + { "entry", std::int32_t{0x12345678} } + }; + + std::vector expected = + { + 0x10, 0x00, 0x00, 0x00, // size (little endian) + 0x10, /// entry: int32 + 'e', 'n', 't', 'r', 'y', '\x00', + 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); + } + } }