in AirLib/include/common/common_utils/json.hpp [6652:6886]
static void to_msgpack_internal(const basic_json& j, std::vector<uint8_t>& v)
{
switch (j.type())
{
case value_t::null:
{
// nil
v.push_back(0xc0);
break;
}
case value_t::boolean:
{
// true and false
v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
break;
}
case value_t::number_integer:
{
if (j.m_value.number_integer >= 0)
{
// MessagePack does not differentiate between positive
// signed integers and unsigned integers. Therefore, we
// used the code from the value_t::number_unsigned case
// here.
if (j.m_value.number_unsigned < 128)
{
// positive fixnum
add_to_vector(v, 1, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
{
// uint 8
v.push_back(0xcc);
add_to_vector(v, 1, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
{
// uint 16
v.push_back(0xcd);
add_to_vector(v, 2, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
{
// uint 32
v.push_back(0xce);
add_to_vector(v, 4, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
{
// uint 64
v.push_back(0xcf);
add_to_vector(v, 8, j.m_value.number_unsigned);
}
}
else
{
if (j.m_value.number_integer >= -32)
{
// negative fixnum
add_to_vector(v, 1, j.m_value.number_integer);
}
else if (j.m_value.number_integer >= std::numeric_limits<int8_t>::min() and j.m_value.number_integer <= std::numeric_limits<int8_t>::max())
{
// int 8
v.push_back(0xd0);
add_to_vector(v, 1, j.m_value.number_integer);
}
else if (j.m_value.number_integer >= std::numeric_limits<int16_t>::min() and j.m_value.number_integer <= std::numeric_limits<int16_t>::max())
{
// int 16
v.push_back(0xd1);
add_to_vector(v, 2, j.m_value.number_integer);
}
else if (j.m_value.number_integer >= std::numeric_limits<int32_t>::min() and j.m_value.number_integer <= std::numeric_limits<int32_t>::max())
{
// int 32
v.push_back(0xd2);
add_to_vector(v, 4, j.m_value.number_integer);
}
else if (j.m_value.number_integer >= std::numeric_limits<int64_t>::min() and j.m_value.number_integer <= std::numeric_limits<int64_t>::max())
{
// int 64
v.push_back(0xd3);
add_to_vector(v, 8, j.m_value.number_integer);
}
}
break;
}
case value_t::number_unsigned:
{
if (j.m_value.number_unsigned < 128)
{
// positive fixnum
add_to_vector(v, 1, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
{
// uint 8
v.push_back(0xcc);
add_to_vector(v, 1, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
{
// uint 16
v.push_back(0xcd);
add_to_vector(v, 2, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
{
// uint 32
v.push_back(0xce);
add_to_vector(v, 4, j.m_value.number_unsigned);
}
else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
{
// uint 64
v.push_back(0xcf);
add_to_vector(v, 8, j.m_value.number_unsigned);
}
break;
}
case value_t::number_float:
{
// float 64
v.push_back(0xcb);
const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
for (size_t i = 0; i < 8; ++i)
{
v.push_back(helper[7 - i]);
}
break;
}
case value_t::string:
{
const auto N = j.m_value.string->size();
if (N <= 31)
{
// fixstr
v.push_back(static_cast<uint8_t>(0xa0 | N));
}
else if (N <= 255)
{
// str 8
v.push_back(0xd9);
add_to_vector(v, 1, N);
}
else if (N <= 65535)
{
// str 16
v.push_back(0xda);
add_to_vector(v, 2, N);
}
else if (N <= 4294967295)
{
// str 32
v.push_back(0xdb);
add_to_vector(v, 4, N);
}
// append string
std::copy(j.m_value.string->begin(), j.m_value.string->end(),
std::back_inserter(v));
break;
}
case value_t::array:
{
const auto N = j.m_value.array->size();
if (N <= 15)
{
// fixarray
v.push_back(static_cast<uint8_t>(0x90 | N));
}
else if (N <= 0xffff)
{
// array 16
v.push_back(0xdc);
add_to_vector(v, 2, N);
}
else if (N <= 0xffffffff)
{
// array 32
v.push_back(0xdd);
add_to_vector(v, 4, N);
}
// append each element
for (const auto& el : *j.m_value.array)
{
to_msgpack_internal(el, v);
}
break;
}
case value_t::object:
{
const auto N = j.m_value.object->size();
if (N <= 15)
{
// fixmap
v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
}
else if (N <= 65535)
{
// map 16
v.push_back(0xde);
add_to_vector(v, 2, N);
}
else if (N <= 4294967295)
{
// map 32
v.push_back(0xdf);
add_to_vector(v, 4, N);
}
// append each element
for (const auto& el : *j.m_value.object)
{
to_msgpack_internal(el.first, v);
to_msgpack_internal(el.second, v);
}
break;
}
default:
{
break;
}
}
}