1c5f01b2fSopenharmony_ci// __ _____ _____ _____ 2c5f01b2fSopenharmony_ci// __| | __| | | | JSON for Modern C++ 3c5f01b2fSopenharmony_ci// | | |__ | | | | | | version 3.11.2 4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5c5f01b2fSopenharmony_ci// 6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT 8c5f01b2fSopenharmony_ci 9c5f01b2fSopenharmony_ci#pragma once 10c5f01b2fSopenharmony_ci 11c5f01b2fSopenharmony_ci#include <algorithm> // generate_n 12c5f01b2fSopenharmony_ci#include <array> // array 13c5f01b2fSopenharmony_ci#include <cmath> // ldexp 14c5f01b2fSopenharmony_ci#include <cstddef> // size_t 15c5f01b2fSopenharmony_ci#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t 16c5f01b2fSopenharmony_ci#include <cstdio> // snprintf 17c5f01b2fSopenharmony_ci#include <cstring> // memcpy 18c5f01b2fSopenharmony_ci#include <iterator> // back_inserter 19c5f01b2fSopenharmony_ci#include <limits> // numeric_limits 20c5f01b2fSopenharmony_ci#include <string> // char_traits, string 21c5f01b2fSopenharmony_ci#include <utility> // make_pair, move 22c5f01b2fSopenharmony_ci#include <vector> // vector 23c5f01b2fSopenharmony_ci 24c5f01b2fSopenharmony_ci#include <nlohmann/detail/exceptions.hpp> 25c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/input_adapters.hpp> 26c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/json_sax.hpp> 27c5f01b2fSopenharmony_ci#include <nlohmann/detail/input/lexer.hpp> 28c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp> 29c5f01b2fSopenharmony_ci#include <nlohmann/detail/meta/is_sax.hpp> 30c5f01b2fSopenharmony_ci#include <nlohmann/detail/meta/type_traits.hpp> 31c5f01b2fSopenharmony_ci#include <nlohmann/detail/string_concat.hpp> 32c5f01b2fSopenharmony_ci#include <nlohmann/detail/value_t.hpp> 33c5f01b2fSopenharmony_ci 34c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN 35c5f01b2fSopenharmony_cinamespace detail 36c5f01b2fSopenharmony_ci{ 37c5f01b2fSopenharmony_ci 38c5f01b2fSopenharmony_ci/// how to treat CBOR tags 39c5f01b2fSopenharmony_cienum class cbor_tag_handler_t 40c5f01b2fSopenharmony_ci{ 41c5f01b2fSopenharmony_ci error, ///< throw a parse_error exception in case of a tag 42c5f01b2fSopenharmony_ci ignore, ///< ignore tags 43c5f01b2fSopenharmony_ci store ///< store tags as binary type 44c5f01b2fSopenharmony_ci}; 45c5f01b2fSopenharmony_ci 46c5f01b2fSopenharmony_ci/*! 47c5f01b2fSopenharmony_ci@brief determine system byte order 48c5f01b2fSopenharmony_ci 49c5f01b2fSopenharmony_ci@return true if and only if system's byte order is little endian 50c5f01b2fSopenharmony_ci 51c5f01b2fSopenharmony_ci@note from https://stackoverflow.com/a/1001328/266378 52c5f01b2fSopenharmony_ci*/ 53c5f01b2fSopenharmony_cistatic inline bool little_endianness(int num = 1) noexcept 54c5f01b2fSopenharmony_ci{ 55c5f01b2fSopenharmony_ci return *reinterpret_cast<char*>(&num) == 1; 56c5f01b2fSopenharmony_ci} 57c5f01b2fSopenharmony_ci 58c5f01b2fSopenharmony_ci 59c5f01b2fSopenharmony_ci/////////////////// 60c5f01b2fSopenharmony_ci// binary reader // 61c5f01b2fSopenharmony_ci/////////////////// 62c5f01b2fSopenharmony_ci 63c5f01b2fSopenharmony_ci/*! 64c5f01b2fSopenharmony_ci@brief deserialization of CBOR, MessagePack, and UBJSON values 65c5f01b2fSopenharmony_ci*/ 66c5f01b2fSopenharmony_citemplate<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>> 67c5f01b2fSopenharmony_ciclass binary_reader 68c5f01b2fSopenharmony_ci{ 69c5f01b2fSopenharmony_ci using number_integer_t = typename BasicJsonType::number_integer_t; 70c5f01b2fSopenharmony_ci using number_unsigned_t = typename BasicJsonType::number_unsigned_t; 71c5f01b2fSopenharmony_ci using number_float_t = typename BasicJsonType::number_float_t; 72c5f01b2fSopenharmony_ci using string_t = typename BasicJsonType::string_t; 73c5f01b2fSopenharmony_ci using binary_t = typename BasicJsonType::binary_t; 74c5f01b2fSopenharmony_ci using json_sax_t = SAX; 75c5f01b2fSopenharmony_ci using char_type = typename InputAdapterType::char_type; 76c5f01b2fSopenharmony_ci using char_int_type = typename std::char_traits<char_type>::int_type; 77c5f01b2fSopenharmony_ci 78c5f01b2fSopenharmony_ci public: 79c5f01b2fSopenharmony_ci /*! 80c5f01b2fSopenharmony_ci @brief create a binary reader 81c5f01b2fSopenharmony_ci 82c5f01b2fSopenharmony_ci @param[in] adapter input adapter to read from 83c5f01b2fSopenharmony_ci */ 84c5f01b2fSopenharmony_ci explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format) 85c5f01b2fSopenharmony_ci { 86c5f01b2fSopenharmony_ci (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {}; 87c5f01b2fSopenharmony_ci } 88c5f01b2fSopenharmony_ci 89c5f01b2fSopenharmony_ci // make class move-only 90c5f01b2fSopenharmony_ci binary_reader(const binary_reader&) = delete; 91c5f01b2fSopenharmony_ci binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) 92c5f01b2fSopenharmony_ci binary_reader& operator=(const binary_reader&) = delete; 93c5f01b2fSopenharmony_ci binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) 94c5f01b2fSopenharmony_ci ~binary_reader() = default; 95c5f01b2fSopenharmony_ci 96c5f01b2fSopenharmony_ci /*! 97c5f01b2fSopenharmony_ci @param[in] format the binary format to parse 98c5f01b2fSopenharmony_ci @param[in] sax_ a SAX event processor 99c5f01b2fSopenharmony_ci @param[in] strict whether to expect the input to be consumed completed 100c5f01b2fSopenharmony_ci @param[in] tag_handler how to treat CBOR tags 101c5f01b2fSopenharmony_ci 102c5f01b2fSopenharmony_ci @return whether parsing was successful 103c5f01b2fSopenharmony_ci */ 104c5f01b2fSopenharmony_ci JSON_HEDLEY_NON_NULL(3) 105c5f01b2fSopenharmony_ci bool sax_parse(const input_format_t format, 106c5f01b2fSopenharmony_ci json_sax_t* sax_, 107c5f01b2fSopenharmony_ci const bool strict = true, 108c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) 109c5f01b2fSopenharmony_ci { 110c5f01b2fSopenharmony_ci sax = sax_; 111c5f01b2fSopenharmony_ci bool result = false; 112c5f01b2fSopenharmony_ci 113c5f01b2fSopenharmony_ci switch (format) 114c5f01b2fSopenharmony_ci { 115c5f01b2fSopenharmony_ci case input_format_t::bson: 116c5f01b2fSopenharmony_ci result = parse_bson_internal(); 117c5f01b2fSopenharmony_ci break; 118c5f01b2fSopenharmony_ci 119c5f01b2fSopenharmony_ci case input_format_t::cbor: 120c5f01b2fSopenharmony_ci result = parse_cbor_internal(true, tag_handler); 121c5f01b2fSopenharmony_ci break; 122c5f01b2fSopenharmony_ci 123c5f01b2fSopenharmony_ci case input_format_t::msgpack: 124c5f01b2fSopenharmony_ci result = parse_msgpack_internal(); 125c5f01b2fSopenharmony_ci break; 126c5f01b2fSopenharmony_ci 127c5f01b2fSopenharmony_ci case input_format_t::ubjson: 128c5f01b2fSopenharmony_ci case input_format_t::bjdata: 129c5f01b2fSopenharmony_ci result = parse_ubjson_internal(); 130c5f01b2fSopenharmony_ci break; 131c5f01b2fSopenharmony_ci 132c5f01b2fSopenharmony_ci case input_format_t::json: // LCOV_EXCL_LINE 133c5f01b2fSopenharmony_ci default: // LCOV_EXCL_LINE 134c5f01b2fSopenharmony_ci JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE 135c5f01b2fSopenharmony_ci } 136c5f01b2fSopenharmony_ci 137c5f01b2fSopenharmony_ci // strict mode: next byte must be EOF 138c5f01b2fSopenharmony_ci if (result && strict) 139c5f01b2fSopenharmony_ci { 140c5f01b2fSopenharmony_ci if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata) 141c5f01b2fSopenharmony_ci { 142c5f01b2fSopenharmony_ci get_ignore_noop(); 143c5f01b2fSopenharmony_ci } 144c5f01b2fSopenharmony_ci else 145c5f01b2fSopenharmony_ci { 146c5f01b2fSopenharmony_ci get(); 147c5f01b2fSopenharmony_ci } 148c5f01b2fSopenharmony_ci 149c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof())) 150c5f01b2fSopenharmony_ci { 151c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, 152c5f01b2fSopenharmony_ci exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr)); 153c5f01b2fSopenharmony_ci } 154c5f01b2fSopenharmony_ci } 155c5f01b2fSopenharmony_ci 156c5f01b2fSopenharmony_ci return result; 157c5f01b2fSopenharmony_ci } 158c5f01b2fSopenharmony_ci 159c5f01b2fSopenharmony_ci private: 160c5f01b2fSopenharmony_ci ////////// 161c5f01b2fSopenharmony_ci // BSON // 162c5f01b2fSopenharmony_ci ////////// 163c5f01b2fSopenharmony_ci 164c5f01b2fSopenharmony_ci /*! 165c5f01b2fSopenharmony_ci @brief Reads in a BSON-object and passes it to the SAX-parser. 166c5f01b2fSopenharmony_ci @return whether a valid BSON-value was passed to the SAX parser 167c5f01b2fSopenharmony_ci */ 168c5f01b2fSopenharmony_ci bool parse_bson_internal() 169c5f01b2fSopenharmony_ci { 170c5f01b2fSopenharmony_ci std::int32_t document_size{}; 171c5f01b2fSopenharmony_ci get_number<std::int32_t, true>(input_format_t::bson, document_size); 172c5f01b2fSopenharmony_ci 173c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1)))) 174c5f01b2fSopenharmony_ci { 175c5f01b2fSopenharmony_ci return false; 176c5f01b2fSopenharmony_ci } 177c5f01b2fSopenharmony_ci 178c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) 179c5f01b2fSopenharmony_ci { 180c5f01b2fSopenharmony_ci return false; 181c5f01b2fSopenharmony_ci } 182c5f01b2fSopenharmony_ci 183c5f01b2fSopenharmony_ci return sax->end_object(); 184c5f01b2fSopenharmony_ci } 185c5f01b2fSopenharmony_ci 186c5f01b2fSopenharmony_ci /*! 187c5f01b2fSopenharmony_ci @brief Parses a C-style string from the BSON input. 188c5f01b2fSopenharmony_ci @param[in,out] result A reference to the string variable where the read 189c5f01b2fSopenharmony_ci string is to be stored. 190c5f01b2fSopenharmony_ci @return `true` if the \x00-byte indicating the end of the string was 191c5f01b2fSopenharmony_ci encountered before the EOF; false` indicates an unexpected EOF. 192c5f01b2fSopenharmony_ci */ 193c5f01b2fSopenharmony_ci bool get_bson_cstr(string_t& result) 194c5f01b2fSopenharmony_ci { 195c5f01b2fSopenharmony_ci auto out = std::back_inserter(result); 196c5f01b2fSopenharmony_ci while (true) 197c5f01b2fSopenharmony_ci { 198c5f01b2fSopenharmony_ci get(); 199c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) 200c5f01b2fSopenharmony_ci { 201c5f01b2fSopenharmony_ci return false; 202c5f01b2fSopenharmony_ci } 203c5f01b2fSopenharmony_ci if (current == 0x00) 204c5f01b2fSopenharmony_ci { 205c5f01b2fSopenharmony_ci return true; 206c5f01b2fSopenharmony_ci } 207c5f01b2fSopenharmony_ci *out++ = static_cast<typename string_t::value_type>(current); 208c5f01b2fSopenharmony_ci } 209c5f01b2fSopenharmony_ci } 210c5f01b2fSopenharmony_ci 211c5f01b2fSopenharmony_ci /*! 212c5f01b2fSopenharmony_ci @brief Parses a zero-terminated string of length @a len from the BSON 213c5f01b2fSopenharmony_ci input. 214c5f01b2fSopenharmony_ci @param[in] len The length (including the zero-byte at the end) of the 215c5f01b2fSopenharmony_ci string to be read. 216c5f01b2fSopenharmony_ci @param[in,out] result A reference to the string variable where the read 217c5f01b2fSopenharmony_ci string is to be stored. 218c5f01b2fSopenharmony_ci @tparam NumberType The type of the length @a len 219c5f01b2fSopenharmony_ci @pre len >= 1 220c5f01b2fSopenharmony_ci @return `true` if the string was successfully parsed 221c5f01b2fSopenharmony_ci */ 222c5f01b2fSopenharmony_ci template<typename NumberType> 223c5f01b2fSopenharmony_ci bool get_bson_string(const NumberType len, string_t& result) 224c5f01b2fSopenharmony_ci { 225c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(len < 1)) 226c5f01b2fSopenharmony_ci { 227c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 228c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 229c5f01b2fSopenharmony_ci exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr)); 230c5f01b2fSopenharmony_ci } 231c5f01b2fSopenharmony_ci 232c5f01b2fSopenharmony_ci return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof(); 233c5f01b2fSopenharmony_ci } 234c5f01b2fSopenharmony_ci 235c5f01b2fSopenharmony_ci /*! 236c5f01b2fSopenharmony_ci @brief Parses a byte array input of length @a len from the BSON input. 237c5f01b2fSopenharmony_ci @param[in] len The length of the byte array to be read. 238c5f01b2fSopenharmony_ci @param[in,out] result A reference to the binary variable where the read 239c5f01b2fSopenharmony_ci array is to be stored. 240c5f01b2fSopenharmony_ci @tparam NumberType The type of the length @a len 241c5f01b2fSopenharmony_ci @pre len >= 0 242c5f01b2fSopenharmony_ci @return `true` if the byte array was successfully parsed 243c5f01b2fSopenharmony_ci */ 244c5f01b2fSopenharmony_ci template<typename NumberType> 245c5f01b2fSopenharmony_ci bool get_bson_binary(const NumberType len, binary_t& result) 246c5f01b2fSopenharmony_ci { 247c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(len < 0)) 248c5f01b2fSopenharmony_ci { 249c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 250c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 251c5f01b2fSopenharmony_ci exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr)); 252c5f01b2fSopenharmony_ci } 253c5f01b2fSopenharmony_ci 254c5f01b2fSopenharmony_ci // All BSON binary values have a subtype 255c5f01b2fSopenharmony_ci std::uint8_t subtype{}; 256c5f01b2fSopenharmony_ci get_number<std::uint8_t>(input_format_t::bson, subtype); 257c5f01b2fSopenharmony_ci result.set_subtype(subtype); 258c5f01b2fSopenharmony_ci 259c5f01b2fSopenharmony_ci return get_binary(input_format_t::bson, len, result); 260c5f01b2fSopenharmony_ci } 261c5f01b2fSopenharmony_ci 262c5f01b2fSopenharmony_ci /*! 263c5f01b2fSopenharmony_ci @brief Read a BSON document element of the given @a element_type. 264c5f01b2fSopenharmony_ci @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html 265c5f01b2fSopenharmony_ci @param[in] element_type_parse_position The position in the input stream, 266c5f01b2fSopenharmony_ci where the `element_type` was read. 267c5f01b2fSopenharmony_ci @warning Not all BSON element types are supported yet. An unsupported 268c5f01b2fSopenharmony_ci @a element_type will give rise to a parse_error.114: 269c5f01b2fSopenharmony_ci Unsupported BSON record type 0x... 270c5f01b2fSopenharmony_ci @return whether a valid BSON-object/array was passed to the SAX parser 271c5f01b2fSopenharmony_ci */ 272c5f01b2fSopenharmony_ci bool parse_bson_element_internal(const char_int_type element_type, 273c5f01b2fSopenharmony_ci const std::size_t element_type_parse_position) 274c5f01b2fSopenharmony_ci { 275c5f01b2fSopenharmony_ci switch (element_type) 276c5f01b2fSopenharmony_ci { 277c5f01b2fSopenharmony_ci case 0x01: // double 278c5f01b2fSopenharmony_ci { 279c5f01b2fSopenharmony_ci double number{}; 280c5f01b2fSopenharmony_ci return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), ""); 281c5f01b2fSopenharmony_ci } 282c5f01b2fSopenharmony_ci 283c5f01b2fSopenharmony_ci case 0x02: // string 284c5f01b2fSopenharmony_ci { 285c5f01b2fSopenharmony_ci std::int32_t len{}; 286c5f01b2fSopenharmony_ci string_t value; 287c5f01b2fSopenharmony_ci return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); 288c5f01b2fSopenharmony_ci } 289c5f01b2fSopenharmony_ci 290c5f01b2fSopenharmony_ci case 0x03: // object 291c5f01b2fSopenharmony_ci { 292c5f01b2fSopenharmony_ci return parse_bson_internal(); 293c5f01b2fSopenharmony_ci } 294c5f01b2fSopenharmony_ci 295c5f01b2fSopenharmony_ci case 0x04: // array 296c5f01b2fSopenharmony_ci { 297c5f01b2fSopenharmony_ci return parse_bson_array(); 298c5f01b2fSopenharmony_ci } 299c5f01b2fSopenharmony_ci 300c5f01b2fSopenharmony_ci case 0x05: // binary 301c5f01b2fSopenharmony_ci { 302c5f01b2fSopenharmony_ci std::int32_t len{}; 303c5f01b2fSopenharmony_ci binary_t value; 304c5f01b2fSopenharmony_ci return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); 305c5f01b2fSopenharmony_ci } 306c5f01b2fSopenharmony_ci 307c5f01b2fSopenharmony_ci case 0x08: // boolean 308c5f01b2fSopenharmony_ci { 309c5f01b2fSopenharmony_ci return sax->boolean(get() != 0); 310c5f01b2fSopenharmony_ci } 311c5f01b2fSopenharmony_ci 312c5f01b2fSopenharmony_ci case 0x0A: // null 313c5f01b2fSopenharmony_ci { 314c5f01b2fSopenharmony_ci return sax->null(); 315c5f01b2fSopenharmony_ci } 316c5f01b2fSopenharmony_ci 317c5f01b2fSopenharmony_ci case 0x10: // int32 318c5f01b2fSopenharmony_ci { 319c5f01b2fSopenharmony_ci std::int32_t value{}; 320c5f01b2fSopenharmony_ci return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value); 321c5f01b2fSopenharmony_ci } 322c5f01b2fSopenharmony_ci 323c5f01b2fSopenharmony_ci case 0x12: // int64 324c5f01b2fSopenharmony_ci { 325c5f01b2fSopenharmony_ci std::int64_t value{}; 326c5f01b2fSopenharmony_ci return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value); 327c5f01b2fSopenharmony_ci } 328c5f01b2fSopenharmony_ci 329c5f01b2fSopenharmony_ci default: // anything else not supported (yet) 330c5f01b2fSopenharmony_ci { 331c5f01b2fSopenharmony_ci std::array<char, 3> cr{{}}; 332c5f01b2fSopenharmony_ci static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) 333c5f01b2fSopenharmony_ci std::string cr_str{cr.data()}; 334c5f01b2fSopenharmony_ci return sax->parse_error(element_type_parse_position, cr_str, 335c5f01b2fSopenharmony_ci parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr)); 336c5f01b2fSopenharmony_ci } 337c5f01b2fSopenharmony_ci } 338c5f01b2fSopenharmony_ci } 339c5f01b2fSopenharmony_ci 340c5f01b2fSopenharmony_ci /*! 341c5f01b2fSopenharmony_ci @brief Read a BSON element list (as specified in the BSON-spec) 342c5f01b2fSopenharmony_ci 343c5f01b2fSopenharmony_ci The same binary layout is used for objects and arrays, hence it must be 344c5f01b2fSopenharmony_ci indicated with the argument @a is_array which one is expected 345c5f01b2fSopenharmony_ci (true --> array, false --> object). 346c5f01b2fSopenharmony_ci 347c5f01b2fSopenharmony_ci @param[in] is_array Determines if the element list being read is to be 348c5f01b2fSopenharmony_ci treated as an object (@a is_array == false), or as an 349c5f01b2fSopenharmony_ci array (@a is_array == true). 350c5f01b2fSopenharmony_ci @return whether a valid BSON-object/array was passed to the SAX parser 351c5f01b2fSopenharmony_ci */ 352c5f01b2fSopenharmony_ci bool parse_bson_element_list(const bool is_array) 353c5f01b2fSopenharmony_ci { 354c5f01b2fSopenharmony_ci string_t key; 355c5f01b2fSopenharmony_ci 356c5f01b2fSopenharmony_ci while (auto element_type = get()) 357c5f01b2fSopenharmony_ci { 358c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) 359c5f01b2fSopenharmony_ci { 360c5f01b2fSopenharmony_ci return false; 361c5f01b2fSopenharmony_ci } 362c5f01b2fSopenharmony_ci 363c5f01b2fSopenharmony_ci const std::size_t element_type_parse_position = chars_read; 364c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) 365c5f01b2fSopenharmony_ci { 366c5f01b2fSopenharmony_ci return false; 367c5f01b2fSopenharmony_ci } 368c5f01b2fSopenharmony_ci 369c5f01b2fSopenharmony_ci if (!is_array && !sax->key(key)) 370c5f01b2fSopenharmony_ci { 371c5f01b2fSopenharmony_ci return false; 372c5f01b2fSopenharmony_ci } 373c5f01b2fSopenharmony_ci 374c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) 375c5f01b2fSopenharmony_ci { 376c5f01b2fSopenharmony_ci return false; 377c5f01b2fSopenharmony_ci } 378c5f01b2fSopenharmony_ci 379c5f01b2fSopenharmony_ci // get_bson_cstr only appends 380c5f01b2fSopenharmony_ci key.clear(); 381c5f01b2fSopenharmony_ci } 382c5f01b2fSopenharmony_ci 383c5f01b2fSopenharmony_ci return true; 384c5f01b2fSopenharmony_ci } 385c5f01b2fSopenharmony_ci 386c5f01b2fSopenharmony_ci /*! 387c5f01b2fSopenharmony_ci @brief Reads an array from the BSON input and passes it to the SAX-parser. 388c5f01b2fSopenharmony_ci @return whether a valid BSON-array was passed to the SAX parser 389c5f01b2fSopenharmony_ci */ 390c5f01b2fSopenharmony_ci bool parse_bson_array() 391c5f01b2fSopenharmony_ci { 392c5f01b2fSopenharmony_ci std::int32_t document_size{}; 393c5f01b2fSopenharmony_ci get_number<std::int32_t, true>(input_format_t::bson, document_size); 394c5f01b2fSopenharmony_ci 395c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1)))) 396c5f01b2fSopenharmony_ci { 397c5f01b2fSopenharmony_ci return false; 398c5f01b2fSopenharmony_ci } 399c5f01b2fSopenharmony_ci 400c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) 401c5f01b2fSopenharmony_ci { 402c5f01b2fSopenharmony_ci return false; 403c5f01b2fSopenharmony_ci } 404c5f01b2fSopenharmony_ci 405c5f01b2fSopenharmony_ci return sax->end_array(); 406c5f01b2fSopenharmony_ci } 407c5f01b2fSopenharmony_ci 408c5f01b2fSopenharmony_ci ////////// 409c5f01b2fSopenharmony_ci // CBOR // 410c5f01b2fSopenharmony_ci ////////// 411c5f01b2fSopenharmony_ci 412c5f01b2fSopenharmony_ci /*! 413c5f01b2fSopenharmony_ci @param[in] get_char whether a new character should be retrieved from the 414c5f01b2fSopenharmony_ci input (true) or whether the last read character should 415c5f01b2fSopenharmony_ci be considered instead (false) 416c5f01b2fSopenharmony_ci @param[in] tag_handler how CBOR tags should be treated 417c5f01b2fSopenharmony_ci 418c5f01b2fSopenharmony_ci @return whether a valid CBOR value was passed to the SAX parser 419c5f01b2fSopenharmony_ci */ 420c5f01b2fSopenharmony_ci bool parse_cbor_internal(const bool get_char, 421c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler) 422c5f01b2fSopenharmony_ci { 423c5f01b2fSopenharmony_ci switch (get_char ? get() : current) 424c5f01b2fSopenharmony_ci { 425c5f01b2fSopenharmony_ci // EOF 426c5f01b2fSopenharmony_ci case std::char_traits<char_type>::eof(): 427c5f01b2fSopenharmony_ci return unexpect_eof(input_format_t::cbor, "value"); 428c5f01b2fSopenharmony_ci 429c5f01b2fSopenharmony_ci // Integer 0x00..0x17 (0..23) 430c5f01b2fSopenharmony_ci case 0x00: 431c5f01b2fSopenharmony_ci case 0x01: 432c5f01b2fSopenharmony_ci case 0x02: 433c5f01b2fSopenharmony_ci case 0x03: 434c5f01b2fSopenharmony_ci case 0x04: 435c5f01b2fSopenharmony_ci case 0x05: 436c5f01b2fSopenharmony_ci case 0x06: 437c5f01b2fSopenharmony_ci case 0x07: 438c5f01b2fSopenharmony_ci case 0x08: 439c5f01b2fSopenharmony_ci case 0x09: 440c5f01b2fSopenharmony_ci case 0x0A: 441c5f01b2fSopenharmony_ci case 0x0B: 442c5f01b2fSopenharmony_ci case 0x0C: 443c5f01b2fSopenharmony_ci case 0x0D: 444c5f01b2fSopenharmony_ci case 0x0E: 445c5f01b2fSopenharmony_ci case 0x0F: 446c5f01b2fSopenharmony_ci case 0x10: 447c5f01b2fSopenharmony_ci case 0x11: 448c5f01b2fSopenharmony_ci case 0x12: 449c5f01b2fSopenharmony_ci case 0x13: 450c5f01b2fSopenharmony_ci case 0x14: 451c5f01b2fSopenharmony_ci case 0x15: 452c5f01b2fSopenharmony_ci case 0x16: 453c5f01b2fSopenharmony_ci case 0x17: 454c5f01b2fSopenharmony_ci return sax->number_unsigned(static_cast<number_unsigned_t>(current)); 455c5f01b2fSopenharmony_ci 456c5f01b2fSopenharmony_ci case 0x18: // Unsigned integer (one-byte uint8_t follows) 457c5f01b2fSopenharmony_ci { 458c5f01b2fSopenharmony_ci std::uint8_t number{}; 459c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); 460c5f01b2fSopenharmony_ci } 461c5f01b2fSopenharmony_ci 462c5f01b2fSopenharmony_ci case 0x19: // Unsigned integer (two-byte uint16_t follows) 463c5f01b2fSopenharmony_ci { 464c5f01b2fSopenharmony_ci std::uint16_t number{}; 465c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); 466c5f01b2fSopenharmony_ci } 467c5f01b2fSopenharmony_ci 468c5f01b2fSopenharmony_ci case 0x1A: // Unsigned integer (four-byte uint32_t follows) 469c5f01b2fSopenharmony_ci { 470c5f01b2fSopenharmony_ci std::uint32_t number{}; 471c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); 472c5f01b2fSopenharmony_ci } 473c5f01b2fSopenharmony_ci 474c5f01b2fSopenharmony_ci case 0x1B: // Unsigned integer (eight-byte uint64_t follows) 475c5f01b2fSopenharmony_ci { 476c5f01b2fSopenharmony_ci std::uint64_t number{}; 477c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); 478c5f01b2fSopenharmony_ci } 479c5f01b2fSopenharmony_ci 480c5f01b2fSopenharmony_ci // Negative integer -1-0x00..-1-0x17 (-1..-24) 481c5f01b2fSopenharmony_ci case 0x20: 482c5f01b2fSopenharmony_ci case 0x21: 483c5f01b2fSopenharmony_ci case 0x22: 484c5f01b2fSopenharmony_ci case 0x23: 485c5f01b2fSopenharmony_ci case 0x24: 486c5f01b2fSopenharmony_ci case 0x25: 487c5f01b2fSopenharmony_ci case 0x26: 488c5f01b2fSopenharmony_ci case 0x27: 489c5f01b2fSopenharmony_ci case 0x28: 490c5f01b2fSopenharmony_ci case 0x29: 491c5f01b2fSopenharmony_ci case 0x2A: 492c5f01b2fSopenharmony_ci case 0x2B: 493c5f01b2fSopenharmony_ci case 0x2C: 494c5f01b2fSopenharmony_ci case 0x2D: 495c5f01b2fSopenharmony_ci case 0x2E: 496c5f01b2fSopenharmony_ci case 0x2F: 497c5f01b2fSopenharmony_ci case 0x30: 498c5f01b2fSopenharmony_ci case 0x31: 499c5f01b2fSopenharmony_ci case 0x32: 500c5f01b2fSopenharmony_ci case 0x33: 501c5f01b2fSopenharmony_ci case 0x34: 502c5f01b2fSopenharmony_ci case 0x35: 503c5f01b2fSopenharmony_ci case 0x36: 504c5f01b2fSopenharmony_ci case 0x37: 505c5f01b2fSopenharmony_ci return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current)); 506c5f01b2fSopenharmony_ci 507c5f01b2fSopenharmony_ci case 0x38: // Negative integer (one-byte uint8_t follows) 508c5f01b2fSopenharmony_ci { 509c5f01b2fSopenharmony_ci std::uint8_t number{}; 510c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number); 511c5f01b2fSopenharmony_ci } 512c5f01b2fSopenharmony_ci 513c5f01b2fSopenharmony_ci case 0x39: // Negative integer -1-n (two-byte uint16_t follows) 514c5f01b2fSopenharmony_ci { 515c5f01b2fSopenharmony_ci std::uint16_t number{}; 516c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number); 517c5f01b2fSopenharmony_ci } 518c5f01b2fSopenharmony_ci 519c5f01b2fSopenharmony_ci case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) 520c5f01b2fSopenharmony_ci { 521c5f01b2fSopenharmony_ci std::uint32_t number{}; 522c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number); 523c5f01b2fSopenharmony_ci } 524c5f01b2fSopenharmony_ci 525c5f01b2fSopenharmony_ci case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) 526c5f01b2fSopenharmony_ci { 527c5f01b2fSopenharmony_ci std::uint64_t number{}; 528c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) 529c5f01b2fSopenharmony_ci - static_cast<number_integer_t>(number)); 530c5f01b2fSopenharmony_ci } 531c5f01b2fSopenharmony_ci 532c5f01b2fSopenharmony_ci // Binary data (0x00..0x17 bytes follow) 533c5f01b2fSopenharmony_ci case 0x40: 534c5f01b2fSopenharmony_ci case 0x41: 535c5f01b2fSopenharmony_ci case 0x42: 536c5f01b2fSopenharmony_ci case 0x43: 537c5f01b2fSopenharmony_ci case 0x44: 538c5f01b2fSopenharmony_ci case 0x45: 539c5f01b2fSopenharmony_ci case 0x46: 540c5f01b2fSopenharmony_ci case 0x47: 541c5f01b2fSopenharmony_ci case 0x48: 542c5f01b2fSopenharmony_ci case 0x49: 543c5f01b2fSopenharmony_ci case 0x4A: 544c5f01b2fSopenharmony_ci case 0x4B: 545c5f01b2fSopenharmony_ci case 0x4C: 546c5f01b2fSopenharmony_ci case 0x4D: 547c5f01b2fSopenharmony_ci case 0x4E: 548c5f01b2fSopenharmony_ci case 0x4F: 549c5f01b2fSopenharmony_ci case 0x50: 550c5f01b2fSopenharmony_ci case 0x51: 551c5f01b2fSopenharmony_ci case 0x52: 552c5f01b2fSopenharmony_ci case 0x53: 553c5f01b2fSopenharmony_ci case 0x54: 554c5f01b2fSopenharmony_ci case 0x55: 555c5f01b2fSopenharmony_ci case 0x56: 556c5f01b2fSopenharmony_ci case 0x57: 557c5f01b2fSopenharmony_ci case 0x58: // Binary data (one-byte uint8_t for n follows) 558c5f01b2fSopenharmony_ci case 0x59: // Binary data (two-byte uint16_t for n follow) 559c5f01b2fSopenharmony_ci case 0x5A: // Binary data (four-byte uint32_t for n follow) 560c5f01b2fSopenharmony_ci case 0x5B: // Binary data (eight-byte uint64_t for n follow) 561c5f01b2fSopenharmony_ci case 0x5F: // Binary data (indefinite length) 562c5f01b2fSopenharmony_ci { 563c5f01b2fSopenharmony_ci binary_t b; 564c5f01b2fSopenharmony_ci return get_cbor_binary(b) && sax->binary(b); 565c5f01b2fSopenharmony_ci } 566c5f01b2fSopenharmony_ci 567c5f01b2fSopenharmony_ci // UTF-8 string (0x00..0x17 bytes follow) 568c5f01b2fSopenharmony_ci case 0x60: 569c5f01b2fSopenharmony_ci case 0x61: 570c5f01b2fSopenharmony_ci case 0x62: 571c5f01b2fSopenharmony_ci case 0x63: 572c5f01b2fSopenharmony_ci case 0x64: 573c5f01b2fSopenharmony_ci case 0x65: 574c5f01b2fSopenharmony_ci case 0x66: 575c5f01b2fSopenharmony_ci case 0x67: 576c5f01b2fSopenharmony_ci case 0x68: 577c5f01b2fSopenharmony_ci case 0x69: 578c5f01b2fSopenharmony_ci case 0x6A: 579c5f01b2fSopenharmony_ci case 0x6B: 580c5f01b2fSopenharmony_ci case 0x6C: 581c5f01b2fSopenharmony_ci case 0x6D: 582c5f01b2fSopenharmony_ci case 0x6E: 583c5f01b2fSopenharmony_ci case 0x6F: 584c5f01b2fSopenharmony_ci case 0x70: 585c5f01b2fSopenharmony_ci case 0x71: 586c5f01b2fSopenharmony_ci case 0x72: 587c5f01b2fSopenharmony_ci case 0x73: 588c5f01b2fSopenharmony_ci case 0x74: 589c5f01b2fSopenharmony_ci case 0x75: 590c5f01b2fSopenharmony_ci case 0x76: 591c5f01b2fSopenharmony_ci case 0x77: 592c5f01b2fSopenharmony_ci case 0x78: // UTF-8 string (one-byte uint8_t for n follows) 593c5f01b2fSopenharmony_ci case 0x79: // UTF-8 string (two-byte uint16_t for n follow) 594c5f01b2fSopenharmony_ci case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) 595c5f01b2fSopenharmony_ci case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) 596c5f01b2fSopenharmony_ci case 0x7F: // UTF-8 string (indefinite length) 597c5f01b2fSopenharmony_ci { 598c5f01b2fSopenharmony_ci string_t s; 599c5f01b2fSopenharmony_ci return get_cbor_string(s) && sax->string(s); 600c5f01b2fSopenharmony_ci } 601c5f01b2fSopenharmony_ci 602c5f01b2fSopenharmony_ci // array (0x00..0x17 data items follow) 603c5f01b2fSopenharmony_ci case 0x80: 604c5f01b2fSopenharmony_ci case 0x81: 605c5f01b2fSopenharmony_ci case 0x82: 606c5f01b2fSopenharmony_ci case 0x83: 607c5f01b2fSopenharmony_ci case 0x84: 608c5f01b2fSopenharmony_ci case 0x85: 609c5f01b2fSopenharmony_ci case 0x86: 610c5f01b2fSopenharmony_ci case 0x87: 611c5f01b2fSopenharmony_ci case 0x88: 612c5f01b2fSopenharmony_ci case 0x89: 613c5f01b2fSopenharmony_ci case 0x8A: 614c5f01b2fSopenharmony_ci case 0x8B: 615c5f01b2fSopenharmony_ci case 0x8C: 616c5f01b2fSopenharmony_ci case 0x8D: 617c5f01b2fSopenharmony_ci case 0x8E: 618c5f01b2fSopenharmony_ci case 0x8F: 619c5f01b2fSopenharmony_ci case 0x90: 620c5f01b2fSopenharmony_ci case 0x91: 621c5f01b2fSopenharmony_ci case 0x92: 622c5f01b2fSopenharmony_ci case 0x93: 623c5f01b2fSopenharmony_ci case 0x94: 624c5f01b2fSopenharmony_ci case 0x95: 625c5f01b2fSopenharmony_ci case 0x96: 626c5f01b2fSopenharmony_ci case 0x97: 627c5f01b2fSopenharmony_ci return get_cbor_array( 628c5f01b2fSopenharmony_ci conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler); 629c5f01b2fSopenharmony_ci 630c5f01b2fSopenharmony_ci case 0x98: // array (one-byte uint8_t for n follows) 631c5f01b2fSopenharmony_ci { 632c5f01b2fSopenharmony_ci std::uint8_t len{}; 633c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler); 634c5f01b2fSopenharmony_ci } 635c5f01b2fSopenharmony_ci 636c5f01b2fSopenharmony_ci case 0x99: // array (two-byte uint16_t for n follow) 637c5f01b2fSopenharmony_ci { 638c5f01b2fSopenharmony_ci std::uint16_t len{}; 639c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler); 640c5f01b2fSopenharmony_ci } 641c5f01b2fSopenharmony_ci 642c5f01b2fSopenharmony_ci case 0x9A: // array (four-byte uint32_t for n follow) 643c5f01b2fSopenharmony_ci { 644c5f01b2fSopenharmony_ci std::uint32_t len{}; 645c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler); 646c5f01b2fSopenharmony_ci } 647c5f01b2fSopenharmony_ci 648c5f01b2fSopenharmony_ci case 0x9B: // array (eight-byte uint64_t for n follow) 649c5f01b2fSopenharmony_ci { 650c5f01b2fSopenharmony_ci std::uint64_t len{}; 651c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler); 652c5f01b2fSopenharmony_ci } 653c5f01b2fSopenharmony_ci 654c5f01b2fSopenharmony_ci case 0x9F: // array (indefinite length) 655c5f01b2fSopenharmony_ci return get_cbor_array(static_cast<std::size_t>(-1), tag_handler); 656c5f01b2fSopenharmony_ci 657c5f01b2fSopenharmony_ci // map (0x00..0x17 pairs of data items follow) 658c5f01b2fSopenharmony_ci case 0xA0: 659c5f01b2fSopenharmony_ci case 0xA1: 660c5f01b2fSopenharmony_ci case 0xA2: 661c5f01b2fSopenharmony_ci case 0xA3: 662c5f01b2fSopenharmony_ci case 0xA4: 663c5f01b2fSopenharmony_ci case 0xA5: 664c5f01b2fSopenharmony_ci case 0xA6: 665c5f01b2fSopenharmony_ci case 0xA7: 666c5f01b2fSopenharmony_ci case 0xA8: 667c5f01b2fSopenharmony_ci case 0xA9: 668c5f01b2fSopenharmony_ci case 0xAA: 669c5f01b2fSopenharmony_ci case 0xAB: 670c5f01b2fSopenharmony_ci case 0xAC: 671c5f01b2fSopenharmony_ci case 0xAD: 672c5f01b2fSopenharmony_ci case 0xAE: 673c5f01b2fSopenharmony_ci case 0xAF: 674c5f01b2fSopenharmony_ci case 0xB0: 675c5f01b2fSopenharmony_ci case 0xB1: 676c5f01b2fSopenharmony_ci case 0xB2: 677c5f01b2fSopenharmony_ci case 0xB3: 678c5f01b2fSopenharmony_ci case 0xB4: 679c5f01b2fSopenharmony_ci case 0xB5: 680c5f01b2fSopenharmony_ci case 0xB6: 681c5f01b2fSopenharmony_ci case 0xB7: 682c5f01b2fSopenharmony_ci return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler); 683c5f01b2fSopenharmony_ci 684c5f01b2fSopenharmony_ci case 0xB8: // map (one-byte uint8_t for n follows) 685c5f01b2fSopenharmony_ci { 686c5f01b2fSopenharmony_ci std::uint8_t len{}; 687c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler); 688c5f01b2fSopenharmony_ci } 689c5f01b2fSopenharmony_ci 690c5f01b2fSopenharmony_ci case 0xB9: // map (two-byte uint16_t for n follow) 691c5f01b2fSopenharmony_ci { 692c5f01b2fSopenharmony_ci std::uint16_t len{}; 693c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler); 694c5f01b2fSopenharmony_ci } 695c5f01b2fSopenharmony_ci 696c5f01b2fSopenharmony_ci case 0xBA: // map (four-byte uint32_t for n follow) 697c5f01b2fSopenharmony_ci { 698c5f01b2fSopenharmony_ci std::uint32_t len{}; 699c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler); 700c5f01b2fSopenharmony_ci } 701c5f01b2fSopenharmony_ci 702c5f01b2fSopenharmony_ci case 0xBB: // map (eight-byte uint64_t for n follow) 703c5f01b2fSopenharmony_ci { 704c5f01b2fSopenharmony_ci std::uint64_t len{}; 705c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler); 706c5f01b2fSopenharmony_ci } 707c5f01b2fSopenharmony_ci 708c5f01b2fSopenharmony_ci case 0xBF: // map (indefinite length) 709c5f01b2fSopenharmony_ci return get_cbor_object(static_cast<std::size_t>(-1), tag_handler); 710c5f01b2fSopenharmony_ci 711c5f01b2fSopenharmony_ci case 0xC6: // tagged item 712c5f01b2fSopenharmony_ci case 0xC7: 713c5f01b2fSopenharmony_ci case 0xC8: 714c5f01b2fSopenharmony_ci case 0xC9: 715c5f01b2fSopenharmony_ci case 0xCA: 716c5f01b2fSopenharmony_ci case 0xCB: 717c5f01b2fSopenharmony_ci case 0xCC: 718c5f01b2fSopenharmony_ci case 0xCD: 719c5f01b2fSopenharmony_ci case 0xCE: 720c5f01b2fSopenharmony_ci case 0xCF: 721c5f01b2fSopenharmony_ci case 0xD0: 722c5f01b2fSopenharmony_ci case 0xD1: 723c5f01b2fSopenharmony_ci case 0xD2: 724c5f01b2fSopenharmony_ci case 0xD3: 725c5f01b2fSopenharmony_ci case 0xD4: 726c5f01b2fSopenharmony_ci case 0xD8: // tagged item (1 bytes follow) 727c5f01b2fSopenharmony_ci case 0xD9: // tagged item (2 bytes follow) 728c5f01b2fSopenharmony_ci case 0xDA: // tagged item (4 bytes follow) 729c5f01b2fSopenharmony_ci case 0xDB: // tagged item (8 bytes follow) 730c5f01b2fSopenharmony_ci { 731c5f01b2fSopenharmony_ci switch (tag_handler) 732c5f01b2fSopenharmony_ci { 733c5f01b2fSopenharmony_ci case cbor_tag_handler_t::error: 734c5f01b2fSopenharmony_ci { 735c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 736c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 737c5f01b2fSopenharmony_ci exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr)); 738c5f01b2fSopenharmony_ci } 739c5f01b2fSopenharmony_ci 740c5f01b2fSopenharmony_ci case cbor_tag_handler_t::ignore: 741c5f01b2fSopenharmony_ci { 742c5f01b2fSopenharmony_ci // ignore binary subtype 743c5f01b2fSopenharmony_ci switch (current) 744c5f01b2fSopenharmony_ci { 745c5f01b2fSopenharmony_ci case 0xD8: 746c5f01b2fSopenharmony_ci { 747c5f01b2fSopenharmony_ci std::uint8_t subtype_to_ignore{}; 748c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype_to_ignore); 749c5f01b2fSopenharmony_ci break; 750c5f01b2fSopenharmony_ci } 751c5f01b2fSopenharmony_ci case 0xD9: 752c5f01b2fSopenharmony_ci { 753c5f01b2fSopenharmony_ci std::uint16_t subtype_to_ignore{}; 754c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype_to_ignore); 755c5f01b2fSopenharmony_ci break; 756c5f01b2fSopenharmony_ci } 757c5f01b2fSopenharmony_ci case 0xDA: 758c5f01b2fSopenharmony_ci { 759c5f01b2fSopenharmony_ci std::uint32_t subtype_to_ignore{}; 760c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype_to_ignore); 761c5f01b2fSopenharmony_ci break; 762c5f01b2fSopenharmony_ci } 763c5f01b2fSopenharmony_ci case 0xDB: 764c5f01b2fSopenharmony_ci { 765c5f01b2fSopenharmony_ci std::uint64_t subtype_to_ignore{}; 766c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype_to_ignore); 767c5f01b2fSopenharmony_ci break; 768c5f01b2fSopenharmony_ci } 769c5f01b2fSopenharmony_ci default: 770c5f01b2fSopenharmony_ci break; 771c5f01b2fSopenharmony_ci } 772c5f01b2fSopenharmony_ci return parse_cbor_internal(true, tag_handler); 773c5f01b2fSopenharmony_ci } 774c5f01b2fSopenharmony_ci 775c5f01b2fSopenharmony_ci case cbor_tag_handler_t::store: 776c5f01b2fSopenharmony_ci { 777c5f01b2fSopenharmony_ci binary_t b; 778c5f01b2fSopenharmony_ci // use binary subtype and store in binary container 779c5f01b2fSopenharmony_ci switch (current) 780c5f01b2fSopenharmony_ci { 781c5f01b2fSopenharmony_ci case 0xD8: 782c5f01b2fSopenharmony_ci { 783c5f01b2fSopenharmony_ci std::uint8_t subtype{}; 784c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype); 785c5f01b2fSopenharmony_ci b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); 786c5f01b2fSopenharmony_ci break; 787c5f01b2fSopenharmony_ci } 788c5f01b2fSopenharmony_ci case 0xD9: 789c5f01b2fSopenharmony_ci { 790c5f01b2fSopenharmony_ci std::uint16_t subtype{}; 791c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype); 792c5f01b2fSopenharmony_ci b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); 793c5f01b2fSopenharmony_ci break; 794c5f01b2fSopenharmony_ci } 795c5f01b2fSopenharmony_ci case 0xDA: 796c5f01b2fSopenharmony_ci { 797c5f01b2fSopenharmony_ci std::uint32_t subtype{}; 798c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype); 799c5f01b2fSopenharmony_ci b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); 800c5f01b2fSopenharmony_ci break; 801c5f01b2fSopenharmony_ci } 802c5f01b2fSopenharmony_ci case 0xDB: 803c5f01b2fSopenharmony_ci { 804c5f01b2fSopenharmony_ci std::uint64_t subtype{}; 805c5f01b2fSopenharmony_ci get_number(input_format_t::cbor, subtype); 806c5f01b2fSopenharmony_ci b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype)); 807c5f01b2fSopenharmony_ci break; 808c5f01b2fSopenharmony_ci } 809c5f01b2fSopenharmony_ci default: 810c5f01b2fSopenharmony_ci return parse_cbor_internal(true, tag_handler); 811c5f01b2fSopenharmony_ci } 812c5f01b2fSopenharmony_ci get(); 813c5f01b2fSopenharmony_ci return get_cbor_binary(b) && sax->binary(b); 814c5f01b2fSopenharmony_ci } 815c5f01b2fSopenharmony_ci 816c5f01b2fSopenharmony_ci default: // LCOV_EXCL_LINE 817c5f01b2fSopenharmony_ci JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE 818c5f01b2fSopenharmony_ci return false; // LCOV_EXCL_LINE 819c5f01b2fSopenharmony_ci } 820c5f01b2fSopenharmony_ci } 821c5f01b2fSopenharmony_ci 822c5f01b2fSopenharmony_ci case 0xF4: // false 823c5f01b2fSopenharmony_ci return sax->boolean(false); 824c5f01b2fSopenharmony_ci 825c5f01b2fSopenharmony_ci case 0xF5: // true 826c5f01b2fSopenharmony_ci return sax->boolean(true); 827c5f01b2fSopenharmony_ci 828c5f01b2fSopenharmony_ci case 0xF6: // null 829c5f01b2fSopenharmony_ci return sax->null(); 830c5f01b2fSopenharmony_ci 831c5f01b2fSopenharmony_ci case 0xF9: // Half-Precision Float (two-byte IEEE 754) 832c5f01b2fSopenharmony_ci { 833c5f01b2fSopenharmony_ci const auto byte1_raw = get(); 834c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) 835c5f01b2fSopenharmony_ci { 836c5f01b2fSopenharmony_ci return false; 837c5f01b2fSopenharmony_ci } 838c5f01b2fSopenharmony_ci const auto byte2_raw = get(); 839c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) 840c5f01b2fSopenharmony_ci { 841c5f01b2fSopenharmony_ci return false; 842c5f01b2fSopenharmony_ci } 843c5f01b2fSopenharmony_ci 844c5f01b2fSopenharmony_ci const auto byte1 = static_cast<unsigned char>(byte1_raw); 845c5f01b2fSopenharmony_ci const auto byte2 = static_cast<unsigned char>(byte2_raw); 846c5f01b2fSopenharmony_ci 847c5f01b2fSopenharmony_ci // code from RFC 7049, Appendix D, Figure 3: 848c5f01b2fSopenharmony_ci // As half-precision floating-point numbers were only added 849c5f01b2fSopenharmony_ci // to IEEE 754 in 2008, today's programming platforms often 850c5f01b2fSopenharmony_ci // still only have limited support for them. It is very 851c5f01b2fSopenharmony_ci // easy to include at least decoding support for them even 852c5f01b2fSopenharmony_ci // without such support. An example of a small decoder for 853c5f01b2fSopenharmony_ci // half-precision floating-point numbers in the C language 854c5f01b2fSopenharmony_ci // is shown in Fig. 3. 855c5f01b2fSopenharmony_ci const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2); 856c5f01b2fSopenharmony_ci const double val = [&half] 857c5f01b2fSopenharmony_ci { 858c5f01b2fSopenharmony_ci const int exp = (half >> 10u) & 0x1Fu; 859c5f01b2fSopenharmony_ci const unsigned int mant = half & 0x3FFu; 860c5f01b2fSopenharmony_ci JSON_ASSERT(0 <= exp&& exp <= 32); 861c5f01b2fSopenharmony_ci JSON_ASSERT(mant <= 1024); 862c5f01b2fSopenharmony_ci switch (exp) 863c5f01b2fSopenharmony_ci { 864c5f01b2fSopenharmony_ci case 0: 865c5f01b2fSopenharmony_ci return std::ldexp(mant, -24); 866c5f01b2fSopenharmony_ci case 31: 867c5f01b2fSopenharmony_ci return (mant == 0) 868c5f01b2fSopenharmony_ci ? std::numeric_limits<double>::infinity() 869c5f01b2fSopenharmony_ci : std::numeric_limits<double>::quiet_NaN(); 870c5f01b2fSopenharmony_ci default: 871c5f01b2fSopenharmony_ci return std::ldexp(mant + 1024, exp - 25); 872c5f01b2fSopenharmony_ci } 873c5f01b2fSopenharmony_ci }(); 874c5f01b2fSopenharmony_ci return sax->number_float((half & 0x8000u) != 0 875c5f01b2fSopenharmony_ci ? static_cast<number_float_t>(-val) 876c5f01b2fSopenharmony_ci : static_cast<number_float_t>(val), ""); 877c5f01b2fSopenharmony_ci } 878c5f01b2fSopenharmony_ci 879c5f01b2fSopenharmony_ci case 0xFA: // Single-Precision Float (four-byte IEEE 754) 880c5f01b2fSopenharmony_ci { 881c5f01b2fSopenharmony_ci float number{}; 882c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), ""); 883c5f01b2fSopenharmony_ci } 884c5f01b2fSopenharmony_ci 885c5f01b2fSopenharmony_ci case 0xFB: // Double-Precision Float (eight-byte IEEE 754) 886c5f01b2fSopenharmony_ci { 887c5f01b2fSopenharmony_ci double number{}; 888c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), ""); 889c5f01b2fSopenharmony_ci } 890c5f01b2fSopenharmony_ci 891c5f01b2fSopenharmony_ci default: // anything else (0xFF is handled inside the other types) 892c5f01b2fSopenharmony_ci { 893c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 894c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 895c5f01b2fSopenharmony_ci exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr)); 896c5f01b2fSopenharmony_ci } 897c5f01b2fSopenharmony_ci } 898c5f01b2fSopenharmony_ci } 899c5f01b2fSopenharmony_ci 900c5f01b2fSopenharmony_ci /*! 901c5f01b2fSopenharmony_ci @brief reads a CBOR string 902c5f01b2fSopenharmony_ci 903c5f01b2fSopenharmony_ci This function first reads starting bytes to determine the expected 904c5f01b2fSopenharmony_ci string length and then copies this number of bytes into a string. 905c5f01b2fSopenharmony_ci Additionally, CBOR's strings with indefinite lengths are supported. 906c5f01b2fSopenharmony_ci 907c5f01b2fSopenharmony_ci @param[out] result created string 908c5f01b2fSopenharmony_ci 909c5f01b2fSopenharmony_ci @return whether string creation completed 910c5f01b2fSopenharmony_ci */ 911c5f01b2fSopenharmony_ci bool get_cbor_string(string_t& result) 912c5f01b2fSopenharmony_ci { 913c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) 914c5f01b2fSopenharmony_ci { 915c5f01b2fSopenharmony_ci return false; 916c5f01b2fSopenharmony_ci } 917c5f01b2fSopenharmony_ci 918c5f01b2fSopenharmony_ci switch (current) 919c5f01b2fSopenharmony_ci { 920c5f01b2fSopenharmony_ci // UTF-8 string (0x00..0x17 bytes follow) 921c5f01b2fSopenharmony_ci case 0x60: 922c5f01b2fSopenharmony_ci case 0x61: 923c5f01b2fSopenharmony_ci case 0x62: 924c5f01b2fSopenharmony_ci case 0x63: 925c5f01b2fSopenharmony_ci case 0x64: 926c5f01b2fSopenharmony_ci case 0x65: 927c5f01b2fSopenharmony_ci case 0x66: 928c5f01b2fSopenharmony_ci case 0x67: 929c5f01b2fSopenharmony_ci case 0x68: 930c5f01b2fSopenharmony_ci case 0x69: 931c5f01b2fSopenharmony_ci case 0x6A: 932c5f01b2fSopenharmony_ci case 0x6B: 933c5f01b2fSopenharmony_ci case 0x6C: 934c5f01b2fSopenharmony_ci case 0x6D: 935c5f01b2fSopenharmony_ci case 0x6E: 936c5f01b2fSopenharmony_ci case 0x6F: 937c5f01b2fSopenharmony_ci case 0x70: 938c5f01b2fSopenharmony_ci case 0x71: 939c5f01b2fSopenharmony_ci case 0x72: 940c5f01b2fSopenharmony_ci case 0x73: 941c5f01b2fSopenharmony_ci case 0x74: 942c5f01b2fSopenharmony_ci case 0x75: 943c5f01b2fSopenharmony_ci case 0x76: 944c5f01b2fSopenharmony_ci case 0x77: 945c5f01b2fSopenharmony_ci { 946c5f01b2fSopenharmony_ci return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result); 947c5f01b2fSopenharmony_ci } 948c5f01b2fSopenharmony_ci 949c5f01b2fSopenharmony_ci case 0x78: // UTF-8 string (one-byte uint8_t for n follows) 950c5f01b2fSopenharmony_ci { 951c5f01b2fSopenharmony_ci std::uint8_t len{}; 952c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); 953c5f01b2fSopenharmony_ci } 954c5f01b2fSopenharmony_ci 955c5f01b2fSopenharmony_ci case 0x79: // UTF-8 string (two-byte uint16_t for n follow) 956c5f01b2fSopenharmony_ci { 957c5f01b2fSopenharmony_ci std::uint16_t len{}; 958c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); 959c5f01b2fSopenharmony_ci } 960c5f01b2fSopenharmony_ci 961c5f01b2fSopenharmony_ci case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) 962c5f01b2fSopenharmony_ci { 963c5f01b2fSopenharmony_ci std::uint32_t len{}; 964c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); 965c5f01b2fSopenharmony_ci } 966c5f01b2fSopenharmony_ci 967c5f01b2fSopenharmony_ci case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) 968c5f01b2fSopenharmony_ci { 969c5f01b2fSopenharmony_ci std::uint64_t len{}; 970c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); 971c5f01b2fSopenharmony_ci } 972c5f01b2fSopenharmony_ci 973c5f01b2fSopenharmony_ci case 0x7F: // UTF-8 string (indefinite length) 974c5f01b2fSopenharmony_ci { 975c5f01b2fSopenharmony_ci while (get() != 0xFF) 976c5f01b2fSopenharmony_ci { 977c5f01b2fSopenharmony_ci string_t chunk; 978c5f01b2fSopenharmony_ci if (!get_cbor_string(chunk)) 979c5f01b2fSopenharmony_ci { 980c5f01b2fSopenharmony_ci return false; 981c5f01b2fSopenharmony_ci } 982c5f01b2fSopenharmony_ci result.append(chunk); 983c5f01b2fSopenharmony_ci } 984c5f01b2fSopenharmony_ci return true; 985c5f01b2fSopenharmony_ci } 986c5f01b2fSopenharmony_ci 987c5f01b2fSopenharmony_ci default: 988c5f01b2fSopenharmony_ci { 989c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 990c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, 991c5f01b2fSopenharmony_ci exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr)); 992c5f01b2fSopenharmony_ci } 993c5f01b2fSopenharmony_ci } 994c5f01b2fSopenharmony_ci } 995c5f01b2fSopenharmony_ci 996c5f01b2fSopenharmony_ci /*! 997c5f01b2fSopenharmony_ci @brief reads a CBOR byte array 998c5f01b2fSopenharmony_ci 999c5f01b2fSopenharmony_ci This function first reads starting bytes to determine the expected 1000c5f01b2fSopenharmony_ci byte array length and then copies this number of bytes into the byte array. 1001c5f01b2fSopenharmony_ci Additionally, CBOR's byte arrays with indefinite lengths are supported. 1002c5f01b2fSopenharmony_ci 1003c5f01b2fSopenharmony_ci @param[out] result created byte array 1004c5f01b2fSopenharmony_ci 1005c5f01b2fSopenharmony_ci @return whether byte array creation completed 1006c5f01b2fSopenharmony_ci */ 1007c5f01b2fSopenharmony_ci bool get_cbor_binary(binary_t& result) 1008c5f01b2fSopenharmony_ci { 1009c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) 1010c5f01b2fSopenharmony_ci { 1011c5f01b2fSopenharmony_ci return false; 1012c5f01b2fSopenharmony_ci } 1013c5f01b2fSopenharmony_ci 1014c5f01b2fSopenharmony_ci switch (current) 1015c5f01b2fSopenharmony_ci { 1016c5f01b2fSopenharmony_ci // Binary data (0x00..0x17 bytes follow) 1017c5f01b2fSopenharmony_ci case 0x40: 1018c5f01b2fSopenharmony_ci case 0x41: 1019c5f01b2fSopenharmony_ci case 0x42: 1020c5f01b2fSopenharmony_ci case 0x43: 1021c5f01b2fSopenharmony_ci case 0x44: 1022c5f01b2fSopenharmony_ci case 0x45: 1023c5f01b2fSopenharmony_ci case 0x46: 1024c5f01b2fSopenharmony_ci case 0x47: 1025c5f01b2fSopenharmony_ci case 0x48: 1026c5f01b2fSopenharmony_ci case 0x49: 1027c5f01b2fSopenharmony_ci case 0x4A: 1028c5f01b2fSopenharmony_ci case 0x4B: 1029c5f01b2fSopenharmony_ci case 0x4C: 1030c5f01b2fSopenharmony_ci case 0x4D: 1031c5f01b2fSopenharmony_ci case 0x4E: 1032c5f01b2fSopenharmony_ci case 0x4F: 1033c5f01b2fSopenharmony_ci case 0x50: 1034c5f01b2fSopenharmony_ci case 0x51: 1035c5f01b2fSopenharmony_ci case 0x52: 1036c5f01b2fSopenharmony_ci case 0x53: 1037c5f01b2fSopenharmony_ci case 0x54: 1038c5f01b2fSopenharmony_ci case 0x55: 1039c5f01b2fSopenharmony_ci case 0x56: 1040c5f01b2fSopenharmony_ci case 0x57: 1041c5f01b2fSopenharmony_ci { 1042c5f01b2fSopenharmony_ci return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result); 1043c5f01b2fSopenharmony_ci } 1044c5f01b2fSopenharmony_ci 1045c5f01b2fSopenharmony_ci case 0x58: // Binary data (one-byte uint8_t for n follows) 1046c5f01b2fSopenharmony_ci { 1047c5f01b2fSopenharmony_ci std::uint8_t len{}; 1048c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && 1049c5f01b2fSopenharmony_ci get_binary(input_format_t::cbor, len, result); 1050c5f01b2fSopenharmony_ci } 1051c5f01b2fSopenharmony_ci 1052c5f01b2fSopenharmony_ci case 0x59: // Binary data (two-byte uint16_t for n follow) 1053c5f01b2fSopenharmony_ci { 1054c5f01b2fSopenharmony_ci std::uint16_t len{}; 1055c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && 1056c5f01b2fSopenharmony_ci get_binary(input_format_t::cbor, len, result); 1057c5f01b2fSopenharmony_ci } 1058c5f01b2fSopenharmony_ci 1059c5f01b2fSopenharmony_ci case 0x5A: // Binary data (four-byte uint32_t for n follow) 1060c5f01b2fSopenharmony_ci { 1061c5f01b2fSopenharmony_ci std::uint32_t len{}; 1062c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && 1063c5f01b2fSopenharmony_ci get_binary(input_format_t::cbor, len, result); 1064c5f01b2fSopenharmony_ci } 1065c5f01b2fSopenharmony_ci 1066c5f01b2fSopenharmony_ci case 0x5B: // Binary data (eight-byte uint64_t for n follow) 1067c5f01b2fSopenharmony_ci { 1068c5f01b2fSopenharmony_ci std::uint64_t len{}; 1069c5f01b2fSopenharmony_ci return get_number(input_format_t::cbor, len) && 1070c5f01b2fSopenharmony_ci get_binary(input_format_t::cbor, len, result); 1071c5f01b2fSopenharmony_ci } 1072c5f01b2fSopenharmony_ci 1073c5f01b2fSopenharmony_ci case 0x5F: // Binary data (indefinite length) 1074c5f01b2fSopenharmony_ci { 1075c5f01b2fSopenharmony_ci while (get() != 0xFF) 1076c5f01b2fSopenharmony_ci { 1077c5f01b2fSopenharmony_ci binary_t chunk; 1078c5f01b2fSopenharmony_ci if (!get_cbor_binary(chunk)) 1079c5f01b2fSopenharmony_ci { 1080c5f01b2fSopenharmony_ci return false; 1081c5f01b2fSopenharmony_ci } 1082c5f01b2fSopenharmony_ci result.insert(result.end(), chunk.begin(), chunk.end()); 1083c5f01b2fSopenharmony_ci } 1084c5f01b2fSopenharmony_ci return true; 1085c5f01b2fSopenharmony_ci } 1086c5f01b2fSopenharmony_ci 1087c5f01b2fSopenharmony_ci default: 1088c5f01b2fSopenharmony_ci { 1089c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 1090c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, 1091c5f01b2fSopenharmony_ci 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)); 1092c5f01b2fSopenharmony_ci } 1093c5f01b2fSopenharmony_ci } 1094c5f01b2fSopenharmony_ci } 1095c5f01b2fSopenharmony_ci 1096c5f01b2fSopenharmony_ci /*! 1097c5f01b2fSopenharmony_ci @param[in] len the length of the array or static_cast<std::size_t>(-1) for an 1098c5f01b2fSopenharmony_ci array of indefinite size 1099c5f01b2fSopenharmony_ci @param[in] tag_handler how CBOR tags should be treated 1100c5f01b2fSopenharmony_ci @return whether array creation completed 1101c5f01b2fSopenharmony_ci */ 1102c5f01b2fSopenharmony_ci bool get_cbor_array(const std::size_t len, 1103c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler) 1104c5f01b2fSopenharmony_ci { 1105c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) 1106c5f01b2fSopenharmony_ci { 1107c5f01b2fSopenharmony_ci return false; 1108c5f01b2fSopenharmony_ci } 1109c5f01b2fSopenharmony_ci 1110c5f01b2fSopenharmony_ci if (len != static_cast<std::size_t>(-1)) 1111c5f01b2fSopenharmony_ci { 1112c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < len; ++i) 1113c5f01b2fSopenharmony_ci { 1114c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) 1115c5f01b2fSopenharmony_ci { 1116c5f01b2fSopenharmony_ci return false; 1117c5f01b2fSopenharmony_ci } 1118c5f01b2fSopenharmony_ci } 1119c5f01b2fSopenharmony_ci } 1120c5f01b2fSopenharmony_ci else 1121c5f01b2fSopenharmony_ci { 1122c5f01b2fSopenharmony_ci while (get() != 0xFF) 1123c5f01b2fSopenharmony_ci { 1124c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) 1125c5f01b2fSopenharmony_ci { 1126c5f01b2fSopenharmony_ci return false; 1127c5f01b2fSopenharmony_ci } 1128c5f01b2fSopenharmony_ci } 1129c5f01b2fSopenharmony_ci } 1130c5f01b2fSopenharmony_ci 1131c5f01b2fSopenharmony_ci return sax->end_array(); 1132c5f01b2fSopenharmony_ci } 1133c5f01b2fSopenharmony_ci 1134c5f01b2fSopenharmony_ci /*! 1135c5f01b2fSopenharmony_ci @param[in] len the length of the object or static_cast<std::size_t>(-1) for an 1136c5f01b2fSopenharmony_ci object of indefinite size 1137c5f01b2fSopenharmony_ci @param[in] tag_handler how CBOR tags should be treated 1138c5f01b2fSopenharmony_ci @return whether object creation completed 1139c5f01b2fSopenharmony_ci */ 1140c5f01b2fSopenharmony_ci bool get_cbor_object(const std::size_t len, 1141c5f01b2fSopenharmony_ci const cbor_tag_handler_t tag_handler) 1142c5f01b2fSopenharmony_ci { 1143c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) 1144c5f01b2fSopenharmony_ci { 1145c5f01b2fSopenharmony_ci return false; 1146c5f01b2fSopenharmony_ci } 1147c5f01b2fSopenharmony_ci 1148c5f01b2fSopenharmony_ci if (len != 0) 1149c5f01b2fSopenharmony_ci { 1150c5f01b2fSopenharmony_ci string_t key; 1151c5f01b2fSopenharmony_ci if (len != static_cast<std::size_t>(-1)) 1152c5f01b2fSopenharmony_ci { 1153c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < len; ++i) 1154c5f01b2fSopenharmony_ci { 1155c5f01b2fSopenharmony_ci get(); 1156c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) 1157c5f01b2fSopenharmony_ci { 1158c5f01b2fSopenharmony_ci return false; 1159c5f01b2fSopenharmony_ci } 1160c5f01b2fSopenharmony_ci 1161c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) 1162c5f01b2fSopenharmony_ci { 1163c5f01b2fSopenharmony_ci return false; 1164c5f01b2fSopenharmony_ci } 1165c5f01b2fSopenharmony_ci key.clear(); 1166c5f01b2fSopenharmony_ci } 1167c5f01b2fSopenharmony_ci } 1168c5f01b2fSopenharmony_ci else 1169c5f01b2fSopenharmony_ci { 1170c5f01b2fSopenharmony_ci while (get() != 0xFF) 1171c5f01b2fSopenharmony_ci { 1172c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) 1173c5f01b2fSopenharmony_ci { 1174c5f01b2fSopenharmony_ci return false; 1175c5f01b2fSopenharmony_ci } 1176c5f01b2fSopenharmony_ci 1177c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) 1178c5f01b2fSopenharmony_ci { 1179c5f01b2fSopenharmony_ci return false; 1180c5f01b2fSopenharmony_ci } 1181c5f01b2fSopenharmony_ci key.clear(); 1182c5f01b2fSopenharmony_ci } 1183c5f01b2fSopenharmony_ci } 1184c5f01b2fSopenharmony_ci } 1185c5f01b2fSopenharmony_ci 1186c5f01b2fSopenharmony_ci return sax->end_object(); 1187c5f01b2fSopenharmony_ci } 1188c5f01b2fSopenharmony_ci 1189c5f01b2fSopenharmony_ci ///////////// 1190c5f01b2fSopenharmony_ci // MsgPack // 1191c5f01b2fSopenharmony_ci ///////////// 1192c5f01b2fSopenharmony_ci 1193c5f01b2fSopenharmony_ci /*! 1194c5f01b2fSopenharmony_ci @return whether a valid MessagePack value was passed to the SAX parser 1195c5f01b2fSopenharmony_ci */ 1196c5f01b2fSopenharmony_ci bool parse_msgpack_internal() 1197c5f01b2fSopenharmony_ci { 1198c5f01b2fSopenharmony_ci switch (get()) 1199c5f01b2fSopenharmony_ci { 1200c5f01b2fSopenharmony_ci // EOF 1201c5f01b2fSopenharmony_ci case std::char_traits<char_type>::eof(): 1202c5f01b2fSopenharmony_ci return unexpect_eof(input_format_t::msgpack, "value"); 1203c5f01b2fSopenharmony_ci 1204c5f01b2fSopenharmony_ci // positive fixint 1205c5f01b2fSopenharmony_ci case 0x00: 1206c5f01b2fSopenharmony_ci case 0x01: 1207c5f01b2fSopenharmony_ci case 0x02: 1208c5f01b2fSopenharmony_ci case 0x03: 1209c5f01b2fSopenharmony_ci case 0x04: 1210c5f01b2fSopenharmony_ci case 0x05: 1211c5f01b2fSopenharmony_ci case 0x06: 1212c5f01b2fSopenharmony_ci case 0x07: 1213c5f01b2fSopenharmony_ci case 0x08: 1214c5f01b2fSopenharmony_ci case 0x09: 1215c5f01b2fSopenharmony_ci case 0x0A: 1216c5f01b2fSopenharmony_ci case 0x0B: 1217c5f01b2fSopenharmony_ci case 0x0C: 1218c5f01b2fSopenharmony_ci case 0x0D: 1219c5f01b2fSopenharmony_ci case 0x0E: 1220c5f01b2fSopenharmony_ci case 0x0F: 1221c5f01b2fSopenharmony_ci case 0x10: 1222c5f01b2fSopenharmony_ci case 0x11: 1223c5f01b2fSopenharmony_ci case 0x12: 1224c5f01b2fSopenharmony_ci case 0x13: 1225c5f01b2fSopenharmony_ci case 0x14: 1226c5f01b2fSopenharmony_ci case 0x15: 1227c5f01b2fSopenharmony_ci case 0x16: 1228c5f01b2fSopenharmony_ci case 0x17: 1229c5f01b2fSopenharmony_ci case 0x18: 1230c5f01b2fSopenharmony_ci case 0x19: 1231c5f01b2fSopenharmony_ci case 0x1A: 1232c5f01b2fSopenharmony_ci case 0x1B: 1233c5f01b2fSopenharmony_ci case 0x1C: 1234c5f01b2fSopenharmony_ci case 0x1D: 1235c5f01b2fSopenharmony_ci case 0x1E: 1236c5f01b2fSopenharmony_ci case 0x1F: 1237c5f01b2fSopenharmony_ci case 0x20: 1238c5f01b2fSopenharmony_ci case 0x21: 1239c5f01b2fSopenharmony_ci case 0x22: 1240c5f01b2fSopenharmony_ci case 0x23: 1241c5f01b2fSopenharmony_ci case 0x24: 1242c5f01b2fSopenharmony_ci case 0x25: 1243c5f01b2fSopenharmony_ci case 0x26: 1244c5f01b2fSopenharmony_ci case 0x27: 1245c5f01b2fSopenharmony_ci case 0x28: 1246c5f01b2fSopenharmony_ci case 0x29: 1247c5f01b2fSopenharmony_ci case 0x2A: 1248c5f01b2fSopenharmony_ci case 0x2B: 1249c5f01b2fSopenharmony_ci case 0x2C: 1250c5f01b2fSopenharmony_ci case 0x2D: 1251c5f01b2fSopenharmony_ci case 0x2E: 1252c5f01b2fSopenharmony_ci case 0x2F: 1253c5f01b2fSopenharmony_ci case 0x30: 1254c5f01b2fSopenharmony_ci case 0x31: 1255c5f01b2fSopenharmony_ci case 0x32: 1256c5f01b2fSopenharmony_ci case 0x33: 1257c5f01b2fSopenharmony_ci case 0x34: 1258c5f01b2fSopenharmony_ci case 0x35: 1259c5f01b2fSopenharmony_ci case 0x36: 1260c5f01b2fSopenharmony_ci case 0x37: 1261c5f01b2fSopenharmony_ci case 0x38: 1262c5f01b2fSopenharmony_ci case 0x39: 1263c5f01b2fSopenharmony_ci case 0x3A: 1264c5f01b2fSopenharmony_ci case 0x3B: 1265c5f01b2fSopenharmony_ci case 0x3C: 1266c5f01b2fSopenharmony_ci case 0x3D: 1267c5f01b2fSopenharmony_ci case 0x3E: 1268c5f01b2fSopenharmony_ci case 0x3F: 1269c5f01b2fSopenharmony_ci case 0x40: 1270c5f01b2fSopenharmony_ci case 0x41: 1271c5f01b2fSopenharmony_ci case 0x42: 1272c5f01b2fSopenharmony_ci case 0x43: 1273c5f01b2fSopenharmony_ci case 0x44: 1274c5f01b2fSopenharmony_ci case 0x45: 1275c5f01b2fSopenharmony_ci case 0x46: 1276c5f01b2fSopenharmony_ci case 0x47: 1277c5f01b2fSopenharmony_ci case 0x48: 1278c5f01b2fSopenharmony_ci case 0x49: 1279c5f01b2fSopenharmony_ci case 0x4A: 1280c5f01b2fSopenharmony_ci case 0x4B: 1281c5f01b2fSopenharmony_ci case 0x4C: 1282c5f01b2fSopenharmony_ci case 0x4D: 1283c5f01b2fSopenharmony_ci case 0x4E: 1284c5f01b2fSopenharmony_ci case 0x4F: 1285c5f01b2fSopenharmony_ci case 0x50: 1286c5f01b2fSopenharmony_ci case 0x51: 1287c5f01b2fSopenharmony_ci case 0x52: 1288c5f01b2fSopenharmony_ci case 0x53: 1289c5f01b2fSopenharmony_ci case 0x54: 1290c5f01b2fSopenharmony_ci case 0x55: 1291c5f01b2fSopenharmony_ci case 0x56: 1292c5f01b2fSopenharmony_ci case 0x57: 1293c5f01b2fSopenharmony_ci case 0x58: 1294c5f01b2fSopenharmony_ci case 0x59: 1295c5f01b2fSopenharmony_ci case 0x5A: 1296c5f01b2fSopenharmony_ci case 0x5B: 1297c5f01b2fSopenharmony_ci case 0x5C: 1298c5f01b2fSopenharmony_ci case 0x5D: 1299c5f01b2fSopenharmony_ci case 0x5E: 1300c5f01b2fSopenharmony_ci case 0x5F: 1301c5f01b2fSopenharmony_ci case 0x60: 1302c5f01b2fSopenharmony_ci case 0x61: 1303c5f01b2fSopenharmony_ci case 0x62: 1304c5f01b2fSopenharmony_ci case 0x63: 1305c5f01b2fSopenharmony_ci case 0x64: 1306c5f01b2fSopenharmony_ci case 0x65: 1307c5f01b2fSopenharmony_ci case 0x66: 1308c5f01b2fSopenharmony_ci case 0x67: 1309c5f01b2fSopenharmony_ci case 0x68: 1310c5f01b2fSopenharmony_ci case 0x69: 1311c5f01b2fSopenharmony_ci case 0x6A: 1312c5f01b2fSopenharmony_ci case 0x6B: 1313c5f01b2fSopenharmony_ci case 0x6C: 1314c5f01b2fSopenharmony_ci case 0x6D: 1315c5f01b2fSopenharmony_ci case 0x6E: 1316c5f01b2fSopenharmony_ci case 0x6F: 1317c5f01b2fSopenharmony_ci case 0x70: 1318c5f01b2fSopenharmony_ci case 0x71: 1319c5f01b2fSopenharmony_ci case 0x72: 1320c5f01b2fSopenharmony_ci case 0x73: 1321c5f01b2fSopenharmony_ci case 0x74: 1322c5f01b2fSopenharmony_ci case 0x75: 1323c5f01b2fSopenharmony_ci case 0x76: 1324c5f01b2fSopenharmony_ci case 0x77: 1325c5f01b2fSopenharmony_ci case 0x78: 1326c5f01b2fSopenharmony_ci case 0x79: 1327c5f01b2fSopenharmony_ci case 0x7A: 1328c5f01b2fSopenharmony_ci case 0x7B: 1329c5f01b2fSopenharmony_ci case 0x7C: 1330c5f01b2fSopenharmony_ci case 0x7D: 1331c5f01b2fSopenharmony_ci case 0x7E: 1332c5f01b2fSopenharmony_ci case 0x7F: 1333c5f01b2fSopenharmony_ci return sax->number_unsigned(static_cast<number_unsigned_t>(current)); 1334c5f01b2fSopenharmony_ci 1335c5f01b2fSopenharmony_ci // fixmap 1336c5f01b2fSopenharmony_ci case 0x80: 1337c5f01b2fSopenharmony_ci case 0x81: 1338c5f01b2fSopenharmony_ci case 0x82: 1339c5f01b2fSopenharmony_ci case 0x83: 1340c5f01b2fSopenharmony_ci case 0x84: 1341c5f01b2fSopenharmony_ci case 0x85: 1342c5f01b2fSopenharmony_ci case 0x86: 1343c5f01b2fSopenharmony_ci case 0x87: 1344c5f01b2fSopenharmony_ci case 0x88: 1345c5f01b2fSopenharmony_ci case 0x89: 1346c5f01b2fSopenharmony_ci case 0x8A: 1347c5f01b2fSopenharmony_ci case 0x8B: 1348c5f01b2fSopenharmony_ci case 0x8C: 1349c5f01b2fSopenharmony_ci case 0x8D: 1350c5f01b2fSopenharmony_ci case 0x8E: 1351c5f01b2fSopenharmony_ci case 0x8F: 1352c5f01b2fSopenharmony_ci return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); 1353c5f01b2fSopenharmony_ci 1354c5f01b2fSopenharmony_ci // fixarray 1355c5f01b2fSopenharmony_ci case 0x90: 1356c5f01b2fSopenharmony_ci case 0x91: 1357c5f01b2fSopenharmony_ci case 0x92: 1358c5f01b2fSopenharmony_ci case 0x93: 1359c5f01b2fSopenharmony_ci case 0x94: 1360c5f01b2fSopenharmony_ci case 0x95: 1361c5f01b2fSopenharmony_ci case 0x96: 1362c5f01b2fSopenharmony_ci case 0x97: 1363c5f01b2fSopenharmony_ci case 0x98: 1364c5f01b2fSopenharmony_ci case 0x99: 1365c5f01b2fSopenharmony_ci case 0x9A: 1366c5f01b2fSopenharmony_ci case 0x9B: 1367c5f01b2fSopenharmony_ci case 0x9C: 1368c5f01b2fSopenharmony_ci case 0x9D: 1369c5f01b2fSopenharmony_ci case 0x9E: 1370c5f01b2fSopenharmony_ci case 0x9F: 1371c5f01b2fSopenharmony_ci return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu)); 1372c5f01b2fSopenharmony_ci 1373c5f01b2fSopenharmony_ci // fixstr 1374c5f01b2fSopenharmony_ci case 0xA0: 1375c5f01b2fSopenharmony_ci case 0xA1: 1376c5f01b2fSopenharmony_ci case 0xA2: 1377c5f01b2fSopenharmony_ci case 0xA3: 1378c5f01b2fSopenharmony_ci case 0xA4: 1379c5f01b2fSopenharmony_ci case 0xA5: 1380c5f01b2fSopenharmony_ci case 0xA6: 1381c5f01b2fSopenharmony_ci case 0xA7: 1382c5f01b2fSopenharmony_ci case 0xA8: 1383c5f01b2fSopenharmony_ci case 0xA9: 1384c5f01b2fSopenharmony_ci case 0xAA: 1385c5f01b2fSopenharmony_ci case 0xAB: 1386c5f01b2fSopenharmony_ci case 0xAC: 1387c5f01b2fSopenharmony_ci case 0xAD: 1388c5f01b2fSopenharmony_ci case 0xAE: 1389c5f01b2fSopenharmony_ci case 0xAF: 1390c5f01b2fSopenharmony_ci case 0xB0: 1391c5f01b2fSopenharmony_ci case 0xB1: 1392c5f01b2fSopenharmony_ci case 0xB2: 1393c5f01b2fSopenharmony_ci case 0xB3: 1394c5f01b2fSopenharmony_ci case 0xB4: 1395c5f01b2fSopenharmony_ci case 0xB5: 1396c5f01b2fSopenharmony_ci case 0xB6: 1397c5f01b2fSopenharmony_ci case 0xB7: 1398c5f01b2fSopenharmony_ci case 0xB8: 1399c5f01b2fSopenharmony_ci case 0xB9: 1400c5f01b2fSopenharmony_ci case 0xBA: 1401c5f01b2fSopenharmony_ci case 0xBB: 1402c5f01b2fSopenharmony_ci case 0xBC: 1403c5f01b2fSopenharmony_ci case 0xBD: 1404c5f01b2fSopenharmony_ci case 0xBE: 1405c5f01b2fSopenharmony_ci case 0xBF: 1406c5f01b2fSopenharmony_ci case 0xD9: // str 8 1407c5f01b2fSopenharmony_ci case 0xDA: // str 16 1408c5f01b2fSopenharmony_ci case 0xDB: // str 32 1409c5f01b2fSopenharmony_ci { 1410c5f01b2fSopenharmony_ci string_t s; 1411c5f01b2fSopenharmony_ci return get_msgpack_string(s) && sax->string(s); 1412c5f01b2fSopenharmony_ci } 1413c5f01b2fSopenharmony_ci 1414c5f01b2fSopenharmony_ci case 0xC0: // nil 1415c5f01b2fSopenharmony_ci return sax->null(); 1416c5f01b2fSopenharmony_ci 1417c5f01b2fSopenharmony_ci case 0xC2: // false 1418c5f01b2fSopenharmony_ci return sax->boolean(false); 1419c5f01b2fSopenharmony_ci 1420c5f01b2fSopenharmony_ci case 0xC3: // true 1421c5f01b2fSopenharmony_ci return sax->boolean(true); 1422c5f01b2fSopenharmony_ci 1423c5f01b2fSopenharmony_ci case 0xC4: // bin 8 1424c5f01b2fSopenharmony_ci case 0xC5: // bin 16 1425c5f01b2fSopenharmony_ci case 0xC6: // bin 32 1426c5f01b2fSopenharmony_ci case 0xC7: // ext 8 1427c5f01b2fSopenharmony_ci case 0xC8: // ext 16 1428c5f01b2fSopenharmony_ci case 0xC9: // ext 32 1429c5f01b2fSopenharmony_ci case 0xD4: // fixext 1 1430c5f01b2fSopenharmony_ci case 0xD5: // fixext 2 1431c5f01b2fSopenharmony_ci case 0xD6: // fixext 4 1432c5f01b2fSopenharmony_ci case 0xD7: // fixext 8 1433c5f01b2fSopenharmony_ci case 0xD8: // fixext 16 1434c5f01b2fSopenharmony_ci { 1435c5f01b2fSopenharmony_ci binary_t b; 1436c5f01b2fSopenharmony_ci return get_msgpack_binary(b) && sax->binary(b); 1437c5f01b2fSopenharmony_ci } 1438c5f01b2fSopenharmony_ci 1439c5f01b2fSopenharmony_ci case 0xCA: // float 32 1440c5f01b2fSopenharmony_ci { 1441c5f01b2fSopenharmony_ci float number{}; 1442c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), ""); 1443c5f01b2fSopenharmony_ci } 1444c5f01b2fSopenharmony_ci 1445c5f01b2fSopenharmony_ci case 0xCB: // float 64 1446c5f01b2fSopenharmony_ci { 1447c5f01b2fSopenharmony_ci double number{}; 1448c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), ""); 1449c5f01b2fSopenharmony_ci } 1450c5f01b2fSopenharmony_ci 1451c5f01b2fSopenharmony_ci case 0xCC: // uint 8 1452c5f01b2fSopenharmony_ci { 1453c5f01b2fSopenharmony_ci std::uint8_t number{}; 1454c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); 1455c5f01b2fSopenharmony_ci } 1456c5f01b2fSopenharmony_ci 1457c5f01b2fSopenharmony_ci case 0xCD: // uint 16 1458c5f01b2fSopenharmony_ci { 1459c5f01b2fSopenharmony_ci std::uint16_t number{}; 1460c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); 1461c5f01b2fSopenharmony_ci } 1462c5f01b2fSopenharmony_ci 1463c5f01b2fSopenharmony_ci case 0xCE: // uint 32 1464c5f01b2fSopenharmony_ci { 1465c5f01b2fSopenharmony_ci std::uint32_t number{}; 1466c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); 1467c5f01b2fSopenharmony_ci } 1468c5f01b2fSopenharmony_ci 1469c5f01b2fSopenharmony_ci case 0xCF: // uint 64 1470c5f01b2fSopenharmony_ci { 1471c5f01b2fSopenharmony_ci std::uint64_t number{}; 1472c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); 1473c5f01b2fSopenharmony_ci } 1474c5f01b2fSopenharmony_ci 1475c5f01b2fSopenharmony_ci case 0xD0: // int 8 1476c5f01b2fSopenharmony_ci { 1477c5f01b2fSopenharmony_ci std::int8_t number{}; 1478c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_integer(number); 1479c5f01b2fSopenharmony_ci } 1480c5f01b2fSopenharmony_ci 1481c5f01b2fSopenharmony_ci case 0xD1: // int 16 1482c5f01b2fSopenharmony_ci { 1483c5f01b2fSopenharmony_ci std::int16_t number{}; 1484c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_integer(number); 1485c5f01b2fSopenharmony_ci } 1486c5f01b2fSopenharmony_ci 1487c5f01b2fSopenharmony_ci case 0xD2: // int 32 1488c5f01b2fSopenharmony_ci { 1489c5f01b2fSopenharmony_ci std::int32_t number{}; 1490c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_integer(number); 1491c5f01b2fSopenharmony_ci } 1492c5f01b2fSopenharmony_ci 1493c5f01b2fSopenharmony_ci case 0xD3: // int 64 1494c5f01b2fSopenharmony_ci { 1495c5f01b2fSopenharmony_ci std::int64_t number{}; 1496c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, number) && sax->number_integer(number); 1497c5f01b2fSopenharmony_ci } 1498c5f01b2fSopenharmony_ci 1499c5f01b2fSopenharmony_ci case 0xDC: // array 16 1500c5f01b2fSopenharmony_ci { 1501c5f01b2fSopenharmony_ci std::uint16_t len{}; 1502c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len)); 1503c5f01b2fSopenharmony_ci } 1504c5f01b2fSopenharmony_ci 1505c5f01b2fSopenharmony_ci case 0xDD: // array 32 1506c5f01b2fSopenharmony_ci { 1507c5f01b2fSopenharmony_ci std::uint32_t len{}; 1508c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len)); 1509c5f01b2fSopenharmony_ci } 1510c5f01b2fSopenharmony_ci 1511c5f01b2fSopenharmony_ci case 0xDE: // map 16 1512c5f01b2fSopenharmony_ci { 1513c5f01b2fSopenharmony_ci std::uint16_t len{}; 1514c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len)); 1515c5f01b2fSopenharmony_ci } 1516c5f01b2fSopenharmony_ci 1517c5f01b2fSopenharmony_ci case 0xDF: // map 32 1518c5f01b2fSopenharmony_ci { 1519c5f01b2fSopenharmony_ci std::uint32_t len{}; 1520c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len)); 1521c5f01b2fSopenharmony_ci } 1522c5f01b2fSopenharmony_ci 1523c5f01b2fSopenharmony_ci // negative fixint 1524c5f01b2fSopenharmony_ci case 0xE0: 1525c5f01b2fSopenharmony_ci case 0xE1: 1526c5f01b2fSopenharmony_ci case 0xE2: 1527c5f01b2fSopenharmony_ci case 0xE3: 1528c5f01b2fSopenharmony_ci case 0xE4: 1529c5f01b2fSopenharmony_ci case 0xE5: 1530c5f01b2fSopenharmony_ci case 0xE6: 1531c5f01b2fSopenharmony_ci case 0xE7: 1532c5f01b2fSopenharmony_ci case 0xE8: 1533c5f01b2fSopenharmony_ci case 0xE9: 1534c5f01b2fSopenharmony_ci case 0xEA: 1535c5f01b2fSopenharmony_ci case 0xEB: 1536c5f01b2fSopenharmony_ci case 0xEC: 1537c5f01b2fSopenharmony_ci case 0xED: 1538c5f01b2fSopenharmony_ci case 0xEE: 1539c5f01b2fSopenharmony_ci case 0xEF: 1540c5f01b2fSopenharmony_ci case 0xF0: 1541c5f01b2fSopenharmony_ci case 0xF1: 1542c5f01b2fSopenharmony_ci case 0xF2: 1543c5f01b2fSopenharmony_ci case 0xF3: 1544c5f01b2fSopenharmony_ci case 0xF4: 1545c5f01b2fSopenharmony_ci case 0xF5: 1546c5f01b2fSopenharmony_ci case 0xF6: 1547c5f01b2fSopenharmony_ci case 0xF7: 1548c5f01b2fSopenharmony_ci case 0xF8: 1549c5f01b2fSopenharmony_ci case 0xF9: 1550c5f01b2fSopenharmony_ci case 0xFA: 1551c5f01b2fSopenharmony_ci case 0xFB: 1552c5f01b2fSopenharmony_ci case 0xFC: 1553c5f01b2fSopenharmony_ci case 0xFD: 1554c5f01b2fSopenharmony_ci case 0xFE: 1555c5f01b2fSopenharmony_ci case 0xFF: 1556c5f01b2fSopenharmony_ci return sax->number_integer(static_cast<std::int8_t>(current)); 1557c5f01b2fSopenharmony_ci 1558c5f01b2fSopenharmony_ci default: // anything else 1559c5f01b2fSopenharmony_ci { 1560c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 1561c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 1562c5f01b2fSopenharmony_ci exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr)); 1563c5f01b2fSopenharmony_ci } 1564c5f01b2fSopenharmony_ci } 1565c5f01b2fSopenharmony_ci } 1566c5f01b2fSopenharmony_ci 1567c5f01b2fSopenharmony_ci /*! 1568c5f01b2fSopenharmony_ci @brief reads a MessagePack string 1569c5f01b2fSopenharmony_ci 1570c5f01b2fSopenharmony_ci This function first reads starting bytes to determine the expected 1571c5f01b2fSopenharmony_ci string length and then copies this number of bytes into a string. 1572c5f01b2fSopenharmony_ci 1573c5f01b2fSopenharmony_ci @param[out] result created string 1574c5f01b2fSopenharmony_ci 1575c5f01b2fSopenharmony_ci @return whether string creation completed 1576c5f01b2fSopenharmony_ci */ 1577c5f01b2fSopenharmony_ci bool get_msgpack_string(string_t& result) 1578c5f01b2fSopenharmony_ci { 1579c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) 1580c5f01b2fSopenharmony_ci { 1581c5f01b2fSopenharmony_ci return false; 1582c5f01b2fSopenharmony_ci } 1583c5f01b2fSopenharmony_ci 1584c5f01b2fSopenharmony_ci switch (current) 1585c5f01b2fSopenharmony_ci { 1586c5f01b2fSopenharmony_ci // fixstr 1587c5f01b2fSopenharmony_ci case 0xA0: 1588c5f01b2fSopenharmony_ci case 0xA1: 1589c5f01b2fSopenharmony_ci case 0xA2: 1590c5f01b2fSopenharmony_ci case 0xA3: 1591c5f01b2fSopenharmony_ci case 0xA4: 1592c5f01b2fSopenharmony_ci case 0xA5: 1593c5f01b2fSopenharmony_ci case 0xA6: 1594c5f01b2fSopenharmony_ci case 0xA7: 1595c5f01b2fSopenharmony_ci case 0xA8: 1596c5f01b2fSopenharmony_ci case 0xA9: 1597c5f01b2fSopenharmony_ci case 0xAA: 1598c5f01b2fSopenharmony_ci case 0xAB: 1599c5f01b2fSopenharmony_ci case 0xAC: 1600c5f01b2fSopenharmony_ci case 0xAD: 1601c5f01b2fSopenharmony_ci case 0xAE: 1602c5f01b2fSopenharmony_ci case 0xAF: 1603c5f01b2fSopenharmony_ci case 0xB0: 1604c5f01b2fSopenharmony_ci case 0xB1: 1605c5f01b2fSopenharmony_ci case 0xB2: 1606c5f01b2fSopenharmony_ci case 0xB3: 1607c5f01b2fSopenharmony_ci case 0xB4: 1608c5f01b2fSopenharmony_ci case 0xB5: 1609c5f01b2fSopenharmony_ci case 0xB6: 1610c5f01b2fSopenharmony_ci case 0xB7: 1611c5f01b2fSopenharmony_ci case 0xB8: 1612c5f01b2fSopenharmony_ci case 0xB9: 1613c5f01b2fSopenharmony_ci case 0xBA: 1614c5f01b2fSopenharmony_ci case 0xBB: 1615c5f01b2fSopenharmony_ci case 0xBC: 1616c5f01b2fSopenharmony_ci case 0xBD: 1617c5f01b2fSopenharmony_ci case 0xBE: 1618c5f01b2fSopenharmony_ci case 0xBF: 1619c5f01b2fSopenharmony_ci { 1620c5f01b2fSopenharmony_ci return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result); 1621c5f01b2fSopenharmony_ci } 1622c5f01b2fSopenharmony_ci 1623c5f01b2fSopenharmony_ci case 0xD9: // str 8 1624c5f01b2fSopenharmony_ci { 1625c5f01b2fSopenharmony_ci std::uint8_t len{}; 1626c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); 1627c5f01b2fSopenharmony_ci } 1628c5f01b2fSopenharmony_ci 1629c5f01b2fSopenharmony_ci case 0xDA: // str 16 1630c5f01b2fSopenharmony_ci { 1631c5f01b2fSopenharmony_ci std::uint16_t len{}; 1632c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); 1633c5f01b2fSopenharmony_ci } 1634c5f01b2fSopenharmony_ci 1635c5f01b2fSopenharmony_ci case 0xDB: // str 32 1636c5f01b2fSopenharmony_ci { 1637c5f01b2fSopenharmony_ci std::uint32_t len{}; 1638c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); 1639c5f01b2fSopenharmony_ci } 1640c5f01b2fSopenharmony_ci 1641c5f01b2fSopenharmony_ci default: 1642c5f01b2fSopenharmony_ci { 1643c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 1644c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, 1645c5f01b2fSopenharmony_ci exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr)); 1646c5f01b2fSopenharmony_ci } 1647c5f01b2fSopenharmony_ci } 1648c5f01b2fSopenharmony_ci } 1649c5f01b2fSopenharmony_ci 1650c5f01b2fSopenharmony_ci /*! 1651c5f01b2fSopenharmony_ci @brief reads a MessagePack byte array 1652c5f01b2fSopenharmony_ci 1653c5f01b2fSopenharmony_ci This function first reads starting bytes to determine the expected 1654c5f01b2fSopenharmony_ci byte array length and then copies this number of bytes into a byte array. 1655c5f01b2fSopenharmony_ci 1656c5f01b2fSopenharmony_ci @param[out] result created byte array 1657c5f01b2fSopenharmony_ci 1658c5f01b2fSopenharmony_ci @return whether byte array creation completed 1659c5f01b2fSopenharmony_ci */ 1660c5f01b2fSopenharmony_ci bool get_msgpack_binary(binary_t& result) 1661c5f01b2fSopenharmony_ci { 1662c5f01b2fSopenharmony_ci // helper function to set the subtype 1663c5f01b2fSopenharmony_ci auto assign_and_return_true = [&result](std::int8_t subtype) 1664c5f01b2fSopenharmony_ci { 1665c5f01b2fSopenharmony_ci result.set_subtype(static_cast<std::uint8_t>(subtype)); 1666c5f01b2fSopenharmony_ci return true; 1667c5f01b2fSopenharmony_ci }; 1668c5f01b2fSopenharmony_ci 1669c5f01b2fSopenharmony_ci switch (current) 1670c5f01b2fSopenharmony_ci { 1671c5f01b2fSopenharmony_ci case 0xC4: // bin 8 1672c5f01b2fSopenharmony_ci { 1673c5f01b2fSopenharmony_ci std::uint8_t len{}; 1674c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && 1675c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, len, result); 1676c5f01b2fSopenharmony_ci } 1677c5f01b2fSopenharmony_ci 1678c5f01b2fSopenharmony_ci case 0xC5: // bin 16 1679c5f01b2fSopenharmony_ci { 1680c5f01b2fSopenharmony_ci std::uint16_t len{}; 1681c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && 1682c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, len, result); 1683c5f01b2fSopenharmony_ci } 1684c5f01b2fSopenharmony_ci 1685c5f01b2fSopenharmony_ci case 0xC6: // bin 32 1686c5f01b2fSopenharmony_ci { 1687c5f01b2fSopenharmony_ci std::uint32_t len{}; 1688c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && 1689c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, len, result); 1690c5f01b2fSopenharmony_ci } 1691c5f01b2fSopenharmony_ci 1692c5f01b2fSopenharmony_ci case 0xC7: // ext 8 1693c5f01b2fSopenharmony_ci { 1694c5f01b2fSopenharmony_ci std::uint8_t len{}; 1695c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1696c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && 1697c5f01b2fSopenharmony_ci get_number(input_format_t::msgpack, subtype) && 1698c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, len, result) && 1699c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1700c5f01b2fSopenharmony_ci } 1701c5f01b2fSopenharmony_ci 1702c5f01b2fSopenharmony_ci case 0xC8: // ext 16 1703c5f01b2fSopenharmony_ci { 1704c5f01b2fSopenharmony_ci std::uint16_t len{}; 1705c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1706c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && 1707c5f01b2fSopenharmony_ci get_number(input_format_t::msgpack, subtype) && 1708c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, len, result) && 1709c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1710c5f01b2fSopenharmony_ci } 1711c5f01b2fSopenharmony_ci 1712c5f01b2fSopenharmony_ci case 0xC9: // ext 32 1713c5f01b2fSopenharmony_ci { 1714c5f01b2fSopenharmony_ci std::uint32_t len{}; 1715c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1716c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, len) && 1717c5f01b2fSopenharmony_ci get_number(input_format_t::msgpack, subtype) && 1718c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, len, result) && 1719c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1720c5f01b2fSopenharmony_ci } 1721c5f01b2fSopenharmony_ci 1722c5f01b2fSopenharmony_ci case 0xD4: // fixext 1 1723c5f01b2fSopenharmony_ci { 1724c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1725c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, subtype) && 1726c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, 1, result) && 1727c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1728c5f01b2fSopenharmony_ci } 1729c5f01b2fSopenharmony_ci 1730c5f01b2fSopenharmony_ci case 0xD5: // fixext 2 1731c5f01b2fSopenharmony_ci { 1732c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1733c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, subtype) && 1734c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, 2, result) && 1735c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1736c5f01b2fSopenharmony_ci } 1737c5f01b2fSopenharmony_ci 1738c5f01b2fSopenharmony_ci case 0xD6: // fixext 4 1739c5f01b2fSopenharmony_ci { 1740c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1741c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, subtype) && 1742c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, 4, result) && 1743c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1744c5f01b2fSopenharmony_ci } 1745c5f01b2fSopenharmony_ci 1746c5f01b2fSopenharmony_ci case 0xD7: // fixext 8 1747c5f01b2fSopenharmony_ci { 1748c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1749c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, subtype) && 1750c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, 8, result) && 1751c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1752c5f01b2fSopenharmony_ci } 1753c5f01b2fSopenharmony_ci 1754c5f01b2fSopenharmony_ci case 0xD8: // fixext 16 1755c5f01b2fSopenharmony_ci { 1756c5f01b2fSopenharmony_ci std::int8_t subtype{}; 1757c5f01b2fSopenharmony_ci return get_number(input_format_t::msgpack, subtype) && 1758c5f01b2fSopenharmony_ci get_binary(input_format_t::msgpack, 16, result) && 1759c5f01b2fSopenharmony_ci assign_and_return_true(subtype); 1760c5f01b2fSopenharmony_ci } 1761c5f01b2fSopenharmony_ci 1762c5f01b2fSopenharmony_ci default: // LCOV_EXCL_LINE 1763c5f01b2fSopenharmony_ci return false; // LCOV_EXCL_LINE 1764c5f01b2fSopenharmony_ci } 1765c5f01b2fSopenharmony_ci } 1766c5f01b2fSopenharmony_ci 1767c5f01b2fSopenharmony_ci /*! 1768c5f01b2fSopenharmony_ci @param[in] len the length of the array 1769c5f01b2fSopenharmony_ci @return whether array creation completed 1770c5f01b2fSopenharmony_ci */ 1771c5f01b2fSopenharmony_ci bool get_msgpack_array(const std::size_t len) 1772c5f01b2fSopenharmony_ci { 1773c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) 1774c5f01b2fSopenharmony_ci { 1775c5f01b2fSopenharmony_ci return false; 1776c5f01b2fSopenharmony_ci } 1777c5f01b2fSopenharmony_ci 1778c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < len; ++i) 1779c5f01b2fSopenharmony_ci { 1780c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) 1781c5f01b2fSopenharmony_ci { 1782c5f01b2fSopenharmony_ci return false; 1783c5f01b2fSopenharmony_ci } 1784c5f01b2fSopenharmony_ci } 1785c5f01b2fSopenharmony_ci 1786c5f01b2fSopenharmony_ci return sax->end_array(); 1787c5f01b2fSopenharmony_ci } 1788c5f01b2fSopenharmony_ci 1789c5f01b2fSopenharmony_ci /*! 1790c5f01b2fSopenharmony_ci @param[in] len the length of the object 1791c5f01b2fSopenharmony_ci @return whether object creation completed 1792c5f01b2fSopenharmony_ci */ 1793c5f01b2fSopenharmony_ci bool get_msgpack_object(const std::size_t len) 1794c5f01b2fSopenharmony_ci { 1795c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) 1796c5f01b2fSopenharmony_ci { 1797c5f01b2fSopenharmony_ci return false; 1798c5f01b2fSopenharmony_ci } 1799c5f01b2fSopenharmony_ci 1800c5f01b2fSopenharmony_ci string_t key; 1801c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < len; ++i) 1802c5f01b2fSopenharmony_ci { 1803c5f01b2fSopenharmony_ci get(); 1804c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) 1805c5f01b2fSopenharmony_ci { 1806c5f01b2fSopenharmony_ci return false; 1807c5f01b2fSopenharmony_ci } 1808c5f01b2fSopenharmony_ci 1809c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) 1810c5f01b2fSopenharmony_ci { 1811c5f01b2fSopenharmony_ci return false; 1812c5f01b2fSopenharmony_ci } 1813c5f01b2fSopenharmony_ci key.clear(); 1814c5f01b2fSopenharmony_ci } 1815c5f01b2fSopenharmony_ci 1816c5f01b2fSopenharmony_ci return sax->end_object(); 1817c5f01b2fSopenharmony_ci } 1818c5f01b2fSopenharmony_ci 1819c5f01b2fSopenharmony_ci //////////// 1820c5f01b2fSopenharmony_ci // UBJSON // 1821c5f01b2fSopenharmony_ci //////////// 1822c5f01b2fSopenharmony_ci 1823c5f01b2fSopenharmony_ci /*! 1824c5f01b2fSopenharmony_ci @param[in] get_char whether a new character should be retrieved from the 1825c5f01b2fSopenharmony_ci input (true, default) or whether the last read 1826c5f01b2fSopenharmony_ci character should be considered instead 1827c5f01b2fSopenharmony_ci 1828c5f01b2fSopenharmony_ci @return whether a valid UBJSON value was passed to the SAX parser 1829c5f01b2fSopenharmony_ci */ 1830c5f01b2fSopenharmony_ci bool parse_ubjson_internal(const bool get_char = true) 1831c5f01b2fSopenharmony_ci { 1832c5f01b2fSopenharmony_ci return get_ubjson_value(get_char ? get_ignore_noop() : current); 1833c5f01b2fSopenharmony_ci } 1834c5f01b2fSopenharmony_ci 1835c5f01b2fSopenharmony_ci /*! 1836c5f01b2fSopenharmony_ci @brief reads a UBJSON string 1837c5f01b2fSopenharmony_ci 1838c5f01b2fSopenharmony_ci This function is either called after reading the 'S' byte explicitly 1839c5f01b2fSopenharmony_ci indicating a string, or in case of an object key where the 'S' byte can be 1840c5f01b2fSopenharmony_ci left out. 1841c5f01b2fSopenharmony_ci 1842c5f01b2fSopenharmony_ci @param[out] result created string 1843c5f01b2fSopenharmony_ci @param[in] get_char whether a new character should be retrieved from the 1844c5f01b2fSopenharmony_ci input (true, default) or whether the last read 1845c5f01b2fSopenharmony_ci character should be considered instead 1846c5f01b2fSopenharmony_ci 1847c5f01b2fSopenharmony_ci @return whether string creation completed 1848c5f01b2fSopenharmony_ci */ 1849c5f01b2fSopenharmony_ci bool get_ubjson_string(string_t& result, const bool get_char = true) 1850c5f01b2fSopenharmony_ci { 1851c5f01b2fSopenharmony_ci if (get_char) 1852c5f01b2fSopenharmony_ci { 1853c5f01b2fSopenharmony_ci get(); // TODO(niels): may we ignore N here? 1854c5f01b2fSopenharmony_ci } 1855c5f01b2fSopenharmony_ci 1856c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value"))) 1857c5f01b2fSopenharmony_ci { 1858c5f01b2fSopenharmony_ci return false; 1859c5f01b2fSopenharmony_ci } 1860c5f01b2fSopenharmony_ci 1861c5f01b2fSopenharmony_ci switch (current) 1862c5f01b2fSopenharmony_ci { 1863c5f01b2fSopenharmony_ci case 'U': 1864c5f01b2fSopenharmony_ci { 1865c5f01b2fSopenharmony_ci std::uint8_t len{}; 1866c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1867c5f01b2fSopenharmony_ci } 1868c5f01b2fSopenharmony_ci 1869c5f01b2fSopenharmony_ci case 'i': 1870c5f01b2fSopenharmony_ci { 1871c5f01b2fSopenharmony_ci std::int8_t len{}; 1872c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1873c5f01b2fSopenharmony_ci } 1874c5f01b2fSopenharmony_ci 1875c5f01b2fSopenharmony_ci case 'I': 1876c5f01b2fSopenharmony_ci { 1877c5f01b2fSopenharmony_ci std::int16_t len{}; 1878c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1879c5f01b2fSopenharmony_ci } 1880c5f01b2fSopenharmony_ci 1881c5f01b2fSopenharmony_ci case 'l': 1882c5f01b2fSopenharmony_ci { 1883c5f01b2fSopenharmony_ci std::int32_t len{}; 1884c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1885c5f01b2fSopenharmony_ci } 1886c5f01b2fSopenharmony_ci 1887c5f01b2fSopenharmony_ci case 'L': 1888c5f01b2fSopenharmony_ci { 1889c5f01b2fSopenharmony_ci std::int64_t len{}; 1890c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1891c5f01b2fSopenharmony_ci } 1892c5f01b2fSopenharmony_ci 1893c5f01b2fSopenharmony_ci case 'u': 1894c5f01b2fSopenharmony_ci { 1895c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 1896c5f01b2fSopenharmony_ci { 1897c5f01b2fSopenharmony_ci break; 1898c5f01b2fSopenharmony_ci } 1899c5f01b2fSopenharmony_ci std::uint16_t len{}; 1900c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1901c5f01b2fSopenharmony_ci } 1902c5f01b2fSopenharmony_ci 1903c5f01b2fSopenharmony_ci case 'm': 1904c5f01b2fSopenharmony_ci { 1905c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 1906c5f01b2fSopenharmony_ci { 1907c5f01b2fSopenharmony_ci break; 1908c5f01b2fSopenharmony_ci } 1909c5f01b2fSopenharmony_ci std::uint32_t len{}; 1910c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1911c5f01b2fSopenharmony_ci } 1912c5f01b2fSopenharmony_ci 1913c5f01b2fSopenharmony_ci case 'M': 1914c5f01b2fSopenharmony_ci { 1915c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 1916c5f01b2fSopenharmony_ci { 1917c5f01b2fSopenharmony_ci break; 1918c5f01b2fSopenharmony_ci } 1919c5f01b2fSopenharmony_ci std::uint64_t len{}; 1920c5f01b2fSopenharmony_ci return get_number(input_format, len) && get_string(input_format, len, result); 1921c5f01b2fSopenharmony_ci } 1922c5f01b2fSopenharmony_ci 1923c5f01b2fSopenharmony_ci default: 1924c5f01b2fSopenharmony_ci break; 1925c5f01b2fSopenharmony_ci } 1926c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 1927c5f01b2fSopenharmony_ci std::string message; 1928c5f01b2fSopenharmony_ci 1929c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 1930c5f01b2fSopenharmony_ci { 1931c5f01b2fSopenharmony_ci message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token; 1932c5f01b2fSopenharmony_ci } 1933c5f01b2fSopenharmony_ci else 1934c5f01b2fSopenharmony_ci { 1935c5f01b2fSopenharmony_ci message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token; 1936c5f01b2fSopenharmony_ci } 1937c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr)); 1938c5f01b2fSopenharmony_ci } 1939c5f01b2fSopenharmony_ci 1940c5f01b2fSopenharmony_ci /*! 1941c5f01b2fSopenharmony_ci @param[out] dim an integer vector storing the ND array dimensions 1942c5f01b2fSopenharmony_ci @return whether reading ND array size vector is successful 1943c5f01b2fSopenharmony_ci */ 1944c5f01b2fSopenharmony_ci bool get_ubjson_ndarray_size(std::vector<size_t>& dim) 1945c5f01b2fSopenharmony_ci { 1946c5f01b2fSopenharmony_ci std::pair<std::size_t, char_int_type> size_and_type; 1947c5f01b2fSopenharmony_ci size_t dimlen = 0; 1948c5f01b2fSopenharmony_ci bool no_ndarray = true; 1949c5f01b2fSopenharmony_ci 1950c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray))) 1951c5f01b2fSopenharmony_ci { 1952c5f01b2fSopenharmony_ci return false; 1953c5f01b2fSopenharmony_ci } 1954c5f01b2fSopenharmony_ci 1955c5f01b2fSopenharmony_ci if (size_and_type.first != npos) 1956c5f01b2fSopenharmony_ci { 1957c5f01b2fSopenharmony_ci if (size_and_type.second != 0) 1958c5f01b2fSopenharmony_ci { 1959c5f01b2fSopenharmony_ci if (size_and_type.second != 'N') 1960c5f01b2fSopenharmony_ci { 1961c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 1962c5f01b2fSopenharmony_ci { 1963c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second))) 1964c5f01b2fSopenharmony_ci { 1965c5f01b2fSopenharmony_ci return false; 1966c5f01b2fSopenharmony_ci } 1967c5f01b2fSopenharmony_ci dim.push_back(dimlen); 1968c5f01b2fSopenharmony_ci } 1969c5f01b2fSopenharmony_ci } 1970c5f01b2fSopenharmony_ci } 1971c5f01b2fSopenharmony_ci else 1972c5f01b2fSopenharmony_ci { 1973c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 1974c5f01b2fSopenharmony_ci { 1975c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray))) 1976c5f01b2fSopenharmony_ci { 1977c5f01b2fSopenharmony_ci return false; 1978c5f01b2fSopenharmony_ci } 1979c5f01b2fSopenharmony_ci dim.push_back(dimlen); 1980c5f01b2fSopenharmony_ci } 1981c5f01b2fSopenharmony_ci } 1982c5f01b2fSopenharmony_ci } 1983c5f01b2fSopenharmony_ci else 1984c5f01b2fSopenharmony_ci { 1985c5f01b2fSopenharmony_ci while (current != ']') 1986c5f01b2fSopenharmony_ci { 1987c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current))) 1988c5f01b2fSopenharmony_ci { 1989c5f01b2fSopenharmony_ci return false; 1990c5f01b2fSopenharmony_ci } 1991c5f01b2fSopenharmony_ci dim.push_back(dimlen); 1992c5f01b2fSopenharmony_ci get_ignore_noop(); 1993c5f01b2fSopenharmony_ci } 1994c5f01b2fSopenharmony_ci } 1995c5f01b2fSopenharmony_ci return true; 1996c5f01b2fSopenharmony_ci } 1997c5f01b2fSopenharmony_ci 1998c5f01b2fSopenharmony_ci /*! 1999c5f01b2fSopenharmony_ci @param[out] result determined size 2000c5f01b2fSopenharmony_ci @param[in,out] is_ndarray for input, `true` means already inside an ndarray vector 2001c5f01b2fSopenharmony_ci or ndarray dimension is not allowed; `false` means ndarray 2002c5f01b2fSopenharmony_ci is allowed; for output, `true` means an ndarray is found; 2003c5f01b2fSopenharmony_ci is_ndarray can only return `true` when its initial value 2004c5f01b2fSopenharmony_ci is `false` 2005c5f01b2fSopenharmony_ci @param[in] prefix type marker if already read, otherwise set to 0 2006c5f01b2fSopenharmony_ci 2007c5f01b2fSopenharmony_ci @return whether size determination completed 2008c5f01b2fSopenharmony_ci */ 2009c5f01b2fSopenharmony_ci bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0) 2010c5f01b2fSopenharmony_ci { 2011c5f01b2fSopenharmony_ci if (prefix == 0) 2012c5f01b2fSopenharmony_ci { 2013c5f01b2fSopenharmony_ci prefix = get_ignore_noop(); 2014c5f01b2fSopenharmony_ci } 2015c5f01b2fSopenharmony_ci 2016c5f01b2fSopenharmony_ci switch (prefix) 2017c5f01b2fSopenharmony_ci { 2018c5f01b2fSopenharmony_ci case 'U': 2019c5f01b2fSopenharmony_ci { 2020c5f01b2fSopenharmony_ci std::uint8_t number{}; 2021c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2022c5f01b2fSopenharmony_ci { 2023c5f01b2fSopenharmony_ci return false; 2024c5f01b2fSopenharmony_ci } 2025c5f01b2fSopenharmony_ci result = static_cast<std::size_t>(number); 2026c5f01b2fSopenharmony_ci return true; 2027c5f01b2fSopenharmony_ci } 2028c5f01b2fSopenharmony_ci 2029c5f01b2fSopenharmony_ci case 'i': 2030c5f01b2fSopenharmony_ci { 2031c5f01b2fSopenharmony_ci std::int8_t number{}; 2032c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2033c5f01b2fSopenharmony_ci { 2034c5f01b2fSopenharmony_ci return false; 2035c5f01b2fSopenharmony_ci } 2036c5f01b2fSopenharmony_ci if (number < 0) 2037c5f01b2fSopenharmony_ci { 2038c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, 2039c5f01b2fSopenharmony_ci exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); 2040c5f01b2fSopenharmony_ci } 2041c5f01b2fSopenharmony_ci result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char 2042c5f01b2fSopenharmony_ci return true; 2043c5f01b2fSopenharmony_ci } 2044c5f01b2fSopenharmony_ci 2045c5f01b2fSopenharmony_ci case 'I': 2046c5f01b2fSopenharmony_ci { 2047c5f01b2fSopenharmony_ci std::int16_t number{}; 2048c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2049c5f01b2fSopenharmony_ci { 2050c5f01b2fSopenharmony_ci return false; 2051c5f01b2fSopenharmony_ci } 2052c5f01b2fSopenharmony_ci if (number < 0) 2053c5f01b2fSopenharmony_ci { 2054c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, 2055c5f01b2fSopenharmony_ci exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); 2056c5f01b2fSopenharmony_ci } 2057c5f01b2fSopenharmony_ci result = static_cast<std::size_t>(number); 2058c5f01b2fSopenharmony_ci return true; 2059c5f01b2fSopenharmony_ci } 2060c5f01b2fSopenharmony_ci 2061c5f01b2fSopenharmony_ci case 'l': 2062c5f01b2fSopenharmony_ci { 2063c5f01b2fSopenharmony_ci std::int32_t number{}; 2064c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2065c5f01b2fSopenharmony_ci { 2066c5f01b2fSopenharmony_ci return false; 2067c5f01b2fSopenharmony_ci } 2068c5f01b2fSopenharmony_ci if (number < 0) 2069c5f01b2fSopenharmony_ci { 2070c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, 2071c5f01b2fSopenharmony_ci exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); 2072c5f01b2fSopenharmony_ci } 2073c5f01b2fSopenharmony_ci result = static_cast<std::size_t>(number); 2074c5f01b2fSopenharmony_ci return true; 2075c5f01b2fSopenharmony_ci } 2076c5f01b2fSopenharmony_ci 2077c5f01b2fSopenharmony_ci case 'L': 2078c5f01b2fSopenharmony_ci { 2079c5f01b2fSopenharmony_ci std::int64_t number{}; 2080c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2081c5f01b2fSopenharmony_ci { 2082c5f01b2fSopenharmony_ci return false; 2083c5f01b2fSopenharmony_ci } 2084c5f01b2fSopenharmony_ci if (number < 0) 2085c5f01b2fSopenharmony_ci { 2086c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, 2087c5f01b2fSopenharmony_ci exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); 2088c5f01b2fSopenharmony_ci } 2089c5f01b2fSopenharmony_ci if (!value_in_range_of<std::size_t>(number)) 2090c5f01b2fSopenharmony_ci { 2091c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, 2092c5f01b2fSopenharmony_ci exception_message(input_format, "integer value overflow", "size"), nullptr)); 2093c5f01b2fSopenharmony_ci } 2094c5f01b2fSopenharmony_ci result = static_cast<std::size_t>(number); 2095c5f01b2fSopenharmony_ci return true; 2096c5f01b2fSopenharmony_ci } 2097c5f01b2fSopenharmony_ci 2098c5f01b2fSopenharmony_ci case 'u': 2099c5f01b2fSopenharmony_ci { 2100c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2101c5f01b2fSopenharmony_ci { 2102c5f01b2fSopenharmony_ci break; 2103c5f01b2fSopenharmony_ci } 2104c5f01b2fSopenharmony_ci std::uint16_t number{}; 2105c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2106c5f01b2fSopenharmony_ci { 2107c5f01b2fSopenharmony_ci return false; 2108c5f01b2fSopenharmony_ci } 2109c5f01b2fSopenharmony_ci result = static_cast<std::size_t>(number); 2110c5f01b2fSopenharmony_ci return true; 2111c5f01b2fSopenharmony_ci } 2112c5f01b2fSopenharmony_ci 2113c5f01b2fSopenharmony_ci case 'm': 2114c5f01b2fSopenharmony_ci { 2115c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2116c5f01b2fSopenharmony_ci { 2117c5f01b2fSopenharmony_ci break; 2118c5f01b2fSopenharmony_ci } 2119c5f01b2fSopenharmony_ci std::uint32_t number{}; 2120c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2121c5f01b2fSopenharmony_ci { 2122c5f01b2fSopenharmony_ci return false; 2123c5f01b2fSopenharmony_ci } 2124c5f01b2fSopenharmony_ci result = conditional_static_cast<std::size_t>(number); 2125c5f01b2fSopenharmony_ci return true; 2126c5f01b2fSopenharmony_ci } 2127c5f01b2fSopenharmony_ci 2128c5f01b2fSopenharmony_ci case 'M': 2129c5f01b2fSopenharmony_ci { 2130c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2131c5f01b2fSopenharmony_ci { 2132c5f01b2fSopenharmony_ci break; 2133c5f01b2fSopenharmony_ci } 2134c5f01b2fSopenharmony_ci std::uint64_t number{}; 2135c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) 2136c5f01b2fSopenharmony_ci { 2137c5f01b2fSopenharmony_ci return false; 2138c5f01b2fSopenharmony_ci } 2139c5f01b2fSopenharmony_ci if (!value_in_range_of<std::size_t>(number)) 2140c5f01b2fSopenharmony_ci { 2141c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, 2142c5f01b2fSopenharmony_ci exception_message(input_format, "integer value overflow", "size"), nullptr)); 2143c5f01b2fSopenharmony_ci } 2144c5f01b2fSopenharmony_ci result = detail::conditional_static_cast<std::size_t>(number); 2145c5f01b2fSopenharmony_ci return true; 2146c5f01b2fSopenharmony_ci } 2147c5f01b2fSopenharmony_ci 2148c5f01b2fSopenharmony_ci case '[': 2149c5f01b2fSopenharmony_ci { 2150c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2151c5f01b2fSopenharmony_ci { 2152c5f01b2fSopenharmony_ci break; 2153c5f01b2fSopenharmony_ci } 2154c5f01b2fSopenharmony_ci if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array 2155c5f01b2fSopenharmony_ci { 2156c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimentional vector is not allowed", "size"), nullptr)); 2157c5f01b2fSopenharmony_ci } 2158c5f01b2fSopenharmony_ci std::vector<size_t> dim; 2159c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim))) 2160c5f01b2fSopenharmony_ci { 2161c5f01b2fSopenharmony_ci return false; 2162c5f01b2fSopenharmony_ci } 2163c5f01b2fSopenharmony_ci if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector 2164c5f01b2fSopenharmony_ci { 2165c5f01b2fSopenharmony_ci result = dim.at(dim.size() - 1); 2166c5f01b2fSopenharmony_ci return true; 2167c5f01b2fSopenharmony_ci } 2168c5f01b2fSopenharmony_ci if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format 2169c5f01b2fSopenharmony_ci { 2170c5f01b2fSopenharmony_ci for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container 2171c5f01b2fSopenharmony_ci { 2172c5f01b2fSopenharmony_ci if ( i == 0 ) 2173c5f01b2fSopenharmony_ci { 2174c5f01b2fSopenharmony_ci result = 0; 2175c5f01b2fSopenharmony_ci return true; 2176c5f01b2fSopenharmony_ci } 2177c5f01b2fSopenharmony_ci } 2178c5f01b2fSopenharmony_ci 2179c5f01b2fSopenharmony_ci string_t key = "_ArraySize_"; 2180c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size()))) 2181c5f01b2fSopenharmony_ci { 2182c5f01b2fSopenharmony_ci return false; 2183c5f01b2fSopenharmony_ci } 2184c5f01b2fSopenharmony_ci result = 1; 2185c5f01b2fSopenharmony_ci for (auto i : dim) 2186c5f01b2fSopenharmony_ci { 2187c5f01b2fSopenharmony_ci result *= i; 2188c5f01b2fSopenharmony_ci if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type() 2189c5f01b2fSopenharmony_ci { 2190c5f01b2fSopenharmony_ci 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)); 2191c5f01b2fSopenharmony_ci } 2192c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i)))) 2193c5f01b2fSopenharmony_ci { 2194c5f01b2fSopenharmony_ci return false; 2195c5f01b2fSopenharmony_ci } 2196c5f01b2fSopenharmony_ci } 2197c5f01b2fSopenharmony_ci is_ndarray = true; 2198c5f01b2fSopenharmony_ci return sax->end_array(); 2199c5f01b2fSopenharmony_ci } 2200c5f01b2fSopenharmony_ci result = 0; 2201c5f01b2fSopenharmony_ci return true; 2202c5f01b2fSopenharmony_ci } 2203c5f01b2fSopenharmony_ci 2204c5f01b2fSopenharmony_ci default: 2205c5f01b2fSopenharmony_ci break; 2206c5f01b2fSopenharmony_ci } 2207c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2208c5f01b2fSopenharmony_ci std::string message; 2209c5f01b2fSopenharmony_ci 2210c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2211c5f01b2fSopenharmony_ci { 2212c5f01b2fSopenharmony_ci message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token; 2213c5f01b2fSopenharmony_ci } 2214c5f01b2fSopenharmony_ci else 2215c5f01b2fSopenharmony_ci { 2216c5f01b2fSopenharmony_ci message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token; 2217c5f01b2fSopenharmony_ci } 2218c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr)); 2219c5f01b2fSopenharmony_ci } 2220c5f01b2fSopenharmony_ci 2221c5f01b2fSopenharmony_ci /*! 2222c5f01b2fSopenharmony_ci @brief determine the type and size for a container 2223c5f01b2fSopenharmony_ci 2224c5f01b2fSopenharmony_ci In the optimized UBJSON format, a type and a size can be provided to allow 2225c5f01b2fSopenharmony_ci for a more compact representation. 2226c5f01b2fSopenharmony_ci 2227c5f01b2fSopenharmony_ci @param[out] result pair of the size and the type 2228c5f01b2fSopenharmony_ci @param[in] inside_ndarray whether the parser is parsing an ND array dimensional vector 2229c5f01b2fSopenharmony_ci 2230c5f01b2fSopenharmony_ci @return whether pair creation completed 2231c5f01b2fSopenharmony_ci */ 2232c5f01b2fSopenharmony_ci bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false) 2233c5f01b2fSopenharmony_ci { 2234c5f01b2fSopenharmony_ci result.first = npos; // size 2235c5f01b2fSopenharmony_ci result.second = 0; // type 2236c5f01b2fSopenharmony_ci bool is_ndarray = false; 2237c5f01b2fSopenharmony_ci 2238c5f01b2fSopenharmony_ci get_ignore_noop(); 2239c5f01b2fSopenharmony_ci 2240c5f01b2fSopenharmony_ci if (current == '$') 2241c5f01b2fSopenharmony_ci { 2242c5f01b2fSopenharmony_ci result.second = get(); // must not ignore 'N', because 'N' maybe the type 2243c5f01b2fSopenharmony_ci if (input_format == input_format_t::bjdata 2244c5f01b2fSopenharmony_ci && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second))) 2245c5f01b2fSopenharmony_ci { 2246c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2247c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 2248c5f01b2fSopenharmony_ci exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr)); 2249c5f01b2fSopenharmony_ci } 2250c5f01b2fSopenharmony_ci 2251c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type"))) 2252c5f01b2fSopenharmony_ci { 2253c5f01b2fSopenharmony_ci return false; 2254c5f01b2fSopenharmony_ci } 2255c5f01b2fSopenharmony_ci 2256c5f01b2fSopenharmony_ci get_ignore_noop(); 2257c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(current != '#')) 2258c5f01b2fSopenharmony_ci { 2259c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value"))) 2260c5f01b2fSopenharmony_ci { 2261c5f01b2fSopenharmony_ci return false; 2262c5f01b2fSopenharmony_ci } 2263c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2264c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 2265c5f01b2fSopenharmony_ci exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr)); 2266c5f01b2fSopenharmony_ci } 2267c5f01b2fSopenharmony_ci 2268c5f01b2fSopenharmony_ci bool is_error = get_ubjson_size_value(result.first, is_ndarray); 2269c5f01b2fSopenharmony_ci if (input_format == input_format_t::bjdata && is_ndarray) 2270c5f01b2fSopenharmony_ci { 2271c5f01b2fSopenharmony_ci if (inside_ndarray) 2272c5f01b2fSopenharmony_ci { 2273c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read, 2274c5f01b2fSopenharmony_ci exception_message(input_format, "ndarray can not be recursive", "size"), nullptr)); 2275c5f01b2fSopenharmony_ci } 2276c5f01b2fSopenharmony_ci result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters 2277c5f01b2fSopenharmony_ci } 2278c5f01b2fSopenharmony_ci return is_error; 2279c5f01b2fSopenharmony_ci } 2280c5f01b2fSopenharmony_ci 2281c5f01b2fSopenharmony_ci if (current == '#') 2282c5f01b2fSopenharmony_ci { 2283c5f01b2fSopenharmony_ci bool is_error = get_ubjson_size_value(result.first, is_ndarray); 2284c5f01b2fSopenharmony_ci if (input_format == input_format_t::bjdata && is_ndarray) 2285c5f01b2fSopenharmony_ci { 2286c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read, 2287c5f01b2fSopenharmony_ci exception_message(input_format, "ndarray requires both type and size", "size"), nullptr)); 2288c5f01b2fSopenharmony_ci } 2289c5f01b2fSopenharmony_ci return is_error; 2290c5f01b2fSopenharmony_ci } 2291c5f01b2fSopenharmony_ci 2292c5f01b2fSopenharmony_ci return true; 2293c5f01b2fSopenharmony_ci } 2294c5f01b2fSopenharmony_ci 2295c5f01b2fSopenharmony_ci /*! 2296c5f01b2fSopenharmony_ci @param prefix the previously read or set type prefix 2297c5f01b2fSopenharmony_ci @return whether value creation completed 2298c5f01b2fSopenharmony_ci */ 2299c5f01b2fSopenharmony_ci bool get_ubjson_value(const char_int_type prefix) 2300c5f01b2fSopenharmony_ci { 2301c5f01b2fSopenharmony_ci switch (prefix) 2302c5f01b2fSopenharmony_ci { 2303c5f01b2fSopenharmony_ci case std::char_traits<char_type>::eof(): // EOF 2304c5f01b2fSopenharmony_ci return unexpect_eof(input_format, "value"); 2305c5f01b2fSopenharmony_ci 2306c5f01b2fSopenharmony_ci case 'T': // true 2307c5f01b2fSopenharmony_ci return sax->boolean(true); 2308c5f01b2fSopenharmony_ci case 'F': // false 2309c5f01b2fSopenharmony_ci return sax->boolean(false); 2310c5f01b2fSopenharmony_ci 2311c5f01b2fSopenharmony_ci case 'Z': // null 2312c5f01b2fSopenharmony_ci return sax->null(); 2313c5f01b2fSopenharmony_ci 2314c5f01b2fSopenharmony_ci case 'U': 2315c5f01b2fSopenharmony_ci { 2316c5f01b2fSopenharmony_ci std::uint8_t number{}; 2317c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_unsigned(number); 2318c5f01b2fSopenharmony_ci } 2319c5f01b2fSopenharmony_ci 2320c5f01b2fSopenharmony_ci case 'i': 2321c5f01b2fSopenharmony_ci { 2322c5f01b2fSopenharmony_ci std::int8_t number{}; 2323c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_integer(number); 2324c5f01b2fSopenharmony_ci } 2325c5f01b2fSopenharmony_ci 2326c5f01b2fSopenharmony_ci case 'I': 2327c5f01b2fSopenharmony_ci { 2328c5f01b2fSopenharmony_ci std::int16_t number{}; 2329c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_integer(number); 2330c5f01b2fSopenharmony_ci } 2331c5f01b2fSopenharmony_ci 2332c5f01b2fSopenharmony_ci case 'l': 2333c5f01b2fSopenharmony_ci { 2334c5f01b2fSopenharmony_ci std::int32_t number{}; 2335c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_integer(number); 2336c5f01b2fSopenharmony_ci } 2337c5f01b2fSopenharmony_ci 2338c5f01b2fSopenharmony_ci case 'L': 2339c5f01b2fSopenharmony_ci { 2340c5f01b2fSopenharmony_ci std::int64_t number{}; 2341c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_integer(number); 2342c5f01b2fSopenharmony_ci } 2343c5f01b2fSopenharmony_ci 2344c5f01b2fSopenharmony_ci case 'u': 2345c5f01b2fSopenharmony_ci { 2346c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2347c5f01b2fSopenharmony_ci { 2348c5f01b2fSopenharmony_ci break; 2349c5f01b2fSopenharmony_ci } 2350c5f01b2fSopenharmony_ci std::uint16_t number{}; 2351c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_unsigned(number); 2352c5f01b2fSopenharmony_ci } 2353c5f01b2fSopenharmony_ci 2354c5f01b2fSopenharmony_ci case 'm': 2355c5f01b2fSopenharmony_ci { 2356c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2357c5f01b2fSopenharmony_ci { 2358c5f01b2fSopenharmony_ci break; 2359c5f01b2fSopenharmony_ci } 2360c5f01b2fSopenharmony_ci std::uint32_t number{}; 2361c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_unsigned(number); 2362c5f01b2fSopenharmony_ci } 2363c5f01b2fSopenharmony_ci 2364c5f01b2fSopenharmony_ci case 'M': 2365c5f01b2fSopenharmony_ci { 2366c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2367c5f01b2fSopenharmony_ci { 2368c5f01b2fSopenharmony_ci break; 2369c5f01b2fSopenharmony_ci } 2370c5f01b2fSopenharmony_ci std::uint64_t number{}; 2371c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_unsigned(number); 2372c5f01b2fSopenharmony_ci } 2373c5f01b2fSopenharmony_ci 2374c5f01b2fSopenharmony_ci case 'h': 2375c5f01b2fSopenharmony_ci { 2376c5f01b2fSopenharmony_ci if (input_format != input_format_t::bjdata) 2377c5f01b2fSopenharmony_ci { 2378c5f01b2fSopenharmony_ci break; 2379c5f01b2fSopenharmony_ci } 2380c5f01b2fSopenharmony_ci const auto byte1_raw = get(); 2381c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) 2382c5f01b2fSopenharmony_ci { 2383c5f01b2fSopenharmony_ci return false; 2384c5f01b2fSopenharmony_ci } 2385c5f01b2fSopenharmony_ci const auto byte2_raw = get(); 2386c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) 2387c5f01b2fSopenharmony_ci { 2388c5f01b2fSopenharmony_ci return false; 2389c5f01b2fSopenharmony_ci } 2390c5f01b2fSopenharmony_ci 2391c5f01b2fSopenharmony_ci const auto byte1 = static_cast<unsigned char>(byte1_raw); 2392c5f01b2fSopenharmony_ci const auto byte2 = static_cast<unsigned char>(byte2_raw); 2393c5f01b2fSopenharmony_ci 2394c5f01b2fSopenharmony_ci // code from RFC 7049, Appendix D, Figure 3: 2395c5f01b2fSopenharmony_ci // As half-precision floating-point numbers were only added 2396c5f01b2fSopenharmony_ci // to IEEE 754 in 2008, today's programming platforms often 2397c5f01b2fSopenharmony_ci // still only have limited support for them. It is very 2398c5f01b2fSopenharmony_ci // easy to include at least decoding support for them even 2399c5f01b2fSopenharmony_ci // without such support. An example of a small decoder for 2400c5f01b2fSopenharmony_ci // half-precision floating-point numbers in the C language 2401c5f01b2fSopenharmony_ci // is shown in Fig. 3. 2402c5f01b2fSopenharmony_ci const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1); 2403c5f01b2fSopenharmony_ci const double val = [&half] 2404c5f01b2fSopenharmony_ci { 2405c5f01b2fSopenharmony_ci const int exp = (half >> 10u) & 0x1Fu; 2406c5f01b2fSopenharmony_ci const unsigned int mant = half & 0x3FFu; 2407c5f01b2fSopenharmony_ci JSON_ASSERT(0 <= exp&& exp <= 32); 2408c5f01b2fSopenharmony_ci JSON_ASSERT(mant <= 1024); 2409c5f01b2fSopenharmony_ci switch (exp) 2410c5f01b2fSopenharmony_ci { 2411c5f01b2fSopenharmony_ci case 0: 2412c5f01b2fSopenharmony_ci return std::ldexp(mant, -24); 2413c5f01b2fSopenharmony_ci case 31: 2414c5f01b2fSopenharmony_ci return (mant == 0) 2415c5f01b2fSopenharmony_ci ? std::numeric_limits<double>::infinity() 2416c5f01b2fSopenharmony_ci : std::numeric_limits<double>::quiet_NaN(); 2417c5f01b2fSopenharmony_ci default: 2418c5f01b2fSopenharmony_ci return std::ldexp(mant + 1024, exp - 25); 2419c5f01b2fSopenharmony_ci } 2420c5f01b2fSopenharmony_ci }(); 2421c5f01b2fSopenharmony_ci return sax->number_float((half & 0x8000u) != 0 2422c5f01b2fSopenharmony_ci ? static_cast<number_float_t>(-val) 2423c5f01b2fSopenharmony_ci : static_cast<number_float_t>(val), ""); 2424c5f01b2fSopenharmony_ci } 2425c5f01b2fSopenharmony_ci 2426c5f01b2fSopenharmony_ci case 'd': 2427c5f01b2fSopenharmony_ci { 2428c5f01b2fSopenharmony_ci float number{}; 2429c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), ""); 2430c5f01b2fSopenharmony_ci } 2431c5f01b2fSopenharmony_ci 2432c5f01b2fSopenharmony_ci case 'D': 2433c5f01b2fSopenharmony_ci { 2434c5f01b2fSopenharmony_ci double number{}; 2435c5f01b2fSopenharmony_ci return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), ""); 2436c5f01b2fSopenharmony_ci } 2437c5f01b2fSopenharmony_ci 2438c5f01b2fSopenharmony_ci case 'H': 2439c5f01b2fSopenharmony_ci { 2440c5f01b2fSopenharmony_ci return get_ubjson_high_precision_number(); 2441c5f01b2fSopenharmony_ci } 2442c5f01b2fSopenharmony_ci 2443c5f01b2fSopenharmony_ci case 'C': // char 2444c5f01b2fSopenharmony_ci { 2445c5f01b2fSopenharmony_ci get(); 2446c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char"))) 2447c5f01b2fSopenharmony_ci { 2448c5f01b2fSopenharmony_ci return false; 2449c5f01b2fSopenharmony_ci } 2450c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(current > 127)) 2451c5f01b2fSopenharmony_ci { 2452c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2453c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, 2454c5f01b2fSopenharmony_ci exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr)); 2455c5f01b2fSopenharmony_ci } 2456c5f01b2fSopenharmony_ci string_t s(1, static_cast<typename string_t::value_type>(current)); 2457c5f01b2fSopenharmony_ci return sax->string(s); 2458c5f01b2fSopenharmony_ci } 2459c5f01b2fSopenharmony_ci 2460c5f01b2fSopenharmony_ci case 'S': // string 2461c5f01b2fSopenharmony_ci { 2462c5f01b2fSopenharmony_ci string_t s; 2463c5f01b2fSopenharmony_ci return get_ubjson_string(s) && sax->string(s); 2464c5f01b2fSopenharmony_ci } 2465c5f01b2fSopenharmony_ci 2466c5f01b2fSopenharmony_ci case '[': // array 2467c5f01b2fSopenharmony_ci return get_ubjson_array(); 2468c5f01b2fSopenharmony_ci 2469c5f01b2fSopenharmony_ci case '{': // object 2470c5f01b2fSopenharmony_ci return get_ubjson_object(); 2471c5f01b2fSopenharmony_ci 2472c5f01b2fSopenharmony_ci default: // anything else 2473c5f01b2fSopenharmony_ci break; 2474c5f01b2fSopenharmony_ci } 2475c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2476c5f01b2fSopenharmony_ci 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)); 2477c5f01b2fSopenharmony_ci } 2478c5f01b2fSopenharmony_ci 2479c5f01b2fSopenharmony_ci /*! 2480c5f01b2fSopenharmony_ci @return whether array creation completed 2481c5f01b2fSopenharmony_ci */ 2482c5f01b2fSopenharmony_ci bool get_ubjson_array() 2483c5f01b2fSopenharmony_ci { 2484c5f01b2fSopenharmony_ci std::pair<std::size_t, char_int_type> size_and_type; 2485c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) 2486c5f01b2fSopenharmony_ci { 2487c5f01b2fSopenharmony_ci return false; 2488c5f01b2fSopenharmony_ci } 2489c5f01b2fSopenharmony_ci 2490c5f01b2fSopenharmony_ci // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata): 2491c5f01b2fSopenharmony_ci // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]} 2492c5f01b2fSopenharmony_ci 2493c5f01b2fSopenharmony_ci if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0) 2494c5f01b2fSopenharmony_ci { 2495c5f01b2fSopenharmony_ci size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker 2496c5f01b2fSopenharmony_ci 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) 2497c5f01b2fSopenharmony_ci { 2498c5f01b2fSopenharmony_ci return p.first < t; 2499c5f01b2fSopenharmony_ci }); 2500c5f01b2fSopenharmony_ci string_t key = "_ArrayType_"; 2501c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second)) 2502c5f01b2fSopenharmony_ci { 2503c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2504c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 2505c5f01b2fSopenharmony_ci exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr)); 2506c5f01b2fSopenharmony_ci } 2507c5f01b2fSopenharmony_ci 2508c5f01b2fSopenharmony_ci string_t type = it->second; // sax->string() takes a reference 2509c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type))) 2510c5f01b2fSopenharmony_ci { 2511c5f01b2fSopenharmony_ci return false; 2512c5f01b2fSopenharmony_ci } 2513c5f01b2fSopenharmony_ci 2514c5f01b2fSopenharmony_ci if (size_and_type.second == 'C') 2515c5f01b2fSopenharmony_ci { 2516c5f01b2fSopenharmony_ci size_and_type.second = 'U'; 2517c5f01b2fSopenharmony_ci } 2518c5f01b2fSopenharmony_ci 2519c5f01b2fSopenharmony_ci key = "_ArrayData_"; 2520c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) )) 2521c5f01b2fSopenharmony_ci { 2522c5f01b2fSopenharmony_ci return false; 2523c5f01b2fSopenharmony_ci } 2524c5f01b2fSopenharmony_ci 2525c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 2526c5f01b2fSopenharmony_ci { 2527c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) 2528c5f01b2fSopenharmony_ci { 2529c5f01b2fSopenharmony_ci return false; 2530c5f01b2fSopenharmony_ci } 2531c5f01b2fSopenharmony_ci } 2532c5f01b2fSopenharmony_ci 2533c5f01b2fSopenharmony_ci return (sax->end_array() && sax->end_object()); 2534c5f01b2fSopenharmony_ci } 2535c5f01b2fSopenharmony_ci 2536c5f01b2fSopenharmony_ci if (size_and_type.first != npos) 2537c5f01b2fSopenharmony_ci { 2538c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) 2539c5f01b2fSopenharmony_ci { 2540c5f01b2fSopenharmony_ci return false; 2541c5f01b2fSopenharmony_ci } 2542c5f01b2fSopenharmony_ci 2543c5f01b2fSopenharmony_ci if (size_and_type.second != 0) 2544c5f01b2fSopenharmony_ci { 2545c5f01b2fSopenharmony_ci if (size_and_type.second != 'N') 2546c5f01b2fSopenharmony_ci { 2547c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 2548c5f01b2fSopenharmony_ci { 2549c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) 2550c5f01b2fSopenharmony_ci { 2551c5f01b2fSopenharmony_ci return false; 2552c5f01b2fSopenharmony_ci } 2553c5f01b2fSopenharmony_ci } 2554c5f01b2fSopenharmony_ci } 2555c5f01b2fSopenharmony_ci } 2556c5f01b2fSopenharmony_ci else 2557c5f01b2fSopenharmony_ci { 2558c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 2559c5f01b2fSopenharmony_ci { 2560c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) 2561c5f01b2fSopenharmony_ci { 2562c5f01b2fSopenharmony_ci return false; 2563c5f01b2fSopenharmony_ci } 2564c5f01b2fSopenharmony_ci } 2565c5f01b2fSopenharmony_ci } 2566c5f01b2fSopenharmony_ci } 2567c5f01b2fSopenharmony_ci else 2568c5f01b2fSopenharmony_ci { 2569c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1)))) 2570c5f01b2fSopenharmony_ci { 2571c5f01b2fSopenharmony_ci return false; 2572c5f01b2fSopenharmony_ci } 2573c5f01b2fSopenharmony_ci 2574c5f01b2fSopenharmony_ci while (current != ']') 2575c5f01b2fSopenharmony_ci { 2576c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) 2577c5f01b2fSopenharmony_ci { 2578c5f01b2fSopenharmony_ci return false; 2579c5f01b2fSopenharmony_ci } 2580c5f01b2fSopenharmony_ci get_ignore_noop(); 2581c5f01b2fSopenharmony_ci } 2582c5f01b2fSopenharmony_ci } 2583c5f01b2fSopenharmony_ci 2584c5f01b2fSopenharmony_ci return sax->end_array(); 2585c5f01b2fSopenharmony_ci } 2586c5f01b2fSopenharmony_ci 2587c5f01b2fSopenharmony_ci /*! 2588c5f01b2fSopenharmony_ci @return whether object creation completed 2589c5f01b2fSopenharmony_ci */ 2590c5f01b2fSopenharmony_ci bool get_ubjson_object() 2591c5f01b2fSopenharmony_ci { 2592c5f01b2fSopenharmony_ci std::pair<std::size_t, char_int_type> size_and_type; 2593c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) 2594c5f01b2fSopenharmony_ci { 2595c5f01b2fSopenharmony_ci return false; 2596c5f01b2fSopenharmony_ci } 2597c5f01b2fSopenharmony_ci 2598c5f01b2fSopenharmony_ci // do not accept ND-array size in objects in BJData 2599c5f01b2fSopenharmony_ci if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0) 2600c5f01b2fSopenharmony_ci { 2601c5f01b2fSopenharmony_ci auto last_token = get_token_string(); 2602c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, 2603c5f01b2fSopenharmony_ci exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr)); 2604c5f01b2fSopenharmony_ci } 2605c5f01b2fSopenharmony_ci 2606c5f01b2fSopenharmony_ci string_t key; 2607c5f01b2fSopenharmony_ci if (size_and_type.first != npos) 2608c5f01b2fSopenharmony_ci { 2609c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) 2610c5f01b2fSopenharmony_ci { 2611c5f01b2fSopenharmony_ci return false; 2612c5f01b2fSopenharmony_ci } 2613c5f01b2fSopenharmony_ci 2614c5f01b2fSopenharmony_ci if (size_and_type.second != 0) 2615c5f01b2fSopenharmony_ci { 2616c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 2617c5f01b2fSopenharmony_ci { 2618c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) 2619c5f01b2fSopenharmony_ci { 2620c5f01b2fSopenharmony_ci return false; 2621c5f01b2fSopenharmony_ci } 2622c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) 2623c5f01b2fSopenharmony_ci { 2624c5f01b2fSopenharmony_ci return false; 2625c5f01b2fSopenharmony_ci } 2626c5f01b2fSopenharmony_ci key.clear(); 2627c5f01b2fSopenharmony_ci } 2628c5f01b2fSopenharmony_ci } 2629c5f01b2fSopenharmony_ci else 2630c5f01b2fSopenharmony_ci { 2631c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size_and_type.first; ++i) 2632c5f01b2fSopenharmony_ci { 2633c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) 2634c5f01b2fSopenharmony_ci { 2635c5f01b2fSopenharmony_ci return false; 2636c5f01b2fSopenharmony_ci } 2637c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) 2638c5f01b2fSopenharmony_ci { 2639c5f01b2fSopenharmony_ci return false; 2640c5f01b2fSopenharmony_ci } 2641c5f01b2fSopenharmony_ci key.clear(); 2642c5f01b2fSopenharmony_ci } 2643c5f01b2fSopenharmony_ci } 2644c5f01b2fSopenharmony_ci } 2645c5f01b2fSopenharmony_ci else 2646c5f01b2fSopenharmony_ci { 2647c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1)))) 2648c5f01b2fSopenharmony_ci { 2649c5f01b2fSopenharmony_ci return false; 2650c5f01b2fSopenharmony_ci } 2651c5f01b2fSopenharmony_ci 2652c5f01b2fSopenharmony_ci while (current != '}') 2653c5f01b2fSopenharmony_ci { 2654c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) 2655c5f01b2fSopenharmony_ci { 2656c5f01b2fSopenharmony_ci return false; 2657c5f01b2fSopenharmony_ci } 2658c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) 2659c5f01b2fSopenharmony_ci { 2660c5f01b2fSopenharmony_ci return false; 2661c5f01b2fSopenharmony_ci } 2662c5f01b2fSopenharmony_ci get_ignore_noop(); 2663c5f01b2fSopenharmony_ci key.clear(); 2664c5f01b2fSopenharmony_ci } 2665c5f01b2fSopenharmony_ci } 2666c5f01b2fSopenharmony_ci 2667c5f01b2fSopenharmony_ci return sax->end_object(); 2668c5f01b2fSopenharmony_ci } 2669c5f01b2fSopenharmony_ci 2670c5f01b2fSopenharmony_ci // Note, no reader for UBJSON binary types is implemented because they do 2671c5f01b2fSopenharmony_ci // not exist 2672c5f01b2fSopenharmony_ci 2673c5f01b2fSopenharmony_ci bool get_ubjson_high_precision_number() 2674c5f01b2fSopenharmony_ci { 2675c5f01b2fSopenharmony_ci // get size of following number string 2676c5f01b2fSopenharmony_ci std::size_t size{}; 2677c5f01b2fSopenharmony_ci bool no_ndarray = true; 2678c5f01b2fSopenharmony_ci auto res = get_ubjson_size_value(size, no_ndarray); 2679c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!res)) 2680c5f01b2fSopenharmony_ci { 2681c5f01b2fSopenharmony_ci return res; 2682c5f01b2fSopenharmony_ci } 2683c5f01b2fSopenharmony_ci 2684c5f01b2fSopenharmony_ci // get number string 2685c5f01b2fSopenharmony_ci std::vector<char> number_vector; 2686c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < size; ++i) 2687c5f01b2fSopenharmony_ci { 2688c5f01b2fSopenharmony_ci get(); 2689c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) 2690c5f01b2fSopenharmony_ci { 2691c5f01b2fSopenharmony_ci return false; 2692c5f01b2fSopenharmony_ci } 2693c5f01b2fSopenharmony_ci number_vector.push_back(static_cast<char>(current)); 2694c5f01b2fSopenharmony_ci } 2695c5f01b2fSopenharmony_ci 2696c5f01b2fSopenharmony_ci // parse number string 2697c5f01b2fSopenharmony_ci using ia_type = decltype(detail::input_adapter(number_vector)); 2698c5f01b2fSopenharmony_ci auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false); 2699c5f01b2fSopenharmony_ci const auto result_number = number_lexer.scan(); 2700c5f01b2fSopenharmony_ci const auto number_string = number_lexer.get_token_string(); 2701c5f01b2fSopenharmony_ci const auto result_remainder = number_lexer.scan(); 2702c5f01b2fSopenharmony_ci 2703c5f01b2fSopenharmony_ci using token_type = typename detail::lexer_base<BasicJsonType>::token_type; 2704c5f01b2fSopenharmony_ci 2705c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) 2706c5f01b2fSopenharmony_ci { 2707c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, 2708c5f01b2fSopenharmony_ci exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr)); 2709c5f01b2fSopenharmony_ci } 2710c5f01b2fSopenharmony_ci 2711c5f01b2fSopenharmony_ci switch (result_number) 2712c5f01b2fSopenharmony_ci { 2713c5f01b2fSopenharmony_ci case token_type::value_integer: 2714c5f01b2fSopenharmony_ci return sax->number_integer(number_lexer.get_number_integer()); 2715c5f01b2fSopenharmony_ci case token_type::value_unsigned: 2716c5f01b2fSopenharmony_ci return sax->number_unsigned(number_lexer.get_number_unsigned()); 2717c5f01b2fSopenharmony_ci case token_type::value_float: 2718c5f01b2fSopenharmony_ci return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); 2719c5f01b2fSopenharmony_ci case token_type::uninitialized: 2720c5f01b2fSopenharmony_ci case token_type::literal_true: 2721c5f01b2fSopenharmony_ci case token_type::literal_false: 2722c5f01b2fSopenharmony_ci case token_type::literal_null: 2723c5f01b2fSopenharmony_ci case token_type::value_string: 2724c5f01b2fSopenharmony_ci case token_type::begin_array: 2725c5f01b2fSopenharmony_ci case token_type::begin_object: 2726c5f01b2fSopenharmony_ci case token_type::end_array: 2727c5f01b2fSopenharmony_ci case token_type::end_object: 2728c5f01b2fSopenharmony_ci case token_type::name_separator: 2729c5f01b2fSopenharmony_ci case token_type::value_separator: 2730c5f01b2fSopenharmony_ci case token_type::parse_error: 2731c5f01b2fSopenharmony_ci case token_type::end_of_input: 2732c5f01b2fSopenharmony_ci case token_type::literal_or_value: 2733c5f01b2fSopenharmony_ci default: 2734c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, 2735c5f01b2fSopenharmony_ci exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr)); 2736c5f01b2fSopenharmony_ci } 2737c5f01b2fSopenharmony_ci } 2738c5f01b2fSopenharmony_ci 2739c5f01b2fSopenharmony_ci /////////////////////// 2740c5f01b2fSopenharmony_ci // Utility functions // 2741c5f01b2fSopenharmony_ci /////////////////////// 2742c5f01b2fSopenharmony_ci 2743c5f01b2fSopenharmony_ci /*! 2744c5f01b2fSopenharmony_ci @brief get next character from the input 2745c5f01b2fSopenharmony_ci 2746c5f01b2fSopenharmony_ci This function provides the interface to the used input adapter. It does 2747c5f01b2fSopenharmony_ci not throw in case the input reached EOF, but returns a -'ve valued 2748c5f01b2fSopenharmony_ci `std::char_traits<char_type>::eof()` in that case. 2749c5f01b2fSopenharmony_ci 2750c5f01b2fSopenharmony_ci @return character read from the input 2751c5f01b2fSopenharmony_ci */ 2752c5f01b2fSopenharmony_ci char_int_type get() 2753c5f01b2fSopenharmony_ci { 2754c5f01b2fSopenharmony_ci ++chars_read; 2755c5f01b2fSopenharmony_ci return current = ia.get_character(); 2756c5f01b2fSopenharmony_ci } 2757c5f01b2fSopenharmony_ci 2758c5f01b2fSopenharmony_ci /*! 2759c5f01b2fSopenharmony_ci @return character read from the input after ignoring all 'N' entries 2760c5f01b2fSopenharmony_ci */ 2761c5f01b2fSopenharmony_ci char_int_type get_ignore_noop() 2762c5f01b2fSopenharmony_ci { 2763c5f01b2fSopenharmony_ci do 2764c5f01b2fSopenharmony_ci { 2765c5f01b2fSopenharmony_ci get(); 2766c5f01b2fSopenharmony_ci } 2767c5f01b2fSopenharmony_ci while (current == 'N'); 2768c5f01b2fSopenharmony_ci 2769c5f01b2fSopenharmony_ci return current; 2770c5f01b2fSopenharmony_ci } 2771c5f01b2fSopenharmony_ci 2772c5f01b2fSopenharmony_ci /* 2773c5f01b2fSopenharmony_ci @brief read a number from the input 2774c5f01b2fSopenharmony_ci 2775c5f01b2fSopenharmony_ci @tparam NumberType the type of the number 2776c5f01b2fSopenharmony_ci @param[in] format the current format (for diagnostics) 2777c5f01b2fSopenharmony_ci @param[out] result number of type @a NumberType 2778c5f01b2fSopenharmony_ci 2779c5f01b2fSopenharmony_ci @return whether conversion completed 2780c5f01b2fSopenharmony_ci 2781c5f01b2fSopenharmony_ci @note This function needs to respect the system's endianness, because 2782c5f01b2fSopenharmony_ci bytes in CBOR, MessagePack, and UBJSON are stored in network order 2783c5f01b2fSopenharmony_ci (big endian) and therefore need reordering on little endian systems. 2784c5f01b2fSopenharmony_ci On the other hand, BSON and BJData use little endian and should reorder 2785c5f01b2fSopenharmony_ci on big endian systems. 2786c5f01b2fSopenharmony_ci */ 2787c5f01b2fSopenharmony_ci template<typename NumberType, bool InputIsLittleEndian = false> 2788c5f01b2fSopenharmony_ci bool get_number(const input_format_t format, NumberType& result) 2789c5f01b2fSopenharmony_ci { 2790c5f01b2fSopenharmony_ci // step 1: read input into array with system's byte order 2791c5f01b2fSopenharmony_ci std::array<std::uint8_t, sizeof(NumberType)> vec{}; 2792c5f01b2fSopenharmony_ci for (std::size_t i = 0; i < sizeof(NumberType); ++i) 2793c5f01b2fSopenharmony_ci { 2794c5f01b2fSopenharmony_ci get(); 2795c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) 2796c5f01b2fSopenharmony_ci { 2797c5f01b2fSopenharmony_ci return false; 2798c5f01b2fSopenharmony_ci } 2799c5f01b2fSopenharmony_ci 2800c5f01b2fSopenharmony_ci // reverse byte order prior to conversion if necessary 2801c5f01b2fSopenharmony_ci if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata)) 2802c5f01b2fSopenharmony_ci { 2803c5f01b2fSopenharmony_ci vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current); 2804c5f01b2fSopenharmony_ci } 2805c5f01b2fSopenharmony_ci else 2806c5f01b2fSopenharmony_ci { 2807c5f01b2fSopenharmony_ci vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE 2808c5f01b2fSopenharmony_ci } 2809c5f01b2fSopenharmony_ci } 2810c5f01b2fSopenharmony_ci 2811c5f01b2fSopenharmony_ci // step 2: convert array into number of type T and return 2812c5f01b2fSopenharmony_ci std::memcpy(&result, vec.data(), sizeof(NumberType)); 2813c5f01b2fSopenharmony_ci return true; 2814c5f01b2fSopenharmony_ci } 2815c5f01b2fSopenharmony_ci 2816c5f01b2fSopenharmony_ci /*! 2817c5f01b2fSopenharmony_ci @brief create a string by reading characters from the input 2818c5f01b2fSopenharmony_ci 2819c5f01b2fSopenharmony_ci @tparam NumberType the type of the number 2820c5f01b2fSopenharmony_ci @param[in] format the current format (for diagnostics) 2821c5f01b2fSopenharmony_ci @param[in] len number of characters to read 2822c5f01b2fSopenharmony_ci @param[out] result string created by reading @a len bytes 2823c5f01b2fSopenharmony_ci 2824c5f01b2fSopenharmony_ci @return whether string creation completed 2825c5f01b2fSopenharmony_ci 2826c5f01b2fSopenharmony_ci @note We can not reserve @a len bytes for the result, because @a len 2827c5f01b2fSopenharmony_ci may be too large. Usually, @ref unexpect_eof() detects the end of 2828c5f01b2fSopenharmony_ci the input before we run out of string memory. 2829c5f01b2fSopenharmony_ci */ 2830c5f01b2fSopenharmony_ci template<typename NumberType> 2831c5f01b2fSopenharmony_ci bool get_string(const input_format_t format, 2832c5f01b2fSopenharmony_ci const NumberType len, 2833c5f01b2fSopenharmony_ci string_t& result) 2834c5f01b2fSopenharmony_ci { 2835c5f01b2fSopenharmony_ci bool success = true; 2836c5f01b2fSopenharmony_ci for (NumberType i = 0; i < len; i++) 2837c5f01b2fSopenharmony_ci { 2838c5f01b2fSopenharmony_ci get(); 2839c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) 2840c5f01b2fSopenharmony_ci { 2841c5f01b2fSopenharmony_ci success = false; 2842c5f01b2fSopenharmony_ci break; 2843c5f01b2fSopenharmony_ci } 2844c5f01b2fSopenharmony_ci result.push_back(static_cast<typename string_t::value_type>(current)); 2845c5f01b2fSopenharmony_ci } 2846c5f01b2fSopenharmony_ci return success; 2847c5f01b2fSopenharmony_ci } 2848c5f01b2fSopenharmony_ci 2849c5f01b2fSopenharmony_ci /*! 2850c5f01b2fSopenharmony_ci @brief create a byte array by reading bytes from the input 2851c5f01b2fSopenharmony_ci 2852c5f01b2fSopenharmony_ci @tparam NumberType the type of the number 2853c5f01b2fSopenharmony_ci @param[in] format the current format (for diagnostics) 2854c5f01b2fSopenharmony_ci @param[in] len number of bytes to read 2855c5f01b2fSopenharmony_ci @param[out] result byte array created by reading @a len bytes 2856c5f01b2fSopenharmony_ci 2857c5f01b2fSopenharmony_ci @return whether byte array creation completed 2858c5f01b2fSopenharmony_ci 2859c5f01b2fSopenharmony_ci @note We can not reserve @a len bytes for the result, because @a len 2860c5f01b2fSopenharmony_ci may be too large. Usually, @ref unexpect_eof() detects the end of 2861c5f01b2fSopenharmony_ci the input before we run out of memory. 2862c5f01b2fSopenharmony_ci */ 2863c5f01b2fSopenharmony_ci template<typename NumberType> 2864c5f01b2fSopenharmony_ci bool get_binary(const input_format_t format, 2865c5f01b2fSopenharmony_ci const NumberType len, 2866c5f01b2fSopenharmony_ci binary_t& result) 2867c5f01b2fSopenharmony_ci { 2868c5f01b2fSopenharmony_ci bool success = true; 2869c5f01b2fSopenharmony_ci for (NumberType i = 0; i < len; i++) 2870c5f01b2fSopenharmony_ci { 2871c5f01b2fSopenharmony_ci get(); 2872c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) 2873c5f01b2fSopenharmony_ci { 2874c5f01b2fSopenharmony_ci success = false; 2875c5f01b2fSopenharmony_ci break; 2876c5f01b2fSopenharmony_ci } 2877c5f01b2fSopenharmony_ci result.push_back(static_cast<std::uint8_t>(current)); 2878c5f01b2fSopenharmony_ci } 2879c5f01b2fSopenharmony_ci return success; 2880c5f01b2fSopenharmony_ci } 2881c5f01b2fSopenharmony_ci 2882c5f01b2fSopenharmony_ci /*! 2883c5f01b2fSopenharmony_ci @param[in] format the current format (for diagnostics) 2884c5f01b2fSopenharmony_ci @param[in] context further context information (for diagnostics) 2885c5f01b2fSopenharmony_ci @return whether the last read character is not EOF 2886c5f01b2fSopenharmony_ci */ 2887c5f01b2fSopenharmony_ci JSON_HEDLEY_NON_NULL(3) 2888c5f01b2fSopenharmony_ci bool unexpect_eof(const input_format_t format, const char* context) const 2889c5f01b2fSopenharmony_ci { 2890c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof())) 2891c5f01b2fSopenharmony_ci { 2892c5f01b2fSopenharmony_ci return sax->parse_error(chars_read, "<end of file>", 2893c5f01b2fSopenharmony_ci parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr)); 2894c5f01b2fSopenharmony_ci } 2895c5f01b2fSopenharmony_ci return true; 2896c5f01b2fSopenharmony_ci } 2897c5f01b2fSopenharmony_ci 2898c5f01b2fSopenharmony_ci /*! 2899c5f01b2fSopenharmony_ci @return a string representation of the last read byte 2900c5f01b2fSopenharmony_ci */ 2901c5f01b2fSopenharmony_ci std::string get_token_string() const 2902c5f01b2fSopenharmony_ci { 2903c5f01b2fSopenharmony_ci std::array<char, 3> cr{{}}; 2904c5f01b2fSopenharmony_ci static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) 2905c5f01b2fSopenharmony_ci return std::string{cr.data()}; 2906c5f01b2fSopenharmony_ci } 2907c5f01b2fSopenharmony_ci 2908c5f01b2fSopenharmony_ci /*! 2909c5f01b2fSopenharmony_ci @param[in] format the current format 2910c5f01b2fSopenharmony_ci @param[in] detail a detailed error message 2911c5f01b2fSopenharmony_ci @param[in] context further context information 2912c5f01b2fSopenharmony_ci @return a message string to use in the parse_error exceptions 2913c5f01b2fSopenharmony_ci */ 2914c5f01b2fSopenharmony_ci std::string exception_message(const input_format_t format, 2915c5f01b2fSopenharmony_ci const std::string& detail, 2916c5f01b2fSopenharmony_ci const std::string& context) const 2917c5f01b2fSopenharmony_ci { 2918c5f01b2fSopenharmony_ci std::string error_msg = "syntax error while parsing "; 2919c5f01b2fSopenharmony_ci 2920c5f01b2fSopenharmony_ci switch (format) 2921c5f01b2fSopenharmony_ci { 2922c5f01b2fSopenharmony_ci case input_format_t::cbor: 2923c5f01b2fSopenharmony_ci error_msg += "CBOR"; 2924c5f01b2fSopenharmony_ci break; 2925c5f01b2fSopenharmony_ci 2926c5f01b2fSopenharmony_ci case input_format_t::msgpack: 2927c5f01b2fSopenharmony_ci error_msg += "MessagePack"; 2928c5f01b2fSopenharmony_ci break; 2929c5f01b2fSopenharmony_ci 2930c5f01b2fSopenharmony_ci case input_format_t::ubjson: 2931c5f01b2fSopenharmony_ci error_msg += "UBJSON"; 2932c5f01b2fSopenharmony_ci break; 2933c5f01b2fSopenharmony_ci 2934c5f01b2fSopenharmony_ci case input_format_t::bson: 2935c5f01b2fSopenharmony_ci error_msg += "BSON"; 2936c5f01b2fSopenharmony_ci break; 2937c5f01b2fSopenharmony_ci 2938c5f01b2fSopenharmony_ci case input_format_t::bjdata: 2939c5f01b2fSopenharmony_ci error_msg += "BJData"; 2940c5f01b2fSopenharmony_ci break; 2941c5f01b2fSopenharmony_ci 2942c5f01b2fSopenharmony_ci case input_format_t::json: // LCOV_EXCL_LINE 2943c5f01b2fSopenharmony_ci default: // LCOV_EXCL_LINE 2944c5f01b2fSopenharmony_ci JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE 2945c5f01b2fSopenharmony_ci } 2946c5f01b2fSopenharmony_ci 2947c5f01b2fSopenharmony_ci return concat(error_msg, ' ', context, ": ", detail); 2948c5f01b2fSopenharmony_ci } 2949c5f01b2fSopenharmony_ci 2950c5f01b2fSopenharmony_ci private: 2951c5f01b2fSopenharmony_ci static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1); 2952c5f01b2fSopenharmony_ci 2953c5f01b2fSopenharmony_ci /// input adapter 2954c5f01b2fSopenharmony_ci InputAdapterType ia; 2955c5f01b2fSopenharmony_ci 2956c5f01b2fSopenharmony_ci /// the current character 2957c5f01b2fSopenharmony_ci char_int_type current = std::char_traits<char_type>::eof(); 2958c5f01b2fSopenharmony_ci 2959c5f01b2fSopenharmony_ci /// the number of characters read 2960c5f01b2fSopenharmony_ci std::size_t chars_read = 0; 2961c5f01b2fSopenharmony_ci 2962c5f01b2fSopenharmony_ci /// whether we can assume little endianness 2963c5f01b2fSopenharmony_ci const bool is_little_endian = little_endianness(); 2964c5f01b2fSopenharmony_ci 2965c5f01b2fSopenharmony_ci /// input format 2966c5f01b2fSopenharmony_ci const input_format_t input_format = input_format_t::json; 2967c5f01b2fSopenharmony_ci 2968c5f01b2fSopenharmony_ci /// the SAX parser 2969c5f01b2fSopenharmony_ci json_sax_t* sax = nullptr; 2970c5f01b2fSopenharmony_ci 2971c5f01b2fSopenharmony_ci // excluded markers in bjdata optimized type 2972c5f01b2fSopenharmony_ci#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \ 2973c5f01b2fSopenharmony_ci make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{') 2974c5f01b2fSopenharmony_ci 2975c5f01b2fSopenharmony_ci#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \ 2976c5f01b2fSopenharmony_ci make_array<bjd_type>( \ 2977c5f01b2fSopenharmony_ci bjd_type{'C', "char"}, \ 2978c5f01b2fSopenharmony_ci bjd_type{'D', "double"}, \ 2979c5f01b2fSopenharmony_ci bjd_type{'I', "int16"}, \ 2980c5f01b2fSopenharmony_ci bjd_type{'L', "int64"}, \ 2981c5f01b2fSopenharmony_ci bjd_type{'M', "uint64"}, \ 2982c5f01b2fSopenharmony_ci bjd_type{'U', "uint8"}, \ 2983c5f01b2fSopenharmony_ci bjd_type{'d', "single"}, \ 2984c5f01b2fSopenharmony_ci bjd_type{'i', "int8"}, \ 2985c5f01b2fSopenharmony_ci bjd_type{'l', "int32"}, \ 2986c5f01b2fSopenharmony_ci bjd_type{'m', "uint32"}, \ 2987c5f01b2fSopenharmony_ci bjd_type{'u', "uint16"}) 2988c5f01b2fSopenharmony_ci 2989c5f01b2fSopenharmony_ci JSON_PRIVATE_UNLESS_TESTED: 2990c5f01b2fSopenharmony_ci // lookup tables 2991c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) 2992c5f01b2fSopenharmony_ci const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers = 2993c5f01b2fSopenharmony_ci JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_; 2994c5f01b2fSopenharmony_ci 2995c5f01b2fSopenharmony_ci using bjd_type = std::pair<char_int_type, string_t>; 2996c5f01b2fSopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) 2997c5f01b2fSopenharmony_ci const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map = 2998c5f01b2fSopenharmony_ci JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_; 2999c5f01b2fSopenharmony_ci 3000c5f01b2fSopenharmony_ci#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ 3001c5f01b2fSopenharmony_ci#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ 3002c5f01b2fSopenharmony_ci}; 3003c5f01b2fSopenharmony_ci 3004c5f01b2fSopenharmony_ci#ifndef JSON_HAS_CPP_17 3005c5f01b2fSopenharmony_ci template<typename BasicJsonType, typename InputAdapterType, typename SAX> 3006c5f01b2fSopenharmony_ci constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos; 3007c5f01b2fSopenharmony_ci#endif 3008c5f01b2fSopenharmony_ci 3009c5f01b2fSopenharmony_ci} // namespace detail 3010c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END 3011