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 <fstream>
15c5f01b2fSopenharmony_ci#include <sstream>
16c5f01b2fSopenharmony_ci#include <iomanip>
17c5f01b2fSopenharmony_ci#include <iostream>
18c5f01b2fSopenharmony_ci#include <set>
19c5f01b2fSopenharmony_ci#include "make_test_data_available.hpp"
20c5f01b2fSopenharmony_ci#include "test_utils.hpp"
21c5f01b2fSopenharmony_ci
22c5f01b2fSopenharmony_cinamespace
23c5f01b2fSopenharmony_ci{
24c5f01b2fSopenharmony_ciclass SaxCountdown
25c5f01b2fSopenharmony_ci{
26c5f01b2fSopenharmony_ci  public:
27c5f01b2fSopenharmony_ci    explicit SaxCountdown(const int count) : events_left(count)
28c5f01b2fSopenharmony_ci    {}
29c5f01b2fSopenharmony_ci
30c5f01b2fSopenharmony_ci    bool null()
31c5f01b2fSopenharmony_ci    {
32c5f01b2fSopenharmony_ci        return events_left-- > 0;
33c5f01b2fSopenharmony_ci    }
34c5f01b2fSopenharmony_ci
35c5f01b2fSopenharmony_ci    bool boolean(bool /*unused*/)
36c5f01b2fSopenharmony_ci    {
37c5f01b2fSopenharmony_ci        return events_left-- > 0;
38c5f01b2fSopenharmony_ci    }
39c5f01b2fSopenharmony_ci
40c5f01b2fSopenharmony_ci    bool number_integer(json::number_integer_t /*unused*/)
41c5f01b2fSopenharmony_ci    {
42c5f01b2fSopenharmony_ci        return events_left-- > 0;
43c5f01b2fSopenharmony_ci    }
44c5f01b2fSopenharmony_ci
45c5f01b2fSopenharmony_ci    bool number_unsigned(json::number_unsigned_t /*unused*/)
46c5f01b2fSopenharmony_ci    {
47c5f01b2fSopenharmony_ci        return events_left-- > 0;
48c5f01b2fSopenharmony_ci    }
49c5f01b2fSopenharmony_ci
50c5f01b2fSopenharmony_ci    bool number_float(json::number_float_t /*unused*/, const std::string& /*unused*/)
51c5f01b2fSopenharmony_ci    {
52c5f01b2fSopenharmony_ci        return events_left-- > 0;
53c5f01b2fSopenharmony_ci    }
54c5f01b2fSopenharmony_ci
55c5f01b2fSopenharmony_ci    bool string(std::string& /*unused*/)
56c5f01b2fSopenharmony_ci    {
57c5f01b2fSopenharmony_ci        return events_left-- > 0;
58c5f01b2fSopenharmony_ci    }
59c5f01b2fSopenharmony_ci
60c5f01b2fSopenharmony_ci    bool binary(std::vector<std::uint8_t>& /*unused*/)
61c5f01b2fSopenharmony_ci    {
62c5f01b2fSopenharmony_ci        return events_left-- > 0;
63c5f01b2fSopenharmony_ci    }
64c5f01b2fSopenharmony_ci
65c5f01b2fSopenharmony_ci    bool start_object(std::size_t /*unused*/)
66c5f01b2fSopenharmony_ci    {
67c5f01b2fSopenharmony_ci        return events_left-- > 0;
68c5f01b2fSopenharmony_ci    }
69c5f01b2fSopenharmony_ci
70c5f01b2fSopenharmony_ci    bool key(std::string& /*unused*/)
71c5f01b2fSopenharmony_ci    {
72c5f01b2fSopenharmony_ci        return events_left-- > 0;
73c5f01b2fSopenharmony_ci    }
74c5f01b2fSopenharmony_ci
75c5f01b2fSopenharmony_ci    bool end_object()
76c5f01b2fSopenharmony_ci    {
77c5f01b2fSopenharmony_ci        return events_left-- > 0;
78c5f01b2fSopenharmony_ci    }
79c5f01b2fSopenharmony_ci
80c5f01b2fSopenharmony_ci    bool start_array(std::size_t /*unused*/)
81c5f01b2fSopenharmony_ci    {
82c5f01b2fSopenharmony_ci        return events_left-- > 0;
83c5f01b2fSopenharmony_ci    }
84c5f01b2fSopenharmony_ci
85c5f01b2fSopenharmony_ci    bool end_array()
86c5f01b2fSopenharmony_ci    {
87c5f01b2fSopenharmony_ci        return events_left-- > 0;
88c5f01b2fSopenharmony_ci    }
89c5f01b2fSopenharmony_ci
90c5f01b2fSopenharmony_ci    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const json::exception& /*unused*/) // NOLINT(readability-convert-member-functions-to-static)
91c5f01b2fSopenharmony_ci    {
92c5f01b2fSopenharmony_ci        return false;
93c5f01b2fSopenharmony_ci    }
94c5f01b2fSopenharmony_ci
95c5f01b2fSopenharmony_ci  private:
96c5f01b2fSopenharmony_ci    int events_left = 0;
97c5f01b2fSopenharmony_ci};
98c5f01b2fSopenharmony_ci} // namespace
99c5f01b2fSopenharmony_ci
100c5f01b2fSopenharmony_ciTEST_CASE("CBOR")
101c5f01b2fSopenharmony_ci{
102c5f01b2fSopenharmony_ci    SECTION("individual values")
103c5f01b2fSopenharmony_ci    {
104c5f01b2fSopenharmony_ci        SECTION("discarded")
105c5f01b2fSopenharmony_ci        {
106c5f01b2fSopenharmony_ci            // discarded values are not serialized
107c5f01b2fSopenharmony_ci            json j = json::value_t::discarded;
108c5f01b2fSopenharmony_ci            const auto result = json::to_cbor(j);
109c5f01b2fSopenharmony_ci            CHECK(result.empty());
110c5f01b2fSopenharmony_ci        }
111c5f01b2fSopenharmony_ci
112c5f01b2fSopenharmony_ci        SECTION("NaN")
113c5f01b2fSopenharmony_ci        {
114c5f01b2fSopenharmony_ci            // NaN value
115c5f01b2fSopenharmony_ci            json j = std::numeric_limits<json::number_float_t>::quiet_NaN();
116c5f01b2fSopenharmony_ci            std::vector<uint8_t> expected = {0xf9, 0x7e, 0x00};
117c5f01b2fSopenharmony_ci            const auto result = json::to_cbor(j);
118c5f01b2fSopenharmony_ci            CHECK(result == expected);
119c5f01b2fSopenharmony_ci        }
120c5f01b2fSopenharmony_ci
121c5f01b2fSopenharmony_ci        SECTION("Infinity")
122c5f01b2fSopenharmony_ci        {
123c5f01b2fSopenharmony_ci            // Infinity value
124c5f01b2fSopenharmony_ci            json j = std::numeric_limits<json::number_float_t>::infinity();
125c5f01b2fSopenharmony_ci            std::vector<uint8_t> expected = {0xf9, 0x7c, 0x00};
126c5f01b2fSopenharmony_ci            const auto result = json::to_cbor(j);
127c5f01b2fSopenharmony_ci            CHECK(result == expected);
128c5f01b2fSopenharmony_ci        }
129c5f01b2fSopenharmony_ci
130c5f01b2fSopenharmony_ci        SECTION("null")
131c5f01b2fSopenharmony_ci        {
132c5f01b2fSopenharmony_ci            json j = nullptr;
133c5f01b2fSopenharmony_ci            std::vector<uint8_t> expected = {0xf6};
134c5f01b2fSopenharmony_ci            const auto result = json::to_cbor(j);
135c5f01b2fSopenharmony_ci            CHECK(result == expected);
136c5f01b2fSopenharmony_ci
137c5f01b2fSopenharmony_ci            // roundtrip
138c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(result) == j);
139c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(result, true, false) == j);
140c5f01b2fSopenharmony_ci        }
141c5f01b2fSopenharmony_ci
142c5f01b2fSopenharmony_ci        SECTION("boolean")
143c5f01b2fSopenharmony_ci        {
144c5f01b2fSopenharmony_ci            SECTION("true")
145c5f01b2fSopenharmony_ci            {
146c5f01b2fSopenharmony_ci                json j = true;
147c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0xf5};
148c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
149c5f01b2fSopenharmony_ci                CHECK(result == expected);
150c5f01b2fSopenharmony_ci
151c5f01b2fSopenharmony_ci                // roundtrip
152c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
153c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
154c5f01b2fSopenharmony_ci            }
155c5f01b2fSopenharmony_ci
156c5f01b2fSopenharmony_ci            SECTION("false")
157c5f01b2fSopenharmony_ci            {
158c5f01b2fSopenharmony_ci                json j = false;
159c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0xf4};
160c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
161c5f01b2fSopenharmony_ci                CHECK(result == expected);
162c5f01b2fSopenharmony_ci
163c5f01b2fSopenharmony_ci                // roundtrip
164c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
165c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
166c5f01b2fSopenharmony_ci            }
167c5f01b2fSopenharmony_ci        }
168c5f01b2fSopenharmony_ci
169c5f01b2fSopenharmony_ci        SECTION("number")
170c5f01b2fSopenharmony_ci        {
171c5f01b2fSopenharmony_ci            SECTION("signed")
172c5f01b2fSopenharmony_ci            {
173c5f01b2fSopenharmony_ci                SECTION("-9223372036854775808..-4294967297")
174c5f01b2fSopenharmony_ci                {
175c5f01b2fSopenharmony_ci                    std::vector<int64_t> numbers;
176c5f01b2fSopenharmony_ci                    numbers.push_back(INT64_MIN);
177c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000000000000);
178c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000000000000);
179c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000000000000);
180c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000000000);
181c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000000000);
182c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000000000);
183c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000000);
184c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000000);
185c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000000);
186c5f01b2fSopenharmony_ci                    numbers.push_back(-4294967297);
187c5f01b2fSopenharmony_ci                    for (auto i : numbers)
188c5f01b2fSopenharmony_ci                    {
189c5f01b2fSopenharmony_ci                        CAPTURE(i)
190c5f01b2fSopenharmony_ci
191c5f01b2fSopenharmony_ci                        // create JSON value with integer number
192c5f01b2fSopenharmony_ci                        json j = i;
193c5f01b2fSopenharmony_ci
194c5f01b2fSopenharmony_ci                        // check type
195c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
196c5f01b2fSopenharmony_ci
197c5f01b2fSopenharmony_ci                        // create expected byte vector
198c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
199c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(0x3b));
200c5f01b2fSopenharmony_ci                        auto positive = static_cast<uint64_t>(-1 - i);
201c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 56) & 0xff));
202c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 48) & 0xff));
203c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 40) & 0xff));
204c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 32) & 0xff));
205c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 24) & 0xff));
206c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 16) & 0xff));
207c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));
208c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(positive & 0xff));
209c5f01b2fSopenharmony_ci
210c5f01b2fSopenharmony_ci                        // compare result + size
211c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
212c5f01b2fSopenharmony_ci                        CHECK(result == expected);
213c5f01b2fSopenharmony_ci                        CHECK(result.size() == 9);
214c5f01b2fSopenharmony_ci
215c5f01b2fSopenharmony_ci                        // check individual bytes
216c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x3b);
217c5f01b2fSopenharmony_ci                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
218c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[2]) << 060) +
219c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[3]) << 050) +
220c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[4]) << 040) +
221c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[5]) << 030) +
222c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[6]) << 020) +
223c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[7]) << 010) +
224c5f01b2fSopenharmony_ci                                            static_cast<uint64_t>(result[8]);
225c5f01b2fSopenharmony_ci                        CHECK(restored == positive);
226c5f01b2fSopenharmony_ci                        CHECK(-1 - static_cast<int64_t>(restored) == i);
227c5f01b2fSopenharmony_ci
228c5f01b2fSopenharmony_ci                        // roundtrip
229c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
230c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
231c5f01b2fSopenharmony_ci                    }
232c5f01b2fSopenharmony_ci                }
233c5f01b2fSopenharmony_ci
234c5f01b2fSopenharmony_ci                SECTION("-4294967296..-65537")
235c5f01b2fSopenharmony_ci                {
236c5f01b2fSopenharmony_ci                    std::vector<int64_t> numbers;
237c5f01b2fSopenharmony_ci                    numbers.push_back(-65537);
238c5f01b2fSopenharmony_ci                    numbers.push_back(-100000);
239c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000);
240c5f01b2fSopenharmony_ci                    numbers.push_back(-10000000);
241c5f01b2fSopenharmony_ci                    numbers.push_back(-100000000);
242c5f01b2fSopenharmony_ci                    numbers.push_back(-1000000000);
243c5f01b2fSopenharmony_ci                    numbers.push_back(-4294967296);
244c5f01b2fSopenharmony_ci                    for (auto i : numbers)
245c5f01b2fSopenharmony_ci                    {
246c5f01b2fSopenharmony_ci                        CAPTURE(i)
247c5f01b2fSopenharmony_ci
248c5f01b2fSopenharmony_ci                        // create JSON value with integer number
249c5f01b2fSopenharmony_ci                        json j = i;
250c5f01b2fSopenharmony_ci
251c5f01b2fSopenharmony_ci                        // check type
252c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
253c5f01b2fSopenharmony_ci
254c5f01b2fSopenharmony_ci                        // create expected byte vector
255c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
256c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(0x3a));
257c5f01b2fSopenharmony_ci                        auto positive = static_cast<uint32_t>(static_cast<uint64_t>(-1 - i) & 0x00000000ffffffff);
258c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 24) & 0xff));
259c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 16) & 0xff));
260c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));
261c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(positive & 0xff));
262c5f01b2fSopenharmony_ci
263c5f01b2fSopenharmony_ci                        // compare result + size
264c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
265c5f01b2fSopenharmony_ci                        CHECK(result == expected);
266c5f01b2fSopenharmony_ci                        CHECK(result.size() == 5);
267c5f01b2fSopenharmony_ci
268c5f01b2fSopenharmony_ci                        // check individual bytes
269c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x3a);
270c5f01b2fSopenharmony_ci                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
271c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[2]) << 020) +
272c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[3]) << 010) +
273c5f01b2fSopenharmony_ci                                            static_cast<uint32_t>(result[4]);
274c5f01b2fSopenharmony_ci                        CHECK(restored == positive);
275c5f01b2fSopenharmony_ci                        CHECK(-1LL - restored == i);
276c5f01b2fSopenharmony_ci
277c5f01b2fSopenharmony_ci                        // roundtrip
278c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
279c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
280c5f01b2fSopenharmony_ci                    }
281c5f01b2fSopenharmony_ci                }
282c5f01b2fSopenharmony_ci
283c5f01b2fSopenharmony_ci                SECTION("-65536..-257")
284c5f01b2fSopenharmony_ci                {
285c5f01b2fSopenharmony_ci                    for (int32_t i = -65536; i <= -257; ++i)
286c5f01b2fSopenharmony_ci                    {
287c5f01b2fSopenharmony_ci                        CAPTURE(i)
288c5f01b2fSopenharmony_ci
289c5f01b2fSopenharmony_ci                        // create JSON value with integer number
290c5f01b2fSopenharmony_ci                        json j = i;
291c5f01b2fSopenharmony_ci
292c5f01b2fSopenharmony_ci                        // check type
293c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
294c5f01b2fSopenharmony_ci
295c5f01b2fSopenharmony_ci                        // create expected byte vector
296c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
297c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(0x39));
298c5f01b2fSopenharmony_ci                        auto positive = static_cast<uint16_t>(-1 - i);
299c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((positive >> 8) & 0xff));
300c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(positive & 0xff));
301c5f01b2fSopenharmony_ci
302c5f01b2fSopenharmony_ci                        // compare result + size
303c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
304c5f01b2fSopenharmony_ci                        CHECK(result == expected);
305c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
306c5f01b2fSopenharmony_ci
307c5f01b2fSopenharmony_ci                        // check individual bytes
308c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x39);
309c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
310c5f01b2fSopenharmony_ci                        CHECK(restored == positive);
311c5f01b2fSopenharmony_ci                        CHECK(-1 - restored == i);
312c5f01b2fSopenharmony_ci
313c5f01b2fSopenharmony_ci                        // roundtrip
314c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
315c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
316c5f01b2fSopenharmony_ci                    }
317c5f01b2fSopenharmony_ci                }
318c5f01b2fSopenharmony_ci
319c5f01b2fSopenharmony_ci                SECTION("-9263 (int 16)")
320c5f01b2fSopenharmony_ci                {
321c5f01b2fSopenharmony_ci                    json j = -9263;
322c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {0x39, 0x24, 0x2e};
323c5f01b2fSopenharmony_ci
324c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
325c5f01b2fSopenharmony_ci                    CHECK(result == expected);
326c5f01b2fSopenharmony_ci
327c5f01b2fSopenharmony_ci                    auto restored = static_cast<int16_t>(-1 - ((result[1] << 8) + result[2]));
328c5f01b2fSopenharmony_ci                    CHECK(restored == -9263);
329c5f01b2fSopenharmony_ci
330c5f01b2fSopenharmony_ci                    // roundtrip
331c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
332c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
333c5f01b2fSopenharmony_ci                }
334c5f01b2fSopenharmony_ci
335c5f01b2fSopenharmony_ci                SECTION("-256..-24")
336c5f01b2fSopenharmony_ci                {
337c5f01b2fSopenharmony_ci                    for (auto i = -256; i < -24; ++i)
338c5f01b2fSopenharmony_ci                    {
339c5f01b2fSopenharmony_ci                        CAPTURE(i)
340c5f01b2fSopenharmony_ci
341c5f01b2fSopenharmony_ci                        // create JSON value with integer number
342c5f01b2fSopenharmony_ci                        json j = i;
343c5f01b2fSopenharmony_ci
344c5f01b2fSopenharmony_ci                        // check type
345c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
346c5f01b2fSopenharmony_ci
347c5f01b2fSopenharmony_ci                        // create expected byte vector
348c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
349c5f01b2fSopenharmony_ci                        expected.push_back(0x38);
350c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(-1 - i));
351c5f01b2fSopenharmony_ci
352c5f01b2fSopenharmony_ci                        // compare result + size
353c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
354c5f01b2fSopenharmony_ci                        CHECK(result == expected);
355c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
356c5f01b2fSopenharmony_ci
357c5f01b2fSopenharmony_ci                        // check individual bytes
358c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x38);
359c5f01b2fSopenharmony_ci                        CHECK(static_cast<int16_t>(-1 - result[1]) == i);
360c5f01b2fSopenharmony_ci
361c5f01b2fSopenharmony_ci                        // roundtrip
362c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
363c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
364c5f01b2fSopenharmony_ci                    }
365c5f01b2fSopenharmony_ci                }
366c5f01b2fSopenharmony_ci
367c5f01b2fSopenharmony_ci                SECTION("-24..-1")
368c5f01b2fSopenharmony_ci                {
369c5f01b2fSopenharmony_ci                    for (auto i = -24; i <= -1; ++i)
370c5f01b2fSopenharmony_ci                    {
371c5f01b2fSopenharmony_ci                        CAPTURE(i)
372c5f01b2fSopenharmony_ci
373c5f01b2fSopenharmony_ci                        // create JSON value with integer number
374c5f01b2fSopenharmony_ci                        json j = i;
375c5f01b2fSopenharmony_ci
376c5f01b2fSopenharmony_ci                        // check type
377c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
378c5f01b2fSopenharmony_ci
379c5f01b2fSopenharmony_ci                        // create expected byte vector
380c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
381c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(0x20 - 1 - static_cast<uint8_t>(i)));
382c5f01b2fSopenharmony_ci
383c5f01b2fSopenharmony_ci                        // compare result + size
384c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
385c5f01b2fSopenharmony_ci                        CHECK(result == expected);
386c5f01b2fSopenharmony_ci                        CHECK(result.size() == 1);
387c5f01b2fSopenharmony_ci
388c5f01b2fSopenharmony_ci                        // check individual bytes
389c5f01b2fSopenharmony_ci                        CHECK(static_cast<int8_t>(0x20 - 1 - result[0]) == i);
390c5f01b2fSopenharmony_ci
391c5f01b2fSopenharmony_ci                        // roundtrip
392c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
393c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
394c5f01b2fSopenharmony_ci                    }
395c5f01b2fSopenharmony_ci                }
396c5f01b2fSopenharmony_ci
397c5f01b2fSopenharmony_ci                SECTION("0..23")
398c5f01b2fSopenharmony_ci                {
399c5f01b2fSopenharmony_ci                    for (size_t i = 0; i <= 23; ++i)
400c5f01b2fSopenharmony_ci                    {
401c5f01b2fSopenharmony_ci                        CAPTURE(i)
402c5f01b2fSopenharmony_ci
403c5f01b2fSopenharmony_ci                        // create JSON value with integer number
404c5f01b2fSopenharmony_ci                        json j = -1;
405c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
406c5f01b2fSopenharmony_ci
407c5f01b2fSopenharmony_ci                        // check type
408c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
409c5f01b2fSopenharmony_ci
410c5f01b2fSopenharmony_ci                        // create expected byte vector
411c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
412c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
413c5f01b2fSopenharmony_ci
414c5f01b2fSopenharmony_ci                        // compare result + size
415c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
416c5f01b2fSopenharmony_ci                        CHECK(result == expected);
417c5f01b2fSopenharmony_ci                        CHECK(result.size() == 1);
418c5f01b2fSopenharmony_ci
419c5f01b2fSopenharmony_ci                        // check individual bytes
420c5f01b2fSopenharmony_ci                        CHECK(result[0] == i);
421c5f01b2fSopenharmony_ci
422c5f01b2fSopenharmony_ci                        // roundtrip
423c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
424c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
425c5f01b2fSopenharmony_ci                    }
426c5f01b2fSopenharmony_ci                }
427c5f01b2fSopenharmony_ci
428c5f01b2fSopenharmony_ci                SECTION("24..255")
429c5f01b2fSopenharmony_ci                {
430c5f01b2fSopenharmony_ci                    for (size_t i = 24; i <= 255; ++i)
431c5f01b2fSopenharmony_ci                    {
432c5f01b2fSopenharmony_ci                        CAPTURE(i)
433c5f01b2fSopenharmony_ci
434c5f01b2fSopenharmony_ci                        // create JSON value with integer number
435c5f01b2fSopenharmony_ci                        json j = -1;
436c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
437c5f01b2fSopenharmony_ci
438c5f01b2fSopenharmony_ci                        // check type
439c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
440c5f01b2fSopenharmony_ci
441c5f01b2fSopenharmony_ci                        // create expected byte vector
442c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
443c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(0x18));
444c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
445c5f01b2fSopenharmony_ci
446c5f01b2fSopenharmony_ci                        // compare result + size
447c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
448c5f01b2fSopenharmony_ci                        CHECK(result == expected);
449c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
450c5f01b2fSopenharmony_ci
451c5f01b2fSopenharmony_ci                        // check individual bytes
452c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x18);
453c5f01b2fSopenharmony_ci                        CHECK(result[1] == i);
454c5f01b2fSopenharmony_ci
455c5f01b2fSopenharmony_ci                        // roundtrip
456c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
457c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
458c5f01b2fSopenharmony_ci                    }
459c5f01b2fSopenharmony_ci                }
460c5f01b2fSopenharmony_ci
461c5f01b2fSopenharmony_ci                SECTION("256..65535")
462c5f01b2fSopenharmony_ci                {
463c5f01b2fSopenharmony_ci                    for (size_t i = 256; i <= 65535; ++i)
464c5f01b2fSopenharmony_ci                    {
465c5f01b2fSopenharmony_ci                        CAPTURE(i)
466c5f01b2fSopenharmony_ci
467c5f01b2fSopenharmony_ci                        // create JSON value with integer number
468c5f01b2fSopenharmony_ci                        json j = -1;
469c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
470c5f01b2fSopenharmony_ci
471c5f01b2fSopenharmony_ci                        // check type
472c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
473c5f01b2fSopenharmony_ci
474c5f01b2fSopenharmony_ci                        // create expected byte vector
475c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
476c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(0x19));
477c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
478c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
479c5f01b2fSopenharmony_ci
480c5f01b2fSopenharmony_ci                        // compare result + size
481c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
482c5f01b2fSopenharmony_ci                        CHECK(result == expected);
483c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
484c5f01b2fSopenharmony_ci
485c5f01b2fSopenharmony_ci                        // check individual bytes
486c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x19);
487c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
488c5f01b2fSopenharmony_ci                        CHECK(restored == i);
489c5f01b2fSopenharmony_ci
490c5f01b2fSopenharmony_ci                        // roundtrip
491c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
492c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
493c5f01b2fSopenharmony_ci                    }
494c5f01b2fSopenharmony_ci                }
495c5f01b2fSopenharmony_ci
496c5f01b2fSopenharmony_ci                SECTION("65536..4294967295")
497c5f01b2fSopenharmony_ci                {
498c5f01b2fSopenharmony_ci                    for (uint32_t i :
499c5f01b2fSopenharmony_ci                            {
500c5f01b2fSopenharmony_ci                                65536u, 77777u, 1048576u
501c5f01b2fSopenharmony_ci                            })
502c5f01b2fSopenharmony_ci                    {
503c5f01b2fSopenharmony_ci                        CAPTURE(i)
504c5f01b2fSopenharmony_ci
505c5f01b2fSopenharmony_ci                        // create JSON value with integer number
506c5f01b2fSopenharmony_ci                        json j = -1;
507c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
508c5f01b2fSopenharmony_ci
509c5f01b2fSopenharmony_ci                        // check type
510c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
511c5f01b2fSopenharmony_ci
512c5f01b2fSopenharmony_ci                        // create expected byte vector
513c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
514c5f01b2fSopenharmony_ci                        expected.push_back(0x1a);
515c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
516c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
517c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
518c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
519c5f01b2fSopenharmony_ci
520c5f01b2fSopenharmony_ci                        // compare result + size
521c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
522c5f01b2fSopenharmony_ci                        CHECK(result == expected);
523c5f01b2fSopenharmony_ci                        CHECK(result.size() == 5);
524c5f01b2fSopenharmony_ci
525c5f01b2fSopenharmony_ci                        // check individual bytes
526c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x1a);
527c5f01b2fSopenharmony_ci                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
528c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[2]) << 020) +
529c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[3]) << 010) +
530c5f01b2fSopenharmony_ci                                            static_cast<uint32_t>(result[4]);
531c5f01b2fSopenharmony_ci                        CHECK(restored == i);
532c5f01b2fSopenharmony_ci
533c5f01b2fSopenharmony_ci                        // roundtrip
534c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
535c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
536c5f01b2fSopenharmony_ci                    }
537c5f01b2fSopenharmony_ci                }
538c5f01b2fSopenharmony_ci
539c5f01b2fSopenharmony_ci                SECTION("4294967296..4611686018427387903")
540c5f01b2fSopenharmony_ci                {
541c5f01b2fSopenharmony_ci                    for (uint64_t i :
542c5f01b2fSopenharmony_ci                            {
543c5f01b2fSopenharmony_ci                                4294967296ul, 4611686018427387903ul
544c5f01b2fSopenharmony_ci                            })
545c5f01b2fSopenharmony_ci                    {
546c5f01b2fSopenharmony_ci                        CAPTURE(i)
547c5f01b2fSopenharmony_ci
548c5f01b2fSopenharmony_ci                        // create JSON value with integer number
549c5f01b2fSopenharmony_ci                        json j = -1;
550c5f01b2fSopenharmony_ci                        j.get_ref<json::number_integer_t&>() = static_cast<json::number_integer_t>(i);
551c5f01b2fSopenharmony_ci
552c5f01b2fSopenharmony_ci                        // check type
553c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
554c5f01b2fSopenharmony_ci
555c5f01b2fSopenharmony_ci                        // create expected byte vector
556c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
557c5f01b2fSopenharmony_ci                        expected.push_back(0x1b);
558c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
559c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
560c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
561c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
562c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
563c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
564c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
565c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
566c5f01b2fSopenharmony_ci
567c5f01b2fSopenharmony_ci                        // compare result + size
568c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
569c5f01b2fSopenharmony_ci                        CHECK(result == expected);
570c5f01b2fSopenharmony_ci                        CHECK(result.size() == 9);
571c5f01b2fSopenharmony_ci
572c5f01b2fSopenharmony_ci                        // check individual bytes
573c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x1b);
574c5f01b2fSopenharmony_ci                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
575c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[2]) << 060) +
576c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[3]) << 050) +
577c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[4]) << 040) +
578c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[5]) << 030) +
579c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[6]) << 020) +
580c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[7]) << 010) +
581c5f01b2fSopenharmony_ci                                            static_cast<uint64_t>(result[8]);
582c5f01b2fSopenharmony_ci                        CHECK(restored == i);
583c5f01b2fSopenharmony_ci
584c5f01b2fSopenharmony_ci                        // roundtrip
585c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
586c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
587c5f01b2fSopenharmony_ci                    }
588c5f01b2fSopenharmony_ci                }
589c5f01b2fSopenharmony_ci
590c5f01b2fSopenharmony_ci                SECTION("-32768..-129 (int 16)")
591c5f01b2fSopenharmony_ci                {
592c5f01b2fSopenharmony_ci                    for (int16_t i = -32768; i <= static_cast<std::int16_t>(-129); ++i)
593c5f01b2fSopenharmony_ci                    {
594c5f01b2fSopenharmony_ci                        CAPTURE(i)
595c5f01b2fSopenharmony_ci
596c5f01b2fSopenharmony_ci                        // create JSON value with integer number
597c5f01b2fSopenharmony_ci                        json j = i;
598c5f01b2fSopenharmony_ci
599c5f01b2fSopenharmony_ci                        // check type
600c5f01b2fSopenharmony_ci                        CHECK(j.is_number_integer());
601c5f01b2fSopenharmony_ci
602c5f01b2fSopenharmony_ci                        // create expected byte vector
603c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
604c5f01b2fSopenharmony_ci                        expected.push_back(0xd1);
605c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
606c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
607c5f01b2fSopenharmony_ci
608c5f01b2fSopenharmony_ci                        // compare result + size
609c5f01b2fSopenharmony_ci                        const auto result = json::to_msgpack(j);
610c5f01b2fSopenharmony_ci                        CHECK(result == expected);
611c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
612c5f01b2fSopenharmony_ci
613c5f01b2fSopenharmony_ci                        // check individual bytes
614c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0xd1);
615c5f01b2fSopenharmony_ci                        auto restored = static_cast<int16_t>((result[1] << 8) + result[2]);
616c5f01b2fSopenharmony_ci                        CHECK(restored == i);
617c5f01b2fSopenharmony_ci
618c5f01b2fSopenharmony_ci                        // roundtrip
619c5f01b2fSopenharmony_ci                        CHECK(json::from_msgpack(result) == j);
620c5f01b2fSopenharmony_ci                    }
621c5f01b2fSopenharmony_ci                }
622c5f01b2fSopenharmony_ci            }
623c5f01b2fSopenharmony_ci
624c5f01b2fSopenharmony_ci            SECTION("unsigned")
625c5f01b2fSopenharmony_ci            {
626c5f01b2fSopenharmony_ci                SECTION("0..23 (Integer)")
627c5f01b2fSopenharmony_ci                {
628c5f01b2fSopenharmony_ci                    for (size_t i = 0; i <= 23; ++i)
629c5f01b2fSopenharmony_ci                    {
630c5f01b2fSopenharmony_ci                        CAPTURE(i)
631c5f01b2fSopenharmony_ci
632c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
633c5f01b2fSopenharmony_ci                        json j = i;
634c5f01b2fSopenharmony_ci
635c5f01b2fSopenharmony_ci                        // check type
636c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
637c5f01b2fSopenharmony_ci
638c5f01b2fSopenharmony_ci                        // create expected byte vector
639c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
640c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
641c5f01b2fSopenharmony_ci
642c5f01b2fSopenharmony_ci                        // compare result + size
643c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
644c5f01b2fSopenharmony_ci                        CHECK(result == expected);
645c5f01b2fSopenharmony_ci                        CHECK(result.size() == 1);
646c5f01b2fSopenharmony_ci
647c5f01b2fSopenharmony_ci                        // check individual bytes
648c5f01b2fSopenharmony_ci                        CHECK(result[0] == i);
649c5f01b2fSopenharmony_ci
650c5f01b2fSopenharmony_ci                        // roundtrip
651c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
652c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
653c5f01b2fSopenharmony_ci                    }
654c5f01b2fSopenharmony_ci                }
655c5f01b2fSopenharmony_ci
656c5f01b2fSopenharmony_ci                SECTION("24..255 (one-byte uint8_t)")
657c5f01b2fSopenharmony_ci                {
658c5f01b2fSopenharmony_ci                    for (size_t i = 24; i <= 255; ++i)
659c5f01b2fSopenharmony_ci                    {
660c5f01b2fSopenharmony_ci                        CAPTURE(i)
661c5f01b2fSopenharmony_ci
662c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
663c5f01b2fSopenharmony_ci                        json j = i;
664c5f01b2fSopenharmony_ci
665c5f01b2fSopenharmony_ci                        // check type
666c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
667c5f01b2fSopenharmony_ci
668c5f01b2fSopenharmony_ci                        // create expected byte vector
669c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
670c5f01b2fSopenharmony_ci                        expected.push_back(0x18);
671c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i));
672c5f01b2fSopenharmony_ci
673c5f01b2fSopenharmony_ci                        // compare result + size
674c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
675c5f01b2fSopenharmony_ci                        CHECK(result == expected);
676c5f01b2fSopenharmony_ci                        CHECK(result.size() == 2);
677c5f01b2fSopenharmony_ci
678c5f01b2fSopenharmony_ci                        // check individual bytes
679c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x18);
680c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint8_t>(result[1]);
681c5f01b2fSopenharmony_ci                        CHECK(restored == i);
682c5f01b2fSopenharmony_ci
683c5f01b2fSopenharmony_ci                        // roundtrip
684c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
685c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
686c5f01b2fSopenharmony_ci                    }
687c5f01b2fSopenharmony_ci                }
688c5f01b2fSopenharmony_ci
689c5f01b2fSopenharmony_ci                SECTION("256..65535 (two-byte uint16_t)")
690c5f01b2fSopenharmony_ci                {
691c5f01b2fSopenharmony_ci                    for (size_t i = 256; i <= 65535; ++i)
692c5f01b2fSopenharmony_ci                    {
693c5f01b2fSopenharmony_ci                        CAPTURE(i)
694c5f01b2fSopenharmony_ci
695c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
696c5f01b2fSopenharmony_ci                        json j = i;
697c5f01b2fSopenharmony_ci
698c5f01b2fSopenharmony_ci                        // check type
699c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
700c5f01b2fSopenharmony_ci
701c5f01b2fSopenharmony_ci                        // create expected byte vector
702c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
703c5f01b2fSopenharmony_ci                        expected.push_back(0x19);
704c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
705c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
706c5f01b2fSopenharmony_ci
707c5f01b2fSopenharmony_ci                        // compare result + size
708c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
709c5f01b2fSopenharmony_ci                        CHECK(result == expected);
710c5f01b2fSopenharmony_ci                        CHECK(result.size() == 3);
711c5f01b2fSopenharmony_ci
712c5f01b2fSopenharmony_ci                        // check individual bytes
713c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x19);
714c5f01b2fSopenharmony_ci                        auto restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
715c5f01b2fSopenharmony_ci                        CHECK(restored == i);
716c5f01b2fSopenharmony_ci
717c5f01b2fSopenharmony_ci                        // roundtrip
718c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
719c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
720c5f01b2fSopenharmony_ci                    }
721c5f01b2fSopenharmony_ci                }
722c5f01b2fSopenharmony_ci
723c5f01b2fSopenharmony_ci                SECTION("65536..4294967295 (four-byte uint32_t)")
724c5f01b2fSopenharmony_ci                {
725c5f01b2fSopenharmony_ci                    for (uint32_t i :
726c5f01b2fSopenharmony_ci                            {
727c5f01b2fSopenharmony_ci                                65536u, 77777u, 1048576u
728c5f01b2fSopenharmony_ci                            })
729c5f01b2fSopenharmony_ci                    {
730c5f01b2fSopenharmony_ci                        CAPTURE(i)
731c5f01b2fSopenharmony_ci
732c5f01b2fSopenharmony_ci                        // create JSON value with unsigned integer number
733c5f01b2fSopenharmony_ci                        json j = i;
734c5f01b2fSopenharmony_ci
735c5f01b2fSopenharmony_ci                        // check type
736c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
737c5f01b2fSopenharmony_ci
738c5f01b2fSopenharmony_ci                        // create expected byte vector
739c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
740c5f01b2fSopenharmony_ci                        expected.push_back(0x1a);
741c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 24) & 0xff));
742c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 16) & 0xff));
743c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 8) & 0xff));
744c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
745c5f01b2fSopenharmony_ci
746c5f01b2fSopenharmony_ci                        // compare result + size
747c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
748c5f01b2fSopenharmony_ci                        CHECK(result == expected);
749c5f01b2fSopenharmony_ci                        CHECK(result.size() == 5);
750c5f01b2fSopenharmony_ci
751c5f01b2fSopenharmony_ci                        // check individual bytes
752c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x1a);
753c5f01b2fSopenharmony_ci                        uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
754c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[2]) << 020) +
755c5f01b2fSopenharmony_ci                                            (static_cast<uint32_t>(result[3]) << 010) +
756c5f01b2fSopenharmony_ci                                            static_cast<uint32_t>(result[4]);
757c5f01b2fSopenharmony_ci                        CHECK(restored == i);
758c5f01b2fSopenharmony_ci
759c5f01b2fSopenharmony_ci                        // roundtrip
760c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
761c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
762c5f01b2fSopenharmony_ci                    }
763c5f01b2fSopenharmony_ci                }
764c5f01b2fSopenharmony_ci
765c5f01b2fSopenharmony_ci                SECTION("4294967296..4611686018427387903 (eight-byte uint64_t)")
766c5f01b2fSopenharmony_ci                {
767c5f01b2fSopenharmony_ci                    for (uint64_t i :
768c5f01b2fSopenharmony_ci                            {
769c5f01b2fSopenharmony_ci                                4294967296ul, 4611686018427387903ul
770c5f01b2fSopenharmony_ci                            })
771c5f01b2fSopenharmony_ci                    {
772c5f01b2fSopenharmony_ci                        CAPTURE(i)
773c5f01b2fSopenharmony_ci
774c5f01b2fSopenharmony_ci                        // create JSON value with integer number
775c5f01b2fSopenharmony_ci                        json j = i;
776c5f01b2fSopenharmony_ci
777c5f01b2fSopenharmony_ci                        // check type
778c5f01b2fSopenharmony_ci                        CHECK(j.is_number_unsigned());
779c5f01b2fSopenharmony_ci
780c5f01b2fSopenharmony_ci                        // create expected byte vector
781c5f01b2fSopenharmony_ci                        std::vector<uint8_t> expected;
782c5f01b2fSopenharmony_ci                        expected.push_back(0x1b);
783c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 070) & 0xff));
784c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 060) & 0xff));
785c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 050) & 0xff));
786c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 040) & 0xff));
787c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 030) & 0xff));
788c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 020) & 0xff));
789c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>((i >> 010) & 0xff));
790c5f01b2fSopenharmony_ci                        expected.push_back(static_cast<uint8_t>(i & 0xff));
791c5f01b2fSopenharmony_ci
792c5f01b2fSopenharmony_ci                        // compare result + size
793c5f01b2fSopenharmony_ci                        const auto result = json::to_cbor(j);
794c5f01b2fSopenharmony_ci                        CHECK(result == expected);
795c5f01b2fSopenharmony_ci                        CHECK(result.size() == 9);
796c5f01b2fSopenharmony_ci
797c5f01b2fSopenharmony_ci                        // check individual bytes
798c5f01b2fSopenharmony_ci                        CHECK(result[0] == 0x1b);
799c5f01b2fSopenharmony_ci                        uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
800c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[2]) << 060) +
801c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[3]) << 050) +
802c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[4]) << 040) +
803c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[5]) << 030) +
804c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[6]) << 020) +
805c5f01b2fSopenharmony_ci                                            (static_cast<uint64_t>(result[7]) << 010) +
806c5f01b2fSopenharmony_ci                                            static_cast<uint64_t>(result[8]);
807c5f01b2fSopenharmony_ci                        CHECK(restored == i);
808c5f01b2fSopenharmony_ci
809c5f01b2fSopenharmony_ci                        // roundtrip
810c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result) == j);
811c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(result, true, false) == j);
812c5f01b2fSopenharmony_ci                    }
813c5f01b2fSopenharmony_ci                }
814c5f01b2fSopenharmony_ci            }
815c5f01b2fSopenharmony_ci
816c5f01b2fSopenharmony_ci            SECTION("double-precision float")
817c5f01b2fSopenharmony_ci            {
818c5f01b2fSopenharmony_ci                SECTION("3.1415925")
819c5f01b2fSopenharmony_ci                {
820c5f01b2fSopenharmony_ci                    double v = 3.1415925;
821c5f01b2fSopenharmony_ci                    json j = v;
822c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
823c5f01b2fSopenharmony_ci                    {
824c5f01b2fSopenharmony_ci                        0xfb, 0x40, 0x09, 0x21, 0xfb, 0x3f, 0xa6, 0xde, 0xfc
825c5f01b2fSopenharmony_ci                    };
826c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
827c5f01b2fSopenharmony_ci                    CHECK(result == expected);
828c5f01b2fSopenharmony_ci
829c5f01b2fSopenharmony_ci                    // roundtrip
830c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
831c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
832c5f01b2fSopenharmony_ci
833c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
834c5f01b2fSopenharmony_ci                }
835c5f01b2fSopenharmony_ci            }
836c5f01b2fSopenharmony_ci
837c5f01b2fSopenharmony_ci            SECTION("single-precision float")
838c5f01b2fSopenharmony_ci            {
839c5f01b2fSopenharmony_ci                SECTION("0.5")
840c5f01b2fSopenharmony_ci                {
841c5f01b2fSopenharmony_ci                    double v = 0.5;
842c5f01b2fSopenharmony_ci                    json j = v;
843c5f01b2fSopenharmony_ci                    // its double-precision float binary value is
844c5f01b2fSopenharmony_ci                    // {0xfb, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
845c5f01b2fSopenharmony_ci                    // but to save memory, we can store it as single-precision float.
846c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {0xfa, 0x3f, 0x00, 0x00, 0x00};
847c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
848c5f01b2fSopenharmony_ci                    CHECK(result == expected);
849c5f01b2fSopenharmony_ci                    // roundtrip
850c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
851c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
852c5f01b2fSopenharmony_ci                }
853c5f01b2fSopenharmony_ci                SECTION("0.0")
854c5f01b2fSopenharmony_ci                {
855c5f01b2fSopenharmony_ci                    double v = 0.0;
856c5f01b2fSopenharmony_ci                    json j = v;
857c5f01b2fSopenharmony_ci                    // its double-precision binary value is:
858c5f01b2fSopenharmony_ci                    // {0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
859c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {0xfa, 0x00, 0x00, 0x00, 0x00};
860c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
861c5f01b2fSopenharmony_ci                    CHECK(result == expected);
862c5f01b2fSopenharmony_ci                    // roundtrip
863c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
864c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
865c5f01b2fSopenharmony_ci                }
866c5f01b2fSopenharmony_ci                SECTION("-0.0")
867c5f01b2fSopenharmony_ci                {
868c5f01b2fSopenharmony_ci                    double v = -0.0;
869c5f01b2fSopenharmony_ci                    json j = v;
870c5f01b2fSopenharmony_ci                    // its double-precision binary value is:
871c5f01b2fSopenharmony_ci                    // {0xfb, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
872c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {0xfa, 0x80, 0x00, 0x00, 0x00};
873c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
874c5f01b2fSopenharmony_ci                    CHECK(result == expected);
875c5f01b2fSopenharmony_ci                    // roundtrip
876c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
877c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
878c5f01b2fSopenharmony_ci                }
879c5f01b2fSopenharmony_ci                SECTION("100.0")
880c5f01b2fSopenharmony_ci                {
881c5f01b2fSopenharmony_ci                    double v = 100.0;
882c5f01b2fSopenharmony_ci                    json j = v;
883c5f01b2fSopenharmony_ci                    // its double-precision binary value is:
884c5f01b2fSopenharmony_ci                    // {0xfb, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
885c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {0xfa, 0x42, 0xc8, 0x00, 0x00};
886c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
887c5f01b2fSopenharmony_ci                    CHECK(result == expected);
888c5f01b2fSopenharmony_ci                    // roundtrip
889c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
890c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
891c5f01b2fSopenharmony_ci                }
892c5f01b2fSopenharmony_ci                SECTION("200.0")
893c5f01b2fSopenharmony_ci                {
894c5f01b2fSopenharmony_ci                    double v = 200.0;
895c5f01b2fSopenharmony_ci                    json j = v;
896c5f01b2fSopenharmony_ci                    // its double-precision binary value is:
897c5f01b2fSopenharmony_ci                    // {0xfb, 0x40, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
898c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected = {0xfa, 0x43, 0x48, 0x00, 0x00};
899c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
900c5f01b2fSopenharmony_ci                    CHECK(result == expected);
901c5f01b2fSopenharmony_ci                    // roundtrip
902c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
903c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
904c5f01b2fSopenharmony_ci                }
905c5f01b2fSopenharmony_ci                SECTION("3.40282e+38(max float)")
906c5f01b2fSopenharmony_ci                {
907c5f01b2fSopenharmony_ci                    float v = (std::numeric_limits<float>::max)();
908c5f01b2fSopenharmony_ci                    json j = v;
909c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
910c5f01b2fSopenharmony_ci                    {
911c5f01b2fSopenharmony_ci                        0xfa, 0x7f, 0x7f, 0xff, 0xff
912c5f01b2fSopenharmony_ci                    };
913c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
914c5f01b2fSopenharmony_ci                    CHECK(result == expected);
915c5f01b2fSopenharmony_ci                    // roundtrip
916c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
917c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
918c5f01b2fSopenharmony_ci                }
919c5f01b2fSopenharmony_ci                SECTION("-3.40282e+38(lowest float)")
920c5f01b2fSopenharmony_ci                {
921c5f01b2fSopenharmony_ci                    auto v = static_cast<double>(std::numeric_limits<float>::lowest());
922c5f01b2fSopenharmony_ci                    json j = v;
923c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
924c5f01b2fSopenharmony_ci                    {
925c5f01b2fSopenharmony_ci                        0xfa, 0xff, 0x7f, 0xff, 0xff
926c5f01b2fSopenharmony_ci                    };
927c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
928c5f01b2fSopenharmony_ci                    CHECK(result == expected);
929c5f01b2fSopenharmony_ci                    // roundtrip
930c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
931c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
932c5f01b2fSopenharmony_ci                }
933c5f01b2fSopenharmony_ci                SECTION("1 + 3.40282e+38(more than max float)")
934c5f01b2fSopenharmony_ci                {
935c5f01b2fSopenharmony_ci                    double v = static_cast<double>((std::numeric_limits<float>::max)()) + 0.1e+34;
936c5f01b2fSopenharmony_ci                    json j = v;
937c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
938c5f01b2fSopenharmony_ci                    {
939c5f01b2fSopenharmony_ci                        0xfb, 0x47, 0xf0, 0x00, 0x03, 0x04, 0xdc, 0x64, 0x49
940c5f01b2fSopenharmony_ci                    };
941c5f01b2fSopenharmony_ci                    // double
942c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
943c5f01b2fSopenharmony_ci                    CHECK(result == expected);
944c5f01b2fSopenharmony_ci                    // roundtrip
945c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
946c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
947c5f01b2fSopenharmony_ci                }
948c5f01b2fSopenharmony_ci                SECTION("-1 - 3.40282e+38(less than lowest float)")
949c5f01b2fSopenharmony_ci                {
950c5f01b2fSopenharmony_ci                    double v = static_cast<double>(std::numeric_limits<float>::lowest()) - 1.0;
951c5f01b2fSopenharmony_ci                    json j = v;
952c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected =
953c5f01b2fSopenharmony_ci                    {
954c5f01b2fSopenharmony_ci                        0xfa, 0xff, 0x7f, 0xff, 0xff
955c5f01b2fSopenharmony_ci                    };
956c5f01b2fSopenharmony_ci                    // the same with lowest float
957c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
958c5f01b2fSopenharmony_ci                    CHECK(result == expected);
959c5f01b2fSopenharmony_ci                    // roundtrip
960c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
961c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == v);
962c5f01b2fSopenharmony_ci                }
963c5f01b2fSopenharmony_ci
964c5f01b2fSopenharmony_ci            }
965c5f01b2fSopenharmony_ci
966c5f01b2fSopenharmony_ci            SECTION("half-precision float (edge cases)")
967c5f01b2fSopenharmony_ci            {
968c5f01b2fSopenharmony_ci                SECTION("errors")
969c5f01b2fSopenharmony_ci                {
970c5f01b2fSopenharmony_ci                    SECTION("no byte follows")
971c5f01b2fSopenharmony_ci                    {
972c5f01b2fSopenharmony_ci                        json _;
973c5f01b2fSopenharmony_ci                        CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf9})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
974c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded());
975c5f01b2fSopenharmony_ci                    }
976c5f01b2fSopenharmony_ci                    SECTION("only one byte follows")
977c5f01b2fSopenharmony_ci                    {
978c5f01b2fSopenharmony_ci                        json _;
979c5f01b2fSopenharmony_ci                        CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
980c5f01b2fSopenharmony_ci                        CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded());
981c5f01b2fSopenharmony_ci                    }
982c5f01b2fSopenharmony_ci                }
983c5f01b2fSopenharmony_ci
984c5f01b2fSopenharmony_ci                SECTION("exp = 0b00000")
985c5f01b2fSopenharmony_ci                {
986c5f01b2fSopenharmony_ci                    SECTION("0 (0 00000 0000000000)")
987c5f01b2fSopenharmony_ci                    {
988c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00}));
989c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
990c5f01b2fSopenharmony_ci                        CHECK(d == 0.0);
991c5f01b2fSopenharmony_ci                    }
992c5f01b2fSopenharmony_ci
993c5f01b2fSopenharmony_ci                    SECTION("-0 (1 00000 0000000000)")
994c5f01b2fSopenharmony_ci                    {
995c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00}));
996c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
997c5f01b2fSopenharmony_ci                        CHECK(d == -0.0);
998c5f01b2fSopenharmony_ci                    }
999c5f01b2fSopenharmony_ci
1000c5f01b2fSopenharmony_ci                    SECTION("2**-24 (0 00000 0000000001)")
1001c5f01b2fSopenharmony_ci                    {
1002c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x01}));
1003c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
1004c5f01b2fSopenharmony_ci                        CHECK(d == std::pow(2.0, -24.0));
1005c5f01b2fSopenharmony_ci                    }
1006c5f01b2fSopenharmony_ci                }
1007c5f01b2fSopenharmony_ci
1008c5f01b2fSopenharmony_ci                SECTION("exp = 0b11111")
1009c5f01b2fSopenharmony_ci                {
1010c5f01b2fSopenharmony_ci                    SECTION("infinity (0 11111 0000000000)")
1011c5f01b2fSopenharmony_ci                    {
1012c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));
1013c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
1014c5f01b2fSopenharmony_ci                        CHECK(d == std::numeric_limits<json::number_float_t>::infinity());
1015c5f01b2fSopenharmony_ci                        CHECK(j.dump() == "null");
1016c5f01b2fSopenharmony_ci                    }
1017c5f01b2fSopenharmony_ci
1018c5f01b2fSopenharmony_ci                    SECTION("-infinity (1 11111 0000000000)")
1019c5f01b2fSopenharmony_ci                    {
1020c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0xfc, 0x00}));
1021c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
1022c5f01b2fSopenharmony_ci                        CHECK(d == -std::numeric_limits<json::number_float_t>::infinity());
1023c5f01b2fSopenharmony_ci                        CHECK(j.dump() == "null");
1024c5f01b2fSopenharmony_ci                    }
1025c5f01b2fSopenharmony_ci                }
1026c5f01b2fSopenharmony_ci
1027c5f01b2fSopenharmony_ci                SECTION("other values from https://en.wikipedia.org/wiki/Half-precision_floating-point_format")
1028c5f01b2fSopenharmony_ci                {
1029c5f01b2fSopenharmony_ci                    SECTION("1 (0 01111 0000000000)")
1030c5f01b2fSopenharmony_ci                    {
1031c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00}));
1032c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
1033c5f01b2fSopenharmony_ci                        CHECK(d == 1);
1034c5f01b2fSopenharmony_ci                    }
1035c5f01b2fSopenharmony_ci
1036c5f01b2fSopenharmony_ci                    SECTION("-2 (1 10000 0000000000)")
1037c5f01b2fSopenharmony_ci                    {
1038c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0xc0, 0x00}));
1039c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
1040c5f01b2fSopenharmony_ci                        CHECK(d == -2);
1041c5f01b2fSopenharmony_ci                    }
1042c5f01b2fSopenharmony_ci
1043c5f01b2fSopenharmony_ci                    SECTION("65504 (0 11110 1111111111)")
1044c5f01b2fSopenharmony_ci                    {
1045c5f01b2fSopenharmony_ci                        json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff}));
1046c5f01b2fSopenharmony_ci                        json::number_float_t d{j};
1047c5f01b2fSopenharmony_ci                        CHECK(d == 65504);
1048c5f01b2fSopenharmony_ci                    }
1049c5f01b2fSopenharmony_ci                }
1050c5f01b2fSopenharmony_ci
1051c5f01b2fSopenharmony_ci                SECTION("infinity")
1052c5f01b2fSopenharmony_ci                {
1053c5f01b2fSopenharmony_ci                    json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c, 0x00}));
1054c5f01b2fSopenharmony_ci                    json::number_float_t d{j};
1055c5f01b2fSopenharmony_ci                    CHECK(!std::isfinite(d));
1056c5f01b2fSopenharmony_ci                    CHECK(j.dump() == "null");
1057c5f01b2fSopenharmony_ci                }
1058c5f01b2fSopenharmony_ci
1059c5f01b2fSopenharmony_ci                SECTION("NaN")
1060c5f01b2fSopenharmony_ci                {
1061c5f01b2fSopenharmony_ci                    json j = json::from_cbor(std::vector<uint8_t>({0xf9, 0x7e, 0x00}));
1062c5f01b2fSopenharmony_ci                    json::number_float_t d{j};
1063c5f01b2fSopenharmony_ci                    CHECK(std::isnan(d));
1064c5f01b2fSopenharmony_ci                    CHECK(j.dump() == "null");
1065c5f01b2fSopenharmony_ci                }
1066c5f01b2fSopenharmony_ci            }
1067c5f01b2fSopenharmony_ci        }
1068c5f01b2fSopenharmony_ci
1069c5f01b2fSopenharmony_ci        SECTION("string")
1070c5f01b2fSopenharmony_ci        {
1071c5f01b2fSopenharmony_ci            SECTION("N = 0..23")
1072c5f01b2fSopenharmony_ci            {
1073c5f01b2fSopenharmony_ci                for (size_t N = 0; N <= 0x17; ++N)
1074c5f01b2fSopenharmony_ci                {
1075c5f01b2fSopenharmony_ci                    CAPTURE(N)
1076c5f01b2fSopenharmony_ci
1077c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1078c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
1079c5f01b2fSopenharmony_ci                    json j = s;
1080c5f01b2fSopenharmony_ci
1081c5f01b2fSopenharmony_ci                    // create expected byte vector
1082c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
1083c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<uint8_t>(0x60 + N));
1084c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
1085c5f01b2fSopenharmony_ci                    {
1086c5f01b2fSopenharmony_ci                        expected.push_back('x');
1087c5f01b2fSopenharmony_ci                    }
1088c5f01b2fSopenharmony_ci
1089c5f01b2fSopenharmony_ci                    // compare result + size
1090c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1091c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1092c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 1);
1093c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1094c5f01b2fSopenharmony_ci                    if (N > 0)
1095c5f01b2fSopenharmony_ci                    {
1096c5f01b2fSopenharmony_ci                        CHECK(result.back() != '\x00');
1097c5f01b2fSopenharmony_ci                    }
1098c5f01b2fSopenharmony_ci
1099c5f01b2fSopenharmony_ci                    // roundtrip
1100c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1101c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1102c5f01b2fSopenharmony_ci                }
1103c5f01b2fSopenharmony_ci            }
1104c5f01b2fSopenharmony_ci
1105c5f01b2fSopenharmony_ci            SECTION("N = 24..255")
1106c5f01b2fSopenharmony_ci            {
1107c5f01b2fSopenharmony_ci                for (size_t N = 24; N <= 255; ++N)
1108c5f01b2fSopenharmony_ci                {
1109c5f01b2fSopenharmony_ci                    CAPTURE(N)
1110c5f01b2fSopenharmony_ci
1111c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1112c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
1113c5f01b2fSopenharmony_ci                    json j = s;
1114c5f01b2fSopenharmony_ci
1115c5f01b2fSopenharmony_ci                    // create expected byte vector
1116c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
1117c5f01b2fSopenharmony_ci                    expected.push_back(0x78);
1118c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<uint8_t>(N));
1119c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
1120c5f01b2fSopenharmony_ci                    {
1121c5f01b2fSopenharmony_ci                        expected.push_back('x');
1122c5f01b2fSopenharmony_ci                    }
1123c5f01b2fSopenharmony_ci
1124c5f01b2fSopenharmony_ci                    // compare result + size
1125c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1126c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1127c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 2);
1128c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1129c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1130c5f01b2fSopenharmony_ci
1131c5f01b2fSopenharmony_ci                    // roundtrip
1132c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1133c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1134c5f01b2fSopenharmony_ci                }
1135c5f01b2fSopenharmony_ci            }
1136c5f01b2fSopenharmony_ci
1137c5f01b2fSopenharmony_ci            SECTION("N = 256..65535")
1138c5f01b2fSopenharmony_ci            {
1139c5f01b2fSopenharmony_ci                for (size_t N :
1140c5f01b2fSopenharmony_ci                        {
1141c5f01b2fSopenharmony_ci                            256u, 999u, 1025u, 3333u, 2048u, 65535u
1142c5f01b2fSopenharmony_ci                        })
1143c5f01b2fSopenharmony_ci                {
1144c5f01b2fSopenharmony_ci                    CAPTURE(N)
1145c5f01b2fSopenharmony_ci
1146c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1147c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
1148c5f01b2fSopenharmony_ci                    json j = s;
1149c5f01b2fSopenharmony_ci
1150c5f01b2fSopenharmony_ci                    // create expected byte vector (hack: create string first)
1151c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(N, 'x');
1152c5f01b2fSopenharmony_ci                    // reverse order of commands, because we insert at begin()
1153c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1154c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1155c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 0x79);
1156c5f01b2fSopenharmony_ci
1157c5f01b2fSopenharmony_ci                    // compare result + size
1158c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1159c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1160c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 3);
1161c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1162c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1163c5f01b2fSopenharmony_ci
1164c5f01b2fSopenharmony_ci                    // roundtrip
1165c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1166c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1167c5f01b2fSopenharmony_ci                }
1168c5f01b2fSopenharmony_ci            }
1169c5f01b2fSopenharmony_ci
1170c5f01b2fSopenharmony_ci            SECTION("N = 65536..4294967295")
1171c5f01b2fSopenharmony_ci            {
1172c5f01b2fSopenharmony_ci                for (size_t N :
1173c5f01b2fSopenharmony_ci                        {
1174c5f01b2fSopenharmony_ci                            65536u, 77777u, 1048576u
1175c5f01b2fSopenharmony_ci                        })
1176c5f01b2fSopenharmony_ci                {
1177c5f01b2fSopenharmony_ci                    CAPTURE(N)
1178c5f01b2fSopenharmony_ci
1179c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1180c5f01b2fSopenharmony_ci                    const auto s = std::string(N, 'x');
1181c5f01b2fSopenharmony_ci                    json j = s;
1182c5f01b2fSopenharmony_ci
1183c5f01b2fSopenharmony_ci                    // create expected byte vector (hack: create string first)
1184c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(N, 'x');
1185c5f01b2fSopenharmony_ci                    // reverse order of commands, because we insert at begin()
1186c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1187c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1188c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));
1189c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));
1190c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 0x7a);
1191c5f01b2fSopenharmony_ci
1192c5f01b2fSopenharmony_ci                    // compare result + size
1193c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1194c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1195c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 5);
1196c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1197c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1198c5f01b2fSopenharmony_ci
1199c5f01b2fSopenharmony_ci                    // roundtrip
1200c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1201c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1202c5f01b2fSopenharmony_ci                }
1203c5f01b2fSopenharmony_ci            }
1204c5f01b2fSopenharmony_ci        }
1205c5f01b2fSopenharmony_ci
1206c5f01b2fSopenharmony_ci        SECTION("array")
1207c5f01b2fSopenharmony_ci        {
1208c5f01b2fSopenharmony_ci            SECTION("empty")
1209c5f01b2fSopenharmony_ci            {
1210c5f01b2fSopenharmony_ci                json j = json::array();
1211c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0x80};
1212c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1213c5f01b2fSopenharmony_ci                CHECK(result == expected);
1214c5f01b2fSopenharmony_ci
1215c5f01b2fSopenharmony_ci                // roundtrip
1216c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1217c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1218c5f01b2fSopenharmony_ci            }
1219c5f01b2fSopenharmony_ci
1220c5f01b2fSopenharmony_ci            SECTION("[null]")
1221c5f01b2fSopenharmony_ci            {
1222c5f01b2fSopenharmony_ci                json j = {nullptr};
1223c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0x81, 0xf6};
1224c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1225c5f01b2fSopenharmony_ci                CHECK(result == expected);
1226c5f01b2fSopenharmony_ci
1227c5f01b2fSopenharmony_ci                // roundtrip
1228c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1229c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1230c5f01b2fSopenharmony_ci            }
1231c5f01b2fSopenharmony_ci
1232c5f01b2fSopenharmony_ci            SECTION("[1,2,3,4,5]")
1233c5f01b2fSopenharmony_ci            {
1234c5f01b2fSopenharmony_ci                json j = json::parse("[1,2,3,4,5]");
1235c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0x85, 0x01, 0x02, 0x03, 0x04, 0x05};
1236c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1237c5f01b2fSopenharmony_ci                CHECK(result == expected);
1238c5f01b2fSopenharmony_ci
1239c5f01b2fSopenharmony_ci                // roundtrip
1240c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1241c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1242c5f01b2fSopenharmony_ci            }
1243c5f01b2fSopenharmony_ci
1244c5f01b2fSopenharmony_ci            SECTION("[[[[]]]]")
1245c5f01b2fSopenharmony_ci            {
1246c5f01b2fSopenharmony_ci                json j = json::parse("[[[[]]]]");
1247c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0x81, 0x81, 0x81, 0x80};
1248c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1249c5f01b2fSopenharmony_ci                CHECK(result == expected);
1250c5f01b2fSopenharmony_ci
1251c5f01b2fSopenharmony_ci                // roundtrip
1252c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1253c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1254c5f01b2fSopenharmony_ci            }
1255c5f01b2fSopenharmony_ci
1256c5f01b2fSopenharmony_ci            SECTION("array with uint16_t elements")
1257c5f01b2fSopenharmony_ci            {
1258c5f01b2fSopenharmony_ci                json j(257, nullptr);
1259c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected(j.size() + 3, 0xf6); // all null
1260c5f01b2fSopenharmony_ci                expected[0] = 0x99; // array 16 bit
1261c5f01b2fSopenharmony_ci                expected[1] = 0x01; // size (0x0101), byte 0
1262c5f01b2fSopenharmony_ci                expected[2] = 0x01; // size (0x0101), byte 1
1263c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1264c5f01b2fSopenharmony_ci                CHECK(result == expected);
1265c5f01b2fSopenharmony_ci
1266c5f01b2fSopenharmony_ci                // roundtrip
1267c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1268c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1269c5f01b2fSopenharmony_ci            }
1270c5f01b2fSopenharmony_ci
1271c5f01b2fSopenharmony_ci            SECTION("array with uint32_t elements")
1272c5f01b2fSopenharmony_ci            {
1273c5f01b2fSopenharmony_ci                json j(65793, nullptr);
1274c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected(j.size() + 5, 0xf6); // all null
1275c5f01b2fSopenharmony_ci                expected[0] = 0x9a; // array 32 bit
1276c5f01b2fSopenharmony_ci                expected[1] = 0x00; // size (0x00010101), byte 0
1277c5f01b2fSopenharmony_ci                expected[2] = 0x01; // size (0x00010101), byte 1
1278c5f01b2fSopenharmony_ci                expected[3] = 0x01; // size (0x00010101), byte 2
1279c5f01b2fSopenharmony_ci                expected[4] = 0x01; // size (0x00010101), byte 3
1280c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1281c5f01b2fSopenharmony_ci                CHECK(result == expected);
1282c5f01b2fSopenharmony_ci
1283c5f01b2fSopenharmony_ci                // roundtrip
1284c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1285c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1286c5f01b2fSopenharmony_ci            }
1287c5f01b2fSopenharmony_ci        }
1288c5f01b2fSopenharmony_ci
1289c5f01b2fSopenharmony_ci        SECTION("object")
1290c5f01b2fSopenharmony_ci        {
1291c5f01b2fSopenharmony_ci            SECTION("empty")
1292c5f01b2fSopenharmony_ci            {
1293c5f01b2fSopenharmony_ci                json j = json::object();
1294c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0xa0};
1295c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1296c5f01b2fSopenharmony_ci                CHECK(result == expected);
1297c5f01b2fSopenharmony_ci
1298c5f01b2fSopenharmony_ci                // roundtrip
1299c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1300c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1301c5f01b2fSopenharmony_ci            }
1302c5f01b2fSopenharmony_ci
1303c5f01b2fSopenharmony_ci            SECTION("{\"\":null}")
1304c5f01b2fSopenharmony_ci            {
1305c5f01b2fSopenharmony_ci                json j = {{"", nullptr}};
1306c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected = {0xa1, 0x60, 0xf6};
1307c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1308c5f01b2fSopenharmony_ci                CHECK(result == expected);
1309c5f01b2fSopenharmony_ci
1310c5f01b2fSopenharmony_ci                // roundtrip
1311c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1312c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1313c5f01b2fSopenharmony_ci            }
1314c5f01b2fSopenharmony_ci
1315c5f01b2fSopenharmony_ci            SECTION("{\"a\": {\"b\": {\"c\": {}}}}")
1316c5f01b2fSopenharmony_ci            {
1317c5f01b2fSopenharmony_ci                json j = json::parse(R"({"a": {"b": {"c": {}}}})");
1318c5f01b2fSopenharmony_ci                std::vector<uint8_t> expected =
1319c5f01b2fSopenharmony_ci                {
1320c5f01b2fSopenharmony_ci                    0xa1, 0x61, 0x61, 0xa1, 0x61, 0x62, 0xa1, 0x61, 0x63, 0xa0
1321c5f01b2fSopenharmony_ci                };
1322c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1323c5f01b2fSopenharmony_ci                CHECK(result == expected);
1324c5f01b2fSopenharmony_ci
1325c5f01b2fSopenharmony_ci                // roundtrip
1326c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1327c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1328c5f01b2fSopenharmony_ci            }
1329c5f01b2fSopenharmony_ci
1330c5f01b2fSopenharmony_ci            SECTION("object with uint8_t elements")
1331c5f01b2fSopenharmony_ci            {
1332c5f01b2fSopenharmony_ci                json j;
1333c5f01b2fSopenharmony_ci                for (auto i = 0; i < 255; ++i)
1334c5f01b2fSopenharmony_ci                {
1335c5f01b2fSopenharmony_ci                    // format i to a fixed width of 5
1336c5f01b2fSopenharmony_ci                    // each entry will need 7 bytes: 6 for string, 1 for null
1337c5f01b2fSopenharmony_ci                    std::stringstream ss;
1338c5f01b2fSopenharmony_ci                    ss << std::setw(5) << std::setfill('0') << i;
1339c5f01b2fSopenharmony_ci                    j.emplace(ss.str(), nullptr);
1340c5f01b2fSopenharmony_ci                }
1341c5f01b2fSopenharmony_ci
1342c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1343c5f01b2fSopenharmony_ci
1344c5f01b2fSopenharmony_ci                // Checking against an expected vector byte by byte is
1345c5f01b2fSopenharmony_ci                // difficult, because no assumption on the order of key/value
1346c5f01b2fSopenharmony_ci                // pairs are made. We therefore only check the prefix (type and
1347c5f01b2fSopenharmony_ci                // size and the overall size. The rest is then handled in the
1348c5f01b2fSopenharmony_ci                // roundtrip check.
1349c5f01b2fSopenharmony_ci                CHECK(result.size() == 1787); // 1 type, 1 size, 255*7 content
1350c5f01b2fSopenharmony_ci                CHECK(result[0] == 0xb8); // map 8 bit
1351c5f01b2fSopenharmony_ci                CHECK(result[1] == 0xff); // size byte (0xff)
1352c5f01b2fSopenharmony_ci                // roundtrip
1353c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1354c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1355c5f01b2fSopenharmony_ci            }
1356c5f01b2fSopenharmony_ci
1357c5f01b2fSopenharmony_ci            SECTION("object with uint16_t elements")
1358c5f01b2fSopenharmony_ci            {
1359c5f01b2fSopenharmony_ci                json j;
1360c5f01b2fSopenharmony_ci                for (auto i = 0; i < 256; ++i)
1361c5f01b2fSopenharmony_ci                {
1362c5f01b2fSopenharmony_ci                    // format i to a fixed width of 5
1363c5f01b2fSopenharmony_ci                    // each entry will need 7 bytes: 6 for string, 1 for null
1364c5f01b2fSopenharmony_ci                    std::stringstream ss;
1365c5f01b2fSopenharmony_ci                    ss << std::setw(5) << std::setfill('0') << i;
1366c5f01b2fSopenharmony_ci                    j.emplace(ss.str(), nullptr);
1367c5f01b2fSopenharmony_ci                }
1368c5f01b2fSopenharmony_ci
1369c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1370c5f01b2fSopenharmony_ci
1371c5f01b2fSopenharmony_ci                // Checking against an expected vector byte by byte is
1372c5f01b2fSopenharmony_ci                // difficult, because no assumption on the order of key/value
1373c5f01b2fSopenharmony_ci                // pairs are made. We therefore only check the prefix (type and
1374c5f01b2fSopenharmony_ci                // size and the overall size. The rest is then handled in the
1375c5f01b2fSopenharmony_ci                // roundtrip check.
1376c5f01b2fSopenharmony_ci                CHECK(result.size() == 1795); // 1 type, 2 size, 256*7 content
1377c5f01b2fSopenharmony_ci                CHECK(result[0] == 0xb9); // map 16 bit
1378c5f01b2fSopenharmony_ci                CHECK(result[1] == 0x01); // byte 0 of size (0x0100)
1379c5f01b2fSopenharmony_ci                CHECK(result[2] == 0x00); // byte 1 of size (0x0100)
1380c5f01b2fSopenharmony_ci
1381c5f01b2fSopenharmony_ci                // roundtrip
1382c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1383c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1384c5f01b2fSopenharmony_ci            }
1385c5f01b2fSopenharmony_ci
1386c5f01b2fSopenharmony_ci            SECTION("object with uint32_t elements")
1387c5f01b2fSopenharmony_ci            {
1388c5f01b2fSopenharmony_ci                json j;
1389c5f01b2fSopenharmony_ci                for (auto i = 0; i < 65536; ++i)
1390c5f01b2fSopenharmony_ci                {
1391c5f01b2fSopenharmony_ci                    // format i to a fixed width of 5
1392c5f01b2fSopenharmony_ci                    // each entry will need 7 bytes: 6 for string, 1 for null
1393c5f01b2fSopenharmony_ci                    std::stringstream ss;
1394c5f01b2fSopenharmony_ci                    ss << std::setw(5) << std::setfill('0') << i;
1395c5f01b2fSopenharmony_ci                    j.emplace(ss.str(), nullptr);
1396c5f01b2fSopenharmony_ci                }
1397c5f01b2fSopenharmony_ci
1398c5f01b2fSopenharmony_ci                const auto result = json::to_cbor(j);
1399c5f01b2fSopenharmony_ci
1400c5f01b2fSopenharmony_ci                // Checking against an expected vector byte by byte is
1401c5f01b2fSopenharmony_ci                // difficult, because no assumption on the order of key/value
1402c5f01b2fSopenharmony_ci                // pairs are made. We therefore only check the prefix (type and
1403c5f01b2fSopenharmony_ci                // size and the overall size. The rest is then handled in the
1404c5f01b2fSopenharmony_ci                // roundtrip check.
1405c5f01b2fSopenharmony_ci                CHECK(result.size() == 458757); // 1 type, 4 size, 65536*7 content
1406c5f01b2fSopenharmony_ci                CHECK(result[0] == 0xba); // map 32 bit
1407c5f01b2fSopenharmony_ci                CHECK(result[1] == 0x00); // byte 0 of size (0x00010000)
1408c5f01b2fSopenharmony_ci                CHECK(result[2] == 0x01); // byte 1 of size (0x00010000)
1409c5f01b2fSopenharmony_ci                CHECK(result[3] == 0x00); // byte 2 of size (0x00010000)
1410c5f01b2fSopenharmony_ci                CHECK(result[4] == 0x00); // byte 3 of size (0x00010000)
1411c5f01b2fSopenharmony_ci
1412c5f01b2fSopenharmony_ci                // roundtrip
1413c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result) == j);
1414c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(result, true, false) == j);
1415c5f01b2fSopenharmony_ci            }
1416c5f01b2fSopenharmony_ci        }
1417c5f01b2fSopenharmony_ci
1418c5f01b2fSopenharmony_ci        SECTION("binary")
1419c5f01b2fSopenharmony_ci        {
1420c5f01b2fSopenharmony_ci            SECTION("N = 0..23")
1421c5f01b2fSopenharmony_ci            {
1422c5f01b2fSopenharmony_ci                for (size_t N = 0; N <= 0x17; ++N)
1423c5f01b2fSopenharmony_ci                {
1424c5f01b2fSopenharmony_ci                    CAPTURE(N)
1425c5f01b2fSopenharmony_ci
1426c5f01b2fSopenharmony_ci                    // create JSON value with byte array containing of N * 'x'
1427c5f01b2fSopenharmony_ci                    const auto s = std::vector<uint8_t>(N, 'x');
1428c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1429c5f01b2fSopenharmony_ci
1430c5f01b2fSopenharmony_ci                    // create expected byte vector
1431c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
1432c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<uint8_t>(0x40 + N));
1433c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
1434c5f01b2fSopenharmony_ci                    {
1435c5f01b2fSopenharmony_ci                        expected.push_back(0x78);
1436c5f01b2fSopenharmony_ci                    }
1437c5f01b2fSopenharmony_ci
1438c5f01b2fSopenharmony_ci                    // compare result + size
1439c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1440c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1441c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 1);
1442c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1443c5f01b2fSopenharmony_ci                    if (N > 0)
1444c5f01b2fSopenharmony_ci                    {
1445c5f01b2fSopenharmony_ci                        CHECK(result.back() != '\x00');
1446c5f01b2fSopenharmony_ci                    }
1447c5f01b2fSopenharmony_ci
1448c5f01b2fSopenharmony_ci                    // roundtrip
1449c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1450c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1451c5f01b2fSopenharmony_ci                }
1452c5f01b2fSopenharmony_ci            }
1453c5f01b2fSopenharmony_ci
1454c5f01b2fSopenharmony_ci            SECTION("N = 24..255")
1455c5f01b2fSopenharmony_ci            {
1456c5f01b2fSopenharmony_ci                for (size_t N = 24; N <= 255; ++N)
1457c5f01b2fSopenharmony_ci                {
1458c5f01b2fSopenharmony_ci                    CAPTURE(N)
1459c5f01b2fSopenharmony_ci
1460c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1461c5f01b2fSopenharmony_ci                    const auto s = std::vector<uint8_t>(N, 'x');
1462c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1463c5f01b2fSopenharmony_ci
1464c5f01b2fSopenharmony_ci                    // create expected byte vector
1465c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected;
1466c5f01b2fSopenharmony_ci                    expected.push_back(0x58);
1467c5f01b2fSopenharmony_ci                    expected.push_back(static_cast<uint8_t>(N));
1468c5f01b2fSopenharmony_ci                    for (size_t i = 0; i < N; ++i)
1469c5f01b2fSopenharmony_ci                    {
1470c5f01b2fSopenharmony_ci                        expected.push_back('x');
1471c5f01b2fSopenharmony_ci                    }
1472c5f01b2fSopenharmony_ci
1473c5f01b2fSopenharmony_ci                    // compare result + size
1474c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1475c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1476c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 2);
1477c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1478c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1479c5f01b2fSopenharmony_ci
1480c5f01b2fSopenharmony_ci                    // roundtrip
1481c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1482c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1483c5f01b2fSopenharmony_ci                }
1484c5f01b2fSopenharmony_ci            }
1485c5f01b2fSopenharmony_ci
1486c5f01b2fSopenharmony_ci            SECTION("N = 256..65535")
1487c5f01b2fSopenharmony_ci            {
1488c5f01b2fSopenharmony_ci                for (size_t N :
1489c5f01b2fSopenharmony_ci                        {
1490c5f01b2fSopenharmony_ci                            256u, 999u, 1025u, 3333u, 2048u, 65535u
1491c5f01b2fSopenharmony_ci                        })
1492c5f01b2fSopenharmony_ci                {
1493c5f01b2fSopenharmony_ci                    CAPTURE(N)
1494c5f01b2fSopenharmony_ci
1495c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1496c5f01b2fSopenharmony_ci                    const auto s = std::vector<uint8_t>(N, 'x');
1497c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1498c5f01b2fSopenharmony_ci
1499c5f01b2fSopenharmony_ci                    // create expected byte vector (hack: create string first)
1500c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(N, 'x');
1501c5f01b2fSopenharmony_ci                    // reverse order of commands, because we insert at begin()
1502c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1503c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1504c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 0x59);
1505c5f01b2fSopenharmony_ci
1506c5f01b2fSopenharmony_ci                    // compare result + size
1507c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1508c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1509c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 3);
1510c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1511c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1512c5f01b2fSopenharmony_ci
1513c5f01b2fSopenharmony_ci                    // roundtrip
1514c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1515c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1516c5f01b2fSopenharmony_ci                }
1517c5f01b2fSopenharmony_ci            }
1518c5f01b2fSopenharmony_ci
1519c5f01b2fSopenharmony_ci            SECTION("N = 65536..4294967295")
1520c5f01b2fSopenharmony_ci            {
1521c5f01b2fSopenharmony_ci                for (size_t N :
1522c5f01b2fSopenharmony_ci                        {
1523c5f01b2fSopenharmony_ci                            65536u, 77777u, 1048576u
1524c5f01b2fSopenharmony_ci                        })
1525c5f01b2fSopenharmony_ci                {
1526c5f01b2fSopenharmony_ci                    CAPTURE(N)
1527c5f01b2fSopenharmony_ci
1528c5f01b2fSopenharmony_ci                    // create JSON value with string containing of N * 'x'
1529c5f01b2fSopenharmony_ci                    const auto s = std::vector<uint8_t>(N, 'x');
1530c5f01b2fSopenharmony_ci                    json j = json::binary(s);
1531c5f01b2fSopenharmony_ci
1532c5f01b2fSopenharmony_ci                    // create expected byte vector (hack: create string first)
1533c5f01b2fSopenharmony_ci                    std::vector<uint8_t> expected(N, 'x');
1534c5f01b2fSopenharmony_ci                    // reverse order of commands, because we insert at begin()
1535c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>(N & 0xff));
1536c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 8) & 0xff));
1537c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 16) & 0xff));
1538c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), static_cast<uint8_t>((N >> 24) & 0xff));
1539c5f01b2fSopenharmony_ci                    expected.insert(expected.begin(), 0x5a);
1540c5f01b2fSopenharmony_ci
1541c5f01b2fSopenharmony_ci                    // compare result + size
1542c5f01b2fSopenharmony_ci                    const auto result = json::to_cbor(j);
1543c5f01b2fSopenharmony_ci                    CHECK(result == expected);
1544c5f01b2fSopenharmony_ci                    CHECK(result.size() == N + 5);
1545c5f01b2fSopenharmony_ci                    // check that no null byte is appended
1546c5f01b2fSopenharmony_ci                    CHECK(result.back() != '\x00');
1547c5f01b2fSopenharmony_ci
1548c5f01b2fSopenharmony_ci                    // roundtrip
1549c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result) == j);
1550c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(result, true, false) == j);
1551c5f01b2fSopenharmony_ci                }
1552c5f01b2fSopenharmony_ci            }
1553c5f01b2fSopenharmony_ci
1554c5f01b2fSopenharmony_ci            SECTION("indefinite size")
1555c5f01b2fSopenharmony_ci            {
1556c5f01b2fSopenharmony_ci                std::vector<std::uint8_t> input = {0x5F, 0x44, 0xaa, 0xbb, 0xcc, 0xdd, 0x43, 0xee, 0xff, 0x99, 0xFF};
1557c5f01b2fSopenharmony_ci                auto j = json::from_cbor(input);
1558c5f01b2fSopenharmony_ci                CHECK(j.is_binary());
1559c5f01b2fSopenharmony_ci                auto k = json::binary({0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x99});
1560c5f01b2fSopenharmony_ci                CAPTURE(j.dump(0, ' ', false, json::error_handler_t::strict))
1561c5f01b2fSopenharmony_ci                CHECK(j == k);
1562c5f01b2fSopenharmony_ci            }
1563c5f01b2fSopenharmony_ci
1564c5f01b2fSopenharmony_ci            SECTION("binary in array")
1565c5f01b2fSopenharmony_ci            {
1566c5f01b2fSopenharmony_ci                // array with three empty byte strings
1567c5f01b2fSopenharmony_ci                std::vector<std::uint8_t> input = {0x83, 0x40, 0x40, 0x40};
1568c5f01b2fSopenharmony_ci                json _;
1569c5f01b2fSopenharmony_ci                CHECK_NOTHROW(_ = json::from_cbor(input));
1570c5f01b2fSopenharmony_ci            }
1571c5f01b2fSopenharmony_ci
1572c5f01b2fSopenharmony_ci            SECTION("binary in object")
1573c5f01b2fSopenharmony_ci            {
1574c5f01b2fSopenharmony_ci                // object mapping "foo" to empty byte string
1575c5f01b2fSopenharmony_ci                std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x40};
1576c5f01b2fSopenharmony_ci                json _;
1577c5f01b2fSopenharmony_ci                CHECK_NOTHROW(_ = json::from_cbor(input));
1578c5f01b2fSopenharmony_ci            }
1579c5f01b2fSopenharmony_ci
1580c5f01b2fSopenharmony_ci            SECTION("SAX callback with binary")
1581c5f01b2fSopenharmony_ci            {
1582c5f01b2fSopenharmony_ci                // object mapping "foo" to byte string
1583c5f01b2fSopenharmony_ci                std::vector<std::uint8_t> input = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0x41, 0x00};
1584c5f01b2fSopenharmony_ci
1585c5f01b2fSopenharmony_ci                // callback to set binary_seen to true if a binary value was seen
1586c5f01b2fSopenharmony_ci                bool binary_seen = false;
1587c5f01b2fSopenharmony_ci                auto callback = [&binary_seen](int /*depth*/, json::parse_event_t /*event*/, json & parsed) noexcept
1588c5f01b2fSopenharmony_ci                {
1589c5f01b2fSopenharmony_ci                    if (parsed.is_binary())
1590c5f01b2fSopenharmony_ci                    {
1591c5f01b2fSopenharmony_ci                        binary_seen = true;
1592c5f01b2fSopenharmony_ci                    }
1593c5f01b2fSopenharmony_ci                    return true;
1594c5f01b2fSopenharmony_ci                };
1595c5f01b2fSopenharmony_ci
1596c5f01b2fSopenharmony_ci                json j;
1597c5f01b2fSopenharmony_ci                auto cbp = nlohmann::detail::json_sax_dom_callback_parser<json>(j, callback, true);
1598c5f01b2fSopenharmony_ci                CHECK(json::sax_parse(input, &cbp, json::input_format_t::cbor));
1599c5f01b2fSopenharmony_ci                CHECK(j.at("foo").is_binary());
1600c5f01b2fSopenharmony_ci                CHECK(binary_seen);
1601c5f01b2fSopenharmony_ci            }
1602c5f01b2fSopenharmony_ci        }
1603c5f01b2fSopenharmony_ci    }
1604c5f01b2fSopenharmony_ci
1605c5f01b2fSopenharmony_ci    SECTION("additional deserialization")
1606c5f01b2fSopenharmony_ci    {
1607c5f01b2fSopenharmony_ci        SECTION("0x5b (byte array)")
1608c5f01b2fSopenharmony_ci        {
1609c5f01b2fSopenharmony_ci            std::vector<uint8_t> given = {0x5b, 0x00, 0x00, 0x00, 0x00,
1610c5f01b2fSopenharmony_ci                                          0x00, 0x00, 0x00, 0x01, 0x61
1611c5f01b2fSopenharmony_ci                                         };
1612c5f01b2fSopenharmony_ci            json j = json::from_cbor(given);
1613c5f01b2fSopenharmony_ci            CHECK(j == json::binary(std::vector<uint8_t> {'a'}));
1614c5f01b2fSopenharmony_ci        }
1615c5f01b2fSopenharmony_ci
1616c5f01b2fSopenharmony_ci        SECTION("0x7b (string)")
1617c5f01b2fSopenharmony_ci        {
1618c5f01b2fSopenharmony_ci            std::vector<uint8_t> given = {0x7b, 0x00, 0x00, 0x00, 0x00,
1619c5f01b2fSopenharmony_ci                                          0x00, 0x00, 0x00, 0x01, 0x61
1620c5f01b2fSopenharmony_ci                                         };
1621c5f01b2fSopenharmony_ci            json j = json::from_cbor(given);
1622c5f01b2fSopenharmony_ci            CHECK(j == "a");
1623c5f01b2fSopenharmony_ci        }
1624c5f01b2fSopenharmony_ci
1625c5f01b2fSopenharmony_ci        SECTION("0x9b (array)")
1626c5f01b2fSopenharmony_ci        {
1627c5f01b2fSopenharmony_ci            std::vector<uint8_t> given = {0x9b, 0x00, 0x00, 0x00, 0x00,
1628c5f01b2fSopenharmony_ci                                          0x00, 0x00, 0x00, 0x01, 0xf4
1629c5f01b2fSopenharmony_ci                                         };
1630c5f01b2fSopenharmony_ci            json j = json::from_cbor(given);
1631c5f01b2fSopenharmony_ci            CHECK(j == json::parse("[false]"));
1632c5f01b2fSopenharmony_ci        }
1633c5f01b2fSopenharmony_ci
1634c5f01b2fSopenharmony_ci        SECTION("0xbb (map)")
1635c5f01b2fSopenharmony_ci        {
1636c5f01b2fSopenharmony_ci            std::vector<uint8_t> given = {0xbb, 0x00, 0x00, 0x00, 0x00,
1637c5f01b2fSopenharmony_ci                                          0x00, 0x00, 0x00, 0x01, 0x60, 0xf4
1638c5f01b2fSopenharmony_ci                                         };
1639c5f01b2fSopenharmony_ci            json j = json::from_cbor(given);
1640c5f01b2fSopenharmony_ci            CHECK(j == json::parse("{\"\": false}"));
1641c5f01b2fSopenharmony_ci        }
1642c5f01b2fSopenharmony_ci    }
1643c5f01b2fSopenharmony_ci
1644c5f01b2fSopenharmony_ci    SECTION("errors")
1645c5f01b2fSopenharmony_ci    {
1646c5f01b2fSopenharmony_ci        SECTION("empty byte vector")
1647c5f01b2fSopenharmony_ci        {
1648c5f01b2fSopenharmony_ci            json _;
1649c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>()), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1650c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded());
1651c5f01b2fSopenharmony_ci        }
1652c5f01b2fSopenharmony_ci
1653c5f01b2fSopenharmony_ci        SECTION("too short byte vector")
1654c5f01b2fSopenharmony_ci        {
1655c5f01b2fSopenharmony_ci            json _;
1656c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x18})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1657c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x19})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1658c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1659c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1660c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1661c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1662c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1663c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1664c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1665c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1666c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1667c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1668c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1669c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1670c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
1671c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x62})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1672c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x62, 0x60})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1673c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x7F})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1674c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1675c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x82, 0x01})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1676c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1677c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1678c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0X61})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1679c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1680c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x5F})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR binary: unexpected end of input", json::parse_error&);
1681c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x5F, 0x00})), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR binary: expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x00", json::parse_error&);
1682c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x41})), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR binary: unexpected end of input", json::parse_error&);
1683c5f01b2fSopenharmony_ci
1684c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded());
1685c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded());
1686c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x19, 0x00}), true, false).is_discarded());
1687c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a}), true, false).is_discarded());
1688c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00}), true, false).is_discarded());
1689c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00}), true, false).is_discarded());
1690c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00}), true, false).is_discarded());
1691c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b}), true, false).is_discarded());
1692c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00}), true, false).is_discarded());
1693c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00}), true, false).is_discarded());
1694c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00}), true, false).is_discarded());
1695c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1696c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1697c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1698c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}), true, false).is_discarded());
1699c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x62}), true, false).is_discarded());
1700c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x62, 0x60}), true, false).is_discarded());
1701c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x7F}), true, false).is_discarded());
1702c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60}), true, false).is_discarded());
1703c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x82, 0x01}), true, false).is_discarded());
1704c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01}), true, false).is_discarded());
1705c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5}), true, false).is_discarded());
1706c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61}), true, false).is_discarded());
1707c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61}), true, false).is_discarded());
1708c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x5F}), true, false).is_discarded());
1709c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x5F, 0x00}), true, false).is_discarded());
1710c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0x41}), true, false).is_discarded());
1711c5f01b2fSopenharmony_ci        }
1712c5f01b2fSopenharmony_ci
1713c5f01b2fSopenharmony_ci        SECTION("unsupported bytes")
1714c5f01b2fSopenharmony_ci        {
1715c5f01b2fSopenharmony_ci            SECTION("concrete examples")
1716c5f01b2fSopenharmony_ci            {
1717c5f01b2fSopenharmony_ci                json _;
1718c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0x1c})), "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C", json::parse_error&);
1719c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded());
1720c5f01b2fSopenharmony_ci
1721c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xf8})), "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xF8", json::parse_error&);
1722c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded());
1723c5f01b2fSopenharmony_ci            }
1724c5f01b2fSopenharmony_ci
1725c5f01b2fSopenharmony_ci            SECTION("all unsupported bytes")
1726c5f01b2fSopenharmony_ci            {
1727c5f01b2fSopenharmony_ci                for (auto byte :
1728c5f01b2fSopenharmony_ci                        {
1729c5f01b2fSopenharmony_ci                            // ?
1730c5f01b2fSopenharmony_ci                            0x1c, 0x1d, 0x1e, 0x1f,
1731c5f01b2fSopenharmony_ci                            // ?
1732c5f01b2fSopenharmony_ci                            0x3c, 0x3d, 0x3e, 0x3f,
1733c5f01b2fSopenharmony_ci                            // ?
1734c5f01b2fSopenharmony_ci                            0x5c, 0x5d, 0x5e,
1735c5f01b2fSopenharmony_ci                            // ?
1736c5f01b2fSopenharmony_ci                            0x7c, 0x7d, 0x7e,
1737c5f01b2fSopenharmony_ci                            // ?
1738c5f01b2fSopenharmony_ci                            0x9c, 0x9d, 0x9e,
1739c5f01b2fSopenharmony_ci                            // ?
1740c5f01b2fSopenharmony_ci                            0xbc, 0xbd, 0xbe,
1741c5f01b2fSopenharmony_ci                            // date/time
1742c5f01b2fSopenharmony_ci                            0xc0, 0xc1,
1743c5f01b2fSopenharmony_ci                            // bignum
1744c5f01b2fSopenharmony_ci                            0xc2, 0xc3,
1745c5f01b2fSopenharmony_ci                            // fraction
1746c5f01b2fSopenharmony_ci                            0xc4,
1747c5f01b2fSopenharmony_ci                            // bigfloat
1748c5f01b2fSopenharmony_ci                            0xc5,
1749c5f01b2fSopenharmony_ci                            // tagged item
1750c5f01b2fSopenharmony_ci                            0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
1751c5f01b2fSopenharmony_ci                            // expected conversion
1752c5f01b2fSopenharmony_ci                            0xd5, 0xd6, 0xd7,
1753c5f01b2fSopenharmony_ci                            // more tagged items
1754c5f01b2fSopenharmony_ci                            0xd8, 0xd9, 0xda, 0xdb,
1755c5f01b2fSopenharmony_ci                            // ?
1756c5f01b2fSopenharmony_ci                            0xdc, 0xdd, 0xde, 0xdf,
1757c5f01b2fSopenharmony_ci                            // (simple value)
1758c5f01b2fSopenharmony_ci                            0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
1759c5f01b2fSopenharmony_ci                            // undefined
1760c5f01b2fSopenharmony_ci                            0xf7,
1761c5f01b2fSopenharmony_ci                            // simple value
1762c5f01b2fSopenharmony_ci                            0xf8
1763c5f01b2fSopenharmony_ci                        })
1764c5f01b2fSopenharmony_ci                {
1765c5f01b2fSopenharmony_ci                    json _;
1766c5f01b2fSopenharmony_ci                    CHECK_THROWS_AS(_ = json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error&);
1767c5f01b2fSopenharmony_ci                    CHECK(json::from_cbor(std::vector<uint8_t>({static_cast<uint8_t>(byte)}), true, false).is_discarded());
1768c5f01b2fSopenharmony_ci                }
1769c5f01b2fSopenharmony_ci            }
1770c5f01b2fSopenharmony_ci        }
1771c5f01b2fSopenharmony_ci
1772c5f01b2fSopenharmony_ci        SECTION("invalid string in map")
1773c5f01b2fSopenharmony_ci        {
1774c5f01b2fSopenharmony_ci            json _;
1775c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(_ = json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF", json::parse_error&);
1776c5f01b2fSopenharmony_ci            CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded());
1777c5f01b2fSopenharmony_ci        }
1778c5f01b2fSopenharmony_ci
1779c5f01b2fSopenharmony_ci        SECTION("strict mode")
1780c5f01b2fSopenharmony_ci        {
1781c5f01b2fSopenharmony_ci            std::vector<uint8_t> vec = {0xf6, 0xf6};
1782c5f01b2fSopenharmony_ci            SECTION("non-strict mode")
1783c5f01b2fSopenharmony_ci            {
1784c5f01b2fSopenharmony_ci                const auto result = json::from_cbor(vec, false);
1785c5f01b2fSopenharmony_ci                CHECK(result == json());
1786c5f01b2fSopenharmony_ci                CHECK(!json::from_cbor(vec, false, false).is_discarded());
1787c5f01b2fSopenharmony_ci            }
1788c5f01b2fSopenharmony_ci
1789c5f01b2fSopenharmony_ci            SECTION("strict mode")
1790c5f01b2fSopenharmony_ci            {
1791c5f01b2fSopenharmony_ci                json _;
1792c5f01b2fSopenharmony_ci                CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: expected end of input; last byte: 0xF6", json::parse_error&);
1793c5f01b2fSopenharmony_ci                CHECK(json::from_cbor(vec, true, false).is_discarded());
1794c5f01b2fSopenharmony_ci            }
1795c5f01b2fSopenharmony_ci        }
1796c5f01b2fSopenharmony_ci    }
1797c5f01b2fSopenharmony_ci
1798c5f01b2fSopenharmony_ci    SECTION("SAX aborts")
1799c5f01b2fSopenharmony_ci    {
1800c5f01b2fSopenharmony_ci        SECTION("start_array(len)")
1801c5f01b2fSopenharmony_ci        {
1802c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {0x83, 0x01, 0x02, 0x03};
1803c5f01b2fSopenharmony_ci            SaxCountdown scp(0);
1804c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));
1805c5f01b2fSopenharmony_ci        }
1806c5f01b2fSopenharmony_ci
1807c5f01b2fSopenharmony_ci        SECTION("start_object(len)")
1808c5f01b2fSopenharmony_ci        {
1809c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0xF4};
1810c5f01b2fSopenharmony_ci            SaxCountdown scp(0);
1811c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));
1812c5f01b2fSopenharmony_ci        }
1813c5f01b2fSopenharmony_ci
1814c5f01b2fSopenharmony_ci        SECTION("key()")
1815c5f01b2fSopenharmony_ci        {
1816c5f01b2fSopenharmony_ci            std::vector<uint8_t> v = {0xA1, 0x63, 0x66, 0x6F, 0x6F, 0xF4};
1817c5f01b2fSopenharmony_ci            SaxCountdown scp(1);
1818c5f01b2fSopenharmony_ci            CHECK(!json::sax_parse(v, &scp, json::input_format_t::cbor));
1819c5f01b2fSopenharmony_ci        }
1820c5f01b2fSopenharmony_ci    }
1821c5f01b2fSopenharmony_ci}
1822c5f01b2fSopenharmony_ci
1823c5f01b2fSopenharmony_ci// use this testcase outside [hide] to run it with Valgrind
1824c5f01b2fSopenharmony_ciTEST_CASE("single CBOR roundtrip")
1825c5f01b2fSopenharmony_ci{
1826c5f01b2fSopenharmony_ci    SECTION("sample.json")
1827c5f01b2fSopenharmony_ci    {
1828c5f01b2fSopenharmony_ci        std::string filename = TEST_DATA_DIRECTORY "/json_testsuite/sample.json";
1829c5f01b2fSopenharmony_ci
1830c5f01b2fSopenharmony_ci        // parse JSON file
1831c5f01b2fSopenharmony_ci        std::ifstream f_json(filename);
1832c5f01b2fSopenharmony_ci        json j1 = json::parse(f_json);
1833c5f01b2fSopenharmony_ci
1834c5f01b2fSopenharmony_ci        // parse CBOR file
1835c5f01b2fSopenharmony_ci        auto packed = utils::read_binary_file(filename + ".cbor");
1836c5f01b2fSopenharmony_ci        json j2;
1837c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j2 = json::from_cbor(packed));
1838c5f01b2fSopenharmony_ci
1839c5f01b2fSopenharmony_ci        // compare parsed JSON values
1840c5f01b2fSopenharmony_ci        CHECK(j1 == j2);
1841c5f01b2fSopenharmony_ci
1842c5f01b2fSopenharmony_ci        SECTION("roundtrips")
1843c5f01b2fSopenharmony_ci        {
1844c5f01b2fSopenharmony_ci            SECTION("std::ostringstream")
1845c5f01b2fSopenharmony_ci            {
1846c5f01b2fSopenharmony_ci                std::basic_ostringstream<std::uint8_t> ss;
1847c5f01b2fSopenharmony_ci                json::to_cbor(j1, ss);
1848c5f01b2fSopenharmony_ci                json j3 = json::from_cbor(ss.str());
1849c5f01b2fSopenharmony_ci                CHECK(j1 == j3);
1850c5f01b2fSopenharmony_ci            }
1851c5f01b2fSopenharmony_ci
1852c5f01b2fSopenharmony_ci            SECTION("std::string")
1853c5f01b2fSopenharmony_ci            {
1854c5f01b2fSopenharmony_ci                std::string s;
1855c5f01b2fSopenharmony_ci                json::to_cbor(j1, s);
1856c5f01b2fSopenharmony_ci                json j3 = json::from_cbor(s);
1857c5f01b2fSopenharmony_ci                CHECK(j1 == j3);
1858c5f01b2fSopenharmony_ci            }
1859c5f01b2fSopenharmony_ci        }
1860c5f01b2fSopenharmony_ci
1861c5f01b2fSopenharmony_ci        // check with different start index
1862c5f01b2fSopenharmony_ci        packed.insert(packed.begin(), 5, 0xff);
1863c5f01b2fSopenharmony_ci        CHECK(j1 == json::from_cbor(packed.begin() + 5, packed.end()));
1864c5f01b2fSopenharmony_ci    }
1865c5f01b2fSopenharmony_ci}
1866c5f01b2fSopenharmony_ci
1867c5f01b2fSopenharmony_ci#if !defined(JSON_NOEXCEPTION)
1868c5f01b2fSopenharmony_ciTEST_CASE("CBOR regressions")
1869c5f01b2fSopenharmony_ci{
1870c5f01b2fSopenharmony_ci    SECTION("fuzz test results")
1871c5f01b2fSopenharmony_ci    {
1872c5f01b2fSopenharmony_ci        /*
1873c5f01b2fSopenharmony_ci        The following test cases were found during a two-day session with
1874c5f01b2fSopenharmony_ci        AFL-Fuzz. As a result, empty byte vectors and excessive lengths are
1875c5f01b2fSopenharmony_ci        detected.
1876c5f01b2fSopenharmony_ci        */
1877c5f01b2fSopenharmony_ci        for (std::string filename :
1878c5f01b2fSopenharmony_ci                {
1879c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test01",
1880c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test02",
1881c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test03",
1882c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test04",
1883c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test05",
1884c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test06",
1885c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test07",
1886c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test08",
1887c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test09",
1888c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test10",
1889c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test11",
1890c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test12",
1891c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test13",
1892c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test14",
1893c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test15",
1894c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test16",
1895c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test17",
1896c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test18",
1897c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test19",
1898c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test20",
1899c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/cbor_regression/test21"
1900c5f01b2fSopenharmony_ci                })
1901c5f01b2fSopenharmony_ci        {
1902c5f01b2fSopenharmony_ci            CAPTURE(filename)
1903c5f01b2fSopenharmony_ci
1904c5f01b2fSopenharmony_ci            try
1905c5f01b2fSopenharmony_ci            {
1906c5f01b2fSopenharmony_ci                // parse CBOR file
1907c5f01b2fSopenharmony_ci                auto vec1 = utils::read_binary_file(filename);
1908c5f01b2fSopenharmony_ci                json j1 = json::from_cbor(vec1);
1909c5f01b2fSopenharmony_ci
1910c5f01b2fSopenharmony_ci                try
1911c5f01b2fSopenharmony_ci                {
1912c5f01b2fSopenharmony_ci                    // step 2: round trip
1913c5f01b2fSopenharmony_ci                    std::vector<uint8_t> vec2 = json::to_cbor(j1);
1914c5f01b2fSopenharmony_ci
1915c5f01b2fSopenharmony_ci                    // parse serialization
1916c5f01b2fSopenharmony_ci                    json j2 = json::from_cbor(vec2);
1917c5f01b2fSopenharmony_ci
1918c5f01b2fSopenharmony_ci                    // deserializations must match
1919c5f01b2fSopenharmony_ci                    CHECK(j1 == j2);
1920c5f01b2fSopenharmony_ci                }
1921c5f01b2fSopenharmony_ci                catch (const json::parse_error&)
1922c5f01b2fSopenharmony_ci                {
1923c5f01b2fSopenharmony_ci                    // parsing a CBOR serialization must not fail
1924c5f01b2fSopenharmony_ci                    CHECK(false);
1925c5f01b2fSopenharmony_ci                }
1926c5f01b2fSopenharmony_ci            }
1927c5f01b2fSopenharmony_ci            catch (const json::parse_error&)
1928c5f01b2fSopenharmony_ci            {
1929c5f01b2fSopenharmony_ci                // parse errors are ok, because input may be random bytes
1930c5f01b2fSopenharmony_ci            }
1931c5f01b2fSopenharmony_ci        }
1932c5f01b2fSopenharmony_ci    }
1933c5f01b2fSopenharmony_ci}
1934c5f01b2fSopenharmony_ci#endif
1935c5f01b2fSopenharmony_ci
1936c5f01b2fSopenharmony_ciTEST_CASE("CBOR roundtrips" * doctest::skip())
1937c5f01b2fSopenharmony_ci{
1938c5f01b2fSopenharmony_ci    SECTION("input from flynn")
1939c5f01b2fSopenharmony_ci    {
1940c5f01b2fSopenharmony_ci        // most of these are excluded due to differences in key order (not a real problem)
1941c5f01b2fSopenharmony_ci        std::set<std::string> exclude_packed;
1942c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/1.json");
1943c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/2.json");
1944c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/3.json");
1945c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/4.json");
1946c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json.org/5.json");
1947c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json_testsuite/sample.json"); // kills AppVeyor
1948c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/json_tests/pass1.json");
1949c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/regression/working_file.json");
1950c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json");
1951c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key.json");
1952c5f01b2fSopenharmony_ci        exclude_packed.insert(TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_long_strings.json");
1953c5f01b2fSopenharmony_ci
1954c5f01b2fSopenharmony_ci        for (std::string filename :
1955c5f01b2fSopenharmony_ci                {
1956c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json",
1957c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/1.json",
1958c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/2.json",
1959c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/3.json",
1960c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/4.json",
1961c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json.org/5.json",
1962c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip01.json",
1963c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip02.json",
1964c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip03.json",
1965c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip04.json",
1966c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip05.json",
1967c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip06.json",
1968c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip07.json",
1969c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip08.json",
1970c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip09.json",
1971c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip10.json",
1972c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip11.json",
1973c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip12.json",
1974c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip13.json",
1975c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip14.json",
1976c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip15.json",
1977c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip16.json",
1978c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip17.json",
1979c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip18.json",
1980c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip19.json",
1981c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip20.json",
1982c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip21.json",
1983c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip22.json",
1984c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip23.json",
1985c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip24.json",
1986c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip25.json",
1987c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip26.json",
1988c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip27.json",
1989c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip28.json",
1990c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip29.json",
1991c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip30.json",
1992c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip31.json",
1993c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_roundtrip/roundtrip32.json",
1994c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_testsuite/sample.json", // kills AppVeyor
1995c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_tests/pass1.json",
1996c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_tests/pass2.json",
1997c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/json_tests/pass3.json",
1998c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/floats.json",
1999c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/signed_ints.json",
2000c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
2001c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/working_file.json",
2002c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_arraysWithSpaces.json",
2003c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty-string.json",
2004c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty.json",
2005c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_ending_with_newline.json",
2006c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_false.json",
2007c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_heterogeneous.json",
2008c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_null.json",
2009c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_1_and_newline.json",
2010c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_leading_space.json",
2011c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_several_null.json",
2012c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_with_trailing_space.json",
2013c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number.json",
2014c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e+1.json",
2015c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_0e1.json",
2016c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_after_space.json",
2017c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
2018c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
2019c5f01b2fSopenharmony_ci                    //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
2020c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
2021c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
2022c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_int.json",
2023c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_one.json",
2024c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_negative_zero.json",
2025c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e.json",
2026c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_neg_exp.json",
2027c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_capital_e_pos_exp.json",
2028c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
2029c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
2030c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
2031c5f01b2fSopenharmony_ci                    //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
2032c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
2033c5f01b2fSopenharmony_ci                    //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
2034c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
2035c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_int.json",
2036c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_simple_real.json",
2037c5f01b2fSopenharmony_ci                    //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_neg_int.json",
2038c5f01b2fSopenharmony_ci                    //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_too_big_pos_int.json",
2039c5f01b2fSopenharmony_ci                    //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_number_very_big_negative_int.json",
2040c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object.json",
2041c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_basic.json",
2042c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key.json",
2043c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_duplicated_key_and_value.json",
2044c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty.json",
2045c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_empty_key.json",
2046c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_escaped_null_in_key.json",
2047c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_extreme_numbers.json",
2048c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_long_strings.json",
2049c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_simple.json",
2050c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_string_unicode.json",
2051c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_object_with_newlines.json",
2052c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json",
2053c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_UTF-16_Surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json",
2054c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pair.json",
2055c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_accepted_surrogate_pairs.json",
2056c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_allowed_escapes.json",
2057c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_and_u_escaped_zero.json",
2058c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_backslash_doublequotes.json",
2059c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_comments.json",
2060c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_a.json",
2061c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_double_escape_n.json",
2062c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_control_character.json",
2063c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_escaped_noncharacter.json",
2064c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array.json",
2065c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_in_array_with_leading_space.json",
2066c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_last_surrogates_1_and_2.json",
2067c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_newline_uescaped.json",
2068c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json",
2069c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json",
2070c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json",
2071c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_null_escape.json",
2072c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_one-byte-utf-8.json",
2073c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_pi.json",
2074c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_simple_ascii.json",
2075c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_space.json",
2076c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_three-byte-utf-8.json",
2077c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_two-byte-utf-8.json",
2078c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2028_line_sep.json",
2079c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_u+2029_par_sep.json",
2080c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_uEscape.json",
2081c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unescaped_char_delete.json",
2082c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode.json",
2083c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicodeEscapedBackslash.json",
2084c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_2.json",
2085c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json",
2086c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json",
2087c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_unicode_escaped_double_quote.json",
2088c5f01b2fSopenharmony_ci                    // TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf16.json",
2089c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_utf8.json",
2090c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_string_with_del_character.json",
2091c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_false.json",
2092c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_int.json",
2093c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_negative_real.json",
2094c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_null.json",
2095c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_string.json",
2096c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_true.json",
2097c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_string_empty.json",
2098c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_trailing_newline.json",
2099c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_true_in_array.json",
2100c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_whitespace_array.json"
2101c5f01b2fSopenharmony_ci                })
2102c5f01b2fSopenharmony_ci        {
2103c5f01b2fSopenharmony_ci            CAPTURE(filename)
2104c5f01b2fSopenharmony_ci
2105c5f01b2fSopenharmony_ci            {
2106c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": std::vector<uint8_t>");
2107c5f01b2fSopenharmony_ci                // parse JSON file
2108c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2109c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2110c5f01b2fSopenharmony_ci
2111c5f01b2fSopenharmony_ci                // parse CBOR file
2112c5f01b2fSopenharmony_ci                auto packed = utils::read_binary_file(filename + ".cbor");
2113c5f01b2fSopenharmony_ci                json j2;
2114c5f01b2fSopenharmony_ci                CHECK_NOTHROW(j2 = json::from_cbor(packed));
2115c5f01b2fSopenharmony_ci
2116c5f01b2fSopenharmony_ci                // compare parsed JSON values
2117c5f01b2fSopenharmony_ci                CHECK(j1 == j2);
2118c5f01b2fSopenharmony_ci            }
2119c5f01b2fSopenharmony_ci
2120c5f01b2fSopenharmony_ci            {
2121c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": std::ifstream");
2122c5f01b2fSopenharmony_ci                // parse JSON file
2123c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2124c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2125c5f01b2fSopenharmony_ci
2126c5f01b2fSopenharmony_ci                // parse CBOR file
2127c5f01b2fSopenharmony_ci                std::ifstream f_cbor(filename + ".cbor", std::ios::binary);
2128c5f01b2fSopenharmony_ci                json j2;
2129c5f01b2fSopenharmony_ci                CHECK_NOTHROW(j2 = json::from_cbor(f_cbor));
2130c5f01b2fSopenharmony_ci
2131c5f01b2fSopenharmony_ci                // compare parsed JSON values
2132c5f01b2fSopenharmony_ci                CHECK(j1 == j2);
2133c5f01b2fSopenharmony_ci            }
2134c5f01b2fSopenharmony_ci
2135c5f01b2fSopenharmony_ci            {
2136c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": uint8_t* and size");
2137c5f01b2fSopenharmony_ci                // parse JSON file
2138c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2139c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2140c5f01b2fSopenharmony_ci
2141c5f01b2fSopenharmony_ci                // parse CBOR file
2142c5f01b2fSopenharmony_ci                auto packed = utils::read_binary_file(filename + ".cbor");
2143c5f01b2fSopenharmony_ci                json j2;
2144c5f01b2fSopenharmony_ci                CHECK_NOTHROW(j2 = json::from_cbor({packed.data(), packed.size()}));
2145c5f01b2fSopenharmony_ci
2146c5f01b2fSopenharmony_ci                // compare parsed JSON values
2147c5f01b2fSopenharmony_ci                CHECK(j1 == j2);
2148c5f01b2fSopenharmony_ci            }
2149c5f01b2fSopenharmony_ci
2150c5f01b2fSopenharmony_ci            {
2151c5f01b2fSopenharmony_ci                INFO_WITH_TEMP(filename + ": output to output adapters");
2152c5f01b2fSopenharmony_ci                // parse JSON file
2153c5f01b2fSopenharmony_ci                std::ifstream f_json(filename);
2154c5f01b2fSopenharmony_ci                json j1 = json::parse(f_json);
2155c5f01b2fSopenharmony_ci
2156c5f01b2fSopenharmony_ci                // parse CBOR file
2157c5f01b2fSopenharmony_ci                auto packed = utils::read_binary_file(filename + ".cbor");
2158c5f01b2fSopenharmony_ci
2159c5f01b2fSopenharmony_ci                if (exclude_packed.count(filename) == 0u)
2160c5f01b2fSopenharmony_ci                {
2161c5f01b2fSopenharmony_ci                    {
2162c5f01b2fSopenharmony_ci                        INFO_WITH_TEMP(filename + ": output adapters: std::vector<uint8_t>");
2163c5f01b2fSopenharmony_ci                        std::vector<uint8_t> vec;
2164c5f01b2fSopenharmony_ci                        json::to_cbor(j1, vec);
2165c5f01b2fSopenharmony_ci                        CHECK(vec == packed);
2166c5f01b2fSopenharmony_ci                    }
2167c5f01b2fSopenharmony_ci                }
2168c5f01b2fSopenharmony_ci            }
2169c5f01b2fSopenharmony_ci        }
2170c5f01b2fSopenharmony_ci    }
2171c5f01b2fSopenharmony_ci}
2172c5f01b2fSopenharmony_ci
2173c5f01b2fSopenharmony_ci#if !defined(JSON_NOEXCEPTION)
2174c5f01b2fSopenharmony_ciTEST_CASE("all CBOR first bytes")
2175c5f01b2fSopenharmony_ci{
2176c5f01b2fSopenharmony_ci    // these bytes will fail immediately with exception parse_error.112
2177c5f01b2fSopenharmony_ci    std::set<uint8_t> unsupported =
2178c5f01b2fSopenharmony_ci    {
2179c5f01b2fSopenharmony_ci        //// types not supported by this library
2180c5f01b2fSopenharmony_ci
2181c5f01b2fSopenharmony_ci        // date/time
2182c5f01b2fSopenharmony_ci        0xc0, 0xc1,
2183c5f01b2fSopenharmony_ci        // bignum
2184c5f01b2fSopenharmony_ci        0xc2, 0xc3,
2185c5f01b2fSopenharmony_ci        // decimal fracion
2186c5f01b2fSopenharmony_ci        0xc4,
2187c5f01b2fSopenharmony_ci        // bigfloat
2188c5f01b2fSopenharmony_ci        0xc5,
2189c5f01b2fSopenharmony_ci        // tagged item
2190c5f01b2fSopenharmony_ci        0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
2191c5f01b2fSopenharmony_ci        0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd8,
2192c5f01b2fSopenharmony_ci        0xd9, 0xda, 0xdb,
2193c5f01b2fSopenharmony_ci        // expected conversion
2194c5f01b2fSopenharmony_ci        0xd5, 0xd6, 0xd7,
2195c5f01b2fSopenharmony_ci        // simple value
2196c5f01b2fSopenharmony_ci        0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
2197c5f01b2fSopenharmony_ci        0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xef, 0xf0,
2198c5f01b2fSopenharmony_ci        0xf1, 0xf2, 0xf3,
2199c5f01b2fSopenharmony_ci        0xf8,
2200c5f01b2fSopenharmony_ci        // undefined
2201c5f01b2fSopenharmony_ci        0xf7,
2202c5f01b2fSopenharmony_ci
2203c5f01b2fSopenharmony_ci        //// bytes not specified by CBOR
2204c5f01b2fSopenharmony_ci
2205c5f01b2fSopenharmony_ci        0x1c, 0x1d, 0x1e, 0x1f,
2206c5f01b2fSopenharmony_ci        0x3c, 0x3d, 0x3e, 0x3f,
2207c5f01b2fSopenharmony_ci        0x5c, 0x5d, 0x5e,
2208c5f01b2fSopenharmony_ci        0x7c, 0x7d, 0x7e,
2209c5f01b2fSopenharmony_ci        0x9c, 0x9d, 0x9e,
2210c5f01b2fSopenharmony_ci        0xbc, 0xbd, 0xbe,
2211c5f01b2fSopenharmony_ci        0xdc, 0xdd, 0xde, 0xdf,
2212c5f01b2fSopenharmony_ci        0xee,
2213c5f01b2fSopenharmony_ci        0xfc, 0xfe, 0xfd,
2214c5f01b2fSopenharmony_ci
2215c5f01b2fSopenharmony_ci        /// break cannot be the first byte
2216c5f01b2fSopenharmony_ci
2217c5f01b2fSopenharmony_ci        0xff
2218c5f01b2fSopenharmony_ci    };
2219c5f01b2fSopenharmony_ci
2220c5f01b2fSopenharmony_ci    for (auto i = 0; i < 256; ++i)
2221c5f01b2fSopenharmony_ci    {
2222c5f01b2fSopenharmony_ci        const auto byte = static_cast<uint8_t>(i);
2223c5f01b2fSopenharmony_ci
2224c5f01b2fSopenharmony_ci        try
2225c5f01b2fSopenharmony_ci        {
2226c5f01b2fSopenharmony_ci            auto res = json::from_cbor(std::vector<uint8_t>(1, byte));
2227c5f01b2fSopenharmony_ci        }
2228c5f01b2fSopenharmony_ci        catch (const json::parse_error& e)
2229c5f01b2fSopenharmony_ci        {
2230c5f01b2fSopenharmony_ci            // check that parse_error.112 is only thrown if the
2231c5f01b2fSopenharmony_ci            // first byte is in the unsupported set
2232c5f01b2fSopenharmony_ci            INFO_WITH_TEMP(e.what());
2233c5f01b2fSopenharmony_ci            if (unsupported.find(byte) != unsupported.end())
2234c5f01b2fSopenharmony_ci            {
2235c5f01b2fSopenharmony_ci                CHECK(e.id == 112);
2236c5f01b2fSopenharmony_ci            }
2237c5f01b2fSopenharmony_ci            else
2238c5f01b2fSopenharmony_ci            {
2239c5f01b2fSopenharmony_ci                CHECK(e.id != 112);
2240c5f01b2fSopenharmony_ci            }
2241c5f01b2fSopenharmony_ci        }
2242c5f01b2fSopenharmony_ci    }
2243c5f01b2fSopenharmony_ci}
2244c5f01b2fSopenharmony_ci#endif
2245c5f01b2fSopenharmony_ci
2246c5f01b2fSopenharmony_ciTEST_CASE("examples from RFC 7049 Appendix A")
2247c5f01b2fSopenharmony_ci{
2248c5f01b2fSopenharmony_ci    SECTION("numbers")
2249c5f01b2fSopenharmony_ci    {
2250c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("0")) == std::vector<uint8_t>({0x00}));
2251c5f01b2fSopenharmony_ci        CHECK(json::parse("0") == json::from_cbor(std::vector<uint8_t>({0x00})));
2252c5f01b2fSopenharmony_ci
2253c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("1")) == std::vector<uint8_t>({0x01}));
2254c5f01b2fSopenharmony_ci        CHECK(json::parse("1") == json::from_cbor(std::vector<uint8_t>({0x01})));
2255c5f01b2fSopenharmony_ci
2256c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("10")) == std::vector<uint8_t>({0x0a}));
2257c5f01b2fSopenharmony_ci        CHECK(json::parse("10") == json::from_cbor(std::vector<uint8_t>({0x0a})));
2258c5f01b2fSopenharmony_ci
2259c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("23")) == std::vector<uint8_t>({0x17}));
2260c5f01b2fSopenharmony_ci        CHECK(json::parse("23") == json::from_cbor(std::vector<uint8_t>({0x17})));
2261c5f01b2fSopenharmony_ci
2262c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("24")) == std::vector<uint8_t>({0x18, 0x18}));
2263c5f01b2fSopenharmony_ci        CHECK(json::parse("24") == json::from_cbor(std::vector<uint8_t>({0x18, 0x18})));
2264c5f01b2fSopenharmony_ci
2265c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("25")) == std::vector<uint8_t>({0x18, 0x19}));
2266c5f01b2fSopenharmony_ci        CHECK(json::parse("25") == json::from_cbor(std::vector<uint8_t>({0x18, 0x19})));
2267c5f01b2fSopenharmony_ci
2268c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("100")) == std::vector<uint8_t>({0x18, 0x64}));
2269c5f01b2fSopenharmony_ci        CHECK(json::parse("100") == json::from_cbor(std::vector<uint8_t>({0x18, 0x64})));
2270c5f01b2fSopenharmony_ci
2271c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("1000")) == std::vector<uint8_t>({0x19, 0x03, 0xe8}));
2272c5f01b2fSopenharmony_ci        CHECK(json::parse("1000") == json::from_cbor(std::vector<uint8_t>({0x19, 0x03, 0xe8})));
2273c5f01b2fSopenharmony_ci
2274c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("1000000")) == std::vector<uint8_t>({0x1a, 0x00, 0x0f, 0x42, 0x40}));
2275c5f01b2fSopenharmony_ci        CHECK(json::parse("1000000") == json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x0f, 0x42, 0x40})));
2276c5f01b2fSopenharmony_ci
2277c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("1000000000000")) == std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00}));
2278c5f01b2fSopenharmony_ci        CHECK(json::parse("1000000000000") == json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00})));
2279c5f01b2fSopenharmony_ci
2280c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("18446744073709551615")) == std::vector<uint8_t>({0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}));
2281c5f01b2fSopenharmony_ci        CHECK(json::parse("18446744073709551615") == json::from_cbor(std::vector<uint8_t>({0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})));
2282c5f01b2fSopenharmony_ci
2283c5f01b2fSopenharmony_ci        // positive bignum is not supported
2284c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("18446744073709551616")) == std::vector<uint8_t>({0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
2285c5f01b2fSopenharmony_ci        //CHECK(json::parse("18446744073709551616") == json::from_cbor(std::vector<uint8_t>({0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})));
2286c5f01b2fSopenharmony_ci
2287c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("-18446744073709551616")) == std::vector<uint8_t>({0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}));
2288c5f01b2fSopenharmony_ci        //CHECK(json::parse("-18446744073709551616") == json::from_cbor(std::vector<uint8_t>({0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})));
2289c5f01b2fSopenharmony_ci
2290c5f01b2fSopenharmony_ci        // negative bignum is not supported
2291c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("-18446744073709551617")) == std::vector<uint8_t>({0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
2292c5f01b2fSopenharmony_ci        //CHECK(json::parse("-18446744073709551617") == json::from_cbor(std::vector<uint8_t>({0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})));
2293c5f01b2fSopenharmony_ci
2294c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("-1")) == std::vector<uint8_t>({0x20}));
2295c5f01b2fSopenharmony_ci        CHECK(json::parse("-1") == json::from_cbor(std::vector<uint8_t>({0x20})));
2296c5f01b2fSopenharmony_ci
2297c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("-10")) == std::vector<uint8_t>({0x29}));
2298c5f01b2fSopenharmony_ci        CHECK(json::parse("-10") == json::from_cbor(std::vector<uint8_t>({0x29})));
2299c5f01b2fSopenharmony_ci
2300c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("-100")) == std::vector<uint8_t>({0x38, 0x63}));
2301c5f01b2fSopenharmony_ci        CHECK(json::parse("-100") == json::from_cbor(std::vector<uint8_t>({0x38, 0x63})));
2302c5f01b2fSopenharmony_ci
2303c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("-1000")) == std::vector<uint8_t>({0x39, 0x03, 0xe7}));
2304c5f01b2fSopenharmony_ci        CHECK(json::parse("-1000") == json::from_cbor(std::vector<uint8_t>({0x39, 0x03, 0xe7})));
2305c5f01b2fSopenharmony_ci
2306c5f01b2fSopenharmony_ci        // half-precision float
2307c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("0.0")) == std::vector<uint8_t>({0xf9, 0x00, 0x00}));
2308c5f01b2fSopenharmony_ci        CHECK(json::parse("0.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x00, 0x00})));
2309c5f01b2fSopenharmony_ci
2310c5f01b2fSopenharmony_ci        // half-precision float
2311c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("-0.0")) == std::vector<uint8_t>({0xf9, 0x80, 0x00}));
2312c5f01b2fSopenharmony_ci        CHECK(json::parse("-0.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x80, 0x00})));
2313c5f01b2fSopenharmony_ci
2314c5f01b2fSopenharmony_ci        // half-precision float
2315c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("1.0")) == std::vector<uint8_t>({0xf9, 0x3c, 0x00}));
2316c5f01b2fSopenharmony_ci        CHECK(json::parse("1.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3c, 0x00})));
2317c5f01b2fSopenharmony_ci
2318c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("1.1")) == std::vector<uint8_t>({0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a}));
2319c5f01b2fSopenharmony_ci        CHECK(json::parse("1.1") == json::from_cbor(std::vector<uint8_t>({0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a})));
2320c5f01b2fSopenharmony_ci
2321c5f01b2fSopenharmony_ci        // half-precision float
2322c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("1.5")) == std::vector<uint8_t>({0xf9, 0x3e, 0x00}));
2323c5f01b2fSopenharmony_ci        CHECK(json::parse("1.5") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x3e, 0x00})));
2324c5f01b2fSopenharmony_ci
2325c5f01b2fSopenharmony_ci        // half-precision float
2326c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("65504.0")) == std::vector<uint8_t>({0xf9, 0x7b, 0xff}));
2327c5f01b2fSopenharmony_ci        CHECK(json::parse("65504.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0x7b, 0xff})));
2328c5f01b2fSopenharmony_ci
2329c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("100000.0")) == std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00}));
2330c5f01b2fSopenharmony_ci        CHECK(json::parse("100000.0") == json::from_cbor(std::vector<uint8_t>({0xfa, 0x47, 0xc3, 0x50, 0x00})));
2331c5f01b2fSopenharmony_ci
2332c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("3.4028234663852886e+38")) == std::vector<uint8_t>({0xfa, 0x7f, 0x7f, 0xff, 0xff}));
2333c5f01b2fSopenharmony_ci        CHECK(json::parse("3.4028234663852886e+38") == json::from_cbor(std::vector<uint8_t>({0xfa, 0x7f, 0x7f, 0xff, 0xff})));
2334c5f01b2fSopenharmony_ci
2335c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("1.0e+300")) == std::vector<uint8_t>({0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c}));
2336c5f01b2fSopenharmony_ci        CHECK(json::parse("1.0e+300") == json::from_cbor(std::vector<uint8_t>({0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c})));
2337c5f01b2fSopenharmony_ci
2338c5f01b2fSopenharmony_ci        // half-precision float
2339c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("5.960464477539063e-8")) == std::vector<uint8_t>({0xf9, 0x00, 0x01}));
2340c5f01b2fSopenharmony_ci        CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
2341c5f01b2fSopenharmony_ci
2342c5f01b2fSopenharmony_ci        // half-precision float
2343c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("0.00006103515625")) == std::vector<uint8_t>({0xf9, 0x04, 0x00}));
2344c5f01b2fSopenharmony_ci        CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
2345c5f01b2fSopenharmony_ci
2346c5f01b2fSopenharmony_ci        // half-precision float
2347c5f01b2fSopenharmony_ci        //CHECK(json::to_cbor(json::parse("-4.0")) == std::vector<uint8_t>({0xf9, 0xc4, 0x00}));
2348c5f01b2fSopenharmony_ci        CHECK(json::parse("-4.0") == json::from_cbor(std::vector<uint8_t>({0xf9, 0xc4, 0x00})));
2349c5f01b2fSopenharmony_ci
2350c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("-4.1")) == std::vector<uint8_t>({0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}));
2351c5f01b2fSopenharmony_ci        CHECK(json::parse("-4.1") == json::from_cbor(std::vector<uint8_t>({0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})));
2352c5f01b2fSopenharmony_ci    }
2353c5f01b2fSopenharmony_ci
2354c5f01b2fSopenharmony_ci    SECTION("simple values")
2355c5f01b2fSopenharmony_ci    {
2356c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("false")) == std::vector<uint8_t>({0xf4}));
2357c5f01b2fSopenharmony_ci        CHECK(json::parse("false") == json::from_cbor(std::vector<uint8_t>({0xf4})));
2358c5f01b2fSopenharmony_ci
2359c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("true")) == std::vector<uint8_t>({0xf5}));
2360c5f01b2fSopenharmony_ci        CHECK(json::parse("true") == json::from_cbor(std::vector<uint8_t>({0xf5})));
2361c5f01b2fSopenharmony_ci
2362c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("true")) == std::vector<uint8_t>({0xf5}));
2363c5f01b2fSopenharmony_ci        CHECK(json::parse("true") == json::from_cbor(std::vector<uint8_t>({0xf5})));
2364c5f01b2fSopenharmony_ci    }
2365c5f01b2fSopenharmony_ci
2366c5f01b2fSopenharmony_ci    SECTION("strings")
2367c5f01b2fSopenharmony_ci    {
2368c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("\"\"")) == std::vector<uint8_t>({0x60}));
2369c5f01b2fSopenharmony_ci        CHECK(json::parse("\"\"") == json::from_cbor(std::vector<uint8_t>({0x60})));
2370c5f01b2fSopenharmony_ci
2371c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("\"a\"")) == std::vector<uint8_t>({0x61, 0x61}));
2372c5f01b2fSopenharmony_ci        CHECK(json::parse("\"a\"") == json::from_cbor(std::vector<uint8_t>({0x61, 0x61})));
2373c5f01b2fSopenharmony_ci
2374c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("\"IETF\"")) == std::vector<uint8_t>({0x64, 0x49, 0x45, 0x54, 0x46}));
2375c5f01b2fSopenharmony_ci        CHECK(json::parse("\"IETF\"") == json::from_cbor(std::vector<uint8_t>({0x64, 0x49, 0x45, 0x54, 0x46})));
2376c5f01b2fSopenharmony_ci
2377c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("\"\\u00fc\"")) == std::vector<uint8_t>({0x62, 0xc3, 0xbc}));
2378c5f01b2fSopenharmony_ci        CHECK(json::parse("\"\\u00fc\"") == json::from_cbor(std::vector<uint8_t>({0x62, 0xc3, 0xbc})));
2379c5f01b2fSopenharmony_ci
2380c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("\"\\u6c34\"")) == std::vector<uint8_t>({0x63, 0xe6, 0xb0, 0xb4}));
2381c5f01b2fSopenharmony_ci        CHECK(json::parse("\"\\u6c34\"") == json::from_cbor(std::vector<uint8_t>({0x63, 0xe6, 0xb0, 0xb4})));
2382c5f01b2fSopenharmony_ci
2383c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("\"\\ud800\\udd51\"")) == std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91}));
2384c5f01b2fSopenharmony_ci        CHECK(json::parse("\"\\ud800\\udd51\"") == json::from_cbor(std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91})));
2385c5f01b2fSopenharmony_ci
2386c5f01b2fSopenharmony_ci        // indefinite length strings
2387c5f01b2fSopenharmony_ci        CHECK(json::parse("\"streaming\"") == json::from_cbor(std::vector<uint8_t>({0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff})));
2388c5f01b2fSopenharmony_ci    }
2389c5f01b2fSopenharmony_ci
2390c5f01b2fSopenharmony_ci    SECTION("byte arrays")
2391c5f01b2fSopenharmony_ci    {
2392c5f01b2fSopenharmony_ci        auto packed = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.cbor");
2393c5f01b2fSopenharmony_ci        json j;
2394c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j = json::from_cbor(packed));
2395c5f01b2fSopenharmony_ci
2396c5f01b2fSopenharmony_ci        auto expected = utils::read_binary_file(TEST_DATA_DIRECTORY "/binary_data/cbor_binary.out");
2397c5f01b2fSopenharmony_ci        CHECK(j == json::binary(expected));
2398c5f01b2fSopenharmony_ci
2399c5f01b2fSopenharmony_ci        // 0xd8
2400c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)) == std::vector<uint8_t> {0xd8, 0x42, 0x40});
2401c5f01b2fSopenharmony_ci        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2402c5f01b2fSopenharmony_ci        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 0x42)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 0x42);
2403c5f01b2fSopenharmony_ci        // 0xd9
2404c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)) == std::vector<uint8_t> {0xd9, 0x03, 0xe8, 0x40});
2405c5f01b2fSopenharmony_ci        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2406c5f01b2fSopenharmony_ci        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 1000)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 1000);
2407c5f01b2fSopenharmony_ci        // 0xda
2408c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)) == std::vector<uint8_t> {0xda, 0x00, 0x06, 0x03, 0xe8, 0x40});
2409c5f01b2fSopenharmony_ci        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2410c5f01b2fSopenharmony_ci        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 394216)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 394216);
2411c5f01b2fSopenharmony_ci        // 0xdb
2412c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)) == std::vector<uint8_t> {0xdb, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x40});
2413c5f01b2fSopenharmony_ci        CHECK(!json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::ignore).get_binary().has_subtype());
2414c5f01b2fSopenharmony_ci        CHECK(json::from_cbor(json::to_cbor(json::binary(std::vector<uint8_t> {}, 8589934590)), true, true, json::cbor_tag_handler_t::store).get_binary().subtype() == 8589934590);
2415c5f01b2fSopenharmony_ci    }
2416c5f01b2fSopenharmony_ci
2417c5f01b2fSopenharmony_ci    SECTION("arrays")
2418c5f01b2fSopenharmony_ci    {
2419c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("[]")) == std::vector<uint8_t>({0x80}));
2420c5f01b2fSopenharmony_ci        CHECK(json::parse("[]") == json::from_cbor(std::vector<uint8_t>({0x80})));
2421c5f01b2fSopenharmony_ci
2422c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("[1, 2, 3]")) == std::vector<uint8_t>({0x83, 0x01, 0x02, 0x03}));
2423c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, 2, 3]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x02, 0x03})));
2424c5f01b2fSopenharmony_ci
2425c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("[1, [2, 3], [4, 5]]")) == std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05}));
2426c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05})));
2427c5f01b2fSopenharmony_ci
2428c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]")) == std::vector<uint8_t>({0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19}));
2429c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]") == json::from_cbor(std::vector<uint8_t>({0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19})));
2430c5f01b2fSopenharmony_ci
2431c5f01b2fSopenharmony_ci        // indefinite length arrays
2432c5f01b2fSopenharmony_ci        CHECK(json::parse("[]") == json::from_cbor(std::vector<uint8_t>({0x9f, 0xff})));
2433c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, [2, 3], [4, 5]] ") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x82, 0x02, 0x03, 0x9f, 0x04, 0x05, 0xff, 0xff})));
2434c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05, 0xff})));
2435c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x82, 0x02, 0x03, 0x9f, 0x04, 0x05, 0xff})));
2436c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, [2, 3], [4, 5]]") == json::from_cbor(std::vector<uint8_t>({0x83, 0x01, 0x9f, 0x02, 0x03, 0xff, 0x82, 0x04, 0x05})));
2437c5f01b2fSopenharmony_ci        CHECK(json::parse("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]") == json::from_cbor(std::vector<uint8_t>({0x9f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0xff})));
2438c5f01b2fSopenharmony_ci    }
2439c5f01b2fSopenharmony_ci
2440c5f01b2fSopenharmony_ci    SECTION("objects")
2441c5f01b2fSopenharmony_ci    {
2442c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("{}")) == std::vector<uint8_t>({0xa0}));
2443c5f01b2fSopenharmony_ci        CHECK(json::parse("{}") == json::from_cbor(std::vector<uint8_t>({0xa0})));
2444c5f01b2fSopenharmony_ci
2445c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("{\"a\": 1, \"b\": [2, 3]}")) == std::vector<uint8_t>({0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03}));
2446c5f01b2fSopenharmony_ci        CHECK(json::parse("{\"a\": 1, \"b\": [2, 3]}") == json::from_cbor(std::vector<uint8_t>({0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03})));
2447c5f01b2fSopenharmony_ci
2448c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("[\"a\", {\"b\": \"c\"}]")) == std::vector<uint8_t>({0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63}));
2449c5f01b2fSopenharmony_ci        CHECK(json::parse("[\"a\", {\"b\": \"c\"}]") == json::from_cbor(std::vector<uint8_t>({0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63})));
2450c5f01b2fSopenharmony_ci
2451c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(json::parse("{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\", \"d\": \"D\", \"e\": \"E\"}")) == std::vector<uint8_t>({0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45}));
2452c5f01b2fSopenharmony_ci        CHECK(json::parse("{\"a\": \"A\", \"b\": \"B\", \"c\": \"C\", \"d\": \"D\", \"e\": \"E\"}") == json::from_cbor(std::vector<uint8_t>({0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, 0x44, 0x61, 0x65, 0x61, 0x45})));
2453c5f01b2fSopenharmony_ci
2454c5f01b2fSopenharmony_ci        // indefinite length objects
2455c5f01b2fSopenharmony_ci        CHECK(json::parse("{\"a\": 1, \"b\": [2, 3]}") == json::from_cbor(std::vector<uint8_t>({0xbf, 0x61, 0x61, 0x01, 0x61, 0x62, 0x9f, 0x02, 0x03, 0xff, 0xff})));
2456c5f01b2fSopenharmony_ci        CHECK(json::parse("[\"a\", {\"b\": \"c\"}]") == json::from_cbor(std::vector<uint8_t>({0x82, 0x61, 0x61, 0xbf, 0x61, 0x62, 0x61, 0x63, 0xff})));
2457c5f01b2fSopenharmony_ci        CHECK(json::parse("{\"Fun\": true, \"Amt\": -2}") == json::from_cbor(std::vector<uint8_t>({0xbf, 0x63, 0x46, 0x75, 0x6e, 0xf5, 0x63, 0x41, 0x6d, 0x74, 0x21, 0xff})));
2458c5f01b2fSopenharmony_ci    }
2459c5f01b2fSopenharmony_ci}
2460c5f01b2fSopenharmony_ci
2461c5f01b2fSopenharmony_ciTEST_CASE("Tagged values")
2462c5f01b2fSopenharmony_ci{
2463c5f01b2fSopenharmony_ci    json j = "s";
2464c5f01b2fSopenharmony_ci    auto v = json::to_cbor(j);
2465c5f01b2fSopenharmony_ci
2466c5f01b2fSopenharmony_ci    SECTION("0xC6..0xD4")
2467c5f01b2fSopenharmony_ci    {
2468c5f01b2fSopenharmony_ci        for (auto b : std::vector<std::uint8_t>
2469c5f01b2fSopenharmony_ci    {
2470c5f01b2fSopenharmony_ci        0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4
2471c5f01b2fSopenharmony_ci    })
2472c5f01b2fSopenharmony_ci        {
2473c5f01b2fSopenharmony_ci            CAPTURE(b);
2474c5f01b2fSopenharmony_ci
2475c5f01b2fSopenharmony_ci            // add tag to value
2476c5f01b2fSopenharmony_ci            auto v_tagged = v;
2477c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), b);
2478c5f01b2fSopenharmony_ci
2479c5f01b2fSopenharmony_ci            // check that parsing fails in error mode
2480c5f01b2fSopenharmony_ci            json _;
2481c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2482c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2483c5f01b2fSopenharmony_ci
2484c5f01b2fSopenharmony_ci            // check that parsing succeeds and gets original value in ignore mode
2485c5f01b2fSopenharmony_ci            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2486c5f01b2fSopenharmony_ci            CHECK(j_tagged == j);
2487c5f01b2fSopenharmony_ci
2488c5f01b2fSopenharmony_ci            auto j_tagged_stored = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::store);
2489c5f01b2fSopenharmony_ci            CHECK(j_tagged_stored == j);
2490c5f01b2fSopenharmony_ci        }
2491c5f01b2fSopenharmony_ci    }
2492c5f01b2fSopenharmony_ci
2493c5f01b2fSopenharmony_ci    SECTION("0xD8 - 1 byte follows")
2494c5f01b2fSopenharmony_ci    {
2495c5f01b2fSopenharmony_ci        SECTION("success")
2496c5f01b2fSopenharmony_ci        {
2497c5f01b2fSopenharmony_ci            // add tag to value
2498c5f01b2fSopenharmony_ci            auto v_tagged = v;
2499c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2500c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xD8); // tag
2501c5f01b2fSopenharmony_ci
2502c5f01b2fSopenharmony_ci            // check that parsing fails in error mode
2503c5f01b2fSopenharmony_ci            json _;
2504c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2505c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2506c5f01b2fSopenharmony_ci
2507c5f01b2fSopenharmony_ci            // check that parsing succeeds and gets original value in ignore mode
2508c5f01b2fSopenharmony_ci            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2509c5f01b2fSopenharmony_ci            CHECK(j_tagged == j);
2510c5f01b2fSopenharmony_ci        }
2511c5f01b2fSopenharmony_ci
2512c5f01b2fSopenharmony_ci        SECTION("missing byte after tag")
2513c5f01b2fSopenharmony_ci        {
2514c5f01b2fSopenharmony_ci            // add tag to value
2515c5f01b2fSopenharmony_ci            auto v_tagged = v;
2516c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xD8); // tag
2517c5f01b2fSopenharmony_ci
2518c5f01b2fSopenharmony_ci            // check that parsing fails in all modes
2519c5f01b2fSopenharmony_ci            json _;
2520c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2521c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2522c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2523c5f01b2fSopenharmony_ci        }
2524c5f01b2fSopenharmony_ci    }
2525c5f01b2fSopenharmony_ci
2526c5f01b2fSopenharmony_ci    SECTION("0xD9 - 2 byte follow")
2527c5f01b2fSopenharmony_ci    {
2528c5f01b2fSopenharmony_ci        SECTION("success")
2529c5f01b2fSopenharmony_ci        {
2530c5f01b2fSopenharmony_ci            // add tag to value
2531c5f01b2fSopenharmony_ci            auto v_tagged = v;
2532c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2533c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2534c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xD9); // tag
2535c5f01b2fSopenharmony_ci
2536c5f01b2fSopenharmony_ci            // check that parsing fails in error mode
2537c5f01b2fSopenharmony_ci            json _;
2538c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2539c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2540c5f01b2fSopenharmony_ci
2541c5f01b2fSopenharmony_ci            // check that parsing succeeds and gets original value in ignore mode
2542c5f01b2fSopenharmony_ci            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2543c5f01b2fSopenharmony_ci            CHECK(j_tagged == j);
2544c5f01b2fSopenharmony_ci        }
2545c5f01b2fSopenharmony_ci
2546c5f01b2fSopenharmony_ci        SECTION("missing byte after tag")
2547c5f01b2fSopenharmony_ci        {
2548c5f01b2fSopenharmony_ci            // add tag to value
2549c5f01b2fSopenharmony_ci            auto v_tagged = v;
2550c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2551c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xD9); // tag
2552c5f01b2fSopenharmony_ci
2553c5f01b2fSopenharmony_ci            // check that parsing fails in all modes
2554c5f01b2fSopenharmony_ci            json _;
2555c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2556c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2557c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2558c5f01b2fSopenharmony_ci        }
2559c5f01b2fSopenharmony_ci    }
2560c5f01b2fSopenharmony_ci
2561c5f01b2fSopenharmony_ci    SECTION("0xDA - 4 bytes follow")
2562c5f01b2fSopenharmony_ci    {
2563c5f01b2fSopenharmony_ci        SECTION("success")
2564c5f01b2fSopenharmony_ci        {
2565c5f01b2fSopenharmony_ci            // add tag to value
2566c5f01b2fSopenharmony_ci            auto v_tagged = v;
2567c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2568c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2569c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2570c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2571c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xDA); // tag
2572c5f01b2fSopenharmony_ci
2573c5f01b2fSopenharmony_ci            // check that parsing fails in error mode
2574c5f01b2fSopenharmony_ci            json _;
2575c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2576c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2577c5f01b2fSopenharmony_ci
2578c5f01b2fSopenharmony_ci            // check that parsing succeeds and gets original value in ignore mode
2579c5f01b2fSopenharmony_ci            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2580c5f01b2fSopenharmony_ci            CHECK(j_tagged == j);
2581c5f01b2fSopenharmony_ci        }
2582c5f01b2fSopenharmony_ci
2583c5f01b2fSopenharmony_ci        SECTION("missing bytes after tag")
2584c5f01b2fSopenharmony_ci        {
2585c5f01b2fSopenharmony_ci            // add tag to value
2586c5f01b2fSopenharmony_ci            auto v_tagged = v;
2587c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2588c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2589c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2590c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xDA); // tag
2591c5f01b2fSopenharmony_ci
2592c5f01b2fSopenharmony_ci            // check that parsing fails in all modes
2593c5f01b2fSopenharmony_ci            json _;
2594c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2595c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2596c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2597c5f01b2fSopenharmony_ci        }
2598c5f01b2fSopenharmony_ci    }
2599c5f01b2fSopenharmony_ci
2600c5f01b2fSopenharmony_ci    SECTION("0xDB - 8 bytes follow")
2601c5f01b2fSopenharmony_ci    {
2602c5f01b2fSopenharmony_ci        SECTION("success")
2603c5f01b2fSopenharmony_ci        {
2604c5f01b2fSopenharmony_ci            // add tag to value
2605c5f01b2fSopenharmony_ci            auto v_tagged = v;
2606c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2607c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2608c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2609c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2610c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2611c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2612c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2613c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2614c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xDB); // tag
2615c5f01b2fSopenharmony_ci
2616c5f01b2fSopenharmony_ci            // check that parsing fails in error mode
2617c5f01b2fSopenharmony_ci            json _;
2618c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2619c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2620c5f01b2fSopenharmony_ci
2621c5f01b2fSopenharmony_ci            // check that parsing succeeds and gets original value in ignore mode
2622c5f01b2fSopenharmony_ci            auto j_tagged = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore);
2623c5f01b2fSopenharmony_ci            CHECK(j_tagged == j);
2624c5f01b2fSopenharmony_ci        }
2625c5f01b2fSopenharmony_ci
2626c5f01b2fSopenharmony_ci        SECTION("missing byte after tag")
2627c5f01b2fSopenharmony_ci        {
2628c5f01b2fSopenharmony_ci            // add tag to value
2629c5f01b2fSopenharmony_ci            auto v_tagged = v;
2630c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x42); // 1 byte
2631c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2632c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2633c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2634c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x23); // 1 byte
2635c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x22); // 1 byte
2636c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0x11); // 1 byte
2637c5f01b2fSopenharmony_ci            v_tagged.insert(v_tagged.begin(), 0xDB); // tag
2638c5f01b2fSopenharmony_ci
2639c5f01b2fSopenharmony_ci            // check that parsing fails in all modes
2640c5f01b2fSopenharmony_ci            json _;
2641c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged), json::parse_error);
2642c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::error), json::parse_error);
2643c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(v_tagged, true, true, json::cbor_tag_handler_t::ignore), json::parse_error);
2644c5f01b2fSopenharmony_ci        }
2645c5f01b2fSopenharmony_ci    }
2646c5f01b2fSopenharmony_ci
2647c5f01b2fSopenharmony_ci    SECTION("tagged binary")
2648c5f01b2fSopenharmony_ci    {
2649c5f01b2fSopenharmony_ci        // create a binary value of subtype 42
2650c5f01b2fSopenharmony_ci        json j_binary;
2651c5f01b2fSopenharmony_ci        j_binary["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42);
2652c5f01b2fSopenharmony_ci
2653c5f01b2fSopenharmony_ci        // convert to CBOR
2654c5f01b2fSopenharmony_ci        const auto vec = json::to_cbor(j_binary);
2655c5f01b2fSopenharmony_ci        CHECK(vec == std::vector<std::uint8_t> {0xA1, 0x66, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79, 0xD8, 0x2A, 0x44, 0xCA, 0xFE, 0xBA, 0xBE});
2656c5f01b2fSopenharmony_ci
2657c5f01b2fSopenharmony_ci        // parse error when parsing tagged value
2658c5f01b2fSopenharmony_ci        json _;
2659c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.112] parse error at byte 9: syntax error while parsing CBOR value: invalid byte: 0xD8", json::parse_error);
2660c5f01b2fSopenharmony_ci
2661c5f01b2fSopenharmony_ci        // binary without subtype when tags are ignored
2662c5f01b2fSopenharmony_ci        json jb = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore);
2663c5f01b2fSopenharmony_ci        CHECK(jb.is_object());
2664c5f01b2fSopenharmony_ci        CHECK(jb["binary"].is_binary());
2665c5f01b2fSopenharmony_ci        CHECK(!jb["binary"].get_binary().has_subtype());
2666c5f01b2fSopenharmony_ci    }
2667c5f01b2fSopenharmony_ci}
2668