mirror of
https://github.com/nlohmann/json.git
synced 2026-07-21 19:23:03 +04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ebb3abba41 | |||
| 3565f40229 |
@@ -1846,6 +1846,29 @@ class binary_reader
|
||||
return get_ubjson_value(get_char ? get_ignore_noop() : current);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief reject a negative UBJSON/BJData string length
|
||||
|
||||
String and key lengths are written with signed integer markers (i, I, l,
|
||||
L). A negative value is malformed; without this check get_string() would
|
||||
silently treat it as an empty string and leave the following bytes to be
|
||||
misread as the next value. This mirrors the non-negative check the
|
||||
optimized-container count path already performs in get_ubjson_size_value.
|
||||
|
||||
@param[in] len the string length read from the input
|
||||
@return whether the length is valid (non-negative)
|
||||
*/
|
||||
template<typename NumberType>
|
||||
bool check_ubjson_string_length(const NumberType len)
|
||||
{
|
||||
if (JSON_HEDLEY_UNLIKELY(len < 0))
|
||||
{
|
||||
return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
|
||||
exception_message(input_format, "string length must not be negative", "string"), nullptr));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief reads a UBJSON string
|
||||
|
||||
@@ -1883,25 +1906,25 @@ class binary_reader
|
||||
case 'i':
|
||||
{
|
||||
std::int8_t len{};
|
||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
||||
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||
}
|
||||
|
||||
case 'I':
|
||||
{
|
||||
std::int16_t len{};
|
||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
||||
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
std::int32_t len{};
|
||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
||||
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||
}
|
||||
|
||||
case 'L':
|
||||
{
|
||||
std::int64_t len{};
|
||||
return get_number(input_format, len) && get_string(input_format, len, result);
|
||||
return get_number(input_format, len) && check_ubjson_string_length(len) && get_string(input_format, len, result);
|
||||
}
|
||||
|
||||
case 'u':
|
||||
|
||||
@@ -42,7 +42,7 @@ enum class bjdata_version_t
|
||||
/*!
|
||||
@brief serialization to CBOR and MessagePack values
|
||||
*/
|
||||
template<typename BasicJsonType, typename CharType>
|
||||
template<typename BasicJsonType, typename CharType, typename OutputSinkType = output_adapter_sink<CharType>>
|
||||
class binary_writer
|
||||
{
|
||||
using string_t = typename BasicJsonType::string_t;
|
||||
@@ -53,12 +53,25 @@ class binary_writer
|
||||
/*!
|
||||
@brief create a binary writer
|
||||
|
||||
@param[in] sink output sink to write to (a value-type sink such as
|
||||
output_vector_sink, or output_adapter_sink wrapping a
|
||||
type-erased output adapter)
|
||||
*/
|
||||
explicit binary_writer(OutputSinkType sink) : oa(std::move(sink))
|
||||
{}
|
||||
|
||||
/*!
|
||||
@brief create a binary writer from a type-erased output adapter
|
||||
|
||||
Convenience constructor for the default (output_adapter_sink) sink so the
|
||||
`output_adapter`-based overloads keep constructing the writer directly from
|
||||
an adapter. Only participates in overload resolution when the sink can be
|
||||
built from an adapter.
|
||||
|
||||
@param[in] adapter output adapter to write to
|
||||
*/
|
||||
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
|
||||
{
|
||||
JSON_ASSERT(oa);
|
||||
}
|
||||
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(OutputSinkType(std::move(adapter)))
|
||||
{}
|
||||
|
||||
/*!
|
||||
@param[in] j JSON value to serialize
|
||||
@@ -99,15 +112,15 @@ class binary_writer
|
||||
{
|
||||
case value_t::null:
|
||||
{
|
||||
oa->write_character(to_char_type(0xF6));
|
||||
oa.write_character(to_char_type(0xF6));
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::boolean:
|
||||
{
|
||||
oa->write_character(j.m_data.m_value.boolean
|
||||
? to_char_type(0xF5)
|
||||
: to_char_type(0xF4));
|
||||
oa.write_character(j.m_data.m_value.boolean
|
||||
? to_char_type(0xF5)
|
||||
: to_char_type(0xF4));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -124,22 +137,22 @@ class binary_writer
|
||||
}
|
||||
else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x18));
|
||||
oa.write_character(to_char_type(0x18));
|
||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x19));
|
||||
oa.write_character(to_char_type(0x19));
|
||||
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x1A));
|
||||
oa.write_character(to_char_type(0x1A));
|
||||
write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else
|
||||
{
|
||||
oa->write_character(to_char_type(0x1B));
|
||||
oa.write_character(to_char_type(0x1B));
|
||||
write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
}
|
||||
@@ -154,22 +167,22 @@ class binary_writer
|
||||
}
|
||||
else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x38));
|
||||
oa.write_character(to_char_type(0x38));
|
||||
write_number(static_cast<std::uint8_t>(positive_number));
|
||||
}
|
||||
else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x39));
|
||||
oa.write_character(to_char_type(0x39));
|
||||
write_number(static_cast<std::uint16_t>(positive_number));
|
||||
}
|
||||
else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x3A));
|
||||
oa.write_character(to_char_type(0x3A));
|
||||
write_number(static_cast<std::uint32_t>(positive_number));
|
||||
}
|
||||
else
|
||||
{
|
||||
oa->write_character(to_char_type(0x3B));
|
||||
oa.write_character(to_char_type(0x3B));
|
||||
write_number(static_cast<std::uint64_t>(positive_number));
|
||||
}
|
||||
}
|
||||
@@ -184,22 +197,22 @@ class binary_writer
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x18));
|
||||
oa.write_character(to_char_type(0x18));
|
||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x19));
|
||||
oa.write_character(to_char_type(0x19));
|
||||
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x1A));
|
||||
oa.write_character(to_char_type(0x1A));
|
||||
write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
|
||||
}
|
||||
else
|
||||
{
|
||||
oa->write_character(to_char_type(0x1B));
|
||||
oa.write_character(to_char_type(0x1B));
|
||||
write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
|
||||
}
|
||||
break;
|
||||
@@ -210,16 +223,16 @@ class binary_writer
|
||||
if (std::isnan(j.m_data.m_value.number_float))
|
||||
{
|
||||
// NaN is 0xf97e00 in CBOR
|
||||
oa->write_character(to_char_type(0xF9));
|
||||
oa->write_character(to_char_type(0x7E));
|
||||
oa->write_character(to_char_type(0x00));
|
||||
oa.write_character(to_char_type(0xF9));
|
||||
oa.write_character(to_char_type(0x7E));
|
||||
oa.write_character(to_char_type(0x00));
|
||||
}
|
||||
else if (std::isinf(j.m_data.m_value.number_float))
|
||||
{
|
||||
// Infinity is 0xf97c00, -Infinity is 0xf9fc00
|
||||
oa->write_character(to_char_type(0xf9));
|
||||
oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
|
||||
oa->write_character(to_char_type(0x00));
|
||||
oa.write_character(to_char_type(0xf9));
|
||||
oa.write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
|
||||
oa.write_character(to_char_type(0x00));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -238,31 +251,31 @@ class binary_writer
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x78));
|
||||
oa.write_character(to_char_type(0x78));
|
||||
write_number(static_cast<std::uint8_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x79));
|
||||
oa.write_character(to_char_type(0x79));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x7A));
|
||||
oa.write_character(to_char_type(0x7A));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x7B));
|
||||
oa.write_character(to_char_type(0x7B));
|
||||
write_number(static_cast<std::uint64_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
// step 2: write the string
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -276,23 +289,23 @@ class binary_writer
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x98));
|
||||
oa.write_character(to_char_type(0x98));
|
||||
write_number(static_cast<std::uint8_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x99));
|
||||
oa.write_character(to_char_type(0x99));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x9A));
|
||||
oa.write_character(to_char_type(0x9A));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x9B));
|
||||
oa.write_character(to_char_type(0x9B));
|
||||
write_number(static_cast<std::uint64_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
@@ -339,31 +352,31 @@ class binary_writer
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x58));
|
||||
oa.write_character(to_char_type(0x58));
|
||||
write_number(static_cast<std::uint8_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x59));
|
||||
oa.write_character(to_char_type(0x59));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x5A));
|
||||
oa.write_character(to_char_type(0x5A));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0x5B));
|
||||
oa.write_character(to_char_type(0x5B));
|
||||
write_number(static_cast<std::uint64_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
// step 2: write each element
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
N);
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
N);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -378,23 +391,23 @@ class binary_writer
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0xB8));
|
||||
oa.write_character(to_char_type(0xB8));
|
||||
write_number(static_cast<std::uint8_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0xB9));
|
||||
oa.write_character(to_char_type(0xB9));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0xBA));
|
||||
oa.write_character(to_char_type(0xBA));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
||||
{
|
||||
oa->write_character(to_char_type(0xBB));
|
||||
oa.write_character(to_char_type(0xBB));
|
||||
write_number(static_cast<std::uint64_t>(N));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
@@ -423,15 +436,15 @@ class binary_writer
|
||||
{
|
||||
case value_t::null: // nil
|
||||
{
|
||||
oa->write_character(to_char_type(0xC0));
|
||||
oa.write_character(to_char_type(0xC0));
|
||||
break;
|
||||
}
|
||||
|
||||
case value_t::boolean: // true and false
|
||||
{
|
||||
oa->write_character(j.m_data.m_value.boolean
|
||||
? to_char_type(0xC3)
|
||||
: to_char_type(0xC2));
|
||||
oa.write_character(j.m_data.m_value.boolean
|
||||
? to_char_type(0xC3)
|
||||
: to_char_type(0xC2));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -450,25 +463,25 @@ class binary_writer
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
// uint 8
|
||||
oa->write_character(to_char_type(0xCC));
|
||||
oa.write_character(to_char_type(0xCC));
|
||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
// uint 16
|
||||
oa->write_character(to_char_type(0xCD));
|
||||
oa.write_character(to_char_type(0xCD));
|
||||
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
// uint 32
|
||||
oa->write_character(to_char_type(0xCE));
|
||||
oa.write_character(to_char_type(0xCE));
|
||||
write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
|
||||
{
|
||||
// uint 64
|
||||
oa->write_character(to_char_type(0xCF));
|
||||
oa.write_character(to_char_type(0xCF));
|
||||
write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
}
|
||||
@@ -483,28 +496,28 @@ class binary_writer
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
||||
{
|
||||
// int 8
|
||||
oa->write_character(to_char_type(0xD0));
|
||||
oa.write_character(to_char_type(0xD0));
|
||||
write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
||||
{
|
||||
// int 16
|
||||
oa->write_character(to_char_type(0xD1));
|
||||
oa.write_character(to_char_type(0xD1));
|
||||
write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
||||
{
|
||||
// int 32
|
||||
oa->write_character(to_char_type(0xD2));
|
||||
oa.write_character(to_char_type(0xD2));
|
||||
write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
|
||||
j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
||||
{
|
||||
// int 64
|
||||
oa->write_character(to_char_type(0xD3));
|
||||
oa.write_character(to_char_type(0xD3));
|
||||
write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
}
|
||||
@@ -521,25 +534,25 @@ class binary_writer
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
// uint 8
|
||||
oa->write_character(to_char_type(0xCC));
|
||||
oa.write_character(to_char_type(0xCC));
|
||||
write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
// uint 16
|
||||
oa->write_character(to_char_type(0xCD));
|
||||
oa.write_character(to_char_type(0xCD));
|
||||
write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
// uint 32
|
||||
oa->write_character(to_char_type(0xCE));
|
||||
oa.write_character(to_char_type(0xCE));
|
||||
write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
|
||||
{
|
||||
// uint 64
|
||||
oa->write_character(to_char_type(0xCF));
|
||||
oa.write_character(to_char_type(0xCF));
|
||||
write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
|
||||
}
|
||||
break;
|
||||
@@ -563,26 +576,26 @@ class binary_writer
|
||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||
{
|
||||
// str 8
|
||||
oa->write_character(to_char_type(0xD9));
|
||||
oa.write_character(to_char_type(0xD9));
|
||||
write_number(static_cast<std::uint8_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
// str 16
|
||||
oa->write_character(to_char_type(0xDA));
|
||||
oa.write_character(to_char_type(0xDA));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
// str 32
|
||||
oa->write_character(to_char_type(0xDB));
|
||||
oa.write_character(to_char_type(0xDB));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
|
||||
// step 2: write the string
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -598,13 +611,13 @@ class binary_writer
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
// array 16
|
||||
oa->write_character(to_char_type(0xDC));
|
||||
oa.write_character(to_char_type(0xDC));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
// array 32
|
||||
oa->write_character(to_char_type(0xDD));
|
||||
oa.write_character(to_char_type(0xDD));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
|
||||
@@ -660,7 +673,7 @@ class binary_writer
|
||||
fixed = false;
|
||||
}
|
||||
|
||||
oa->write_character(to_char_type(output_type));
|
||||
oa.write_character(to_char_type(output_type));
|
||||
if (!fixed)
|
||||
{
|
||||
write_number(static_cast<std::uint8_t>(N));
|
||||
@@ -672,7 +685,7 @@ class binary_writer
|
||||
? 0xC8 // ext 16
|
||||
: 0xC5; // bin 16
|
||||
|
||||
oa->write_character(to_char_type(output_type));
|
||||
oa.write_character(to_char_type(output_type));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
@@ -681,7 +694,7 @@ class binary_writer
|
||||
? 0xC9 // ext 32
|
||||
: 0xC6; // bin 32
|
||||
|
||||
oa->write_character(to_char_type(output_type));
|
||||
oa.write_character(to_char_type(output_type));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
|
||||
@@ -692,9 +705,9 @@ class binary_writer
|
||||
}
|
||||
|
||||
// step 2: write the byte string
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
N);
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
N);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -711,13 +724,13 @@ class binary_writer
|
||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||
{
|
||||
// map 16
|
||||
oa->write_character(to_char_type(0xDE));
|
||||
oa.write_character(to_char_type(0xDE));
|
||||
write_number(static_cast<std::uint16_t>(N));
|
||||
}
|
||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||
{
|
||||
// map 32
|
||||
oa->write_character(to_char_type(0xDF));
|
||||
oa.write_character(to_char_type(0xDF));
|
||||
write_number(static_cast<std::uint32_t>(N));
|
||||
}
|
||||
|
||||
@@ -756,7 +769,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('Z'));
|
||||
oa.write_character(to_char_type('Z'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -765,9 +778,9 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(j.m_data.m_value.boolean
|
||||
? to_char_type('T')
|
||||
: to_char_type('F'));
|
||||
oa.write_character(j.m_data.m_value.boolean
|
||||
? to_char_type('T')
|
||||
: to_char_type('F'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -794,12 +807,12 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('S'));
|
||||
oa.write_character(to_char_type('S'));
|
||||
}
|
||||
write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
|
||||
j.m_data.m_value.string->size());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -807,7 +820,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('['));
|
||||
oa.write_character(to_char_type('['));
|
||||
}
|
||||
|
||||
bool prefix_required = true;
|
||||
@@ -826,14 +839,14 @@ class binary_writer
|
||||
if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
|
||||
{
|
||||
prefix_required = false;
|
||||
oa->write_character(to_char_type('$'));
|
||||
oa->write_character(first_prefix);
|
||||
oa.write_character(to_char_type('$'));
|
||||
oa.write_character(first_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_count)
|
||||
{
|
||||
oa->write_character(to_char_type('#'));
|
||||
oa.write_character(to_char_type('#'));
|
||||
write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
|
||||
}
|
||||
|
||||
@@ -844,7 +857,7 @@ class binary_writer
|
||||
|
||||
if (!use_count)
|
||||
{
|
||||
oa->write_character(to_char_type(']'));
|
||||
oa.write_character(to_char_type(']'));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -854,40 +867,40 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('['));
|
||||
oa.write_character(to_char_type('['));
|
||||
}
|
||||
|
||||
if (use_type && (bjdata_draft3 || !j.m_data.m_value.binary->empty()))
|
||||
{
|
||||
JSON_ASSERT(use_count);
|
||||
oa->write_character(to_char_type('$'));
|
||||
oa->write_character(bjdata_draft3 ? 'B' : 'U');
|
||||
oa.write_character(to_char_type('$'));
|
||||
oa.write_character(bjdata_draft3 ? 'B' : 'U');
|
||||
}
|
||||
|
||||
if (use_count)
|
||||
{
|
||||
oa->write_character(to_char_type('#'));
|
||||
oa.write_character(to_char_type('#'));
|
||||
write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
|
||||
}
|
||||
|
||||
if (use_type)
|
||||
{
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
j.m_data.m_value.binary->size());
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
|
||||
j.m_data.m_value.binary->size());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
|
||||
{
|
||||
oa->write_character(to_char_type(bjdata_draft3 ? 'B' : 'U'));
|
||||
oa->write_character(to_char_type(j.m_data.m_value.binary->data()[i]));
|
||||
oa.write_character(to_char_type(bjdata_draft3 ? 'B' : 'U'));
|
||||
oa.write_character(to_char_type(j.m_data.m_value.binary->data()[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_count)
|
||||
{
|
||||
oa->write_character(to_char_type(']'));
|
||||
oa.write_character(to_char_type(']'));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -905,7 +918,7 @@ class binary_writer
|
||||
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('{'));
|
||||
oa.write_character(to_char_type('{'));
|
||||
}
|
||||
|
||||
bool prefix_required = true;
|
||||
@@ -924,29 +937,29 @@ class binary_writer
|
||||
if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
|
||||
{
|
||||
prefix_required = false;
|
||||
oa->write_character(to_char_type('$'));
|
||||
oa->write_character(first_prefix);
|
||||
oa.write_character(to_char_type('$'));
|
||||
oa.write_character(first_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_count)
|
||||
{
|
||||
oa->write_character(to_char_type('#'));
|
||||
oa.write_character(to_char_type('#'));
|
||||
write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
|
||||
}
|
||||
|
||||
for (const auto& el : *j.m_data.m_value.object)
|
||||
{
|
||||
write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(el.first.c_str()),
|
||||
el.first.size());
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(el.first.c_str()),
|
||||
el.first.size());
|
||||
write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata, bjdata_version);
|
||||
}
|
||||
|
||||
if (!use_count)
|
||||
{
|
||||
oa->write_character(to_char_type('}'));
|
||||
oa.write_character(to_char_type('}'));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -985,10 +998,10 @@ class binary_writer
|
||||
void write_bson_entry_header(const string_t& name,
|
||||
const std::uint8_t element_type)
|
||||
{
|
||||
oa->write_character(to_char_type(element_type)); // boolean
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(name.c_str()),
|
||||
name.size() + 1u);
|
||||
oa.write_character(to_char_type(element_type)); // boolean
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(name.c_str()),
|
||||
name.size() + 1u);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -998,7 +1011,7 @@ class binary_writer
|
||||
const bool value)
|
||||
{
|
||||
write_bson_entry_header(name, 0x08);
|
||||
oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
|
||||
oa.write_character(value ? to_char_type(0x01) : to_char_type(0x00));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1028,9 +1041,9 @@ class binary_writer
|
||||
write_bson_entry_header(name, 0x02);
|
||||
|
||||
write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
|
||||
oa->write_characters(
|
||||
reinterpret_cast<const CharType*>(value.c_str()),
|
||||
value.size() + 1);
|
||||
oa.write_characters(
|
||||
reinterpret_cast<const CharType*>(value.c_str()),
|
||||
value.size() + 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1151,7 +1164,7 @@ class binary_writer
|
||||
write_bson_element(std::to_string(array_index++), el);
|
||||
}
|
||||
|
||||
oa->write_character(to_char_type(0x00));
|
||||
oa.write_character(to_char_type(0x00));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1165,7 +1178,7 @@ class binary_writer
|
||||
write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
|
||||
write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
|
||||
|
||||
oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
|
||||
oa.write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -1291,7 +1304,7 @@ class binary_writer
|
||||
write_bson_element(el.first, el.second);
|
||||
}
|
||||
|
||||
oa->write_character(to_char_type(0x00));
|
||||
oa.write_character(to_char_type(0x00));
|
||||
}
|
||||
|
||||
//////////
|
||||
@@ -1335,7 +1348,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(get_ubjson_float_prefix(n));
|
||||
oa.write_character(get_ubjson_float_prefix(n));
|
||||
}
|
||||
write_number(n, use_bjdata);
|
||||
}
|
||||
@@ -1351,7 +1364,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('i')); // int8
|
||||
oa.write_character(to_char_type('i')); // int8
|
||||
}
|
||||
write_number(static_cast<std::uint8_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1359,7 +1372,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('U')); // uint8
|
||||
oa.write_character(to_char_type('U')); // uint8
|
||||
}
|
||||
write_number(static_cast<std::uint8_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1367,7 +1380,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('I')); // int16
|
||||
oa.write_character(to_char_type('I')); // int16
|
||||
}
|
||||
write_number(static_cast<std::int16_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1375,7 +1388,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('u')); // uint16 - bjdata only
|
||||
oa.write_character(to_char_type('u')); // uint16 - bjdata only
|
||||
}
|
||||
write_number(static_cast<std::uint16_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1383,7 +1396,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('l')); // int32
|
||||
oa.write_character(to_char_type('l')); // int32
|
||||
}
|
||||
write_number(static_cast<std::int32_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1391,7 +1404,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('m')); // uint32 - bjdata only
|
||||
oa.write_character(to_char_type('m')); // uint32 - bjdata only
|
||||
}
|
||||
write_number(static_cast<std::uint32_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1399,7 +1412,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('L')); // int64
|
||||
oa.write_character(to_char_type('L')); // int64
|
||||
}
|
||||
write_number(static_cast<std::int64_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1407,7 +1420,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('M')); // uint64 - bjdata only
|
||||
oa.write_character(to_char_type('M')); // uint64 - bjdata only
|
||||
}
|
||||
write_number(static_cast<std::uint64_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1415,14 +1428,14 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('H')); // high-precision number
|
||||
oa.write_character(to_char_type('H')); // high-precision number
|
||||
}
|
||||
|
||||
const auto number = BasicJsonType(n).dump();
|
||||
write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
|
||||
for (std::size_t i = 0; i < number.size(); ++i)
|
||||
{
|
||||
oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
|
||||
oa.write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1439,7 +1452,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('i')); // int8
|
||||
oa.write_character(to_char_type('i')); // int8
|
||||
}
|
||||
write_number(static_cast<std::int8_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1447,7 +1460,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('U')); // uint8
|
||||
oa.write_character(to_char_type('U')); // uint8
|
||||
}
|
||||
write_number(static_cast<std::uint8_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1455,7 +1468,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('I')); // int16
|
||||
oa.write_character(to_char_type('I')); // int16
|
||||
}
|
||||
write_number(static_cast<std::int16_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1463,7 +1476,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('u')); // uint16 - bjdata only
|
||||
oa.write_character(to_char_type('u')); // uint16 - bjdata only
|
||||
}
|
||||
write_number(static_cast<uint16_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1471,7 +1484,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('l')); // int32
|
||||
oa.write_character(to_char_type('l')); // int32
|
||||
}
|
||||
write_number(static_cast<std::int32_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1479,7 +1492,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('m')); // uint32 - bjdata only
|
||||
oa.write_character(to_char_type('m')); // uint32 - bjdata only
|
||||
}
|
||||
write_number(static_cast<uint32_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1487,7 +1500,7 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('L')); // int64
|
||||
oa.write_character(to_char_type('L')); // int64
|
||||
}
|
||||
write_number(static_cast<std::int64_t>(n), use_bjdata);
|
||||
}
|
||||
@@ -1496,14 +1509,14 @@ class binary_writer
|
||||
{
|
||||
if (add_prefix)
|
||||
{
|
||||
oa->write_character(to_char_type('H')); // high-precision number
|
||||
oa.write_character(to_char_type('H')); // high-precision number
|
||||
}
|
||||
|
||||
const auto number = BasicJsonType(n).dump();
|
||||
write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
|
||||
for (std::size_t i = 0; i < number.size(); ++i)
|
||||
{
|
||||
oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
|
||||
oa.write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
|
||||
}
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
@@ -1656,10 +1669,10 @@ class binary_writer
|
||||
return true;
|
||||
}
|
||||
|
||||
oa->write_character('[');
|
||||
oa->write_character('$');
|
||||
oa->write_character(dtype);
|
||||
oa->write_character('#');
|
||||
oa.write_character('[');
|
||||
oa.write_character('$');
|
||||
oa.write_character(dtype);
|
||||
oa.write_character('#');
|
||||
|
||||
key = "_ArraySize_";
|
||||
write_ubjson(value.at(key), use_count, use_type, true, true, bjdata_version);
|
||||
@@ -1769,7 +1782,7 @@ class binary_writer
|
||||
std::reverse(vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
oa->write_characters(vec.data(), sizeof(NumberType));
|
||||
oa.write_characters(vec.data(), sizeof(NumberType));
|
||||
}
|
||||
|
||||
void write_compact_float(const number_float_t n, detail::input_format_t format)
|
||||
@@ -1782,16 +1795,16 @@ class binary_writer
|
||||
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
|
||||
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))))
|
||||
{
|
||||
oa->write_character(format == detail::input_format_t::cbor
|
||||
? get_cbor_float_prefix(static_cast<float>(n))
|
||||
: get_msgpack_float_prefix(static_cast<float>(n)));
|
||||
oa.write_character(format == detail::input_format_t::cbor
|
||||
? get_cbor_float_prefix(static_cast<float>(n))
|
||||
: get_msgpack_float_prefix(static_cast<float>(n)));
|
||||
write_number(static_cast<float>(n));
|
||||
}
|
||||
else
|
||||
{
|
||||
oa->write_character(format == detail::input_format_t::cbor
|
||||
? get_cbor_float_prefix(n)
|
||||
: get_msgpack_float_prefix(n));
|
||||
oa.write_character(format == detail::input_format_t::cbor
|
||||
? get_cbor_float_prefix(n)
|
||||
: get_msgpack_float_prefix(n));
|
||||
write_number(n);
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
@@ -1858,7 +1871,7 @@ class binary_writer
|
||||
const bool is_little_endian = little_endianness();
|
||||
|
||||
/// the output
|
||||
output_adapter_t<CharType> oa = nullptr;
|
||||
OutputSinkType oa;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -118,6 +118,68 @@ class output_string_adapter : public output_adapter_protocol<CharType>
|
||||
StringType& str;
|
||||
};
|
||||
|
||||
/// @brief non-virtual output sink writing into a std::vector
|
||||
///
|
||||
/// Unlike output_vector_adapter, this sink is not part of the virtual
|
||||
/// output_adapter_protocol hierarchy: it is passed to binary_writer by value as
|
||||
/// a template parameter, so write_character()/write_characters() are ordinary
|
||||
/// (inlinable) calls with no vtable lookup and no shared_ptr. It is used for the
|
||||
/// common `to_cbor`/`to_msgpack`/... into a std::vector.
|
||||
template<typename CharType, typename AllocatorType = std::allocator<CharType>>
|
||||
class output_vector_sink
|
||||
{
|
||||
public:
|
||||
explicit output_vector_sink(std::vector<CharType, AllocatorType>& vec) noexcept
|
||||
: v(vec)
|
||||
{}
|
||||
|
||||
void write_character(CharType c)
|
||||
{
|
||||
v.push_back(c);
|
||||
}
|
||||
|
||||
JSON_HEDLEY_NON_NULL(2)
|
||||
void write_characters(const CharType* s, std::size_t length)
|
||||
{
|
||||
v.insert(v.end(), s, s + length);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<CharType, AllocatorType>& v;
|
||||
};
|
||||
|
||||
/// @brief output sink forwarding to a type-erased output adapter
|
||||
///
|
||||
/// Wraps the polymorphic output_adapter_t so the same binary_writer template can
|
||||
/// also target arbitrary adapters (output streams, strings, user-provided
|
||||
/// adapters) via the `output_adapter`-based overloads. Each write still goes
|
||||
/// through one virtual call, exactly as before; only the concrete sinks above
|
||||
/// avoid it.
|
||||
template<typename CharType>
|
||||
class output_adapter_sink
|
||||
{
|
||||
public:
|
||||
explicit output_adapter_sink(output_adapter_t<CharType> adapter)
|
||||
: oa(std::move(adapter))
|
||||
{
|
||||
JSON_ASSERT(oa);
|
||||
}
|
||||
|
||||
void write_character(CharType c)
|
||||
{
|
||||
oa->write_character(c);
|
||||
}
|
||||
|
||||
JSON_HEDLEY_NON_NULL(2)
|
||||
void write_characters(const CharType* s, std::size_t length)
|
||||
{
|
||||
oa->write_characters(s, length);
|
||||
}
|
||||
|
||||
private:
|
||||
output_adapter_t<CharType> oa = nullptr;
|
||||
};
|
||||
|
||||
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
||||
class output_adapter
|
||||
{
|
||||
|
||||
@@ -140,7 +140,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
friend ::nlohmann::detail::serializer<basic_json>;
|
||||
template<typename BasicJsonType>
|
||||
friend class ::nlohmann::detail::iter_impl;
|
||||
template<typename BasicJsonType, typename CharType>
|
||||
template<typename BasicJsonType, typename CharType, typename OutputSinkType>
|
||||
friend class ::nlohmann::detail::binary_writer;
|
||||
template<typename BasicJsonType, typename InputType, typename SAX>
|
||||
friend class ::nlohmann::detail::binary_reader;
|
||||
@@ -186,7 +186,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
template<typename InputType>
|
||||
using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
|
||||
template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
|
||||
template<typename CharType, typename OutputSinkType = ::nlohmann::detail::output_adapter_sink<CharType>>
|
||||
using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType, OutputSinkType>;
|
||||
|
||||
JSON_PRIVATE_UNLESS_TESTED:
|
||||
using serializer = ::nlohmann::detail::serializer<basic_json>;
|
||||
@@ -4327,7 +4328,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static std::vector<std::uint8_t> to_cbor(const basic_json& j)
|
||||
{
|
||||
std::vector<std::uint8_t> result;
|
||||
to_cbor(j, result);
|
||||
binary_writer<std::uint8_t, detail::output_vector_sink<std::uint8_t>>(
|
||||
detail::output_vector_sink<std::uint8_t>(result)).write_cbor(j);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4350,7 +4352,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
|
||||
{
|
||||
std::vector<std::uint8_t> result;
|
||||
to_msgpack(j, result);
|
||||
binary_writer<std::uint8_t, detail::output_vector_sink<std::uint8_t>>(
|
||||
detail::output_vector_sink<std::uint8_t>(result)).write_msgpack(j);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4375,7 +4378,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bool use_type = false)
|
||||
{
|
||||
std::vector<std::uint8_t> result;
|
||||
to_ubjson(j, result, use_size, use_type);
|
||||
binary_writer<std::uint8_t, detail::output_vector_sink<std::uint8_t>>(
|
||||
detail::output_vector_sink<std::uint8_t>(result)).write_ubjson(j, use_size, use_type);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4403,7 +4407,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const bjdata_version_t version = bjdata_version_t::draft2)
|
||||
{
|
||||
std::vector<std::uint8_t> result;
|
||||
to_bjdata(j, result, use_size, use_type, version);
|
||||
binary_writer<std::uint8_t, detail::output_vector_sink<std::uint8_t>>(
|
||||
detail::output_vector_sink<std::uint8_t>(result)).write_ubjson(j, use_size, use_type, true, true, version);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4430,7 +4435,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static std::vector<std::uint8_t> to_bson(const basic_json& j)
|
||||
{
|
||||
std::vector<std::uint8_t> result;
|
||||
to_bson(j, result);
|
||||
binary_writer<std::uint8_t, detail::output_vector_sink<std::uint8_t>>(
|
||||
detail::output_vector_sink<std::uint8_t>(result)).write_bson(j);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+270
-166
File diff suppressed because it is too large
Load Diff
@@ -2721,6 +2721,19 @@ TEST_CASE("BJData")
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing BJData string: expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x31", json::parse_error&);
|
||||
}
|
||||
|
||||
SECTION("negative length")
|
||||
{
|
||||
json _;
|
||||
|
||||
std::vector<uint8_t> const vi = {'S', 'i', 0xFF};
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vi), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing BJData string: string length must not be negative", json::parse_error&);
|
||||
CHECK(json::from_bjdata(vi, true, false).is_discarded());
|
||||
|
||||
std::vector<uint8_t> const vl = {'S', 'l', 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vl), "[json.exception.parse_error.113] parse error at byte 6: syntax error while parsing BJData string: string length must not be negative", json::parse_error&);
|
||||
CHECK(json::from_bjdata(vl, true, false).is_discarded());
|
||||
}
|
||||
|
||||
SECTION("parse bjdata markers in ubjson")
|
||||
{
|
||||
// create a single-character string for all number types
|
||||
|
||||
@@ -1862,6 +1862,31 @@ TEST_CASE("UBJSON")
|
||||
json _;
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31", json::parse_error&);
|
||||
}
|
||||
|
||||
SECTION("negative length")
|
||||
{
|
||||
json _;
|
||||
|
||||
std::vector<uint8_t> const vi = {'S', 'i', 0xFF};
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vi), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||
CHECK(json::from_ubjson(vi, true, false).is_discarded());
|
||||
|
||||
std::vector<uint8_t> const vI = {'S', 'I', 0xFF, 0xFF};
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vI), "[json.exception.parse_error.113] parse error at byte 4: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||
CHECK(json::from_ubjson(vI, true, false).is_discarded());
|
||||
|
||||
std::vector<uint8_t> const vl = {'S', 'l', 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vl), "[json.exception.parse_error.113] parse error at byte 6: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||
CHECK(json::from_ubjson(vl, true, false).is_discarded());
|
||||
|
||||
std::vector<uint8_t> const vL = {'S', 'L', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vL), "[json.exception.parse_error.113] parse error at byte 10: syntax error while parsing UBJSON string: string length must not be negative", json::parse_error&);
|
||||
CHECK(json::from_ubjson(vL, true, false).is_discarded());
|
||||
|
||||
// a length of zero remains valid and yields an empty string
|
||||
std::vector<uint8_t> const v0 = {'S', 'i', 0};
|
||||
CHECK(json::from_ubjson(v0) == json(""));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
|
||||
Reference in New Issue
Block a user