🔨 added fix for arrays

This commit is contained in:
Niels Lohmann 2018-10-25 13:01:18 +02:00
parent 1968e5c793
commit 62126278a6
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
9 changed files with 43 additions and 19 deletions

View file

@ -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
}; };
``` ```
### 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.
- [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.

View file

@ -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
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));

View file

@ -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
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));

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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")
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")
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]")
{ {
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));
}
} }
} }
} }