41 using string_t =
typename BasicJsonType::string_t;
42 using binary_t =
typename BasicJsonType::binary_t;
43 using number_float_t =
typename BasicJsonType::number_float_t;
66 write_bson_object(*j.m_data.m_value.object);
101 oa->write_character(j.m_data.m_value.boolean
109 if (j.m_data.m_value.number_integer >= 0)
114 if (j.m_data.m_value.number_integer <= 0x17)
116 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_integer));
118 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
121 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_integer));
123 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
126 write_number(
static_cast<std::uint16_t
>(j.m_data.m_value.number_integer));
128 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
131 write_number(
static_cast<std::uint32_t
>(j.m_data.m_value.number_integer));
136 write_number(
static_cast<std::uint64_t
>(j.m_data.m_value.number_integer));
143 const auto positive_number = -1 - j.m_data.m_value.number_integer;
144 if (j.m_data.m_value.number_integer >= -24)
146 write_number(
static_cast<std::uint8_t
>(0x20 + positive_number));
148 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
151 write_number(
static_cast<std::uint8_t
>(positive_number));
153 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
156 write_number(
static_cast<std::uint16_t
>(positive_number));
158 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
161 write_number(
static_cast<std::uint32_t
>(positive_number));
166 write_number(
static_cast<std::uint64_t
>(positive_number));
174 if (j.m_data.m_value.number_unsigned <= 0x17)
176 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_unsigned));
178 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
181 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_unsigned));
183 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
186 write_number(
static_cast<std::uint16_t
>(j.m_data.m_value.number_unsigned));
188 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
191 write_number(
static_cast<std::uint32_t
>(j.m_data.m_value.number_unsigned));
196 write_number(
static_cast<std::uint64_t
>(j.m_data.m_value.number_unsigned));
203 if (std::isnan(j.m_data.m_value.number_float))
210 else if (std::isinf(j.m_data.m_value.number_float))
227 const auto N = j.m_data.m_value.string->size();
230 write_number(
static_cast<std::uint8_t
>(0x60 + N));
232 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
235 write_number(
static_cast<std::uint8_t
>(N));
237 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
240 write_number(
static_cast<std::uint16_t
>(N));
242 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
245 write_number(
static_cast<std::uint32_t
>(N));
248 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
251 write_number(
static_cast<std::uint64_t
>(N));
256 oa->write_characters(
257 reinterpret_cast<const CharType*
>(j.m_data.m_value.string->c_str()),
258 j.m_data.m_value.string->size());
265 const auto N = j.m_data.m_value.array->size();
268 write_number(
static_cast<std::uint8_t
>(0x80 + N));
270 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
273 write_number(
static_cast<std::uint8_t
>(N));
275 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
278 write_number(
static_cast<std::uint16_t
>(N));
280 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
283 write_number(
static_cast<std::uint32_t
>(N));
286 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
289 write_number(
static_cast<std::uint64_t
>(N));
294 for (
const auto& el : *j.m_data.m_value.array)
303 if (j.m_data.m_value.binary->has_subtype())
305 if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
307 write_number(
static_cast<std::uint8_t
>(0xd8));
308 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.binary->subtype()));
310 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
312 write_number(
static_cast<std::uint8_t
>(0xd9));
313 write_number(
static_cast<std::uint16_t
>(j.m_data.m_value.binary->subtype()));
315 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
317 write_number(
static_cast<std::uint8_t
>(0xda));
318 write_number(
static_cast<std::uint32_t
>(j.m_data.m_value.binary->subtype()));
320 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
322 write_number(
static_cast<std::uint8_t
>(0xdb));
323 write_number(
static_cast<std::uint64_t
>(j.m_data.m_value.binary->subtype()));
328 const auto N = j.m_data.m_value.binary->size();
331 write_number(
static_cast<std::uint8_t
>(0x40 + N));
333 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
336 write_number(
static_cast<std::uint8_t
>(N));
338 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
341 write_number(
static_cast<std::uint16_t
>(N));
343 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
346 write_number(
static_cast<std::uint32_t
>(N));
349 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
352 write_number(
static_cast<std::uint64_t
>(N));
357 oa->write_characters(
358 reinterpret_cast<const CharType*
>(j.m_data.m_value.binary->data()),
367 const auto N = j.m_data.m_value.object->size();
370 write_number(
static_cast<std::uint8_t
>(0xA0 + N));
372 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
375 write_number(
static_cast<std::uint8_t
>(N));
377 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
380 write_number(
static_cast<std::uint16_t
>(N));
382 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
385 write_number(
static_cast<std::uint32_t
>(N));
388 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
391 write_number(
static_cast<std::uint64_t
>(N));
396 for (
const auto& el : *j.m_data.m_value.object)
425 oa->write_character(j.m_data.m_value.boolean
433 if (j.m_data.m_value.number_integer >= 0)
438 if (j.m_data.m_value.number_unsigned < 128)
441 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_integer));
443 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
447 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_integer));
449 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
453 write_number(
static_cast<std::uint16_t
>(j.m_data.m_value.number_integer));
455 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
459 write_number(
static_cast<std::uint32_t
>(j.m_data.m_value.number_integer));
461 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
465 write_number(
static_cast<std::uint64_t
>(j.m_data.m_value.number_integer));
470 if (j.m_data.m_value.number_integer >= -32)
473 write_number(
static_cast<std::int8_t
>(j.m_data.m_value.number_integer));
475 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
476 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
480 write_number(
static_cast<std::int8_t
>(j.m_data.m_value.number_integer));
482 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
483 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
487 write_number(
static_cast<std::int16_t
>(j.m_data.m_value.number_integer));
489 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
490 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
494 write_number(
static_cast<std::int32_t
>(j.m_data.m_value.number_integer));
496 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
497 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
501 write_number(
static_cast<std::int64_t
>(j.m_data.m_value.number_integer));
509 if (j.m_data.m_value.number_unsigned < 128)
512 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_integer));
514 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
518 write_number(
static_cast<std::uint8_t
>(j.m_data.m_value.number_integer));
520 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
524 write_number(
static_cast<std::uint16_t
>(j.m_data.m_value.number_integer));
526 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
530 write_number(
static_cast<std::uint32_t
>(j.m_data.m_value.number_integer));
532 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
536 write_number(
static_cast<std::uint64_t
>(j.m_data.m_value.number_integer));
550 const auto N = j.m_data.m_value.string->size();
554 write_number(
static_cast<std::uint8_t
>(0xA0 | N));
556 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
560 write_number(
static_cast<std::uint8_t
>(N));
562 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
566 write_number(
static_cast<std::uint16_t
>(N));
568 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
572 write_number(
static_cast<std::uint32_t
>(N));
576 oa->write_characters(
577 reinterpret_cast<const CharType*
>(j.m_data.m_value.string->c_str()),
578 j.m_data.m_value.string->size());
585 const auto N = j.m_data.m_value.array->size();
589 write_number(
static_cast<std::uint8_t
>(0x90 | N));
591 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
595 write_number(
static_cast<std::uint16_t
>(N));
597 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
601 write_number(
static_cast<std::uint32_t
>(N));
605 for (
const auto& el : *j.m_data.m_value.array)
616 const bool use_ext = j.m_data.m_value.binary->has_subtype();
619 const auto N = j.m_data.m_value.binary->size();
620 if (N <= (std::numeric_limits<std::uint8_t>::max)())
622 std::uint8_t output_type{};
659 write_number(
static_cast<std::uint8_t
>(N));
662 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
664 const std::uint8_t output_type = use_ext
669 write_number(
static_cast<std::uint16_t
>(N));
671 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
673 const std::uint8_t output_type = use_ext
678 write_number(
static_cast<std::uint32_t
>(N));
684 write_number(
static_cast<std::int8_t
>(j.m_data.m_value.binary->subtype()));
688 oa->write_characters(
689 reinterpret_cast<const CharType*
>(j.m_data.m_value.binary->data()),
698 const auto N = j.m_data.m_value.object->size();
702 write_number(
static_cast<std::uint8_t
>(0x80 | (N & 0xF)));
704 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
708 write_number(
static_cast<std::uint16_t
>(N));
710 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
714 write_number(
static_cast<std::uint32_t
>(N));
718 for (
const auto& el : *j.m_data.m_value.object)
740 const bool use_type,
const bool add_prefix =
true,
741 const bool use_bjdata =
false)
758 oa->write_character(j.m_data.m_value.boolean
767 write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
773 write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
779 write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
789 write_number_with_ubjson_prefix(j.m_data.m_value.string->size(),
true, use_bjdata);
790 oa->write_characters(
791 reinterpret_cast<const CharType*
>(j.m_data.m_value.string->c_str()),
792 j.m_data.m_value.string->size());
803 bool prefix_required =
true;
804 if (use_type && !j.m_data.m_value.array->empty())
807 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
808 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
809 [
this, first_prefix, use_bjdata](
const BasicJsonType & v)
811 return ubjson_prefix(v, use_bjdata) == first_prefix;
814 std::vector<CharType> bjdx = {
'[',
'{',
'S',
'H',
'T',
'F',
'N',
'Z'};
816 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
818 prefix_required =
false;
820 oa->write_character(first_prefix);
827 write_number_with_ubjson_prefix(j.m_data.m_value.array->size(),
true, use_bjdata);
830 for (
const auto& el : *j.m_data.m_value.array)
832 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
850 if (use_type && !j.m_data.m_value.binary->empty())
854 oa->write_character(
'U');
860 write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(),
true, use_bjdata);
865 oa->write_characters(
866 reinterpret_cast<const CharType*
>(j.m_data.m_value.binary->data()),
867 j.m_data.m_value.binary->size());
871 for (
size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
874 oa->write_character(j.m_data.m_value.binary->data()[i]);
888 if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find(
"_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find(
"_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find(
"_ArrayData_") != j.m_data.m_value.object->end())
890 if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type))
901 bool prefix_required =
true;
902 if (use_type && !j.m_data.m_value.object->empty())
905 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
906 const bool same_prefix = std::all_of(j.begin(), j.end(),
907 [
this, first_prefix, use_bjdata](
const BasicJsonType & v)
909 return ubjson_prefix(v, use_bjdata) == first_prefix;
912 std::vector<CharType> bjdx = {
'[',
'{',
'S',
'H',
'T',
'F',
'N',
'Z'};
914 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
916 prefix_required =
false;
918 oa->write_character(first_prefix);
925 write_number_with_ubjson_prefix(j.m_data.m_value.object->size(),
true, use_bjdata);
928 for (
const auto& el : *j.m_data.m_value.object)
930 write_number_with_ubjson_prefix(el.first.size(),
true, use_bjdata);
931 oa->write_characters(
932 reinterpret_cast<const CharType*
>(el.first.c_str()),
934 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
960 static std::size_t calc_bson_entry_header_size(
const string_t& name,
const BasicJsonType& j)
962 const auto it = name.find(
static_cast<typename string_t::value_type
>(0));
966 static_cast<void>(j);
969 return 1ul + name.size() + 1u;
975 void write_bson_entry_header(
const string_t& name,
976 const std::uint8_t element_type)
979 oa->write_characters(
980 reinterpret_cast<const CharType*
>(name.c_str()),
987 void write_bson_boolean(
const string_t& name,
990 write_bson_entry_header(name, 0x08);
997 void write_bson_double(
const string_t& name,
1000 write_bson_entry_header(name, 0x01);
1001 write_number<double>(
value,
true);
1007 static std::size_t calc_bson_string_size(
const string_t&
value)
1009 return sizeof(std::int32_t) +
value.size() + 1ul;
1015 void write_bson_string(
const string_t& name,
1016 const string_t&
value)
1018 write_bson_entry_header(name, 0x02);
1020 write_number<std::int32_t>(
static_cast<std::int32_t
>(
value.size() + 1ul),
true);
1021 oa->write_characters(
1022 reinterpret_cast<const CharType*
>(
value.c_str()),
1029 void write_bson_null(
const string_t& name)
1031 write_bson_entry_header(name, 0x0A);
1037 static std::size_t calc_bson_integer_size(
const std::int64_t
value)
1039 return (std::numeric_limits<std::int32_t>::min)() <=
value &&
value <= (std::numeric_limits<std::int32_t>::max)()
1040 ?
sizeof(std::int32_t)
1041 :
sizeof(std::int64_t);
1047 void write_bson_integer(
const string_t& name,
1048 const std::int64_t
value)
1050 if ((std::numeric_limits<std::int32_t>::min)() <=
value &&
value <= (std::numeric_limits<std::int32_t>::max)())
1052 write_bson_entry_header(name, 0x10);
1053 write_number<std::int32_t>(
static_cast<std::int32_t
>(
value),
true);
1057 write_bson_entry_header(name, 0x12);
1058 write_number<std::int64_t>(
static_cast<std::int64_t
>(
value),
true);
1065 static constexpr std::size_t calc_bson_unsigned_size(
const std::uint64_t
value)
noexcept
1067 return (
value <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
1068 ?
sizeof(std::int32_t)
1069 : sizeof(
std::int64_t);
1075 void write_bson_unsigned(
const string_t& name,
1076 const BasicJsonType& j)
1078 if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
1080 write_bson_entry_header(name, 0x10 );
1081 write_number<std::int32_t>(
static_cast<std::int32_t
>(j.m_data.m_value.number_unsigned),
true);
1083 else if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
1085 write_bson_entry_header(name, 0x12 );
1086 write_number<std::int64_t>(
static_cast<std::int64_t
>(j.m_data.m_value.number_unsigned),
true);
1090 JSON_THROW(
out_of_range::create(407,
concat(
"integer number ", std::to_string(j.m_data.m_value.number_unsigned),
" cannot be represented by BSON as it does not fit int64"), &j));
1097 void write_bson_object_entry(
const string_t& name,
1098 const typename BasicJsonType::object_t&
value)
1100 write_bson_entry_header(name, 0x03);
1101 write_bson_object(
value);
1107 static std::size_t calc_bson_array_size(
const typename BasicJsonType::array_t&
value)
1109 std::size_t array_index = 0ul;
1111 const std::size_t embedded_document_size = std::accumulate(std::begin(
value), std::end(
value),
static_cast<std::size_t
>(0), [&array_index](std::size_t result,
const typename BasicJsonType::array_t::value_type & el)
1113 return result + calc_bson_element_size(std::to_string(array_index++), el);
1116 return sizeof(std::int32_t) + embedded_document_size + 1ul;
1122 static std::size_t calc_bson_binary_size(
const typename BasicJsonType::binary_t&
value)
1124 return sizeof(std::int32_t) +
value.size() + 1ul;
1130 void write_bson_array(
const string_t& name,
1131 const typename BasicJsonType::array_t&
value)
1133 write_bson_entry_header(name, 0x04);
1134 write_number<std::int32_t>(
static_cast<std::int32_t
>(calc_bson_array_size(
value)),
true);
1136 std::size_t array_index = 0ul;
1138 for (
const auto& el :
value)
1140 write_bson_element(std::to_string(array_index++), el);
1149 void write_bson_binary(
const string_t& name,
1150 const binary_t&
value)
1152 write_bson_entry_header(name, 0x05);
1154 write_number<std::int32_t>(
static_cast<std::int32_t
>(
value.size()),
true);
1155 write_number(
value.has_subtype() ?
static_cast<std::uint8_t
>(
value.subtype()) :
static_cast<std::uint8_t
>(0x00));
1157 oa->write_characters(
reinterpret_cast<const CharType*
>(
value.data()),
value.size());
1164 static std::size_t calc_bson_element_size(
const string_t& name,
1165 const BasicJsonType& j)
1167 const auto header_size = calc_bson_entry_header_size(name, j);
1171 return header_size + calc_bson_object_size(*j.m_data.m_value.object);
1174 return header_size + calc_bson_array_size(*j.m_data.m_value.array);
1177 return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
1180 return header_size + 1ul;
1183 return header_size + 8ul;
1186 return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
1189 return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
1192 return header_size + calc_bson_string_size(*j.m_data.m_value.string);
1195 return header_size + 0ul;
1212 void write_bson_element(
const string_t& name,
1213 const BasicJsonType& j)
1218 return write_bson_object_entry(name, *j.m_data.m_value.object);
1221 return write_bson_array(name, *j.m_data.m_value.array);
1224 return write_bson_binary(name, *j.m_data.m_value.binary);
1227 return write_bson_boolean(name, j.m_data.m_value.boolean);
1230 return write_bson_double(name, j.m_data.m_value.number_float);
1233 return write_bson_integer(name, j.m_data.m_value.number_integer);
1236 return write_bson_unsigned(name, j);
1239 return write_bson_string(name, *j.m_data.m_value.string);
1242 return write_bson_null(name);
1259 static std::size_t calc_bson_object_size(
const typename BasicJsonType::object_t&
value)
1261 const std::size_t document_size = std::accumulate(
value.begin(),
value.end(),
static_cast<std::size_t
>(0),
1262 [](
size_t result,
const typename BasicJsonType::object_t::value_type & el)
1264 return result += calc_bson_element_size(el.first, el.second);
1267 return sizeof(std::int32_t) + document_size + 1ul;
1274 void write_bson_object(
const typename BasicJsonType::object_t&
value)
1276 write_number<std::int32_t>(
static_cast<std::int32_t
>(calc_bson_object_size(
value)),
true);
1278 for (
const auto& el :
value)
1280 write_bson_element(el.first, el.second);
1290 static constexpr CharType get_cbor_float_prefix(
float )
1295 static constexpr CharType get_cbor_float_prefix(
double )
1304 static constexpr CharType get_msgpack_float_prefix(
float )
1309 static constexpr CharType get_msgpack_float_prefix(
double )
1319 template<
typename NumberType,
typename std::enable_if<
1320 std::is_floating_point<NumberType>::value,
int>::type = 0>
1321 void write_number_with_ubjson_prefix(
const NumberType n,
1322 const bool add_prefix,
1323 const bool use_bjdata)
1327 oa->write_character(get_ubjson_float_prefix(n));
1329 write_number(n, use_bjdata);
1333 template<
typename NumberType,
typename std::enable_if<
1334 std::is_unsigned<NumberType>::value,
int>::type = 0>
1335 void write_number_with_ubjson_prefix(
const NumberType n,
1336 const bool add_prefix,
1337 const bool use_bjdata)
1339 if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
1345 write_number(
static_cast<std::uint8_t
>(n), use_bjdata);
1347 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
1353 write_number(
static_cast<std::uint8_t
>(n), use_bjdata);
1355 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
1361 write_number(
static_cast<std::int16_t
>(n), use_bjdata);
1363 else if (use_bjdata && n <=
static_cast<uint64_t
>((std::numeric_limits<uint16_t>::max)()))
1369 write_number(
static_cast<std::uint16_t
>(n), use_bjdata);
1371 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
1377 write_number(
static_cast<std::int32_t
>(n), use_bjdata);
1379 else if (use_bjdata && n <=
static_cast<uint64_t
>((std::numeric_limits<uint32_t>::max)()))
1385 write_number(
static_cast<std::uint32_t
>(n), use_bjdata);
1387 else if (n <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
1393 write_number(
static_cast<std::int64_t
>(n), use_bjdata);
1395 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
1401 write_number(
static_cast<std::uint64_t
>(n), use_bjdata);
1410 const auto number = BasicJsonType(n).dump();
1411 write_number_with_ubjson_prefix(number.size(),
true, use_bjdata);
1412 for (std::size_t i = 0; i < number.size(); ++i)
1414 oa->write_character(
to_char_type(
static_cast<std::uint8_t
>(number[i])));
1420 template <
typename NumberType,
typename std::enable_if <
1421 std::is_signed<NumberType>::value&&
1422 !std::is_floating_point<NumberType>::value,
int >::type = 0 >
1423 void write_number_with_ubjson_prefix(
const NumberType n,
1424 const bool add_prefix,
1425 const bool use_bjdata)
1427 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
1433 write_number(
static_cast<std::int8_t
>(n), use_bjdata);
1435 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)()))
1441 write_number(
static_cast<std::uint8_t
>(n), use_bjdata);
1443 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
1449 write_number(
static_cast<std::int16_t
>(n), use_bjdata);
1451 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)())))
1457 write_number(
static_cast<uint16_t
>(n), use_bjdata);
1459 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
1465 write_number(
static_cast<std::int32_t
>(n), use_bjdata);
1467 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)())))
1473 write_number(
static_cast<uint32_t
>(n), use_bjdata);
1475 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
1481 write_number(
static_cast<std::int64_t
>(n), use_bjdata);
1491 const auto number = BasicJsonType(n).dump();
1492 write_number_with_ubjson_prefix(number.size(),
true, use_bjdata);
1493 for (std::size_t i = 0; i < number.size(); ++i)
1495 oa->write_character(
to_char_type(
static_cast<std::uint8_t
>(number[i])));
1504 CharType ubjson_prefix(
const BasicJsonType& j,
const bool use_bjdata)
const noexcept
1512 return j.m_data.m_value.boolean ?
'T' :
'F';
1516 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
1520 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
1524 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
1528 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
1532 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
1536 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
1540 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
1550 if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int8_t>::max)()))
1554 if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::uint8_t>::max)()))
1558 if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int16_t>::max)()))
1562 if (use_bjdata && j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::uint16_t>::max)()))
1566 if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int32_t>::max)()))
1570 if (use_bjdata && j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::uint32_t>::max)()))
1574 if (j.m_data.m_value.number_unsigned <=
static_cast<std::uint64_t
>((std::numeric_limits<std::int64_t>::max)()))
1578 if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
1587 return get_ubjson_float_prefix(j.m_data.m_value.number_float);
1605 static constexpr CharType get_ubjson_float_prefix(
float )
1610 static constexpr CharType get_ubjson_float_prefix(
double )
1618 bool write_bjdata_ndarray(
const typename BasicJsonType::object_t&
value,
const bool use_count,
const bool use_type)
1620 std::map<string_t, CharType> bjdtype = {{
"uint8",
'U'}, {
"int8",
'i'}, {
"uint16",
'u'}, {
"int16",
'I'},
1621 {
"uint32",
'm'}, {
"int32",
'l'}, {
"uint64",
'M'}, {
"int64",
'L'}, {
"single",
'd'}, {
"double",
'D'}, {
"char",
'C'}
1624 string_t
key =
"_ArrayType_";
1625 auto it = bjdtype.find(
static_cast<string_t
>(
value.at(
key)));
1626 if (it == bjdtype.end())
1630 CharType dtype = it->second;
1632 key =
"_ArraySize_";
1633 std::size_t len = (
value.at(
key).empty() ? 0 : 1);
1634 for (
const auto& el :
value.at(
key))
1636 len *=
static_cast<std::size_t
>(el.m_data.m_value.number_unsigned);
1639 key =
"_ArrayData_";
1645 oa->write_character(
'[');
1646 oa->write_character(
'$');
1647 oa->write_character(dtype);
1648 oa->write_character(
'#');
1650 key =
"_ArraySize_";
1653 key =
"_ArrayData_";
1654 if (dtype ==
'U' || dtype ==
'C')
1656 for (
const auto& el :
value.at(
key))
1658 write_number(
static_cast<std::uint8_t
>(el.m_data.m_value.number_unsigned),
true);
1661 else if (dtype ==
'i')
1663 for (
const auto& el :
value.at(
key))
1665 write_number(
static_cast<std::int8_t
>(el.m_data.m_value.number_integer),
true);
1668 else if (dtype ==
'u')
1670 for (
const auto& el :
value.at(
key))
1672 write_number(
static_cast<std::uint16_t
>(el.m_data.m_value.number_unsigned),
true);
1675 else if (dtype ==
'I')
1677 for (
const auto& el :
value.at(
key))
1679 write_number(
static_cast<std::int16_t
>(el.m_data.m_value.number_integer),
true);
1682 else if (dtype ==
'm')
1684 for (
const auto& el :
value.at(
key))
1686 write_number(
static_cast<std::uint32_t
>(el.m_data.m_value.number_unsigned),
true);
1689 else if (dtype ==
'l')
1691 for (
const auto& el :
value.at(
key))
1693 write_number(
static_cast<std::int32_t
>(el.m_data.m_value.number_integer),
true);
1696 else if (dtype ==
'M')
1698 for (
const auto& el :
value.at(
key))
1700 write_number(
static_cast<std::uint64_t
>(el.m_data.m_value.number_unsigned),
true);
1703 else if (dtype ==
'L')
1705 for (
const auto& el :
value.at(
key))
1707 write_number(
static_cast<std::int64_t
>(el.m_data.m_value.number_integer),
true);
1710 else if (dtype ==
'd')
1712 for (
const auto& el :
value.at(
key))
1714 write_number(
static_cast<float>(el.m_data.m_value.number_float),
true);
1717 else if (dtype ==
'D')
1719 for (
const auto& el :
value.at(
key))
1721 write_number(
static_cast<double>(el.m_data.m_value.number_float),
true);
1744 template<
typename NumberType>
1745 void write_number(
const NumberType n,
const bool OutputIsLittleEndian =
false)
1748 std::array<CharType,
sizeof(NumberType)> vec{};
1749 std::memcpy(vec.data(), &n,
sizeof(NumberType));
1752 if (is_little_endian != OutputIsLittleEndian)
1755 std::reverse(vec.begin(), vec.end());
1758 oa->write_characters(vec.data(),
sizeof(NumberType));
1764#pragma GCC diagnostic push
1765#pragma GCC diagnostic ignored "-Wfloat-equal"
1767 if (
static_cast<double>(n) >=
static_cast<double>(std::numeric_limits<float>::lowest()) &&
1768 static_cast<double>(n) <=
static_cast<double>((std::numeric_limits<float>::max)()) &&
1769 static_cast<double>(
static_cast<float>(n)) ==
static_cast<double>(n))
1772 ? get_cbor_float_prefix(
static_cast<float>(n))
1773 : get_msgpack_float_prefix(
static_cast<float>(n)));
1774 write_number(
static_cast<float>(n));
1779 ? get_cbor_float_prefix(n)
1780 : get_msgpack_float_prefix(n));
1784#pragma GCC diagnostic pop
1793 template <
typename C = CharType,
1794 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * =
nullptr >
1797 return *
reinterpret_cast<char*
>(&x);
1800 template <
typename C = CharType,
1801 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * =
nullptr >
1804 static_assert(
sizeof(std::uint8_t) ==
sizeof(CharType),
"size of CharType must be equal to std::uint8_t");
1805 static_assert(std::is_trivial<CharType>::value,
"CharType must be trivial");
1807 std::memcpy(&result, &x,
sizeof(x));
1811 template<
typename C = CharType,
1818 template <
typename InputCharType,
typename C = CharType,
1820 std::is_signed<C>::value &&
1821 std::is_signed<char>::value &&
1822 std::is_same<char, typename std::remove_cv<InputCharType>::type>
::value