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