BSON: Fixed array serialization by adding increasing integral names to the array elements

This commit is contained in:
Julian Becker 2018-10-25 07:38:02 +02:00
parent ad11b6c35e
commit 24a4142399
5 changed files with 3394 additions and 17 deletions

View File

@ -837,10 +837,10 @@ 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 i = 0ull;
for (const auto& el : value)
{
embedded_document_size += calc_bson_element_size("", el);
embedded_document_size += calc_bson_element_size(std::to_string(i++), el);
}
return sizeof(std::int32_t) + embedded_document_size + 1ul;
@ -854,9 +854,10 @@ class binary_writer
write_bson_entry_header(name, 0x04); // array
write_number<std::int32_t, true>(calc_bson_array_size(value));
std::size_t i = 0ull;
for (const auto& el : value)
{
write_bson_element("", el);
write_bson_element(std::to_string(i++), el);
}
oa->write_character(static_cast<CharType>(0x00));

View File

@ -8994,10 +8994,10 @@ 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 i = 0ull;
for (const auto& el : value)
{
embedded_document_size += calc_bson_element_size("", el);
embedded_document_size += calc_bson_element_size(std::to_string(i++), el);
}
return sizeof(std::int32_t) + embedded_document_size + 1ul;
@ -9011,9 +9011,10 @@ class binary_writer
write_bson_entry_header(name, 0x04); // array
write_number<std::int32_t, true>(calc_bson_array_size(value));
std::size_t i = 0ull;
for (const auto& el : value)
{
write_bson_element("", el);
write_bson_element(std::to_string(i++), el);
}
oa->write_character(static_cast<CharType>(0x00));

View File

@ -4,6 +4,8 @@
https://code.google.com/p/json-test-suite/downloads/detail?name=sample.zip&can=2&q=
The file sample_cstr_keys.json has been copied from sample.json and modified by removing all U+0000 code points from all the keys.
## License
Apache License Version 2.0

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@ SOFTWARE.
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <fstream>
#include <sstream>
TEST_CASE("BSON")
{
@ -483,19 +484,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
@ -1118,7 +1119,7 @@ TEST_CASE("BSON numerical data")
0x00u // end marker
};
CHECK_THROWS_AS(json::to_bson(j), json::out_of_range&);
CHECK_THROWS_AS(json::to_bson(j), json::out_of_range);
CHECK_THROWS_WITH(json::to_bson(j), "[json.exception.out_of_range.407] number overflow serializing " + std::to_string(i));
}
}
@ -1126,3 +1127,60 @@ TEST_CASE("BSON numerical data")
}
}
}
// use this testcase outside [hide] to run it with Valgrind
TEST_CASE("Single BSON roundtrip: sample_cstr_keys.json")
{
std::ifstream f_json("test/data/json_testsuite/sample_cstr_keys.json");
json j1 = json::parse(f_json);
{
SECTION("std::vector")
{
auto packed = json::to_bson(j1);
json j2 = json::from_bson(packed);
CHECK(j1 == j2);
}
SECTION("std::ostringstream")
{
std::ostringstream ss, ss2;
json::to_bson(j1, ss);
json j2 = json::from_bson(ss.str());
CHECK(j1 == j2);
}
SECTION("std::string")
{
std::string s;
json::to_bson(j1, s);
json j2 = json::from_bson(s);
CHECK(j1 == j2);
}
}
}
TEST_CASE("BSON FAQ Examples")
{
std::vector<std::uint8_t> bson
{
0x31, 0x00, 0x00, 0x00,
0x04, 'B', 'S', 'O', 'N', 0x00, // array
0x26, 0x00, 0x00, 0x00, // array size
0x02, 0x30, 0x00, // string
0x08, 0x00, 0x00, 0x00, 'a', 'w', 'e', 's', 'o', 'm', 'e', 0x00,
0x01, 0x31, 0x00, // double
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x14, 0x40,
0x10, 0x32, 0x00, // int32
0xc2, 0x07, 0x00, 0x00,
0x00,
0x00};
json expected{ {"BSON", json::array({std::string("awesome"), 5.05, 1986})}};
json json1 = json::from_bson(bson);
CHECK(expected == json1);
CHECK(bson == json::to_bson(json1));
}