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