12 #include <nlohmann/detail/input/binary_reader.hpp>
13 #include <nlohmann/detail/macro_scope.hpp>
14 #include <nlohmann/detail/output/output_adapters.hpp>
27 template<
typename BasicJsonType,
typename CharType>
30 using string_t =
typename BasicJsonType::string_t;
31 using binary_t =
typename BasicJsonType::binary_t;
32 using number_float_t =
typename BasicJsonType::number_float_t;
55 write_bson_object(*j.m_value.object);
70 JSON_THROW(type_error::create(317,
"to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
84 oa->write_character(to_char_type(0xF6));
90 oa->write_character(j.m_value.boolean
92 : to_char_type(0xF4));
98 if (j.m_value.number_integer >= 0)
103 if (j.m_value.number_integer <= 0x17)
105 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
107 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
109 oa->write_character(to_char_type(0x18));
110 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
112 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
114 oa->write_character(to_char_type(0x19));
115 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
117 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
119 oa->write_character(to_char_type(0x1A));
120 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
124 oa->write_character(to_char_type(0x1B));
125 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
132 const auto positive_number = -1 - j.m_value.number_integer;
133 if (j.m_value.number_integer >= -24)
135 write_number(
static_cast<std::uint8_t>(0x20 + positive_number));
137 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
139 oa->write_character(to_char_type(0x38));
140 write_number(
static_cast<std::uint8_t>(positive_number));
142 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
144 oa->write_character(to_char_type(0x39));
147 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
149 oa->write_character(to_char_type(0x3A));
154 oa->write_character(to_char_type(0x3B));
163 if (j.m_value.number_unsigned <= 0x17)
165 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
167 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
169 oa->write_character(to_char_type(0x18));
170 write_number(
static_cast<std::uint8_t>(j.m_value.number_unsigned));
172 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
174 oa->write_character(to_char_type(0x19));
175 write_number(
static_cast<std::uint16_t>(j.m_value.number_unsigned));
177 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
179 oa->write_character(to_char_type(0x1A));
180 write_number(
static_cast<std::uint32_t>(j.m_value.number_unsigned));
184 oa->write_character(to_char_type(0x1B));
185 write_number(
static_cast<std::uint64_t>(j.m_value.number_unsigned));
192 if (std::isnan(j.m_value.number_float))
195 oa->write_character(to_char_type(0xF9));
196 oa->write_character(to_char_type(0x7E));
197 oa->write_character(to_char_type(0x00));
199 else if (std::isinf(j.m_value.number_float))
202 oa->write_character(to_char_type(0xf9));
203 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
204 oa->write_character(to_char_type(0x00));
208 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
216 const auto N = j.m_value.string->size();
221 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
223 oa->write_character(to_char_type(0x78));
226 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
228 oa->write_character(to_char_type(0x79));
231 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
233 oa->write_character(to_char_type(0x7A));
237 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
239 oa->write_character(to_char_type(0x7B));
245 oa->write_characters(
246 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
247 j.m_value.string->size());
254 const auto N = j.m_value.array->size();
259 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
261 oa->write_character(to_char_type(0x98));
264 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
266 oa->write_character(to_char_type(0x99));
269 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
271 oa->write_character(to_char_type(0x9A));
275 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
277 oa->write_character(to_char_type(0x9B));
283 for (
const auto& el : *j.m_value.array)
292 if (j.m_value.binary->has_subtype())
294 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
297 write_number(
static_cast<std::uint8_t>(j.m_value.binary->subtype()));
299 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
302 write_number(
static_cast<std::uint16_t>(j.m_value.binary->subtype()));
304 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
307 write_number(
static_cast<std::uint32_t>(j.m_value.binary->subtype()));
309 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
312 write_number(
static_cast<std::uint64_t>(j.m_value.binary->subtype()));
317 const auto N = j.m_value.binary->size();
322 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
324 oa->write_character(to_char_type(0x58));
327 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
329 oa->write_character(to_char_type(0x59));
332 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
334 oa->write_character(to_char_type(0x5A));
338 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
340 oa->write_character(to_char_type(0x5B));
346 oa->write_characters(
347 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
356 const auto N = j.m_value.object->size();
361 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
363 oa->write_character(to_char_type(0xB8));
366 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
368 oa->write_character(to_char_type(0xB9));
371 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
373 oa->write_character(to_char_type(0xBA));
377 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
379 oa->write_character(to_char_type(0xBB));
385 for (
const auto& el : *j.m_value.object)
408 oa->write_character(to_char_type(0xC0));
414 oa->write_character(j.m_value.boolean
416 : to_char_type(0xC2));
422 if (j.m_value.number_integer >= 0)
427 if (j.m_value.number_unsigned < 128)
430 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
432 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
435 oa->write_character(to_char_type(0xCC));
436 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
438 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
441 oa->write_character(to_char_type(0xCD));
442 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
444 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
447 oa->write_character(to_char_type(0xCE));
448 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
450 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
453 oa->write_character(to_char_type(0xCF));
454 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
459 if (j.m_value.number_integer >= -32)
462 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
464 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
465 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
468 oa->write_character(to_char_type(0xD0));
469 write_number(
static_cast<std::int8_t>(j.m_value.number_integer));
471 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
472 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
475 oa->write_character(to_char_type(0xD1));
476 write_number(
static_cast<std::int16_t>(j.m_value.number_integer));
478 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
479 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
482 oa->write_character(to_char_type(0xD2));
483 write_number(
static_cast<std::int32_t>(j.m_value.number_integer));
485 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
486 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
489 oa->write_character(to_char_type(0xD3));
490 write_number(
static_cast<std::int64_t>(j.m_value.number_integer));
498 if (j.m_value.number_unsigned < 128)
501 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
503 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
506 oa->write_character(to_char_type(0xCC));
507 write_number(
static_cast<std::uint8_t>(j.m_value.number_integer));
509 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
512 oa->write_character(to_char_type(0xCD));
513 write_number(
static_cast<std::uint16_t>(j.m_value.number_integer));
515 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
518 oa->write_character(to_char_type(0xCE));
519 write_number(
static_cast<std::uint32_t>(j.m_value.number_integer));
521 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
524 oa->write_character(to_char_type(0xCF));
525 write_number(
static_cast<std::uint64_t>(j.m_value.number_integer));
532 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
539 const auto N = j.m_value.string->size();
545 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
548 oa->write_character(to_char_type(0xD9));
551 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
554 oa->write_character(to_char_type(0xDA));
557 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
560 oa->write_character(to_char_type(0xDB));
565 oa->write_characters(
566 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
567 j.m_value.string->size());
574 const auto N = j.m_value.array->size();
580 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
583 oa->write_character(to_char_type(0xDC));
586 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
589 oa->write_character(to_char_type(0xDD));
594 for (
const auto& el : *j.m_value.array)
605 const bool use_ext = j.m_value.binary->has_subtype();
608 const auto N = j.m_value.binary->size();
609 if (N <= (std::numeric_limits<std::uint8_t>::max)())
645 oa->write_character(to_char_type(output_type));
651 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
657 oa->write_character(to_char_type(output_type));
660 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
666 oa->write_character(to_char_type(output_type));
673 write_number(
static_cast<std::int8_t>(j.m_value.binary->subtype()));
677 oa->write_characters(
678 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
687 const auto N = j.m_value.object->size();
691 write_number(
static_cast<std::uint8_t>(0x80 | (N & 0xF)));
693 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
696 oa->write_character(to_char_type(0xDE));
699 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
702 oa->write_character(to_char_type(0xDF));
707 for (
const auto& el : *j.m_value.object)
728 const bool use_type,
const bool add_prefix =
true)
736 oa->write_character(to_char_type(
'Z'));
745 oa->write_character(j.m_value.boolean
747 : to_char_type(
'F'));
754 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
760 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
766 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
774 oa->write_character(to_char_type(
'S'));
776 write_number_with_ubjson_prefix(j.m_value.string->size(),
true);
777 oa->write_characters(
778 reinterpret_cast<const CharType*
>(j.m_value.string->c_str()),
779 j.m_value.string->size());
787 oa->write_character(to_char_type(
'['));
790 bool prefix_required =
true;
791 if (use_type && !j.m_value.array->empty())
793 JSON_ASSERT(use_count);
794 const CharType first_prefix = ubjson_prefix(j.front());
795 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
796 [
this, first_prefix](
const BasicJsonType & v)
798 return ubjson_prefix(v) == first_prefix;
803 prefix_required =
false;
804 oa->write_character(to_char_type(
'$'));
805 oa->write_character(first_prefix);
811 oa->write_character(to_char_type(
'#'));
812 write_number_with_ubjson_prefix(j.m_value.array->size(),
true);
815 for (
const auto& el : *j.m_value.array)
822 oa->write_character(to_char_type(
']'));
832 oa->write_character(to_char_type(
'['));
835 if (use_type && !j.m_value.binary->empty())
837 JSON_ASSERT(use_count);
838 oa->write_character(to_char_type(
'$'));
839 oa->write_character(
'U');
844 oa->write_character(to_char_type(
'#'));
845 write_number_with_ubjson_prefix(j.m_value.binary->size(),
true);
850 oa->write_characters(
851 reinterpret_cast<const CharType*
>(j.m_value.binary->data()),
852 j.m_value.binary->size());
856 for (
size_t i = 0; i < j.m_value.binary->size(); ++i)
858 oa->write_character(to_char_type(
'U'));
859 oa->write_character(j.m_value.binary->data()[i]);
865 oa->write_character(to_char_type(
']'));
875 oa->write_character(to_char_type(
'{'));
878 bool prefix_required =
true;
879 if (use_type && !j.m_value.object->empty())
881 JSON_ASSERT(use_count);
882 const CharType first_prefix = ubjson_prefix(j.front());
883 const bool same_prefix = std::all_of(j.begin(), j.end(),
884 [
this, first_prefix](
const BasicJsonType & v)
886 return ubjson_prefix(v) == first_prefix;
891 prefix_required =
false;
892 oa->write_character(to_char_type(
'$'));
893 oa->write_character(first_prefix);
899 oa->write_character(to_char_type(
'#'));
900 write_number_with_ubjson_prefix(j.m_value.object->size(),
true);
903 for (
const auto& el : *j.m_value.object)
905 write_number_with_ubjson_prefix(el.first.size(),
true);
906 oa->write_characters(
907 reinterpret_cast<const CharType*
>(el.first.c_str()),
909 write_ubjson(el.second, use_count, use_type, prefix_required);
914 oa->write_character(to_char_type(
'}'));
935 static std::size_t calc_bson_entry_header_size(
const string_t& name,
const BasicJsonType& j)
937 const auto it = name.find(
static_cast<typename string_t::value_type
>(0));
938 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
940 JSON_THROW(out_of_range::create(409,
"BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) +
")", j));
941 static_cast<void>(j);
944 return 1ul + name.size() + 1u;
950 void write_bson_entry_header(
const string_t& name,
953 oa->write_character(to_char_type(element_type));
954 oa->write_characters(
955 reinterpret_cast<const CharType*
>(name.c_str()),
962 void write_bson_boolean(
const string_t& name,
965 write_bson_entry_header(name, 0x08);
966 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
972 void write_bson_double(
const string_t& name,
975 write_bson_entry_header(name, 0x01);
976 write_number<double, true>(value);
982 static std::size_t calc_bson_string_size(
const string_t& value)
990 void write_bson_string(
const string_t& name,
991 const string_t& value)
993 write_bson_entry_header(name, 0x02);
996 oa->write_characters(
997 reinterpret_cast<const CharType*
>(
value.c_str()),
1004 void write_bson_null(
const string_t& name)
1006 write_bson_entry_header(name, 0x0A);
1012 static std::size_t calc_bson_integer_size(
const std::int64_t value)
1014 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
1022 void write_bson_integer(
const string_t& name,
1025 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
1027 write_bson_entry_header(name, 0x10);
1028 write_number<std::int32_t, true>(
static_cast<std::int32_t>(value));
1032 write_bson_entry_header(name, 0x12);
1033 write_number<std::int64_t, true>(
static_cast<std::int64_t>(value));
1040 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t value) noexcept
1042 return (value <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1050 void write_bson_unsigned(
const string_t& name,
1051 const BasicJsonType& j)
1053 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1055 write_bson_entry_header(name, 0x10 );
1056 write_number<std::int32_t, true>(
static_cast<std::int32_t>(j.m_value.number_unsigned));
1058 else if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1060 write_bson_entry_header(name, 0x12 );
1061 write_number<std::int64_t, true>(
static_cast<std::int64_t>(j.m_value.number_unsigned));
1065 JSON_THROW(out_of_range::create(407,
"integer number " + std::to_string(j.m_value.number_unsigned) +
" cannot be represented by BSON as it does not fit int64", j));
1072 void write_bson_object_entry(
const string_t& name,
1073 const typename BasicJsonType::object_t& value)
1075 write_bson_entry_header(name, 0x03);
1076 write_bson_object(value);
1082 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t& value)
1084 std::size_t array_index = 0ul;
1086 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)
1088 return result + calc_bson_element_size(std::to_string(array_index++), el);
1091 return sizeof(
std::int32_t) + embedded_document_size + 1ul;
1097 static std::size_t calc_bson_binary_size(
const typename BasicJsonType::binary_t& value)
1105 void write_bson_array(
const string_t& name,
1106 const typename BasicJsonType::array_t& value)
1108 write_bson_entry_header(name, 0x04);
1109 write_number<std::int32_t, true>(
static_cast<std::int32_t>(calc_bson_array_size(value)));
1111 std::size_t array_index = 0ul;
1113 for (
const auto& el : value)
1115 write_bson_element(std::to_string(array_index++), el);
1118 oa->write_character(to_char_type(0x00));
1124 void write_bson_binary(
const string_t& name,
1125 const binary_t& value)
1127 write_bson_entry_header(name, 0x05);
1132 oa->write_characters(
reinterpret_cast<const CharType*
>(
value.data()),
value.size());
1139 static std::size_t calc_bson_element_size(
const string_t& name,
1140 const BasicJsonType& j)
1142 const auto header_size = calc_bson_entry_header_size(name, j);
1146 return header_size + calc_bson_object_size(*j.m_value.object);
1149 return header_size + calc_bson_array_size(*j.m_value.array);
1152 return header_size + calc_bson_binary_size(*j.m_value.binary);
1155 return header_size + 1ul;
1158 return header_size + 8ul;
1161 return header_size + calc_bson_integer_size(j.m_value.number_integer);
1164 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
1167 return header_size + calc_bson_string_size(*j.m_value.string);
1170 return header_size + 0ul;
1187 void write_bson_element(
const string_t& name,
1188 const BasicJsonType& j)
1193 return write_bson_object_entry(name, *j.m_value.object);
1196 return write_bson_array(name, *j.m_value.array);
1199 return write_bson_binary(name, *j.m_value.binary);
1202 return write_bson_boolean(name, j.m_value.boolean);
1205 return write_bson_double(name, j.m_value.number_float);
1208 return write_bson_integer(name, j.m_value.number_integer);
1211 return write_bson_unsigned(name, j);
1214 return write_bson_string(name, *j.m_value.string);
1217 return write_bson_null(name);
1234 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t& value)
1236 std::size_t document_size = std::accumulate(
value.begin(),
value.end(), std::size_t(0),
1237 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
1239 return result += calc_bson_element_size(el.first, el.second);
1249 void write_bson_object(
const typename BasicJsonType::object_t& value)
1251 write_number<std::int32_t, true>(
static_cast<std::int32_t>(calc_bson_object_size(value)));
1253 for (
const auto& el : value)
1255 write_bson_element(el.first, el.second);
1258 oa->write_character(to_char_type(0x00));
1265 static constexpr CharType get_cbor_float_prefix(
float )
1267 return to_char_type(0xFA);
1270 static constexpr CharType get_cbor_float_prefix(
double )
1272 return to_char_type(0xFB);
1279 static constexpr CharType get_msgpack_float_prefix(
float )
1281 return to_char_type(0xCA);
1284 static constexpr CharType get_msgpack_float_prefix(
double )
1286 return to_char_type(0xCB);
1294 template<
typename NumberType,
typename std::enable_if<
1295 std::is_floating_point<NumberType>::value,
int>::type = 0>
1296 void write_number_with_ubjson_prefix(
const NumberType n,
1297 const bool add_prefix)
1301 oa->write_character(get_ubjson_float_prefix(n));
1307 template<
typename NumberType,
typename std::enable_if<
1308 std::is_unsigned<NumberType>::value,
int>::type = 0>
1309 void write_number_with_ubjson_prefix(
const NumberType n,
1310 const bool add_prefix)
1312 if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1316 oa->write_character(to_char_type(
'i'));
1320 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
1324 oa->write_character(to_char_type(
'U'));
1328 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1332 oa->write_character(to_char_type(
'I'));
1336 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1340 oa->write_character(to_char_type(
'l'));
1344 else if (n <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1348 oa->write_character(to_char_type(
'L'));
1356 oa->write_character(to_char_type(
'H'));
1359 const auto number = BasicJsonType(n).dump();
1360 write_number_with_ubjson_prefix(number.size(),
true);
1361 for (std::size_t i = 0; i < number.size(); ++i)
1363 oa->write_character(to_char_type(
static_cast<std::uint8_t>(number[i])));
1369 template <
typename NumberType,
typename std::enable_if <
1370 std::is_signed<NumberType>::value&&
1371 !std::is_floating_point<NumberType>::value,
int >::type = 0 >
1372 void write_number_with_ubjson_prefix(
const NumberType n,
1373 const bool add_prefix)
1375 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
1379 oa->write_character(to_char_type(
'i'));
1383 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)()))
1387 oa->write_character(to_char_type(
'U'));
1391 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
1395 oa->write_character(to_char_type(
'I'));
1399 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
1403 oa->write_character(to_char_type(
'l'));
1407 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
1411 oa->write_character(to_char_type(
'L'));
1420 oa->write_character(to_char_type(
'H'));
1423 const auto number = BasicJsonType(n).dump();
1424 write_number_with_ubjson_prefix(number.size(),
true);
1425 for (std::size_t i = 0; i < number.size(); ++i)
1427 oa->write_character(to_char_type(
static_cast<std::uint8_t>(number[i])));
1436 CharType ubjson_prefix(
const BasicJsonType& j)
const noexcept
1444 return j.m_value.boolean ?
'T' :
'F';
1448 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)())
1452 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)())
1456 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)())
1460 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)())
1464 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)())
1474 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1478 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
1482 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1486 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1490 if (j.m_value.number_unsigned <=
static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1499 return get_ubjson_float_prefix(j.m_value.number_float);
1517 static constexpr CharType get_ubjson_float_prefix(
float )
1522 static constexpr CharType get_ubjson_float_prefix(
double )
1542 template<
typename NumberType,
bool OutputIsLittleEndian = false>
1543 void write_number(
const NumberType n)
1546 std::array<CharType,
sizeof(NumberType)> vec{};
1547 std::memcpy(vec.data(), &n,
sizeof(NumberType));
1550 if (is_little_endian != OutputIsLittleEndian)
1553 std::reverse(vec.begin(), vec.end());
1556 oa->write_characters(vec.data(),
sizeof(NumberType));
1562 #pragma GCC diagnostic push
1563 #pragma GCC diagnostic ignored "-Wfloat-equal"
1565 if (
static_cast<double>(n) >=
static_cast<double>(std::numeric_limits<float>::lowest()) &&
1566 static_cast<double>(n) <=
static_cast<double>((std::numeric_limits<float>::max)()) &&
1567 static_cast<double>(
static_cast<float>(n)) ==
static_cast<double>(n))
1569 oa->write_character(format == detail::input_format_t::cbor
1570 ? get_cbor_float_prefix(
static_cast<float>(n))
1571 : get_msgpack_float_prefix(
static_cast<float>(n)));
1572 write_number(
static_cast<float>(n));
1576 oa->write_character(format == detail::input_format_t::cbor
1577 ? get_cbor_float_prefix(n)
1578 : get_msgpack_float_prefix(n));
1582 #pragma GCC diagnostic pop
1591 template <
typename C = CharType,
1592 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * =
nullptr >
1593 static constexpr CharType to_char_type(
std::uint8_t x) noexcept
1595 return *
reinterpret_cast<char*
>(&x);
1598 template <
typename C = CharType,
1599 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * =
nullptr >
1602 static_assert(
sizeof(
std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
1603 static_assert(std::is_trivial<CharType>::value,
"CharType must be trivial");
1605 std::memcpy(&result, &x,
sizeof(x));
1609 template<
typename C = CharType,
1610 enable_if_t<std::is_unsigned<C>::value>* =
nullptr>
1611 static constexpr CharType to_char_type(
std::uint8_t x) noexcept
1616 template <
typename InputCharType,
typename C = CharType,
1618 std::is_signed<C>::value &&
1619 std::is_signed<char>::value &&
1620 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
1622 static constexpr CharType to_char_type(InputCharType x) noexcept
1629 const bool is_little_endian = little_endianess();
1632 output_adapter_t<CharType> oa =
nullptr;
serialization to CBOR and MessagePack values
Definition: binary_writer.hpp:29
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: binary_writer.hpp:727
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: binary_writer.hpp:40
void write_bson(const BasicJsonType &j)
Definition: binary_writer.hpp:49
void write_cbor(const BasicJsonType &j)
Definition: binary_writer.hpp:78
void write_msgpack(const BasicJsonType &j)
Definition: binary_writer.hpp:402
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)
@ discarded
discarded by the parser callback function
@ 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:37
input_format_t
the supported input formats
Definition: input_adapters.hpp:26
namespace for Niels Lohmann
Definition: adl_serializer.hpp:12