16 #include <nlohmann/detail/exceptions.hpp>
17 #include <nlohmann/detail/input/input_adapters.hpp>
18 #include <nlohmann/detail/input/json_sax.hpp>
19 #include <nlohmann/detail/input/lexer.hpp>
20 #include <nlohmann/detail/macro_scope.hpp>
21 #include <nlohmann/detail/meta/is_sax.hpp>
22 #include <nlohmann/detail/meta/type_traits.hpp>
23 #include <nlohmann/detail/value_t.hpp>
45 static inline bool little_endianess(
int num = 1) noexcept
47 return *
reinterpret_cast<char*
>(&num) == 1;
58 template<
typename BasicJsonType,
typename InputAdapterType,
typename SAX = json_sax_dom_parser<BasicJsonType>>
61 using number_integer_t =
typename BasicJsonType::number_integer_t;
62 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
63 using number_float_t =
typename BasicJsonType::number_float_t;
64 using string_t =
typename BasicJsonType::string_t;
65 using binary_t =
typename BasicJsonType::binary_t;
66 using json_sax_t = SAX;
67 using char_type =
typename InputAdapterType::char_type;
68 using char_int_type =
typename std::char_traits<char_type>::int_type;
76 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
96 JSON_HEDLEY_NON_NULL(3)
99 const
bool strict = true,
107 case input_format_t::bson:
108 result = parse_bson_internal();
111 case input_format_t::cbor:
112 result = parse_cbor_internal(
true, tag_handler);
115 case input_format_t::msgpack:
116 result = parse_msgpack_internal();
119 case input_format_t::ubjson:
120 result = parse_ubjson_internal();
123 case input_format_t::json:
131 if (format == input_format_t::ubjson)
140 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
142 return sax->parse_error(chars_read, get_token_string(),
143 parse_error::create(110, chars_read, exception_message(format,
"expected end of input; last byte: 0x" + get_token_string(),
"value"), BasicJsonType()));
159 bool parse_bson_internal()
162 get_number<std::int32_t, true>(input_format_t::bson, document_size);
164 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
169 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(
false)))
174 return sax->end_object();
184 bool get_bson_cstr(string_t& result)
186 auto out = std::back_inserter(result);
190 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson,
"cstring")))
198 *out++ =
static_cast<typename string_t::value_type
>(current);
213 template<
typename NumberType>
214 bool get_bson_string(
const NumberType len, string_t& result)
216 if (JSON_HEDLEY_UNLIKELY(len < 1))
218 auto last_token = get_token_string();
219 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"), BasicJsonType()));
222 return get_string(input_format_t::bson, len -
static_cast<NumberType
>(1), result) && get() != std::char_traits<char_type>::eof();
234 template<
typename NumberType>
235 bool get_bson_binary(
const NumberType len, binary_t& result)
237 if (JSON_HEDLEY_UNLIKELY(len < 0))
239 auto last_token = get_token_string();
240 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"), BasicJsonType()));
245 get_number<std::uint8_t>(input_format_t::bson, subtype);
246 result.set_subtype(subtype);
248 return get_binary(input_format_t::bson, len, result);
261 bool parse_bson_element_internal(
const char_int_type element_type,
262 const std::size_t element_type_parse_position)
264 switch (element_type)
269 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
276 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
281 return parse_bson_internal();
286 return parse_bson_array();
293 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
298 return sax->boolean(get() != 0);
309 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
315 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
320 std::array<char, 3> cr{{}};
321 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(element_type));
322 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()), BasicJsonType()));
339 bool parse_bson_element_list(
const bool is_array)
343 while (
auto element_type = get())
345 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson,
"element list")))
350 const std::size_t element_type_parse_position = chars_read;
351 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
356 if (!is_array && !sax->key(key))
361 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
377 bool parse_bson_array()
380 get_number<std::int32_t, true>(input_format_t::bson, document_size);
382 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
387 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(
true)))
392 return sax->end_array();
407 bool parse_cbor_internal(
const bool get_char,
410 switch (get_char ? get() : current)
413 case std::char_traits<char_type>::eof():
441 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
446 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
452 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
458 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
464 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
492 return sax->number_integer(
static_cast<std::int8_t>(0x20 - 1 - current));
497 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
503 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
509 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1) - number);
515 return get_number(input_format_t::cbor, number) && sax->number_integer(
static_cast<number_integer_t
>(-1)
516 -
static_cast<number_integer_t
>(number));
551 return get_cbor_binary(b) && sax->binary(b);
586 return get_cbor_string(s) && sax->string(s);
614 return get_cbor_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
619 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
625 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
631 return get_number(input_format_t::cbor, len) && get_cbor_array(
static_cast<std::size_t
>(len), tag_handler);
637 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
641 return get_cbor_array(std::size_t(-1), tag_handler);
668 return get_cbor_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
673 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
679 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
685 return get_number(input_format_t::cbor, len) && get_cbor_object(
static_cast<std::size_t
>(len), tag_handler);
691 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
695 return get_cbor_object(std::size_t(-1), tag_handler);
721 auto last_token = get_token_string();
722 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"), BasicJsonType()));
733 get_number(input_format_t::cbor, subtype_to_ignore);
739 get_number(input_format_t::cbor, subtype_to_ignore);
745 get_number(input_format_t::cbor, subtype_to_ignore);
751 get_number(input_format_t::cbor, subtype_to_ignore);
757 return parse_cbor_internal(
true, tag_handler);
769 get_number(input_format_t::cbor, subtype);
770 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
776 get_number(input_format_t::cbor, subtype);
777 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
783 get_number(input_format_t::cbor, subtype);
784 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
790 get_number(input_format_t::cbor, subtype);
791 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
795 return parse_cbor_internal(
true, tag_handler);
798 return get_cbor_binary(b) && sax->binary(b);
808 return sax->boolean(
false);
811 return sax->boolean(
true);
818 const auto byte1_raw = get();
819 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"number")))
823 const auto byte2_raw = get();
824 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"number")))
829 const auto byte1 =
static_cast<unsigned char>(byte1_raw);
830 const auto byte2 =
static_cast<unsigned char>(byte2_raw);
840 const auto half =
static_cast<unsigned int>((byte1 << 8u) + byte2);
841 const double val = [&half]
843 const int exp = (half >> 10u) & 0x1Fu;
844 const unsigned int mant = half & 0x3FFu;
845 JSON_ASSERT(0 <= exp&& exp <= 32);
846 JSON_ASSERT(mant <= 1024);
850 return std::ldexp(mant, -24);
853 ? std::numeric_limits<double>::infinity()
854 : std::numeric_limits<double>::quiet_NaN();
856 return std::ldexp(mant + 1024, exp - 25);
859 return sax->number_float((half & 0x8000u) != 0
860 ?
static_cast<number_float_t
>(-val)
861 :
static_cast<number_float_t
>(val),
"");
867 return get_number(input_format_t::cbor, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
873 return get_number(input_format_t::cbor, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
878 auto last_token = get_token_string();
879 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"), BasicJsonType()));
895 bool get_cbor_string(string_t& result)
897 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"string")))
930 return get_string(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
936 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
942 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
948 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
954 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
959 while (get() != 0xFF)
962 if (!get_cbor_string(chunk))
966 result.append(chunk);
973 auto last_token = get_token_string();
974 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"), BasicJsonType()));
990 bool get_cbor_binary(binary_t& result)
992 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor,
"binary")))
1025 return get_binary(input_format_t::cbor,
static_cast<unsigned int>(current) & 0x1Fu, result);
1031 return get_number(input_format_t::cbor, len) &&
1032 get_binary(input_format_t::cbor, len, result);
1038 return get_number(input_format_t::cbor, len) &&
1039 get_binary(input_format_t::cbor, len, result);
1045 return get_number(input_format_t::cbor, len) &&
1046 get_binary(input_format_t::cbor, len, result);
1052 return get_number(input_format_t::cbor, len) &&
1053 get_binary(input_format_t::cbor, len, result);
1058 while (get() != 0xFF)
1061 if (!get_cbor_binary(chunk))
1065 result.insert(result.end(), chunk.begin(), chunk.end());
1072 auto last_token = get_token_string();
1073 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"), BasicJsonType()));
1084 bool get_cbor_array(
const std::size_t len,
1087 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
1092 if (len != std::size_t(-1))
1094 for (std::size_t i = 0; i < len; ++i)
1096 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1104 while (get() != 0xFF)
1106 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
false, tag_handler)))
1113 return sax->end_array();
1122 bool get_cbor_object(
const std::size_t len,
1125 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
1133 if (len != std::size_t(-1))
1135 for (std::size_t i = 0; i < len; ++i)
1138 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
1143 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1152 while (get() != 0xFF)
1154 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
1159 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(
true, tag_handler)))
1168 return sax->end_object();
1178 bool parse_msgpack_internal()
1183 case std::char_traits<char_type>::eof():
1315 return sax->number_unsigned(
static_cast<number_unsigned_t
>(current));
1334 return get_msgpack_object(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
1353 return get_msgpack_array(
static_cast<std::size_t
>(
static_cast<unsigned int>(current) & 0x0Fu));
1393 return get_msgpack_string(s) && sax->string(s);
1400 return sax->boolean(
false);
1403 return sax->boolean(
true);
1418 return get_msgpack_binary(b) && sax->binary(b);
1424 return get_number(input_format_t::msgpack, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
1430 return get_number(input_format_t::msgpack, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
1436 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1442 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1448 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1454 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
1460 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1466 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1472 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1478 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
1484 return get_number(input_format_t::msgpack, len) && get_msgpack_array(
static_cast<std::size_t
>(len));
1490 return get_number(input_format_t::msgpack, len) && get_msgpack_array(
static_cast<std::size_t
>(len));
1496 return get_number(input_format_t::msgpack, len) && get_msgpack_object(
static_cast<std::size_t
>(len));
1502 return get_number(input_format_t::msgpack, len) && get_msgpack_object(
static_cast<std::size_t
>(len));
1538 return sax->number_integer(
static_cast<std::int8_t>(current));
1542 auto last_token = get_token_string();
1543 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"), BasicJsonType()));
1558 bool get_msgpack_string(string_t& result)
1560 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack,
"string")))
1601 return get_string(input_format_t::msgpack,
static_cast<unsigned int>(current) & 0x1Fu, result);
1607 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1613 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1619 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
1624 auto last_token = get_token_string();
1625 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"), BasicJsonType()));
1640 bool get_msgpack_binary(binary_t& result)
1643 auto assign_and_return_true = [&result](
std::int8_t subtype)
1645 result.set_subtype(
static_cast<std::uint8_t>(subtype));
1654 return get_number(input_format_t::msgpack, len) &&
1655 get_binary(input_format_t::msgpack, len, result);
1661 return get_number(input_format_t::msgpack, len) &&
1662 get_binary(input_format_t::msgpack, len, result);
1668 return get_number(input_format_t::msgpack, len) &&
1669 get_binary(input_format_t::msgpack, len, result);
1676 return get_number(input_format_t::msgpack, len) &&
1677 get_number(input_format_t::msgpack, subtype) &&
1678 get_binary(input_format_t::msgpack, len, result) &&
1679 assign_and_return_true(subtype);
1686 return get_number(input_format_t::msgpack, len) &&
1687 get_number(input_format_t::msgpack, subtype) &&
1688 get_binary(input_format_t::msgpack, len, result) &&
1689 assign_and_return_true(subtype);
1696 return get_number(input_format_t::msgpack, len) &&
1697 get_number(input_format_t::msgpack, subtype) &&
1698 get_binary(input_format_t::msgpack, len, result) &&
1699 assign_and_return_true(subtype);
1705 return get_number(input_format_t::msgpack, subtype) &&
1706 get_binary(input_format_t::msgpack, 1, result) &&
1707 assign_and_return_true(subtype);
1713 return get_number(input_format_t::msgpack, subtype) &&
1714 get_binary(input_format_t::msgpack, 2, result) &&
1715 assign_and_return_true(subtype);
1721 return get_number(input_format_t::msgpack, subtype) &&
1722 get_binary(input_format_t::msgpack, 4, result) &&
1723 assign_and_return_true(subtype);
1729 return get_number(input_format_t::msgpack, subtype) &&
1730 get_binary(input_format_t::msgpack, 8, result) &&
1731 assign_and_return_true(subtype);
1737 return get_number(input_format_t::msgpack, subtype) &&
1738 get_binary(input_format_t::msgpack, 16, result) &&
1739 assign_and_return_true(subtype);
1751 bool get_msgpack_array(
const std::size_t len)
1753 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
1758 for (std::size_t i = 0; i < len; ++i)
1760 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
1766 return sax->end_array();
1773 bool get_msgpack_object(
const std::size_t len)
1775 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
1781 for (std::size_t i = 0; i < len; ++i)
1784 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
1789 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
1796 return sax->end_object();
1810 bool parse_ubjson_internal(
const bool get_char =
true)
1812 return get_ubjson_value(get_char ? get_ignore_noop() : current);
1829 bool get_ubjson_string(string_t& result,
const bool get_char =
true)
1836 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"value")))
1846 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1852 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1858 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1864 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1870 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
1874 auto last_token = get_token_string();
1875 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"), BasicJsonType()));
1883 bool get_ubjson_size_value(std::size_t& result)
1885 switch (get_ignore_noop())
1890 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1894 result =
static_cast<std::size_t
>(number);
1901 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1905 result =
static_cast<std::size_t
>(number);
1912 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1916 result =
static_cast<std::size_t
>(number);
1923 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1927 result =
static_cast<std::size_t
>(number);
1934 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
1938 result =
static_cast<std::size_t
>(number);
1944 auto last_token = get_token_string();
1945 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"), BasicJsonType()));
1960 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
1962 result.first = string_t::npos;
1969 result.second = get();
1970 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"type")))
1976 if (JSON_HEDLEY_UNLIKELY(current !=
'#'))
1978 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"value")))
1982 auto last_token = get_token_string();
1983 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"), BasicJsonType()));
1986 return get_ubjson_size_value(result.first);
1991 return get_ubjson_size_value(result.first);
2001 bool get_ubjson_value(
const char_int_type prefix)
2005 case std::char_traits<char_type>::eof():
2009 return sax->boolean(
true);
2011 return sax->boolean(
false);
2019 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
2025 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
2031 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
2037 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
2043 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
2049 return get_number(input_format_t::ubjson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
2055 return get_number(input_format_t::ubjson, number) && sax->number_float(
static_cast<number_float_t
>(number),
"");
2060 return get_ubjson_high_precision_number();
2066 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"char")))
2070 if (JSON_HEDLEY_UNLIKELY(current > 127))
2072 auto last_token = get_token_string();
2073 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"), BasicJsonType()));
2075 string_t s(1,
static_cast<typename string_t::value_type
>(current));
2076 return sax->string(s);
2082 return get_ubjson_string(s) && sax->string(s);
2086 return get_ubjson_array();
2089 return get_ubjson_object();
2093 auto last_token = get_token_string();
2094 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"), BasicJsonType()));
2102 bool get_ubjson_array()
2104 std::pair<std::size_t, char_int_type> size_and_type;
2105 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
2110 if (size_and_type.first != string_t::npos)
2112 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
2117 if (size_and_type.second != 0)
2119 if (size_and_type.second !=
'N')
2121 for (std::size_t i = 0; i < size_and_type.first; ++i)
2123 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2132 for (std::size_t i = 0; i < size_and_type.first; ++i)
2134 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2143 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
2148 while (current !=
']')
2150 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(
false)))
2158 return sax->end_array();
2164 bool get_ubjson_object()
2166 std::pair<std::size_t, char_int_type> size_and_type;
2167 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
2173 if (size_and_type.first != string_t::npos)
2175 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
2180 if (size_and_type.second != 0)
2182 for (std::size_t i = 0; i < size_and_type.first; ++i)
2184 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
2188 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
2197 for (std::size_t i = 0; i < size_and_type.first; ++i)
2199 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
2203 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2213 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
2218 while (current !=
'}')
2220 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key,
false) || !sax->key(key)))
2224 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
2233 return sax->end_object();
2239 bool get_ubjson_high_precision_number()
2243 auto res = get_ubjson_size_value(size);
2244 if (JSON_HEDLEY_UNLIKELY(!res))
2250 std::vector<char> number_vector;
2251 for (std::size_t i = 0; i < size; ++i)
2254 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson,
"number")))
2258 number_vector.push_back(
static_cast<char>(current));
2262 using ia_type = decltype(detail::input_adapter(number_vector));
2263 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector),
false);
2264 const auto result_number = number_lexer.scan();
2265 const auto number_string = number_lexer.get_token_string();
2266 const auto result_remainder = number_lexer.scan();
2270 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
2272 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"), BasicJsonType()));
2275 switch (result_number)
2277 case token_type::value_integer:
2278 return sax->number_integer(number_lexer.get_number_integer());
2279 case token_type::value_unsigned:
2280 return sax->number_unsigned(number_lexer.get_number_unsigned());
2281 case token_type::value_float:
2282 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
2283 case token_type::uninitialized:
2284 case token_type::literal_true:
2285 case token_type::literal_false:
2286 case token_type::literal_null:
2287 case token_type::value_string:
2288 case token_type::begin_array:
2289 case token_type::begin_object:
2290 case token_type::end_array:
2291 case token_type::end_object:
2292 case token_type::name_separator:
2293 case token_type::value_separator:
2294 case token_type::parse_error:
2295 case token_type::end_of_input:
2296 case token_type::literal_or_value:
2298 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"), BasicJsonType()));
2318 return current = ia.get_character();
2324 char_int_type get_ignore_noop()
2330 while (current ==
'N');
2348 template<
typename NumberType,
bool InputIsLittleEndian = false>
2353 for (std::size_t i = 0; i <
sizeof(NumberType); ++i)
2356 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"number")))
2362 if (is_little_endian != InputIsLittleEndian)
2364 vec[
sizeof(NumberType) - i - 1] =
static_cast<std::uint8_t>(current);
2373 std::memcpy(&result, vec.data(),
sizeof(NumberType));
2391 template<
typename NumberType>
2393 const NumberType len,
2396 bool success =
true;
2397 for (NumberType i = 0; i < len; i++)
2400 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"string")))
2405 result.push_back(
static_cast<typename string_t::value_type
>(current));
2424 template<
typename NumberType>
2426 const NumberType len,
2429 bool success =
true;
2430 for (NumberType i = 0; i < len; i++)
2433 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format,
"binary")))
2448 JSON_HEDLEY_NON_NULL(3)
2449 bool unexpect_eof(const
input_format_t format, const
char* context)
const
2451 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
2453 return sax->parse_error(chars_read,
"<end of file>",
2454 parse_error::create(110, chars_read, exception_message(format,
"unexpected end of input", context), BasicJsonType()));
2462 std::string get_token_string()
const
2464 std::array<char, 3> cr{{}};
2465 (std::snprintf)(cr.data(), cr.size(),
"%.2hhX",
static_cast<unsigned char>(current));
2466 return std::string{cr.data()};
2476 const std::string& detail,
2477 const std::string& context)
const
2479 std::string error_msg =
"syntax error while parsing ";
2483 case input_format_t::cbor:
2484 error_msg +=
"CBOR";
2487 case input_format_t::msgpack:
2488 error_msg +=
"MessagePack";
2491 case input_format_t::ubjson:
2492 error_msg +=
"UBJSON";
2495 case input_format_t::bson:
2496 error_msg +=
"BSON";
2499 case input_format_t::json:
2504 return error_msg +
" " + context +
": " + detail;
2509 InputAdapterType ia;
2512 char_int_type current = std::char_traits<char_type>::eof();
2515 std::size_t chars_read = 0;
2518 const bool is_little_endian = little_endianess();
2521 json_sax_t* sax =
nullptr;
deserialization of CBOR, MessagePack, and UBJSON values
Definition: binary_reader.hpp:60
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition: binary_reader.hpp:76
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:97
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, const BasicJsonType &context)
create a parse error exception
Definition: exceptions.hpp:197
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
cbor_tag_handler_t
how to treat CBOR tags
Definition: binary_reader.hpp:32
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ strict
throw a type_error exception in case of invalid UTF-8
input_format_t
the supported input formats
Definition: input_adapters.hpp:26
namespace for Niels Lohmann
Definition: adl_serializer.hpp:12
Definition: is_sax.hpp:97