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