templatized output adapters
This commit is contained in:
parent
7444c7fa25
commit
bf55a999c5
@ -23,11 +23,13 @@ namespace detail
|
|||||||
/*!
|
/*!
|
||||||
@brief serialization to CBOR and MessagePack values
|
@brief serialization to CBOR and MessagePack values
|
||||||
*/
|
*/
|
||||||
template<typename BasicJsonType, typename CharType>
|
template<typename BasicJsonType, typename OutputAdapterType>
|
||||||
class binary_writer
|
class binary_writer
|
||||||
{
|
{
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
using binary_t = typename BasicJsonType::binary_t;
|
using binary_t = typename BasicJsonType::binary_t;
|
||||||
|
using output_adapter_t = OutputAdapterType;
|
||||||
|
using CharType = typename OutputAdapterType::char_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
@ -35,10 +37,8 @@ class binary_writer
|
|||||||
|
|
||||||
@param[in] adapter output adapter to write to
|
@param[in] adapter output adapter to write to
|
||||||
*/
|
*/
|
||||||
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
|
explicit binary_writer(OutputAdapterType adapter) : oa(std::move(adapter))
|
||||||
{
|
{}
|
||||||
assert(oa);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@param[in] j JSON value to serialize
|
@param[in] j JSON value to serialize
|
||||||
@ -70,15 +70,15 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
case value_t::null:
|
case value_t::null:
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(0xF6));
|
oa.write_character(to_char_type(0xF6));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::boolean:
|
case value_t::boolean:
|
||||||
{
|
{
|
||||||
oa->write_character(j.m_value.boolean
|
oa.write_character(j.m_value.boolean
|
||||||
? to_char_type(0xF5)
|
? to_char_type(0xF5)
|
||||||
: to_char_type(0xF4));
|
: to_char_type(0xF4));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,22 +95,22 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (j.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_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (j.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_value.number_integer));
|
write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (j.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_value.number_integer));
|
write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(0x1B));
|
oa.write_character(to_char_type(0x1B));
|
||||||
write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
|
write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,22 +125,22 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
|
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));
|
write_number(static_cast<std::uint8_t>(positive_number));
|
||||||
}
|
}
|
||||||
else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
|
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));
|
write_number(static_cast<std::uint16_t>(positive_number));
|
||||||
}
|
}
|
||||||
else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
|
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));
|
write_number(static_cast<std::uint32_t>(positive_number));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(0x3B));
|
oa.write_character(to_char_type(0x3B));
|
||||||
write_number(static_cast<std::uint64_t>(positive_number));
|
write_number(static_cast<std::uint64_t>(positive_number));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,22 +155,22 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (j.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_value.number_unsigned));
|
write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (j.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_value.number_unsigned));
|
write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (j.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_value.number_unsigned));
|
write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(0x1B));
|
oa.write_character(to_char_type(0x1B));
|
||||||
write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
|
write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -181,16 +181,16 @@ class binary_writer
|
|||||||
if (std::isnan(j.m_value.number_float))
|
if (std::isnan(j.m_value.number_float))
|
||||||
{
|
{
|
||||||
// NaN is 0xf97e00 in CBOR
|
// NaN is 0xf97e00 in CBOR
|
||||||
oa->write_character(to_char_type(0xF9));
|
oa.write_character(to_char_type(0xF9));
|
||||||
oa->write_character(to_char_type(0x7E));
|
oa.write_character(to_char_type(0x7E));
|
||||||
oa->write_character(to_char_type(0x00));
|
oa.write_character(to_char_type(0x00));
|
||||||
}
|
}
|
||||||
else if (std::isinf(j.m_value.number_float))
|
else if (std::isinf(j.m_value.number_float))
|
||||||
{
|
{
|
||||||
// Infinity is 0xf97c00, -Infinity is 0xf9fc00
|
// Infinity is 0xf97c00, -Infinity is 0xf9fc00
|
||||||
oa->write_character(to_char_type(0xf9));
|
oa.write_character(to_char_type(0xf9));
|
||||||
oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
|
oa.write_character(j.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(0x00));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -198,12 +198,12 @@ class binary_writer
|
|||||||
static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
|
static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
|
||||||
static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
|
static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
|
||||||
{
|
{
|
||||||
oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
|
oa.write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
|
||||||
write_number(static_cast<float>(j.m_value.number_float));
|
write_number(static_cast<float>(j.m_value.number_float));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
|
oa.write_character(get_cbor_float_prefix(j.m_value.number_float));
|
||||||
write_number(j.m_value.number_float);
|
write_number(j.m_value.number_float);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,29 +220,29 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
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));
|
write_number(static_cast<std::uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
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));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
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));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
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));
|
write_number(static_cast<std::uint64_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
// step 2: write the string
|
// step 2: write the string
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||||
j.m_value.string->size());
|
j.m_value.string->size());
|
||||||
break;
|
break;
|
||||||
@ -258,23 +258,23 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
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));
|
write_number(static_cast<std::uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
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));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
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));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
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));
|
write_number(static_cast<std::uint64_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
@ -297,29 +297,29 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
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));
|
write_number(static_cast<std::uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
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));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
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));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
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));
|
write_number(static_cast<std::uint64_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
|
||||||
// step 2: write each element
|
// step 2: write each element
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
||||||
N);
|
N);
|
||||||
|
|
||||||
@ -336,23 +336,23 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
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));
|
write_number(static_cast<std::uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
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));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
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));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
else if (N <= (std::numeric_limits<std::uint64_t>::max)())
|
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));
|
write_number(static_cast<std::uint64_t>(N));
|
||||||
}
|
}
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
@ -380,15 +380,15 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
case value_t::null: // nil
|
case value_t::null: // nil
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(0xC0));
|
oa.write_character(to_char_type(0xC0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::boolean: // true and false
|
case value_t::boolean: // true and false
|
||||||
{
|
{
|
||||||
oa->write_character(j.m_value.boolean
|
oa.write_character(j.m_value.boolean
|
||||||
? to_char_type(0xC3)
|
? to_char_type(0xC3)
|
||||||
: to_char_type(0xC2));
|
: to_char_type(0xC2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,25 +407,25 @@ class binary_writer
|
|||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 8
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 16
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 32
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 64
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,28 +440,28 @@ class binary_writer
|
|||||||
j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
|
||||||
{
|
{
|
||||||
// int 8
|
// 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_value.number_integer));
|
write_number(static_cast<std::int8_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
|
else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
|
||||||
j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
|
||||||
{
|
{
|
||||||
// int 16
|
// 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_value.number_integer));
|
write_number(static_cast<std::int16_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
|
else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
|
||||||
j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
|
||||||
{
|
{
|
||||||
// int 32
|
// 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_value.number_integer));
|
write_number(static_cast<std::int32_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
|
else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
|
||||||
j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
|
||||||
{
|
{
|
||||||
// int 64
|
// 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_value.number_integer));
|
write_number(static_cast<std::int64_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,25 +478,25 @@ class binary_writer
|
|||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 8
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 16
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 32
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
|
else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
|
||||||
{
|
{
|
||||||
// uint 64
|
// 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_value.number_integer));
|
write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -504,7 +504,7 @@ class binary_writer
|
|||||||
|
|
||||||
case value_t::number_float:
|
case value_t::number_float:
|
||||||
{
|
{
|
||||||
oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
|
oa.write_character(get_msgpack_float_prefix(j.m_value.number_float));
|
||||||
write_number(j.m_value.number_float);
|
write_number(j.m_value.number_float);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -521,24 +521,24 @@ class binary_writer
|
|||||||
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint8_t>::max)())
|
||||||
{
|
{
|
||||||
// str 8
|
// str 8
|
||||||
oa->write_character(to_char_type(0xD9));
|
oa.write_character(to_char_type(0xD9));
|
||||||
write_number(static_cast<std::uint8_t>(N));
|
write_number(static_cast<std::uint8_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// str 16
|
// str 16
|
||||||
oa->write_character(to_char_type(0xDA));
|
oa.write_character(to_char_type(0xDA));
|
||||||
write_number(static_cast<std::uint16_t>(N));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// str 32
|
// str 32
|
||||||
oa->write_character(to_char_type(0xDB));
|
oa.write_character(to_char_type(0xDB));
|
||||||
write_number(static_cast<std::uint32_t>(N));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 2: write the string
|
// step 2: write the string
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||||
j.m_value.string->size());
|
j.m_value.string->size());
|
||||||
break;
|
break;
|
||||||
@ -556,13 +556,13 @@ class binary_writer
|
|||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// array 16
|
// array 16
|
||||||
oa->write_character(to_char_type(0xDC));
|
oa.write_character(to_char_type(0xDC));
|
||||||
write_number(static_cast<std::uint16_t>(N));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// array 32
|
// array 32
|
||||||
oa->write_character(to_char_type(0xDD));
|
oa.write_character(to_char_type(0xDD));
|
||||||
write_number(static_cast<std::uint32_t>(N));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +618,7 @@ class binary_writer
|
|||||||
fixed = false;
|
fixed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
oa->write_character(to_char_type(output_type));
|
oa.write_character(to_char_type(output_type));
|
||||||
if (not fixed)
|
if (not fixed)
|
||||||
{
|
{
|
||||||
write_number(static_cast<std::uint8_t>(N));
|
write_number(static_cast<std::uint8_t>(N));
|
||||||
@ -636,7 +636,7 @@ class binary_writer
|
|||||||
output_type = 0xC5; // bin 16
|
output_type = 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));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
@ -651,7 +651,7 @@ class binary_writer
|
|||||||
output_type = 0xC6; // bin 32
|
output_type = 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));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,7 +662,7 @@ class binary_writer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// step 2: write the byte string
|
// step 2: write the byte string
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
||||||
N);
|
N);
|
||||||
|
|
||||||
@ -681,13 +681,13 @@ class binary_writer
|
|||||||
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint16_t>::max)())
|
||||||
{
|
{
|
||||||
// map 16
|
// map 16
|
||||||
oa->write_character(to_char_type(0xDE));
|
oa.write_character(to_char_type(0xDE));
|
||||||
write_number(static_cast<std::uint16_t>(N));
|
write_number(static_cast<std::uint16_t>(N));
|
||||||
}
|
}
|
||||||
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
else if (N <= (std::numeric_limits<std::uint32_t>::max)())
|
||||||
{
|
{
|
||||||
// map 32
|
// map 32
|
||||||
oa->write_character(to_char_type(0xDF));
|
oa.write_character(to_char_type(0xDF));
|
||||||
write_number(static_cast<std::uint32_t>(N));
|
write_number(static_cast<std::uint32_t>(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,7 +720,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('Z'));
|
oa.write_character(to_char_type('Z'));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -729,9 +729,9 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(j.m_value.boolean
|
oa.write_character(j.m_value.boolean
|
||||||
? to_char_type('T')
|
? to_char_type('T')
|
||||||
: to_char_type('F'));
|
: to_char_type('F'));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -758,10 +758,10 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('S'));
|
oa.write_character(to_char_type('S'));
|
||||||
}
|
}
|
||||||
write_number_with_ubjson_prefix(j.m_value.string->size(), true);
|
write_number_with_ubjson_prefix(j.m_value.string->size(), true);
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
|
||||||
j.m_value.string->size());
|
j.m_value.string->size());
|
||||||
break;
|
break;
|
||||||
@ -771,7 +771,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('['));
|
oa.write_character(to_char_type('['));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prefix_required = true;
|
bool prefix_required = true;
|
||||||
@ -788,14 +788,14 @@ class binary_writer
|
|||||||
if (same_prefix)
|
if (same_prefix)
|
||||||
{
|
{
|
||||||
prefix_required = false;
|
prefix_required = false;
|
||||||
oa->write_character(to_char_type('$'));
|
oa.write_character(to_char_type('$'));
|
||||||
oa->write_character(first_prefix);
|
oa.write_character(first_prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_count)
|
if (use_count)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('#'));
|
oa.write_character(to_char_type('#'));
|
||||||
write_number_with_ubjson_prefix(j.m_value.array->size(), true);
|
write_number_with_ubjson_prefix(j.m_value.array->size(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +806,7 @@ class binary_writer
|
|||||||
|
|
||||||
if (not use_count)
|
if (not use_count)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(']'));
|
oa.write_character(to_char_type(']'));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -816,25 +816,25 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('['));
|
oa.write_character(to_char_type('['));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_type and not j.m_value.binary->empty())
|
if (use_type and not j.m_value.binary->empty())
|
||||||
{
|
{
|
||||||
assert(use_count);
|
assert(use_count);
|
||||||
oa->write_character(to_char_type('$'));
|
oa.write_character(to_char_type('$'));
|
||||||
oa->write_character('U');
|
oa.write_character('U');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_count)
|
if (use_count)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('#'));
|
oa.write_character(to_char_type('#'));
|
||||||
write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
|
write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_type)
|
if (use_type)
|
||||||
{
|
{
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
reinterpret_cast<const CharType*>(j.m_value.binary->data()),
|
||||||
j.m_value.binary->size());
|
j.m_value.binary->size());
|
||||||
}
|
}
|
||||||
@ -842,14 +842,14 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < j.m_value.binary->size(); ++i)
|
for (size_t i = 0; i < j.m_value.binary->size(); ++i)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('U'));
|
oa.write_character(to_char_type('U'));
|
||||||
oa->write_character(j.m_value.binary->data()[i]);
|
oa.write_character(j.m_value.binary->data()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not use_count)
|
if (not use_count)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(']'));
|
oa.write_character(to_char_type(']'));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -859,7 +859,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('{'));
|
oa.write_character(to_char_type('{'));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prefix_required = true;
|
bool prefix_required = true;
|
||||||
@ -876,21 +876,21 @@ class binary_writer
|
|||||||
if (same_prefix)
|
if (same_prefix)
|
||||||
{
|
{
|
||||||
prefix_required = false;
|
prefix_required = false;
|
||||||
oa->write_character(to_char_type('$'));
|
oa.write_character(to_char_type('$'));
|
||||||
oa->write_character(first_prefix);
|
oa.write_character(first_prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_count)
|
if (use_count)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('#'));
|
oa.write_character(to_char_type('#'));
|
||||||
write_number_with_ubjson_prefix(j.m_value.object->size(), true);
|
write_number_with_ubjson_prefix(j.m_value.object->size(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& el : *j.m_value.object)
|
for (const auto& el : *j.m_value.object)
|
||||||
{
|
{
|
||||||
write_number_with_ubjson_prefix(el.first.size(), true);
|
write_number_with_ubjson_prefix(el.first.size(), true);
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(el.first.c_str()),
|
reinterpret_cast<const CharType*>(el.first.c_str()),
|
||||||
el.first.size());
|
el.first.size());
|
||||||
write_ubjson(el.second, use_count, use_type, prefix_required);
|
write_ubjson(el.second, use_count, use_type, prefix_required);
|
||||||
@ -898,7 +898,7 @@ class binary_writer
|
|||||||
|
|
||||||
if (not use_count)
|
if (not use_count)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type('}'));
|
oa.write_character(to_char_type('}'));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -936,8 +936,8 @@ class binary_writer
|
|||||||
void write_bson_entry_header(const string_t& name,
|
void write_bson_entry_header(const string_t& name,
|
||||||
const std::uint8_t element_type)
|
const std::uint8_t element_type)
|
||||||
{
|
{
|
||||||
oa->write_character(to_char_type(element_type)); // boolean
|
oa.write_character(to_char_type(element_type)); // boolean
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(name.c_str()),
|
reinterpret_cast<const CharType*>(name.c_str()),
|
||||||
name.size() + 1u);
|
name.size() + 1u);
|
||||||
}
|
}
|
||||||
@ -949,7 +949,7 @@ class binary_writer
|
|||||||
const bool value)
|
const bool value)
|
||||||
{
|
{
|
||||||
write_bson_entry_header(name, 0x08);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -979,7 +979,7 @@ class binary_writer
|
|||||||
write_bson_entry_header(name, 0x02);
|
write_bson_entry_header(name, 0x02);
|
||||||
|
|
||||||
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
|
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
|
||||||
oa->write_characters(
|
oa.write_characters(
|
||||||
reinterpret_cast<const CharType*>(value.c_str()),
|
reinterpret_cast<const CharType*>(value.c_str()),
|
||||||
value.size() + 1);
|
value.size() + 1);
|
||||||
}
|
}
|
||||||
@ -1101,7 +1101,7 @@ class binary_writer
|
|||||||
write_bson_element(std::to_string(array_index++), el);
|
write_bson_element(std::to_string(array_index++), el);
|
||||||
}
|
}
|
||||||
|
|
||||||
oa->write_character(to_char_type(0x00));
|
oa.write_character(to_char_type(0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1115,7 +1115,7 @@ class binary_writer
|
|||||||
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
|
write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
|
||||||
write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
|
write_number(value.has_subtype() ? value.subtype() : 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1240,7 +1240,7 @@ class binary_writer
|
|||||||
write_bson_element(el.first, el.second);
|
write_bson_element(el.first, el.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
oa->write_character(to_char_type(0x00));
|
oa.write_character(to_char_type(0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
@ -1283,7 +1283,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
if (add_prefix)
|
||||||
{
|
{
|
||||||
oa->write_character(get_ubjson_float_prefix(n));
|
oa.write_character(get_ubjson_float_prefix(n));
|
||||||
}
|
}
|
||||||
write_number(n);
|
write_number(n);
|
||||||
}
|
}
|
||||||
@ -1298,7 +1298,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::uint8_t>(n));
|
||||||
}
|
}
|
||||||
@ -1306,7 +1306,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::uint8_t>(n));
|
||||||
}
|
}
|
||||||
@ -1314,7 +1314,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int16_t>(n));
|
||||||
}
|
}
|
||||||
@ -1322,7 +1322,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int32_t>(n));
|
||||||
}
|
}
|
||||||
@ -1330,7 +1330,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int64_t>(n));
|
||||||
}
|
}
|
||||||
@ -1351,7 +1351,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int8_t>(n));
|
||||||
}
|
}
|
||||||
@ -1359,7 +1359,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::uint8_t>(n));
|
||||||
}
|
}
|
||||||
@ -1367,7 +1367,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int16_t>(n));
|
||||||
}
|
}
|
||||||
@ -1375,7 +1375,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int32_t>(n));
|
||||||
}
|
}
|
||||||
@ -1383,7 +1383,7 @@ class binary_writer
|
|||||||
{
|
{
|
||||||
if (add_prefix)
|
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));
|
write_number(static_cast<std::int64_t>(n));
|
||||||
}
|
}
|
||||||
@ -1515,7 +1515,7 @@ class binary_writer
|
|||||||
std::reverse(vec.begin(), vec.end());
|
std::reverse(vec.begin(), vec.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
oa->write_characters(vec.data(), sizeof(NumberType));
|
oa.write_characters(vec.data(), sizeof(NumberType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1564,7 +1564,7 @@ class binary_writer
|
|||||||
const bool is_little_endian = little_endianess();
|
const bool is_little_endian = little_endianess();
|
||||||
|
|
||||||
/// the output
|
/// the output
|
||||||
output_adapter_t<CharType> oa = nullptr;
|
output_adapter_t oa;
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|||||||
@ -14,110 +14,134 @@ namespace nlohmann
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
/// abstract output adapter interface
|
|
||||||
template<typename CharType> struct output_adapter_protocol
|
|
||||||
|
template<typename T>
|
||||||
|
struct output_adapter_impl;
|
||||||
|
|
||||||
|
// Output to a string, append() is faster than insert(str.end(),...) on some compilers,
|
||||||
|
// so it's worth having a special override for it.
|
||||||
|
template<typename StringType>
|
||||||
|
struct string_output_adapter
|
||||||
{
|
{
|
||||||
virtual void write_character(CharType c) = 0;
|
using char_type = typename StringType::value_type;
|
||||||
virtual void write_characters(const CharType* s, std::size_t length) = 0;
|
|
||||||
virtual ~output_adapter_protocol() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// a type to simplify interfaces
|
string_output_adapter(StringType& dst) : dst_(dst) {}
|
||||||
template<typename CharType>
|
|
||||||
using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
|
|
||||||
|
|
||||||
/// output adapter for byte vectors
|
void write_character(char_type c)
|
||||||
template<typename CharType>
|
|
||||||
class output_vector_adapter : public output_adapter_protocol<CharType>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
|
|
||||||
: v(vec)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void write_character(CharType c) override
|
|
||||||
{
|
{
|
||||||
v.push_back(c);
|
dst_.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
void write_characters(const char_type* str, std::size_t len)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
|
||||||
{
|
{
|
||||||
std::copy(s, s + length, std::back_inserter(v));
|
dst_.append(str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CharType>& v;
|
StringType& dst_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// output adapter for output streams
|
// Output to an iterator-like object
|
||||||
template<typename CharType>
|
template<class IteratorType>
|
||||||
class output_stream_adapter : public output_adapter_protocol<CharType>
|
struct iterator_output_adapter
|
||||||
{
|
{
|
||||||
public:
|
using char_type = char; //?????????????????????????
|
||||||
explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
|
|
||||||
: stream(s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void write_character(CharType c) override
|
iterator_output_adapter(IteratorType dst) : dst_(dst) {}
|
||||||
|
|
||||||
|
void write_character(char_type c)
|
||||||
{
|
{
|
||||||
stream.put(c);
|
*dst_++ = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
void write_characters(const char_type* str, std::size_t len)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
|
||||||
{
|
{
|
||||||
stream.write(s, static_cast<std::streamsize>(length));
|
std::copy(str, str + len, dst_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::basic_ostream<CharType>& stream;
|
IteratorType dst_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// output adapter for basic_string
|
// Output to a stream-like object
|
||||||
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
template<class StreamType>
|
||||||
class output_string_adapter : public output_adapter_protocol<CharType>
|
struct stream_output_adapter
|
||||||
{
|
{
|
||||||
public:
|
using char_type = typename StreamType::char_type;
|
||||||
explicit output_string_adapter(StringType& s) noexcept
|
|
||||||
: str(s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void write_character(CharType c) override
|
stream_output_adapter(StreamType& dst) : dst_(dst) {}
|
||||||
|
|
||||||
|
void write_character(char_type c)
|
||||||
{
|
{
|
||||||
str.push_back(c);
|
dst_.put(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSON_HEDLEY_NON_NULL(2)
|
void write_characters(const char_type* str, std::size_t len)
|
||||||
void write_characters(const CharType* s, std::size_t length) override
|
|
||||||
{
|
{
|
||||||
str.append(s, length);
|
dst_.write(str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringType& str;
|
StreamType& dst_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CharType, typename StringType = std::basic_string<CharType>>
|
template<typename T, typename = void>
|
||||||
class output_adapter
|
struct is_output_iterator : public std::false_type {};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_output_iterator<T,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
typename std::iterator_traits<T>::iterator_category,
|
||||||
|
std::output_iterator_tag>::value
|
||||||
|
>::type> : public std::true_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto has_push_back (int)
|
||||||
|
-> decltype( std::declval<T>().push_back('a'),
|
||||||
|
std::true_type() );
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
constexpr std::false_type has_push_back (long);
|
||||||
|
|
||||||
|
// If the parameter is a basic_string
|
||||||
|
template<typename CharT, typename Traits, typename Allocator>
|
||||||
|
string_output_adapter<std::basic_string<CharT, Traits, Allocator>> output_adapter(std::basic_string<CharT, Traits, Allocator>& dst)
|
||||||
{
|
{
|
||||||
public:
|
return string_output_adapter<std::basic_string<CharT, Traits, Allocator>>(dst);
|
||||||
output_adapter(std::vector<CharType>& vec)
|
}
|
||||||
: oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
|
|
||||||
|
|
||||||
output_adapter(std::basic_ostream<CharType>& s)
|
// If the parameter is an output iterator
|
||||||
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
|
template<typename IteratorType,
|
||||||
|
typename std::enable_if<
|
||||||
|
is_output_iterator<IteratorType>::value,
|
||||||
|
int>::type = 0>
|
||||||
|
auto output_adapter(IteratorType dst) -> iterator_output_adapter<IteratorType>
|
||||||
|
{
|
||||||
|
return iterator_output_adapter<IteratorType>(std::move(dst));
|
||||||
|
}
|
||||||
|
|
||||||
output_adapter(StringType& s)
|
// Try to extract an output iterator from the parameter
|
||||||
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
|
template<typename ContainerType,
|
||||||
|
typename std::enable_if<
|
||||||
|
decltype(has_push_back<ContainerType>(0))::value,
|
||||||
|
int>::type = 0>
|
||||||
|
auto output_adapter(ContainerType& dst) -> decltype(output_adapter(std::back_inserter(dst)))
|
||||||
|
{
|
||||||
|
return output_adapter(std::back_inserter(dst));
|
||||||
|
}
|
||||||
|
|
||||||
operator output_adapter_t<CharType>()
|
|
||||||
{
|
|
||||||
return oa;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
// If all else fails, treat it as a stream
|
||||||
output_adapter_t<CharType> oa = nullptr;
|
template<typename StreamType, typename std::enable_if<
|
||||||
};
|
not is_output_iterator<StreamType>::value and
|
||||||
|
not decltype(has_push_back<StreamType>(0))::value,
|
||||||
|
int>::type = 0>
|
||||||
|
stream_output_adapter<StreamType> output_adapter(StreamType& dst)
|
||||||
|
{
|
||||||
|
return stream_output_adapter<StreamType>(dst);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace nlohmann
|
} // namespace nlohmann
|
||||||
|
|||||||
@ -38,7 +38,7 @@ enum class error_handler_t
|
|||||||
ignore ///< ignore invalid UTF-8 sequences
|
ignore ///< ignore invalid UTF-8 sequences
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType, typename OutputAdapterType>
|
||||||
class serializer
|
class serializer
|
||||||
{
|
{
|
||||||
using string_t = typename BasicJsonType::string_t;
|
using string_t = typename BasicJsonType::string_t;
|
||||||
@ -46,16 +46,19 @@ class serializer
|
|||||||
using number_integer_t = typename BasicJsonType::number_integer_t;
|
using number_integer_t = typename BasicJsonType::number_integer_t;
|
||||||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
|
||||||
using binary_char_t = typename BasicJsonType::binary_t::value_type;
|
using binary_char_t = typename BasicJsonType::binary_t::value_type;
|
||||||
|
using output_adapter_t = OutputAdapterType;
|
||||||
|
|
||||||
static constexpr std::uint8_t UTF8_ACCEPT = 0;
|
static constexpr std::uint8_t UTF8_ACCEPT = 0;
|
||||||
static constexpr std::uint8_t UTF8_REJECT = 1;
|
static constexpr std::uint8_t UTF8_REJECT = 1;
|
||||||
|
|
||||||
|
static_assert(sizeof(typename output_adapter_t::char_type) == 1, "can only serialize to UTF-8");
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
@param[in] s output stream to serialize to
|
@param[in] s output stream to serialize to
|
||||||
@param[in] ichar indentation character to use
|
@param[in] ichar indentation character to use
|
||||||
@param[in] error_handler_ how to react on decoding errors
|
@param[in] error_handler_ how to react on decoding errors
|
||||||
*/
|
*/
|
||||||
serializer(output_adapter_t<char> s, const char ichar,
|
serializer(output_adapter_t s, const char ichar,
|
||||||
error_handler_t error_handler_ = error_handler_t::strict)
|
error_handler_t error_handler_ = error_handler_t::strict)
|
||||||
: o(std::move(s))
|
: o(std::move(s))
|
||||||
, loc(std::localeconv())
|
, loc(std::localeconv())
|
||||||
@ -107,13 +110,13 @@ class serializer
|
|||||||
{
|
{
|
||||||
if (val.m_value.object->empty())
|
if (val.m_value.object->empty())
|
||||||
{
|
{
|
||||||
o->write_characters("{}", 2);
|
o.write_characters("{}", 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o->write_characters("{\n", 2);
|
o.write_characters("{\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
@ -126,51 +129,51 @@ class serializer
|
|||||||
auto i = val.m_value.object->cbegin();
|
auto i = val.m_value.object->cbegin();
|
||||||
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o.write_characters(indent_string.c_str(), new_indent);
|
||||||
o->write_character('\"');
|
o.write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\": ", 3);
|
o.write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o.write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(i != val.m_value.object->cend());
|
assert(i != val.m_value.object->cend());
|
||||||
assert(std::next(i) == val.m_value.object->cend());
|
assert(std::next(i) == val.m_value.object->cend());
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o.write_characters(indent_string.c_str(), new_indent);
|
||||||
o->write_character('\"');
|
o.write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\": ", 3);
|
o.write_characters("\": ", 3);
|
||||||
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
dump(i->second, true, ensure_ascii, indent_step, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o.write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o.write_characters(indent_string.c_str(), current_indent);
|
||||||
o->write_character('}');
|
o.write_character('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_character('{');
|
o.write_character('{');
|
||||||
|
|
||||||
// first n-1 elements
|
// first n-1 elements
|
||||||
auto i = val.m_value.object->cbegin();
|
auto i = val.m_value.object->cbegin();
|
||||||
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
|
||||||
{
|
{
|
||||||
o->write_character('\"');
|
o.write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\":", 2);
|
o.write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
||||||
o->write_character(',');
|
o.write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(i != val.m_value.object->cend());
|
assert(i != val.m_value.object->cend());
|
||||||
assert(std::next(i) == val.m_value.object->cend());
|
assert(std::next(i) == val.m_value.object->cend());
|
||||||
o->write_character('\"');
|
o.write_character('\"');
|
||||||
dump_escaped(i->first, ensure_ascii);
|
dump_escaped(i->first, ensure_ascii);
|
||||||
o->write_characters("\":", 2);
|
o.write_characters("\":", 2);
|
||||||
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
dump(i->second, false, ensure_ascii, indent_step, current_indent);
|
||||||
|
|
||||||
o->write_character('}');
|
o.write_character('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -180,13 +183,13 @@ class serializer
|
|||||||
{
|
{
|
||||||
if (val.m_value.array->empty())
|
if (val.m_value.array->empty())
|
||||||
{
|
{
|
||||||
o->write_characters("[]", 2);
|
o.write_characters("[]", 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o->write_characters("[\n", 2);
|
o.write_characters("[\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
@ -199,37 +202,37 @@ class serializer
|
|||||||
for (auto i = val.m_value.array->cbegin();
|
for (auto i = val.m_value.array->cbegin();
|
||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o.write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
dump(*i, true, ensure_ascii, indent_step, new_indent);
|
||||||
o->write_characters(",\n", 2);
|
o.write_characters(",\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o.write_characters(indent_string.c_str(), new_indent);
|
||||||
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
|
||||||
|
|
||||||
o->write_character('\n');
|
o.write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o.write_characters(indent_string.c_str(), current_indent);
|
||||||
o->write_character(']');
|
o.write_character(']');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_character('[');
|
o.write_character('[');
|
||||||
|
|
||||||
// first n-1 elements
|
// first n-1 elements
|
||||||
for (auto i = val.m_value.array->cbegin();
|
for (auto i = val.m_value.array->cbegin();
|
||||||
i != val.m_value.array->cend() - 1; ++i)
|
i != val.m_value.array->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
dump(*i, false, ensure_ascii, indent_step, current_indent);
|
||||||
o->write_character(',');
|
o.write_character(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
// last element
|
// last element
|
||||||
assert(not val.m_value.array->empty());
|
assert(not val.m_value.array->empty());
|
||||||
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
|
||||||
|
|
||||||
o->write_character(']');
|
o.write_character(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -237,9 +240,9 @@ class serializer
|
|||||||
|
|
||||||
case value_t::string:
|
case value_t::string:
|
||||||
{
|
{
|
||||||
o->write_character('\"');
|
o.write_character('\"');
|
||||||
dump_escaped(*val.m_value.string, ensure_ascii);
|
dump_escaped(*val.m_value.string, ensure_ascii);
|
||||||
o->write_character('\"');
|
o.write_character('\"');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +250,7 @@ class serializer
|
|||||||
{
|
{
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
o->write_characters("{\n", 2);
|
o.write_characters("{\n", 2);
|
||||||
|
|
||||||
// variable to hold indentation for recursive calls
|
// variable to hold indentation for recursive calls
|
||||||
const auto new_indent = current_indent + indent_step;
|
const auto new_indent = current_indent + indent_step;
|
||||||
@ -256,9 +259,9 @@ class serializer
|
|||||||
indent_string.resize(indent_string.size() * 2, ' ');
|
indent_string.resize(indent_string.size() * 2, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o.write_characters(indent_string.c_str(), new_indent);
|
||||||
|
|
||||||
o->write_characters("\"bytes\": [", 10);
|
o.write_characters("\"bytes\": [", 10);
|
||||||
|
|
||||||
if (not val.m_value.binary->empty())
|
if (not val.m_value.binary->empty())
|
||||||
{
|
{
|
||||||
@ -266,30 +269,30 @@ class serializer
|
|||||||
i != val.m_value.binary->cend() - 1; ++i)
|
i != val.m_value.binary->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
dump_integer(*i);
|
dump_integer(*i);
|
||||||
o->write_characters(", ", 2);
|
o.write_characters(", ", 2);
|
||||||
}
|
}
|
||||||
dump_integer(val.m_value.binary->back());
|
dump_integer(val.m_value.binary->back());
|
||||||
}
|
}
|
||||||
|
|
||||||
o->write_characters("],\n", 3);
|
o.write_characters("],\n", 3);
|
||||||
o->write_characters(indent_string.c_str(), new_indent);
|
o.write_characters(indent_string.c_str(), new_indent);
|
||||||
|
|
||||||
o->write_characters("\"subtype\": ", 11);
|
o.write_characters("\"subtype\": ", 11);
|
||||||
if (val.m_value.binary->has_subtype())
|
if (val.m_value.binary->has_subtype())
|
||||||
{
|
{
|
||||||
dump_integer(val.m_value.binary->subtype());
|
dump_integer(val.m_value.binary->subtype());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_characters("null", 4);
|
o.write_characters("null", 4);
|
||||||
}
|
}
|
||||||
o->write_character('\n');
|
o.write_character('\n');
|
||||||
o->write_characters(indent_string.c_str(), current_indent);
|
o.write_characters(indent_string.c_str(), current_indent);
|
||||||
o->write_character('}');
|
o.write_character('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_characters("{\"bytes\":[", 10);
|
o.write_characters("{\"bytes\":[", 10);
|
||||||
|
|
||||||
if (not val.m_value.binary->empty())
|
if (not val.m_value.binary->empty())
|
||||||
{
|
{
|
||||||
@ -297,20 +300,20 @@ class serializer
|
|||||||
i != val.m_value.binary->cend() - 1; ++i)
|
i != val.m_value.binary->cend() - 1; ++i)
|
||||||
{
|
{
|
||||||
dump_integer(*i);
|
dump_integer(*i);
|
||||||
o->write_character(',');
|
o.write_character(',');
|
||||||
}
|
}
|
||||||
dump_integer(val.m_value.binary->back());
|
dump_integer(val.m_value.binary->back());
|
||||||
}
|
}
|
||||||
|
|
||||||
o->write_characters("],\"subtype\":", 12);
|
o.write_characters("],\"subtype\":", 12);
|
||||||
if (val.m_value.binary->has_subtype())
|
if (val.m_value.binary->has_subtype())
|
||||||
{
|
{
|
||||||
dump_integer(val.m_value.binary->subtype());
|
dump_integer(val.m_value.binary->subtype());
|
||||||
o->write_character('}');
|
o.write_character('}');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_characters("null}", 5);
|
o.write_characters("null}", 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -320,11 +323,11 @@ class serializer
|
|||||||
{
|
{
|
||||||
if (val.m_value.boolean)
|
if (val.m_value.boolean)
|
||||||
{
|
{
|
||||||
o->write_characters("true", 4);
|
o.write_characters("true", 4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_characters("false", 5);
|
o.write_characters("false", 5);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -349,13 +352,13 @@ class serializer
|
|||||||
|
|
||||||
case value_t::discarded:
|
case value_t::discarded:
|
||||||
{
|
{
|
||||||
o->write_characters("<discarded>", 11);
|
o.write_characters("<discarded>", 11);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case value_t::null:
|
case value_t::null:
|
||||||
{
|
{
|
||||||
o->write_characters("null", 4);
|
o.write_characters("null", 4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,7 +486,7 @@ class serializer
|
|||||||
// written ("\uxxxx\uxxxx\0") for one code point
|
// written ("\uxxxx\uxxxx\0") for one code point
|
||||||
if (string_buffer.size() - bytes < 13)
|
if (string_buffer.size() - bytes < 13)
|
||||||
{
|
{
|
||||||
o->write_characters(string_buffer.data(), bytes);
|
o.write_characters(string_buffer.data(), bytes);
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,9 +537,9 @@ class serializer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, output_adapter_t>::to_char_type('\xEF');
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, output_adapter_t>::to_char_type('\xBF');
|
||||||
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
|
string_buffer[bytes++] = detail::binary_writer<BasicJsonType, output_adapter_t>::to_char_type('\xBD');
|
||||||
}
|
}
|
||||||
|
|
||||||
// write buffer and reset index; there must be 13 bytes
|
// write buffer and reset index; there must be 13 bytes
|
||||||
@ -544,7 +547,7 @@ class serializer
|
|||||||
// written ("\uxxxx\uxxxx\0") for one code point
|
// written ("\uxxxx\uxxxx\0") for one code point
|
||||||
if (string_buffer.size() - bytes < 13)
|
if (string_buffer.size() - bytes < 13)
|
||||||
{
|
{
|
||||||
o->write_characters(string_buffer.data(), bytes);
|
o.write_characters(string_buffer.data(), bytes);
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,7 +586,7 @@ class serializer
|
|||||||
// write buffer
|
// write buffer
|
||||||
if (bytes > 0)
|
if (bytes > 0)
|
||||||
{
|
{
|
||||||
o->write_characters(string_buffer.data(), bytes);
|
o.write_characters(string_buffer.data(), bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -601,22 +604,22 @@ class serializer
|
|||||||
case error_handler_t::ignore:
|
case error_handler_t::ignore:
|
||||||
{
|
{
|
||||||
// write all accepted bytes
|
// write all accepted bytes
|
||||||
o->write_characters(string_buffer.data(), bytes_after_last_accept);
|
o.write_characters(string_buffer.data(), bytes_after_last_accept);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case error_handler_t::replace:
|
case error_handler_t::replace:
|
||||||
{
|
{
|
||||||
// write all accepted bytes
|
// write all accepted bytes
|
||||||
o->write_characters(string_buffer.data(), bytes_after_last_accept);
|
o.write_characters(string_buffer.data(), bytes_after_last_accept);
|
||||||
// add a replacement character
|
// add a replacement character
|
||||||
if (ensure_ascii)
|
if (ensure_ascii)
|
||||||
{
|
{
|
||||||
o->write_characters("\\ufffd", 6);
|
o.write_characters("\\ufffd", 6);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
o->write_characters("\xEF\xBF\xBD", 3);
|
o.write_characters("\xEF\xBF\xBD", 3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -696,7 +699,7 @@ class serializer
|
|||||||
// special case for "0"
|
// special case for "0"
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
o->write_character('0');
|
o.write_character('0');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,7 +753,7 @@ class serializer
|
|||||||
*(--buffer_ptr) = static_cast<char>('0' + abs_value);
|
*(--buffer_ptr) = static_cast<char>('0' + abs_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
o->write_characters(number_buffer.data(), n_chars);
|
o.write_characters(number_buffer.data(), n_chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -766,7 +769,7 @@ class serializer
|
|||||||
// NaN / inf
|
// NaN / inf
|
||||||
if (not std::isfinite(x))
|
if (not std::isfinite(x))
|
||||||
{
|
{
|
||||||
o->write_characters("null", 4);
|
o.write_characters("null", 4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,7 +790,7 @@ class serializer
|
|||||||
char* begin = number_buffer.data();
|
char* begin = number_buffer.data();
|
||||||
char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
|
char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
|
||||||
|
|
||||||
o->write_characters(begin, static_cast<size_t>(end - begin));
|
o.write_characters(begin, static_cast<size_t>(end - begin));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
|
void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
|
||||||
@ -823,7 +826,7 @@ class serializer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
|
o.write_characters(number_buffer.data(), static_cast<std::size_t>(len));
|
||||||
|
|
||||||
// determine if need to append ".0"
|
// determine if need to append ".0"
|
||||||
const bool value_is_int_like =
|
const bool value_is_int_like =
|
||||||
@ -835,7 +838,7 @@ class serializer
|
|||||||
|
|
||||||
if (value_is_int_like)
|
if (value_is_int_like)
|
||||||
{
|
{
|
||||||
o->write_characters(".0", 2);
|
o.write_characters(".0", 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -922,7 +925,7 @@ class serializer
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/// the output of the serializer
|
/// the output of the serializer
|
||||||
output_adapter_t<char> o = nullptr;
|
output_adapter_t o;
|
||||||
|
|
||||||
/// a (hopefully) large enough character buffer
|
/// a (hopefully) large enough character buffer
|
||||||
std::array<char, 64> number_buffer{{}};
|
std::array<char, 64> number_buffer{{}};
|
||||||
|
|||||||
@ -174,7 +174,8 @@ class basic_json
|
|||||||
|
|
||||||
template<typename BasicJsonType, typename InputType>
|
template<typename BasicJsonType, typename InputType>
|
||||||
friend class ::nlohmann::detail::parser;
|
friend class ::nlohmann::detail::parser;
|
||||||
friend ::nlohmann::detail::serializer<basic_json>;
|
template<typename BasicJsonType, typename OutputAdapterType>
|
||||||
|
friend class ::nlohmann::detail::serializer;
|
||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
friend class ::nlohmann::detail::iter_impl;
|
friend class ::nlohmann::detail::iter_impl;
|
||||||
template<typename BasicJsonType, typename CharType>
|
template<typename BasicJsonType, typename CharType>
|
||||||
@ -211,14 +212,12 @@ class basic_json
|
|||||||
using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
|
using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
|
||||||
template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
|
template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
|
||||||
|
|
||||||
template<typename CharType>
|
|
||||||
using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
|
|
||||||
|
|
||||||
template<typename InputType>
|
template<typename InputType>
|
||||||
using binary_reader = ::nlohmann::detail::binary_reader<basic_json, 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> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
|
||||||
|
|
||||||
using serializer = ::nlohmann::detail::serializer<basic_json>;
|
template<typename OutputAdapterType>
|
||||||
|
using serializer = ::nlohmann::detail::serializer<basic_json, OutputAdapterType>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_t = detail::value_t;
|
using value_t = detail::value_t;
|
||||||
@ -2269,7 +2268,23 @@ class basic_json
|
|||||||
const error_handler_t error_handler = error_handler_t::strict) const
|
const error_handler_t error_handler = error_handler_t::strict) const
|
||||||
{
|
{
|
||||||
string_t result;
|
string_t result;
|
||||||
serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
|
|
||||||
|
dump_to(result, indent, indent_char, ensure_ascii, error_handler);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename OutputType>
|
||||||
|
void dump_to(OutputType&& dst,
|
||||||
|
const int indent = -1,
|
||||||
|
const char indent_char = ' ',
|
||||||
|
const bool ensure_ascii = false,
|
||||||
|
const error_handler_t error_handler = error_handler_t::strict) const
|
||||||
|
{
|
||||||
|
auto oa = detail::output_adapter(std::forward<OutputType>(dst));
|
||||||
|
using serializer_t = serializer<decltype(oa)>;
|
||||||
|
serializer<decltype(oa)> s(std::move(oa), indent_char, error_handler);
|
||||||
|
|
||||||
if (indent >= 0)
|
if (indent >= 0)
|
||||||
{
|
{
|
||||||
@ -2279,10 +2294,7 @@ class basic_json
|
|||||||
{
|
{
|
||||||
s.dump(*this, false, ensure_ascii, 0);
|
s.dump(*this, false, ensure_ascii, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief return the type of the JSON value (explicit)
|
@brief return the type of the JSON value (explicit)
|
||||||
|
|
||||||
@ -6516,9 +6528,7 @@ class basic_json
|
|||||||
// reset width to 0 for subsequent calls to this stream
|
// reset width to 0 for subsequent calls to this stream
|
||||||
o.width(0);
|
o.width(0);
|
||||||
|
|
||||||
// do the actual serialization
|
j.dump_to(o, indentation, ' ', false);
|
||||||
serializer s(detail::output_adapter<char>(o), o.fill());
|
|
||||||
s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6976,14 +6986,11 @@ class basic_json
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
|
template<typename OutputType>
|
||||||
|
static void to_cbor(const basic_json& j, OutputType&& o)
|
||||||
{
|
{
|
||||||
binary_writer<uint8_t>(o).write_cbor(j);
|
auto oa = detail::output_adapter(std::forward<OutputType>(o));
|
||||||
}
|
binary_writer<decltype(oa)>(std::move(oa)).write_cbor(j);
|
||||||
|
|
||||||
static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
|
|
||||||
{
|
|
||||||
binary_writer<char>(o).write_cbor(j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -7073,15 +7080,13 @@ class basic_json
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
|
template<typename OutputType>
|
||||||
|
static void to_msgpack(const basic_json& j, OutputType&& o)
|
||||||
{
|
{
|
||||||
binary_writer<uint8_t>(o).write_msgpack(j);
|
auto oa = detail::output_adapter(std::forward<OutputType>(o));
|
||||||
|
binary_writer<decltype(oa)>(std::move(oa)).write_msgpack(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
|
|
||||||
{
|
|
||||||
binary_writer<char>(o).write_msgpack(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a UBJSON serialization of a given JSON value
|
@brief create a UBJSON serialization of a given JSON value
|
||||||
@ -7174,23 +7179,18 @@ class basic_json
|
|||||||
const bool use_type = false)
|
const bool use_type = false)
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> result;
|
std::vector<uint8_t> result;
|
||||||
to_ubjson(j, result, use_size, use_type);
|
to_ubjson(j, std::back_inserter(result), use_size, use_type);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
|
template<typename OutputType>
|
||||||
|
static void to_ubjson(const basic_json& j, OutputType&& o,
|
||||||
const bool use_size = false, const bool use_type = false)
|
const bool use_size = false, const bool use_type = false)
|
||||||
{
|
{
|
||||||
binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
|
auto oa = detail::output_adapter(std::forward<OutputType>(o));
|
||||||
|
binary_writer<decltype(oa)>(std::move(oa)).write_ubjson(j, use_size, use_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
|
|
||||||
const bool use_size = false, const bool use_type = false)
|
|
||||||
{
|
|
||||||
binary_writer<char>(o).write_ubjson(j, use_size, use_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Serializes the given JSON object `j` to BSON and returns a vector
|
@brief Serializes the given JSON object `j` to BSON and returns a vector
|
||||||
containing the corresponding BSON-representation.
|
containing the corresponding BSON-representation.
|
||||||
@ -7262,17 +7262,11 @@ class basic_json
|
|||||||
@pre The input `j` shall be an object: `j.is_object() == true`
|
@pre The input `j` shall be an object: `j.is_object() == true`
|
||||||
@sa @ref to_bson(const basic_json&)
|
@sa @ref to_bson(const basic_json&)
|
||||||
*/
|
*/
|
||||||
static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
|
template<typename OutputType>
|
||||||
|
static void to_bson(const basic_json& j, OutputType&& o)
|
||||||
{
|
{
|
||||||
binary_writer<uint8_t>(o).write_bson(j);
|
auto oa = detail::output_adapter(std::forward<OutputType>(o));
|
||||||
}
|
binary_writer<decltype(oa)>(std::move(oa)).write_bson(j);
|
||||||
|
|
||||||
/*!
|
|
||||||
@copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
|
|
||||||
*/
|
|
||||||
static void to_bson(const basic_json& j, detail::output_adapter<char> o)
|
|
||||||
{
|
|
||||||
binary_writer<char>(o).write_bson(j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1587,7 +1587,7 @@ TEST_CASE("parser class")
|
|||||||
CHECK (j_filtered1.size() == 2);
|
CHECK (j_filtered1.size() == 2);
|
||||||
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
|
CHECK (j_filtered1 == json({1, {{"qux", "baz"}}}));
|
||||||
|
|
||||||
json j_filtered2 = json::parse(structured_array, [](int, json::parse_event_t e, const json & /*parsed*/)
|
json j_filtered2 = json::parse(structured_array, [](int, json::parse_event_t e, const json& /*parsed*/)
|
||||||
{
|
{
|
||||||
if (e == json::parse_event_t::object_end)
|
if (e == json::parse_event_t::object_end)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -42,7 +42,8 @@ void check_escaped(const char* original, const char* escaped = "", const bool en
|
|||||||
void check_escaped(const char* original, const char* escaped, const bool ensure_ascii)
|
void check_escaped(const char* original, const char* escaped, const bool ensure_ascii)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
json::serializer s(nlohmann::detail::output_adapter<char>(ss), ' ');
|
auto oa = nlohmann::detail::output_adapter(ss);
|
||||||
|
json::serializer<decltype(oa)> s(std::move(oa), ' ');
|
||||||
s.dump_escaped(original, ensure_ascii);
|
s.dump_escaped(original, ensure_ascii);
|
||||||
CHECK(ss.str() == escaped);
|
CHECK(ss.str() == escaped);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user