Merge pull request #2125 from nlohmann/binary_type

Clean up implementation of binary type
This commit is contained in:
Niels Lohmann 2020-05-20 18:58:29 +02:00 committed by GitHub
commit a82c80e9af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 1425 additions and 780 deletions

View file

@ -499,7 +499,7 @@ TEST_CASE("BSON")
const auto s = std::vector<std::uint8_t>(N, 'x');
json j =
{
{ "entry", json::binary_array(s) }
{ "entry", json::binary(s, 0) }
};
std::vector<std::uint8_t> expected =
@ -529,7 +529,7 @@ TEST_CASE("BSON")
const std::vector<std::uint8_t> md5hash = {0xd7, 0x7e, 0x27, 0x54, 0xbe, 0x12, 0x37, 0xfe, 0xd6, 0x0c, 0x33, 0x98, 0x30, 0x3b, 0x8d, 0xc4};
json j =
{
{ "entry", json::binary_array(md5hash, 5) }
{ "entry", json::binary(md5hash, 5) }
};
std::vector<std::uint8_t> expected =

View file

@ -1450,7 +1450,7 @@ TEST_CASE("CBOR")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<uint8_t> expected;
@ -1484,7 +1484,7 @@ TEST_CASE("CBOR")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<uint8_t> expected;
@ -1519,7 +1519,7 @@ TEST_CASE("CBOR")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector (hack: create string first)
std::vector<uint8_t> expected(N, 'x');
@ -1552,7 +1552,7 @@ TEST_CASE("CBOR")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector (hack: create string first)
std::vector<uint8_t> expected(N, 'x');
@ -1581,8 +1581,8 @@ TEST_CASE("CBOR")
std::vector<std::uint8_t> input = {0x5F, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x43, 0xee, 0xff, 0x99, 0xFF};
auto j = json::from_cbor(input);
CHECK(j.is_binary());
auto k = json::binary_array({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});
CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict, true))
auto k = json::binary({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});
CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict))
CHECK(j == k);
}
@ -1633,7 +1633,7 @@ TEST_CASE("CBOR")
0x00, 0x00, 0x00, 0x01, 0x61
};
json j = json::from_cbor(given);
CHECK(j == json::binary_array(std::vector<uint8_t> {'a'}));
CHECK(j == json::binary(std::vector<uint8_t> {'a'}));
}
SECTION("0x7b (string)")
@ -2502,7 +2502,7 @@ TEST_CASE("examples from RFC 7049 Appendix A")
std::ifstream f_bin(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out", std::ios::binary);
std::vector<uint8_t> expected((std::istreambuf_iterator<char>(f_bin)),
std::istreambuf_iterator<char>());
CHECK(j == json::binary_array(expected));
CHECK(j == json::binary(expected));
}
SECTION("arrays")

View file

@ -77,7 +77,7 @@ class SaxEventLogger
return true;
}
bool binary(std::vector<std::uint8_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(std::vector<std::uint8_t>&) override
bool binary(json::binary_t&) override
{
return events_left-- > 0;
}

View file

@ -101,7 +101,7 @@ TEST_CASE("lexicographical comparison operators")
true, false,
{1, 2, 3}, {"one", "two", "three"},
{{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}},
json::binary_array({1, 2, 3}), json::binary_array({1, 2, 4})
json::binary({1, 2, 3}), json::binary({1, 2, 4})
};
SECTION("comparison: equal")

View file

@ -121,7 +121,7 @@ TEST_CASE("constructors")
auto t = json::value_t::binary;
json j(t);
CHECK(j.type() == t);
CHECK(j == json::binary_array({}));
CHECK(j == json::binary({}));
}
}
@ -481,6 +481,23 @@ TEST_CASE("constructors")
}
}
SECTION("create a binary (explicit)")
{
SECTION("empty binary")
{
json::binary_t b{};
json j(b);
CHECK(j.type() == json::value_t::binary);
}
SECTION("filled binary")
{
json::binary_t b({1, 2, 3});
json j(b);
CHECK(j.type() == json::value_t::binary);
}
}
SECTION("create an integer number (explicit)")
{
SECTION("uninitialized value")
@ -1465,12 +1482,12 @@ TEST_CASE("constructors")
SECTION("binary")
{
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json j_new(j.begin(), j.end());
CHECK((j == j_new));
}
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json j_new(j.cbegin(), j.cend());
CHECK((j == j_new));
}

View file

@ -94,7 +94,7 @@ TEST_CASE("other constructors and destructor")
SECTION("binary")
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json k(j);
CHECK(j == k);
}
@ -177,7 +177,7 @@ TEST_CASE("other constructors and destructor")
SECTION("binary")
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json k;
k = j;
CHECK(j == k);

