From 904642f261f5698c6c2c611567252abec0f17247 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 17 May 2020 22:50:27 +0200 Subject: [PATCH] :recycle: rename internal_binary_t with binary_t --- README.md | 30 ++ doc/examples/is_array.cpp | 2 + doc/examples/is_array.link | 2 +- doc/examples/is_array.output | 1 + doc/examples/is_binary.cpp | 30 ++ doc/examples/is_binary.link | 1 + doc/examples/is_binary.output | 9 + doc/examples/is_boolean.cpp | 2 + doc/examples/is_boolean.link | 2 +- doc/examples/is_boolean.output | 1 + doc/examples/is_discarded.cpp | 2 + doc/examples/is_discarded.link | 2 +- doc/examples/is_discarded.output | 1 + doc/examples/is_null.cpp | 2 + doc/examples/is_null.link | 2 +- doc/examples/is_null.output | 1 + doc/examples/is_number.cpp | 2 + doc/examples/is_number.link | 2 +- doc/examples/is_number.output | 1 + doc/examples/is_number_float.cpp | 2 + doc/examples/is_number_float.link | 2 +- doc/examples/is_number_float.output | 1 + doc/examples/is_number_integer.cpp | 2 + doc/examples/is_number_integer.link | 2 +- doc/examples/is_number_integer.output | 1 + doc/examples/is_number_unsigned.cpp | 2 + doc/examples/is_number_unsigned.link | 2 +- doc/examples/is_number_unsigned.output | 1 + doc/examples/is_object.cpp | 2 + doc/examples/is_object.link | 2 +- doc/examples/is_object.output | 1 + doc/examples/is_primitive.cpp | 2 + doc/examples/is_primitive.link | 2 +- doc/examples/is_primitive.output | 1 + doc/examples/is_string.cpp | 2 + doc/examples/is_string.link | 2 +- doc/examples/is_string.output | 1 + doc/examples/is_structured.cpp | 2 + doc/examples/is_structured.link | 2 +- doc/examples/is_structured.output | 1 + doc/examples/sax_parse.cpp | 2 +- doc/examples/sax_parse.link | 2 +- doc/index.md | 9 +- .../nlohmann/detail/conversions/from_json.hpp | 6 +- .../nlohmann/detail/conversions/to_json.hpp | 12 +- .../nlohmann/detail/input/binary_reader.hpp | 18 +- include/nlohmann/detail/input/json_sax.hpp | 16 +- .../detail/iterators/internal_iterator.hpp | 2 +- .../nlohmann/detail/output/binary_writer.hpp | 6 +- include/nlohmann/detail/output/serializer.hpp | 4 +- include/nlohmann/detail/wrapped_binary_t.hpp | 98 ++++- include/nlohmann/json.hpp | 224 ++++------ single_include/nlohmann/json.hpp | 386 +++++++++--------- test/src/unit-class_parser.cpp | 4 +- test/src/unit-constructor1.cpp | 4 +- test/src/unit-deserialization.cpp | 2 +- test/src/unit-modifiers.cpp | 22 +- test/src/unit-msgpack.cpp | 6 +- test/src/unit-pointer_access.cpp | 40 +- 59 files changed, 536 insertions(+), 457 deletions(-) create mode 100644 doc/examples/is_binary.cpp create mode 100644 doc/examples/is_binary.link create mode 100644 doc/examples/is_binary.output diff --git a/README.md b/README.md index 612b8a66..d2c3f978 100644 --- a/README.md +++ b/README.md @@ -1047,6 +1047,36 @@ std::vector v_ubjson = json::to_ubjson(j); json j_from_ubjson = json::from_ubjson(v_ubjson); ``` +The library also supports binary types from BSON, CBOR (byte strings), and MessagePack (bin, ext, fixext). They are stored by default as `std::vector` to be processed outside of the library. + +```cpp +// CBOR byte string with payload 0xCAFE +std::vector v = {0x42, 0xCA, 0xFE}; + +// read value +json j = json::from_cbor(v); + +// the JSON value has type binary +j.is_binary(); // true + +// get reference to stored binary value +auto& binary = j.get_binary(); + +// the binary value has no subtype (CBOR has no binary subtypes) +binary.has_subtype(); // false + +// access std::vector member functions +binary.size(); // 2 +binary[0]; // 0xCA +binary[1]; // 0xFE + +// set subtype to 0x10 +binary.set_subtype(0x10); + +// serialize to MessagePack +auto cbor = json::to_msgpack(j); // 0xD5 (fixext2), 0x10, 0xCA, 0xFE +``` + ## Supported compilers diff --git a/doc/examples/is_array.cpp b/doc/examples/is_array.cpp index 235dab76..8286697b 100644 --- a/doc/examples/is_array.cpp +++ b/doc/examples/is_array.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_array() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_array() << '\n'; std::cout << j_array.is_array() << '\n'; std::cout << j_string.is_array() << '\n'; + std::cout << j_binary.is_array() << '\n'; } diff --git a/doc/examples/is_array.link b/doc/examples/is_array.link index 4232a922..fc292eb6 100644 --- a/doc/examples/is_array.link +++ b/doc/examples/is_array.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_array.output b/doc/examples/is_array.output index 5b8cc40c..7b7ef3f1 100644 --- a/doc/examples/is_array.output +++ b/doc/examples/is_array.output @@ -6,3 +6,4 @@ false false true false +false diff --git a/doc/examples/is_binary.cpp b/doc/examples/is_binary.cpp new file mode 100644 index 00000000..74173e91 --- /dev/null +++ b/doc/examples/is_binary.cpp @@ -0,0 +1,30 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); + + // call is_binary() + std::cout << std::boolalpha; + std::cout << j_null.is_binary() << '\n'; + std::cout << j_boolean.is_binary() << '\n'; + std::cout << j_number_integer.is_binary() << '\n'; + std::cout << j_number_unsigned_integer.is_binary() << '\n'; + std::cout << j_number_float.is_binary() << '\n'; + std::cout << j_object.is_binary() << '\n'; + std::cout << j_array.is_binary() << '\n'; + std::cout << j_string.is_binary() << '\n'; + std::cout << j_binary.is_binary() << '\n'; +} diff --git a/doc/examples/is_binary.link b/doc/examples/is_binary.link new file mode 100644 index 00000000..cc8e715e --- /dev/null +++ b/doc/examples/is_binary.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/is_binary.output b/doc/examples/is_binary.output new file mode 100644 index 00000000..505e76e4 --- /dev/null +++ b/doc/examples/is_binary.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +false +true diff --git a/doc/examples/is_boolean.cpp b/doc/examples/is_boolean.cpp index ccc202d0..d51d594e 100644 --- a/doc/examples/is_boolean.cpp +++ b/doc/examples/is_boolean.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_boolean() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_boolean() << '\n'; std::cout << j_array.is_boolean() << '\n'; std::cout << j_string.is_boolean() << '\n'; + std::cout << j_binary.is_boolean() << '\n'; } diff --git a/doc/examples/is_boolean.link b/doc/examples/is_boolean.link index 19f0b008..779a36e9 100644 --- a/doc/examples/is_boolean.link +++ b/doc/examples/is_boolean.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_boolean.output b/doc/examples/is_boolean.output index 721b3a5e..eace89d2 100644 --- a/doc/examples/is_boolean.output +++ b/doc/examples/is_boolean.output @@ -6,3 +6,4 @@ false false false false +false diff --git a/doc/examples/is_discarded.cpp b/doc/examples/is_discarded.cpp index 782e6499..914890c4 100644 --- a/doc/examples/is_discarded.cpp +++ b/doc/examples/is_discarded.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_discarded() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_discarded() << '\n'; std::cout << j_array.is_discarded() << '\n'; std::cout << j_string.is_discarded() << '\n'; + std::cout << j_binary.is_discarded() << '\n'; } diff --git a/doc/examples/is_discarded.link b/doc/examples/is_discarded.link index 9ec778f7..c51128f6 100644 --- a/doc/examples/is_discarded.link +++ b/doc/examples/is_discarded.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_discarded.output b/doc/examples/is_discarded.output index 485b1696..14718f64 100644 --- a/doc/examples/is_discarded.output +++ b/doc/examples/is_discarded.output @@ -6,3 +6,4 @@ false false false false +false diff --git a/doc/examples/is_null.cpp b/doc/examples/is_null.cpp index 4a635092..2e2730e1 100644 --- a/doc/examples/is_null.cpp +++ b/doc/examples/is_null.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_null() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_null() << '\n'; std::cout << j_array.is_null() << '\n'; std::cout << j_string.is_null() << '\n'; + std::cout << j_binary.is_null() << '\n'; } diff --git a/doc/examples/is_null.link b/doc/examples/is_null.link index dd1a5aab..fe02d31f 100644 --- a/doc/examples/is_null.link +++ b/doc/examples/is_null.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_null.output b/doc/examples/is_null.output index 4cc64628..42bbee2a 100644 --- a/doc/examples/is_null.output +++ b/doc/examples/is_null.output @@ -6,3 +6,4 @@ false false false false +false diff --git a/doc/examples/is_number.cpp b/doc/examples/is_number.cpp index eb23bd24..8ef27b0a 100644 --- a/doc/examples/is_number.cpp +++ b/doc/examples/is_number.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_number() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_number() << '\n'; std::cout << j_array.is_number() << '\n'; std::cout << j_string.is_number() << '\n'; + std::cout << j_binary.is_number() << '\n'; } diff --git a/doc/examples/is_number.link b/doc/examples/is_number.link index 43c52b47..c2623b29 100644 --- a/doc/examples/is_number.link +++ b/doc/examples/is_number.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number.output b/doc/examples/is_number.output index 06dbc282..53ef340b 100644 --- a/doc/examples/is_number.output +++ b/doc/examples/is_number.output @@ -6,3 +6,4 @@ true false false false +false diff --git a/doc/examples/is_number_float.cpp b/doc/examples/is_number_float.cpp index 3435a7e0..8b8fa3bf 100644 --- a/doc/examples/is_number_float.cpp +++ b/doc/examples/is_number_float.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_number_float() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_number_float() << '\n'; std::cout << j_array.is_number_float() << '\n'; std::cout << j_string.is_number_float() << '\n'; + std::cout << j_binary.is_number_float() << '\n'; } diff --git a/doc/examples/is_number_float.link b/doc/examples/is_number_float.link index 4d8f0ea8..ec3c822e 100644 --- a/doc/examples/is_number_float.link +++ b/doc/examples/is_number_float.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number_float.output b/doc/examples/is_number_float.output index 09afae4c..0e64601a 100644 --- a/doc/examples/is_number_float.output +++ b/doc/examples/is_number_float.output @@ -6,3 +6,4 @@ true false false false +false diff --git a/doc/examples/is_number_integer.cpp b/doc/examples/is_number_integer.cpp index 6f6e4204..efd76a7d 100644 --- a/doc/examples/is_number_integer.cpp +++ b/doc/examples/is_number_integer.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_number_integer() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_number_integer() << '\n'; std::cout << j_array.is_number_integer() << '\n'; std::cout << j_string.is_number_integer() << '\n'; + std::cout << j_binary.is_number_integer() << '\n'; } diff --git a/doc/examples/is_number_integer.link b/doc/examples/is_number_integer.link index 0233e0f7..49b57e66 100644 --- a/doc/examples/is_number_integer.link +++ b/doc/examples/is_number_integer.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number_integer.output b/doc/examples/is_number_integer.output index be0f7393..c1df310f 100644 --- a/doc/examples/is_number_integer.output +++ b/doc/examples/is_number_integer.output @@ -6,3 +6,4 @@ false false false false +false diff --git a/doc/examples/is_number_unsigned.cpp b/doc/examples/is_number_unsigned.cpp index 2ea2673e..1a85b832 100644 --- a/doc/examples/is_number_unsigned.cpp +++ b/doc/examples/is_number_unsigned.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_number_unsigned() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_number_unsigned() << '\n'; std::cout << j_array.is_number_unsigned() << '\n'; std::cout << j_string.is_number_unsigned() << '\n'; + std::cout << j_binary.is_number_unsigned() << '\n'; } diff --git a/doc/examples/is_number_unsigned.link b/doc/examples/is_number_unsigned.link index 89817630..1af8cef1 100644 --- a/doc/examples/is_number_unsigned.link +++ b/doc/examples/is_number_unsigned.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_number_unsigned.output b/doc/examples/is_number_unsigned.output index fdf264e0..e6059d48 100644 --- a/doc/examples/is_number_unsigned.output +++ b/doc/examples/is_number_unsigned.output @@ -6,3 +6,4 @@ false false false false +false diff --git a/doc/examples/is_object.cpp b/doc/examples/is_object.cpp index 42cedf8f..63728eab 100644 --- a/doc/examples/is_object.cpp +++ b/doc/examples/is_object.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_object() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_object() << '\n'; std::cout << j_array.is_object() << '\n'; std::cout << j_string.is_object() << '\n'; + std::cout << j_binary.is_object() << '\n'; } diff --git a/doc/examples/is_object.link b/doc/examples/is_object.link index 5dd305bb..ce82ff85 100644 --- a/doc/examples/is_object.link +++ b/doc/examples/is_object.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_object.output b/doc/examples/is_object.output index e041e392..d9a429f8 100644 --- a/doc/examples/is_object.output +++ b/doc/examples/is_object.output @@ -6,3 +6,4 @@ false true false false +false diff --git a/doc/examples/is_primitive.cpp b/doc/examples/is_primitive.cpp index d70c83e3..88b0a6a9 100644 --- a/doc/examples/is_primitive.cpp +++ b/doc/examples/is_primitive.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_primitive() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_primitive() << '\n'; std::cout << j_array.is_primitive() << '\n'; std::cout << j_string.is_primitive() << '\n'; + std::cout << j_binary.is_primitive() << '\n'; } diff --git a/doc/examples/is_primitive.link b/doc/examples/is_primitive.link index ae58b2d7..4571494d 100644 --- a/doc/examples/is_primitive.link +++ b/doc/examples/is_primitive.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_primitive.output b/doc/examples/is_primitive.output index 635db6e3..77af24c0 100644 --- a/doc/examples/is_primitive.output +++ b/doc/examples/is_primitive.output @@ -6,3 +6,4 @@ true false false true +true diff --git a/doc/examples/is_string.cpp b/doc/examples/is_string.cpp index 2679cd1c..8bab2794 100644 --- a/doc/examples/is_string.cpp +++ b/doc/examples/is_string.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_string() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_string() << '\n'; std::cout << j_array.is_string() << '\n'; std::cout << j_string.is_string() << '\n'; + std::cout << j_binary.is_string() << '\n'; } diff --git a/doc/examples/is_string.link b/doc/examples/is_string.link index 92b05e75..9d126a95 100644 --- a/doc/examples/is_string.link +++ b/doc/examples/is_string.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_string.output b/doc/examples/is_string.output index 672eb438..6446f187 100644 --- a/doc/examples/is_string.output +++ b/doc/examples/is_string.output @@ -6,3 +6,4 @@ false false false true +false diff --git a/doc/examples/is_structured.cpp b/doc/examples/is_structured.cpp index 33e2bbd0..b022285b 100644 --- a/doc/examples/is_structured.cpp +++ b/doc/examples/is_structured.cpp @@ -14,6 +14,7 @@ int main() json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; + json j_binary = json::binary_array({1, 2, 3}); // call is_structured() std::cout << std::boolalpha; @@ -25,4 +26,5 @@ int main() std::cout << j_object.is_structured() << '\n'; std::cout << j_array.is_structured() << '\n'; std::cout << j_string.is_structured() << '\n'; + std::cout << j_binary.is_structured() << '\n'; } diff --git a/doc/examples/is_structured.link b/doc/examples/is_structured.link index 44e06e9f..f3eb6272 100644 --- a/doc/examples/is_structured.link +++ b/doc/examples/is_structured.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/examples/is_structured.output b/doc/examples/is_structured.output index e1186dd8..625c124b 100644 --- a/doc/examples/is_structured.output +++ b/doc/examples/is_structured.output @@ -6,3 +6,4 @@ false true true false +false diff --git a/doc/examples/sax_parse.cpp b/doc/examples/sax_parse.cpp index 82a99f7d..45273eb6 100644 --- a/doc/examples/sax_parse.cpp +++ b/doc/examples/sax_parse.cpp @@ -79,7 +79,7 @@ class sax_event_consumer : public json::json_sax_t return true; } - bool binary(binary_t& val) override + bool binary(json::binary_t& val) override { events.push_back("binary"); return true; diff --git a/doc/examples/sax_parse.link b/doc/examples/sax_parse.link index c51f517c..034b48c9 100644 --- a/doc/examples/sax_parse.link +++ b/doc/examples/sax_parse.link @@ -1 +1 @@ -online \ No newline at end of file +online \ No newline at end of file diff --git a/doc/index.md b/doc/index.md index f2de2e3a..3691461d 100644 --- a/doc/index.md +++ b/doc/index.md @@ -22,12 +22,14 @@ These pages contain the API documentation of JSON for Modern C++, a C++11 header @link nlohmann::basic_json::is_object is_object @endlink, @link nlohmann::basic_json::is_array is_array @endlink, @link nlohmann::basic_json::is_string is_string @endlink, - @link nlohmann::basic_json::is_discarded is_discarded @endlink -- check for value type + @link nlohmann::basic_json::is_discarded is_discarded @endlink, + @link nlohmann::basic_json::is_binary is_binary @endlink -- check for value type - @link nlohmann::basic_json::operator value_t() const operator value_t @endlink -- type of the value (implicit conversion) - value access - @link nlohmann::basic_json::get get @endlink -- get a value - @link nlohmann::basic_json::get_ptr get_ptr @endlink -- get a value pointer - @link nlohmann::basic_json::get_ref get_ref @endlink -- get a value reference + - @link nlohmann::basic_json::get_binary get_binary @endlink -- get a binary value - @link nlohmann::basic_json::operator ValueType() const operator ValueType @endlink -- get a value (implicit conversion) - @link nlohmann::basic_json::value value @endlink -- get a value from an object and return default value if key is not present - exceptions @@ -67,8 +69,9 @@ These pages contain the API documentation of JSON for Modern C++, a C++11 header - @link nlohmann::basic_json::number_integer_t signed integers @endlink - @link nlohmann::basic_json::number_unsigned_t unsigned integers @endlink - @link nlohmann::basic_json::number_float_t floating-point @endlink + - @link nlohmann::basic_json::binary_t binary values @endlink - further JSON standards - - @link nlohmann::json_pointer JSON Pointer @endlink (REF 6901) + - @link nlohmann::json_pointer JSON Pointer @endlink (RFC 6901) - @link nlohmann::basic_json::patch JSON Patch @endlink (RFC 6902) - @link nlohmann::basic_json::merge_patch JSON Merge Patch @endlink (RFC 7396) @@ -324,7 +327,7 @@ Note that this table only lists those exceptions thrown due to the type. For ins -@copyright Copyright © 2013-2019 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT). +@copyright Copyright © 2013-2020 Niels Lohmann. The code is licensed under the [MIT License](http://opensource.org/licenses/MIT). @author [Niels Lohmann](http://nlohmann.me) @see https://github.com/nlohmann/json to download the source code diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index b6105b05..e8731f22 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -228,7 +228,7 @@ template ::value and not is_constructible_object_type::value and not is_constructible_string_type::value and - not std::is_same::value and + not std::is_same::value and not is_basic_json::value, int > = 0 > auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) @@ -246,14 +246,14 @@ void()) } template -void from_json(const BasicJsonType& j, typename BasicJsonType::internal_binary_t& bin) +void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) { if (JSON_HEDLEY_UNLIKELY(not j.is_binary())) { JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()))); } - bin = *j.template get_ptr(); + bin = *j.template get_ptr(); } template struct external_constructor { template - static void construct(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& b) + static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) { j.m_type = value_t::binary; - typename BasicJsonType::internal_binary_t value{b}; + typename BasicJsonType::binary_t value{b}; j.m_value = value; j.assert_invariant(); } template - static void construct(BasicJsonType& j, typename BasicJsonType::internal_binary_t&& b) + static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) { j.m_type = value_t::binary; - typename BasicJsonType::internal_binary_t value{std::move(b)}; + typename BasicJsonType::binary_t value{std::move(b)}; j.m_value = value; j.assert_invariant(); } @@ -280,7 +280,7 @@ template ::value and not is_compatible_object_type::value and not is_compatible_string_type::value and - not std::is_same::value and + not std::is_same::value and not is_basic_json::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleArrayType& arr) @@ -289,7 +289,7 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr) } template -void to_json(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& bin) +void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) { external_constructor::construct(j, bin); } diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index 35d7dbd6..e859c7d1 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -52,7 +52,7 @@ class binary_reader using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; using json_sax_t = SAX; public: @@ -219,7 +219,7 @@ class binary_reader @return `true` if the byte array was successfully parsed */ template - bool get_bson_binary(const NumberType len, internal_binary_t& result) + bool get_bson_binary(const NumberType len, binary_t& result) { if (JSON_HEDLEY_UNLIKELY(len < 0)) { @@ -276,7 +276,7 @@ class binary_reader case 0x05: // binary { std::int32_t len; - internal_binary_t value; + binary_t value; return get_number(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value); } @@ -532,7 +532,7 @@ class binary_reader case 0x5B: // Binary data (eight-byte uint64_t for n follow) case 0x5F: // Binary data (indefinite length) { - internal_binary_t b; + binary_t b; return get_cbor_binary(b) and sax->binary(b); } @@ -862,7 +862,7 @@ class binary_reader @return whether byte array creation completed */ - bool get_cbor_binary(internal_binary_t& result) + bool get_cbor_binary(binary_t& result) { if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary"))) { @@ -932,7 +932,7 @@ class binary_reader { while (get() != 0xFF) { - internal_binary_t chunk; + binary_t chunk; if (not get_cbor_binary(chunk)) { return false; @@ -1282,7 +1282,7 @@ class binary_reader case 0xD7: // fixext 8 case 0xD8: // fixext 16 { - internal_binary_t b; + binary_t b; return get_msgpack_binary(b) and sax->binary(b); } @@ -1505,7 +1505,7 @@ class binary_reader @return whether byte array creation completed */ - bool get_msgpack_binary(internal_binary_t& result) + bool get_msgpack_binary(binary_t& result) { // helper function to set the subtype auto assign_and_return_true = [&result](std::int8_t subtype) @@ -2223,7 +2223,7 @@ class binary_reader template bool get_binary(const input_format_t format, const NumberType len, - internal_binary_t& result) + binary_t& result) { bool success = true; std::generate_n(std::back_inserter(result), len, [this, &success, &format]() diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index 54b53fd3..25be7e4b 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -27,7 +27,7 @@ struct json_sax using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; /*! @brief a null value was read @@ -78,7 +78,7 @@ struct json_sax @return whether parsing should proceed @note It is safe to move the passed binary. */ - virtual bool binary(internal_binary_t& val) = 0; + virtual bool binary(binary_t& val) = 0; /*! @brief the beginning of an object was read @@ -154,7 +154,7 @@ class json_sax_dom_parser using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; /*! @param[in, out] r reference to a JSON value that is manipulated while @@ -208,7 +208,7 @@ class json_sax_dom_parser return true; } - bool binary(internal_binary_t& val) + bool binary(binary_t& val) { handle_value(std::move(val)); return true; @@ -343,7 +343,7 @@ class json_sax_dom_callback_parser using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; using parser_callback_t = typename BasicJsonType::parser_callback_t; using parse_event_t = typename BasicJsonType::parse_event_t; @@ -398,7 +398,7 @@ class json_sax_dom_callback_parser return true; } - bool binary(internal_binary_t& val) + bool binary(binary_t& val) { handle_value(std::move(val)); return true; @@ -654,7 +654,7 @@ class json_sax_acceptor using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; bool null() { @@ -686,7 +686,7 @@ class json_sax_acceptor return true; } - bool binary(internal_binary_t& /*unused*/) + bool binary(binary_t& /*unused*/) { return true; } diff --git a/include/nlohmann/detail/iterators/internal_iterator.hpp b/include/nlohmann/detail/iterators/internal_iterator.hpp index 71539a6a..742df483 100644 --- a/include/nlohmann/detail/iterators/internal_iterator.hpp +++ b/include/nlohmann/detail/iterators/internal_iterator.hpp @@ -19,7 +19,7 @@ template struct internal_iterator /// iterator for JSON arrays typename BasicJsonType::array_t::iterator array_iterator {}; /// iterator for JSON binary arrays - typename BasicJsonType::binary_t::iterator binary_iterator {}; + typename BasicJsonType::binary_t::container_type::iterator binary_iterator {}; /// generic iterator for all other types primitive_iterator_t primitive_iterator {}; }; diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index 1feb95dc..4478ab34 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -27,7 +27,7 @@ template class binary_writer { using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; public: /*! @@ -1080,7 +1080,7 @@ class binary_writer /*! @return The size of the BSON-encoded binary array @a value */ - static std::size_t calc_bson_binary_size(const typename BasicJsonType::internal_binary_t& value) + static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value) { return sizeof(std::int32_t) + value.size() + 1ul; } @@ -1108,7 +1108,7 @@ class binary_writer @brief Writes a BSON element with key @a name and binary value @a value */ void write_bson_binary(const string_t& name, - const internal_binary_t& value) + const binary_t& value) { write_bson_entry_header(name, 0x05); diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index 75ce6783..dc963f53 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -45,7 +45,7 @@ class serializer using number_float_t = typename BasicJsonType::number_float_t; using number_integer_t = typename BasicJsonType::number_integer_t; using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using binary_t = typename BasicJsonType::binary_t; + using binary_char_t = typename BasicJsonType::binary_t::value_type; static constexpr std::uint8_t UTF8_ACCEPT = 0; static constexpr std::uint8_t UTF8_REJECT = 1; @@ -624,7 +624,7 @@ class serializer template::value or std::is_same::value or - std::is_same::value, + std::is_same::value, int> = 0> void dump_integer(NumberType x) { diff --git a/include/nlohmann/detail/wrapped_binary_t.hpp b/include/nlohmann/detail/wrapped_binary_t.hpp index 230641bd..6edd7b52 100644 --- a/include/nlohmann/detail/wrapped_binary_t.hpp +++ b/include/nlohmann/detail/wrapped_binary_t.hpp @@ -19,36 +19,51 @@ template class wrapped_binary_t : public BinaryType { public: - using binary_t = BinaryType; + /// the type of the underlying container + using container_type = BinaryType; - wrapped_binary_t() noexcept(noexcept(binary_t())) - : binary_t() + wrapped_binary_t() noexcept(noexcept(container_type())) + : container_type() {} - wrapped_binary_t(const binary_t& b) noexcept(noexcept(binary_t(b))) - : binary_t(b) + wrapped_binary_t(const container_type& b) noexcept(noexcept(container_type(b))) + : container_type(b) {} - wrapped_binary_t(binary_t&& b) noexcept(noexcept(binary_t(std::move(b)))) - : binary_t(std::move(b)) + wrapped_binary_t(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) {} - wrapped_binary_t(const binary_t& b, - std::uint8_t subtype) noexcept(noexcept(binary_t(b))) - : binary_t(b) + wrapped_binary_t(const container_type& b, + std::uint8_t subtype) noexcept(noexcept(container_type(b))) + : container_type(b) , m_subtype(subtype) , m_has_subtype(true) {} - wrapped_binary_t(binary_t&& b, std::uint8_t subtype) noexcept(noexcept(binary_t(std::move(b)))) - : binary_t(std::move(b)) + wrapped_binary_t(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) , m_subtype(subtype) , m_has_subtype(true) {} /*! - @brief set the subtype - @param subtype subtype to set (implementation specific) + @brief sets the binary subtype + + Sets the binary subtype of the value, also flags a binary JSON value as + having a subtype, which has implications for serialization. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref subtype() -- return the binary subtype + @sa @ref clear_subtype() -- clears the binary subtype + @sa @ref has_subtype() -- returns whether or not the binary value has a + subtype + + @since version 3.8.0 */ void set_subtype(std::uint8_t subtype) noexcept { @@ -57,8 +72,25 @@ class wrapped_binary_t : public BinaryType } /*! - @brief get the subtype - @return subtype (implementation specific) + @brief return the binary subtype + + Returns the numerical subtype of the value if it has a subtype. If it does + not have a subtype, this function will return size_t(-1) as a sentinel + value. + + @return the numerical subtype of the binary value + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref set_subtype() -- sets the binary subtype + @sa @ref clear_subtype() -- clears the binary subtype + @sa @ref has_subtype() -- returns whether or not the binary value has a + subtype + + @since version 3.8.0 */ constexpr std::uint8_t subtype() const noexcept { @@ -66,8 +98,20 @@ class wrapped_binary_t : public BinaryType } /*! - @brief get whether a subtype was set - @return whether a subtype was set + @brief return whether the value has a subtype + + @return whether the value has a subtype + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref subtype() -- return the binary subtype + @sa @ref set_subtype() -- sets the binary subtype + @sa @ref clear_subtype() -- clears the binary subtype + + @since version 3.8.0 */ constexpr bool has_subtype() const noexcept { @@ -75,7 +119,23 @@ class wrapped_binary_t : public BinaryType } /*! - @brief clear the subtype + @brief clears the binary subtype + + Clears the binary subtype and flags the value as not having a subtype, which + has implications for serialization; for instance MessagePack will prefer the + bin family over the ext family. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref subtype() -- return the binary subtype + @sa @ref set_subtype() -- sets the binary subtype + @sa @ref has_subtype() -- returns whether or not the binary value has a + subtype + + @since version 3.8.0 */ void clear_subtype() noexcept { diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 2b976d91..fc849a38 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -884,23 +884,7 @@ class basic_json for any access to array values, a pointer of the type `binary_t*` must be dereferenced. - @sa @ref array_t -- type for an array value - - @since version 3.8.0 - */ - using binary_t = BinaryType; - - /*! - @brief binary array with a binary type - - This type is used to store binary types internally. It wrapps the template - type `BinaryType` (@ref binary_t) and adds a subtype to allow to distinguish - different binary types from different formats. - - While @ref binary_t is used to define how binary values are stored, this - type is used to access binary values once they are parsed. - - Notes on subtypes: + #### Notes on subtypes - CBOR - Binary values are represented as byte strings. No subtypes are @@ -911,13 +895,15 @@ class basic_json is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then added as singed 8-bit integer. - If no subtype is given, the bin family (bin8, bin16, bin32) is used. - - BSON + - BSON - If a subtype is given, it is used and added as unsigned 8-bit integer. - If no subtype is given, the generic binary subtype 0x00 is used. @sa @ref binary_array -- create a binary array + + @since version 3.8.0 */ - using internal_binary_t = nlohmann::detail::wrapped_binary_t; + using binary_t = nlohmann::detail::wrapped_binary_t; /// @} private: @@ -978,7 +964,7 @@ class basic_json /// string (stored with pointer to save storage) string_t* string; /// binary (stored with pointer to save storage) - internal_binary_t* binary; + binary_t* binary; /// boolean boolean_t boolean; /// number (integer) @@ -1023,7 +1009,7 @@ class basic_json case value_t::binary: { - binary = create(); + binary = create(); break; } @@ -1106,27 +1092,27 @@ class basic_json } /// constructor for binary arrays - json_value(const binary_t& value) + json_value(const typename binary_t::container_type& value) { - binary = create(value); + binary = create(value); } /// constructor for rvalue binary arrays - json_value(binary_t&& value) + json_value(typename binary_t::container_type&& value) { - binary = create(std::move(value)); + binary = create(std::move(value)); } /// constructor for binary arrays (internal type) - json_value(const internal_binary_t& value) + json_value(const binary_t& value) { - binary = create(value); + binary = create(value); } /// constructor for rvalue binary arrays (internal type) - json_value(internal_binary_t&& value) + json_value(binary_t&& value) { - binary = create(std::move(value)); + binary = create(std::move(value)); } void destroy(value_t t) noexcept @@ -1206,7 +1192,7 @@ class basic_json case value_t::binary: { - AllocatorType alloc; + AllocatorType alloc; std::allocator_traits::destroy(alloc, binary); std::allocator_traits::deallocate(alloc, binary, 1); break; @@ -1492,7 +1478,7 @@ class basic_json using other_string_t = typename BasicJsonType::string_t; using other_object_t = typename BasicJsonType::object_t; using other_array_t = typename BasicJsonType::array_t; - using other_binary_t = typename BasicJsonType::internal_binary_t; + using other_binary_t = typename BasicJsonType::binary_t; switch (val.type()) { @@ -1686,7 +1672,7 @@ class basic_json @since version 3.8.0 */ JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(const binary_t& init) + static basic_json binary_array(const typename binary_t::container_type& init) { auto res = basic_json(); res.m_type = value_t::binary; @@ -1695,11 +1681,11 @@ class basic_json } JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(const binary_t& init, std::uint8_t subtype) + static basic_json binary_array(const typename binary_t::container_type& init, std::uint8_t subtype) { auto res = basic_json(); res.m_type = value_t::binary; - res.m_value = internal_binary_t(init, subtype); + res.m_value = binary_t(init, subtype); return res; } @@ -1731,7 +1717,7 @@ class basic_json @since version 3.8.0 */ JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(binary_t&& init) + static basic_json binary_array(typename binary_t::container_type&& init) { auto res = basic_json(); res.m_type = value_t::binary; @@ -1740,11 +1726,11 @@ class basic_json } JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(binary_t&& init, std::uint8_t subtype) + static basic_json binary_array(typename binary_t::container_type&& init, std::uint8_t subtype) { auto res = basic_json(); res.m_type = value_t::binary; - res.m_value = internal_binary_t(std::move(init), subtype); + res.m_value = binary_t(std::move(init), subtype); return res; } @@ -2794,13 +2780,13 @@ class basic_json } /// get a pointer to the value (binary) - internal_binary_t* get_impl_ptr(internal_binary_t* /*unused*/) noexcept + binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept { return is_binary() ? m_value.binary : nullptr; } /// get a pointer to the value (binary) - constexpr const internal_binary_t* get_impl_ptr(const internal_binary_t* /*unused*/) const noexcept + constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept { return is_binary() ? m_value.binary : nullptr; } @@ -3230,6 +3216,36 @@ class basic_json return get(); } + /*! + @return reference to the binary value + + @throw type_error.302 if the value is not binary + + @sa @ref is_binary() to check if the value is binary + + @since version 3.8.0 + */ + binary_t& get_binary() + { + if (not is_binary()) + { + JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()))); + } + + return *get_ptr(); + } + + /// @copydoc get_binary() + const binary_t& get_binary() const + { + if (not is_binary()) + { + JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()))); + } + + return *get_ptr(); + } + /// @} @@ -3852,118 +3868,6 @@ class basic_json return value(ptr, string_t(default_value)); } - /*! - @brief return the binary subtype - - Returns the numerical subtype of the JSON value, if the JSON value is of - type "binary", and it has a subtype. If it does not have a subtype (or the - object is not of type binary) this function will return size_t(-1) as a - sentinel value. - - @return the numerical subtype of the binary JSON value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - std::size_t get_subtype() const noexcept - { - if (is_binary() and m_value.binary->has_subtype) - { - return m_value.binary->subtype; - } - - return std::size_t(-1); - } - - /*! - @brief sets the binary subtype - - Sets the binary subtype of the JSON value, also flags a binary JSON value as - having a subtype, which has implications for serialization to msgpack (will - prefer ext file formats over bin). If the JSON value is not a binary value, - this function does nothing. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref get_subtype() -- return the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - - void set_subtype(std::uint8_t subtype) noexcept - { - if (is_binary()) - { - m_value.binary->set_subtype(subtype); - } - } - - /*! - @brief clears the binary subtype - - Clears the binary subtype of the JSON value, also flags a binary JSON value - as not having a subtype, which has implications for serialization to msgpack - (will prefer bin file formats over ext). If the JSON value is not a binary - value, this function does nothing. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref get_subtype() -- return the binary subtype - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void clear_subtype() noexcept - { - if (is_binary()) - { - m_value.binary->clear_subtype(); - } - } - - /*! - @brief return whether or not the binary subtype has a value - - Returns whether or not the binary subtype has a value. - - @return whether or not the binary subtype has a value. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref get_subtype() -- return the binary subtype - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - - @since version 3.8.0 - */ - bool has_subtype() const noexcept - { - return is_binary() and m_value.binary->has_subtype(); - } - /*! @brief access the first element @@ -4133,7 +4037,7 @@ class basic_json } else if (is_binary()) { - AllocatorType alloc; + AllocatorType alloc; std::allocator_traits::destroy(alloc, m_value.binary); std::allocator_traits::deallocate(alloc, m_value.binary, 1); m_value.binary = nullptr; @@ -4247,7 +4151,7 @@ class basic_json } else if (is_binary()) { - AllocatorType alloc; + AllocatorType alloc; std::allocator_traits::destroy(alloc, m_value.binary); std::allocator_traits::deallocate(alloc, m_value.binary, 1); m_value.binary = nullptr; @@ -6087,6 +5991,20 @@ class basic_json } } + /// @copydoc swap(binary_t) + void swap(typename binary_t::container_type& other) + { + // swap only works for strings + if (JSON_HEDLEY_LIKELY(is_binary())) + { + std::swap(*(m_value.binary), other); + } + else + { + JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); + } + } + /// @} public: diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 1a8aa14c..0033be23 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3448,7 +3448,7 @@ template ::value and not is_constructible_object_type::value and not is_constructible_string_type::value and - not std::is_same::value and + not std::is_same::value and not is_basic_json::value, int > = 0 > auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) @@ -3466,14 +3466,14 @@ void()) } template -void from_json(const BasicJsonType& j, typename BasicJsonType::internal_binary_t& bin) +void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) { if (JSON_HEDLEY_UNLIKELY(not j.is_binary())) { JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()))); } - bin = *j.template get_ptr(); + bin = *j.template get_ptr(); } template struct external_constructor { template - static void construct(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& b) + static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) { j.m_type = value_t::binary; - typename BasicJsonType::internal_binary_t value{b}; + typename BasicJsonType::binary_t value{b}; j.m_value = value; j.assert_invariant(); } template - static void construct(BasicJsonType& j, typename BasicJsonType::internal_binary_t&& b) + static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) { j.m_type = value_t::binary; - typename BasicJsonType::internal_binary_t value{std::move(b)}; + typename BasicJsonType::binary_t value{std::move(b)}; j.m_value = value; j.assert_invariant(); } @@ -4085,7 +4085,7 @@ template ::value and not is_compatible_object_type::value and not is_compatible_string_type::value and - not std::is_same::value and + not std::is_same::value and not is_basic_json::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleArrayType& arr) @@ -4094,7 +4094,7 @@ void to_json(BasicJsonType& j, const CompatibleArrayType& arr) } template -void to_json(BasicJsonType& j, const typename BasicJsonType::internal_binary_t& bin) +void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) { external_constructor::construct(j, bin); } @@ -4764,7 +4764,7 @@ struct json_sax using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; /*! @brief a null value was read @@ -4815,7 +4815,7 @@ struct json_sax @return whether parsing should proceed @note It is safe to move the passed binary. */ - virtual bool binary(internal_binary_t& val) = 0; + virtual bool binary(binary_t& val) = 0; /*! @brief the beginning of an object was read @@ -4891,7 +4891,7 @@ class json_sax_dom_parser using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; /*! @param[in, out] r reference to a JSON value that is manipulated while @@ -4945,7 +4945,7 @@ class json_sax_dom_parser return true; } - bool binary(internal_binary_t& val) + bool binary(binary_t& val) { handle_value(std::move(val)); return true; @@ -5080,7 +5080,7 @@ class json_sax_dom_callback_parser using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; using parser_callback_t = typename BasicJsonType::parser_callback_t; using parse_event_t = typename BasicJsonType::parse_event_t; @@ -5135,7 +5135,7 @@ class json_sax_dom_callback_parser return true; } - bool binary(internal_binary_t& val) + bool binary(binary_t& val) { handle_value(std::move(val)); return true; @@ -5391,7 +5391,7 @@ class json_sax_acceptor using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; bool null() { @@ -5423,7 +5423,7 @@ class json_sax_acceptor return true; } - bool binary(internal_binary_t& /*unused*/) + bool binary(binary_t& /*unused*/) { return true; } @@ -5645,7 +5645,7 @@ class binary_reader using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; using json_sax_t = SAX; public: @@ -5812,7 +5812,7 @@ class binary_reader @return `true` if the byte array was successfully parsed */ template - bool get_bson_binary(const NumberType len, internal_binary_t& result) + bool get_bson_binary(const NumberType len, binary_t& result) { if (JSON_HEDLEY_UNLIKELY(len < 0)) { @@ -5869,7 +5869,7 @@ class binary_reader case 0x05: // binary { std::int32_t len; - internal_binary_t value; + binary_t value; return get_number(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value); } @@ -6125,7 +6125,7 @@ class binary_reader case 0x5B: // Binary data (eight-byte uint64_t for n follow) case 0x5F: // Binary data (indefinite length) { - internal_binary_t b; + binary_t b; return get_cbor_binary(b) and sax->binary(b); } @@ -6455,7 +6455,7 @@ class binary_reader @return whether byte array creation completed */ - bool get_cbor_binary(internal_binary_t& result) + bool get_cbor_binary(binary_t& result) { if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary"))) { @@ -6525,7 +6525,7 @@ class binary_reader { while (get() != 0xFF) { - internal_binary_t chunk; + binary_t chunk; if (not get_cbor_binary(chunk)) { return false; @@ -6875,7 +6875,7 @@ class binary_reader case 0xD7: // fixext 8 case 0xD8: // fixext 16 { - internal_binary_t b; + binary_t b; return get_msgpack_binary(b) and sax->binary(b); } @@ -7098,7 +7098,7 @@ class binary_reader @return whether byte array creation completed */ - bool get_msgpack_binary(internal_binary_t& result) + bool get_msgpack_binary(binary_t& result) { // helper function to set the subtype auto assign_and_return_true = [&result](std::int8_t subtype) @@ -7816,7 +7816,7 @@ class binary_reader template bool get_binary(const input_format_t format, const NumberType len, - internal_binary_t& result) + binary_t& result) { bool success = true; std::generate_n(std::back_inserter(result), len, [this, &success, &format]() @@ -10089,7 +10089,7 @@ template struct internal_iterator /// iterator for JSON arrays typename BasicJsonType::array_t::iterator array_iterator {}; /// iterator for JSON binary arrays - typename BasicJsonType::binary_t::iterator binary_iterator {}; + typename BasicJsonType::binary_t::container_type::iterator binary_iterator {}; /// generic iterator for all other types primitive_iterator_t primitive_iterator {}; }; @@ -12080,7 +12080,7 @@ template class binary_writer { using string_t = typename BasicJsonType::string_t; - using internal_binary_t = typename BasicJsonType::internal_binary_t; + using binary_t = typename BasicJsonType::binary_t; public: /*! @@ -13133,7 +13133,7 @@ class binary_writer /*! @return The size of the BSON-encoded binary array @a value */ - static std::size_t calc_bson_binary_size(const typename BasicJsonType::internal_binary_t& value) + static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value) { return sizeof(std::int32_t) + value.size() + 1ul; } @@ -13161,7 +13161,7 @@ class binary_writer @brief Writes a BSON element with key @a name and binary value @a value */ void write_bson_binary(const string_t& name, - const internal_binary_t& value) + const binary_t& value) { write_bson_entry_header(name, 0x05); @@ -14789,7 +14789,7 @@ class serializer using number_float_t = typename BasicJsonType::number_float_t; using number_integer_t = typename BasicJsonType::number_integer_t; using number_unsigned_t = typename BasicJsonType::number_unsigned_t; - using binary_t = typename BasicJsonType::binary_t; + using binary_char_t = typename BasicJsonType::binary_t::value_type; static constexpr std::uint8_t UTF8_ACCEPT = 0; static constexpr std::uint8_t UTF8_REJECT = 1; @@ -15368,7 +15368,7 @@ class serializer template::value or std::is_same::value or - std::is_same::value, + std::is_same::value, int> = 0> void dump_integer(NumberType x) { @@ -15667,36 +15667,51 @@ template class wrapped_binary_t : public BinaryType { public: - using binary_t = BinaryType; + /// the type of the underlying container + using container_type = BinaryType; - wrapped_binary_t() noexcept(noexcept(binary_t())) - : binary_t() + wrapped_binary_t() noexcept(noexcept(container_type())) + : container_type() {} - wrapped_binary_t(const binary_t& b) noexcept(noexcept(binary_t(b))) - : binary_t(b) + wrapped_binary_t(const container_type& b) noexcept(noexcept(container_type(b))) + : container_type(b) {} - wrapped_binary_t(binary_t&& b) noexcept(noexcept(binary_t(std::move(b)))) - : binary_t(std::move(b)) + wrapped_binary_t(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) {} - wrapped_binary_t(const binary_t& b, - std::uint8_t subtype) noexcept(noexcept(binary_t(b))) - : binary_t(b) + wrapped_binary_t(const container_type& b, + std::uint8_t subtype) noexcept(noexcept(container_type(b))) + : container_type(b) , m_subtype(subtype) , m_has_subtype(true) {} - wrapped_binary_t(binary_t&& b, std::uint8_t subtype) noexcept(noexcept(binary_t(std::move(b)))) - : binary_t(std::move(b)) + wrapped_binary_t(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) , m_subtype(subtype) , m_has_subtype(true) {} /*! - @brief set the subtype - @param subtype subtype to set (implementation specific) + @brief sets the binary subtype + + Sets the binary subtype of the value, also flags a binary JSON value as + having a subtype, which has implications for serialization. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref subtype() -- return the binary subtype + @sa @ref clear_subtype() -- clears the binary subtype + @sa @ref has_subtype() -- returns whether or not the binary value has a + subtype + + @since version 3.8.0 */ void set_subtype(std::uint8_t subtype) noexcept { @@ -15705,8 +15720,25 @@ class wrapped_binary_t : public BinaryType } /*! - @brief get the subtype - @return subtype (implementation specific) + @brief return the binary subtype + + Returns the numerical subtype of the value if it has a subtype. If it does + not have a subtype, this function will return size_t(-1) as a sentinel + value. + + @return the numerical subtype of the binary value + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref set_subtype() -- sets the binary subtype + @sa @ref clear_subtype() -- clears the binary subtype + @sa @ref has_subtype() -- returns whether or not the binary value has a + subtype + + @since version 3.8.0 */ constexpr std::uint8_t subtype() const noexcept { @@ -15714,8 +15746,20 @@ class wrapped_binary_t : public BinaryType } /*! - @brief get whether a subtype was set - @return whether a subtype was set + @brief return whether the value has a subtype + + @return whether the value has a subtype + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref subtype() -- return the binary subtype + @sa @ref set_subtype() -- sets the binary subtype + @sa @ref clear_subtype() -- clears the binary subtype + + @since version 3.8.0 */ constexpr bool has_subtype() const noexcept { @@ -15723,7 +15767,23 @@ class wrapped_binary_t : public BinaryType } /*! - @brief clear the subtype + @brief clears the binary subtype + + Clears the binary subtype and flags the value as not having a subtype, which + has implications for serialization; for instance MessagePack will prefer the + bin family over the ext family. + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this member function never throws + exceptions. + + @sa @ref subtype() -- return the binary subtype + @sa @ref set_subtype() -- sets the binary subtype + @sa @ref has_subtype() -- returns whether or not the binary value has a + subtype + + @since version 3.8.0 */ void clear_subtype() noexcept { @@ -16553,23 +16613,7 @@ class basic_json for any access to array values, a pointer of the type `binary_t*` must be dereferenced. - @sa @ref array_t -- type for an array value - - @since version 3.8.0 - */ - using binary_t = BinaryType; - - /*! - @brief binary array with a binary type - - This type is used to store binary types internally. It wrapps the template - type `BinaryType` (@ref binary_t) and adds a subtype to allow to distinguish - different binary types from different formats. - - While @ref binary_t is used to define how binary values are stored, this - type is used to access binary values once they are parsed. - - Notes on subtypes: + #### Notes on subtypes - CBOR - Binary values are represented as byte strings. No subtypes are @@ -16580,13 +16624,15 @@ class basic_json is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then added as singed 8-bit integer. - If no subtype is given, the bin family (bin8, bin16, bin32) is used. - - BSON + - BSON - If a subtype is given, it is used and added as unsigned 8-bit integer. - If no subtype is given, the generic binary subtype 0x00 is used. @sa @ref binary_array -- create a binary array + + @since version 3.8.0 */ - using internal_binary_t = nlohmann::detail::wrapped_binary_t; + using binary_t = nlohmann::detail::wrapped_binary_t; /// @} private: @@ -16647,7 +16693,7 @@ class basic_json /// string (stored with pointer to save storage) string_t* string; /// binary (stored with pointer to save storage) - internal_binary_t* binary; + binary_t* binary; /// boolean boolean_t boolean; /// number (integer) @@ -16692,7 +16738,7 @@ class basic_json case value_t::binary: { - binary = create(); + binary = create(); break; } @@ -16775,27 +16821,27 @@ class basic_json } /// constructor for binary arrays - json_value(const binary_t& value) + json_value(const typename binary_t::container_type& value) { - binary = create(value); + binary = create(value); } /// constructor for rvalue binary arrays - json_value(binary_t&& value) + json_value(typename binary_t::container_type&& value) { - binary = create(std::move(value)); + binary = create(std::move(value)); } /// constructor for binary arrays (internal type) - json_value(const internal_binary_t& value) + json_value(const binary_t& value) { - binary = create(value); + binary = create(value); } /// constructor for rvalue binary arrays (internal type) - json_value(internal_binary_t&& value) + json_value(binary_t&& value) { - binary = create(std::move(value)); + binary = create(std::move(value)); } void destroy(value_t t) noexcept @@ -16875,7 +16921,7 @@ class basic_json case value_t::binary: { - AllocatorType alloc; + AllocatorType alloc; std::allocator_traits::destroy(alloc, binary); std::allocator_traits::deallocate(alloc, binary, 1); break; @@ -17161,7 +17207,7 @@ class basic_json using other_string_t = typename BasicJsonType::string_t; using other_object_t = typename BasicJsonType::object_t; using other_array_t = typename BasicJsonType::array_t; - using other_binary_t = typename BasicJsonType::internal_binary_t; + using other_binary_t = typename BasicJsonType::binary_t; switch (val.type()) { @@ -17355,7 +17401,7 @@ class basic_json @since version 3.8.0 */ JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(const binary_t& init) + static basic_json binary_array(const typename binary_t::container_type& init) { auto res = basic_json(); res.m_type = value_t::binary; @@ -17364,11 +17410,11 @@ class basic_json } JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(const binary_t& init, std::uint8_t subtype) + static basic_json binary_array(const typename binary_t::container_type& init, std::uint8_t subtype) { auto res = basic_json(); res.m_type = value_t::binary; - res.m_value = internal_binary_t(init, subtype); + res.m_value = binary_t(init, subtype); return res; } @@ -17400,7 +17446,7 @@ class basic_json @since version 3.8.0 */ JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(binary_t&& init) + static basic_json binary_array(typename binary_t::container_type&& init) { auto res = basic_json(); res.m_type = value_t::binary; @@ -17409,11 +17455,11 @@ class basic_json } JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json binary_array(binary_t&& init, std::uint8_t subtype) + static basic_json binary_array(typename binary_t::container_type&& init, std::uint8_t subtype) { auto res = basic_json(); res.m_type = value_t::binary; - res.m_value = internal_binary_t(std::move(init), subtype); + res.m_value = binary_t(std::move(init), subtype); return res; } @@ -18463,13 +18509,13 @@ class basic_json } /// get a pointer to the value (binary) - internal_binary_t* get_impl_ptr(internal_binary_t* /*unused*/) noexcept + binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept { return is_binary() ? m_value.binary : nullptr; } /// get a pointer to the value (binary) - constexpr const internal_binary_t* get_impl_ptr(const internal_binary_t* /*unused*/) const noexcept + constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept { return is_binary() ? m_value.binary : nullptr; } @@ -18899,6 +18945,36 @@ class basic_json return get(); } + /*! + @return reference to the binary value + + @throw type_error.302 if the value is not binary + + @sa @ref is_binary() to check if the value is binary + + @since version 3.8.0 + */ + binary_t& get_binary() + { + if (not is_binary()) + { + JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()))); + } + + return *get_ptr(); + } + + /// @copydoc get_binary() + const binary_t& get_binary() const + { + if (not is_binary()) + { + JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()))); + } + + return *get_ptr(); + } + /// @} @@ -19521,118 +19597,6 @@ class basic_json return value(ptr, string_t(default_value)); } - /*! - @brief return the binary subtype - - Returns the numerical subtype of the JSON value, if the JSON value is of - type "binary", and it has a subtype. If it does not have a subtype (or the - object is not of type binary) this function will return size_t(-1) as a - sentinel value. - - @return the numerical subtype of the binary JSON value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - std::size_t get_subtype() const noexcept - { - if (is_binary() and m_value.binary->has_subtype) - { - return m_value.binary->subtype; - } - - return std::size_t(-1); - } - - /*! - @brief sets the binary subtype - - Sets the binary subtype of the JSON value, also flags a binary JSON value as - having a subtype, which has implications for serialization to msgpack (will - prefer ext file formats over bin). If the JSON value is not a binary value, - this function does nothing. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref get_subtype() -- return the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - - void set_subtype(std::uint8_t subtype) noexcept - { - if (is_binary()) - { - m_value.binary->set_subtype(subtype); - } - } - - /*! - @brief clears the binary subtype - - Clears the binary subtype of the JSON value, also flags a binary JSON value - as not having a subtype, which has implications for serialization to msgpack - (will prefer bin file formats over ext). If the JSON value is not a binary - value, this function does nothing. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref get_subtype() -- return the binary subtype - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ - void clear_subtype() noexcept - { - if (is_binary()) - { - m_value.binary->clear_subtype(); - } - } - - /*! - @brief return whether or not the binary subtype has a value - - Returns whether or not the binary subtype has a value. - - @return whether or not the binary subtype has a value. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa @ref get_subtype() -- return the binary subtype - @sa @ref set_subtype() -- sets the binary subtype - @sa @ref clear_subtype() -- clears the binary subtype - - @since version 3.8.0 - */ - bool has_subtype() const noexcept - { - return is_binary() and m_value.binary->has_subtype(); - } - /*! @brief access the first element @@ -19802,7 +19766,7 @@ class basic_json } else if (is_binary()) { - AllocatorType alloc; + AllocatorType alloc; std::allocator_traits::destroy(alloc, m_value.binary); std::allocator_traits::deallocate(alloc, m_value.binary, 1); m_value.binary = nullptr; @@ -19916,7 +19880,7 @@ class basic_json } else if (is_binary()) { - AllocatorType alloc; + AllocatorType alloc; std::allocator_traits::destroy(alloc, m_value.binary); std::allocator_traits::deallocate(alloc, m_value.binary, 1); m_value.binary = nullptr; @@ -21756,6 +21720,20 @@ class basic_json } } + /// @copydoc swap(binary_t) + void swap(typename binary_t::container_type& other) + { + // swap only works for strings + if (JSON_HEDLEY_LIKELY(is_binary())) + { + std::swap(*(m_value.binary), other); + } + else + { + JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()))); + } + } + /// @} public: diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index f8eb6112..d43099f2 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -77,7 +77,7 @@ class SaxEventLogger return true; } - bool binary(json::internal_binary_t& val) + bool binary(json::binary_t& val) { std::string binary_contents = "binary("; std::string comma_space = ""; @@ -183,7 +183,7 @@ class SaxCountdown : public nlohmann::json::json_sax_t return events_left-- > 0; } - bool binary(json::internal_binary_t&) override + bool binary(json::binary_t&) override { return events_left-- > 0; } diff --git a/test/src/unit-constructor1.cpp b/test/src/unit-constructor1.cpp index 742bdcd9..81fca64a 100644 --- a/test/src/unit-constructor1.cpp +++ b/test/src/unit-constructor1.cpp @@ -485,14 +485,14 @@ TEST_CASE("constructors") { SECTION("empty binary") { - json::internal_binary_t b{}; + json::binary_t b{}; json j(b); CHECK(j.type() == json::value_t::binary); } SECTION("filled binary") { - json::internal_binary_t b({1, 2, 3}); + json::binary_t b({1, 2, 3}); json j(b); CHECK(j.type() == json::value_t::binary); } diff --git a/test/src/unit-deserialization.cpp b/test/src/unit-deserialization.cpp index 52ea9259..15744b9e 100644 --- a/test/src/unit-deserialization.cpp +++ b/test/src/unit-deserialization.cpp @@ -76,7 +76,7 @@ struct SaxEventLogger : public nlohmann::json_sax return true; } - bool binary(json::internal_binary_t& val) override + bool binary(json::binary_t& val) override { std::string binary_contents = "binary("; std::string comma_space = ""; diff --git a/test/src/unit-modifiers.cpp b/test/src/unit-modifiers.cpp index 2349dc14..fc290162 100644 --- a/test/src/unit-modifiers.cpp +++ b/test/src/unit-modifiers.cpp @@ -968,21 +968,35 @@ TEST_CASE("modifiers") SECTION("binary_t type") { json j = json::binary_array({1, 2, 3, 4}); - json::binary_t s = {1, 2, 3, 4}; + json::binary_t s = {{5, 6, 7, 8}}; j.swap(s); - CHECK(j == json::binary_array({1, 2, 3, 4})); + CHECK(j == json::binary_array({5, 6, 7, 8})); j.swap(s); CHECK(j == json::binary_array({1, 2, 3, 4})); } - SECTION("non-string_t type") + SECTION("binary_t::container_type type") + { + json j = json::binary_array({1, 2, 3, 4}); + std::vector s = {{5, 6, 7, 8}}; + + j.swap(s); + + CHECK(j == json::binary_array({5, 6, 7, 8})); + + j.swap(s); + + CHECK(j == json::binary_array({1, 2, 3, 4})); + } + + SECTION("non-binary_t type") { json j = 17; - json::binary_t s = {1, 2, 3, 4}; + json::binary_t s = {{1, 2, 3, 4}}; CHECK_THROWS_AS(j.swap(s), json::type_error&); CHECK_THROWS_WITH(j.swap(s), "[json.exception.type_error.310] cannot use swap() with number"); diff --git a/test/src/unit-msgpack.cpp b/test/src/unit-msgpack.cpp index 40b63735..acdafaa8 100644 --- a/test/src/unit-msgpack.cpp +++ b/test/src/unit-msgpack.cpp @@ -1134,7 +1134,7 @@ TEST_CASE("MessagePack") const auto s = std::vector(N, 'x'); json j = json::binary_array(s); std::uint8_t subtype = 42; - j.set_subtype(subtype); + j.get_binary().set_subtype(subtype); // create expected byte vector std::vector expected; @@ -1209,7 +1209,7 @@ TEST_CASE("MessagePack") const auto s = std::vector(N, 'x'); json j = json::binary_array(s); std::uint8_t subtype = 42; - j.set_subtype(subtype); + j.get_binary().set_subtype(subtype); // create expected byte vector (hack: create string first) std::vector expected(N, 'x'); @@ -1245,7 +1245,7 @@ TEST_CASE("MessagePack") const auto s = std::vector(N, 'x'); json j = json::binary_array(s); std::uint8_t subtype = 42; - j.set_subtype(subtype); + j.get_binary().set_subtype(subtype); // create expected byte vector (hack: create string first) std::vector expected(N, 'x'); diff --git a/test/src/unit-pointer_access.cpp b/test/src/unit-pointer_access.cpp index 5f3f9e31..72ee1ab7 100644 --- a/test/src/unit-pointer_access.cpp +++ b/test/src/unit-pointer_access.cpp @@ -60,7 +60,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const object_t") @@ -89,7 +89,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to array_t") @@ -118,7 +118,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const array_t") @@ -147,7 +147,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to string_t") @@ -176,7 +176,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const string_t") @@ -205,7 +205,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to boolean_t") @@ -234,7 +234,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const boolean_t") @@ -263,7 +263,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to number_integer_t") @@ -292,7 +292,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() != nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const number_integer_t") @@ -321,7 +321,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() != nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to number_unsigned_t") @@ -350,7 +350,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() != nullptr); CHECK(value.get_ptr() != nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const number_unsigned_t") @@ -379,7 +379,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() != nullptr); CHECK(value.get_ptr() != nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to number_float_t") @@ -408,7 +408,7 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() != nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } SECTION("pointer access to const number_float_t") @@ -437,12 +437,12 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() != nullptr); - CHECK(value.get_ptr() == nullptr); + CHECK(value.get_ptr() == nullptr); } - SECTION("pointer access to const internal_binary_t") + SECTION("pointer access to const binary_t") { - using test_type = const json::internal_binary_t; + using test_type = const json::binary_t; const json value = json::binary_array({1, 2, 3}); // check if pointers are returned correctly @@ -466,12 +466,12 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() != nullptr); + CHECK(value.get_ptr() != nullptr); } - SECTION("pointer access to const internal_binary_t") + SECTION("pointer access to const binary_t") { - using test_type = const json::internal_binary_t; + using test_type = const json::binary_t; const json value = json::binary_array({}); // check if pointers are returned correctly @@ -495,6 +495,6 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); CHECK(value.get_ptr() == nullptr); - CHECK(value.get_ptr() != nullptr); + CHECK(value.get_ptr() != nullptr); } }