11 #include <nlohmann/detail/input/binary_reader.hpp>
12 #include <nlohmann/detail/macro_scope.hpp>
13 #include <nlohmann/detail/output/output_adapters.hpp>
26 template<
typename BasicJsonType,
typename CharType>
29 using string_t =
typename BasicJsonType::string_t;
30 using binary_t =
typename BasicJsonType::binary_t;
31 using number_float_t =
typename BasicJsonType::number_float_t;
54 write_bson_object(*j.m_value.object);
60 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
74 oa->write_character(to_char_type(0xF6));
80 oa->write_character(j.m_value.boolean
82 : to_char_type(0xF4));
88 if (j.m_value.number_integer >= 0)
93 if (j.m_value.number_integer <= 0x17)
95 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
97 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
99 oa->write_character(to_char_type(0x18));
100 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
102 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
104 oa->write_character(to_char_type(0x19));
105 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
107 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
109 oa->write_character(to_char_type(0x1A));
110 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
114 oa->write_character(to_char_type(0x1B));
115 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
122 const auto positive_number = -1 - j.m_value.number_integer;
123 if (j.m_value.number_integer >= -24)
125 write_number(
static_cast<std::uint8_t>(0x20 + positive_number));
127 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
129 oa->write_character(to_char_type(0x38));
130 write_number(
static_cast<std::uint8_t>(positive_number));
132 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
134 oa->write_character(to_char_type(0x39));
137 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
139 oa->write_character(to_char_type(0x3A));
144 oa->write_character(to_char_type(0x3B));
153 if (j.m_value.number_unsigned <= 0x17)
155 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
157 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
159 oa->write_character(to_char_type(0x18));
160 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
162 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
164 oa->write_character(to_char_type(0x19));
165 write_number(
static_cast<std::uint16_t>(j.m_value.number_unsigned));
167 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
169 oa->write_character(to_char_type(0x1A));
170 write_number(
static_cast<std::uint32_t>(j.m_value.number_unsigned));
174 oa->write_character(to_char_type(0x1B));
175 write_number(
static_cast<std::uint64_t>(j.m_value.number_unsigned));
182 if (std::isnan(j.m_value.number_float))
185 oa->write_character(to_char_type(0xF9));
186 oa->write_character(to_char_type(0x7E));
187 oa->write_character(to_char_type(0x00));
189 else if (std::isinf(j.m_value.number_float))
192 oa->write_character(to_char_type(0xf9));
193 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
194 oa->write_character(to_char_type(0x00));
198 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
206 const auto N = j.m_value.string->size();
211 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
213 oa->write_character(to_char_type(0x78));
216 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
218 oa->write_character(to_char_type(0x79));
221 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
223 oa->write_character(to_char_type(0x7A));
227 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
229 oa->write_character(to_char_type(0x7B));
235 oa->write_characters(
236 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
237 j.m_value.string->size());
244 const auto N = j.m_value.array->size();
249 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
251 oa->write_character(to_char_type(0x98));
254 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
256 oa->write_character(to_char_type(0x99));
259 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
261 oa->write_character(to_char_type(0x9A));
265 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
267 oa->write_character(to_char_type(0x9B));
273 for (
const auto& el : *j.m_value.array)
282 if (j.m_value.binary->has_subtype())
285 write_number(j.m_value.binary->subtype());
289 const auto N = j.m_value.binary->size();
294 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
296 oa->write_character(to_char_type(0x58));
299 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
301 oa->write_character(to_char_type(0x59));
304 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
306 oa->write_character(to_char_type(0x5A));
310 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
312 oa->write_character(to_char_type(0x5B));
318 oa->write_characters(
319 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
328 const auto N = j.m_value.object->size();
333 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
335 oa->write_character(to_char_type(0xB8));
338 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
340 oa->write_character(to_char_type(0xB9));
343 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
345 oa->write_character(to_char_type(0xBA));
349 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
351 oa->write_character(to_char_type(0xBB));
357 for (
const auto& el : *j.m_value.object)
379 oa->write_character(to_char_type(0xC0));
385 oa->write_character(j.m_value.boolean
387 : to_char_type(0xC2));
393 if (j.m_value.number_integer >= 0)
398 if (j.m_value.number_unsigned < 128)
401 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
403 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
406 oa->write_character(to_char_type(0xCC));
407 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
409 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
412 oa->write_character(to_char_type(0xCD));
413 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
415 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
418 oa->write_character(to_char_type(0xCE));
419 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
421 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
424 oa->write_character(to_char_type(0xCF));
425 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
430 if (j.m_value.number_integer >= -32)
433 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
435 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
436 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
439 oa->write_character(to_char_type(0xD0));
440 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
442 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
443 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
446 oa->write_character(to_char_type(0xD1));
447 write_number(
static_cast<std::int16_t>(j.m_value.number_integer));
449 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
450 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
453 oa->write_character(to_char_type(0xD2));
454 write_number(
static_cast<std::int32_t>(j.m_value.number_integer));
456 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
457 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
460 oa->write_character(to_char_type(0xD3));
461 write_number(
static_cast<std::int64_t>(j.m_value.number_integer));
469 if (j.m_value.number_unsigned < 128)
472 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
474 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
477 oa->write_character(to_char_type(0xCC));
478 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
480 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
483 oa->write_character(to_char_type(0xCD));
484 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
486 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
489 oa->write_character(to_char_type(0xCE));
490 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
492 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
495 oa->write_character(to_char_type(0xCF));
496 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
503 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
510 const auto N = j.m_value.string->size();
516 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
519 oa->write_character(to_char_type(0xD9));
522 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
525 oa->write_character(to_char_type(0xDA));
528 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
531 oa->write_character(to_char_type(0xDB));
536 oa->write_characters(
537 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
538 j.m_value.string->size());
545 const auto N = j.m_value.array->size();
551 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
554 oa->write_character(to_char_type(0xDC));
557 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
560 oa->write_character(to_char_type(0xDD));
565 for (
const auto& el : *j.m_value.array)
576 const bool use_ext = j.m_value.binary->has_subtype();
579 const auto N = j.m_value.binary->size();
580 if (N <= (std::numeric_limits<std::uint8_t>::max)())
616 oa->write_character(to_char_type(output_type));
622 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
628 oa->write_character(to_char_type(output_type));
631 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
637 oa->write_character(to_char_type(output_type));
644 write_number(
static_cast<std::int8_t>(j.m_value.binary->subtype()));
648 oa->write_characters(
649 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
658 const auto N = j.m_value.object->size();
662 write_number(
static_cast<std::uint8_t>(0x80 | (N & 0xF)));
664 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
667 oa->write_character(to_char_type(0xDE));
670 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
673 oa->write_character(to_char_type(0xDF));
678 for (
const auto& el : *j.m_value.object)
698 const bool use_type,
const bool add_prefix =
true)
706 oa->write_character(to_char_type(
'Z'));
715 oa->write_character(j.m_value.boolean
717 : to_char_type(
'F'));
724 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
730 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
736 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
744 oa->write_character(to_char_type(
'S'));
746 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
747 oa->write_characters(
748 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
749 j.m_value.string->size());
757 oa->write_character(to_char_type(
'['));
760 bool prefix_required =
true;
761 if (use_type && !j.m_value.array->empty())
763 JSON_ASSERT(use_count);
764 const CharType first_prefix = ubjson_prefix(j.front());
765 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
766 [
this, first_prefix](
const BasicJsonType & v)
768 return ubjson_prefix(v) == first_prefix;
773 prefix_required =
false;
774 oa->write_character(to_char_type(
'$'));
775 oa->write_character(first_prefix);
781 oa->write_character(to_char_type(
'#'));
782 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
785 for (
const auto& el : *j.m_value.array)
792 oa->write_character(to_char_type(
']'));
802 oa->write_character(to_char_type(
'['));
805 if (use_type && !j.m_value.binary->empty())
807 JSON_ASSERT(use_count);
808 oa->write_character(to_char_type(
'$'));
809 oa->write_character(
'U');
814 oa->write_character(to_char_type(
'#'));
815 write_number_with_ubjson_prefix(j.m_value.binary->size(),
true);
820 oa->write_characters(
821 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
822 j.m_value.binary->size());
826 for (
size_t i = 0; i < j.m_value.binary->size(); ++i)
828 oa->write_character(to_char_type(
'U'));
829 oa->write_character(j.m_value.binary->data()[i]);
835 oa->write_character(to_char_type(
']'));
845 oa->write_character(to_char_type(
'{'));
848 bool prefix_required =
true;
849 if (use_type && !j.m_value.object->empty())
851 JSON_ASSERT(use_count);
852 const CharType first_prefix = ubjson_prefix(j.front());
853 const bool same_prefix = std::all_of(j.begin(), j.end(),
854 [
this, first_prefix](
const BasicJsonType & v)
856 return ubjson_prefix(v) == first_prefix;
861 prefix_required =
false;
862 oa->write_character(to_char_type(
'$'));
863 oa->write_character(first_prefix);
869 oa->write_character(to_char_type(
'#'));
870 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
873 for (
const auto& el : *j.m_value.object)
875 write_number_with_ubjson_prefix(el.first.size(),
true);
876 oa->write_characters(
877 reinterpret_cast<const CharType*
>(el.first.c_str()),
879 write_ubjson(el.second, use_count, use_type, prefix_required);
884 oa->write_character(to_char_type(
'}'));
904 static std::size_t calc_bson_entry_header_size(
const string_t& name)
906 const auto it = name.find(
static_cast<typename string_t::value_type
>(0));
907 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
909 JSON_THROW(out_of_range::create(409,
910 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")"));
913 return 1ul + name.size() + 1u;
919 void write_bson_entry_header(
const string_t& name,
922 oa->write_character(to_char_type(element_type));
923 oa->write_characters(
924 reinterpret_cast<const CharType*
>(name.c_str()),
931 void write_bson_boolean(
const string_t& name,
934 write_bson_entry_header(name, 0x08);
935 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
941 void write_bson_double(
const string_t& name,
944 write_bson_entry_header(name, 0x01);
945 write_number<double, true>(value);
951 static std::size_t calc_bson_string_size(
const string_t& value)
959 void write_bson_string(
const string_t& name,
960 const string_t& value)
962 write_bson_entry_header(name, 0x02);
965 oa->write_characters(
966 reinterpret_cast<const CharType*
>(
value.c_str()),
973 void write_bson_null(
const string_t& name)
975 write_bson_entry_header(name, 0x0A);
981 static std::size_t calc_bson_integer_size(
const std::int64_t value)
983 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
991 void write_bson_integer(
const string_t& name,
994 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
996 write_bson_entry_header(name, 0x10);
997 write_number<std::int32_t, true>(
static_cast<std::int32_t>(value));
1001 write_bson_entry_header(name, 0x12);
1002 write_number<std::int64_t, true>(
static_cast<std::int64_t>(value));
1009 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value) noexcept
1011 return (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1019 void write_bson_unsigned(
const string_t& name,
1022 if (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1024 write_bson_entry_header(name, 0x10 );
1025 write_number<std::int32_t, true>(
static_cast<std::int32_t>(value));
1027 else if (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1029 write_bson_entry_header(name, 0x12 );
1030 write_number<std::int64_t, true>(
static_cast<std::int64_t>(value));
1034 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(value) +
" cannot be represented by BSON as it does not fit int64"));
1041 void write_bson_object_entry(
const string_t& name,
1042 const typename BasicJsonType::object_t& value)
1044 write_bson_entry_header(name, 0x03);
1045 write_bson_object(value);
1051 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
1053 std::size_t array_index = 0ul;
1055 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result,
const typename BasicJsonType::array_t::value_type & el)
1057 return result + calc_bson_element_size(std::to_string(array_index++), el);
1060 return sizeof(
std::int32_t) + embedded_document_size + 1ul;
1066 static std::size_t calc_bson_binary_size(
const typename BasicJsonType::binary_t& value)
1074 void write_bson_array(
const string_t& name,
1075 const typename BasicJsonType::array_t& value)
1077 write_bson_entry_header(name, 0x04);
1078 write_number<std::int32_t, true>(
static_cast<std::int32_t>(calc_bson_array_size(value)));
1080 std::size_t array_index = 0ul;
1082 for (
const auto& el : value)
1084 write_bson_element(std::to_string(array_index++), el);
1087 oa->write_character(to_char_type(0x00));
1093 void write_bson_binary(
const string_t& name,
1094 const binary_t& value)
1096 write_bson_entry_header(name, 0x05);
1101 oa->write_characters(
reinterpret_cast<const CharType*
>(
value.data()),
value.size());
1108 static std::size_t calc_bson_element_size(
const string_t& name,
1109 const BasicJsonType& j)
1111 const auto header_size = calc_bson_entry_header_size(name);
1115 return header_size + calc_bson_object_size(*j.m_value.object);
1118 return header_size + calc_bson_array_size(*j.m_value.array);
1121 return header_size + calc_bson_binary_size(*j.m_value.binary);
1124 return header_size + 1ul;
1127 return header_size + 8ul;
1130 return header_size + calc_bson_integer_size(j.m_value.number_integer);
1133 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
1136 return header_size + calc_bson_string_size(*j.m_value.string);
1139 return header_size + 0ul;
1156 void write_bson_element(
const string_t& name,
1157 const BasicJsonType& j)
1162 return write_bson_object_entry(name, *j.m_value.object);
1165 return write_bson_array(name, *j.m_value.array);
1168 return write_bson_binary(name, *j.m_value.binary);
1171 return write_bson_boolean(name, j.m_value.boolean);
1174 return write_bson_double(name, j.m_value.number_float);
1177 return write_bson_integer(name, j.m_value.number_integer);
1180 return write_bson_unsigned(name, j.m_value.number_unsigned);
1183 return write_bson_string(name, *j.m_value.string);
1186 return write_bson_null(name);
1202 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
1204 std::size_t document_size = std::accumulate(
value.begin(),
value.end(), std::size_t(0),
1205 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
1207 return result += calc_bson_element_size(el.first, el.second);
1217 void write_bson_object(
const typename BasicJsonType::object_t& value)
1219 write_number<std::int32_t, true>(
static_cast<std::int32_t>(calc_bson_object_size(value)));
1221 for (
const auto& el : value)
1223 write_bson_element(el.first, el.second);
1226 oa->write_character(to_char_type(0x00));
1233 static constexpr CharType get_cbor_float_prefix(
float )
1235 return to_char_type(0xFA);
1238 static constexpr CharType get_cbor_float_prefix(
double )
1240 return to_char_type(0xFB);
1247 static constexpr CharType get_msgpack_float_prefix(
float )
1249 return to_char_type(0xCA);
1252 static constexpr CharType get_msgpack_float_prefix(
double )
1254 return to_char_type(0xCB);
1262 template<
typename NumberType,
typename std::enable_if<
1263 std::is_floating_point<NumberType>::value,
int>::type = 0>
1264 void write_number_with_ubjson_prefix(
const NumberType n,
1265 const bool add_prefix)
1269 oa->write_character(get_ubjson_float_prefix(n));
1275 template<
typename NumberType,
typename std::enable_if<
1276 std::is_unsigned<NumberType>::value,
int>::type = 0>
1277 void write_number_with_ubjson_prefix(
const NumberType n,
1278 const bool add_prefix)
1280 if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1284 oa->write_character(to_char_type(
'i'));
1288 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
1292 oa->write_character(to_char_type(
'U'));
1296 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1300 oa->write_character(to_char_type(
'I'));
1304 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1308 oa->write_character(to_char_type(
'l'));
1312 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1316 oa->write_character(to_char_type(
'L'));
1324 oa->write_character(to_char_type(
'H'));
1327 const auto number = BasicJsonType(n).dump();
1328 write_number_with_ubjson_prefix(number.size(),
true);
1329 for (std::size_t i = 0; i < number.size(); ++i)
1331 oa->write_character(to_char_type(
static_cast<std::uint8_t>(number[i])));
1337 template <
typename NumberType,
typename std::enable_if <
1338 std::is_signed<NumberType>::value&&
1339 !std::is_floating_point<NumberType>::value,
int >::type = 0 >
1340 void write_number_with_ubjson_prefix(
const NumberType n,
1341 const bool add_prefix)
1343 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
1347 oa->write_character(to_char_type(
'i'));
1351 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)()))
1355 oa->write_character(to_char_type(
'U'));
1359 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
1363 oa->write_character(to_char_type(
'I'));
1367 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
1371 oa->write_character(to_char_type(
'l'));
1375 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
1379 oa->write_character(to_char_type(
'L'));
1388 oa->write_character(to_char_type(
'H'));
1391 const auto number = BasicJsonType(n).dump();
1392 write_number_with_ubjson_prefix(number.size(),
true);
1393 for (std::size_t i = 0; i < number.size(); ++i)
1395 oa->write_character(to_char_type(
static_cast<std::uint8_t>(number[i])));
1404 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept
1412 return j.m_value.boolean ?
'T' :
'F';
1416 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
1420 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
1424 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
1428 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
1432 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
1442 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1446 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
1450 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1454 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1458 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1467 return get_ubjson_float_prefix(j.m_value.number_float);
1484 static constexpr CharType get_ubjson_float_prefix(
float )
1489 static constexpr CharType get_ubjson_float_prefix(
double )
1509 template<
typename NumberType,
bool OutputIsLittleEndian = false>
1510 void write_number(
const NumberType n)
1513 std::array<CharType,
sizeof(NumberType)> vec;
1514 std::memcpy(vec.data(), &n,
sizeof(NumberType));
1517 if (is_little_endian != OutputIsLittleEndian)
1520 std::reverse(vec.begin(), vec.end());
1523 oa->write_characters(vec.data(),
sizeof(NumberType));
1528 if (
static_cast<double>(n) >=
static_cast<double>(std::numeric_limits<float>::lowest()) &&
1529 static_cast<double>(n) <=
static_cast<double>((std::numeric_limits<float>::max)()) &&
1530 static_cast<double>(
static_cast<float>(n)) ==
static_cast<double>(n))
1532 oa->write_character(format == detail::input_format_t::cbor
1533 ? get_cbor_float_prefix(
static_cast<float>(n))
1534 : get_msgpack_float_prefix(
static_cast<float>(n)));
1535 write_number(
static_cast<float>(n));
1539 oa->write_character(format == detail::input_format_t::cbor
1540 ? get_cbor_float_prefix(n)
1541 : get_msgpack_float_prefix(n));
1551 template <
typename C = CharType,
1552 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * =
nullptr >
1553 static constexpr CharType to_char_type(
std::uint8_t x) noexcept
1555 return *
reinterpret_cast<char*
>(&x);
1558 template <
typename C = CharType,
1559 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * =
nullptr >
1562 static_assert(
sizeof(
std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
1563 static_assert(std::is_trivial<CharType>::value,
"CharType must be trivial");
1565 std::memcpy(&result, &x,
sizeof(x));
1569 template<
typename C = CharType,
1570 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
1571 static constexpr CharType to_char_type(
std::uint8_t x) noexcept
1576 template <
typename InputCharType,
typename C = CharType,
1578 std::is_signed<C>::value &&
1579 std::is_signed<char>::value &&
1580 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
1582 static constexpr CharType to_char_type(InputCharType x) noexcept
1589 const bool is_little_endian = little_endianess();
1592 output_adapter_t<CharType> oa =
nullptr;
serialization to CBOR and MessagePack values
Definition: binary_writer.hpp:28
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: binary_writer.hpp:697
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: binary_writer.hpp:39
void write_bson(const BasicJsonType &j)
Definition: binary_writer.hpp:48
void write_cbor(const BasicJsonType &j)
Definition: binary_writer.hpp:68
void write_msgpack(const BasicJsonType &j)
Definition: binary_writer.hpp:373
zip_uint64_t uint64_t
zip_uint64_t_t typedef.
Definition: zip.hpp:108
zip_int64_t int64_t
zip_int64_t typedef.
Definition: zip.hpp:103
zip_uint32_t uint32_t
zip_uint32_t typedef.
Definition: zip.hpp:98
zip_int32_t int32_t
zip_int32_t typedef.
Definition: zip.hpp:93
zip_uint8_t uint8_t
zip_uint8_t typedef.
Definition: zip.hpp:78
zip_uint16_t uint16_t
zip_uint16_t typedef.
Definition: zip.hpp:88
zip_int16_t int16_t
zip_int16_t typedef.
Definition: zip.hpp:83
zip_int8_t int8_t
zip_int8_t typedef.
Definition: zip.hpp:73
@ number_integer
number value (signed integer)
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
@ value
the parser finished reading a JSON value
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: output_adapters.hpp:27
input_format_t
the supported input formats
Definition: input_adapters.hpp:23
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9