71 using number_integer_t =
typename BasicJsonType::number_integer_t;
72 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
73 using number_float_t =
typename BasicJsonType::number_float_t;
74 using string_t =
typename BasicJsonType::string_t;
75 using binary_t =
typename BasicJsonType::binary_t;
76 using json_sax_t = SAX;
77 using char_type =
typename InputAdapterType::char_type;
86 explicit binary_reader(InputAdapterType&& adapter,
const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
106 JSON_HEDLEY_NON_NULL(3)
117 case input_format_t::bson:
118 result = parse_bson_internal();
121 case input_format_t::cbor:
122 result = parse_cbor_internal(
true, tag_handler);
125 case input_format_t::msgpack:
126 result = parse_msgpack_internal();
129 case input_format_t::ubjson:
130 case input_format_t::bjdata:
131 result = parse_ubjson_internal();
134 case input_format_t::json:
142 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
153 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(110, chars_read,
154 exception_message(input_format, concat(
"expected end of input; last byte: 0x", get_token_string()),
"value"),
nullptr));
170 bool parse_bson_internal()
172 std::int32_t document_size{};
173 get_number<std::int32_t, true>(input_format_t::bson, document_size);
175 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
180 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(
false)))
185 return sax->end_object();
195 bool get_bson_cstr(string_t& result)
197 auto out = std::back_inserter(result);
201 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson,
"cstring")))
209 *out++ =
static_cast<typename string_t::value_type
>(current);
224 template<
typename NumberType>
225 bool get_bson_string(
const NumberType len, string_t& result)
227 if (JSON_HEDLEY_UNLIKELY(len < 1))
229 auto last_token = get_token_string();
231 exception_message(input_format_t::bson, concat(
"string length must be at least 1, is ", std::to_string(len)),
"string"),
nullptr));
234 return get_string(input_format_t::bson, len -
static_cast<NumberType
>(1), result) && get() != char_traits<char_type>::eof();
246 template<
typename NumberType>
247 bool get_bson_binary(
const NumberType len, binary_t& result)
249 if (JSON_HEDLEY_UNLIKELY(len < 0))
251 auto last_token = get_token_string();
253 exception_message(input_format_t::bson, concat(
"byte array length cannot be negative, is ", std::to_string(len)),
"binary"),
nullptr));
257 std::uint8_t subtype{};
258 get_number<std::uint8_t>(input_format_t::bson, subtype);
259 result.set_subtype(subtype);
261 return get_binary(input_format_t::bson, len, result);
274 bool parse_bson_element_internal(
const char_int_type element_type,
275 const std::size_t element_type_parse_position)
277 switch (element_type)
282 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
289 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
294 return parse_bson_internal();
299 return parse_bson_array();
306 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
311 return sax->boolean(get() != 0);
321 std::int32_t value{};
322 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
327 std::int64_t value{};
328 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
333 std::uint64_t value{};
334 return get_number<std::uint64_t, true>(input_format_t::bson, value) && sax->number_unsigned(value);
339 std::array<char, 3> cr{{}};
340 static_cast<void>((std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type)));
341 const std::string cr_str{cr.data()};
342 return sax->parse_error(element_type_parse_position, cr_str,
343 parse_error::create(114, element_type_parse_position, concat(
"Unsupported BSON record type 0x", cr_str),
nullptr));
360 bool parse_bson_element_list(
const bool is_array)
364 while (
auto element_type = get())
366 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson,
"element list")))
371 const std::size_t element_type_parse_position = chars_read;
372 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(
key)))
377 if (!is_array && !sax->key(
key))
382 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
398 bool parse_bson_array()
400 std::int32_t document_size{};
401 get_number<std::int32_t, true>(input_format_t::bson, document_size);
403 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
408 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(
true)))
413 return sax->end_array();
428 bool parse_cbor_internal(
const bool get_char,
431 switch (get_char ? get() : current)
434 case char_traits<char_type>::eof():
462 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
466 std::uint8_t number{};
467 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
472 std::uint16_t number{};
473 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
478 std::uint32_t number{};
479 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
484 std::uint64_t number{};
485 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
513 return sax->number_integer(
static_cast<std::int8_t
>(0x20 - 1 - current));
517 std::uint8_t number{};
518 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
523 std::uint16_t number{};
524 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
529 std::uint32_t number{};
530 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
535 std::uint64_t number{};
536 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1)
537 -
static_cast<number_integer_t
>(number));
572 return get_cbor_binary(b) && sax->binary(b);
607 return get_cbor_string(s) && sax->string(s);
635 return get_cbor_array(
636 conditional_static_cast<std::size_t>(
static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
641 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
647 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
653 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
659 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
663 return get_cbor_array(detail::unknown_size(), tag_handler);
690 return get_cbor_object(conditional_static_cast<std::size_t>(
static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
695 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
701 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
707 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
713 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
717 return get_cbor_object(detail::unknown_size(), tag_handler);
743 auto last_token = get_token_string();
745 exception_message(input_format_t::cbor, concat(
"invalid byte: 0x", last_token),
"value"),
nullptr));
755 std::uint8_t subtype_to_ignore{};
756 get_number(input_format_t::cbor, subtype_to_ignore);
761 std::uint16_t subtype_to_ignore{};
762 get_number(input_format_t::cbor, subtype_to_ignore);
767 std::uint32_t subtype_to_ignore{};
768 get_number(input_format_t::cbor, subtype_to_ignore);
773 std::uint64_t subtype_to_ignore{};
774 get_number(input_format_t::cbor, subtype_to_ignore);
780 return parse_cbor_internal(
true, tag_handler);
791 std::uint8_t subtype{};
792 get_number(input_format_t::cbor, subtype);
793 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
798 std::uint16_t subtype{};
799 get_number(input_format_t::cbor, subtype);
800 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
805 std::uint32_t subtype{};
806 get_number(input_format_t::cbor, subtype);
807 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
812 std::uint64_t subtype{};
813 get_number(input_format_t::cbor, subtype);
814 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
818 return parse_cbor_internal(
true, tag_handler);
821 return get_cbor_binary(b) && sax->binary(b);
831 return sax->boolean(
false);
834 return sax->boolean(
true);
841 const auto byte1_raw = get();
842 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"number")))
846 const auto byte2_raw = get();
847 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"number")))
852 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
853 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
863 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
864 const double val = [&half]
866 const int exp = (half >> 10u) & 0x1Fu;
867 const unsigned int mant = half & 0x3FFu;
868 JSON_ASSERT(0 <= exp&& exp <= 32);
869 JSON_ASSERT(mant <= 1024);
873 return std::ldexp(mant, -24);
876 ? std::numeric_limits<double>::infinity()
877 : std::numeric_limits<double>::quiet_NaN();
879 return std::ldexp(mant + 1024, exp - 25);
882 return sax->number_float((half & 0x8000u) != 0
883 ?
static_cast<number_float_t
>(-val)
884 :
static_cast<number_float_t
>(val),
"");
890 return get_number(input_format_t::cbor, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
896 return get_number(input_format_t::cbor, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
901 auto last_token = get_token_string();
903 exception_message(input_format_t::cbor, concat(
"invalid byte: 0x", last_token),
"value"),
nullptr));
919 bool get_cbor_string(string_t& result)
921 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"string")))
954 return get_string(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
960 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
966 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
972 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
978 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
983 while (get() != 0xFF)
986 if (!get_cbor_string(chunk))
990 result.append(chunk);
997 auto last_token = get_token_string();
999 exception_message(input_format_t::cbor, concat(
"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token),
"string"),
nullptr));
1015 bool get_cbor_binary(binary_t& result)
1017 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"binary")))
1050 return get_binary(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
1056 return get_number(input_format_t::cbor, len) &&
1057 get_binary(input_format_t::cbor, len, result);
1062 std::uint16_t len{};
1063 return get_number(input_format_t::cbor, len) &&
1064 get_binary(input_format_t::cbor, len, result);
1069 std::uint32_t len{};
1070 return get_number(input_format_t::cbor, len) &&
1071 get_binary(input_format_t::cbor, len, result);
1076 std::uint64_t len{};
1077 return get_number(input_format_t::cbor, len) &&
1078 get_binary(input_format_t::cbor, len, result);
1083 while (get() != 0xFF)
1086 if (!get_cbor_binary(chunk))
1090 result.insert(result.end(), chunk.begin(), chunk.end());
1097 auto last_token = get_token_string();
1099 exception_message(input_format_t::cbor, concat(
"expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token),
"binary"),
nullptr));
1110 bool get_cbor_array(
const std::size_t len,
1113 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
1118 if (len != detail::unknown_size())
1120 for (std::size_t i = 0; i < len; ++i)
1122 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1130 while (get() != 0xFF)
1132 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
false, tag_handler)))
1139 return sax->end_array();
1148 bool get_cbor_object(
const std::size_t len,
1151 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
1159 if (len != detail::unknown_size())
1161 for (std::size_t i = 0; i < len; ++i)
1164 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(
key) || !sax->key(
key)))
1169 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1178 while (get() != 0xFF)
1180 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(
key) || !sax->key(
key)))
1185 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1194 return sax->end_object();
1204 bool parse_msgpack_internal()
1209 case char_traits<char_type>::eof():
1341 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
1360 return get_msgpack_object(conditional_static_cast<std::size_t>(
static_cast<unsigned int>(current) & 0x0Fu));
1379 return get_msgpack_array(conditional_static_cast<std::size_t>(
static_cast<unsigned int>(current) & 0x0Fu));
1419 return get_msgpack_string(s) && sax->string(s);
1426 return sax->boolean(
false);
1429 return sax->boolean(
true);
1444 return get_msgpack_binary(b) && sax->binary(b);
1450 return get_number(input_format_t::msgpack, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
1456 return get_number(input_format_t::msgpack, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
1461 std::uint8_t number{};
1462 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1467 std::uint16_t number{};
1468 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1473 std::uint32_t number{};
1474 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1479 std::uint64_t number{};
1480 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1485 std::int8_t number{};
1486 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1491 std::int16_t number{};
1492 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1497 std::int32_t number{};
1498 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1503 std::int64_t number{};
1504 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1509 std::uint16_t len{};
1510 return get_number(input_format_t::msgpack, len) && get_msgpack_array(
static_cast<std::size_t
>(len));
1515 std::uint32_t len{};
1516 return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
1521 std::uint16_t len{};
1522 return get_number(input_format_t::msgpack, len) && get_msgpack_object(
static_cast<std::size_t
>(len));
1527 std::uint32_t len{};
1528 return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
1564 return sax->number_integer(
static_cast<std::int8_t
>(current));
1568 auto last_token = get_token_string();
1570 exception_message(input_format_t::msgpack, concat(
"invalid byte: 0x", last_token),
"value"),
nullptr));
1585 bool get_msgpack_string(string_t& result)
1587 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack,
"string")))
1628 return get_string(input_format_t::msgpack,
static_cast<unsigned int>(current) & 0x1Fu, result);
1634 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1639 std::uint16_t len{};
1640 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1645 std::uint32_t len{};
1646 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1651 auto last_token = get_token_string();
1653 exception_message(input_format_t::msgpack, concat(
"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token),
"string"),
nullptr));
1668 bool get_msgpack_binary(binary_t& result)
1671 auto assign_and_return_true = [&result](std::int8_t subtype)
1673 result.set_subtype(
static_cast<std::uint8_t
>(subtype));
1682 return get_number(input_format_t::msgpack, len) &&
1683 get_binary(input_format_t::msgpack, len, result);
1688 std::uint16_t len{};
1689 return get_number(input_format_t::msgpack, len) &&
1690 get_binary(input_format_t::msgpack, len, result);
1695 std::uint32_t len{};
1696 return get_number(input_format_t::msgpack, len) &&
1697 get_binary(input_format_t::msgpack, len, result);
1703 std::int8_t subtype{};
1704 return get_number(input_format_t::msgpack, len) &&
1705 get_number(input_format_t::msgpack, subtype) &&
1706 get_binary(input_format_t::msgpack, len, result) &&
1707 assign_and_return_true(subtype);
1712 std::uint16_t len{};
1713 std::int8_t subtype{};
1714 return get_number(input_format_t::msgpack, len) &&
1715 get_number(input_format_t::msgpack, subtype) &&
1716 get_binary(input_format_t::msgpack, len, result) &&
1717 assign_and_return_true(subtype);
1722 std::uint32_t len{};
1723 std::int8_t subtype{};
1724 return get_number(input_format_t::msgpack, len) &&
1725 get_number(input_format_t::msgpack, subtype) &&
1726 get_binary(input_format_t::msgpack, len, result) &&
1727 assign_and_return_true(subtype);
1732 std::int8_t subtype{};
1733 return get_number(input_format_t::msgpack, subtype) &&
1734 get_binary(input_format_t::msgpack, 1, result) &&
1735 assign_and_return_true(subtype);
1740 std::int8_t subtype{};
1741 return get_number(input_format_t::msgpack, subtype) &&
1742 get_binary(input_format_t::msgpack, 2, result) &&
1743 assign_and_return_true(subtype);
1748 std::int8_t subtype{};
1749 return get_number(input_format_t::msgpack, subtype) &&
1750 get_binary(input_format_t::msgpack, 4, result) &&
1751 assign_and_return_true(subtype);
1756 std::int8_t subtype{};
1757 return get_number(input_format_t::msgpack, subtype) &&
1758 get_binary(input_format_t::msgpack, 8, result) &&
1759 assign_and_return_true(subtype);
1764 std::int8_t subtype{};
1765 return get_number(input_format_t::msgpack, subtype) &&
1766 get_binary(input_format_t::msgpack, 16, result) &&
1767 assign_and_return_true(subtype);
1779 bool get_msgpack_array(
const std::size_t len)
1781 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
1786 for (std::size_t i = 0; i < len; ++i)
1788 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
1794 return sax->end_array();
1801 bool get_msgpack_object(
const std::size_t len)
1803 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
1809 for (std::size_t i = 0; i < len; ++i)
1812 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(
key) || !sax->key(
key)))
1817 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
1824 return sax->end_object();
1838 bool parse_ubjson_internal(
const bool get_char =
true)
1840 return get_ubjson_value(get_char ? get_ignore_noop() : current);
1857 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
1864 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"value")))
1874 return get_number(input_format, len) && get_string(input_format, len, result);
1880 return get_number(input_format, len) && get_string(input_format, len, result);
1886 return get_number(input_format, len) && get_string(input_format, len, result);
1892 return get_number(input_format, len) && get_string(input_format, len, result);
1898 return get_number(input_format, len) && get_string(input_format, len, result);
1903 if (input_format != input_format_t::bjdata)
1907 std::uint16_t len{};
1908 return get_number(input_format, len) && get_string(input_format, len, result);
1913 if (input_format != input_format_t::bjdata)
1917 std::uint32_t len{};
1918 return get_number(input_format, len) && get_string(input_format, len, result);
1923 if (input_format != input_format_t::bjdata)
1927 std::uint64_t len{};
1928 return get_number(input_format, len) && get_string(input_format, len, result);
1934 auto last_token = get_token_string();
1935 std::string message;
1937 if (input_format != input_format_t::bjdata)
1939 message =
"expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
1943 message =
"expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
1945 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format, message,
"string"),
nullptr));
1952 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
1954 std::pair<std::size_t, char_int_type> size_and_type;
1956 bool no_ndarray =
true;
1958 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
1963 if (size_and_type.first != npos)
1965 if (size_and_type.second != 0)
1967 if (size_and_type.second !=
'N')
1969 for (std::size_t i = 0; i < size_and_type.first; ++i)
1971 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
1975 dim.push_back(dimlen);
1981 for (std::size_t i = 0; i < size_and_type.first; ++i)
1983 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
1987 dim.push_back(dimlen);
1993 while (current !=
']')
1995 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
1999 dim.push_back(dimlen);
2017 bool get_ubjson_size_value(std::size_t& result,
bool& is_ndarray, char_int_type prefix = 0)
2021 prefix = get_ignore_noop();
2028 std::uint8_t number{};
2029 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2033 result =
static_cast<std::size_t
>(number);
2039 std::int8_t number{};
2040 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2046 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(113, chars_read,
2047 exception_message(input_format,
"count in an optimized container must be positive",
"size"),
nullptr));
2049 result =
static_cast<std::size_t
>(number);
2055 std::int16_t number{};
2056 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2062 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(113, chars_read,
2063 exception_message(input_format,
"count in an optimized container must be positive",
"size"),
nullptr));
2065 result =
static_cast<std::size_t
>(number);
2071 std::int32_t number{};
2072 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2078 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(113, chars_read,
2079 exception_message(input_format,
"count in an optimized container must be positive",
"size"),
nullptr));
2081 result =
static_cast<std::size_t
>(number);
2087 std::int64_t number{};
2088 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2094 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(113, chars_read,
2095 exception_message(input_format,
"count in an optimized container must be positive",
"size"),
nullptr));
2097 if (!value_in_range_of<std::size_t>(number))
2099 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
2100 exception_message(input_format,
"integer value overflow",
"size"),
nullptr));
2102 result =
static_cast<std::size_t
>(number);
2108 if (input_format != input_format_t::bjdata)
2112 std::uint16_t number{};
2113 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2117 result =
static_cast<std::size_t
>(number);
2123 if (input_format != input_format_t::bjdata)
2127 std::uint32_t number{};
2128 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2132 result = conditional_static_cast<std::size_t>(number);
2138 if (input_format != input_format_t::bjdata)
2142 std::uint64_t number{};
2143 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
2147 if (!value_in_range_of<std::size_t>(number))
2149 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
2150 exception_message(input_format,
"integer value overflow",
"size"),
nullptr));
2152 result = detail::conditional_static_cast<std::size_t>(number);
2158 if (input_format != input_format_t::bjdata)
2164 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(113, chars_read, exception_message(input_format,
"ndarray dimensional vector is not allowed",
"size"),
nullptr));
2166 std::vector<size_t> dim;
2167 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
2171 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1))
2173 result = dim.at(dim.size() - 1);
2187 string_t
key =
"_ArraySize_";
2188 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(
key) || !sax->start_array(dim.size())))
2198 if (JSON_HEDLEY_UNLIKELY(i > 0 && result > (std::numeric_limits<std::size_t>::max)() / i))
2200 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format,
"excessive ndarray size caused overflow",
"size"),
nullptr));
2204 if (result == 0 || result == npos)
2206 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format,
"excessive ndarray size caused overflow",
"size"),
nullptr));
2208 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(
static_cast<number_unsigned_t
>(i))))
2214 return sax->end_array();
2223 auto last_token = get_token_string();
2224 std::string message;
2226 if (input_format != input_format_t::bjdata)
2228 message =
"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
2232 message =
"expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
2234 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format, message,
"size"),
nullptr));
2248 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result,
bool inside_ndarray =
false)
2250 result.first = npos;
2252 bool is_ndarray =
false;
2258 result.second = get();
2259 if (input_format == input_format_t::bjdata
2260 && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
2262 auto last_token = get_token_string();
2264 exception_message(input_format, concat(
"marker 0x", last_token,
" is not a permitted optimized array type"),
"type"),
nullptr));
2267 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"type")))
2273 if (JSON_HEDLEY_UNLIKELY(current !=
'#'))
2275 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"value")))
2279 auto last_token = get_token_string();
2281 exception_message(input_format, concat(
"expected '#' after type information; last byte: 0x", last_token),
"size"),
nullptr));
2284 const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
2285 if (input_format == input_format_t::bjdata && is_ndarray)
2289 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(112, chars_read,
2290 exception_message(input_format,
"ndarray can not be recursive",
"size"),
nullptr));
2292 result.second |= (1 << 8);
2299 const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
2300 if (input_format == input_format_t::bjdata && is_ndarray)
2302 return sax->parse_error(chars_read, get_token_string(),
parse_error::create(112, chars_read,
2303 exception_message(input_format,
"ndarray requires both type and size",
"size"),
nullptr));
2315 bool get_ubjson_value(
const char_int_type prefix)
2319 case char_traits<char_type>::eof():
2320 return unexpect_eof(input_format,
"value");
2323 return sax->boolean(
true);
2325 return sax->boolean(
false);
2332 if (input_format != input_format_t::bjdata)
2336 std::uint8_t number{};
2337 return get_number(input_format, number) && sax->number_unsigned(number);
2342 std::uint8_t number{};
2343 return get_number(input_format, number) && sax->number_unsigned(number);
2348 std::int8_t number{};
2349 return get_number(input_format, number) && sax->number_integer(number);
2354 std::int16_t number{};
2355 return get_number(input_format, number) && sax->number_integer(number);
2360 std::int32_t number{};
2361 return get_number(input_format, number) && sax->number_integer(number);
2366 std::int64_t number{};
2367 return get_number(input_format, number) && sax->number_integer(number);
2372 if (input_format != input_format_t::bjdata)
2376 std::uint16_t number{};
2377 return get_number(input_format, number) && sax->number_unsigned(number);
2382 if (input_format != input_format_t::bjdata)
2386 std::uint32_t number{};
2387 return get_number(input_format, number) && sax->number_unsigned(number);
2392 if (input_format != input_format_t::bjdata)
2396 std::uint64_t number{};
2397 return get_number(input_format, number) && sax->number_unsigned(number);
2402 if (input_format != input_format_t::bjdata)
2406 const auto byte1_raw = get();
2407 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"number")))
2411 const auto byte2_raw = get();
2412 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"number")))
2417 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
2418 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
2428 const auto half =
static_cast<unsigned int>((byte2 << 8u) + byte1);
2429 const double val = [&half]
2431 const int exp = (half >> 10u) & 0x1Fu;
2432 const unsigned int mant = half & 0x3FFu;
2433 JSON_ASSERT(0 <= exp&& exp <= 32);
2434 JSON_ASSERT(mant <= 1024);
2438 return std::ldexp(mant, -24);
2441 ? std::numeric_limits<double>::infinity()
2442 : std::numeric_limits<double>::quiet_NaN();
2444 return std::ldexp(mant + 1024, exp - 25);
2447 return sax->number_float((half & 0x8000u) != 0
2448 ?
static_cast<number_float_t
>(-val)
2449 :
static_cast<number_float_t
>(val),
"");
2455 return get_number(input_format, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
2461 return get_number(input_format, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
2466 return get_ubjson_high_precision_number();
2472 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"char")))
2476 if (JSON_HEDLEY_UNLIKELY(current > 127))
2478 auto last_token = get_token_string();
2480 exception_message(input_format, concat(
"byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token),
"char"),
nullptr));
2482 string_t s(1,
static_cast<typename string_t::value_type
>(current));
2483 return sax->string(s);
2489 return get_ubjson_string(s) && sax->string(s);
2493 return get_ubjson_array();
2496 return get_ubjson_object();
2501 auto last_token = get_token_string();
2502 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format,
"invalid byte: 0x" + last_token,
"value"),
nullptr));
2508 bool get_ubjson_array()
2510 std::pair<std::size_t, char_int_type> size_and_type;
2511 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
2519 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
2521 size_and_type.second &= ~(
static_cast<char_int_type
>(1) << 8);
2522 auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](
const bjd_type & p, char_int_type t)
2526 string_t
key =
"_ArrayType_";
2527 if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
2529 auto last_token = get_token_string();
2531 exception_message(input_format,
"invalid byte: 0x" + last_token,
"type"),
nullptr));
2534 string_t type = it->second;
2535 if (JSON_HEDLEY_UNLIKELY(!sax->key(
key) || !sax->string(type)))
2540 if (size_and_type.second ==
'C' || size_and_type.second ==
'B')
2542 size_and_type.second =
'U';
2545 key =
"_ArrayData_";
2546 if (JSON_HEDLEY_UNLIKELY(!sax->key(
key) || !sax->start_array(size_and_type.first) ))
2551 for (std::size_t i = 0; i < size_and_type.first; ++i)
2553 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2559 return (sax->end_array() && sax->end_object());
2563 if (input_format == input_format_t::bjdata && size_and_type.first != npos && size_and_type.second ==
'B')
2566 return get_binary(input_format, size_and_type.first, result) && sax->binary(result);
2569 if (size_and_type.first != npos)
2571 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
2576 if (size_and_type.second != 0)
2578 if (size_and_type.second !=
'N')
2580 for (std::size_t i = 0; i < size_and_type.first; ++i)
2582 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2591 for (std::size_t i = 0; i < size_and_type.first; ++i)
2593 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2602 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
2607 while (current !=
']')
2609 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(
false)))
2617 return sax->end_array();
2623 bool get_ubjson_object()
2625 std::pair<std::size_t, char_int_type> size_and_type;
2626 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
2632 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
2634 auto last_token = get_token_string();
2636 exception_message(input_format,
"BJData object does not support ND-array size in optimized format",
"object"),
nullptr));
2640 if (size_and_type.first != npos)
2642 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
2647 if (size_and_type.second != 0)
2649 for (std::size_t i = 0; i < size_and_type.first; ++i)
2651 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(
key) || !sax->key(
key)))
2655 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2664 for (std::size_t i = 0; i < size_and_type.first; ++i)
2666 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(
key) || !sax->key(
key)))
2670 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2680 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
2685 while (current !=
'}')
2687 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(
key,
false) || !sax->key(
key)))
2691 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2700 return sax->end_object();
2706 bool get_ubjson_high_precision_number()
2710 bool no_ndarray =
true;
2711 auto res = get_ubjson_size_value(size, no_ndarray);
2712 if (JSON_HEDLEY_UNLIKELY(!res))
2718 std::vector<char> number_vector;
2719 for (std::size_t i = 0; i < size; ++i)
2722 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format,
"number")))
2726 number_vector.push_back(
static_cast<char>(current));
2730 using ia_type =
decltype(detail::input_adapter(number_vector));
2731 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector),
false);
2732 const auto result_number = number_lexer.scan();
2733 const auto number_string = number_lexer.get_token_string();
2734 const auto result_remainder = number_lexer.scan();
2738 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
2741 exception_message(input_format, concat(
"invalid number text: ", number_lexer.get_token_string()),
"high-precision number"),
nullptr));
2744 switch (result_number)
2746 case token_type::value_integer:
2747 return sax->number_integer(number_lexer.get_number_integer());
2748 case token_type::value_unsigned:
2749 return sax->number_unsigned(number_lexer.get_number_unsigned());
2750 case token_type::value_float:
2751 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
2752 case token_type::uninitialized:
2753 case token_type::literal_true:
2754 case token_type::literal_false:
2755 case token_type::literal_null:
2756 case token_type::value_string:
2757 case token_type::begin_array:
2758 case token_type::begin_object:
2759 case token_type::end_array:
2760 case token_type::end_object:
2761 case token_type::name_separator:
2762 case token_type::value_separator:
2763 case token_type::parse_error:
2764 case token_type::end_of_input:
2765 case token_type::literal_or_value:
2768 exception_message(input_format, concat(
"invalid number text: ", number_lexer.get_token_string()),
"high-precision number"),
nullptr));
2788 return current = ia.get_character();
2800 bool get_to(T& dest,
const input_format_t format,
const char* context)
2802 auto new_chars_read = ia.get_elements(&dest);
2803 chars_read += new_chars_read;
2804 if (JSON_HEDLEY_UNLIKELY(new_chars_read <
sizeof(T)))
2808 sax->parse_error(chars_read,
"<end of file>",
parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context),
nullptr));
2817 char_int_type get_ignore_noop()
2823 while (current ==
'N');
2828 template<
class NumberType>
2829 static void byte_swap(NumberType& number)
2831 constexpr std::size_t sz =
sizeof(number);
2832#ifdef __cpp_lib_byteswap
2833 if constexpr (sz == 1)
2837 else if constexpr(std::is_integral_v<NumberType>)
2839 number = std::byteswap(number);
2845 auto* ptr =
reinterpret_cast<std::uint8_t*
>(&number);
2846 for (std::size_t i = 0; i < sz / 2; ++i)
2848 std::swap(ptr[i], ptr[sz - i - 1]);
2850#ifdef __cpp_lib_byteswap
2870 template<
typename NumberType,
bool InputIsLittleEndian = false>
2875 if (JSON_HEDLEY_UNLIKELY(!get_to(result, format,
"number")))
2879 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
2900 template<
typename NumberType>
2902 const NumberType len,
2905 bool success =
true;
2906 for (NumberType i = 0; i < len; i++)
2909 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"string")))
2914 result.push_back(
static_cast<typename string_t::value_type
>(current));
2933 template<
typename NumberType>
2935 const NumberType len,
2938 bool success =
true;
2939 for (NumberType i = 0; i < len; i++)
2942 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"binary")))
2947 result.push_back(
static_cast<typename binary_t::value_type
>(current));
2957 JSON_HEDLEY_NON_NULL(3)
2958 bool unexpect_eof(const
input_format_t format, const
char* context)
const
2960 if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
2962 return sax->parse_error(chars_read,
"<end of file>",
2963 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context),
nullptr));
2971 std::string get_token_string()
const
2973 std::array<char, 3> cr{{}};
2974 static_cast<void>((std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(current)));
2975 return std::string{cr.data()};
2985 const std::string& detail,
2986 const std::string& context)
const
2988 std::string error_msg =
"syntax error while parsing ";
2992 case input_format_t::cbor:
2993 error_msg +=
"CBOR";
2996 case input_format_t::msgpack:
2997 error_msg +=
"MessagePack";
3000 case input_format_t::ubjson:
3001 error_msg +=
"UBJSON";
3004 case input_format_t::bson:
3005 error_msg +=
"BSON";
3008 case input_format_t::bjdata:
3009 error_msg +=
"BJData";
3012 case input_format_t::json:
3017 return concat(error_msg,
' ', context,
": ", detail);
3021 static JSON_INLINE_VARIABLE
constexpr std::size_t npos = detail::unknown_size();
3024 InputAdapterType ia;
3027 char_int_type current = char_traits<char_type>::eof();
3030 std::size_t chars_read = 0;
3039 json_sax_t* sax =
nullptr;
3042#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
3043 make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
3045#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
3046 make_array<bjd_type>( \
3047 bjd_type{'B', "byte"}, \
3048 bjd_type{'C', "char"}, \
3049 bjd_type{'D', "double"}, \
3050 bjd_type{'I', "int16"}, \
3051 bjd_type{'L', "int64"}, \
3052 bjd_type{'M', "uint64"}, \
3053 bjd_type{'U', "uint8"}, \
3054 bjd_type{'d', "single"}, \
3055 bjd_type{'i', "int8"}, \
3056 bjd_type{'l', "int32"}, \
3057 bjd_type{'m', "uint32"}, \
3058 bjd_type{'u', "uint16"})
3060 JSON_PRIVATE_UNLESS_TESTED:
3063 const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
3064 JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_;
3066 using bjd_type = std::pair<char_int_type, string_t>;
3068 const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
3069 JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_;
3071#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
3072#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_