BSON: Fixed array serialization by adding increasing integral names to the array elements
This commit is contained in:
parent
ad11b6c35e
commit
24a4142399
@ -837,10 +837,10 @@ 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 i = 0ull;
|
||||||
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(i++), el);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof(std::int32_t) + embedded_document_size + 1ul;
|
return sizeof(std::int32_t) + embedded_document_size + 1ul;
|
||||||
@ -854,9 +854,10 @@ class binary_writer
|
|||||||
write_bson_entry_header(name, 0x04); // array
|
write_bson_entry_header(name, 0x04); // array
|
||||||
write_number<std::int32_t, true>(calc_bson_array_size(value));
|
write_number<std::int32_t, true>(calc_bson_array_size(value));
|
||||||
|
|
||||||
|
std::size_t i = 0ull;
|
||||||
for (const auto& el : value)
|
for (const auto& el : value)
|
||||||
{
|
{
|
||||||
write_bson_element("", el);
|
write_bson_element(std::to_string(i++), el);
|
||||||
}
|
}
|
||||||
|
|
||||||
oa->write_character(static_cast<CharType>(0x00));
|
oa->write_character(static_cast<CharType>(0x00));
|
||||||
|
|||||||
@ -8994,10 +8994,10 @@ 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 i = 0ull;
|
||||||
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(i++), el);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof(std::int32_t) + embedded_document_size + 1ul;
|
return sizeof(std::int32_t) + embedded_document_size + 1ul;
|
||||||
@ -9011,9 +9011,10 @@ class binary_writer
|
|||||||
write_bson_entry_header(name, 0x04); // array
|
write_bson_entry_header(name, 0x04); // array
|
||||||
write_number<std::int32_t, true>(calc_bson_array_size(value));
|
write_number<std::int32_t, true>(calc_bson_array_size(value));
|
||||||
|
|
||||||
|
std::size_t i = 0ull;
|
||||||
for (const auto& el : value)
|
for (const auto& el : value)
|
||||||
{
|
{
|
||||||
write_bson_element("", el);
|
write_bson_element(std::to_string(i++), el);
|
||||||
}
|
}
|
||||||
|
|
||||||
oa->write_character(static_cast<CharType>(0x00));
|
oa->write_character(static_cast<CharType>(0x00));
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
https://code.google.com/p/json-test-suite/downloads/detail?name=sample.zip&can=2&q=
|
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
|
## License
|
||||||
|
|
||||||
Apache License Version 2.0
|
Apache License Version 2.0
|
||||||
|
|||||||
3315
test/data/json_testsuite/sample_cstr_keys.json
Normal file
3315
test/data/json_testsuite/sample_cstr_keys.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ SOFTWARE.
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
TEST_CASE("BSON")
|
TEST_CASE("BSON")
|
||||||
{
|
{
|
||||||
@ -483,19 +484,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
|
||||||
@ -1118,7 +1119,7 @@ TEST_CASE("BSON numerical data")
|
|||||||
0x00u // end marker
|
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));
|
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));
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user