add option to process binary subtypes in CBOR

This commit is contained in:
Niels Lohmann 2021-08-06 16:41:01 +02:00
parent 51a9880022
commit 89c98dfc20
No known key found for this signature in database
GPG Key ID: 7F3CEA63AE251B69
3 changed files with 114 additions and 20 deletions

View File

@ -31,7 +31,8 @@ namespace detail
enum class cbor_tag_handler_t enum class cbor_tag_handler_t
{ {
error, ///< throw a parse_error exception in case of a tag error, ///< throw a parse_error exception in case of a tag
ignore ///< ignore tags ignore, ///< ignore tags
store ///< store tags as binary type
}; };
/*! /*!
@ -722,30 +723,31 @@ class binary_reader
case cbor_tag_handler_t::ignore: case cbor_tag_handler_t::ignore:
{ {
// ignore binary subtype
switch (current) switch (current)
{ {
case 0xD8: case 0xD8:
{ {
std::uint8_t len{}; std::uint8_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
case 0xD9: case 0xD9:
{ {
std::uint16_t len{}; std::uint16_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
case 0xDA: case 0xDA:
{ {
std::uint32_t len{}; std::uint32_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
case 0xDB: case 0xDB:
{ {
std::uint64_t len{}; std::uint64_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
default: default:
@ -754,6 +756,47 @@ class binary_reader
return parse_cbor_internal(true, tag_handler); return parse_cbor_internal(true, tag_handler);
} }
case cbor_tag_handler_t::store:
{
binary_t b;
// use binary subtype and store in binary container
switch (current)
{
case 0xD8:
{
std::uint8_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
case 0xD9:
{
std::uint16_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
case 0xDA:
{
std::uint32_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
case 0xDB:
{
std::uint64_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
default:
break;
}
get();
return get_cbor_binary(b) && sax->binary(b);
}
default: // LCOV_EXCL_LINE default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return false; // LCOV_EXCL_LINE return false; // LCOV_EXCL_LINE

View File

@ -8270,7 +8270,8 @@ namespace detail
enum class cbor_tag_handler_t enum class cbor_tag_handler_t
{ {
error, ///< throw a parse_error exception in case of a tag error, ///< throw a parse_error exception in case of a tag
ignore ///< ignore tags ignore, ///< ignore tags
store ///< store tags as binary type
}; };
/*! /*!
@ -8961,30 +8962,31 @@ class binary_reader
case cbor_tag_handler_t::ignore: case cbor_tag_handler_t::ignore:
{ {
// ignore binary subtype
switch (current) switch (current)
{ {
case 0xD8: case 0xD8:
{ {
std::uint8_t len{}; std::uint8_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
case 0xD9: case 0xD9:
{ {
std::uint16_t len{}; std::uint16_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
case 0xDA: case 0xDA:
{ {
std::uint32_t len{}; std::uint32_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
case 0xDB: case 0xDB:
{ {
std::uint64_t len{}; std::uint64_t subtype_to_ignore{};
get_number(input_format_t::cbor, len); get_number(input_format_t::cbor, subtype_to_ignore);
break; break;
} }
default: default:
@ -8993,6 +8995,47 @@ class binary_reader
return parse_cbor_internal(true, tag_handler); return parse_cbor_internal(true, tag_handler);
} }
case cbor_tag_handler_t::store:
{
binary_t b;
// use binary subtype and store in binary container
switch (current)
{
case 0xD8:
{
std::uint8_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
case 0xD9:
{
std::uint16_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
case 0xDA:
{
std::uint32_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
case 0xDB:
{
std::uint64_t subtype{};
get_number(input_format_t::cbor, subtype);
b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
break;
}
default:
break;
}
get();
return get_cbor_binary(b) && sax->binary(b);
}
default: // LCOV_EXCL_LINE default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
return false; // LCOV_EXCL_LINE return false; // LCOV_EXCL_LINE

View File

@ -2488,12 +2488,20 @@ TEST_CASE("examples from RFC 7049 Appendix A")
// 0xd8 // 0xd8
CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40}); CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40});
CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 0x42);
// 0xd9 // 0xd9
CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)) == std::vector<uint8_t> {0xd9, 0x03, 0xe8, 0x40}); CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)) == std::vector<uint8_t> {0xd9, 0x03, 0xe8, 0x40});
CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 1000);
// 0xda // 0xda
CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)) == std::vector<uint8_t> {0xda, 0x00, 0x06, 0x03, 0xe8, 0x40}); CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)) == std::vector<uint8_t> {0xda, 0x00, 0x06, 0x03, 0xe8, 0x40});
CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 394216);
// 0xdb // 0xdb
CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)) == std::vector<uint8_t> {0xdb, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x40}); CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)) == std::vector<uint8_t> {0xdb, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x40});
CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 8589934590);
} }
SECTION("arrays") SECTION("arrays")