View file

@ -189,7 +189,6 @@ TEST_CASE("value conversion")
}
}
SECTION("get an object (implicit)")
{
json::object_t o_reference = {{"object", json::object()},
@ -1259,6 +1258,124 @@ TEST_CASE("value conversion")
}
}
SECTION("get a binary value (explicit)")
{
json::binary_t n_reference{{1, 2, 3}};
json j(n_reference);
SECTION("binary_t")
{
json::binary_t b = j.get<json::binary_t>();
CHECK(*json(b).m_value.binary == *j.m_value.binary);
}
SECTION("get_binary()")
{
SECTION("non-const")
{
auto& b = j.get_binary();
CHECK(*json(b).m_value.binary == *j.m_value.binary);
}
SECTION("non-const")
{
const json j_const = j;
const auto& b = j_const.get_binary();
CHECK(*json(b).m_value.binary == *j.m_value.binary);
}
}
SECTION("exception in case of a non-string type")
{
json j_null(json::value_t::null);
json j_object(json::value_t::object);
json j_array(json::value_t::array);
json j_string(json::value_t::string);
json j_boolean(json::value_t::boolean);
const json j_null_const(json::value_t::null);
const json j_object_const(json::value_t::object);
const json j_array_const(json::value_t::array);
const json j_string_const(json::value_t::string);
const json j_boolean_const(json::value_t::boolean);
CHECK_THROWS_WITH_AS(j_null.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(j_object.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(j_array.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(j_string.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(j_boolean.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is boolean",
json::type_error&);
CHECK_THROWS_WITH_AS(j_null_const.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(j_object_const.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(j_array_const.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(j_string_const.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(j_boolean_const.get<json::binary_t>(),
"[json.exception.type_error.302] type must be binary, but is boolean",
json::type_error&);
CHECK_THROWS_WITH_AS(j_null.get_binary(),
"[json.exception.type_error.302] type must be binary, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(j_object.get_binary(),
"[json.exception.type_error.302] type must be binary, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(j_array.get_binary(),
"[json.exception.type_error.302] type must be binary, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(j_string.get_binary(),
"[json.exception.type_error.302] type must be binary, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(j_boolean.get_binary(),
"[json.exception.type_error.302] type must be binary, but is boolean",
json::type_error&);
CHECK_THROWS_WITH_AS(j_null_const.get_binary(),
"[json.exception.type_error.302] type must be binary, but is null",
json::type_error&);
CHECK_THROWS_WITH_AS(j_object_const.get_binary(),
"[json.exception.type_error.302] type must be binary, but is object",
json::type_error&);
CHECK_THROWS_WITH_AS(j_array_const.get_binary(),
"[json.exception.type_error.302] type must be binary, but is array",
json::type_error&);
CHECK_THROWS_WITH_AS(j_string_const.get_binary(),
"[json.exception.type_error.302] type must be binary, but is string",
json::type_error&);
CHECK_THROWS_WITH_AS(j_boolean_const.get_binary(),
"[json.exception.type_error.302] type must be binary, but is boolean",
json::type_error&);
}
}
SECTION("get a binary value (implicit)")
{
json::binary_t n_reference{{1, 2, 3}};
json j(n_reference);
SECTION("binary_t")
{
json::binary_t b = j;
CHECK(*json(b).m_value.binary == *j.m_value.binary);
}
}
SECTION("get an enum")
{
enum c_enum { value_1, value_2 };

View file

@ -76,7 +76,7 @@ struct SaxEventLogger : public nlohmann::json_sax<json>
return true;
}
bool binary(std::vector<std::uint8_t>& val) override
bool binary(json::binary_t& val) override
{
std::string binary_contents = "binary(";
std::string comma_space = "";

View file

@ -698,13 +698,13 @@ TEST_CASE("element access 1")
SECTION("binary")
{
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json::iterator it = j.erase(j.begin());
CHECK(j.type() == json::value_t::null);
CHECK(it == j.end());
}
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json::const_iterator it = j.erase(j.cbegin());
CHECK(j.type() == json::value_t::null);
CHECK(it == j.end());
@ -896,13 +896,13 @@ TEST_CASE("element access 1")
SECTION("binary")
{
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json::iterator it = j.erase(j.begin(), j.end());
CHECK(j.type() == json::value_t::null);
CHECK(it == j.end());
}
{
json j = json::binary_array({1, 2, 3});
json j = json::binary({1, 2, 3});
json::const_iterator it = j.erase(j.cbegin(), j.cend());
CHECK(j.type() == json::value_t::null);
CHECK(it == j.end());

View file

@ -261,6 +261,9 @@ TEST_CASE("object inspection")
// important test, because it yields a resize of the indent_string
// inside the dump() function
CHECK(j.dump(1024).size() == 15472);
const auto binary = json::binary({1, 2, 3}, 128);
CHECK(binary.dump(1024).size() == 2086);
}
SECTION("dump and floating-point numbers")
@ -469,7 +472,7 @@ TEST_CASE("object inspection")
SECTION("binary")
{
json j = json::binary_array({});
json j = json::binary({});
json::value_t t = j;
CHECK(t == j.type());
}

View file

@ -110,7 +110,7 @@ TEST_CASE("modifiers")
{
SECTION("empty binary")
{
json j = json::binary_array({});
json j = json::binary({});
json k = j;
j.clear();
@ -121,7 +121,7 @@ TEST_CASE("modifiers")
SECTION("filled binary")
{
json j = json::binary_array({1, 2, 3, 4, 5});
json j = json::binary({1, 2, 3, 4, 5});
json k = j;
j.clear();
@ -967,25 +967,40 @@ 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 j = json::binary({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({5, 6, 7, 8}));
j.swap(s);
CHECK(j == json::binary_array({1, 2, 3, 4}));
CHECK(j == json::binary({1, 2, 3, 4}));
}
SECTION("non-string_t type")
SECTION("binary_t::container_type type")
{
json j = json::binary({1, 2, 3, 4});
std::vector<std::uint8_t> s = {{5, 6, 7, 8}};
j.swap(s);
CHECK(j == json::binary({5, 6, 7, 8}));
j.swap(s);
CHECK(j == json::binary({1, 2, 3, 4}));
}
SECTION("non-binary_t type")
{
json j = 17;
json::binary_t s = {1, 2, 3, 4};
json::binary_t s1 = {{1, 2, 3, 4}};
std::vector<std::uint8_t> s2 = {{5, 6, 7, 8}};
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");
CHECK_THROWS_WITH_AS(j.swap(s1), "[json.exception.type_error.310] cannot use swap() with number", json::type_error);
CHECK_THROWS_WITH_AS(j.swap(s2), "[json.exception.type_error.310] cannot use swap() with number", json::type_error);
}
}
}

View file

@ -1132,9 +1132,9 @@ TEST_CASE("MessagePack")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
std::uint8_t subtype = 42;
j.set_subtype(subtype);
j.get_binary().set_subtype(subtype);
// create expected byte vector
std::vector<uint8_t> expected;
@ -1207,9 +1207,9 @@ TEST_CASE("MessagePack")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(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<uint8_t> expected(N, 'x');
@ -1243,9 +1243,9 @@ TEST_CASE("MessagePack")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(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<uint8_t> expected(N, 'x');
@ -1281,7 +1281,7 @@ TEST_CASE("MessagePack")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<std::uint8_t> expected;
@ -1319,7 +1319,7 @@ TEST_CASE("MessagePack")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector (hack: create string first)
std::vector<std::uint8_t> expected(N, 'x');
@ -1352,7 +1352,7 @@ TEST_CASE("MessagePack")
// create JSON value with string containing of N * 'x'
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector (hack: create string first)
std::vector<uint8_t> expected(N, 'x');

View file

@ -61,7 +61,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const object_t")
@ -91,7 +90,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to array_t")
@ -121,7 +119,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const array_t")
@ -151,7 +148,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to string_t")
@ -181,7 +177,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const string_t")
@ -211,7 +206,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to boolean_t")
@ -241,7 +235,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const boolean_t")
@ -271,8 +264,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to number_integer_t")
@ -302,7 +293,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const number_integer_t")
@ -332,7 +322,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to number_unsigned_t")
@ -362,7 +351,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const number_unsigned_t")
@ -392,7 +380,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to number_float_t")
@ -422,7 +409,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<json::number_float_t*>() != nullptr);
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
CHECK(value.get_ptr<json::internal_binary_t*>() == nullptr);
}
SECTION("pointer access to const number_float_t")
@ -457,20 +443,20 @@ TEST_CASE("pointer access")
SECTION("pointer access to const binary_t")
{
using test_type = const json::binary_t;
const json value = json::binary_array({});
const json value = json::binary({1, 2, 3});
// check if pointers are returned correctly
test_type* p1 = value.get_ptr<test_type*>();
CHECK(p1 == value.get_ptr<test_type*>());
//CHECK(*p1 == value.get<test_type>());
CHECK(*p1 == value.get<test_type>());
const test_type* p2 = value.get_ptr<const test_type*>();
CHECK(p2 == value.get_ptr<const test_type*>());
//CHECK(*p2 == value.get<test_type>());
CHECK(*p2 == value.get<test_type>());
const test_type* const p3 = value.get_ptr<const test_type* const>();
CHECK(p3 == value.get_ptr<const test_type* const>());
//CHECK(*p3 == value.get<test_type>());
CHECK(*p3 == value.get<test_type>());
// check if null pointers are returned correctly
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
@ -485,21 +471,21 @@ TEST_CASE("pointer access")
SECTION("pointer access to const binary_t")
{
using test_type = const json::internal_binary_t;
const json value = json::binary_array({});
using test_type = const json::binary_t;
const json value = json::binary({});
// check if pointers are returned correctly
test_type* p1 = value.get_ptr<test_type*>();
CHECK(p1 == value.get_ptr<test_type*>());
//CHECK(*p1 == value.get<test_type>());
CHECK(*p1 == value.get<test_type>());
const test_type* p2 = value.get_ptr<const test_type*>();
CHECK(p2 == value.get_ptr<const test_type*>());
//CHECK(*p2 == value.get<test_type>());
CHECK(*p2 == value.get<test_type>());
const test_type* const p3 = value.get_ptr<const test_type* const>();
CHECK(p3 == value.get_ptr<const test_type* const>());
//CHECK(*p3 == value.get<test_type>());
CHECK(*p3 == value.get<test_type>());
// check if null pointers are returned correctly
CHECK(value.get_ptr<const json::object_t*>() == nullptr);
@ -509,6 +495,6 @@ TEST_CASE("pointer access")
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_unsigned_t*>() == nullptr);
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
CHECK(value.get_ptr<const json::internal_binary_t*>() != nullptr);
CHECK(value.get_ptr<const json::binary_t*>() != nullptr);
}
}

View file

@ -1919,8 +1919,7 @@ TEST_CASE("regression tests")
j.dump(4, // Indent
' ', // Indent char
false, // Ensure ascii
json::error_handler_t::strict, // Error
true // Allow binary data
json::error_handler_t::strict // Error
)
);
}

View file

@ -209,52 +209,114 @@ TEST_CASE_TEMPLATE("serialization for extreme integer values", T, int32_t, uint3
TEST_CASE("dump with binary values")
{
SECTION("serialize_binary = false")
{
auto binary = json::binary_array({1, 2, 3, 4});
auto binary_empty = json::binary_array({});
json object = {{"key", binary}};
json array = {"value", 1, binary};
auto binary = json::binary({1, 2, 3, 4});
auto binary_empty = json::binary({});
auto binary_with_subtype = json::binary({1, 2, 3, 4}, 128);
auto binary_empty_with_subtype = json::binary({}, 128);
CHECK_THROWS_AS(binary.dump(), json::type_error);
CHECK_THROWS_AS(binary_empty.dump(), json::type_error);
CHECK_THROWS_AS(object.dump(), json::type_error);
CHECK_THROWS_AS(array.dump(), json::type_error);
CHECK_THROWS_WITH(binary.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
CHECK_THROWS_WITH(binary_empty.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
CHECK_THROWS_WITH(object.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
CHECK_THROWS_WITH(array.dump(), "[json.exception.type_error.317] cannot serialize binary data to text JSON");
json object = {{"key", binary}};
json object_empty = {{"key", binary_empty}};
json object_with_subtype = {{"key", binary_with_subtype}};
json object_empty_with_subtype = {{"key", binary_empty_with_subtype}};
json array = {"value", 1, binary};
json array_empty = {"value", 1, binary_empty};
json array_with_subtype = {"value", 1, binary_with_subtype};
json array_empty_with_subtype = {"value", 1, binary_empty_with_subtype};
SECTION("normal")
{
CHECK(binary.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":null}");
CHECK(binary_empty.dump() == "{\"bytes\":[],\"subtype\":null}");
CHECK(binary_with_subtype.dump() == "{\"bytes\":[1,2,3,4],\"subtype\":128}");
CHECK(binary_empty_with_subtype.dump() == "{\"bytes\":[],\"subtype\":128}");
CHECK(object.dump() == "{\"key\":{\"bytes\":[1,2,3,4],\"subtype\":null}}");
CHECK(object_empty.dump() == "{\"key\":{\"bytes\":[],\"subtype\":null}}");
CHECK(object_with_subtype.dump() == "{\"key\":{\"bytes\":[1,2,3,4],\"subtype\":128}}");
CHECK(object_empty_with_subtype.dump() == "{\"key\":{\"bytes\":[],\"subtype\":128}}");
CHECK(array.dump() == "[\"value\",1,{\"bytes\":[1,2,3,4],\"subtype\":null}]");
CHECK(array_empty.dump() == "[\"value\",1,{\"bytes\":[],\"subtype\":null}]");
CHECK(array_with_subtype.dump() == "[\"value\",1,{\"bytes\":[1,2,3,4],\"subtype\":128}]");
CHECK(array_empty_with_subtype.dump() == "[\"value\",1,{\"bytes\":[],\"subtype\":128}]");
}
SECTION("serialize_binary = true")
SECTION("pretty-printed")
{
auto binary = json::binary_array({1, 2, 3, 4});
auto binary_empty = json::binary_array({});
json object = {{"key", binary}};
json array = {"value", 1, binary};
CHECK(binary.dump(-1, ' ', false, json::error_handler_t::strict, true) == "b[1,2,3,4]");
CHECK(binary_empty.dump(-1, ' ', false, json::error_handler_t::strict, true) == "b[]");
CHECK(object.dump(-1, ' ', false, json::error_handler_t::strict, true) == "{\"key\":b[1,2,3,4]}");
CHECK(array.dump(-1, ' ', false, json::error_handler_t::strict, true) == "[\"value\",1,b[1,2,3,4]]");
}
SECTION("serialize_binary = true, pretty-printed")
{
auto binary = json::binary_array({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20});
auto binary_empty = json::binary_array({});
json object = {{"key", binary}};
json array = {"value", 1, binary};
CHECK(binary.dump(4, ' ', false, json::error_handler_t::strict, true) == "b[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]");
CHECK(binary_empty.dump(4, ' ', false, json::error_handler_t::strict, true) == "b[]");
CHECK(object.dump(4, ' ', false, json::error_handler_t::strict, true) == "{\n"
" \"key\": b[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]\n"
CHECK(binary.dump(4) == "{\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
"}");
CHECK(array.dump(4, ' ', false, json::error_handler_t::strict, true) == "[\n"
CHECK(binary_empty.dump(4) == "{\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
"}");
CHECK(binary_with_subtype.dump(4) == "{\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
"}");
CHECK(binary_empty_with_subtype.dump(4) == "{\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
"}");
CHECK(object.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
" }\n"
"}");
CHECK(object_empty.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
" }\n"
"}");
CHECK(object_with_subtype.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
" }\n"
"}");
CHECK(object_empty_with_subtype.dump(4) == "{\n"
" \"key\": {\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
" }\n"
"}");
CHECK(array.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" b[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]\n"
" {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": null\n"
" }\n"
"]");
CHECK(array_empty.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [],\n"
" \"subtype\": null\n"
" }\n"
"]");
CHECK(array_with_subtype.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [1, 2, 3, 4],\n"
" \"subtype\": 128\n"
" }\n"
"]");
CHECK(array_empty_with_subtype.dump(4) == "[\n"
" \"value\",\n"
" 1,\n"
" {\n"
" \"bytes\": [],\n"
" \"subtype\": 128\n"
" }\n"
"]");
}
}

View file

@ -921,7 +921,7 @@ TEST_CASE("UBJSON")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<std::uint8_t> expected;
@ -972,7 +972,7 @@ TEST_CASE("UBJSON")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<uint8_t> expected;
@ -1012,7 +1012,7 @@ TEST_CASE("UBJSON")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<std::uint8_t> expected(N + 7, 'x');
@ -1049,7 +1049,7 @@ TEST_CASE("UBJSON")
// create JSON value with byte array containing of N * 'x'
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
// create expected byte vector
std::vector<std::uint8_t> expected(N + 9, 'x');
@ -1081,7 +1081,7 @@ TEST_CASE("UBJSON")
{
const std::size_t N = 10;
const auto s = std::vector<std::uint8_t>(N, 'x');
json j = json::binary_array(s);
json j = json::binary(s);
SECTION("No Count No Type")
{

View file

@ -763,6 +763,16 @@ TEST_CASE("different basic_json types conversions")
CHECK(cj == "forty-two");
}
SECTION("binary")
{
json j = json::binary({1, 2, 3}, 42);
custom_json cj = j;
CHECK(cj.get_binary().subtype() == 42);
std::vector<std::uint8_t> cv = cj.get_binary();
std::vector<std::uint8_t> v = j.get_binary();
CHECK(cv == v);
}
SECTION("object")
{
json j = {{"forty", "two"}};