File indexing completed on 2025-01-18 10:02:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <algorithm> // reverse
0012 #include <array> // array
0013 #include <map> // map
0014 #include <cmath> // isnan, isinf
0015 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
0016 #include <cstring> // memcpy
0017 #include <limits> // numeric_limits
0018 #include <string> // string
0019 #include <utility> // move
0020 #include <vector> // vector
0021
0022 #include <nlohmann/detail/input/binary_reader.hpp>
0023 #include <nlohmann/detail/macro_scope.hpp>
0024 #include <nlohmann/detail/output/output_adapters.hpp>
0025 #include <nlohmann/detail/string_concat.hpp>
0026
0027 NLOHMANN_JSON_NAMESPACE_BEGIN
0028 namespace detail
0029 {
0030
0031
0032
0033
0034
0035
0036
0037
0038 template<typename BasicJsonType, typename CharType>
0039 class binary_writer
0040 {
0041 using string_t = typename BasicJsonType::string_t;
0042 using binary_t = typename BasicJsonType::binary_t;
0043 using number_float_t = typename BasicJsonType::number_float_t;
0044
0045 public:
0046
0047
0048
0049
0050
0051 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
0052 {
0053 JSON_ASSERT(oa);
0054 }
0055
0056
0057
0058
0059
0060 void write_bson(const BasicJsonType& j)
0061 {
0062 switch (j.type())
0063 {
0064 case value_t::object:
0065 {
0066 write_bson_object(*j.m_value.object);
0067 break;
0068 }
0069
0070 case value_t::null:
0071 case value_t::array:
0072 case value_t::string:
0073 case value_t::boolean:
0074 case value_t::number_integer:
0075 case value_t::number_unsigned:
0076 case value_t::number_float:
0077 case value_t::binary:
0078 case value_t::discarded:
0079 default:
0080 {
0081 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
0082 }
0083 }
0084 }
0085
0086
0087
0088
0089 void write_cbor(const BasicJsonType& j)
0090 {
0091 switch (j.type())
0092 {
0093 case value_t::null:
0094 {
0095 oa->write_character(to_char_type(0xF6));
0096 break;
0097 }
0098
0099 case value_t::boolean:
0100 {
0101 oa->write_character(j.m_value.boolean
0102 ? to_char_type(0xF5)
0103 : to_char_type(0xF4));
0104 break;
0105 }
0106
0107 case value_t::number_integer:
0108 {
0109 if (j.m_value.number_integer >= 0)
0110 {
0111
0112
0113
0114 if (j.m_value.number_integer <= 0x17)
0115 {
0116 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
0117 }
0118 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
0119 {
0120 oa->write_character(to_char_type(0x18));
0121 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
0122 }
0123 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
0124 {
0125 oa->write_character(to_char_type(0x19));
0126 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
0127 }
0128 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
0129 {
0130 oa->write_character(to_char_type(0x1A));
0131 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
0132 }
0133 else
0134 {
0135 oa->write_character(to_char_type(0x1B));
0136 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
0137 }
0138 }
0139 else
0140 {
0141
0142
0143 const auto positive_number = -1 - j.m_value.number_integer;
0144 if (j.m_value.number_integer >= -24)
0145 {
0146 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
0147 }
0148 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
0149 {
0150 oa->write_character(to_char_type(0x38));
0151 write_number(static_cast<std::uint8_t>(positive_number));
0152 }
0153 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
0154 {
0155 oa->write_character(to_char_type(0x39));
0156 write_number(static_cast<std::uint16_t>(positive_number));
0157 }
0158 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
0159 {
0160 oa->write_character(to_char_type(0x3A));
0161 write_number(static_cast<std::uint32_t>(positive_number));
0162 }
0163 else
0164 {
0165 oa->write_character(to_char_type(0x3B));
0166 write_number(static_cast<std::uint64_t>(positive_number));
0167 }
0168 }
0169 break;
0170 }
0171
0172 case value_t::number_unsigned:
0173 {
0174 if (j.m_value.number_unsigned <= 0x17)
0175 {
0176 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
0177 }
0178 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
0179 {
0180 oa->write_character(to_char_type(0x18));
0181 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
0182 }
0183 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
0184 {
0185 oa->write_character(to_char_type(0x19));
0186 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
0187 }
0188 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
0189 {
0190 oa->write_character(to_char_type(0x1A));
0191 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
0192 }
0193 else
0194 {
0195 oa->write_character(to_char_type(0x1B));
0196 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
0197 }
0198 break;
0199 }
0200
0201 case value_t::number_float:
0202 {
0203 if (std::isnan(j.m_value.number_float))
0204 {
0205
0206 oa->write_character(to_char_type(0xF9));
0207 oa->write_character(to_char_type(0x7E));
0208 oa->write_character(to_char_type(0x00));
0209 }
0210 else if (std::isinf(j.m_value.number_float))
0211 {
0212
0213 oa->write_character(to_char_type(0xf9));
0214 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
0215 oa->write_character(to_char_type(0x00));
0216 }
0217 else
0218 {
0219 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
0220 }
0221 break;
0222 }
0223
0224 case value_t::string:
0225 {
0226
0227 const auto N = j.m_value.string->size();
0228 if (N <= 0x17)
0229 {
0230 write_number(static_cast<std::uint8_t>(0x60 + N));
0231 }
0232 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
0233 {
0234 oa->write_character(to_char_type(0x78));
0235 write_number(static_cast<std::uint8_t>(N));
0236 }
0237 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0238 {
0239 oa->write_character(to_char_type(0x79));
0240 write_number(static_cast<std::uint16_t>(N));
0241 }
0242 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0243 {
0244 oa->write_character(to_char_type(0x7A));
0245 write_number(static_cast<std::uint32_t>(N));
0246 }
0247
0248 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
0249 {
0250 oa->write_character(to_char_type(0x7B));
0251 write_number(static_cast<std::uint64_t>(N));
0252 }
0253
0254
0255
0256 oa->write_characters(
0257 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
0258 j.m_value.string->size());
0259 break;
0260 }
0261
0262 case value_t::array:
0263 {
0264
0265 const auto N = j.m_value.array->size();
0266 if (N <= 0x17)
0267 {
0268 write_number(static_cast<std::uint8_t>(0x80 + N));
0269 }
0270 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
0271 {
0272 oa->write_character(to_char_type(0x98));
0273 write_number(static_cast<std::uint8_t>(N));
0274 }
0275 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0276 {
0277 oa->write_character(to_char_type(0x99));
0278 write_number(static_cast<std::uint16_t>(N));
0279 }
0280 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0281 {
0282 oa->write_character(to_char_type(0x9A));
0283 write_number(static_cast<std::uint32_t>(N));
0284 }
0285
0286 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
0287 {
0288 oa->write_character(to_char_type(0x9B));
0289 write_number(static_cast<std::uint64_t>(N));
0290 }
0291
0292
0293
0294 for (const auto& el : *j.m_value.array)
0295 {
0296 write_cbor(el);
0297 }
0298 break;
0299 }
0300
0301 case value_t::binary:
0302 {
0303 if (j.m_value.binary->has_subtype())
0304 {
0305 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
0306 {
0307 write_number(static_cast<std::uint8_t>(0xd8));
0308 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
0309 }
0310 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
0311 {
0312 write_number(static_cast<std::uint8_t>(0xd9));
0313 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
0314 }
0315 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
0316 {
0317 write_number(static_cast<std::uint8_t>(0xda));
0318 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
0319 }
0320 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
0321 {
0322 write_number(static_cast<std::uint8_t>(0xdb));
0323 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
0324 }
0325 }
0326
0327
0328 const auto N = j.m_value.binary->size();
0329 if (N <= 0x17)
0330 {
0331 write_number(static_cast<std::uint8_t>(0x40 + N));
0332 }
0333 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
0334 {
0335 oa->write_character(to_char_type(0x58));
0336 write_number(static_cast<std::uint8_t>(N));
0337 }
0338 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0339 {
0340 oa->write_character(to_char_type(0x59));
0341 write_number(static_cast<std::uint16_t>(N));
0342 }
0343 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0344 {
0345 oa->write_character(to_char_type(0x5A));
0346 write_number(static_cast<std::uint32_t>(N));
0347 }
0348
0349 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
0350 {
0351 oa->write_character(to_char_type(0x5B));
0352 write_number(static_cast<std::uint64_t>(N));
0353 }
0354
0355
0356
0357 oa->write_characters(
0358 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
0359 N);
0360
0361 break;
0362 }
0363
0364 case value_t::object:
0365 {
0366
0367 const auto N = j.m_value.object->size();
0368 if (N <= 0x17)
0369 {
0370 write_number(static_cast<std::uint8_t>(0xA0 + N));
0371 }
0372 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
0373 {
0374 oa->write_character(to_char_type(0xB8));
0375 write_number(static_cast<std::uint8_t>(N));
0376 }
0377 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0378 {
0379 oa->write_character(to_char_type(0xB9));
0380 write_number(static_cast<std::uint16_t>(N));
0381 }
0382 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0383 {
0384 oa->write_character(to_char_type(0xBA));
0385 write_number(static_cast<std::uint32_t>(N));
0386 }
0387
0388 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
0389 {
0390 oa->write_character(to_char_type(0xBB));
0391 write_number(static_cast<std::uint64_t>(N));
0392 }
0393
0394
0395
0396 for (const auto& el : *j.m_value.object)
0397 {
0398 write_cbor(el.first);
0399 write_cbor(el.second);
0400 }
0401 break;
0402 }
0403
0404 case value_t::discarded:
0405 default:
0406 break;
0407 }
0408 }
0409
0410
0411
0412
0413 void write_msgpack(const BasicJsonType& j)
0414 {
0415 switch (j.type())
0416 {
0417 case value_t::null:
0418 {
0419 oa->write_character(to_char_type(0xC0));
0420 break;
0421 }
0422
0423 case value_t::boolean:
0424 {
0425 oa->write_character(j.m_value.boolean
0426 ? to_char_type(0xC3)
0427 : to_char_type(0xC2));
0428 break;
0429 }
0430
0431 case value_t::number_integer:
0432 {
0433 if (j.m_value.number_integer >= 0)
0434 {
0435
0436
0437
0438 if (j.m_value.number_unsigned < 128)
0439 {
0440
0441 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
0442 }
0443 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
0444 {
0445
0446 oa->write_character(to_char_type(0xCC));
0447 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
0448 }
0449 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
0450 {
0451
0452 oa->write_character(to_char_type(0xCD));
0453 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
0454 }
0455 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
0456 {
0457
0458 oa->write_character(to_char_type(0xCE));
0459 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
0460 }
0461 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
0462 {
0463
0464 oa->write_character(to_char_type(0xCF));
0465 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
0466 }
0467 }
0468 else
0469 {
0470 if (j.m_value.number_integer >= -32)
0471 {
0472
0473 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
0474 }
0475 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
0476 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
0477 {
0478
0479 oa->write_character(to_char_type(0xD0));
0480 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
0481 }
0482 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
0483 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
0484 {
0485
0486 oa->write_character(to_char_type(0xD1));
0487 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
0488 }
0489 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
0490 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
0491 {
0492
0493 oa->write_character(to_char_type(0xD2));
0494 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
0495 }
0496 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
0497 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
0498 {
0499
0500 oa->write_character(to_char_type(0xD3));
0501 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
0502 }
0503 }
0504 break;
0505 }
0506
0507 case value_t::number_unsigned:
0508 {
0509 if (j.m_value.number_unsigned < 128)
0510 {
0511
0512 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
0513 }
0514 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
0515 {
0516
0517 oa->write_character(to_char_type(0xCC));
0518 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
0519 }
0520 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
0521 {
0522
0523 oa->write_character(to_char_type(0xCD));
0524 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
0525 }
0526 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
0527 {
0528
0529 oa->write_character(to_char_type(0xCE));
0530 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
0531 }
0532 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
0533 {
0534
0535 oa->write_character(to_char_type(0xCF));
0536 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
0537 }
0538 break;
0539 }
0540
0541 case value_t::number_float:
0542 {
0543 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
0544 break;
0545 }
0546
0547 case value_t::string:
0548 {
0549
0550 const auto N = j.m_value.string->size();
0551 if (N <= 31)
0552 {
0553
0554 write_number(static_cast<std::uint8_t>(0xA0 | N));
0555 }
0556 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
0557 {
0558
0559 oa->write_character(to_char_type(0xD9));
0560 write_number(static_cast<std::uint8_t>(N));
0561 }
0562 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0563 {
0564
0565 oa->write_character(to_char_type(0xDA));
0566 write_number(static_cast<std::uint16_t>(N));
0567 }
0568 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0569 {
0570
0571 oa->write_character(to_char_type(0xDB));
0572 write_number(static_cast<std::uint32_t>(N));
0573 }
0574
0575
0576 oa->write_characters(
0577 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
0578 j.m_value.string->size());
0579 break;
0580 }
0581
0582 case value_t::array:
0583 {
0584
0585 const auto N = j.m_value.array->size();
0586 if (N <= 15)
0587 {
0588
0589 write_number(static_cast<std::uint8_t>(0x90 | N));
0590 }
0591 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0592 {
0593
0594 oa->write_character(to_char_type(0xDC));
0595 write_number(static_cast<std::uint16_t>(N));
0596 }
0597 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0598 {
0599
0600 oa->write_character(to_char_type(0xDD));
0601 write_number(static_cast<std::uint32_t>(N));
0602 }
0603
0604
0605 for (const auto& el : *j.m_value.array)
0606 {
0607 write_msgpack(el);
0608 }
0609 break;
0610 }
0611
0612 case value_t::binary:
0613 {
0614
0615
0616 const bool use_ext = j.m_value.binary->has_subtype();
0617
0618
0619 const auto N = j.m_value.binary->size();
0620 if (N <= (std::numeric_limits<std::uint8_t>::max)())
0621 {
0622 std::uint8_t output_type{};
0623 bool fixed = true;
0624 if (use_ext)
0625 {
0626 switch (N)
0627 {
0628 case 1:
0629 output_type = 0xD4;
0630 break;
0631 case 2:
0632 output_type = 0xD5;
0633 break;
0634 case 4:
0635 output_type = 0xD6;
0636 break;
0637 case 8:
0638 output_type = 0xD7;
0639 break;
0640 case 16:
0641 output_type = 0xD8;
0642 break;
0643 default:
0644 output_type = 0xC7;
0645 fixed = false;
0646 break;
0647 }
0648
0649 }
0650 else
0651 {
0652 output_type = 0xC4;
0653 fixed = false;
0654 }
0655
0656 oa->write_character(to_char_type(output_type));
0657 if (!fixed)
0658 {
0659 write_number(static_cast<std::uint8_t>(N));
0660 }
0661 }
0662 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0663 {
0664 std::uint8_t output_type = use_ext
0665 ? 0xC8
0666 : 0xC5;
0667
0668 oa->write_character(to_char_type(output_type));
0669 write_number(static_cast<std::uint16_t>(N));
0670 }
0671 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0672 {
0673 std::uint8_t output_type = use_ext
0674 ? 0xC9
0675 : 0xC6;
0676
0677 oa->write_character(to_char_type(output_type));
0678 write_number(static_cast<std::uint32_t>(N));
0679 }
0680
0681
0682 if (use_ext)
0683 {
0684 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
0685 }
0686
0687
0688 oa->write_characters(
0689 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
0690 N);
0691
0692 break;
0693 }
0694
0695 case value_t::object:
0696 {
0697
0698 const auto N = j.m_value.object->size();
0699 if (N <= 15)
0700 {
0701
0702 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
0703 }
0704 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
0705 {
0706
0707 oa->write_character(to_char_type(0xDE));
0708 write_number(static_cast<std::uint16_t>(N));
0709 }
0710 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
0711 {
0712
0713 oa->write_character(to_char_type(0xDF));
0714 write_number(static_cast<std::uint32_t>(N));
0715 }
0716
0717
0718 for (const auto& el : *j.m_value.object)
0719 {
0720 write_msgpack(el.first);
0721 write_msgpack(el.second);
0722 }
0723 break;
0724 }
0725
0726 case value_t::discarded:
0727 default:
0728 break;
0729 }
0730 }
0731
0732
0733
0734
0735
0736
0737
0738
0739 void write_ubjson(const BasicJsonType& j, const bool use_count,
0740 const bool use_type, const bool add_prefix = true,
0741 const bool use_bjdata = false)
0742 {
0743 switch (j.type())
0744 {
0745 case value_t::null:
0746 {
0747 if (add_prefix)
0748 {
0749 oa->write_character(to_char_type('Z'));
0750 }
0751 break;
0752 }
0753
0754 case value_t::boolean:
0755 {
0756 if (add_prefix)
0757 {
0758 oa->write_character(j.m_value.boolean
0759 ? to_char_type('T')
0760 : to_char_type('F'));
0761 }
0762 break;
0763 }
0764
0765 case value_t::number_integer:
0766 {
0767 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
0768 break;
0769 }
0770
0771 case value_t::number_unsigned:
0772 {
0773 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
0774 break;
0775 }
0776
0777 case value_t::number_float:
0778 {
0779 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
0780 break;
0781 }
0782
0783 case value_t::string:
0784 {
0785 if (add_prefix)
0786 {
0787 oa->write_character(to_char_type('S'));
0788 }
0789 write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
0790 oa->write_characters(
0791 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
0792 j.m_value.string->size());
0793 break;
0794 }
0795
0796 case value_t::array:
0797 {
0798 if (add_prefix)
0799 {
0800 oa->write_character(to_char_type('['));
0801 }
0802
0803 bool prefix_required = true;
0804 if (use_type && !j.m_value.array->empty())
0805 {
0806 JSON_ASSERT(use_count);
0807 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
0808 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
0809 [this, first_prefix, use_bjdata](const BasicJsonType & v)
0810 {
0811 return ubjson_prefix(v, use_bjdata) == first_prefix;
0812 });
0813
0814 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'};
0815
0816 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
0817 {
0818 prefix_required = false;
0819 oa->write_character(to_char_type('$'));
0820 oa->write_character(first_prefix);
0821 }
0822 }
0823
0824 if (use_count)
0825 {
0826 oa->write_character(to_char_type('#'));
0827 write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
0828 }
0829
0830 for (const auto& el : *j.m_value.array)
0831 {
0832 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
0833 }
0834
0835 if (!use_count)
0836 {
0837 oa->write_character(to_char_type(']'));
0838 }
0839
0840 break;
0841 }
0842
0843 case value_t::binary:
0844 {
0845 if (add_prefix)
0846 {
0847 oa->write_character(to_char_type('['));
0848 }
0849
0850 if (use_type && !j.m_value.binary->empty())
0851 {
0852 JSON_ASSERT(use_count);
0853 oa->write_character(to_char_type('$'));
0854 oa->write_character('U');
0855 }
0856
0857 if (use_count)
0858 {
0859 oa->write_character(to_char_type('#'));
0860 write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
0861 }
0862
0863 if (use_type)
0864 {
0865 oa->write_characters(
0866 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
0867 j.m_value.binary->size());
0868 }
0869 else
0870 {
0871 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
0872 {
0873 oa->write_character(to_char_type('U'));
0874 oa->write_character(j.m_value.binary->data()[i]);
0875 }
0876 }
0877
0878 if (!use_count)
0879 {
0880 oa->write_character(to_char_type(']'));
0881 }
0882
0883 break;
0884 }
0885
0886 case value_t::object:
0887 {
0888 if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
0889 {
0890 if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type))
0891 {
0892 break;
0893 }
0894 }
0895
0896 if (add_prefix)
0897 {
0898 oa->write_character(to_char_type('{'));
0899 }
0900
0901 bool prefix_required = true;
0902 if (use_type && !j.m_value.object->empty())
0903 {
0904 JSON_ASSERT(use_count);
0905 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
0906 const bool same_prefix = std::all_of(j.begin(), j.end(),
0907 [this, first_prefix, use_bjdata](const BasicJsonType & v)
0908 {
0909 return ubjson_prefix(v, use_bjdata) == first_prefix;
0910 });
0911
0912 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'};
0913
0914 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
0915 {
0916 prefix_required = false;
0917 oa->write_character(to_char_type('$'));
0918 oa->write_character(first_prefix);
0919 }
0920 }
0921
0922 if (use_count)
0923 {
0924 oa->write_character(to_char_type('#'));
0925 write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
0926 }
0927
0928 for (const auto& el : *j.m_value.object)
0929 {
0930 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
0931 oa->write_characters(
0932 reinterpret_cast<const CharType*>(el.first.c_str()),
0933 el.first.size());
0934 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
0935 }
0936
0937 if (!use_count)
0938 {
0939 oa->write_character(to_char_type('}'));
0940 }
0941
0942 break;
0943 }
0944
0945 case value_t::discarded:
0946 default:
0947 break;
0948 }
0949 }
0950
0951 private:
0952
0953
0954
0955
0956
0957
0958
0959
0960 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
0961 {
0962 const auto it = name.find(static_cast<typename string_t::value_type>(0));
0963 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
0964 {
0965 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
0966 static_cast<void>(j);
0967 }
0968
0969 return 1ul + name.size() + 1u;
0970 }
0971
0972
0973
0974
0975 void write_bson_entry_header(const string_t& name,
0976 const std::uint8_t element_type)
0977 {
0978 oa->write_character(to_char_type(element_type));
0979 oa->write_characters(
0980 reinterpret_cast<const CharType*>(name.c_str()),
0981 name.size() + 1u);
0982 }
0983
0984
0985
0986
0987 void write_bson_boolean(const string_t& name,
0988 const bool value)
0989 {
0990 write_bson_entry_header(name, 0x08);
0991 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
0992 }
0993
0994
0995
0996
0997 void write_bson_double(const string_t& name,
0998 const double value)
0999 {
1000 write_bson_entry_header(name, 0x01);
1001 write_number<double>(value, true);
1002 }
1003
1004
1005
1006
1007 static std::size_t calc_bson_string_size(const string_t& value)
1008 {
1009 return sizeof(std::int32_t) + value.size() + 1ul;
1010 }
1011
1012
1013
1014
1015 void write_bson_string(const string_t& name,
1016 const string_t& value)
1017 {
1018 write_bson_entry_header(name, 0x02);
1019
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()),
1023 value.size() + 1);
1024 }
1025
1026
1027
1028
1029 void write_bson_null(const string_t& name)
1030 {
1031 write_bson_entry_header(name, 0x0A);
1032 }
1033
1034
1035
1036
1037 static std::size_t calc_bson_integer_size(const std::int64_t value)
1038 {
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);
1042 }
1043
1044
1045
1046
1047 void write_bson_integer(const string_t& name,
1048 const std::int64_t value)
1049 {
1050 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
1051 {
1052 write_bson_entry_header(name, 0x10);
1053 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
1054 }
1055 else
1056 {
1057 write_bson_entry_header(name, 0x12);
1058 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
1059 }
1060 }
1061
1062
1063
1064
1065 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
1066 {
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);
1070 }
1071
1072
1073
1074
1075 void write_bson_unsigned(const string_t& name,
1076 const BasicJsonType& j)
1077 {
1078 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1079 {
1080 write_bson_entry_header(name, 0x10 );
1081 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
1082 }
1083 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1084 {
1085 write_bson_entry_header(name, 0x12 );
1086 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
1087 }
1088 else
1089 {
1090 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
1091 }
1092 }
1093
1094
1095
1096
1097 void write_bson_object_entry(const string_t& name,
1098 const typename BasicJsonType::object_t& value)
1099 {
1100 write_bson_entry_header(name, 0x03);
1101 write_bson_object(value);
1102 }
1103
1104
1105
1106
1107 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
1108 {
1109 std::size_t array_index = 0ul;
1110
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)
1112 {
1113 return result + calc_bson_element_size(std::to_string(array_index++), el);
1114 });
1115
1116 return sizeof(std::int32_t) + embedded_document_size + 1ul;
1117 }
1118
1119
1120
1121
1122 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
1123 {
1124 return sizeof(std::int32_t) + value.size() + 1ul;
1125 }
1126
1127
1128
1129
1130 void write_bson_array(const string_t& name,
1131 const typename BasicJsonType::array_t& value)
1132 {
1133 write_bson_entry_header(name, 0x04);
1134 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
1135
1136 std::size_t array_index = 0ul;
1137
1138 for (const auto& el : value)
1139 {
1140 write_bson_element(std::to_string(array_index++), el);
1141 }
1142
1143 oa->write_character(to_char_type(0x00));
1144 }
1145
1146
1147
1148
1149 void write_bson_binary(const string_t& name,
1150 const binary_t& value)
1151 {
1152 write_bson_entry_header(name, 0x05);
1153
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));
1156
1157 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
1158 }
1159
1160
1161
1162
1163
1164 static std::size_t calc_bson_element_size(const string_t& name,
1165 const BasicJsonType& j)
1166 {
1167 const auto header_size = calc_bson_entry_header_size(name, j);
1168 switch (j.type())
1169 {
1170 case value_t::object:
1171 return header_size + calc_bson_object_size(*j.m_value.object);
1172
1173 case value_t::array:
1174 return header_size + calc_bson_array_size(*j.m_value.array);
1175
1176 case value_t::binary:
1177 return header_size + calc_bson_binary_size(*j.m_value.binary);
1178
1179 case value_t::boolean:
1180 return header_size + 1ul;
1181
1182 case value_t::number_float:
1183 return header_size + 8ul;
1184
1185 case value_t::number_integer:
1186 return header_size + calc_bson_integer_size(j.m_value.number_integer);
1187
1188 case value_t::number_unsigned:
1189 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
1190
1191 case value_t::string:
1192 return header_size + calc_bson_string_size(*j.m_value.string);
1193
1194 case value_t::null:
1195 return header_size + 0ul;
1196
1197
1198 case value_t::discarded:
1199 default:
1200 JSON_ASSERT(false);
1201 return 0ul;
1202
1203 }
1204 }
1205
1206
1207
1208
1209
1210
1211
1212 void write_bson_element(const string_t& name,
1213 const BasicJsonType& j)
1214 {
1215 switch (j.type())
1216 {
1217 case value_t::object:
1218 return write_bson_object_entry(name, *j.m_value.object);
1219
1220 case value_t::array:
1221 return write_bson_array(name, *j.m_value.array);
1222
1223 case value_t::binary:
1224 return write_bson_binary(name, *j.m_value.binary);
1225
1226 case value_t::boolean:
1227 return write_bson_boolean(name, j.m_value.boolean);
1228
1229 case value_t::number_float:
1230 return write_bson_double(name, j.m_value.number_float);
1231
1232 case value_t::number_integer:
1233 return write_bson_integer(name, j.m_value.number_integer);
1234
1235 case value_t::number_unsigned:
1236 return write_bson_unsigned(name, j);
1237
1238 case value_t::string:
1239 return write_bson_string(name, *j.m_value.string);
1240
1241 case value_t::null:
1242 return write_bson_null(name);
1243
1244
1245 case value_t::discarded:
1246 default:
1247 JSON_ASSERT(false);
1248 return;
1249
1250 }
1251 }
1252
1253
1254
1255
1256
1257
1258
1259 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
1260 {
1261 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)
1263 {
1264 return result += calc_bson_element_size(el.first, el.second);
1265 });
1266
1267 return sizeof(std::int32_t) + document_size + 1ul;
1268 }
1269
1270
1271
1272
1273
1274 void write_bson_object(const typename BasicJsonType::object_t& value)
1275 {
1276 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
1277
1278 for (const auto& el : value)
1279 {
1280 write_bson_element(el.first, el.second);
1281 }
1282
1283 oa->write_character(to_char_type(0x00));
1284 }
1285
1286
1287
1288
1289
1290 static constexpr CharType get_cbor_float_prefix(float )
1291 {
1292 return to_char_type(0xFA);
1293 }
1294
1295 static constexpr CharType get_cbor_float_prefix(double )
1296 {
1297 return to_char_type(0xFB);
1298 }
1299
1300
1301
1302
1303
1304 static constexpr CharType get_msgpack_float_prefix(float )
1305 {
1306 return to_char_type(0xCA);
1307 }
1308
1309 static constexpr CharType get_msgpack_float_prefix(double )
1310 {
1311 return to_char_type(0xCB);
1312 }
1313
1314
1315
1316
1317
1318
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)
1324 {
1325 if (add_prefix)
1326 {
1327 oa->write_character(get_ubjson_float_prefix(n));
1328 }
1329 write_number(n, use_bjdata);
1330 }
1331
1332
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)
1338 {
1339 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1340 {
1341 if (add_prefix)
1342 {
1343 oa->write_character(to_char_type('i'));
1344 }
1345 write_number(static_cast<std::uint8_t>(n), use_bjdata);
1346 }
1347 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
1348 {
1349 if (add_prefix)
1350 {
1351 oa->write_character(to_char_type('U'));
1352 }
1353 write_number(static_cast<std::uint8_t>(n), use_bjdata);
1354 }
1355 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1356 {
1357 if (add_prefix)
1358 {
1359 oa->write_character(to_char_type('I'));
1360 }
1361 write_number(static_cast<std::int16_t>(n), use_bjdata);
1362 }
1363 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
1364 {
1365 if (add_prefix)
1366 {
1367 oa->write_character(to_char_type('u'));
1368 }
1369 write_number(static_cast<std::uint16_t>(n), use_bjdata);
1370 }
1371 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1372 {
1373 if (add_prefix)
1374 {
1375 oa->write_character(to_char_type('l'));
1376 }
1377 write_number(static_cast<std::int32_t>(n), use_bjdata);
1378 }
1379 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
1380 {
1381 if (add_prefix)
1382 {
1383 oa->write_character(to_char_type('m'));
1384 }
1385 write_number(static_cast<std::uint32_t>(n), use_bjdata);
1386 }
1387 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1388 {
1389 if (add_prefix)
1390 {
1391 oa->write_character(to_char_type('L'));
1392 }
1393 write_number(static_cast<std::int64_t>(n), use_bjdata);
1394 }
1395 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
1396 {
1397 if (add_prefix)
1398 {
1399 oa->write_character(to_char_type('M'));
1400 }
1401 write_number(static_cast<std::uint64_t>(n), use_bjdata);
1402 }
1403 else
1404 {
1405 if (add_prefix)
1406 {
1407 oa->write_character(to_char_type('H'));
1408 }
1409
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)
1413 {
1414 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
1415 }
1416 }
1417 }
1418
1419
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)
1426 {
1427 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
1428 {
1429 if (add_prefix)
1430 {
1431 oa->write_character(to_char_type('i'));
1432 }
1433 write_number(static_cast<std::int8_t>(n), use_bjdata);
1434 }
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)()))
1436 {
1437 if (add_prefix)
1438 {
1439 oa->write_character(to_char_type('U'));
1440 }
1441 write_number(static_cast<std::uint8_t>(n), use_bjdata);
1442 }
1443 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
1444 {
1445 if (add_prefix)
1446 {
1447 oa->write_character(to_char_type('I'));
1448 }
1449 write_number(static_cast<std::int16_t>(n), use_bjdata);
1450 }
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)())))
1452 {
1453 if (add_prefix)
1454 {
1455 oa->write_character(to_char_type('u'));
1456 }
1457 write_number(static_cast<uint16_t>(n), use_bjdata);
1458 }
1459 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
1460 {
1461 if (add_prefix)
1462 {
1463 oa->write_character(to_char_type('l'));
1464 }
1465 write_number(static_cast<std::int32_t>(n), use_bjdata);
1466 }
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)())))
1468 {
1469 if (add_prefix)
1470 {
1471 oa->write_character(to_char_type('m'));
1472 }
1473 write_number(static_cast<uint32_t>(n), use_bjdata);
1474 }
1475 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
1476 {
1477 if (add_prefix)
1478 {
1479 oa->write_character(to_char_type('L'));
1480 }
1481 write_number(static_cast<std::int64_t>(n), use_bjdata);
1482 }
1483
1484 else
1485 {
1486 if (add_prefix)
1487 {
1488 oa->write_character(to_char_type('H'));
1489 }
1490
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)
1494 {
1495 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
1496 }
1497 }
1498
1499 }
1500
1501
1502
1503
1504 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
1505 {
1506 switch (j.type())
1507 {
1508 case value_t::null:
1509 return 'Z';
1510
1511 case value_t::boolean:
1512 return j.m_value.boolean ? 'T' : 'F';
1513
1514 case value_t::number_integer:
1515 {
1516 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)())
1517 {
1518 return 'i';
1519 }
1520 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)())
1521 {
1522 return 'U';
1523 }
1524 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)())
1525 {
1526 return 'I';
1527 }
1528 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
1529 {
1530 return 'u';
1531 }
1532 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)())
1533 {
1534 return 'l';
1535 }
1536 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
1537 {
1538 return 'm';
1539 }
1540 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)())
1541 {
1542 return 'L';
1543 }
1544
1545 return 'H';
1546 }
1547
1548 case value_t::number_unsigned:
1549 {
1550 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
1551 {
1552 return 'i';
1553 }
1554 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
1555 {
1556 return 'U';
1557 }
1558 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
1559 {
1560 return 'I';
1561 }
1562 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
1563 {
1564 return 'u';
1565 }
1566 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
1567 {
1568 return 'l';
1569 }
1570 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
1571 {
1572 return 'm';
1573 }
1574 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
1575 {
1576 return 'L';
1577 }
1578 if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
1579 {
1580 return 'M';
1581 }
1582
1583 return 'H';
1584 }
1585
1586 case value_t::number_float:
1587 return get_ubjson_float_prefix(j.m_value.number_float);
1588
1589 case value_t::string:
1590 return 'S';
1591
1592 case value_t::array:
1593 case value_t::binary:
1594 return '[';
1595
1596 case value_t::object:
1597 return '{';
1598
1599 case value_t::discarded:
1600 default:
1601 return 'N';
1602 }
1603 }
1604
1605 static constexpr CharType get_ubjson_float_prefix(float )
1606 {
1607 return 'd';
1608 }
1609
1610 static constexpr CharType get_ubjson_float_prefix(double )
1611 {
1612 return 'D';
1613 }
1614
1615
1616
1617
1618 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
1619 {
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'}
1622 };
1623
1624 string_t key = "_ArrayType_";
1625 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
1626 if (it == bjdtype.end())
1627 {
1628 return true;
1629 }
1630 CharType dtype = it->second;
1631
1632 key = "_ArraySize_";
1633 std::size_t len = (value.at(key).empty() ? 0 : 1);
1634 for (const auto& el : value.at(key))
1635 {
1636 len *= static_cast<std::size_t>(el.m_value.number_unsigned);
1637 }
1638
1639 key = "_ArrayData_";
1640 if (value.at(key).size() != len)
1641 {
1642 return true;
1643 }
1644
1645 oa->write_character('[');
1646 oa->write_character('$');
1647 oa->write_character(dtype);
1648 oa->write_character('#');
1649
1650 key = "_ArraySize_";
1651 write_ubjson(value.at(key), use_count, use_type, true, true);
1652
1653 key = "_ArrayData_";
1654 if (dtype == 'U' || dtype == 'C')
1655 {
1656 for (const auto& el : value.at(key))
1657 {
1658 write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
1659 }
1660 }
1661 else if (dtype == 'i')
1662 {
1663 for (const auto& el : value.at(key))
1664 {
1665 write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
1666 }
1667 }
1668 else if (dtype == 'u')
1669 {
1670 for (const auto& el : value.at(key))
1671 {
1672 write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
1673 }
1674 }
1675 else if (dtype == 'I')
1676 {
1677 for (const auto& el : value.at(key))
1678 {
1679 write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
1680 }
1681 }
1682 else if (dtype == 'm')
1683 {
1684 for (const auto& el : value.at(key))
1685 {
1686 write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
1687 }
1688 }
1689 else if (dtype == 'l')
1690 {
1691 for (const auto& el : value.at(key))
1692 {
1693 write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
1694 }
1695 }
1696 else if (dtype == 'M')
1697 {
1698 for (const auto& el : value.at(key))
1699 {
1700 write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
1701 }
1702 }
1703 else if (dtype == 'L')
1704 {
1705 for (const auto& el : value.at(key))
1706 {
1707 write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
1708 }
1709 }
1710 else if (dtype == 'd')
1711 {
1712 for (const auto& el : value.at(key))
1713 {
1714 write_number(static_cast<float>(el.m_value.number_float), true);
1715 }
1716 }
1717 else if (dtype == 'D')
1718 {
1719 for (const auto& el : value.at(key))
1720 {
1721 write_number(static_cast<double>(el.m_value.number_float), true);
1722 }
1723 }
1724 return false;
1725 }
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744 template<typename NumberType>
1745 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
1746 {
1747
1748 std::array<CharType, sizeof(NumberType)> vec{};
1749 std::memcpy(vec.data(), &n, sizeof(NumberType));
1750
1751
1752 if (is_little_endian != OutputIsLittleEndian)
1753 {
1754
1755 std::reverse(vec.begin(), vec.end());
1756 }
1757
1758 oa->write_characters(vec.data(), sizeof(NumberType));
1759 }
1760
1761 void write_compact_float(const number_float_t n, detail::input_format_t format)
1762 {
1763 #ifdef __GNUC__
1764 #pragma GCC diagnostic push
1765 #pragma GCC diagnostic ignored "-Wfloat-equal"
1766 #endif
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))
1770 {
1771 oa->write_character(format == detail::input_format_t::cbor
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));
1775 }
1776 else
1777 {
1778 oa->write_character(format == detail::input_format_t::cbor
1779 ? get_cbor_float_prefix(n)
1780 : get_msgpack_float_prefix(n));
1781 write_number(n);
1782 }
1783 #ifdef __GNUC__
1784 #pragma GCC diagnostic pop
1785 #endif
1786 }
1787
1788 public:
1789
1790
1791
1792
1793 template < typename C = CharType,
1794 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
1795 static constexpr CharType to_char_type(std::uint8_t x) noexcept
1796 {
1797 return *reinterpret_cast<char*>(&x);
1798 }
1799
1800 template < typename C = CharType,
1801 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
1802 static CharType to_char_type(std::uint8_t x) noexcept
1803 {
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");
1806 CharType result;
1807 std::memcpy(&result, &x, sizeof(x));
1808 return result;
1809 }
1810
1811 template<typename C = CharType,
1812 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
1813 static constexpr CharType to_char_type(std::uint8_t x) noexcept
1814 {
1815 return x;
1816 }
1817
1818 template < typename InputCharType, typename C = CharType,
1819 enable_if_t <
1820 std::is_signed<C>::value &&
1821 std::is_signed<char>::value &&
1822 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
1823 > * = nullptr >
1824 static constexpr CharType to_char_type(InputCharType x) noexcept
1825 {
1826 return x;
1827 }
1828
1829 private:
1830
1831 const bool is_little_endian = little_endianness();
1832
1833
1834 output_adapter_t<CharType> oa = nullptr;
1835 };
1836
1837 }
1838 NLOHMANN_JSON_NAMESPACE_END