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