1c5f01b2fSopenharmony_ci//     __ _____ _____ _____
2c5f01b2fSopenharmony_ci//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
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#include "doctest_compatibility.h"
10c5f01b2fSopenharmony_ci
11c5f01b2fSopenharmony_ci#include <nlohmann/json.hpp>
12c5f01b2fSopenharmony_ciusing nlohmann::json;
13c5f01b2fSopenharmony_ci
14c5f01b2fSopenharmony_ci#include <iostream>
15c5f01b2fSopenharmony_ci#include <fstream>
16c5f01b2fSopenharmony_ci#include <set>
17c5f01b2fSopenharmony_ci#include "make_test_data_available.hpp"
18c5f01b2fSopenharmony_ci#include "test_utils.hpp"
19c5f01b2fSopenharmony_ci
20c5f01b2fSopenharmony_cinamespace
21c5f01b2fSopenharmony_ci{
22c5f01b2fSopenharmony_ciclass SaxCountdown
23c5f01b2fSopenharmony_ci{
24c5f01b2fSopenharmony_ci  public:
25c5f01b2fSopenharmony_ci    explicit SaxCountdown(const int count) : events_left(count)
26c5f01b2fSopenharmony_ci    {}
27c5f01b2fSopenharmony_ci
28c5f01b2fSopenharmony_ci    bool null()
29c5f01b2fSopenharmony_ci    {
30c5f01b2fSopenharmony_ci        return events_left-- > 0;
31c5f01b2fSopenharmony_ci    }
32c5f01b2fSopenharmony_ci
33c5f01b2fSopenharmony_ci    bool boolean(bool /*unused*/)
34c5f01b2fSopenharmony_ci    {
35c5f01b2fSopenharmony_ci        return events_left-- > 0;
36c5f01b2fSopenharmony_ci    }
37c5f01b2fSopenharmony_ci
38c5f01b2fSopenharmony_ci    bool number_integer(json::number_integer_t /*unused*/)
39c5f01b2fSopenharmony_ci    {
40c5f01b2fSopenharmony_ci        return events_left-- > 0;
41c5f01b2fSopenharmony_ci    }
42c5f01b2fSopenharmony_ci
43c5f01b2fSopenharmony_ci    bool number_unsigned(json::number_unsigned_t /*unused*/)
44c5f01b2fSopenharmony_ci    {
45c5f01b2fSopenharmony_ci        return events_left-- > 0;
46c5f01b2fSopenharmony_ci    }
47c5f01b2fSopenharmony_ci
48c5f01b2fSopenharmony_ci    bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
49c5f01b2fSopenharmony_ci    {
50c5f01b2fSopenharmony_ci        return events_left-- > 0;
51c5f01b2fSopenharmony_ci    }
52c5f01b2fSopenharmony_ci
53c5f01b2fSopenharmony_ci    bool string(std::string& /*unused*/)
54c5f01b2fSopenharmony_ci    {
55c5f01b2fSopenharmony_ci        return events_left-- > 0;
56c5f01b2fSopenharmony_ci    }
57c5f01b2fSopenharmony_ci
58c5f01b2fSopenharmony_ci    bool binary(std::vector<std::uint8_t>& /*unused*/)
59c5f01b2fSopenharmony_ci    {
60c5f01b2fSopenharmony_ci        return events_left-- > 0;
61c5f01b2fSopenharmony_ci    }
62c5f01b2fSopenharmony_ci
63c5f01b2fSopenharmony_ci    bool start_object(std::size_t /*unused*/)
64c5f01b2fSopenharmony_ci    {
65c5f01b2fSopenharmony_ci        return events_left-- > 0;
66c5f01b2fSopenharmony_ci    }
67c5f01b2fSopenharmony_ci
68c5f01b2fSopenharmony_ci    bool key(std::string& /*unused*/)
69c5f01b2fSopenharmony_ci    {
70c5f01b2fSopenharmony_ci        return events_left-- > 0;
71c5f01b2fSopenharmony_ci    }
72c5f01b2fSopenharmony_ci
73c5f01b2fSopenharmony_ci    bool end_object()
74c5f01b2fSopenharmony_ci    {
75c5f01b2fSopenharmony_ci        return events_left-- > 0;
76c5f01b2fSopenharmony_ci    }
77c5f01b2fSopenharmony_ci
78c5f01b2fSopenharmony_ci    bool start_array(std::size_t /*unused*/)
79c5f01b2fSopenharmony_ci    {
80c5f01b2fSopenharmony_ci        return events_left-- > 0;
81c5f01b2fSopenharmony_ci    }
82c5f01b2fSopenharmony_ci
83c5f01b2fSopenharmony_ci    bool end_array()
84c5f01b2fSopenharmony_ci    {
85c5f01b2fSopenharmony_ci        return events_left-- > 0;
86c5f01b2fSopenharmony_ci    }
87c5f01b2fSopenharmony_ci
88c5f01b2fSopenharmony_ci    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
89c5f01b2fSopenharmony_ci    {
90c5f01b2fSopenharmony_ci        return false;
91c5f01b2fSopenharmony_ci    }
92c5f01b2fSopenharmony_ci
93c5f01b2fSopenharmony_ci  private:
94c5f01b2fSopenharmony_ci    int events_left = 0;
95c5f01b2fSopenharmony_ci};
96c5f01b2fSopenharmony_ci} // namespace
97c5f01b2fSopenharmony_ci
98c5f01b2fSopenharmony_ciTEST_CASE("UBJSON")
99c5f01b2fSopenharmony_ci{
100c5f01b2fSopenharmony_ci    SECTION("individual values")
101c5f01b2fSopenharmony_ci    {
102c5f01b2fSopenharmony_ci        SECTION("discarded")
103c5f01b2fSopenharmony_ci        {
104c5f01b2fSopenharmony_ci            // discarded values are not serialized
105c5f01b2fSopenharmony_ci            json j = json::value_t::discarded;
106c5f01b2fSopenharmony_ci            const auto result = json::to_ubjson(j);
107c5f01b2fSopenharmony_ci            CHECK(result.empty());
108c5f01b2fSopenharmony_ci        }
109c5f01b2fSopenharmony_ci
110c5f01b2fSopenharmony_ci        SECTION("null")
111c5f01b2fSopenharmony_ci        {
112c5f01b2fSopenharmony_ci            json j = nullptr;
113c5f01b2fSopenharmony_ci            std::vector<uint8_t> expected = {'Z'};
114c5f01b2fSopenharmony_ci            const auto result = json::to_ubjson(j);
115c5f01b2fSopenharmony_ci            CHECK(result == expected);
116c5f01b2fSopenharmony_ci
117c5f01b2fSopenharmony_ci            // roundtrip
118c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(result) == j);
119c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(result, true, false) == j);
120c5f01b2fSopenharmony_ci        }
121c5f01b2fSopenharmony_ci
122c5f01b2fSopenharmony_ci        SECTION("boolean")
123c5f01b2fSopenharmony_ci        {
124c5f01b2fSopenharmony_ci            SECTION("true")
125c5f01b2fSopenharmony_ci            {
126c5f01b2fSopenharmony_ci                json j = true;
127c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'T'};
128c5f01b2fSopenharmony_ci                const auto result = json::to_ubjson(j);
129c5f01b2fSopenharmony_ci                CHECK(result == expected);
130c5f01b2fSopenharmony_ci
131c5f01b2fSopenharmony_ci                // roundtrip
132c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(result) == j);
133c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(result, true, false) == j);
134c5f01b2fSopenharmony_ci            }
135c5f01b2fSopenharmony_ci
136c5f01b2fSopenharmony_ci            SECTION("false")
137c5f01b2fSopenharmony_ci            {
138c5f01b2fSopenharmony_ci                json j = false;
139c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'F'};
140c5f01b2fSopenharmony_ci                const auto result = json::to_ubjson(j);
141c5f01b2fSopenharmony_ci                CHECK(result == expected);
142c5f01b2fSopenharmony_ci
143c5f01b2fSopenharmony_ci                // roundtrip
144c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(result) == j);
145c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(result, true, false) == j);
146c5f01b2fSopenharmony_ci            }
147c5f01b2fSopenharmony_ci        }
148c5f01b2fSopenharmony_ci
149c5f01b2fSopenharmony_ci        SECTION("number")
150c5f01b2fSopenharmony_ci        {
151c5f01b2fSopenharmony_ci            SECTION("signed")
152c5f01b2fSopenharmony_ci            {
153c5f01b2fSopenharmony_ci                SECTION("-9223372036854775808..-2147483649 (int64)")
154c5f01b2fSopenharmony_ci                {
155c5f01b2fSopenharmony_ci                    std::vector<int64_t> numbers;
156c5f01b2fSopenharmony_ci                    numbers.push_back((std::numeric_limits<int64_t>::min)());
157c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000000000000LL);
158c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000000000000LL);
159c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000000000000LL);
160c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000000000LL);
161c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000000000LL);
162c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000000000LL);
163c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000000LL);
164c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000000LL);
165c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000000LL);
166c5f01b2fSopenharmony_ci                    numbers.push_back(-2147483649LL);
167c5f01b2fSopenharmony_ci                    for (auto i : numbers)
168c5f01b2fSopenharmony_ci                    {
169c5f01b2fSopenharmony_ci                        CAPTURE(i)
170c5f01b2fSopenharmony_ci
171c5f01b2fSopenharmony_ci                        // create JSON value with integer number
172c5f01b2fSopenharmony_ci                        json j = i;
173c5f01b2fSopenharmony_ci
174c5f01b2fSopenharmony_ci                        // check type
175c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
176c5f01b2fSopenharmony_ci
177c5f01b2fSopenharmony_ci                        // create expected byte vector
178c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
179c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>('L'));
180c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 56) & 0xff));
181c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 48) & 0xff));
182c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 40) & 0xff));
183c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 32) & 0xff));
184c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
185c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
186c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
187c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
188c5f01b2fSopenharmony_ci
189c5f01b2fSopenharmony_ci                        // compare result + size
190c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
191c5f01b2fSopenharmony_ci                        CHECK(result == expected);
192c5f01b2fSopenharmony_ci                        CHECK(result.size() == 9);
193c5f01b2fSopenharmony_ci
194c5f01b2fSopenharmony_ci                        // check individual bytes
195c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'L');
196c5f01b2fSopenharmony_ci                        int64_t restored = (static_cast<int64_t>(result[1]) << 070) +
197c5f01b2fSopenharmony_ci                                           (static_cast<int64_t>(result[2]) << 060) +
198c5f01b2fSopenharmony_ci                                           (static_cast<int64_t>(result[3]) << 050) +
199c5f01b2fSopenharmony_ci                                           (static_cast<int64_t>(result[4]) << 040) +
200c5f01b2fSopenharmony_ci                                           (static_cast<int64_t>(result[5]) << 030) +
201c5f01b2fSopenharmony_ci                                           (static_cast<int64_t>(result[6]) << 020) +
202c5f01b2fSopenharmony_ci                                           (static_cast<int64_t>(result[7]) << 010) +
203c5f01b2fSopenharmony_ci                                           static_cast<int64_t>(result[8]);
204c5f01b2fSopenharmony_ci                        CHECK(restored == i);
205c5f01b2fSopenharmony_ci
206c5f01b2fSopenharmony_ci                        // roundtrip
207c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
208c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
209c5f01b2fSopenharmony_ci                    }
210c5f01b2fSopenharmony_ci                }
211c5f01b2fSopenharmony_ci
212c5f01b2fSopenharmony_ci                SECTION("-2147483648..-32769 (int32)")
213c5f01b2fSopenharmony_ci                {
214c5f01b2fSopenharmony_ci                    std::vector<int32_t> numbers;
215c5f01b2fSopenharmony_ci                    numbers.push_back(-32769);
216c5f01b2fSopenharmony_ci                    numbers.push_back(-100000);
217c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000);
218c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000);
219c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000);
220c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000);
221c5f01b2fSopenharmony_ci                    numbers.push_back(-2147483647 - 1); // https://stackoverflow.com/a/29356002/266378
222c5f01b2fSopenharmony_ci                    for (auto i : numbers)
223c5f01b2fSopenharmony_ci                    {
224c5f01b2fSopenharmony_ci                        CAPTURE(i)
225c5f01b2fSopenharmony_ci
226c5f01b2fSopenharmony_ci                        // create JSON value with integer number
227c5f01b2fSopenharmony_ci                        json j = i;
228c5f01b2fSopenharmony_ci
229c5f01b2fSopenharmony_ci                        // check type
230c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
231c5f01b2fSopenharmony_ci
232c5f01b2fSopenharmony_ci                        // create expected byte vector
233c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
234c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>('l'));
235c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
236c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
237c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
238c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
239c5f01b2fSopenharmony_ci
240c5f01b2fSopenharmony_ci                        // compare result + size
241c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
242c5f01b2fSopenharmony_ci                        CHECK(result == expected);
243c5f01b2fSopenharmony_ci                        CHECK(result.size() == 5);
244c5f01b2fSopenharmony_ci
245c5f01b2fSopenharmony_ci                        // check individual bytes
246c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'l');
247c5f01b2fSopenharmony_ci                        int32_t restored = (static_cast<int32_t>(result[1]) << 030) +
248c5f01b2fSopenharmony_ci                                           (static_cast<int32_t>(result[2]) << 020) +
249c5f01b2fSopenharmony_ci                                           (static_cast<int32_t>(result[3]) << 010) +
250c5f01b2fSopenharmony_ci                                           static_cast<int32_t>(result[4]);
251c5f01b2fSopenharmony_ci                        CHECK(restored == i);
252c5f01b2fSopenharmony_ci
253c5f01b2fSopenharmony_ci                        // roundtrip
254c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
255c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
256c5f01b2fSopenharmony_ci                    }
257c5f01b2fSopenharmony_ci                }
258c5f01b2fSopenharmony_ci
259c5f01b2fSopenharmony_ci                SECTION("-32768..-129 (int16)")
260c5f01b2fSopenharmony_ci                {
261c5f01b2fSopenharmony_ci                    for (int32_t i = -32768; i <= -129; ++i)
262c5f01b2fSopenharmony_ci                    {
263c5f01b2fSopenharmony_ci                        CAPTURE(i)
264c5f01b2fSopenharmony_ci
265c5f01b2fSopenharmony_ci                        // create JSON value with integer number
266c5f01b2fSopenharmony_ci                        json j = i;
267c5f01b2fSopenharmony_ci
268c5f01b2fSopenharmony_ci                        // check type
269c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
270c5f01b2fSopenharmony_ci
271c5f01b2fSopenharmony_ci                        // create expected byte vector
272c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
273c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>('I'));
274c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
275c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
276c5f01b2fSopenharmony_ci
277c5f01b2fSopenharmony_ci                        // compare result + size
278c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
279c5f01b2fSopenharmony_ci                        CHECK(result == expected);
280c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
281c5f01b2fSopenharmony_ci
282c5f01b2fSopenharmony_ci                        // check individual bytes
283c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'I');
284c5f01b2fSopenharmony_ci                        auto restored = static_cast<int16_t>(((result[1] << 8) + result[2]));
285c5f01b2fSopenharmony_ci                        CHECK(restored == i);
286c5f01b2fSopenharmony_ci
287c5f01b2fSopenharmony_ci                        // roundtrip
288c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
289c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
290c5f01b2fSopenharmony_ci                    }
291c5f01b2fSopenharmony_ci                }
292c5f01b2fSopenharmony_ci
293c5f01b2fSopenharmony_ci                SECTION("-9263 (int16)")
294c5f01b2fSopenharmony_ci                {
295c5f01b2fSopenharmony_ci                    json j = -9263;
296c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'I', 0xdb, 0xd1};
297c5f01b2fSopenharmony_ci
298c5f01b2fSopenharmony_ci                    // compare result + size
299c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
300c5f01b2fSopenharmony_ci                    CHECK(result == expected);
301c5f01b2fSopenharmony_ci                    CHECK(result.size() == 3);
302c5f01b2fSopenharmony_ci
303c5f01b2fSopenharmony_ci                    // check individual bytes
304c5f01b2fSopenharmony_ci                    CHECK(result[0] == 'I');
305c5f01b2fSopenharmony_ci                    auto restored = static_cast<int16_t>(((result[1] << 8) + result[2]));
306c5f01b2fSopenharmony_ci                    CHECK(restored == -9263);
307c5f01b2fSopenharmony_ci
308c5f01b2fSopenharmony_ci                    // roundtrip
309c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
310c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
311c5f01b2fSopenharmony_ci                }
312c5f01b2fSopenharmony_ci
313c5f01b2fSopenharmony_ci                SECTION("-128..-1 (int8)")
314c5f01b2fSopenharmony_ci                {
315c5f01b2fSopenharmony_ci                    for (auto i = -128; i <= -1; ++i)
316c5f01b2fSopenharmony_ci                    {
317c5f01b2fSopenharmony_ci                        CAPTURE(i)
318c5f01b2fSopenharmony_ci
319c5f01b2fSopenharmony_ci                        // create JSON value with integer number
320c5f01b2fSopenharmony_ci                        json j = i;
321c5f01b2fSopenharmony_ci
322c5f01b2fSopenharmony_ci                        // check type
323c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
324c5f01b2fSopenharmony_ci
325c5f01b2fSopenharmony_ci                        // create expected byte vector
326c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
327c5f01b2fSopenharmony_ci                        expected.push_back('i');
328c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
329c5f01b2fSopenharmony_ci
330c5f01b2fSopenharmony_ci                        // compare result + size
331c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
332c5f01b2fSopenharmony_ci                        CHECK(result == expected);
333c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
334c5f01b2fSopenharmony_ci
335c5f01b2fSopenharmony_ci                        // check individual bytes
336c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'i');
337c5f01b2fSopenharmony_ci                        CHECK(static_cast<int8_t>(result[1]) == i);
338c5f01b2fSopenharmony_ci
339c5f01b2fSopenharmony_ci                        // roundtrip
340c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
341c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
342c5f01b2fSopenharmony_ci                    }
343c5f01b2fSopenharmony_ci                }
344c5f01b2fSopenharmony_ci
345c5f01b2fSopenharmony_ci                SECTION("0..127 (int8)")
346c5f01b2fSopenharmony_ci                {
347c5f01b2fSopenharmony_ci                    for (size_t i = 0; i <= 127; ++i)
348c5f01b2fSopenharmony_ci                    {
349c5f01b2fSopenharmony_ci                        CAPTURE(i)
350c5f01b2fSopenharmony_ci
351c5f01b2fSopenharmony_ci                        // create JSON value with integer number
352c5f01b2fSopenharmony_ci                        json j = -1;
353c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
354c5f01b2fSopenharmony_ci
355c5f01b2fSopenharmony_ci                        // check type
356c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
357c5f01b2fSopenharmony_ci
358c5f01b2fSopenharmony_ci                        // create expected byte vector
359c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
360c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>('i'));
361c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
362c5f01b2fSopenharmony_ci
363c5f01b2fSopenharmony_ci                        // compare result + size
364c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
365c5f01b2fSopenharmony_ci                        CHECK(result == expected);
366c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
367c5f01b2fSopenharmony_ci
368c5f01b2fSopenharmony_ci                        // check individual bytes
369c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'i');
370c5f01b2fSopenharmony_ci                        CHECK(result[1] == i);
371c5f01b2fSopenharmony_ci
372c5f01b2fSopenharmony_ci                        // roundtrip
373c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
374c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
375c5f01b2fSopenharmony_ci                    }
376c5f01b2fSopenharmony_ci                }
377c5f01b2fSopenharmony_ci
378c5f01b2fSopenharmony_ci                SECTION("128..255 (uint8)")
379c5f01b2fSopenharmony_ci                {
380c5f01b2fSopenharmony_ci                    for (size_t i = 128; i <= 255; ++i)
381c5f01b2fSopenharmony_ci                    {
382c5f01b2fSopenharmony_ci                        CAPTURE(i)
383c5f01b2fSopenharmony_ci
384c5f01b2fSopenharmony_ci                        // create JSON value with integer number
385c5f01b2fSopenharmony_ci                        json j = -1;
386c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
387c5f01b2fSopenharmony_ci
388c5f01b2fSopenharmony_ci                        // check type
389c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
390c5f01b2fSopenharmony_ci
391c5f01b2fSopenharmony_ci                        // create expected byte vector
392c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
393c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>('U'));
394c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
395c5f01b2fSopenharmony_ci
396c5f01b2fSopenharmony_ci                        // compare result + size
397c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
398c5f01b2fSopenharmony_ci                        CHECK(result == expected);
399c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
400c5f01b2fSopenharmony_ci
401c5f01b2fSopenharmony_ci                        // check individual bytes
402c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'U');
403c5f01b2fSopenharmony_ci                        CHECK(result[1] == i);
404c5f01b2fSopenharmony_ci
405c5f01b2fSopenharmony_ci                        // roundtrip
406c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
407c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
408c5f01b2fSopenharmony_ci                    }
409c5f01b2fSopenharmony_ci                }
410c5f01b2fSopenharmony_ci
411c5f01b2fSopenharmony_ci                SECTION("256..32767 (int16)")
412c5f01b2fSopenharmony_ci                {
413c5f01b2fSopenharmony_ci                    for (size_t i = 256; i <= 32767; ++i)
414c5f01b2fSopenharmony_ci                    {
415c5f01b2fSopenharmony_ci                        CAPTURE(i)
416c5f01b2fSopenharmony_ci
417c5f01b2fSopenharmony_ci                        // create JSON value with integer number
418c5f01b2fSopenharmony_ci                        json j = -1;
419c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
420c5f01b2fSopenharmony_ci
421c5f01b2fSopenharmony_ci                        // check type
422c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
423c5f01b2fSopenharmony_ci
424c5f01b2fSopenharmony_ci                        // create expected byte vector
425c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
426c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>('I'));
427c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
428c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
429c5f01b2fSopenharmony_ci
430c5f01b2fSopenharmony_ci                        // compare result + size
431c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
432c5f01b2fSopenharmony_ci                        CHECK(result == expected);
433c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
434c5f01b2fSopenharmony_ci
435c5f01b2fSopenharmony_ci                        // check individual bytes
436c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'I');
437c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
438c5f01b2fSopenharmony_ci                        CHECK(restored == i);
439c5f01b2fSopenharmony_ci
440c5f01b2fSopenharmony_ci                        // roundtrip
441c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
442c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
443c5f01b2fSopenharmony_ci                    }
444c5f01b2fSopenharmony_ci                }
445c5f01b2fSopenharmony_ci
446c5f01b2fSopenharmony_ci                SECTION("65536..2147483647 (int32)")
447c5f01b2fSopenharmony_ci                {
448c5f01b2fSopenharmony_ci                    for (uint32_t i :
449c5f01b2fSopenharmony_ci                            {
450c5f01b2fSopenharmony_ci                                65536u, 77777u, 1048576u
451c5f01b2fSopenharmony_ci                            })
452c5f01b2fSopenharmony_ci                    {
453c5f01b2fSopenharmony_ci                        CAPTURE(i)
454c5f01b2fSopenharmony_ci
455c5f01b2fSopenharmony_ci                        // create JSON value with integer number
456c5f01b2fSopenharmony_ci                        json j = -1;
457c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
458c5f01b2fSopenharmony_ci
459c5f01b2fSopenharmony_ci                        // check type
460c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
461c5f01b2fSopenharmony_ci
462c5f01b2fSopenharmony_ci                        // create expected byte vector
463c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
464c5f01b2fSopenharmony_ci                        expected.push_back('l');
465c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
466c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
467c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
468c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
469c5f01b2fSopenharmony_ci
470c5f01b2fSopenharmony_ci                        // compare result + size
471c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
472c5f01b2fSopenharmony_ci                        CHECK(result == expected);
473c5f01b2fSopenharmony_ci                        CHECK(result.size() == 5);
474c5f01b2fSopenharmony_ci
475c5f01b2fSopenharmony_ci                        // check individual bytes
476c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'l');
477c5f01b2fSopenharmony_ci                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
478c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[2]) << 020) +
479c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[3]) << 010) +
480c5f01b2fSopenharmony_ci                                            static_cast<uint32_t>(result[4]);
481c5f01b2fSopenharmony_ci                        CHECK(restored == i);
482c5f01b2fSopenharmony_ci
483c5f01b2fSopenharmony_ci                        // roundtrip
484c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
485c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
486c5f01b2fSopenharmony_ci                    }
487c5f01b2fSopenharmony_ci                }
488c5f01b2fSopenharmony_ci
489c5f01b2fSopenharmony_ci                SECTION("2147483648..9223372036854775807 (int64)")
490c5f01b2fSopenharmony_ci                {
491c5f01b2fSopenharmony_ci                    std::vector<uint64_t> v = {2147483648ul, 9223372036854775807ul};
492c5f01b2fSopenharmony_ci                    for (uint64_t i : v)
493c5f01b2fSopenharmony_ci                    {
494c5f01b2fSopenharmony_ci                        CAPTURE(i)
495c5f01b2fSopenharmony_ci
496c5f01b2fSopenharmony_ci                        // create JSON value with integer number
497c5f01b2fSopenharmony_ci                        json j = -1;
498c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
499c5f01b2fSopenharmony_ci
500c5f01b2fSopenharmony_ci                        // check type
501c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
502c5f01b2fSopenharmony_ci
503c5f01b2fSopenharmony_ci                        // create expected byte vector
504c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
505c5f01b2fSopenharmony_ci                        expected.push_back('L');
506c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
507c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
508c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
509c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
510c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
511c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
512c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
513c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
514c5f01b2fSopenharmony_ci
515c5f01b2fSopenharmony_ci                        // compare result + size
516c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
517c5f01b2fSopenharmony_ci                        CHECK(result == expected);
518c5f01b2fSopenharmony_ci                        CHECK(result.size() == 9);
519c5f01b2fSopenharmony_ci
520c5f01b2fSopenharmony_ci                        // check individual bytes
521c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'L');
522c5f01b2fSopenharmony_ci                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
523c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[2]) << 060) +
524c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[3]) << 050) +
525c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[4]) << 040) +
526c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[5]) << 030) +
527c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[6]) << 020) +
528c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[7]) << 010) +
529c5f01b2fSopenharmony_ci                                            static_cast<uint64_t>(result[8]);
530c5f01b2fSopenharmony_ci                        CHECK(restored == i);
531c5f01b2fSopenharmony_ci
532c5f01b2fSopenharmony_ci                        // roundtrip
533c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
534c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
535c5f01b2fSopenharmony_ci                    }
536c5f01b2fSopenharmony_ci                }
537c5f01b2fSopenharmony_ci            }
538c5f01b2fSopenharmony_ci
539c5f01b2fSopenharmony_ci            SECTION("unsigned")
540c5f01b2fSopenharmony_ci            {
541c5f01b2fSopenharmony_ci                SECTION("0..127 (int8)")
542c5f01b2fSopenharmony_ci                {
543c5f01b2fSopenharmony_ci                    for (size_t i = 0; i <= 127; ++i)
544c5f01b2fSopenharmony_ci                    {
545c5f01b2fSopenharmony_ci                        CAPTURE(i)
546c5f01b2fSopenharmony_ci
547c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
548c5f01b2fSopenharmony_ci                        json j = i;
549c5f01b2fSopenharmony_ci
550c5f01b2fSopenharmony_ci                        // check type
551c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
552c5f01b2fSopenharmony_ci
553c5f01b2fSopenharmony_ci                        // create expected byte vector
554c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
555c5f01b2fSopenharmony_ci                        expected.push_back('i');
556c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
557c5f01b2fSopenharmony_ci
558c5f01b2fSopenharmony_ci                        // compare result + size
559c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
560c5f01b2fSopenharmony_ci                        CHECK(result == expected);
561c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
562c5f01b2fSopenharmony_ci
563c5f01b2fSopenharmony_ci                        // check individual bytes
564c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'i');
565c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint8_t>(result[1]);
566c5f01b2fSopenharmony_ci                        CHECK(restored == i);
567c5f01b2fSopenharmony_ci
568c5f01b2fSopenharmony_ci                        // roundtrip
569c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
570c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
571c5f01b2fSopenharmony_ci                    }
572c5f01b2fSopenharmony_ci                }
573c5f01b2fSopenharmony_ci
574c5f01b2fSopenharmony_ci                SECTION("128..255 (uint8)")
575c5f01b2fSopenharmony_ci                {
576c5f01b2fSopenharmony_ci                    for (size_t i = 128; i <= 255; ++i)
577c5f01b2fSopenharmony_ci                    {
578c5f01b2fSopenharmony_ci                        CAPTURE(i)
579c5f01b2fSopenharmony_ci
580c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
581c5f01b2fSopenharmony_ci                        json j = i;
582c5f01b2fSopenharmony_ci
583c5f01b2fSopenharmony_ci                        // check type
584c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
585c5f01b2fSopenharmony_ci
586c5f01b2fSopenharmony_ci                        // create expected byte vector
587c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
588c5f01b2fSopenharmony_ci                        expected.push_back('U');
589c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
590c5f01b2fSopenharmony_ci
591c5f01b2fSopenharmony_ci                        // compare result + size
592c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
593c5f01b2fSopenharmony_ci                        CHECK(result == expected);
594c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
595c5f01b2fSopenharmony_ci
596c5f01b2fSopenharmony_ci                        // check individual bytes
597c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'U');
598c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint8_t>(result[1]);
599c5f01b2fSopenharmony_ci                        CHECK(restored == i);
600c5f01b2fSopenharmony_ci
601c5f01b2fSopenharmony_ci                        // roundtrip
602c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
603c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
604c5f01b2fSopenharmony_ci                    }
605c5f01b2fSopenharmony_ci                }
606c5f01b2fSopenharmony_ci
607c5f01b2fSopenharmony_ci                SECTION("256..32767 (int16)")
608c5f01b2fSopenharmony_ci                {
609c5f01b2fSopenharmony_ci                    for (size_t i = 256; i <= 32767; ++i)
610c5f01b2fSopenharmony_ci                    {
611c5f01b2fSopenharmony_ci                        CAPTURE(i)
612c5f01b2fSopenharmony_ci
613c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
614c5f01b2fSopenharmony_ci                        json j = i;
615c5f01b2fSopenharmony_ci
616c5f01b2fSopenharmony_ci                        // check type
617c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
618c5f01b2fSopenharmony_ci
619c5f01b2fSopenharmony_ci                        // create expected byte vector
620c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
621c5f01b2fSopenharmony_ci                        expected.push_back('I');
622c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
623c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
624c5f01b2fSopenharmony_ci
625c5f01b2fSopenharmony_ci                        // compare result + size
626c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
627c5f01b2fSopenharmony_ci                        CHECK(result == expected);
628c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
629c5f01b2fSopenharmony_ci
630c5f01b2fSopenharmony_ci                        // check individual bytes
631c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'I');
632c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
633c5f01b2fSopenharmony_ci                        CHECK(restored == i);
634c5f01b2fSopenharmony_ci
635c5f01b2fSopenharmony_ci                        // roundtrip
636c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
637c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
638c5f01b2fSopenharmony_ci                    }
639c5f01b2fSopenharmony_ci                }
640c5f01b2fSopenharmony_ci
641c5f01b2fSopenharmony_ci                SECTION("65536..2147483647 (int32)")
642c5f01b2fSopenharmony_ci                {
643c5f01b2fSopenharmony_ci                    for (uint32_t i :
644c5f01b2fSopenharmony_ci                            {
645c5f01b2fSopenharmony_ci                                65536u, 77777u, 1048576u
646c5f01b2fSopenharmony_ci                            })
647c5f01b2fSopenharmony_ci                    {
648c5f01b2fSopenharmony_ci                        CAPTURE(i)
649c5f01b2fSopenharmony_ci
650c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
651c5f01b2fSopenharmony_ci                        json j = i;
652c5f01b2fSopenharmony_ci
653c5f01b2fSopenharmony_ci                        // check type
654c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
655c5f01b2fSopenharmony_ci
656c5f01b2fSopenharmony_ci                        // create expected byte vector
657c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
658c5f01b2fSopenharmony_ci                        expected.push_back('l');
659c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
660c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
661c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
662c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
663c5f01b2fSopenharmony_ci
664c5f01b2fSopenharmony_ci                        // compare result + size
665c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
666c5f01b2fSopenharmony_ci                        CHECK(result == expected);
667c5f01b2fSopenharmony_ci                        CHECK(result.size() == 5);
668c5f01b2fSopenharmony_ci
669c5f01b2fSopenharmony_ci                        // check individual bytes
670c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'l');
671c5f01b2fSopenharmony_ci                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
672c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[2]) << 020) +
673c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[3]) << 010) +
674c5f01b2fSopenharmony_ci                                            static_cast<uint32_t>(result[4]);
675c5f01b2fSopenharmony_ci                        CHECK(restored == i);
676c5f01b2fSopenharmony_ci
677c5f01b2fSopenharmony_ci                        // roundtrip
678c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
679c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
680c5f01b2fSopenharmony_ci                    }
681c5f01b2fSopenharmony_ci                }
682c5f01b2fSopenharmony_ci
683c5f01b2fSopenharmony_ci                SECTION("2147483648..9223372036854775807 (int64)")
684c5f01b2fSopenharmony_ci                {
685c5f01b2fSopenharmony_ci                    std::vector<uint64_t> v = {2147483648ul, 9223372036854775807ul};
686c5f01b2fSopenharmony_ci                    for (uint64_t i : v)
687c5f01b2fSopenharmony_ci                    {
688c5f01b2fSopenharmony_ci                        CAPTURE(i)
689c5f01b2fSopenharmony_ci
690c5f01b2fSopenharmony_ci                        // create JSON value with integer number
691c5f01b2fSopenharmony_ci                        json j = i;
692c5f01b2fSopenharmony_ci
693c5f01b2fSopenharmony_ci                        // check type
694c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
695c5f01b2fSopenharmony_ci
696c5f01b2fSopenharmony_ci                        // create expected byte vector
697c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
698c5f01b2fSopenharmony_ci                        expected.push_back('L');
699c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
700c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
701c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
702c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
703c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
704c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
705c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
706c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
707c5f01b2fSopenharmony_ci
708c5f01b2fSopenharmony_ci                        // compare result + size
709c5f01b2fSopenharmony_ci                        const auto result = json::to_ubjson(j);
710c5f01b2fSopenharmony_ci                        CHECK(result == expected);
711c5f01b2fSopenharmony_ci                        CHECK(result.size() == 9);
712c5f01b2fSopenharmony_ci
713c5f01b2fSopenharmony_ci                        // check individual bytes
714c5f01b2fSopenharmony_ci                        CHECK(result[0] == 'L');
715c5f01b2fSopenharmony_ci                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
716c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[2]) << 060) +
717c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[3]) << 050) +
718c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[4]) << 040) +
719c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[5]) << 030) +
720c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[6]) << 020) +
721c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[7]) << 010) +
722c5f01b2fSopenharmony_ci                                            static_cast<uint64_t>(result[8]);
723c5f01b2fSopenharmony_ci                        CHECK(restored == i);
724c5f01b2fSopenharmony_ci
725c5f01b2fSopenharmony_ci                        // roundtrip
726c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result) == j);
727c5f01b2fSopenharmony_ci                        CHECK(json::from_ubjson(result, true, false) == j);
728c5f01b2fSopenharmony_ci                    }
729c5f01b2fSopenharmony_ci                }
730c5f01b2fSopenharmony_ci            }
731c5f01b2fSopenharmony_ci
732c5f01b2fSopenharmony_ci            SECTION("float64")
733c5f01b2fSopenharmony_ci            {
734c5f01b2fSopenharmony_ci                SECTION("3.1415925")
735c5f01b2fSopenharmony_ci                {
736c5f01b2fSopenharmony_ci                    double v = 3.1415925;
737c5f01b2fSopenharmony_ci                    json j = v;
738c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
739c5f01b2fSopenharmony_ci                    {
740c5f01b2fSopenharmony_ci                        'D', 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc
741c5f01b2fSopenharmony_ci                    };
742c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
743c5f01b2fSopenharmony_ci                    CHECK(result == expected);
744c5f01b2fSopenharmony_ci
745c5f01b2fSopenharmony_ci                    // roundtrip
746c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
747c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == v);
748c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
749c5f01b2fSopenharmony_ci                }
750c5f01b2fSopenharmony_ci            }
751c5f01b2fSopenharmony_ci
752c5f01b2fSopenharmony_ci            SECTION("high-precision number")
753c5f01b2fSopenharmony_ci            {
754c5f01b2fSopenharmony_ci                SECTION("unsigned integer number")
755c5f01b2fSopenharmony_ci                {
756c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec = {'H', 'i', 0x14, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
757c5f01b2fSopenharmony_ci                    const auto j = json::from_ubjson(vec);
758c5f01b2fSopenharmony_ci                    CHECK(j.is_number_unsigned());
759c5f01b2fSopenharmony_ci                    CHECK(j.dump() == "12345678901234567890");
760c5f01b2fSopenharmony_ci                }
761c5f01b2fSopenharmony_ci
762c5f01b2fSopenharmony_ci                SECTION("signed integer number")
763c5f01b2fSopenharmony_ci                {
764c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec = {'H', 'i', 0x13, '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'};
765c5f01b2fSopenharmony_ci                    const auto j = json::from_ubjson(vec);
766c5f01b2fSopenharmony_ci                    CHECK(j.is_number_integer());
767c5f01b2fSopenharmony_ci                    CHECK(j.dump() == "-123456789012345678");
768c5f01b2fSopenharmony_ci                }
769c5f01b2fSopenharmony_ci
770c5f01b2fSopenharmony_ci                SECTION("floating-point number")
771c5f01b2fSopenharmony_ci                {
772c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec = {'H', 'i', 0x16, '3', '.', '1', '4', '1', '5', '9',  '2', '6', '5', '3', '5', '8', '9',  '7', '9', '3', '2', '3', '8', '4',  '6'};
773c5f01b2fSopenharmony_ci                    const auto j = json::from_ubjson(vec);
774c5f01b2fSopenharmony_ci                    CHECK(j.is_number_float());
775c5f01b2fSopenharmony_ci                    CHECK(j.dump() == "3.141592653589793");
776c5f01b2fSopenharmony_ci                }
777c5f01b2fSopenharmony_ci
778c5f01b2fSopenharmony_ci                SECTION("errors")
779c5f01b2fSopenharmony_ci                {
780c5f01b2fSopenharmony_ci                    // error while parsing length
781c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec0 = {'H', 'i'};
782c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(vec0, true, false).is_discarded());
783c5f01b2fSopenharmony_ci                    // error while parsing string
784c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec1 = {'H', 'i', '1'};
785c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(vec1, true, false).is_discarded());
786c5f01b2fSopenharmony_ci
787c5f01b2fSopenharmony_ci                    json _;
788c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec2 = {'H', 'i', 2, '1', 'A', '3'};
789c5f01b2fSopenharmony_ci                    CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec2), "[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A", json::parse_error);
790c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec3 = {'H', 'i', 2, '1', '.'};
791c5f01b2fSopenharmony_ci                    CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec3), "[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1.", json::parse_error);
792c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec4 = {'H', 2, '1', '0'};
793c5f01b2fSopenharmony_ci                    CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec4), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x02", json::parse_error);
794c5f01b2fSopenharmony_ci                }
795c5f01b2fSopenharmony_ci
796c5f01b2fSopenharmony_ci                SECTION("serialization")
797c5f01b2fSopenharmony_ci                {
798c5f01b2fSopenharmony_ci                    // number that does not fit int64
799c5f01b2fSopenharmony_ci                    json j = 11111111111111111111ULL;
800c5f01b2fSopenharmony_ci                    CHECK(j.is_number_unsigned());
801c5f01b2fSopenharmony_ci
802c5f01b2fSopenharmony_ci                    // number will be serialized to high-precision number
803c5f01b2fSopenharmony_ci                    const auto vec = json::to_ubjson(j);
804c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'H', 'i', 0x14, '1',  '1',  '1',  '1',  '1', '1',  '1',  '1',  '1',  '1', '1',  '1',  '1',  '1',  '1', '1',  '1',  '1',  '1',  '1'};
805c5f01b2fSopenharmony_ci                    CHECK(vec == expected);
806c5f01b2fSopenharmony_ci
807c5f01b2fSopenharmony_ci                    // roundtrip
808c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(vec) == j);
809c5f01b2fSopenharmony_ci                }
810c5f01b2fSopenharmony_ci            }
811c5f01b2fSopenharmony_ci        }
812c5f01b2fSopenharmony_ci
813c5f01b2fSopenharmony_ci        SECTION("string")
814c5f01b2fSopenharmony_ci        {
815c5f01b2fSopenharmony_ci            SECTION("N = 0..127")
816c5f01b2fSopenharmony_ci            {
817c5f01b2fSopenharmony_ci                for (size_t N = 0; N <= 127; ++N)
818c5f01b2fSopenharmony_ci                {
819c5f01b2fSopenharmony_ci                    CAPTURE(N)
820c5f01b2fSopenharmony_ci
821c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
822c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
823c5f01b2fSopenharmony_ci                    json j = s;
824c5f01b2fSopenharmony_ci
825c5f01b2fSopenharmony_ci                    // create expected byte vector
826c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
827c5f01b2fSopenharmony_ci                    expected.push_back('S');
828c5f01b2fSopenharmony_ci                    expected.push_back('i');
829c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<uint8_t>(N));
830c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
831c5f01b2fSopenharmony_ci                    {
832c5f01b2fSopenharmony_ci                        expected.push_back('x');
833c5f01b2fSopenharmony_ci                    }
834c5f01b2fSopenharmony_ci
835c5f01b2fSopenharmony_ci                    // compare result + size
836c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
837c5f01b2fSopenharmony_ci                    CHECK(result == expected);
838c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 3);
839c5f01b2fSopenharmony_ci                    // check that no null byte is appended
840c5f01b2fSopenharmony_ci                    if (N > 0)
841c5f01b2fSopenharmony_ci                    {
842c5f01b2fSopenharmony_ci                        CHECK(result.back() != '\x00');
843c5f01b2fSopenharmony_ci                    }
844c5f01b2fSopenharmony_ci
845c5f01b2fSopenharmony_ci                    // roundtrip
846c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
847c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
848c5f01b2fSopenharmony_ci                }
849c5f01b2fSopenharmony_ci            }
850c5f01b2fSopenharmony_ci
851c5f01b2fSopenharmony_ci            SECTION("N = 128..255")
852c5f01b2fSopenharmony_ci            {
853c5f01b2fSopenharmony_ci                for (size_t N = 128; N <= 255; ++N)
854c5f01b2fSopenharmony_ci                {
855c5f01b2fSopenharmony_ci                    CAPTURE(N)
856c5f01b2fSopenharmony_ci
857c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
858c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
859c5f01b2fSopenharmony_ci                    json j = s;
860c5f01b2fSopenharmony_ci
861c5f01b2fSopenharmony_ci                    // create expected byte vector
862c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
863c5f01b2fSopenharmony_ci                    expected.push_back('S');
864c5f01b2fSopenharmony_ci                    expected.push_back('U');
865c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<uint8_t>(N));
866c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
867c5f01b2fSopenharmony_ci                    {
868c5f01b2fSopenharmony_ci                        expected.push_back('x');
869c5f01b2fSopenharmony_ci                    }
870c5f01b2fSopenharmony_ci
871c5f01b2fSopenharmony_ci                    // compare result + size
872c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
873c5f01b2fSopenharmony_ci                    CHECK(result == expected);
874c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 3);
875c5f01b2fSopenharmony_ci                    // check that no null byte is appended
876c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
877c5f01b2fSopenharmony_ci
878c5f01b2fSopenharmony_ci                    // roundtrip
879c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
880c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
881c5f01b2fSopenharmony_ci                }
882c5f01b2fSopenharmony_ci            }
883c5f01b2fSopenharmony_ci
884c5f01b2fSopenharmony_ci            SECTION("N = 256..32767")
885c5f01b2fSopenharmony_ci            {
886c5f01b2fSopenharmony_ci                for (size_t N :
887c5f01b2fSopenharmony_ci                        {
888c5f01b2fSopenharmony_ci                            256u, 999u, 1025u, 3333u, 2048u, 32767u
889c5f01b2fSopenharmony_ci                        })
890c5f01b2fSopenharmony_ci                {
891c5f01b2fSopenharmony_ci                    CAPTURE(N)
892c5f01b2fSopenharmony_ci
893c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
894c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
895c5f01b2fSopenharmony_ci                    json j = s;
896c5f01b2fSopenharmony_ci
897c5f01b2fSopenharmony_ci                    // create expected byte vector (hack: create string first)
898c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(N, 'x');
899c5f01b2fSopenharmony_ci                    // reverse order of commands, because we insert at begin()
900c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
901c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
902c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 'I');
903c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 'S');
904c5f01b2fSopenharmony_ci
905c5f01b2fSopenharmony_ci                    // compare result + size
906c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
907c5f01b2fSopenharmony_ci                    CHECK(result == expected);
908c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 4);
909c5f01b2fSopenharmony_ci                    // check that no null byte is appended
910c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
911c5f01b2fSopenharmony_ci
912c5f01b2fSopenharmony_ci                    // roundtrip
913c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
914c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
915c5f01b2fSopenharmony_ci                }
916c5f01b2fSopenharmony_ci            }
917c5f01b2fSopenharmony_ci
918c5f01b2fSopenharmony_ci            SECTION("N = 65536..2147483647")
919c5f01b2fSopenharmony_ci            {
920c5f01b2fSopenharmony_ci                for (size_t N :
921c5f01b2fSopenharmony_ci                        {
922c5f01b2fSopenharmony_ci                            65536u, 77777u, 1048576u
923c5f01b2fSopenharmony_ci                        })
924c5f01b2fSopenharmony_ci                {
925c5f01b2fSopenharmony_ci                    CAPTURE(N)
926c5f01b2fSopenharmony_ci
927c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
928c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
929c5f01b2fSopenharmony_ci                    json j = s;
930c5f01b2fSopenharmony_ci
931c5f01b2fSopenharmony_ci                    // create expected byte vector (hack: create string first)
932c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(N, 'x');
933c5f01b2fSopenharmony_ci                    // reverse order of commands, because we insert at begin()
934c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
935c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
936c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));
937c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));
938c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 'l');
939c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 'S');
940c5f01b2fSopenharmony_ci
941c5f01b2fSopenharmony_ci                    // compare result + size
942c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
943c5f01b2fSopenharmony_ci                    CHECK(result == expected);
944c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 6);
945c5f01b2fSopenharmony_ci                    // check that no null byte is appended
946c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
947c5f01b2fSopenharmony_ci
948c5f01b2fSopenharmony_ci                    // roundtrip
949c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
950c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
951c5f01b2fSopenharmony_ci                }
952c5f01b2fSopenharmony_ci            }
953c5f01b2fSopenharmony_ci        }
954c5f01b2fSopenharmony_ci
955c5f01b2fSopenharmony_ci        SECTION("binary")
956c5f01b2fSopenharmony_ci        {
957c5f01b2fSopenharmony_ci            SECTION("N = 0..127")
958c5f01b2fSopenharmony_ci            {
959c5f01b2fSopenharmony_ci                for (std::size_t N = 0; N <= 127; ++N)
960c5f01b2fSopenharmony_ci                {
961c5f01b2fSopenharmony_ci                    CAPTURE(N)
962c5f01b2fSopenharmony_ci
963c5f01b2fSopenharmony_ci                    // create JSON value with byte array containing of N * 'x'
964c5f01b2fSopenharmony_ci                    const auto s = std::vector<std::uint8_t>(N, 'x');
965c5f01b2fSopenharmony_ci                    json j = json::binary(s);
966c5f01b2fSopenharmony_ci
967c5f01b2fSopenharmony_ci                    // create expected byte vector
968c5f01b2fSopenharmony_ci                    std::vector<std::uint8_t> expected;
969c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('['));
970c5f01b2fSopenharmony_ci                    if (N != 0)
971c5f01b2fSopenharmony_ci                    {
972c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<std::uint8_t>('$'));
973c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<std::uint8_t>('U'));
974c5f01b2fSopenharmony_ci                    }
975c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('#'));
976c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('i'));
977c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>(N));
978c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
979c5f01b2fSopenharmony_ci                    {
980c5f01b2fSopenharmony_ci                        expected.push_back(0x78);
981c5f01b2fSopenharmony_ci                    }
982c5f01b2fSopenharmony_ci
983c5f01b2fSopenharmony_ci                    // compare result + size
984c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
985c5f01b2fSopenharmony_ci                    CHECK(result == expected);
986c5f01b2fSopenharmony_ci                    if (N == 0)
987c5f01b2fSopenharmony_ci                    {
988c5f01b2fSopenharmony_ci                        CHECK(result.size() == N + 4);
989c5f01b2fSopenharmony_ci                    }
990c5f01b2fSopenharmony_ci                    else
991c5f01b2fSopenharmony_ci                    {
992c5f01b2fSopenharmony_ci                        CHECK(result.size() == N + 6);
993c5f01b2fSopenharmony_ci                    }
994c5f01b2fSopenharmony_ci
995c5f01b2fSopenharmony_ci                    // check that no null byte is appended
996c5f01b2fSopenharmony_ci                    if (N > 0)
997c5f01b2fSopenharmony_ci                    {
998c5f01b2fSopenharmony_ci                        CHECK(result.back() != '\x00');
999c5f01b2fSopenharmony_ci                    }
1000c5f01b2fSopenharmony_ci
1001c5f01b2fSopenharmony_ci                    // roundtrip only works to an array of numbers
1002c5f01b2fSopenharmony_ci                    json j_out = s;
1003c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j_out);
1004c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j_out);
1005c5f01b2fSopenharmony_ci                }
1006c5f01b2fSopenharmony_ci            }
1007c5f01b2fSopenharmony_ci
1008c5f01b2fSopenharmony_ci            SECTION("N = 128..255")
1009c5f01b2fSopenharmony_ci            {
1010c5f01b2fSopenharmony_ci                for (std::size_t N = 128; N <= 255; ++N)
1011c5f01b2fSopenharmony_ci                {
1012c5f01b2fSopenharmony_ci                    CAPTURE(N)
1013c5f01b2fSopenharmony_ci
1014c5f01b2fSopenharmony_ci                    // create JSON value with byte array containing of N * 'x'
1015c5f01b2fSopenharmony_ci                    const auto s = std::vector<std::uint8_t>(N, 'x');
1016c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1017c5f01b2fSopenharmony_ci
1018c5f01b2fSopenharmony_ci                    // create expected byte vector
1019c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
1020c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('['));
1021c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('$'));
1022c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('U'));
1023c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('#'));
1024c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('U'));
1025c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>(N));
1026c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
1027c5f01b2fSopenharmony_ci                    {
1028c5f01b2fSopenharmony_ci                        expected.push_back(0x78);
1029c5f01b2fSopenharmony_ci                    }
1030c5f01b2fSopenharmony_ci
1031c5f01b2fSopenharmony_ci                    // compare result + size
1032c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1033c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1034c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 6);
1035c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1036c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1037c5f01b2fSopenharmony_ci
1038c5f01b2fSopenharmony_ci                    // roundtrip only works to an array of numbers
1039c5f01b2fSopenharmony_ci                    json j_out = s;
1040c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j_out);
1041c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j_out);
1042c5f01b2fSopenharmony_ci                }
1043c5f01b2fSopenharmony_ci            }
1044c5f01b2fSopenharmony_ci
1045c5f01b2fSopenharmony_ci            SECTION("N = 256..32767")
1046c5f01b2fSopenharmony_ci            {
1047c5f01b2fSopenharmony_ci                for (std::size_t N :
1048c5f01b2fSopenharmony_ci                        {
1049c5f01b2fSopenharmony_ci                            256u, 999u, 1025u, 3333u, 2048u, 32767u
1050c5f01b2fSopenharmony_ci                        })
1051c5f01b2fSopenharmony_ci                {
1052c5f01b2fSopenharmony_ci                    CAPTURE(N)
1053c5f01b2fSopenharmony_ci
1054c5f01b2fSopenharmony_ci                    // create JSON value with byte array containing of N * 'x'
1055c5f01b2fSopenharmony_ci                    const auto s = std::vector<std::uint8_t>(N, 'x');
1056c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1057c5f01b2fSopenharmony_ci
1058c5f01b2fSopenharmony_ci                    // create expected byte vector
1059c5f01b2fSopenharmony_ci                    std::vector<std::uint8_t> expected(N + 7, 'x');
1060c5f01b2fSopenharmony_ci                    expected[0] = '[';
1061c5f01b2fSopenharmony_ci                    expected[1] = '$';
1062c5f01b2fSopenharmony_ci                    expected[2] = 'U';
1063c5f01b2fSopenharmony_ci                    expected[3] = '#';
1064c5f01b2fSopenharmony_ci                    expected[4] = 'I';
1065c5f01b2fSopenharmony_ci                    expected[5] = static_cast<std::uint8_t>((N >> 8) & 0xFF);
1066c5f01b2fSopenharmony_ci                    expected[6] = static_cast<std::uint8_t>(N & 0xFF);
1067c5f01b2fSopenharmony_ci
1068c5f01b2fSopenharmony_ci                    // compare result + size
1069c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1070c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1071c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 7);
1072c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1073c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1074c5f01b2fSopenharmony_ci
1075c5f01b2fSopenharmony_ci                    // roundtrip only works to an array of numbers
1076c5f01b2fSopenharmony_ci                    json j_out = s;
1077c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j_out);
1078c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j_out);
1079c5f01b2fSopenharmony_ci                }
1080c5f01b2fSopenharmony_ci            }
1081c5f01b2fSopenharmony_ci
1082c5f01b2fSopenharmony_ci            SECTION("N = 32768..2147483647")
1083c5f01b2fSopenharmony_ci            {
1084c5f01b2fSopenharmony_ci                for (std::size_t N :
1085c5f01b2fSopenharmony_ci                        {
1086c5f01b2fSopenharmony_ci                            32768u, 77777u, 1048576u
1087c5f01b2fSopenharmony_ci                        })
1088c5f01b2fSopenharmony_ci                {
1089c5f01b2fSopenharmony_ci                    CAPTURE(N)
1090c5f01b2fSopenharmony_ci
1091c5f01b2fSopenharmony_ci                    // create JSON value with byte array containing of N * 'x'
1092c5f01b2fSopenharmony_ci                    const auto s = std::vector<std::uint8_t>(N, 'x');
1093c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1094c5f01b2fSopenharmony_ci
1095c5f01b2fSopenharmony_ci                    // create expected byte vector
1096c5f01b2fSopenharmony_ci                    std::vector<std::uint8_t> expected(N + 9, 'x');
1097c5f01b2fSopenharmony_ci                    expected[0] = '[';
1098c5f01b2fSopenharmony_ci                    expected[1] = '$';
1099c5f01b2fSopenharmony_ci                    expected[2] = 'U';
1100c5f01b2fSopenharmony_ci                    expected[3] = '#';
1101c5f01b2fSopenharmony_ci                    expected[4] = 'l';
1102c5f01b2fSopenharmony_ci                    expected[5] = static_cast<std::uint8_t>((N >> 24) & 0xFF);
1103c5f01b2fSopenharmony_ci                    expected[6] = static_cast<std::uint8_t>((N >> 16) & 0xFF);
1104c5f01b2fSopenharmony_ci                    expected[7] = static_cast<std::uint8_t>((N >> 8) & 0xFF);
1105c5f01b2fSopenharmony_ci                    expected[8] = static_cast<std::uint8_t>(N & 0xFF);
1106c5f01b2fSopenharmony_ci
1107c5f01b2fSopenharmony_ci                    // compare result + size
1108c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1109c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1110c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 9);
1111c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1112c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1113c5f01b2fSopenharmony_ci
1114c5f01b2fSopenharmony_ci                    // roundtrip only works to an array of numbers
1115c5f01b2fSopenharmony_ci                    json j_out = s;
1116c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j_out);
1117c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j_out);
1118c5f01b2fSopenharmony_ci                }
1119c5f01b2fSopenharmony_ci            }
1120c5f01b2fSopenharmony_ci
1121c5f01b2fSopenharmony_ci            SECTION("Other Serializations")
1122c5f01b2fSopenharmony_ci            {
1123c5f01b2fSopenharmony_ci                const std::size_t N = 10;
1124c5f01b2fSopenharmony_ci                const auto s = std::vector<std::uint8_t>(N, 'x');
1125c5f01b2fSopenharmony_ci                json j = json::binary(s);
1126c5f01b2fSopenharmony_ci
1127c5f01b2fSopenharmony_ci                SECTION("No Count No Type")
1128c5f01b2fSopenharmony_ci                {
1129c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
1130c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('['));
1131c5f01b2fSopenharmony_ci                    for (std::size_t i = 0; i < N; ++i)
1132c5f01b2fSopenharmony_ci                    {
1133c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<std::uint8_t>('U'));
1134c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<std::uint8_t>(0x78));
1135c5f01b2fSopenharmony_ci                    }
1136c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>(']'));
1137c5f01b2fSopenharmony_ci
1138c5f01b2fSopenharmony_ci                    // compare result + size
1139c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, false, false);
1140c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1141c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 12);
1142c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1143c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1144c5f01b2fSopenharmony_ci
1145c5f01b2fSopenharmony_ci                    // roundtrip only works to an array of numbers
1146c5f01b2fSopenharmony_ci                    json j_out = s;
1147c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j_out);
1148c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j_out);
1149c5f01b2fSopenharmony_ci                }
1150c5f01b2fSopenharmony_ci
1151c5f01b2fSopenharmony_ci                SECTION("Yes Count No Type")
1152c5f01b2fSopenharmony_ci                {
1153c5f01b2fSopenharmony_ci                    std::vector<std::uint8_t> expected;
1154c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('['));
1155c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('#'));
1156c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>('i'));
1157c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<std::uint8_t>(N));
1158c5f01b2fSopenharmony_ci
1159c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
1160c5f01b2fSopenharmony_ci                    {
1161c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<std::uint8_t>('U'));
1162c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<std::uint8_t>(0x78));
1163c5f01b2fSopenharmony_ci                    }
1164c5f01b2fSopenharmony_ci
1165c5f01b2fSopenharmony_ci                    // compare result + size
1166c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, false);
1167c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1168c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 14);
1169c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1170c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1171c5f01b2fSopenharmony_ci
1172c5f01b2fSopenharmony_ci                    // roundtrip only works to an array of numbers
1173c5f01b2fSopenharmony_ci                    json j_out = s;
1174c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j_out);
1175c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j_out);
1176c5f01b2fSopenharmony_ci                }
1177c5f01b2fSopenharmony_ci            }
1178c5f01b2fSopenharmony_ci        }
1179c5f01b2fSopenharmony_ci
1180c5f01b2fSopenharmony_ci        SECTION("array")
1181c5f01b2fSopenharmony_ci        {
1182c5f01b2fSopenharmony_ci            SECTION("empty")
1183c5f01b2fSopenharmony_ci            {
1184c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1185c5f01b2fSopenharmony_ci                {
1186c5f01b2fSopenharmony_ci                    json j = json::array();
1187c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', ']'};
1188c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1189c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1190c5f01b2fSopenharmony_ci
1191c5f01b2fSopenharmony_ci                    // roundtrip
1192c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1193c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1194c5f01b2fSopenharmony_ci                }
1195c5f01b2fSopenharmony_ci
1196c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1197c5f01b2fSopenharmony_ci                {
1198c5f01b2fSopenharmony_ci                    json j = json::array();
1199c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '#', 'i', 0};
1200c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1201c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1202c5f01b2fSopenharmony_ci
1203c5f01b2fSopenharmony_ci                    // roundtrip
1204c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1205c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1206c5f01b2fSopenharmony_ci                }
1207c5f01b2fSopenharmony_ci
1208c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1209c5f01b2fSopenharmony_ci                {
1210c5f01b2fSopenharmony_ci                    json j = json::array();
1211c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '#', 'i', 0};
1212c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1213c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1214c5f01b2fSopenharmony_ci
1215c5f01b2fSopenharmony_ci                    // roundtrip
1216c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1217c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1218c5f01b2fSopenharmony_ci                }
1219c5f01b2fSopenharmony_ci            }
1220c5f01b2fSopenharmony_ci
1221c5f01b2fSopenharmony_ci            SECTION("[null]")
1222c5f01b2fSopenharmony_ci            {
1223c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1224c5f01b2fSopenharmony_ci                {
1225c5f01b2fSopenharmony_ci                    json j = {nullptr};
1226c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', 'Z', ']'};
1227c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1228c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1229c5f01b2fSopenharmony_ci
1230c5f01b2fSopenharmony_ci                    // roundtrip
1231c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1232c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1233c5f01b2fSopenharmony_ci                }
1234c5f01b2fSopenharmony_ci
1235c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1236c5f01b2fSopenharmony_ci                {
1237c5f01b2fSopenharmony_ci                    json j = {nullptr};
1238c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '#', 'i', 1, 'Z'};
1239c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1240c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1241c5f01b2fSopenharmony_ci
1242c5f01b2fSopenharmony_ci                    // roundtrip
1243c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1244c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1245c5f01b2fSopenharmony_ci                }
1246c5f01b2fSopenharmony_ci
1247c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1248c5f01b2fSopenharmony_ci                {
1249c5f01b2fSopenharmony_ci                    json j = {nullptr};
1250c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'i', 1};
1251c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1252c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1253c5f01b2fSopenharmony_ci
1254c5f01b2fSopenharmony_ci                    // roundtrip
1255c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1256c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1257c5f01b2fSopenharmony_ci                }
1258c5f01b2fSopenharmony_ci            }
1259c5f01b2fSopenharmony_ci
1260c5f01b2fSopenharmony_ci            SECTION("[1,2,3,4,5]")
1261c5f01b2fSopenharmony_ci            {
1262c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1263c5f01b2fSopenharmony_ci                {
1264c5f01b2fSopenharmony_ci                    json j = json::parse("[1,2,3,4,5]");
1265c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', 'i', 1, 'i', 2, 'i', 3, 'i', 4, 'i', 5, ']'};
1266c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1267c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1268c5f01b2fSopenharmony_ci
1269c5f01b2fSopenharmony_ci                    // roundtrip
1270c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1271c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1272c5f01b2fSopenharmony_ci                }
1273c5f01b2fSopenharmony_ci
1274c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1275c5f01b2fSopenharmony_ci                {
1276c5f01b2fSopenharmony_ci                    json j = json::parse("[1,2,3,4,5]");
1277c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '#', 'i', 5, 'i', 1, 'i', 2, 'i', 3, 'i', 4, 'i', 5};
1278c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1279c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1280c5f01b2fSopenharmony_ci
1281c5f01b2fSopenharmony_ci                    // roundtrip
1282c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1283c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1284c5f01b2fSopenharmony_ci                }
1285c5f01b2fSopenharmony_ci
1286c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1287c5f01b2fSopenharmony_ci                {
1288c5f01b2fSopenharmony_ci                    json j = json::parse("[1,2,3,4,5]");
1289c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 5, 1, 2, 3, 4, 5};
1290c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1291c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1292c5f01b2fSopenharmony_ci
1293c5f01b2fSopenharmony_ci                    // roundtrip
1294c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1295c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1296c5f01b2fSopenharmony_ci                }
1297c5f01b2fSopenharmony_ci            }
1298c5f01b2fSopenharmony_ci
1299c5f01b2fSopenharmony_ci            SECTION("[[[[]]]]")
1300c5f01b2fSopenharmony_ci            {
1301c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1302c5f01b2fSopenharmony_ci                {
1303c5f01b2fSopenharmony_ci                    json j = json::parse("[[[[]]]]");
1304c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '[', '[', '[', ']', ']', ']', ']'};
1305c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1306c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1307c5f01b2fSopenharmony_ci
1308c5f01b2fSopenharmony_ci                    // roundtrip
1309c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1310c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1311c5f01b2fSopenharmony_ci                }
1312c5f01b2fSopenharmony_ci
1313c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1314c5f01b2fSopenharmony_ci                {
1315c5f01b2fSopenharmony_ci                    json j = json::parse("[[[[]]]]");
1316c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '#', 'i', 1, '[', '#', 'i', 1, '[', '#', 'i', 1, '[', '#', 'i', 0};
1317c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1318c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1319c5f01b2fSopenharmony_ci
1320c5f01b2fSopenharmony_ci                    // roundtrip
1321c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1322c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1323c5f01b2fSopenharmony_ci                }
1324c5f01b2fSopenharmony_ci
1325c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1326c5f01b2fSopenharmony_ci                {
1327c5f01b2fSopenharmony_ci                    json j = json::parse("[[[[]]]]");
1328c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '$', '[', '#', 'i', 1, '$', '[', '#', 'i', 1, '$', '[', '#', 'i', 1, '#', 'i', 0};
1329c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1330c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1331c5f01b2fSopenharmony_ci
1332c5f01b2fSopenharmony_ci                    // roundtrip
1333c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1334c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1335c5f01b2fSopenharmony_ci                }
1336c5f01b2fSopenharmony_ci            }
1337c5f01b2fSopenharmony_ci
1338c5f01b2fSopenharmony_ci            SECTION("array with uint16_t elements")
1339c5f01b2fSopenharmony_ci            {
1340c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1341c5f01b2fSopenharmony_ci                {
1342c5f01b2fSopenharmony_ci                    json j(257, nullptr);
1343c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(j.size() + 2, 'Z'); // all null
1344c5f01b2fSopenharmony_ci                    expected[0] = '['; // opening array
1345c5f01b2fSopenharmony_ci                    expected[258] = ']'; // closing array
1346c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1347c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1348c5f01b2fSopenharmony_ci
1349c5f01b2fSopenharmony_ci                    // roundtrip
1350c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1351c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1352c5f01b2fSopenharmony_ci                }
1353c5f01b2fSopenharmony_ci
1354c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1355c5f01b2fSopenharmony_ci                {
1356c5f01b2fSopenharmony_ci                    json j(257, nullptr);
1357c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(j.size() + 5, 'Z'); // all null
1358c5f01b2fSopenharmony_ci                    expected[0] = '['; // opening array
1359c5f01b2fSopenharmony_ci                    expected[1] = '#'; // array size
1360c5f01b2fSopenharmony_ci                    expected[2] = 'I'; // int16
1361c5f01b2fSopenharmony_ci                    expected[3] = 0x01; // 0x0101, first byte
1362c5f01b2fSopenharmony_ci                    expected[4] = 0x01; // 0x0101, second byte
1363c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1364c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1365c5f01b2fSopenharmony_ci
1366c5f01b2fSopenharmony_ci                    // roundtrip
1367c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1368c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1369c5f01b2fSopenharmony_ci                }
1370c5f01b2fSopenharmony_ci
1371c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1372c5f01b2fSopenharmony_ci                {
1373c5f01b2fSopenharmony_ci                    json j(257, nullptr);
1374c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'I', 0x01, 0x01};
1375c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1376c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1377c5f01b2fSopenharmony_ci
1378c5f01b2fSopenharmony_ci                    // roundtrip
1379c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1380c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1381c5f01b2fSopenharmony_ci                }
1382c5f01b2fSopenharmony_ci            }
1383c5f01b2fSopenharmony_ci
1384c5f01b2fSopenharmony_ci            SECTION("array with uint32_t elements")
1385c5f01b2fSopenharmony_ci            {
1386c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1387c5f01b2fSopenharmony_ci                {
1388c5f01b2fSopenharmony_ci                    json j(65793, nullptr);
1389c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(j.size() + 2, 'Z'); // all null
1390c5f01b2fSopenharmony_ci                    expected[0] = '['; // opening array
1391c5f01b2fSopenharmony_ci                    expected[65794] = ']'; // closing array
1392c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1393c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1394c5f01b2fSopenharmony_ci
1395c5f01b2fSopenharmony_ci                    // roundtrip
1396c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1397c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1398c5f01b2fSopenharmony_ci                }
1399c5f01b2fSopenharmony_ci
1400c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1401c5f01b2fSopenharmony_ci                {
1402c5f01b2fSopenharmony_ci                    json j(65793, nullptr);
1403c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(j.size() + 7, 'Z'); // all null
1404c5f01b2fSopenharmony_ci                    expected[0] = '['; // opening array
1405c5f01b2fSopenharmony_ci                    expected[1] = '#'; // array size
1406c5f01b2fSopenharmony_ci                    expected[2] = 'l'; // int32
1407c5f01b2fSopenharmony_ci                    expected[3] = 0x00; // 0x00010101, first byte
1408c5f01b2fSopenharmony_ci                    expected[4] = 0x01; // 0x00010101, second byte
1409c5f01b2fSopenharmony_ci                    expected[5] = 0x01; // 0x00010101, third byte
1410c5f01b2fSopenharmony_ci                    expected[6] = 0x01; // 0x00010101, fourth byte
1411c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1412c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1413c5f01b2fSopenharmony_ci
1414c5f01b2fSopenharmony_ci                    // roundtrip
1415c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1416c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1417c5f01b2fSopenharmony_ci                }
1418c5f01b2fSopenharmony_ci
1419c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1420c5f01b2fSopenharmony_ci                {
1421c5f01b2fSopenharmony_ci                    json j(65793, nullptr);
1422c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'[', '$', 'Z', '#', 'l', 0x00, 0x01, 0x01, 0x01};
1423c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1424c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1425c5f01b2fSopenharmony_ci
1426c5f01b2fSopenharmony_ci                    // roundtrip
1427c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1428c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1429c5f01b2fSopenharmony_ci                }
1430c5f01b2fSopenharmony_ci            }
1431c5f01b2fSopenharmony_ci        }
1432c5f01b2fSopenharmony_ci
1433c5f01b2fSopenharmony_ci        SECTION("object")
1434c5f01b2fSopenharmony_ci        {
1435c5f01b2fSopenharmony_ci            SECTION("empty")
1436c5f01b2fSopenharmony_ci            {
1437c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1438c5f01b2fSopenharmony_ci                {
1439c5f01b2fSopenharmony_ci                    json j = json::object();
1440c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'{', '}'};
1441c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1442c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1443c5f01b2fSopenharmony_ci
1444c5f01b2fSopenharmony_ci                    // roundtrip
1445c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1446c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1447c5f01b2fSopenharmony_ci                }
1448c5f01b2fSopenharmony_ci
1449c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1450c5f01b2fSopenharmony_ci                {
1451c5f01b2fSopenharmony_ci                    json j = json::object();
1452c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'{', '#', 'i', 0};
1453c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1454c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1455c5f01b2fSopenharmony_ci
1456c5f01b2fSopenharmony_ci                    // roundtrip
1457c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1458c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1459c5f01b2fSopenharmony_ci                }
1460c5f01b2fSopenharmony_ci
1461c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1462c5f01b2fSopenharmony_ci                {
1463c5f01b2fSopenharmony_ci                    json j = json::object();
1464c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'{', '#', 'i', 0};
1465c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1466c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1467c5f01b2fSopenharmony_ci
1468c5f01b2fSopenharmony_ci                    // roundtrip
1469c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1470c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1471c5f01b2fSopenharmony_ci                }
1472c5f01b2fSopenharmony_ci            }
1473c5f01b2fSopenharmony_ci
1474c5f01b2fSopenharmony_ci            SECTION("{\"\":null}")
1475c5f01b2fSopenharmony_ci            {
1476c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1477c5f01b2fSopenharmony_ci                {
1478c5f01b2fSopenharmony_ci                    json j = {{"", nullptr}};
1479c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'{', 'i', 0, 'Z', '}'};
1480c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1481c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1482c5f01b2fSopenharmony_ci
1483c5f01b2fSopenharmony_ci                    // roundtrip
1484c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1485c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1486c5f01b2fSopenharmony_ci                }
1487c5f01b2fSopenharmony_ci
1488c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1489c5f01b2fSopenharmony_ci                {
1490c5f01b2fSopenharmony_ci                    json j = {{"", nullptr}};
1491c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'{', '#', 'i', 1, 'i', 0, 'Z'};
1492c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1493c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1494c5f01b2fSopenharmony_ci
1495c5f01b2fSopenharmony_ci                    // roundtrip
1496c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1497c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1498c5f01b2fSopenharmony_ci                }
1499c5f01b2fSopenharmony_ci
1500c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1501c5f01b2fSopenharmony_ci                {
1502c5f01b2fSopenharmony_ci                    json j = {{"", nullptr}};
1503c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {'{', '$', 'Z', '#', 'i', 1, 'i', 0};
1504c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1505c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1506c5f01b2fSopenharmony_ci
1507c5f01b2fSopenharmony_ci                    // roundtrip
1508c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1509c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1510c5f01b2fSopenharmony_ci                }
1511c5f01b2fSopenharmony_ci            }
1512c5f01b2fSopenharmony_ci
1513c5f01b2fSopenharmony_ci            SECTION("{\"a\": {\"b\": {\"c\": {}}}}")
1514c5f01b2fSopenharmony_ci            {
1515c5f01b2fSopenharmony_ci                SECTION("size=false type=false")
1516c5f01b2fSopenharmony_ci                {
1517c5f01b2fSopenharmony_ci                    json j = json::parse(R"({"a": {"b": {"c": {}}}})");
1518c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
1519c5f01b2fSopenharmony_ci                    {
1520c5f01b2fSopenharmony_ci                        '{', 'i', 1, 'a', '{', 'i', 1, 'b', '{', 'i', 1, 'c', '{', '}', '}', '}', '}'
1521c5f01b2fSopenharmony_ci                    };
1522c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j);
1523c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1524c5f01b2fSopenharmony_ci
1525c5f01b2fSopenharmony_ci                    // roundtrip
1526c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1527c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1528c5f01b2fSopenharmony_ci                }
1529c5f01b2fSopenharmony_ci
1530c5f01b2fSopenharmony_ci                SECTION("size=true type=false")
1531c5f01b2fSopenharmony_ci                {
1532c5f01b2fSopenharmony_ci                    json j = json::parse(R"({"a": {"b": {"c": {}}}})");
1533c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
1534c5f01b2fSopenharmony_ci                    {
1535c5f01b2fSopenharmony_ci                        '{', '#', 'i', 1, 'i', 1, 'a', '{', '#', 'i', 1, 'i', 1, 'b', '{', '#', 'i', 1, 'i', 1, 'c', '{', '#', 'i', 0
1536c5f01b2fSopenharmony_ci                    };
1537c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true);
1538c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1539c5f01b2fSopenharmony_ci
1540c5f01b2fSopenharmony_ci                    // roundtrip
1541c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1542c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1543c5f01b2fSopenharmony_ci                }
1544c5f01b2fSopenharmony_ci
1545c5f01b2fSopenharmony_ci                SECTION("size=true type=true")
1546c5f01b2fSopenharmony_ci                {
1547c5f01b2fSopenharmony_ci                    json j = json::parse(R"({"a": {"b": {"c": {}}}})");
1548c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
1549c5f01b2fSopenharmony_ci                    {
1550c5f01b2fSopenharmony_ci                        '{', '$', '{', '#', 'i', 1, 'i', 1, 'a', '$', '{', '#', 'i', 1, 'i', 1, 'b', '$', '{', '#', 'i', 1, 'i', 1, 'c', '#', 'i', 0
1551c5f01b2fSopenharmony_ci                    };
1552c5f01b2fSopenharmony_ci                    const auto result = json::to_ubjson(j, true, true);
1553c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1554c5f01b2fSopenharmony_ci
1555c5f01b2fSopenharmony_ci                    // roundtrip
1556c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result) == j);
1557c5f01b2fSopenharmony_ci                    CHECK(json::from_ubjson(result, true, false) == j);
1558c5f01b2fSopenharmony_ci                }
1559c5f01b2fSopenharmony_ci            }
1560c5f01b2fSopenharmony_ci        }
1561c5f01b2fSopenharmony_ci    }
1562c5f01b2fSopenharmony_ci
1563c5f01b2fSopenharmony_ci    SECTION("errors")
1564c5f01b2fSopenharmony_ci    {
1565c5f01b2fSopenharmony_ci        SECTION("strict mode")
1566c5f01b2fSopenharmony_ci        {
1567c5f01b2fSopenharmony_ci            std::vector<uint8_t> vec = {'Z', 'Z'};
1568c5f01b2fSopenharmony_ci            SECTION("non-strict mode")
1569c5f01b2fSopenharmony_ci            {
1570c5f01b2fSopenharmony_ci                const auto result = json::from_ubjson(vec, false);
1571c5f01b2fSopenharmony_ci                CHECK(result == json());
1572c5f01b2fSopenharmony_ci            }
1573c5f01b2fSopenharmony_ci
1574c5f01b2fSopenharmony_ci            SECTION("strict mode")
1575c5f01b2fSopenharmony_ci            {
1576c5f01b2fSopenharmony_ci                json _;
1577c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vec), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A", json::parse_error&);
1578c5f01b2fSopenharmony_ci            }
1579c5f01b2fSopenharmony_ci        }
1580c5f01b2fSopenharmony_ci
1581c5f01b2fSopenharmony_ci        SECTION("excessive size")
1582c5f01b2fSopenharmony_ci        {
1583c5f01b2fSopenharmony_ci            SECTION("array")
1584c5f01b2fSopenharmony_ci            {
1585c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
1586c5f01b2fSopenharmony_ci                json _;
1587c5f01b2fSopenharmony_ci                CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
1588c5f01b2fSopenharmony_ci
1589c5f01b2fSopenharmony_ci                json j;
1590c5f01b2fSopenharmony_ci                nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
1591c5f01b2fSopenharmony_ci                {
1592c5f01b2fSopenharmony_ci                    return true;
1593c5f01b2fSopenharmony_ci                });
1594c5f01b2fSopenharmony_ci                CHECK_THROWS_AS(_ = json::sax_parse(v_ubjson, &scp, json::input_format_t::ubjson), json::out_of_range&);
1595c5f01b2fSopenharmony_ci            }
1596c5f01b2fSopenharmony_ci
1597c5f01b2fSopenharmony_ci            SECTION("object")
1598c5f01b2fSopenharmony_ci            {
1599c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_ubjson = {'{', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
1600c5f01b2fSopenharmony_ci                json _;
1601c5f01b2fSopenharmony_ci                CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
1602c5f01b2fSopenharmony_ci
1603c5f01b2fSopenharmony_ci                json j;
1604c5f01b2fSopenharmony_ci                nlohmann::detail::json_sax_dom_callback_parser<json> scp(j, [](int /*unused*/, json::parse_event_t /*unused*/, const json& /*unused*/) noexcept
1605c5f01b2fSopenharmony_ci                {
1606c5f01b2fSopenharmony_ci                    return true;
1607c5f01b2fSopenharmony_ci                });
1608c5f01b2fSopenharmony_ci                CHECK_THROWS_AS(_ = json::sax_parse(v_ubjson, &scp, json::input_format_t::ubjson), json::out_of_range&);
1609c5f01b2fSopenharmony_ci            }
1610c5f01b2fSopenharmony_ci        }
1611c5f01b2fSopenharmony_ci    }
1612c5f01b2fSopenharmony_ci
1613c5f01b2fSopenharmony_ci    SECTION("SAX aborts")
1614c5f01b2fSopenharmony_ci    {
1615c5f01b2fSopenharmony_ci        SECTION("start_array()")
1616c5f01b2fSopenharmony_ci        {
1617c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'[', 'T', 'F', ']'};
1618c5f01b2fSopenharmony_ci            SaxCountdown scp(0);
1619c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));
1620c5f01b2fSopenharmony_ci        }
1621c5f01b2fSopenharmony_ci
1622c5f01b2fSopenharmony_ci        SECTION("start_object()")
1623c5f01b2fSopenharmony_ci        {
1624c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};
1625c5f01b2fSopenharmony_ci            SaxCountdown scp(0);
1626c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));
1627c5f01b2fSopenharmony_ci        }
1628c5f01b2fSopenharmony_ci
1629c5f01b2fSopenharmony_ci        SECTION("key() in object")
1630c5f01b2fSopenharmony_ci        {
1631c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};
1632c5f01b2fSopenharmony_ci            SaxCountdown scp(1);
1633c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));
1634c5f01b2fSopenharmony_ci        }
1635c5f01b2fSopenharmony_ci
1636c5f01b2fSopenharmony_ci        SECTION("start_array(len)")
1637c5f01b2fSopenharmony_ci        {
1638c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'[', '#', 'i', '2', 'T', 'F'};
1639c5f01b2fSopenharmony_ci            SaxCountdown scp(0);
1640c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));
1641c5f01b2fSopenharmony_ci        }
1642c5f01b2fSopenharmony_ci
1643c5f01b2fSopenharmony_ci        SECTION("start_object(len)")
1644c5f01b2fSopenharmony_ci        {
1645c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', '#', 'i', '1', 3, 'f', 'o', 'o', 'F'};
1646c5f01b2fSopenharmony_ci            SaxCountdown scp(0);
1647c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));
1648c5f01b2fSopenharmony_ci        }
1649c5f01b2fSopenharmony_ci
1650c5f01b2fSopenharmony_ci        SECTION("key() in object with length")
1651c5f01b2fSopenharmony_ci        {
1652c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', 'i', 3, 'f', 'o', 'o', 'F', '}'};
1653c5f01b2fSopenharmony_ci            SaxCountdown scp(1);
1654c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::ubjson));
1655c5f01b2fSopenharmony_ci        }
1656c5f01b2fSopenharmony_ci    }
1657c5f01b2fSopenharmony_ci
1658c5f01b2fSopenharmony_ci    SECTION("parsing values")
1659c5f01b2fSopenharmony_ci    {
1660c5f01b2fSopenharmony_ci        SECTION("strings")
1661c5f01b2fSopenharmony_ci        {
1662c5f01b2fSopenharmony_ci            // create a single-character string for all number types
1663c5f01b2fSopenharmony_ci            std::vector<uint8_t> s_i = {'S', 'i', 1, 'a'};
1664c5f01b2fSopenharmony_ci            std::vector<uint8_t> s_U = {'S', 'U', 1, 'a'};
1665c5f01b2fSopenharmony_ci            std::vector<uint8_t> s_I = {'S', 'I', 0, 1, 'a'};
1666c5f01b2fSopenharmony_ci            std::vector<uint8_t> s_l = {'S', 'l', 0, 0, 0, 1, 'a'};
1667c5f01b2fSopenharmony_ci            std::vector<uint8_t> s_L = {'S', 'L', 0, 0, 0, 0, 0, 0, 0, 1, 'a'};
1668c5f01b2fSopenharmony_ci
1669c5f01b2fSopenharmony_ci            // check if string is parsed correctly to "a"
1670c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(s_i) == "a");
1671c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(s_U) == "a");
1672c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(s_I) == "a");
1673c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(s_l) == "a");
1674c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(s_L) == "a");
1675c5f01b2fSopenharmony_ci
1676c5f01b2fSopenharmony_ci            // roundtrip: output should be optimized
1677c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(json::from_ubjson(s_i)) == s_i);
1678c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(json::from_ubjson(s_U)) == s_i);
1679c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(json::from_ubjson(s_I)) == s_i);
1680c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(json::from_ubjson(s_l)) == s_i);
1681c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(json::from_ubjson(s_L)) == s_i);
1682c5f01b2fSopenharmony_ci        }
1683c5f01b2fSopenharmony_ci
1684c5f01b2fSopenharmony_ci        SECTION("number")
1685c5f01b2fSopenharmony_ci        {
1686c5f01b2fSopenharmony_ci            SECTION("float")
1687c5f01b2fSopenharmony_ci            {
1688c5f01b2fSopenharmony_ci                // float32
1689c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_d = {'d', 0x40, 0x49, 0x0f, 0xd0};
1690c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_d) == 3.14159f);
1691c5f01b2fSopenharmony_ci
1692c5f01b2fSopenharmony_ci                // float64
1693c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_D = {'D', 0x40, 0x09, 0x21, 0xf9, 0xf0, 0x1b, 0x86, 0x6e};
1694c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_D) == 3.14159);
1695c5f01b2fSopenharmony_ci
1696c5f01b2fSopenharmony_ci                // float32 is serialized as float64 as the library does not support float32
1697c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_d)) == json::to_ubjson(3.14159f));
1698c5f01b2fSopenharmony_ci            }
1699c5f01b2fSopenharmony_ci        }
1700c5f01b2fSopenharmony_ci
1701c5f01b2fSopenharmony_ci        SECTION("array")
1702c5f01b2fSopenharmony_ci        {
1703c5f01b2fSopenharmony_ci            SECTION("optimized version (length only)")
1704c5f01b2fSopenharmony_ci            {
1705c5f01b2fSopenharmony_ci                // create vector with two elements of the same type
1706c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_TU = {'[', '#', 'U', 2, 'T', 'T'};
1707c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_T = {'[', '#', 'i', 2, 'T', 'T'};
1708c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_F = {'[', '#', 'i', 2, 'F', 'F'};
1709c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_Z = {'[', '#', 'i', 2, 'Z', 'Z'};
1710c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_i = {'[', '#', 'i', 2, 'i', 0x7F, 'i', 0x7F};
1711c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_U = {'[', '#', 'i', 2, 'U', 0xFF, 'U', 0xFF};
1712c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_I = {'[', '#', 'i', 2, 'I', 0x7F, 0xFF, 'I', 0x7F, 0xFF};
1713c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_l = {'[', '#', 'i', 2, 'l', 0x7F, 0xFF, 0xFF, 0xFF, 'l', 0x7F, 0xFF, 0xFF, 0xFF};
1714c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_L = {'[', '#', 'i', 2, 'L', 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'L', 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1715c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_D = {'[', '#', 'i', 2, 'D', 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a, 'D', 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a};
1716c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_S = {'[', '#', 'i', 2, 'S', 'i', 1, 'a', 'S', 'i', 1, 'a'};
1717c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_C = {'[', '#', 'i', 2, 'C', 'a', 'C', 'a'};
1718c5f01b2fSopenharmony_ci
1719c5f01b2fSopenharmony_ci                // check if vector is parsed correctly
1720c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_TU) == json({true, true}));
1721c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_T) == json({true, true}));
1722c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_F) == json({false, false}));
1723c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_Z) == json({nullptr, nullptr}));
1724c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_i) == json({127, 127}));
1725c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_U) == json({255, 255}));
1726c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_I) == json({32767, 32767}));
1727c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_l) == json({2147483647, 2147483647}));
1728c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_L) == json({9223372036854775807, 9223372036854775807}));
1729c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_D) == json({3.1415926, 3.1415926}));
1730c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_S) == json({"a", "a"}));
1731c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_C) == json({"a", "a"}));
1732c5f01b2fSopenharmony_ci
1733c5f01b2fSopenharmony_ci                // roundtrip: output should be optimized
1734c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_T), true) == v_T);
1735c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_F), true) == v_F);
1736c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_Z), true) == v_Z);
1737c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_i), true) == v_i);
1738c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_U), true) == v_U);
1739c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_I), true) == v_I);
1740c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_l), true) == v_l);
1741c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_L), true) == v_L);
1742c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_D), true) == v_D);
1743c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_S), true) == v_S);
1744c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_C), true) == v_S); // char is serialized to string
1745c5f01b2fSopenharmony_ci            }
1746c5f01b2fSopenharmony_ci
1747c5f01b2fSopenharmony_ci            SECTION("optimized version (type and length)")
1748c5f01b2fSopenharmony_ci            {
1749c5f01b2fSopenharmony_ci                // create vector with two elements of the same type
1750c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_N = {'[', '$', 'N', '#', 'i', 2};
1751c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_T = {'[', '$', 'T', '#', 'i', 2};
1752c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_F = {'[', '$', 'F', '#', 'i', 2};
1753c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_Z = {'[', '$', 'Z', '#', 'i', 2};
1754c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_i = {'[', '$', 'i', '#', 'i', 2, 0x7F, 0x7F};
1755c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_U = {'[', '$', 'U', '#', 'i', 2, 0xFF, 0xFF};
1756c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_I = {'[', '$', 'I', '#', 'i', 2, 0x7F, 0xFF, 0x7F, 0xFF};
1757c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_l = {'[', '$', 'l', '#', 'i', 2, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF};
1758c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_L = {'[', '$', 'L', '#', 'i', 2, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1759c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_D = {'[', '$', 'D', '#', 'i', 2, 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a, 0x40, 0x09, 0x21, 0xfb, 0x4d, 0x12, 0xd8, 0x4a};
1760c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_S = {'[', '$', 'S', '#', 'i', 2, 'i', 1, 'a', 'i', 1, 'a'};
1761c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_C = {'[', '$', 'C', '#', 'i', 2, 'a', 'a'};
1762c5f01b2fSopenharmony_ci
1763c5f01b2fSopenharmony_ci                // check if vector is parsed correctly
1764c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_N) == json::array());
1765c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_T) == json({true, true}));
1766c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_F) == json({false, false}));
1767c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_Z) == json({nullptr, nullptr}));
1768c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_i) == json({127, 127}));
1769c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_U) == json({255, 255}));
1770c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_I) == json({32767, 32767}));
1771c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_l) == json({2147483647, 2147483647}));
1772c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_L) == json({9223372036854775807, 9223372036854775807}));
1773c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_D) == json({3.1415926, 3.1415926}));
1774c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_S) == json({"a", "a"}));
1775c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v_C) == json({"a", "a"}));
1776c5f01b2fSopenharmony_ci
1777c5f01b2fSopenharmony_ci                // roundtrip: output should be optimized
1778c5f01b2fSopenharmony_ci                std::vector<uint8_t> v_empty = {'[', '#', 'i', 0};
1779c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_N), true, true) == v_empty);
1780c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_T), true, true) == v_T);
1781c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_F), true, true) == v_F);
1782c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_Z), true, true) == v_Z);
1783c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_i), true, true) == v_i);
1784c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_U), true, true) == v_U);
1785c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_I), true, true) == v_I);
1786c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_l), true, true) == v_l);
1787c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_L), true, true) == v_L);
1788c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_D), true, true) == v_D);
1789c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_S), true, true) == v_S);
1790c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(json::from_ubjson(v_C), true, true) == v_S); // char is serialized to string
1791c5f01b2fSopenharmony_ci            }
1792c5f01b2fSopenharmony_ci        }
1793c5f01b2fSopenharmony_ci    }
1794c5f01b2fSopenharmony_ci
1795c5f01b2fSopenharmony_ci    SECTION("parse errors")
1796c5f01b2fSopenharmony_ci    {
1797c5f01b2fSopenharmony_ci        SECTION("empty byte vector")
1798c5f01b2fSopenharmony_ci        {
1799c5f01b2fSopenharmony_ci            json _;
1800c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(std::vector<uint8_t>()), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1801c5f01b2fSopenharmony_ci        }
1802c5f01b2fSopenharmony_ci
1803c5f01b2fSopenharmony_ci        SECTION("char")
1804c5f01b2fSopenharmony_ci        {
1805c5f01b2fSopenharmony_ci            SECTION("eof after C byte")
1806c5f01b2fSopenharmony_ci            {
1807c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'C'};
1808c5f01b2fSopenharmony_ci                json _;
1809c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input", json::parse_error&);
1810c5f01b2fSopenharmony_ci            }
1811c5f01b2fSopenharmony_ci
1812c5f01b2fSopenharmony_ci            SECTION("byte out of range")
1813c5f01b2fSopenharmony_ci            {
1814c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'C', 130};
1815c5f01b2fSopenharmony_ci                json _;
1816c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82", json::parse_error&);
1817c5f01b2fSopenharmony_ci            }
1818c5f01b2fSopenharmony_ci        }
1819c5f01b2fSopenharmony_ci
1820c5f01b2fSopenharmony_ci        SECTION("strings")
1821c5f01b2fSopenharmony_ci        {
1822c5f01b2fSopenharmony_ci            SECTION("eof after S byte")
1823c5f01b2fSopenharmony_ci            {
1824c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'S'};
1825c5f01b2fSopenharmony_ci                json _;
1826c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1827c5f01b2fSopenharmony_ci            }
1828c5f01b2fSopenharmony_ci
1829c5f01b2fSopenharmony_ci            SECTION("invalid byte")
1830c5f01b2fSopenharmony_ci            {
1831c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'S', '1', 'a'};
1832c5f01b2fSopenharmony_ci                json _;
1833c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31", json::parse_error&);
1834c5f01b2fSopenharmony_ci            }
1835c5f01b2fSopenharmony_ci        }
1836c5f01b2fSopenharmony_ci
1837c5f01b2fSopenharmony_ci        SECTION("array")
1838c5f01b2fSopenharmony_ci        {
1839c5f01b2fSopenharmony_ci            SECTION("optimized array: no size following type")
1840c5f01b2fSopenharmony_ci            {
1841c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'[', '$', 'i', 2};
1842c5f01b2fSopenharmony_ci                json _;
1843c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02", json::parse_error&);
1844c5f01b2fSopenharmony_ci            }
1845c5f01b2fSopenharmony_ci        }
1846c5f01b2fSopenharmony_ci
1847c5f01b2fSopenharmony_ci        SECTION("strings")
1848c5f01b2fSopenharmony_ci        {
1849c5f01b2fSopenharmony_ci            std::vector<uint8_t> vS = {'S'};
1850c5f01b2fSopenharmony_ci            json _;
1851c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1852c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vS, true, false).is_discarded());
1853c5f01b2fSopenharmony_ci
1854c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'S', 'i', '2', 'a'};
1855c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON string: unexpected end of input", json::parse_error&);
1856c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v, true, false).is_discarded());
1857c5f01b2fSopenharmony_ci
1858c5f01b2fSopenharmony_ci            std::vector<uint8_t> vC = {'C'};
1859c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vC), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input", json::parse_error&);
1860c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vC, true, false).is_discarded());
1861c5f01b2fSopenharmony_ci        }
1862c5f01b2fSopenharmony_ci
1863c5f01b2fSopenharmony_ci        SECTION("sizes")
1864c5f01b2fSopenharmony_ci        {
1865c5f01b2fSopenharmony_ci            std::vector<uint8_t> vU = {'[', '#', 'U'};
1866c5f01b2fSopenharmony_ci            json _;
1867c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vU), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1868c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vU, true, false).is_discarded());
1869c5f01b2fSopenharmony_ci
1870c5f01b2fSopenharmony_ci            std::vector<uint8_t> vi = {'[', '#', 'i'};
1871c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1872c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vi, true, false).is_discarded());
1873c5f01b2fSopenharmony_ci
1874c5f01b2fSopenharmony_ci            std::vector<uint8_t> vI = {'[', '#', 'I'};
1875c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vI), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1876c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vI, true, false).is_discarded());
1877c5f01b2fSopenharmony_ci
1878c5f01b2fSopenharmony_ci            std::vector<uint8_t> vl = {'[', '#', 'l'};
1879c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vl), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1880c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vl, true, false).is_discarded());
1881c5f01b2fSopenharmony_ci
1882c5f01b2fSopenharmony_ci            std::vector<uint8_t> vL = {'[', '#', 'L'};
1883c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vL), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1884c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vL, true, false).is_discarded());
1885c5f01b2fSopenharmony_ci
1886c5f01b2fSopenharmony_ci            std::vector<uint8_t> v0 = {'[', '#', 'T', ']'};
1887c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v0), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x54", json::parse_error&);
1888c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v0, true, false).is_discarded());
1889c5f01b2fSopenharmony_ci        }
1890c5f01b2fSopenharmony_ci
1891c5f01b2fSopenharmony_ci        SECTION("types")
1892c5f01b2fSopenharmony_ci        {
1893c5f01b2fSopenharmony_ci            std::vector<uint8_t> v0 = {'[', '$'};
1894c5f01b2fSopenharmony_ci            json _;
1895c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v0), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing UBJSON type: unexpected end of input", json::parse_error&);
1896c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v0, true, false).is_discarded());
1897c5f01b2fSopenharmony_ci
1898c5f01b2fSopenharmony_ci            std::vector<uint8_t> vi = {'[', '$', '#'};
1899c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1900c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vi, true, false).is_discarded());
1901c5f01b2fSopenharmony_ci
1902c5f01b2fSopenharmony_ci            std::vector<uint8_t> vT = {'[', '$', 'T'};
1903c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vT), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1904c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vT, true, false).is_discarded());
1905c5f01b2fSopenharmony_ci        }
1906c5f01b2fSopenharmony_ci
1907c5f01b2fSopenharmony_ci        SECTION("arrays")
1908c5f01b2fSopenharmony_ci        {
1909c5f01b2fSopenharmony_ci            std::vector<uint8_t> vST = {'[', '$', 'i', '#', 'i', 2, 1};
1910c5f01b2fSopenharmony_ci            json _;
1911c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1912c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vST, true, false).is_discarded());
1913c5f01b2fSopenharmony_ci
1914c5f01b2fSopenharmony_ci            std::vector<uint8_t> vS = {'[', '#', 'i', 2, 'i', 1};
1915c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1916c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vS, true, false).is_discarded());
1917c5f01b2fSopenharmony_ci
1918c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'[', 'i', 2, 'i', 1};
1919c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1920c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v, true, false).is_discarded());
1921c5f01b2fSopenharmony_ci        }
1922c5f01b2fSopenharmony_ci
1923c5f01b2fSopenharmony_ci        SECTION("objects")
1924c5f01b2fSopenharmony_ci        {
1925c5f01b2fSopenharmony_ci            std::vector<uint8_t> vST = {'{', '$', 'i', '#', 'i', 2, 'i', 1, 'a', 1};
1926c5f01b2fSopenharmony_ci            json _;
1927c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 11: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1928c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vST, true, false).is_discarded());
1929c5f01b2fSopenharmony_ci
1930c5f01b2fSopenharmony_ci            std::vector<uint8_t> vT = {'{', '$', 'i', 'i', 1, 'a', 1};
1931c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vT), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x69", json::parse_error&);
1932c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vT, true, false).is_discarded());
1933c5f01b2fSopenharmony_ci
1934c5f01b2fSopenharmony_ci            std::vector<uint8_t> vS = {'{', '#', 'i', 2, 'i', 1, 'a', 'i', 1};
1935c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1936c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vS, true, false).is_discarded());
1937c5f01b2fSopenharmony_ci
1938c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', 'i', 1, 'a', 'i', 1};
1939c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1940c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v, true, false).is_discarded());
1941c5f01b2fSopenharmony_ci
1942c5f01b2fSopenharmony_ci            std::vector<uint8_t> v2 = {'{', 'i', 1, 'a', 'i', 1, 'i'};
1943c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v2), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1944c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v2, true, false).is_discarded());
1945c5f01b2fSopenharmony_ci
1946c5f01b2fSopenharmony_ci            std::vector<uint8_t> v3 = {'{', 'i', 1, 'a'};
1947c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(v3), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1948c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v3, true, false).is_discarded());
1949c5f01b2fSopenharmony_ci
1950c5f01b2fSopenharmony_ci            std::vector<uint8_t> vST1 = {'{', '$', 'd', '#', 'i', 2, 'i', 1, 'a'};
1951c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vST1), "[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON number: unexpected end of input", json::parse_error&);
1952c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vST1, true, false).is_discarded());
1953c5f01b2fSopenharmony_ci
1954c5f01b2fSopenharmony_ci            std::vector<uint8_t> vST2 = {'{', '#', 'i', 2, 'i', 1, 'a'};
1955c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_ubjson(vST2), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON value: unexpected end of input", json::parse_error&);
1956c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(vST2, true, false).is_discarded());
1957c5f01b2fSopenharmony_ci        }
1958c5f01b2fSopenharmony_ci    }
1959c5f01b2fSopenharmony_ci
1960c5f01b2fSopenharmony_ci    SECTION("writing optimized values")
1961c5f01b2fSopenharmony_ci    {
1962c5f01b2fSopenharmony_ci        SECTION("integer")
1963c5f01b2fSopenharmony_ci        {
1964c5f01b2fSopenharmony_ci            SECTION("array of i")
1965c5f01b2fSopenharmony_ci            {
1966c5f01b2fSopenharmony_ci                json j = {1, -1};
1967c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 2, 1, 0xff};
1968c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
1969c5f01b2fSopenharmony_ci            }
1970c5f01b2fSopenharmony_ci
1971c5f01b2fSopenharmony_ci            SECTION("array of U")
1972c5f01b2fSopenharmony_ci            {
1973c5f01b2fSopenharmony_ci                json j = {200, 201};
1974c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'U', '#', 'i', 2, 0xC8, 0xC9};
1975c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
1976c5f01b2fSopenharmony_ci            }
1977c5f01b2fSopenharmony_ci
1978c5f01b2fSopenharmony_ci            SECTION("array of I")
1979c5f01b2fSopenharmony_ci            {
1980c5f01b2fSopenharmony_ci                json j = {30000, -30000};
1981c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'I', '#', 'i', 2, 0x75, 0x30, 0x8a, 0xd0};
1982c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
1983c5f01b2fSopenharmony_ci            }
1984c5f01b2fSopenharmony_ci
1985c5f01b2fSopenharmony_ci            SECTION("array of l")
1986c5f01b2fSopenharmony_ci            {
1987c5f01b2fSopenharmony_ci                json j = {70000, -70000};
1988c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'l', '#', 'i', 2, 0x00, 0x01, 0x11, 0x70, 0xFF, 0xFE, 0xEE, 0x90};
1989c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
1990c5f01b2fSopenharmony_ci            }
1991c5f01b2fSopenharmony_ci
1992c5f01b2fSopenharmony_ci            SECTION("array of L")
1993c5f01b2fSopenharmony_ci            {
1994c5f01b2fSopenharmony_ci                json j = {5000000000, -5000000000};
1995c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'L', '#', 'i', 2, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0xD5, 0xFA, 0x0E, 0x00};
1996c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
1997c5f01b2fSopenharmony_ci            }
1998c5f01b2fSopenharmony_ci        }
1999c5f01b2fSopenharmony_ci
2000c5f01b2fSopenharmony_ci        SECTION("unsigned integer")
2001c5f01b2fSopenharmony_ci        {
2002c5f01b2fSopenharmony_ci            SECTION("array of i")
2003c5f01b2fSopenharmony_ci            {
2004c5f01b2fSopenharmony_ci                json j = {1u, 2u};
2005c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'i', '#', 'i', 2, 1, 2};
2006c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'i', 1, 'i', 2};
2007c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
2008c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == expected_size);
2009c5f01b2fSopenharmony_ci            }
2010c5f01b2fSopenharmony_ci
2011c5f01b2fSopenharmony_ci            SECTION("array of U")
2012c5f01b2fSopenharmony_ci            {
2013c5f01b2fSopenharmony_ci                json j = {200u, 201u};
2014c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'U', '#', 'i', 2, 0xC8, 0xC9};
2015c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'U', 0xC8, 'U', 0xC9};
2016c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
2017c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == expected_size);
2018c5f01b2fSopenharmony_ci            }
2019c5f01b2fSopenharmony_ci
2020c5f01b2fSopenharmony_ci            SECTION("array of I")
2021c5f01b2fSopenharmony_ci            {
2022c5f01b2fSopenharmony_ci                json j = {30000u, 30001u};
2023c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'I', '#', 'i', 2, 0x75, 0x30, 0x75, 0x31};
2024c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'I', 0x75, 0x30, 'I', 0x75, 0x31};
2025c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
2026c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == expected_size);
2027c5f01b2fSopenharmony_ci            }
2028c5f01b2fSopenharmony_ci
2029c5f01b2fSopenharmony_ci            SECTION("array of l")
2030c5f01b2fSopenharmony_ci            {
2031c5f01b2fSopenharmony_ci                json j = {70000u, 70001u};
2032c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'l', '#', 'i', 2, 0x00, 0x01, 0x11, 0x70, 0x00, 0x01, 0x11, 0x71};
2033c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'l', 0x00, 0x01, 0x11, 0x70, 'l', 0x00, 0x01, 0x11, 0x71};
2034c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
2035c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == expected_size);
2036c5f01b2fSopenharmony_ci            }
2037c5f01b2fSopenharmony_ci
2038c5f01b2fSopenharmony_ci            SECTION("array of L")
2039c5f01b2fSopenharmony_ci            {
2040c5f01b2fSopenharmony_ci                json j = {5000000000u, 5000000001u};
2041c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {'[', '$', 'L', '#', 'i', 2, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x01};
2042c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected_size = {'[', '#', 'i', 2, 'L', 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x00, 'L', 0x00, 0x00, 0x00, 0x01, 0x2A, 0x05, 0xF2, 0x01};
2043c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == expected);
2044c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == expected_size);
2045c5f01b2fSopenharmony_ci            }
2046c5f01b2fSopenharmony_ci        }
2047c5f01b2fSopenharmony_ci
2048c5f01b2fSopenharmony_ci        SECTION("discarded")
2049c5f01b2fSopenharmony_ci        {
2050c5f01b2fSopenharmony_ci            json j = {json::value_t::discarded, json::value_t::discarded};
2051c5f01b2fSopenharmony_ci            std::vector<uint8_t> expected = {'[', '$', 'N', '#', 'i', 2};
2052c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j, true, true) == expected);
2053c5f01b2fSopenharmony_ci        }
2054c5f01b2fSopenharmony_ci    }
2055c5f01b2fSopenharmony_ci}
2056c5f01b2fSopenharmony_ci
2057c5f01b2fSopenharmony_ciTEST_CASE("Universal Binary JSON Specification Examples 1")
2058c5f01b2fSopenharmony_ci{
2059c5f01b2fSopenharmony_ci    SECTION("Null Value")
2060c5f01b2fSopenharmony_ci    {
2061c5f01b2fSopenharmony_ci        json j = {{"passcode", nullptr}};
2062c5f01b2fSopenharmony_ci        std::vector<uint8_t> v = {'{', 'i', 8, 'p', 'a', 's', 's', 'c', 'o', 'd', 'e', 'Z', '}'};
2063c5f01b2fSopenharmony_ci        CHECK(json::to_ubjson(j) == v);
2064c5f01b2fSopenharmony_ci        CHECK(json::from_ubjson(v) == j);
2065c5f01b2fSopenharmony_ci    }
2066c5f01b2fSopenharmony_ci
2067c5f01b2fSopenharmony_ci    SECTION("No-Op Value")
2068c5f01b2fSopenharmony_ci    {
2069c5f01b2fSopenharmony_ci        json j = {"foo", "bar", "baz"};
2070c5f01b2fSopenharmony_ci        std::vector<uint8_t> v = {'[', 'S', 'i', 3, 'f', 'o', 'o',
2071c5f01b2fSopenharmony_ci                                  'S', 'i', 3, 'b', 'a', 'r',
2072c5f01b2fSopenharmony_ci                                  'S', 'i', 3, 'b', 'a', 'z', ']'
2073c5f01b2fSopenharmony_ci                                 };
2074c5f01b2fSopenharmony_ci        std::vector<uint8_t> v2 = {'[', 'S', 'i', 3, 'f', 'o', 'o', 'N',
2075c5f01b2fSopenharmony_ci                                   'S', 'i', 3, 'b', 'a', 'r', 'N', 'N', 'N',
2076c5f01b2fSopenharmony_ci                                   'S', 'i', 3, 'b', 'a', 'z', 'N', 'N', ']'
2077c5f01b2fSopenharmony_ci                                  };
2078c5f01b2fSopenharmony_ci        CHECK(json::to_ubjson(j) == v);
2079c5f01b2fSopenharmony_ci        CHECK(json::from_ubjson(v) == j);
2080c5f01b2fSopenharmony_ci        CHECK(json::from_ubjson(v2) == j);
2081c5f01b2fSopenharmony_ci    }
2082c5f01b2fSopenharmony_ci
2083c5f01b2fSopenharmony_ci    SECTION("Boolean Types")
2084c5f01b2fSopenharmony_ci    {
2085c5f01b2fSopenharmony_ci        json j = {{"authorized", true}, {"verified", false}};
2086c5f01b2fSopenharmony_ci        std::vector<uint8_t> v = {'{', 'i', 10, 'a', 'u', 't', 'h', 'o', 'r', 'i', 'z', 'e', 'd', 'T',
2087c5f01b2fSopenharmony_ci                                  'i', 8, 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'F', '}'
2088c5f01b2fSopenharmony_ci                                 };
2089c5f01b2fSopenharmony_ci        CHECK(json::to_ubjson(j) == v);
2090c5f01b2fSopenharmony_ci        CHECK(json::from_ubjson(v) == j);
2091c5f01b2fSopenharmony_ci    }
2092c5f01b2fSopenharmony_ci
2093c5f01b2fSopenharmony_ci    SECTION("Numeric Types")
2094c5f01b2fSopenharmony_ci    {
2095c5f01b2fSopenharmony_ci        json j =
2096c5f01b2fSopenharmony_ci        {
2097c5f01b2fSopenharmony_ci            {"int8", 16},
2098c5f01b2fSopenharmony_ci            {"uint8", 255},
2099c5f01b2fSopenharmony_ci            {"int16", 32767},
2100c5f01b2fSopenharmony_ci            {"int32", 2147483647},
2101c5f01b2fSopenharmony_ci            {"int64", 9223372036854775807},
2102c5f01b2fSopenharmony_ci            {"float64", 113243.7863123}
2103c5f01b2fSopenharmony_ci        };
2104c5f01b2fSopenharmony_ci        std::vector<uint8_t> v = {'{',
2105c5f01b2fSopenharmony_ci                                  'i', 7, 'f', 'l', 'o', 'a', 't', '6', '4', 'D', 0x40, 0xfb, 0xa5, 0xbc, 0x94, 0xbc, 0x34, 0xcf,
2106c5f01b2fSopenharmony_ci                                  'i', 5, 'i', 'n', 't', '1', '6', 'I', 0x7f, 0xff,
2107c5f01b2fSopenharmony_ci                                  'i', 5, 'i', 'n', 't', '3', '2', 'l', 0x7f, 0xff, 0xff, 0xff,
2108c5f01b2fSopenharmony_ci                                  'i', 5, 'i', 'n', 't', '6', '4', 'L', 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2109c5f01b2fSopenharmony_ci                                  'i', 4, 'i', 'n', 't', '8', 'i', 16,
2110c5f01b2fSopenharmony_ci                                  'i', 5, 'u', 'i', 'n', 't', '8', 'U', 0xff,
2111c5f01b2fSopenharmony_ci                                  '}'
2112c5f01b2fSopenharmony_ci                                 };
2113c5f01b2fSopenharmony_ci        CHECK(json::to_ubjson(j) == v);
2114c5f01b2fSopenharmony_ci        CHECK(json::from_ubjson(v) == j);
2115c5f01b2fSopenharmony_ci    }
2116c5f01b2fSopenharmony_ci
2117c5f01b2fSopenharmony_ci    SECTION("Char Type")
2118c5f01b2fSopenharmony_ci    {
2119c5f01b2fSopenharmony_ci        json j = {{"rolecode", "a"}, {"delim", ";"}};
2120c5f01b2fSopenharmony_ci        std::vector<uint8_t> v = {'{', 'i', 5, 'd', 'e', 'l', 'i', 'm', 'C', ';', 'i', 8, 'r', 'o', 'l', 'e', 'c', 'o', 'd', 'e', 'C', 'a', '}'};
2121c5f01b2fSopenharmony_ci        //CHECK(json::to_ubjson(j) == v);
2122c5f01b2fSopenharmony_ci        CHECK(json::from_ubjson(v) == j);
2123c5f01b2fSopenharmony_ci    }
2124c5f01b2fSopenharmony_ci
2125c5f01b2fSopenharmony_ci    SECTION("String Type")
2126c5f01b2fSopenharmony_ci    {
2127c5f01b2fSopenharmony_ci        SECTION("English")
2128c5f01b2fSopenharmony_ci        {
2129c5f01b2fSopenharmony_ci            json j = "hello";
2130c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'S', 'i', 5, 'h', 'e', 'l', 'l', 'o'};
2131c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j) == v);
2132c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2133c5f01b2fSopenharmony_ci        }
2134c5f01b2fSopenharmony_ci
2135c5f01b2fSopenharmony_ci        SECTION("Russian")
2136c5f01b2fSopenharmony_ci        {
2137c5f01b2fSopenharmony_ci            json j = "привет";
2138c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'S', 'i', 12, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x82};
2139c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j) == v);
2140c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2141c5f01b2fSopenharmony_ci        }
2142c5f01b2fSopenharmony_ci
2143c5f01b2fSopenharmony_ci        SECTION("Russian")
2144c5f01b2fSopenharmony_ci        {
2145c5f01b2fSopenharmony_ci            json j = "مرحبا";
2146c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'S', 'i', 10, 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7};
2147c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j) == v);
2148c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2149c5f01b2fSopenharmony_ci        }
2150c5f01b2fSopenharmony_ci    }
2151c5f01b2fSopenharmony_ci
2152c5f01b2fSopenharmony_ci    SECTION("Array Type")
2153c5f01b2fSopenharmony_ci    {
2154c5f01b2fSopenharmony_ci        SECTION("size=false type=false")
2155c5f01b2fSopenharmony_ci        {
2156c5f01b2fSopenharmony_ci            // note the float has been replaced by a double
2157c5f01b2fSopenharmony_ci            json j = {nullptr, true, false, 4782345193, 153.132, "ham"};
2158c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'[', 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm', ']'};
2159c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j) == v);
2160c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2161c5f01b2fSopenharmony_ci        }
2162c5f01b2fSopenharmony_ci
2163c5f01b2fSopenharmony_ci        SECTION("size=true type=false")
2164c5f01b2fSopenharmony_ci        {
2165c5f01b2fSopenharmony_ci            // note the float has been replaced by a double
2166c5f01b2fSopenharmony_ci            json j = {nullptr, true, false, 4782345193, 153.132, "ham"};
2167c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'[', '#', 'i', 6, 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm'};
2168c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j, true) == v);
2169c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2170c5f01b2fSopenharmony_ci        }
2171c5f01b2fSopenharmony_ci
2172c5f01b2fSopenharmony_ci        SECTION("size=true type=true")
2173c5f01b2fSopenharmony_ci        {
2174c5f01b2fSopenharmony_ci            // note the float has been replaced by a double
2175c5f01b2fSopenharmony_ci            json j = {nullptr, true, false, 4782345193, 153.132, "ham"};
2176c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'[', '#', 'i', 6, 'Z', 'T', 'F', 'L', 0x00, 0x00, 0x00, 0x01, 0x1D, 0x0C, 0xCB, 0xE9, 'D', 0x40, 0x63, 0x24, 0x39, 0x58, 0x10, 0x62, 0x4e, 'S', 'i', 3, 'h', 'a', 'm'};
2177c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j, true, true) == v);
2178c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2179c5f01b2fSopenharmony_ci        }
2180c5f01b2fSopenharmony_ci    }
2181c5f01b2fSopenharmony_ci
2182c5f01b2fSopenharmony_ci    SECTION("Object Type")
2183c5f01b2fSopenharmony_ci    {
2184c5f01b2fSopenharmony_ci        SECTION("size=false type=false")
2185c5f01b2fSopenharmony_ci        {
2186c5f01b2fSopenharmony_ci            json j =
2187c5f01b2fSopenharmony_ci            {
2188c5f01b2fSopenharmony_ci                {
2189c5f01b2fSopenharmony_ci                    "post", {
2190c5f01b2fSopenharmony_ci                        {"id", 1137},
2191c5f01b2fSopenharmony_ci                        {"author", "rkalla"},
2192c5f01b2fSopenharmony_ci                        {"timestamp", 1364482090592},
2193c5f01b2fSopenharmony_ci                        {"body", "I totally agree!"}
2194c5f01b2fSopenharmony_ci                    }
2195c5f01b2fSopenharmony_ci                }
2196c5f01b2fSopenharmony_ci            };
2197c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', 'i', 4, 'p', 'o', 's', 't', '{',
2198c5f01b2fSopenharmony_ci                                      'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',
2199c5f01b2fSopenharmony_ci                                      'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',
2200c5f01b2fSopenharmony_ci                                      'i', 2, 'i', 'd', 'I', 0x04, 0x71,
2201c5f01b2fSopenharmony_ci                                      'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60,
2202c5f01b2fSopenharmony_ci                                      '}', '}'
2203c5f01b2fSopenharmony_ci                                     };
2204c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j) == v);
2205c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2206c5f01b2fSopenharmony_ci        }
2207c5f01b2fSopenharmony_ci
2208c5f01b2fSopenharmony_ci        SECTION("size=true type=false")
2209c5f01b2fSopenharmony_ci        {
2210c5f01b2fSopenharmony_ci            json j =
2211c5f01b2fSopenharmony_ci            {
2212c5f01b2fSopenharmony_ci                {
2213c5f01b2fSopenharmony_ci                    "post", {
2214c5f01b2fSopenharmony_ci                        {"id", 1137},
2215c5f01b2fSopenharmony_ci                        {"author", "rkalla"},
2216c5f01b2fSopenharmony_ci                        {"timestamp", 1364482090592},
2217c5f01b2fSopenharmony_ci                        {"body", "I totally agree!"}
2218c5f01b2fSopenharmony_ci                    }
2219c5f01b2fSopenharmony_ci                }
2220c5f01b2fSopenharmony_ci            };
2221c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', '#', 'i', 1, 'i', 4, 'p', 'o', 's', 't', '{', '#', 'i', 4,
2222c5f01b2fSopenharmony_ci                                      'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',
2223c5f01b2fSopenharmony_ci                                      'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',
2224c5f01b2fSopenharmony_ci                                      'i', 2, 'i', 'd', 'I', 0x04, 0x71,
2225c5f01b2fSopenharmony_ci                                      'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60
2226c5f01b2fSopenharmony_ci                                     };
2227c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j, true) == v);
2228c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2229c5f01b2fSopenharmony_ci        }
2230c5f01b2fSopenharmony_ci
2231c5f01b2fSopenharmony_ci        SECTION("size=true type=true")
2232c5f01b2fSopenharmony_ci        {
2233c5f01b2fSopenharmony_ci            json j =
2234c5f01b2fSopenharmony_ci            {
2235c5f01b2fSopenharmony_ci                {
2236c5f01b2fSopenharmony_ci                    "post", {
2237c5f01b2fSopenharmony_ci                        {"id", 1137},
2238c5f01b2fSopenharmony_ci                        {"author", "rkalla"},
2239c5f01b2fSopenharmony_ci                        {"timestamp", 1364482090592},
2240c5f01b2fSopenharmony_ci                        {"body", "I totally agree!"}
2241c5f01b2fSopenharmony_ci                    }
2242c5f01b2fSopenharmony_ci                }
2243c5f01b2fSopenharmony_ci            };
2244c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {'{', '$', '{', '#', 'i', 1, 'i', 4, 'p', 'o', 's', 't', '#', 'i', 4,
2245c5f01b2fSopenharmony_ci                                      'i', 6, 'a', 'u', 't', 'h', 'o', 'r', 'S', 'i', 6, 'r', 'k', 'a', 'l', 'l', 'a',
2246c5f01b2fSopenharmony_ci                                      'i', 4, 'b', 'o', 'd', 'y', 'S', 'i', 16, 'I', ' ', 't', 'o', 't', 'a', 'l', 'l', 'y', ' ', 'a', 'g', 'r', 'e', 'e', '!',
2247c5f01b2fSopenharmony_ci                                      'i', 2, 'i', 'd', 'I', 0x04, 0x71,
2248c5f01b2fSopenharmony_ci                                      'i', 9, 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'L', 0x00, 0x00, 0x01, 0x3D, 0xB1, 0x78, 0x66, 0x60
2249c5f01b2fSopenharmony_ci                                     };
2250c5f01b2fSopenharmony_ci            CHECK(json::to_ubjson(j, true, true) == v);
2251c5f01b2fSopenharmony_ci            CHECK(json::from_ubjson(v) == j);
2252c5f01b2fSopenharmony_ci        }
2253c5f01b2fSopenharmony_ci    }
2254c5f01b2fSopenharmony_ci
2255c5f01b2fSopenharmony_ci    SECTION("Optimized Format")
2256c5f01b2fSopenharmony_ci    {
2257c5f01b2fSopenharmony_ci        SECTION("Array Example")
2258c5f01b2fSopenharmony_ci        {
2259c5f01b2fSopenharmony_ci            SECTION("No Optimization")
2260c5f01b2fSopenharmony_ci            {
2261c5f01b2fSopenharmony_ci                // note the floats have been replaced by doubles
2262c5f01b2fSopenharmony_ci                json j = {29.97, 31.13, 67.0, 2.113, 23.888};
2263c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'[',
2264c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,
2265c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,
2266c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
2267c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,
2268c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17,
2269c5f01b2fSopenharmony_ci                                          ']'
2270c5f01b2fSopenharmony_ci                                         };
2271c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j) == v);
2272c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == j);
2273c5f01b2fSopenharmony_ci            }
2274c5f01b2fSopenharmony_ci
2275c5f01b2fSopenharmony_ci            SECTION("Optimized with count")
2276c5f01b2fSopenharmony_ci            {
2277c5f01b2fSopenharmony_ci                // note the floats have been replaced by doubles
2278c5f01b2fSopenharmony_ci                json j = {29.97, 31.13, 67.0, 2.113, 23.888};
2279c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'[', '#', 'i', 5,
2280c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,
2281c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,
2282c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
2283c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,
2284c5f01b2fSopenharmony_ci                                          'D', 0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17
2285c5f01b2fSopenharmony_ci                                         };
2286c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == v);
2287c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == j);
2288c5f01b2fSopenharmony_ci            }
2289c5f01b2fSopenharmony_ci
2290c5f01b2fSopenharmony_ci            SECTION("Optimized with type & count")
2291c5f01b2fSopenharmony_ci            {
2292c5f01b2fSopenharmony_ci                // note the floats have been replaced by doubles
2293c5f01b2fSopenharmony_ci                json j = {29.97, 31.13, 67.0, 2.113, 23.888};
2294c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'[', '$', 'D', '#', 'i', 5,
2295c5f01b2fSopenharmony_ci                                          0x40, 0x3d, 0xf8, 0x51, 0xeb, 0x85, 0x1e, 0xb8,
2296c5f01b2fSopenharmony_ci                                          0x40, 0x3f, 0x21, 0x47, 0xae, 0x14, 0x7a, 0xe1,
2297c5f01b2fSopenharmony_ci                                          0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
2298c5f01b2fSopenharmony_ci                                          0x40, 0x00, 0xe7, 0x6c, 0x8b, 0x43, 0x95, 0x81,
2299c5f01b2fSopenharmony_ci                                          0x40, 0x37, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17
2300c5f01b2fSopenharmony_ci                                         };
2301c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == v);
2302c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == j);
2303c5f01b2fSopenharmony_ci            }
2304c5f01b2fSopenharmony_ci        }
2305c5f01b2fSopenharmony_ci
2306c5f01b2fSopenharmony_ci        SECTION("Object Example")
2307c5f01b2fSopenharmony_ci        {
2308c5f01b2fSopenharmony_ci            SECTION("No Optimization")
2309c5f01b2fSopenharmony_ci            {
2310c5f01b2fSopenharmony_ci                // note the floats have been replaced by doubles
2311c5f01b2fSopenharmony_ci                json j = { {"lat", 29.976}, {"long", 31.131}, {"alt", 67.0} };
2312c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'{',
2313c5f01b2fSopenharmony_ci                                          'i', 3, 'a', 'l', 't', 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
2314c5f01b2fSopenharmony_ci                                          'i', 3, 'l', 'a', 't', 'D', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,
2315c5f01b2fSopenharmony_ci                                          'i', 4, 'l', 'o', 'n', 'g', 'D', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8,
2316c5f01b2fSopenharmony_ci                                          '}'
2317c5f01b2fSopenharmony_ci                                         };
2318c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j) == v);
2319c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == j);
2320c5f01b2fSopenharmony_ci            }
2321c5f01b2fSopenharmony_ci
2322c5f01b2fSopenharmony_ci            SECTION("Optimized with count")
2323c5f01b2fSopenharmony_ci            {
2324c5f01b2fSopenharmony_ci                // note the floats have been replaced by doubles
2325c5f01b2fSopenharmony_ci                json j = { {"lat", 29.976}, {"long", 31.131}, {"alt", 67.0} };
2326c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'{', '#', 'i', 3,
2327c5f01b2fSopenharmony_ci                                          'i', 3, 'a', 'l', 't', 'D', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
2328c5f01b2fSopenharmony_ci                                          'i', 3, 'l', 'a', 't', 'D', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,
2329c5f01b2fSopenharmony_ci                                          'i', 4, 'l', 'o', 'n', 'g', 'D', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8
2330c5f01b2fSopenharmony_ci                                         };
2331c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true) == v);
2332c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == j);
2333c5f01b2fSopenharmony_ci            }
2334c5f01b2fSopenharmony_ci
2335c5f01b2fSopenharmony_ci            SECTION("Optimized with type & count")
2336c5f01b2fSopenharmony_ci            {
2337c5f01b2fSopenharmony_ci                // note the floats have been replaced by doubles
2338c5f01b2fSopenharmony_ci                json j = { {"lat", 29.976}, {"long", 31.131}, {"alt", 67.0} };
2339c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'{', '$', 'D', '#', 'i', 3,
2340c5f01b2fSopenharmony_ci                                          'i', 3, 'a', 'l', 't', 0x40, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
2341c5f01b2fSopenharmony_ci                                          'i', 3, 'l', 'a', 't', 0x40, 0x3d, 0xf9, 0xdb, 0x22, 0xd0, 0xe5, 0x60,
2342c5f01b2fSopenharmony_ci                                          'i', 4, 'l', 'o', 'n', 'g', 0x40, 0x3f, 0x21, 0x89, 0x37, 0x4b, 0xc6, 0xa8
2343c5f01b2fSopenharmony_ci                                         };
2344c5f01b2fSopenharmony_ci                CHECK(json::to_ubjson(j, true, true) == v);
2345c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == j);
2346c5f01b2fSopenharmony_ci            }
2347c5f01b2fSopenharmony_ci        }
2348c5f01b2fSopenharmony_ci
2349c5f01b2fSopenharmony_ci        SECTION("Special Cases (Null, No-Op and Boolean)")
2350c5f01b2fSopenharmony_ci        {
2351c5f01b2fSopenharmony_ci            SECTION("Array")
2352c5f01b2fSopenharmony_ci            {
2353c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'[', '$', 'N', '#', 'I', 0x02, 0x00};
2354c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == json::array());
2355c5f01b2fSopenharmony_ci            }
2356c5f01b2fSopenharmony_ci
2357c5f01b2fSopenharmony_ci            SECTION("Object")
2358c5f01b2fSopenharmony_ci            {
2359c5f01b2fSopenharmony_ci                std::vector<uint8_t> v = {'{', '$', 'Z', '#', 'i', 3, 'i', 4, 'n', 'a', 'm', 'e', 'i', 8, 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', 'i', 5, 'e', 'm', 'a', 'i', 'l'};
2360c5f01b2fSopenharmony_ci                CHECK(json::from_ubjson(v) == json({ {"name", nullptr}, {"password", nullptr}, {"email", nullptr} }));
2361c5f01b2fSopenharmony_ci            }
2362c5f01b2fSopenharmony_ci        }
2363c5f01b2fSopenharmony_ci    }
2364c5f01b2fSopenharmony_ci}
2365c5f01b2fSopenharmony_ci
2366c5f01b2fSopenharmony_ci#if !defined(JSON_NOEXCEPTION)
2367c5f01b2fSopenharmony_ciTEST_CASE("all UBJSON first bytes")
2368c5f01b2fSopenharmony_ci{
2369c5f01b2fSopenharmony_ci    // these bytes will fail immediately with exception parse_error.112
2370c5f01b2fSopenharmony_ci    std::set<uint8_t> supported =
2371c5f01b2fSopenharmony_ci    {
2372c5f01b2fSopenharmony_ci        'T', 'F', 'Z', 'U', 'i', 'I', 'l', 'L', 'd', 'D', 'C', 'S', '[', '{', 'N', 'H'
2373c5f01b2fSopenharmony_ci    };
2374c5f01b2fSopenharmony_ci
2375c5f01b2fSopenharmony_ci    for (auto i = 0; i < 256; ++i)
2376c5f01b2fSopenharmony_ci    {
2377c5f01b2fSopenharmony_ci        const auto byte = static_cast<uint8_t>(i);
2378c5f01b2fSopenharmony_ci        CAPTURE(byte)
2379c5f01b2fSopenharmony_ci
2380c5f01b2fSopenharmony_ci        try
2381c5f01b2fSopenharmony_ci        {
2382c5f01b2fSopenharmony_ci            auto res = json::from_ubjson(std::vector<uint8_t>(1, byte));
2383c5f01b2fSopenharmony_ci        }
2384c5f01b2fSopenharmony_ci        catch (const json::parse_error& e)
2385c5f01b2fSopenharmony_ci        {
2386c5f01b2fSopenharmony_ci            // check that parse_error.112 is only thrown if the
2387c5f01b2fSopenharmony_ci            // first byte is not in the supported set
2388c5f01b2fSopenharmony_ci            INFO_WITH_TEMP(e.what());
2389c5f01b2fSopenharmony_ci            if (supported.find(byte) == supported.end())
2390c5f01b2fSopenharmony_ci            {
2391c5f01b2fSopenharmony_ci                CHECK(e.id == 112);
2392c5f01b2fSopenharmony_ci            }
2393c5f01b2fSopenharmony_ci            else
2394c5f01b2fSopenharmony_ci            {
2395c5f01b2fSopenharmony_ci                CHECK(e.id != 112);
2396c5f01b2fSopenharmony_ci            }
2397c5f01b2fSopenharmony_ci        }
2398c5f01b2fSopenharmony_ci    }
2399c5f01b2fSopenharmony_ci}
2400c5f01b2fSopenharmony_ci#endif
2401c5f01b2fSopenharmony_ci
2402c5f01b2fSopenharmony_ciTEST_CASE("UBJSON roundtrips" * doctest::skip())
2403c5f01b2fSopenharmony_ci{
2404c5f01b2fSopenharmony_ci    SECTION("input from self-generated UBJSON files")
2405c5f01b2fSopenharmony_ci    {
2406c5f01b2fSopenharmony_ci        for (std::string filename :
2407c5f01b2fSopenharmony_ci                {
2408c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
2409c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/1.json",
2410c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/2.json",
2411c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/3.json",
2412c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/4.json",
2413c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/5.json",
2414c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
2415c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
2416c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
2417c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip04.json",
2418c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip05.json",
2419c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip06.json",
2420c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip07.json",
2421c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip08.json",
2422c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip09.json",
2423c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip10.json",
2424c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip11.json",
2425c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip12.json",
2426c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip13.json",
2427c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip14.json",
2428c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip15.json",
2429c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip16.json",
2430c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip17.json",
2431c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip18.json",
2432c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip19.json",
2433c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip20.json",
2434c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip21.json",
2435c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip22.json",
2436c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip23.json",
2437c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip24.json",
2438c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip25.json",
2439c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip26.json",
2440c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip27.json",
2441c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip28.json",
2442c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip29.json",
2443c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip30.json",
2444c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip31.json",
2445c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip32.json",
2446c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_testsuite/sample.json",
2447c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_tests/pass1.json",
2448c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_tests/pass2.json",
2449c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_tests/pass3.json"
2450c5f01b2fSopenharmony_ci                })
2451c5f01b2fSopenharmony_ci        {
2452c5f01b2fSopenharmony_ci            CAPTURE(filename)
2453c5f01b2fSopenharmony_ci
2454c5f01b2fSopenharmony_ci            {
2455c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": std::vector<uint8_t>");
2456c5f01b2fSopenharmony_ci                // parse JSON file
2457c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2458c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2459c5f01b2fSopenharmony_ci
2460c5f01b2fSopenharmony_ci                // parse UBJSON file
2461c5f01b2fSopenharmony_ci                auto packed = utils::read_binary_file(filename + ".ubjson");
2462c5f01b2fSopenharmony_ci                json j2;
2463c5f01b2fSopenharmony_ci                CHECK_NOTHROW(j2 = json::from_ubjson(packed));
2464c5f01b2fSopenharmony_ci
2465c5f01b2fSopenharmony_ci                // compare parsed JSON values
2466c5f01b2fSopenharmony_ci                CHECK(j1 == j2);
2467c5f01b2fSopenharmony_ci            }
2468c5f01b2fSopenharmony_ci
2469c5f01b2fSopenharmony_ci            {
2470c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": std::ifstream");
2471c5f01b2fSopenharmony_ci                // parse JSON file
2472c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2473c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2474c5f01b2fSopenharmony_ci
2475c5f01b2fSopenharmony_ci                // parse UBJSON file
2476c5f01b2fSopenharmony_ci                std::ifstream f_ubjson(filename + ".ubjson", std::ios::binary);
2477c5f01b2fSopenharmony_ci                json j2;
2478c5f01b2fSopenharmony_ci                CHECK_NOTHROW(j2 = json::from_ubjson(f_ubjson));
2479c5f01b2fSopenharmony_ci
2480c5f01b2fSopenharmony_ci                // compare parsed JSON values
2481c5f01b2fSopenharmony_ci                CHECK(j1 == j2);
2482c5f01b2fSopenharmony_ci            }
2483c5f01b2fSopenharmony_ci
2484c5f01b2fSopenharmony_ci            {
2485c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": uint8_t* and size");
2486c5f01b2fSopenharmony_ci                // parse JSON file
2487c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2488c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2489c5f01b2fSopenharmony_ci
2490c5f01b2fSopenharmony_ci                // parse UBJSON file
2491c5f01b2fSopenharmony_ci                auto packed = utils::read_binary_file(filename + ".ubjson");
2492c5f01b2fSopenharmony_ci                json j2;
2493c5f01b2fSopenharmony_ci                CHECK_NOTHROW(j2 = json::from_ubjson({packed.data(), packed.size()}));
2494c5f01b2fSopenharmony_ci
2495c5f01b2fSopenharmony_ci                // compare parsed JSON values
2496c5f01b2fSopenharmony_ci                CHECK(j1 == j2);
2497c5f01b2fSopenharmony_ci            }
2498c5f01b2fSopenharmony_ci
2499c5f01b2fSopenharmony_ci            {
2500c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": output to output adapters");
2501c5f01b2fSopenharmony_ci                // parse JSON file
2502c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2503c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2504c5f01b2fSopenharmony_ci
2505c5f01b2fSopenharmony_ci                // parse UBJSON file
2506c5f01b2fSopenharmony_ci                auto packed = utils::read_binary_file(filename + ".ubjson");
2507c5f01b2fSopenharmony_ci
2508c5f01b2fSopenharmony_ci                {
2509c5f01b2fSopenharmony_ci                    INFO_WITH_TEMP(filename + ": output adapters: std::vector<uint8_t>");
2510c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec;
2511c5f01b2fSopenharmony_ci                    json::to_ubjson(j1, vec);
2512c5f01b2fSopenharmony_ci                    CHECK(vec == packed);
2513c5f01b2fSopenharmony_ci                }
2514c5f01b2fSopenharmony_ci            }
2515c5f01b2fSopenharmony_ci        }
2516c5f01b2fSopenharmony_ci    }
2517c5f01b2fSopenharmony_ci}
2518