🔨 added fix for arrays

pull/1320/head
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)
- [Implicit conversions](#implicit-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)
- [License](#license)
- [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
// create a JSON value
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
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.
- [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.
- [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.

View File

@ -875,10 +875,11 @@ class binary_writer
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
{
std::size_t embedded_document_size = 0ul;
std::size_t array_index = 0ul;
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;
@ -893,9 +894,11 @@ class binary_writer
write_bson_entry_header(name, 0x04); // array
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)
{
write_bson_element("", el);
write_bson_element(std::to_string(array_index++), el);
}
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)
{
std::size_t embedded_document_size = 0ul;
std::size_t array_index = 0ul;
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;
@ -9173,9 +9174,11 @@ class binary_writer
write_bson_entry_header(name, 0x04); // array
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)
{
write_bson_element("", el);
write_bson_element(std::to_string(array_index++), el);
}
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 =
{
0x41, 0x00, 0x00, 0x00, // size (little endian)
0x49, 0x00, 0x00, 0x00, // size (little endian)
0x04, /// entry: embedded document
'e', 'n', 't', 'r', 'y', '\x00',
0x35, 0x00, 0x00, 0x00, // size (little endian)
0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x02, 0x00, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, 0x00, 0x05, 0x00, 0x00, 0x00,
0x10, 0x00, 0x06, 0x00, 0x00, 0x00,
0x10, 0x00, 0x07, 0x00, 0x00, 0x00,
0x10, 0x00, 0x08, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x00, 0x00, // size (little endian)
0x10, '0', 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, '1', 0x00, 0x02, 0x00, 0x00, 0x00,
0x10, '2', 0x00, 0x03, 0x00, 0x00, 0x00,
0x10, '3', 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, '4', 0x00, 0x05, 0x00, 0x00, 0x00,
0x10, '5', 0x00, 0x06, 0x00, 0x00, 0x00,
0x10, '6', 0x00, 0x07, 0x00, 0x00, 0x00,
0x10, '7', 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, // end marker (embedded document)
0x00 // end marker
@ -552,6 +552,7 @@ TEST_CASE("BSON")
CHECK(parsed == expected);
auto dumped = json::to_bson(parsed);
CHECK(dumped == input);
CHECK(json::from_bson(dumped) == expected);
}
SECTION("Example 2")
@ -561,7 +562,7 @@ TEST_CASE("BSON")
json expected = {{"BSON", {"awesome", 5.05, 1986}}};
CHECK(parsed == expected);
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);
}
}
@ -1225,7 +1226,14 @@ TEST_CASE("BSON roundtrips", "[hide]")
{
std::vector<uint8_t> 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));
}
}
}
}