15 #include <nlohmann/detail/exceptions.hpp>
16 #include <nlohmann/detail/input/input_adapters.hpp>
17 #include <nlohmann/detail/input/json_sax.hpp>
18 #include <nlohmann/detail/input/lexer.hpp>
19 #include <nlohmann/detail/macro_scope.hpp>
20 #include <nlohmann/detail/meta/is_sax.hpp>
21 #include <nlohmann/detail/value_t.hpp>
42 static inline bool little_endianess(
int num = 1) noexcept
44 return *
reinterpret_cast<char*
>(&num) == 1;
55 template<
typename BasicJsonType,
typename InputAdapterType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
58 using number_integer_t =
typename BasicJsonType::number_integer_t;
59 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
60 using number_float_t =
typename BasicJsonType::number_float_t;
61 using string_t =
typename BasicJsonType::string_t;
62 using binary_t =
typename BasicJsonType::binary_t;
63 using json_sax_t = SAX;
64 using char_type =
typename InputAdapterType::char_type;
65 using char_int_type =
typename std::char_traits<char_type>::int_type;
73 explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
93 JSON_HEDLEY_NON_NULL(3)
96 const
bool strict = true,
104 case input_format_t::bson:
105 result = parse_bson_internal();
108 case input_format_t::cbor:
109 result = parse_cbor_internal(
true, tag_handler);
112 case input_format_t::msgpack:
113 result = parse_msgpack_internal();
116 case input_format_t::ubjson:
117 result = parse_ubjson_internal();
127 if (format == input_format_t::ubjson)
136 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
138 return sax->parse_error(chars_read, get_token_string(),
139 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value")));
155 bool parse_bson_internal()
158 get_number<std::int32_t, true>(input_format_t::bson, document_size);
160 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
165 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(
false)))
170 return sax->end_object();
180 bool get_bson_cstr(string_t& result)
182 auto out = std::back_inserter(result);
186 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson,
"cstring")))
194 *out++ =
static_cast<typename string_t::value_type
>(current);
209 template<
typename NumberType>
210 bool get_bson_string(
const NumberType len, string_t& result)
212 if (JSON_HEDLEY_UNLIKELY(len < 1))
214 auto last_token = get_token_string();
215 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::bson,
"string length must be at least 1, is " + std::to_string(len),
"string")));
218 return get_string(input_format_t::bson, len -
static_cast<NumberType
>(1), result) && get() != std::char_traits<char_type>::eof();
230 template<
typename NumberType>
231 bool get_bson_binary(
const NumberType len, binary_t& result)
233 if (JSON_HEDLEY_UNLIKELY(len < 0))
235 auto last_token = get_token_string();
236 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::bson,
"byte array length cannot be negative, is " + std::to_string(len),
"binary")));
241 get_number<std::uint8_t>(input_format_t::bson, subtype);
242 result.set_subtype(subtype);
244 return get_binary(input_format_t::bson, len, result);
257 bool parse_bson_element_internal(
const char_int_type element_type,
258 const std::size_t element_type_parse_position)
260 switch (element_type)
265 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
272 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
277 return parse_bson_internal();
282 return parse_bson_array();
289 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
294 return sax->boolean(get() != 0);
305 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
311 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
316 std::array<char, 3> cr{{}};
317 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type));
318 return sax->parse_error(element_type_parse_position, std::string(cr.data()),
parse_error::create(114, element_type_parse_position,
"Unsupported BSON record type 0x" + std::string(cr.data())));
335 bool parse_bson_element_list(
const bool is_array)
339 while (
auto element_type = get())
341 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson,
"element list")))
346 const std::size_t element_type_parse_position = chars_read;
347 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
352 if (!is_array && !sax->key(key))
357 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
373 bool parse_bson_array()
376 get_number<std::int32_t, true>(input_format_t::bson, document_size);
378 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
383 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(
true)))
388 return sax->end_array();
403 bool parse_cbor_internal(
const bool get_char,
406 switch (get_char ? get() : current)
409 case std::char_traits<char_type>::eof():
437 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
442 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
448 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
454 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
460 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
488 return sax->number_integer(
static_cast<std::int8_t>(0x20 - 1 - current));
493 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
499 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
505 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
511 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1)
512 -
static_cast<number_integer_t
>(number));
547 return get_cbor_binary(b) && sax->binary(b);
582 return get_cbor_string(s) && sax->string(s);
610 return get_cbor_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
615 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
621 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
627 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
633 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
637 return get_cbor_array(std::size_t(-1), tag_handler);
664 return get_cbor_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
669 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
675 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
681 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
687 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
691 return get_cbor_object(std::size_t(-1), tag_handler);
717 auto last_token = get_token_string();
718 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::cbor,
"invalid byte: 0x" + last_token,
"value")));
728 get_number(input_format_t::cbor, len);
734 get_number(input_format_t::cbor, len);
740 get_number(input_format_t::cbor, len);
746 get_number(input_format_t::cbor, len);
752 return parse_cbor_internal(
true, tag_handler);
761 return sax->boolean(
false);
764 return sax->boolean(
true);
771 const auto byte1_raw = get();
772 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"number")))
776 const auto byte2_raw = get();
777 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"number")))
782 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
783 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
793 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
794 const double val = [&half]
796 const int exp = (half >> 10u) & 0x1Fu;
797 const unsigned int mant = half & 0x3FFu;
798 JSON_ASSERT(0 <= exp&& exp <= 32);
799 JSON_ASSERT(mant <= 1024);
803 return std::ldexp(mant, -24);
806 ? std::numeric_limits<double>::infinity()
807 : std::numeric_limits<double>::quiet_NaN();
809 return std::ldexp(mant + 1024, exp - 25);
812 return sax->number_float((half & 0x8000u) != 0
813 ?
static_cast<number_float_t
>(-val)
814 :
static_cast<number_float_t
>(val),
"");
820 return get_number(input_format_t::cbor, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
826 return get_number(input_format_t::cbor, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
831 auto last_token = get_token_string();
832 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::cbor,
"invalid byte: 0x" + last_token,
"value")));
848 bool get_cbor_string(string_t& result)
850 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"string")))
883 return get_string(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
889 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
895 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
901 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
907 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
912 while (get() != 0xFF)
915 if (!get_cbor_string(chunk))
919 result.append(chunk);
926 auto last_token = get_token_string();
927 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::cbor,
"expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token,
"string")));
943 bool get_cbor_binary(binary_t& result)
945 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"binary")))
978 return get_binary(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
984 return get_number(input_format_t::cbor, len) &&
985 get_binary(input_format_t::cbor, len, result);
991 return get_number(input_format_t::cbor, len) &&
992 get_binary(input_format_t::cbor, len, result);
998 return get_number(input_format_t::cbor, len) &&
999 get_binary(input_format_t::cbor, len, result);
1005 return get_number(input_format_t::cbor, len) &&
1006 get_binary(input_format_t::cbor, len, result);
1011 while (get() != 0xFF)
1014 if (!get_cbor_binary(chunk))
1018 result.insert(result.end(), chunk.begin(), chunk.end());
1025 auto last_token = get_token_string();
1026 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::cbor,
"expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token,
"binary")));
1037 bool get_cbor_array(
const std::size_t len,
1040 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
1045 if (len != std::size_t(-1))
1047 for (std::size_t i = 0; i < len; ++i)
1049 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1057 while (get() != 0xFF)
1059 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
false, tag_handler)))
1066 return sax->end_array();
1075 bool get_cbor_object(
const std::size_t len,
1078 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
1084 if (len != std::size_t(-1))
1086 for (std::size_t i = 0; i < len; ++i)
1089 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
1094 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1103 while (get() != 0xFF)
1105 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
1110 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1118 return sax->end_object();
1128 bool parse_msgpack_internal()
1133 case std::char_traits<char_type>::eof():
1265 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
1284 return get_msgpack_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
1303 return get_msgpack_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
1343 return get_msgpack_string(s) && sax->string(s);
1350 return sax->boolean(
false);
1353 return sax->boolean(
true);
1368 return get_msgpack_binary(b) && sax->binary(b);
1374 return get_number(input_format_t::msgpack, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
1380 return get_number(input_format_t::msgpack, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
1386 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1392 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1398 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1404 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1410 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1416 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1422 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1428 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1434 return get_number(input_format_t::msgpack, len) && get_msgpack_array(
static_cast<std::size_t
>(len));
1440 return get_number(input_format_t::msgpack, len) && get_msgpack_array(
static_cast<std::size_t
>(len));
1446 return get_number(input_format_t::msgpack, len) && get_msgpack_object(
static_cast<std::size_t
>(len));
1452 return get_number(input_format_t::msgpack, len) && get_msgpack_object(
static_cast<std::size_t
>(len));
1488 return sax->number_integer(
static_cast<std::int8_t>(current));
1492 auto last_token = get_token_string();
1493 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::msgpack,
"invalid byte: 0x" + last_token,
"value")));
1508 bool get_msgpack_string(string_t& result)
1510 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack,
"string")))
1551 return get_string(input_format_t::msgpack,
static_cast<unsigned int>(current) & 0x1Fu, result);
1557 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1563 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1569 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1574 auto last_token = get_token_string();
1575 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::msgpack,
"expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token,
"string")));
1590 bool get_msgpack_binary(binary_t& result)
1593 auto assign_and_return_true = [&result](
std::int8_t subtype)
1595 result.set_subtype(
static_cast<std::uint8_t>(subtype));
1604 return get_number(input_format_t::msgpack, len) &&
1605 get_binary(input_format_t::msgpack, len, result);
1611 return get_number(input_format_t::msgpack, len) &&
1612 get_binary(input_format_t::msgpack, len, result);
1618 return get_number(input_format_t::msgpack, len) &&
1619 get_binary(input_format_t::msgpack, len, result);
1626 return get_number(input_format_t::msgpack, len) &&
1627 get_number(input_format_t::msgpack, subtype) &&
1628 get_binary(input_format_t::msgpack, len, result) &&
1629 assign_and_return_true(subtype);
1636 return get_number(input_format_t::msgpack, len) &&
1637 get_number(input_format_t::msgpack, subtype) &&
1638 get_binary(input_format_t::msgpack, len, result) &&
1639 assign_and_return_true(subtype);
1646 return get_number(input_format_t::msgpack, len) &&
1647 get_number(input_format_t::msgpack, subtype) &&
1648 get_binary(input_format_t::msgpack, len, result) &&
1649 assign_and_return_true(subtype);
1655 return get_number(input_format_t::msgpack, subtype) &&
1656 get_binary(input_format_t::msgpack, 1, result) &&
1657 assign_and_return_true(subtype);
1663 return get_number(input_format_t::msgpack, subtype) &&
1664 get_binary(input_format_t::msgpack, 2, result) &&
1665 assign_and_return_true(subtype);
1671 return get_number(input_format_t::msgpack, subtype) &&
1672 get_binary(input_format_t::msgpack, 4, result) &&
1673 assign_and_return_true(subtype);
1679 return get_number(input_format_t::msgpack, subtype) &&
1680 get_binary(input_format_t::msgpack, 8, result) &&
1681 assign_and_return_true(subtype);
1687 return get_number(input_format_t::msgpack, subtype) &&
1688 get_binary(input_format_t::msgpack, 16, result) &&
1689 assign_and_return_true(subtype);
1701 bool get_msgpack_array(
const std::size_t len)
1703 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
1708 for (std::size_t i = 0; i < len; ++i)
1710 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
1716 return sax->end_array();
1723 bool get_msgpack_object(
const std::size_t len)
1725 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
1731 for (std::size_t i = 0; i < len; ++i)
1734 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
1739 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
1746 return sax->end_object();
1760 bool parse_ubjson_internal(
const bool get_char =
true)
1762 return get_ubjson_value(get_char ? get_ignore_noop() : current);
1779 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
1786 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"value")))
1796 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1802 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1808 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1814 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1820 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1824 auto last_token = get_token_string();
1825 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L); last byte: 0x" + last_token,
"string")));
1833 bool get_ubjson_size_value(std::size_t& result)
1835 switch (get_ignore_noop())
1840 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1844 result =
static_cast<std::size_t
>(number);
1851 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1855 result =
static_cast<std::size_t
>(number);
1862 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1866 result =
static_cast<std::size_t
>(number);
1873 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1877 result =
static_cast<std::size_t
>(number);
1884 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1888 result =
static_cast<std::size_t
>(number);
1894 auto last_token = get_token_string();
1895 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token,
"size")));
1910 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
1912 result.first = string_t::npos;
1919 result.second = get();
1920 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"type")))
1926 if (JSON_HEDLEY_UNLIKELY(current !=
'#'))
1928 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"value")))
1932 auto last_token = get_token_string();
1933 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"expected '#' after type information; last byte: 0x" + last_token,
"size")));
1936 return get_ubjson_size_value(result.first);
1941 return get_ubjson_size_value(result.first);
1951 bool get_ubjson_value(
const char_int_type prefix)
1955 case std::char_traits<char_type>::eof():
1959 return sax->boolean(
true);
1961 return sax->boolean(
false);
1969 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
1975 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
1981 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
1987 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
1993 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
1999 return get_number(input_format_t::ubjson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
2005 return get_number(input_format_t::ubjson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
2010 return get_ubjson_high_precision_number();
2016 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"char")))
2020 if (JSON_HEDLEY_UNLIKELY(current > 127))
2022 auto last_token = get_token_string();
2023 return sax->parse_error(chars_read, last_token,
parse_error::create(113, chars_read, exception_message(input_format_t::ubjson,
"byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token,
"char")));
2025 string_t s(1,
static_cast<typename string_t::value_type
>(current));
2026 return sax->string(s);
2032 return get_ubjson_string(s) && sax->string(s);
2036 return get_ubjson_array();
2039 return get_ubjson_object();
2043 auto last_token = get_token_string();
2044 return sax->parse_error(chars_read, last_token,
parse_error::create(112, chars_read, exception_message(input_format_t::ubjson,
"invalid byte: 0x" + last_token,
"value")));
2052 bool get_ubjson_array()
2054 std::pair<std::size_t, char_int_type> size_and_type;
2055 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
2060 if (size_and_type.first != string_t::npos)
2062 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
2067 if (size_and_type.second != 0)
2069 if (size_and_type.second !=
'N')
2071 for (std::size_t i = 0; i < size_and_type.first; ++i)
2073 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2082 for (std::size_t i = 0; i < size_and_type.first; ++i)
2084 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2093 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
2098 while (current !=
']')
2100 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(
false)))
2108 return sax->end_array();
2114 bool get_ubjson_object()
2116 std::pair<std::size_t, char_int_type> size_and_type;
2117 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
2123 if (size_and_type.first != string_t::npos)
2125 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
2130 if (size_and_type.second != 0)
2132 for (std::size_t i = 0; i < size_and_type.first; ++i)
2134 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
2138 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2147 for (std::size_t i = 0; i < size_and_type.first; ++i)
2149 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
2153 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2163 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
2168 while (current !=
'}')
2170 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key,
false) || !sax->key(key)))
2174 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2183 return sax->end_object();
2189 bool get_ubjson_high_precision_number()
2193 auto res = get_ubjson_size_value(size);
2194 if (JSON_HEDLEY_UNLIKELY(!res))
2200 std::vector<char> number_vector;
2201 for (std::size_t i = 0; i < size; ++i)
2204 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"number")))
2208 number_vector.push_back(
static_cast<char>(current));
2212 auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
2213 auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia),
false);
2214 const auto result_number = number_lexer.scan();
2215 const auto number_string = number_lexer.get_token_string();
2216 const auto result_remainder = number_lexer.scan();
2220 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
2222 return sax->parse_error(chars_read, number_string,
parse_error::create(115, chars_read, exception_message(input_format_t::ubjson,
"invalid number text: " + number_lexer.get_token_string(),
"high-precision number")));
2225 switch (result_number)
2227 case token_type::value_integer:
2228 return sax->number_integer(number_lexer.get_number_integer());
2229 case token_type::value_unsigned:
2230 return sax->number_unsigned(number_lexer.get_number_unsigned());
2231 case token_type::value_float:
2232 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
2234 return sax->parse_error(chars_read, number_string,
parse_error::create(115, chars_read, exception_message(input_format_t::ubjson,
"invalid number text: " + number_lexer.get_token_string(),
"high-precision number")));
2254 return current = ia.get_character();
2260 char_int_type get_ignore_noop()
2266 while (current ==
'N');
2284 template<
typename NumberType,
bool InputIsLittleEndian = false>
2289 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
2292 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"number")))
2298 if (is_little_endian != InputIsLittleEndian)
2300 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t>(current);
2309 std::memcpy(&result, vec.data(),
sizeof(NumberType));
2327 template<
typename NumberType>
2329 const NumberType len,
2332 bool success =
true;
2333 for (NumberType i = 0; i < len; i++)
2336 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"string")))
2341 result.push_back(
static_cast<typename string_t::value_type
>(current));
2360 template<
typename NumberType>
2362 const NumberType len,
2365 bool success =
true;
2366 for (NumberType i = 0; i < len; i++)
2369 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"binary")))
2384 JSON_HEDLEY_NON_NULL(3)
2385 bool unexpect_eof(const
input_format_t format, const
char* context)
const
2387 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
2389 return sax->parse_error(chars_read,
"<end of file>",
2390 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context)));
2398 std::string get_token_string()
const
2400 std::array<char, 3> cr{{}};
2401 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(current));
2402 return std::string{cr.data()};
2412 const std::string& detail,
2413 const std::string& context)
const
2415 std::string error_msg =
"syntax error while parsing ";
2419 case input_format_t::cbor:
2420 error_msg +=
"CBOR";
2423 case input_format_t::msgpack:
2424 error_msg +=
"MessagePack";
2427 case input_format_t::ubjson:
2428 error_msg +=
"UBJSON";
2431 case input_format_t::bson:
2432 error_msg +=
"BSON";
2439 return error_msg +
" " + context +
": " + detail;
2444 InputAdapterType ia;
2447 char_int_type current = std::char_traits<char_type>::eof();
2450 std::size_t chars_read = 0;
2453 const bool is_little_endian = little_endianess();
2456 json_sax_t* sax =
nullptr;
deserialization of CBOR, MessagePack, and UBJSON values
Definition: binary_reader.hpp:57
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: binary_reader.hpp:94
binary_reader(InputAdapterType &&adapter)
create a binary reader
Definition: binary_reader.hpp:73
token_type
token types for the parser
Definition: lexer.hpp:31
static parse_error create(int id_, const position_t &pos, const std::string &what_arg)
create a parse error exception
Definition: exceptions.hpp:130
zip_uint64_t uint64_t
zip_uint64_t_t typedef.
Definition: zip.hpp:108
zip_int64_t int64_t
zip_int64_t typedef.
Definition: zip.hpp:103
zip_uint32_t uint32_t
zip_uint32_t typedef.
Definition: zip.hpp:98
zip_int32_t int32_t
zip_int32_t typedef.
Definition: zip.hpp:93
zip_uint8_t uint8_t
zip_uint8_t typedef.
Definition: zip.hpp:78
zip_uint16_t uint16_t
zip_uint16_t typedef.
Definition: zip.hpp:88
zip_int16_t int16_t
zip_int16_t typedef.
Definition: zip.hpp:83
zip_int8_t int8_t
zip_int8_t typedef.
Definition: zip.hpp:73
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
cbor_tag_handler_t
how to treat CBOR tags
Definition: binary_reader.hpp:30
@ error
throw a parse_error exception in case of a tag
@ strict
throw a type_error exception in case of invalid UTF-8
input_format_t
the supported input formats
Definition: input_adapters.hpp:23
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
Definition: is_sax.hpp:97