🚧 add integer support

This commit is contained in:
Niels Lohmann
2021-09-04 14:54:54 +02:00
parent c7440a6da2
commit e6518ff2d6
3 changed files with 566 additions and 28 deletions

View File

@@ -944,27 +944,42 @@ class binary_writer
break;
}
case value_t::number_unsigned:
{
if (j.m_value.number_unsigned > std::numeric_limits<std::int64_t>::max())
{
JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BON8 as it does not fit int64", j));
}
write_bon8_integer(static_cast<typename BasicJsonType::number_integer_t>(j.m_value.number_unsigned));
break;
}
case value_t::number_integer:
{
write_bon8_integer(j.m_value.number_integer);
break;
}
case value_t::number_float:
{
// special values
if (j.m_value.number_float == -1.0)
{
oa->write_character(to_char_type(0xFB));
break;
}
if (j.m_value.number_float == 0.0)
else if (j.m_value.number_float == 0.0 && !std::signbit(j.m_value.number_float))
{
oa->write_character(to_char_type(0xFC));
break;
}
if (j.m_value.number_float == 1.0)
else if (j.m_value.number_float == 1.0)
{
oa->write_character(to_char_type(0xFD));
break;
}
// write float with prefix
write_compact_float(j.m_value.number_float, detail::input_format_t::bon8);
else
{
// write float with prefix
write_compact_float(j.m_value.number_float, detail::input_format_t::bon8);
}
break;
}
@@ -1680,6 +1695,79 @@ class binary_writer
// BON8 //
//////////
void write_bon8_integer(typename BasicJsonType::number_integer_t value)
{
if (value < std::numeric_limits<std::int32_t>::min() || value > std::numeric_limits<std::int32_t>::max())
{
// 64 bit integers
oa->write_character(0x8D);
write_number(static_cast<std::int64_t>(value));
}
else if (value < -33554432 || value > 67108863)
{
// 32 bit integers
oa->write_character(0x8C);
write_number(static_cast<std::int32_t>(value));
}
else if (value < -262144)
{
JSON_ASSERT(value >= -33554432);
value = -value - 1;
oa->write_character(0xF0 + (value >> 22 & 0x07));
oa->write_character(0xC0 + (value >> 16 & 0x3F));
oa->write_character(value >> 8);
oa->write_character(value);
}
else if (value < -1920)
{
JSON_ASSERT(value >= -262144);
value = -value - 1;
oa->write_character(0xE0 + (value >> 14 & 0x0F));
oa->write_character(0xC0 + (value >> 8 & 0x3F));
oa->write_character(value);
}
else if (value < -10)
{
JSON_ASSERT(value >= -1920);
value = -value - 1;
oa->write_character(0xC2 + (value >> 6 & 0x1F));
oa->write_character(0xC0 + (value & 0x3F));
}
else if (value < 0)
{
JSON_ASSERT(value >= -10);
value = -value - 1;
oa->write_character(0xB8 + value);
}
else if (value <= 39)
{
JSON_ASSERT(value >= 0);
oa->write_character(0x90 + value);
}
else if (value <= 3839)
{
JSON_ASSERT(value >= 0);
oa->write_character(0xC2 + (value >> 7 & 0x1F));
oa->write_character(value & 0x7F);
}
else if (value <= 524287)
{
JSON_ASSERT(value >= 0);
oa->write_character(0xE0 + (value >> 15 & 0x0F));
oa->write_character(value >> 8 & 0x7F);
oa->write_character(value);
}
else
{
JSON_ASSERT(value >= 0);
JSON_ASSERT(value <= 67108863);
oa->write_character(0xF0 + (value >> 23 & 0x17));
oa->write_character(value >> 16 & 0x7F);
oa->write_character(value >> 8);
oa->write_character(value);
}
}
static constexpr CharType get_bon8_float_prefix(float /*unused*/)
{
return to_char_type(0x8E);
@@ -1735,13 +1823,13 @@ class binary_writer
switch (format)
{
case input_format_t::cbor:
get_cbor_float_prefix(static_cast<float>(n));
oa->write_character(get_cbor_float_prefix(static_cast<float>(n)));
break;
case input_format_t::msgpack:
get_msgpack_float_prefix(static_cast<float>(n));
oa->write_character(get_msgpack_float_prefix(static_cast<float>(n)));
break;
case input_format_t::bon8:
get_bon8_float_prefix(static_cast<float>(n));
oa->write_character(get_bon8_float_prefix(static_cast<float>(n)));
break;
default:
break;
@@ -1753,13 +1841,13 @@ class binary_writer
switch (format)
{
case input_format_t::cbor:
get_cbor_float_prefix(n);
oa->write_character(get_cbor_float_prefix(n));
break;
case input_format_t::msgpack:
get_msgpack_float_prefix(n);
oa->write_character(get_msgpack_float_prefix(n));
break;
case input_format_t::bon8:
get_bon8_float_prefix(n);
oa->write_character(get_bon8_float_prefix(n));
break;
default:
break;