move is_bjdata to an optional param to write_ubjson

This commit is contained in:
Qianqian Fang 2022-02-21 10:35:13 -05:00
parent 53855c14d4
commit 7589b604aa
3 changed files with 114 additions and 112 deletions

View File

@ -39,7 +39,7 @@ class binary_writer
@param[in] adapter output adapter to write to
@param[in] is_bjdata_ a boolean, if true, output is BJData format, default is false
*/
explicit binary_writer(output_adapter_t<CharType> adapter, const bool is_bjdata_ = false) : oa(std::move(adapter)), is_bjdata(is_bjdata_)
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
{
JSON_ASSERT(oa);
}
@ -727,7 +727,8 @@ class binary_writer
@param[in] add_prefix whether prefixes need to be used for this value
*/
void write_ubjson(const BasicJsonType& j, const bool use_count,
const bool use_type, const bool add_prefix = true)
const bool use_type, const bool add_prefix = true,
const bool use_bjdata = false)
{
switch (j.type())
{
@ -753,19 +754,19 @@ class binary_writer
case value_t::number_integer:
{
write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
break;
}
case value_t::number_unsigned:
{
write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
break;
}
case value_t::number_float:
{
write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
break;
}
@ -775,7 +776,7 @@ class binary_writer
{
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, use_bjdata);
oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
j.m_value.string->size());
@ -793,11 +794,11 @@ class binary_writer
if (use_type && !j.m_value.array->empty())
{
JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front());
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
[this, first_prefix](const BasicJsonType & v)
[this, first_prefix, use_bjdata](const BasicJsonType & v)
{
return ubjson_prefix(v) == first_prefix;
return ubjson_prefix(v, use_bjdata) == first_prefix;
});
if (same_prefix)
@ -811,7 +812,7 @@ class binary_writer
if (use_count)
{
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, use_bjdata);
}
for (const auto& el : *j.m_value.array)
@ -844,7 +845,7 @@ class binary_writer
if (use_count)
{
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, use_bjdata);
}
if (use_type)
@ -881,11 +882,11 @@ class binary_writer
if (use_type && !j.m_value.object->empty())
{
JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front());
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin(), j.end(),
[this, first_prefix](const BasicJsonType & v)
[this, first_prefix, use_bjdata](const BasicJsonType & v)
{
return ubjson_prefix(v) == first_prefix;
return ubjson_prefix(v, use_bjdata) == first_prefix;
});
if (same_prefix)
@ -899,12 +900,12 @@ class binary_writer
if (use_count)
{
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, use_bjdata);
}
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, use_bjdata);
oa->write_characters(
reinterpret_cast<const CharType*>(el.first.c_str()),
el.first.size());
@ -1296,20 +1297,22 @@ class binary_writer
template<typename NumberType, typename std::enable_if<
std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
const bool add_prefix,
const bool use_bjdata = false)
{
if (add_prefix)
{
oa->write_character(get_ubjson_float_prefix(n));
}
write_number(n);
write_number(n, use_bjdata);
}
// UBJSON: write number (unsigned integer)
template<typename NumberType, typename std::enable_if<
std::is_unsigned<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
const bool add_prefix,
const bool use_bjdata = false)
{
if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
{
@ -1317,7 +1320,7 @@ class binary_writer
{
oa->write_character(to_char_type('i')); // int8
}
write_number(static_cast<std::uint8_t>(n));
write_number(static_cast<std::uint8_t>(n), use_bjdata);
}
else if (n <= (std::numeric_limits<std::uint8_t>::max)())
{
@ -1325,7 +1328,7 @@ class binary_writer
{
oa->write_character(to_char_type('U')); // uint8
}
write_number(static_cast<std::uint8_t>(n));
write_number(static_cast<std::uint8_t>(n), use_bjdata);
}
else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
{
@ -1333,15 +1336,15 @@ class binary_writer
{
oa->write_character(to_char_type('I')); // int16
}
write_number(static_cast<std::int16_t>(n));
write_number(static_cast<std::int16_t>(n), use_bjdata);
}
else if (is_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
{
if (add_prefix)
{
oa->write_character(to_char_type('u')); // uint16 - bjdata only
}
write_number(static_cast<std::uint16_t>(n));
write_number(static_cast<std::uint16_t>(n), use_bjdata);
}
else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
{
@ -1349,15 +1352,15 @@ class binary_writer
{
oa->write_character(to_char_type('l')); // int32
}
write_number(static_cast<std::int32_t>(n));
write_number(static_cast<std::int32_t>(n), use_bjdata);
}
else if (is_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
{
if (add_prefix)
{
oa->write_character(to_char_type('m')); // uint32 - bjdata only
}
write_number(static_cast<std::uint32_t>(n));
write_number(static_cast<std::uint32_t>(n), use_bjdata);
}
else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
{
@ -1365,15 +1368,15 @@ class binary_writer
{
oa->write_character(to_char_type('L')); // int64
}
write_number(static_cast<std::int64_t>(n));
write_number(static_cast<std::int64_t>(n), use_bjdata);
}
else if (is_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
{
if (add_prefix)
{
oa->write_character(to_char_type('M')); // uint64 - bjdata only
}
write_number(static_cast<std::uint64_t>(n));
write_number(static_cast<std::uint64_t>(n), use_bjdata);
}
else
{
@ -1383,7 +1386,7 @@ class binary_writer
}
const auto number = BasicJsonType(n).dump();
write_number_with_ubjson_prefix(number.size(), true);
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])));
@ -1396,7 +1399,8 @@ class binary_writer
std::is_signed<NumberType>::value&&
!std::is_floating_point<NumberType>::value, int >::type = 0 >
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
const bool add_prefix,
const bool use_bjdata = false)
{
if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
{
@ -1404,7 +1408,7 @@ class binary_writer
{
oa->write_character(to_char_type('i')); // int8
}
write_number(static_cast<std::int8_t>(n));
write_number(static_cast<std::int8_t>(n), use_bjdata);
}
else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
{
@ -1412,7 +1416,7 @@ class binary_writer
{
oa->write_character(to_char_type('U')); // uint8
}
write_number(static_cast<std::uint8_t>(n));
write_number(static_cast<std::uint8_t>(n), use_bjdata);
}
else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
{
@ -1420,15 +1424,15 @@ class binary_writer
{
oa->write_character(to_char_type('I')); // int16
}
write_number(static_cast<std::int16_t>(n));
write_number(static_cast<std::int16_t>(n), use_bjdata);
}
else if (is_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
{
if (add_prefix)
{
oa->write_character(to_char_type('u')); // uint16 - bjdata only
}
write_number(static_cast<uint16_t>(n));
write_number(static_cast<uint16_t>(n), use_bjdata);
}
else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
{
@ -1436,15 +1440,15 @@ class binary_writer
{
oa->write_character(to_char_type('l')); // int32
}
write_number(static_cast<std::int32_t>(n));
write_number(static_cast<std::int32_t>(n), use_bjdata);
}
else if (is_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
{
if (add_prefix)
{
oa->write_character(to_char_type('m')); // uint32 - bjdata only
}
write_number(static_cast<uint32_t>(n));
write_number(static_cast<uint32_t>(n), use_bjdata);
}
else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
{
@ -1452,7 +1456,7 @@ class binary_writer
{
oa->write_character(to_char_type('L')); // int64
}
write_number(static_cast<std::int64_t>(n));
write_number(static_cast<std::int64_t>(n), use_bjdata);
}
// LCOV_EXCL_START
else
@ -1463,7 +1467,7 @@ class binary_writer
}
const auto number = BasicJsonType(n).dump();
write_number_with_ubjson_prefix(number.size(), true);
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])));
@ -1475,7 +1479,7 @@ class binary_writer
/*!
@brief determine the type prefix of container values
*/
CharType ubjson_prefix(const BasicJsonType& j) const noexcept
CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata = false) const noexcept
{
switch (j.type())
{
@ -1499,7 +1503,7 @@ class binary_writer
{
return 'I';
}
if (is_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
{
return 'u';
}
@ -1507,7 +1511,7 @@ class binary_writer
{
return 'l';
}
if (is_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
{
return 'm';
}
@ -1533,7 +1537,7 @@ class binary_writer
{
return 'I';
}
if (is_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
{
return 'u';
}
@ -1541,7 +1545,7 @@ class binary_writer
{
return 'l';
}
if (is_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
{
return 'm';
}
@ -1549,7 +1553,7 @@ class binary_writer
{
return 'L';
}
if (is_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
{
return 'M';
}
@ -1604,14 +1608,14 @@ class binary_writer
on big endian systems.
*/
template<typename NumberType, bool OutputIsLittleEndian = false>
void write_number(const NumberType n)
void write_number(const NumberType n, const bool use_bjdata = false)
{
// step 1: write number to array of length NumberType
std::array<CharType, sizeof(NumberType)> vec{};
std::memcpy(vec.data(), &n, sizeof(NumberType));
// step 2: write array to output (with possible reordering)
if (is_little_endian != (OutputIsLittleEndian || is_bjdata))
if (is_little_endian != (OutputIsLittleEndian || use_bjdata))
{
// reverse byte order prior to conversion if necessary
std::reverse(vec.begin(), vec.end());
@ -1692,9 +1696,6 @@ class binary_writer
/// whether we can assume little endianness
const bool is_little_endian = little_endianness();
/// whether to write in bjdata format
const bool is_bjdata = false;
/// the output
output_adapter_t<CharType> oa = nullptr;
};

View File

@ -3970,20 +3970,20 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool use_type = false)
{
std::vector<std::uint8_t> result;
to_bjdata(j, result, use_size, use_type);
to_bjdata(j, result, use_size, use_type, true);
return result;
}
static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<std::uint8_t>(o, true).write_ubjson(j, use_size, use_type);
binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true);
}
static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<char>(o, true).write_ubjson(j, use_size, use_type);
binary_writer<char>(o).write_ubjson(j, use_size, use_type, true);
}
/// @brief create a BSON serialization of a given JSON value

View File

@ -13863,7 +13863,7 @@ class binary_writer
@param[in] adapter output adapter to write to
@param[in] is_bjdata_ a boolean, if true, output is BJData format, default is false
*/
explicit binary_writer(output_adapter_t<CharType> adapter, const bool is_bjdata_ = false) : oa(std::move(adapter)), is_bjdata(is_bjdata_)
explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
{
JSON_ASSERT(oa);
}
@ -14551,7 +14551,8 @@ class binary_writer
@param[in] add_prefix whether prefixes need to be used for this value
*/
void write_ubjson(const BasicJsonType& j, const bool use_count,
const bool use_type, const bool add_prefix = true)
const bool use_type, const bool add_prefix = true,
const bool use_bjdata = false)
{
switch (j.type())
{
@ -14577,19 +14578,19 @@ class binary_writer
case value_t::number_integer:
{
write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
break;
}
case value_t::number_unsigned:
{
write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
break;
}
case value_t::number_float:
{
write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
break;
}
@ -14599,7 +14600,7 @@ class binary_writer
{
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, use_bjdata);
oa->write_characters(
reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
j.m_value.string->size());
@ -14617,11 +14618,11 @@ class binary_writer
if (use_type && !j.m_value.array->empty())
{
JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front());
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
[this, first_prefix](const BasicJsonType & v)
[this, first_prefix, use_bjdata](const BasicJsonType & v)
{
return ubjson_prefix(v) == first_prefix;
return ubjson_prefix(v, use_bjdata) == first_prefix;
});
if (same_prefix)
@ -14635,7 +14636,7 @@ class binary_writer
if (use_count)
{
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, use_bjdata);
}
for (const auto& el : *j.m_value.array)
@ -14668,7 +14669,7 @@ class binary_writer
if (use_count)
{
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, use_bjdata);
}
if (use_type)
@ -14705,11 +14706,11 @@ class binary_writer
if (use_type && !j.m_value.object->empty())
{
JSON_ASSERT(use_count);
const CharType first_prefix = ubjson_prefix(j.front());
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin(), j.end(),
[this, first_prefix](const BasicJsonType & v)
[this, first_prefix, use_bjdata](const BasicJsonType & v)
{
return ubjson_prefix(v) == first_prefix;
return ubjson_prefix(v, use_bjdata) == first_prefix;
});
if (same_prefix)
@ -14723,12 +14724,12 @@ class binary_writer
if (use_count)
{
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, use_bjdata);
}
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, use_bjdata);
oa->write_characters(
reinterpret_cast<const CharType*>(el.first.c_str()),
el.first.size());
@ -15120,20 +15121,22 @@ class binary_writer
template<typename NumberType, typename std::enable_if<
std::is_floating_point<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
const bool add_prefix,
const bool use_bjdata = false)
{
if (add_prefix)
{
oa->write_character(get_ubjson_float_prefix(n));
}
write_number(n);
write_number(n, use_bjdata);
}
// UBJSON: write number (unsigned integer)
template<typename NumberType, typename std::enable_if<
std::is_unsigned<NumberType>::value, int>::type = 0>
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
const bool add_prefix,
const bool use_bjdata = false)
{
if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
{
@ -15141,7 +15144,7 @@ class binary_writer
{
oa->write_character(to_char_type('i')); // int8
}
write_number(static_cast<std::uint8_t>(n));
write_number(static_cast<std::uint8_t>(n), use_bjdata);
}
else if (n <= (std::numeric_limits<std::uint8_t>::max)())
{
@ -15149,7 +15152,7 @@ class binary_writer
{
oa->write_character(to_char_type('U')); // uint8
}
write_number(static_cast<std::uint8_t>(n));
write_number(static_cast<std::uint8_t>(n), use_bjdata);
}
else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
{
@ -15157,15 +15160,15 @@ class binary_writer
{
oa->write_character(to_char_type('I')); // int16
}
write_number(static_cast<std::int16_t>(n));
write_number(static_cast<std::int16_t>(n), use_bjdata);
}
else if (is_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
{
if (add_prefix)
{
oa->write_character(to_char_type('u')); // uint16 - bjdata only
}
write_number(static_cast<std::uint16_t>(n));
write_number(static_cast<std::uint16_t>(n), use_bjdata);
}
else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
{
@ -15173,15 +15176,15 @@ class binary_writer
{
oa->write_character(to_char_type('l')); // int32
}
write_number(static_cast<std::int32_t>(n));
write_number(static_cast<std::int32_t>(n), use_bjdata);
}
else if (is_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
{
if (add_prefix)
{
oa->write_character(to_char_type('m')); // uint32 - bjdata only
}
write_number(static_cast<std::uint32_t>(n));
write_number(static_cast<std::uint32_t>(n), use_bjdata);
}
else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
{
@ -15189,15 +15192,15 @@ class binary_writer
{
oa->write_character(to_char_type('L')); // int64
}
write_number(static_cast<std::int64_t>(n));
write_number(static_cast<std::int64_t>(n), use_bjdata);
}
else if (is_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
{
if (add_prefix)
{
oa->write_character(to_char_type('M')); // uint64 - bjdata only
}
write_number(static_cast<std::uint64_t>(n));
write_number(static_cast<std::uint64_t>(n), use_bjdata);
}
else
{
@ -15207,7 +15210,7 @@ class binary_writer
}
const auto number = BasicJsonType(n).dump();
write_number_with_ubjson_prefix(number.size(), true);
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])));
@ -15220,7 +15223,8 @@ class binary_writer
std::is_signed<NumberType>::value&&
!std::is_floating_point<NumberType>::value, int >::type = 0 >
void write_number_with_ubjson_prefix(const NumberType n,
const bool add_prefix)
const bool add_prefix,
const bool use_bjdata = false)
{
if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
{
@ -15228,7 +15232,7 @@ class binary_writer
{
oa->write_character(to_char_type('i')); // int8
}
write_number(static_cast<std::int8_t>(n));
write_number(static_cast<std::int8_t>(n), use_bjdata);
}
else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
{
@ -15236,7 +15240,7 @@ class binary_writer
{
oa->write_character(to_char_type('U')); // uint8
}
write_number(static_cast<std::uint8_t>(n));
write_number(static_cast<std::uint8_t>(n), use_bjdata);
}
else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
{
@ -15244,15 +15248,15 @@ class binary_writer
{
oa->write_character(to_char_type('I')); // int16
}
write_number(static_cast<std::int16_t>(n));
write_number(static_cast<std::int16_t>(n), use_bjdata);
}
else if (is_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
{
if (add_prefix)
{
oa->write_character(to_char_type('u')); // uint16 - bjdata only
}
write_number(static_cast<uint16_t>(n));
write_number(static_cast<uint16_t>(n), use_bjdata);
}
else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
{
@ -15260,15 +15264,15 @@ class binary_writer
{
oa->write_character(to_char_type('l')); // int32
}
write_number(static_cast<std::int32_t>(n));
write_number(static_cast<std::int32_t>(n), use_bjdata);
}
else if (is_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
{
if (add_prefix)
{
oa->write_character(to_char_type('m')); // uint32 - bjdata only
}
write_number(static_cast<uint32_t>(n));
write_number(static_cast<uint32_t>(n), use_bjdata);
}
else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
{
@ -15276,7 +15280,7 @@ class binary_writer
{
oa->write_character(to_char_type('L')); // int64
}
write_number(static_cast<std::int64_t>(n));
write_number(static_cast<std::int64_t>(n), use_bjdata);
}
// LCOV_EXCL_START
else
@ -15287,7 +15291,7 @@ class binary_writer
}
const auto number = BasicJsonType(n).dump();
write_number_with_ubjson_prefix(number.size(), true);
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])));
@ -15299,7 +15303,7 @@ class binary_writer
/*!
@brief determine the type prefix of container values
*/
CharType ubjson_prefix(const BasicJsonType& j) const noexcept
CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata = false) const noexcept
{
switch (j.type())
{
@ -15323,7 +15327,7 @@ class binary_writer
{
return 'I';
}
if (is_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
{
return 'u';
}
@ -15331,7 +15335,7 @@ class binary_writer
{
return 'l';
}
if (is_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
{
return 'm';
}
@ -15357,7 +15361,7 @@ class binary_writer
{
return 'I';
}
if (is_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
{
return 'u';
}
@ -15365,7 +15369,7 @@ class binary_writer
{
return 'l';
}
if (is_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
{
return 'm';
}
@ -15373,7 +15377,7 @@ class binary_writer
{
return 'L';
}
if (is_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
{
return 'M';
}
@ -15428,14 +15432,14 @@ class binary_writer
on big endian systems.
*/
template<typename NumberType, bool OutputIsLittleEndian = false>
void write_number(const NumberType n)
void write_number(const NumberType n, const bool use_bjdata = false)
{
// step 1: write number to array of length NumberType
std::array<CharType, sizeof(NumberType)> vec{};
std::memcpy(vec.data(), &n, sizeof(NumberType));
// step 2: write array to output (with possible reordering)
if (is_little_endian != (OutputIsLittleEndian || is_bjdata))
if (is_little_endian != (OutputIsLittleEndian || use_bjdata))
{
// reverse byte order prior to conversion if necessary
std::reverse(vec.begin(), vec.end());
@ -15516,9 +15520,6 @@ class binary_writer
/// whether we can assume little endianness
const bool is_little_endian = little_endianness();
/// whether to write in bjdata format
const bool is_bjdata = false;
/// the output
output_adapter_t<CharType> oa = nullptr;
};
@ -21740,20 +21741,20 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool use_type = false)
{
std::vector<std::uint8_t> result;
to_bjdata(j, result, use_size, use_type);
to_bjdata(j, result, use_size, use_type, true);
return result;
}
static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<std::uint8_t>(o, true).write_ubjson(j, use_size, use_type);
binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true);
}
static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
const bool use_size = false, const bool use_type = false)
{
binary_writer<char>(o, true).write_ubjson(j, use_size, use_type);
binary_writer<char>(o).write_ubjson(j, use_size, use_type, true);
}
/// @brief create a BSON serialization of a given JSON value