🔨 added fix for arrays

parent 1968e5c7
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
- [JSON Merge Patch](#json-merge-patch) - [JSON Merge Patch](#json-merge-patch)
- [Implicit conversions](#implicit-conversions) - [Implicit conversions](#implicit-conversions)
- [Conversions to/from arbitrary types](#arbitrary-types-conversions) - [Conversions to/from arbitrary types](#arbitrary-types-conversions)
- [Binary formats (CBOR, MessagePack, and UBJSON)](#binary-formats-cbor-messagepack-and-ubjson) - [Binary formats (CBOR, BSON, MessagePack, and UBJSON)](#binary-formats-bson-cbor-messagepack-and-ubjson)
- [Supported compilers](#supported-compilers) - [Supported compilers](#supported-compilers)
- [License](#license) - [License](#license)
- [Contact](#contact) - [Contact](#contact)
...@@ -874,14 +874,22 @@ struct bad_serializer ...@@ -874,14 +874,22 @@ struct bad_serializer
}; };
``` ```
### Binary formats (CBOR, MessagePack, and UBJSON) ### Binary formats (CBOR, BSON, MessagePack, and UBJSON
Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors. Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance over a network. Hence, the library supports [BSON](http://bsonspec.org) (Binary JSON), [CBOR](http://cbor.io) (Concise Binary Object Representation), [MessagePack](http://msgpack.org), and [UBJSON](http://ubjson.org) (Universal Binary JSON Specification) to efficiently encode JSON values to byte vectors and to decode such vectors.
```cpp ```cpp
// create a JSON value // create a JSON value
json j = R"({"compact": true, "schema": 0})"_json; json j = R"({"compact": true, "schema": 0})"_json;
// serialize to BSON
std::vector<std::uint8_t> v_bson = json::to_bson(j);
// 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// roundtrip
json j_from_bson = json::from_bson(v_bson);
// serialize to CBOR // serialize to CBOR
std::vector<std::uint8_t> v_cbor = json::to_cbor(j); std::vector<std::uint8_t> v_cbor = json::to_cbor(j);
...@@ -1138,6 +1146,8 @@ I deeply appreciate the help of the following people. ...@@ -1138,6 +1146,8 @@ I deeply appreciate the help of the following people.
- [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8. - [Henry Schreiner](https://github.com/henryiii) added support for GCC 4.8.
- [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory. - [knilch](https://github.com/knilch0r) made sure the test suite does not stall when run in the wrong directory.
- [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning. - [Antonio Borondo](https://github.com/antonioborondo) fixed an MSVC 2017 warning.
- [efp](https://github.com/efp) added line and column information to parse errors.
- [julian-becker](https://github.com/julian-becker) added BSON support.
Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
......
...@@ -875,10 +875,11 @@ class binary_writer ...@@ -875,10 +875,11 @@ class binary_writer
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value) static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
{ {
std::size_t embedded_document_size = 0ul; std::size_t embedded_document_size = 0ul;
std::size_t array_index = 0ul;
for (const auto& el : value) for (const auto& el : value)
{ {
embedded_document_size += calc_bson_element_size("", el); embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
} }
return sizeof(std::int32_t) + embedded_document_size + 1ul; return sizeof(std::int32_t) + embedded_document_size + 1ul;
...@@ -893,9 +894,11 @@ class binary_writer ...@@ -893,9 +894,11 @@ class binary_writer
write_bson_entry_header(name, 0x04); // array write_bson_entry_header(name, 0x04); // array
write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value))); write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
std::size_t array_index = 0ul;
for (const auto& el : value) for (const auto& el : value)
{ {
write_bson_element("", el); write_bson_element(std::to_string(array_index++), el);
} }
oa->write_character(static_cast<CharType>(0x00)); oa->write_character(static_cast<CharType>(0x00));
......
...@@ -9155,10 +9155,11 @@ class binary_writer ...@@ -9155,10 +9155,11 @@ class binary_writer
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value) static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
{ {
std::size_t embedded_document_size = 0ul; std::size_t embedded_document_size = 0ul;
std::size_t array_index = 0ul;
for (const auto& el : value) for (const auto& el : value)
{ {
embedded_document_size += calc_bson_element_size("", el); embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
} }
return sizeof(std::int32_t) + embedded_document_size + 1ul; return sizeof(std::int32_t) + embedded_document_size + 1ul;
...@@ -9173,9 +9174,11 @@ class binary_writer ...@@ -9173,9 +9174,11 @@ class binary_writer
write_bson_entry_header(name, 0x04); // array write_bson_entry_header(name, 0x04); // array
write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value))); write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
std::size_t array_index = 0ul;
for (const auto& el : value) for (const auto& el : value)
{ {
write_bson_element("", el); write_bson_element(std::to_string(array_index++), el);
} }
oa->write_character(static_cast<CharType>(0x00)); oa->write_character(static_cast<CharType>(0x00));
......
...@@ -483,19 +483,19 @@ TEST_CASE("BSON") ...@@ -483,19 +483,19 @@ TEST_CASE("BSON")
std::vector<uint8_t> expected = std::vector<uint8_t> expected =
{ {
0x41, 0x00, 0x00, 0x00, // size (little endian) 0x49, 0x00, 0x00, 0x00, // size (little endian)
0x04, /// entry: embedded document 0x04, /// entry: embedded document
'e', 'n', 't', 'r', 'y', '\x00', 'e', 'n', 't', 'r', 'y', '\x00',
0x35, 0x00, 0x00, 0x00, // size (little endian) 0x3D, 0x00, 0x00, 0x00, // size (little endian)
0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, '0', 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, '1', 0x00, 0x02, 0x00, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, '2', 0x00, 0x03, 0x00, 0x00, 0x00,
0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, '3', 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x10, '4', 0x00, 0x05, 0x00, 0x00, 0x00,
0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, '5', 0x00, 0x06, 0x00, 0x00, 0x00,
0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, '6', 0x00, 0x07, 0x00, 0x00, 0x00,
0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, '7', 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, // end marker (embedded document) 0x00, // end marker (embedded document)
0x00 // end marker 0x00 // end marker
...@@ -552,6 +552,7 @@ TEST_CASE("BSON") ...@@ -552,6 +552,7 @@ TEST_CASE("BSON")
CHECK(parsed == expected); CHECK(parsed == expected);
auto dumped = json::to_bson(parsed); auto dumped = json::to_bson(parsed);
CHECK(dumped == input); CHECK(dumped == input);
CHECK(json::from_bson(dumped) == expected);
} }
SECTION("Example 2") SECTION("Example 2")
...@@ -561,7 +562,7 @@ TEST_CASE("BSON") ...@@ -561,7 +562,7 @@ TEST_CASE("BSON")
json expected = {{"BSON", {"awesome", 5.05, 1986}}}; json expected = {{"BSON", {"awesome", 5.05, 1986}}};
CHECK(parsed == expected); CHECK(parsed == expected);
auto dumped = json::to_bson(parsed); auto dumped = json::to_bson(parsed);
//CHECK(dumped == input); // see https://github.com/nlohmann/json/pull/1254#issuecomment-432831216 CHECK(dumped == input);
CHECK(json::from_bson(dumped) == expected); CHECK(json::from_bson(dumped) == expected);
} }
} }
...@@ -1225,7 +1226,14 @@ TEST_CASE("BSON roundtrips", "[hide]") ...@@ -1225,7 +1226,14 @@ TEST_CASE("BSON roundtrips", "[hide]")
{ {
std::vector<uint8_t> vec; std::vector<uint8_t> vec;
json::to_bson(j1, vec); json::to_bson(j1, vec);
CHECK(vec == packed);
if (vec != packed)
{
// the exact serializations may differ due to the order of
// object keys; in these cases, just compare whether both
// serializations create the same JSON value
CHECK(json::from_bson(vec) == json::from_bson(packed));
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment