Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental support for BSON (de)serialization #1254

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f06c8fd
BSON: serialization of non-objects is not supported
julian-becker Sep 14, 2018
5f5836c
BSON: Support empty objects
julian-becker Sep 14, 2018
9a0dddc
BSON: Object with single boolean
julian-becker Sep 15, 2018
0c0f2e4
BSON: support doubles
julian-becker Sep 15, 2018
6c447de
BSON: Support objects with string members
julian-becker Sep 15, 2018
c5ef023
BSON: support objects with null members
julian-becker Sep 15, 2018
7ee361f
BSON: support objects with int32 members
julian-becker Sep 15, 2018
c0d8921
BSON: support objects with int64 members
julian-becker Sep 15, 2018
83b427a
BSON: unsigned integers
julian-becker Sep 15, 2018
5ce7d6b
BSON: support objects with objects as members
julian-becker Sep 15, 2018
120d1d7
BSON: test case for a more complex document
julian-becker Sep 15, 2018
cf485c2
BSON: Support for arrays
julian-becker Sep 15, 2018
df33a90
BSON: Bugfix for non-empty arrays
julian-becker Sep 15, 2018
763705c
Fix: Add missing `begin()` and `end()` member functions to `alt_string`
julian-becker Sep 24, 2018
bce4816
BSON: Added test case for the different input/output_adapters
julian-becker Sep 24, 2018
ef358ae
BSON: Fixed hangup in case of incomplete bson input and improved test…
julian-becker Sep 25, 2018
0a09db9
BSON: Extend `binary_reader::get_number` to be able to hanlde little …
julian-becker Sep 29, 2018
e8730e5
BSON: Reworked `binary_reader::get_bson_cstr()`
julian-becker Sep 29, 2018
81f4b34
BSON: Improved documentation and error handling/reporting
julian-becker Oct 7, 2018
062aeaf
BSON: Reworked the `binary_writer` such that it precomputes the size …
julian-becker Oct 7, 2018
df0f612
BSON: allow and discard values and object entries of type `value_t::d…
julian-becker Oct 7, 2018
5bccacd
BSON: throw json.exception.out_of_range.407 in case a value of type `…
julian-becker Oct 16, 2018
daa3ca8
BSON: Adjusted documentation of `binary_writer::to_bson()`
julian-becker Oct 16, 2018
978c3c4
BSON: throw `json.exception.out_of_range.409` in case a key to be ser…
julian-becker Oct 16, 2018
2a63869
Merge branch 'develop' of https://github.com/nlohmann/json into featu…
julian-becker Oct 17, 2018
8de10c5
BSON: Hopefully fixing ambiguity (on some compilers) to call to strin…
julian-becker Oct 17, 2018
5ba812d
BSON: fixed incorrect casting in unit-bson.cpp
julian-becker Oct 18, 2018
ad11b6c
BSON: Improved exception-related tests and report location of U+0000 …
julian-becker Oct 18, 2018
24a4142
BSON: Fixed array serialization by adding increasing integral names t…
julian-becker Oct 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/nlohmann/detail/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten
json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |

@liveexample{The following code shows how a `type_error` exception can be
caught.,type_error}
Expand Down
142 changes: 140 additions & 2 deletions include/nlohmann/detail/input/binary_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class binary_reader
result = parse_ubjson_internal();
break;

case input_format_t::bson:
result = parse_bson_internal();
break;

// LCOV_EXCL_START
default:
assert(false);
Expand Down Expand Up @@ -120,6 +124,139 @@ class binary_reader
}

private:

/*!
@return whether array creation completed
*/
bool get_bson_cstr(string_t& result)
{
auto out = std::back_inserter(result);
while (true)
{
get();
if (JSON_UNLIKELY(not unexpect_eof()))
{
return false;
}
if (current == 0x00)
{
return true;
}
*out++ = static_cast<char>(current);
}

return true;
}

bool parse_bson_entries(bool is_array)
julian-becker marked this conversation as resolved.
Show resolved Hide resolved
{
while (auto entry_type = get())
{
string_t key;
if (!get_bson_cstr(key))
{
return false;
}

if (!is_array)
{
sax->key(key);
}

switch (entry_type)
{
case 0x01: // double
{
double number;
get_number<double, true>(number);
sax->number_float(static_cast<number_float_t>(number), "");
}
break;
julian-becker marked this conversation as resolved.
Show resolved Hide resolved
case 0x02: // string
{
std::int32_t len;
string_t value;
get_number<std::int32_t, true>(len);
get_string(len - 1ul, value);
get();
sax->string(value);
}
break;
case 0x08: // boolean
{
sax->boolean(static_cast<bool>(get()));
}
break;
case 0x10: // int32
{
std::int32_t value;
get_number<std::int32_t, true>(value);
sax->number_integer(static_cast<std::int32_t>(value));
}
break;
case 0x12: // int64
{
std::int64_t value;
get_number<std::int64_t, true>(value);
sax->number_integer(static_cast<std::int64_t>(value));
}
break;
case 0x0A: // null
{
sax->null();
}
break;
case 0x03: // object
{
parse_bson_internal();
}
break;
case 0x04: // array
{
parse_bson_array();
}
break;
}
julian-becker marked this conversation as resolved.
Show resolved Hide resolved
}
return true;
}

bool parse_bson_array()
{
std::int32_t documentSize;
get_number<std::int32_t, true>(documentSize);

if (JSON_UNLIKELY(not sax->start_array(-1)))
{
return false;
}

if (!parse_bson_entries(/*is_array*/true))
{
return false;
}

return sax->end_array();
}

bool parse_bson_internal()
{
std::int32_t documentSize;
get_number<std::int32_t, true>(documentSize);

if (JSON_UNLIKELY(not sax->start_object(-1)))
{
return false;
}

if (!parse_bson_entries(/*is_array*/false))
{
return false;
}

return sax->end_object();
}

/*!
@param[in] get_char whether a new character should be retrieved from the
input (true, default) or whether the last read
Expand Down Expand Up @@ -870,7 +1007,7 @@ class binary_reader
bytes in CBOR, MessagePack, and UBJSON are stored in network order
(big endian) and therefore need reordering on little endian systems.
*/
template<typename NumberType>
template<typename NumberType, bool InputIsLittleEndian = false>
bool get_number(NumberType& result)
{
// step 1: read input into array with system's byte order
Expand All @@ -884,7 +1021,7 @@ class binary_reader
}

// reverse byte order prior to conversion if necessary
if (is_little_endian)
if (is_little_endian && !InputIsLittleEndian)
{
vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
}
Expand All @@ -899,6 +1036,7 @@ class binary_reader
return true;
}


/*!
@brief create a string by reading characters from the input

Expand Down
2 changes: 1 addition & 1 deletion include/nlohmann/detail/input/input_adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace nlohmann
namespace detail
{
/// the supported input formats
enum class input_format_t { json, cbor, msgpack, ubjson };
enum class input_format_t { json, cbor, msgpack, ubjson, bson };

////////////////////
// input adapters //
Expand Down
Loading