join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1
25#ifndef __JOIN_JSON_HPP__
26#define __JOIN_JSON_HPP__
27
28// libjoin.
29#include <join/atodpow.hpp>
30#include <join/dtoa.hpp>
31#include <join/sax.hpp>
32
33// C++.
34#include <codecvt>
35#include <memory>
36#include <locale>
37
38namespace join
39{
40 namespace details
41 {
42 constexpr char digitPairs[201] = {
43 "00010203040506070809"
44 "10111213141516171819"
45 "20212223242526272829"
46 "30313233343536373839"
47 "40414243444546474849"
48 "50515253545556575859"
49 "60616263646566676869"
50 "70717273747576777879"
51 "80818283848586878889"
52 "90919293949596979899"
53 };
54
56 {
57 uint8_t data[256];
58
59 constexpr UnescapedTable () : data {}
60 {
61 for (int i = 0; i < 32; ++i) { data[i] = 'u'; }
62 data['\b'] = 'b';
63 data['\t'] = 't';
64 data['\n'] = 'n';
65 data['\f'] = 'f';
66 data['\r'] = 'r';
67 data['"'] = '"';
68 data['\\'] = '\\';
69 }
70 };
71
73 }
74
76 {
77 constexpr LocaleDelete () noexcept = default;
78
79 void operator () (locale_t loc) noexcept
80 {
81 freelocale (loc);
82 }
83 };
84
85 using LocalePtr = std::unique_ptr <std::remove_pointer_t <locale_t>, LocaleDelete>;
86
103
107 class JsonCategory : public std::error_category
108 {
109 public:
114 virtual const char* name () const noexcept;
115
121 virtual std::string message (int code) const;
122 };
123
128 const std::error_category& jsonCategory () noexcept;
129
135 std::error_code make_error_code (JsonErrc code) noexcept;
136
142 std::error_condition make_error_condition (JsonErrc code) noexcept;
143
148 {
149 public:
155 JsonWriter (std::ostream& document, size_t indentation = 0)
156 : StreamWriter (document)
157 , _indentation (indentation)
158 {
159 }
160
165 JsonWriter (const JsonWriter& other) = delete;
166
172 JsonWriter& operator= (const JsonWriter& other) = delete;
173
178 JsonWriter (JsonWriter&& other) = delete;
179
185 JsonWriter& operator= (JsonWriter&& other) = delete;
186
190 virtual ~JsonWriter () = default;
191
196 virtual int setNull () override
197 {
198 array ();
199 append4 ("null");
200 _first = false;
201 return 0;
202 }
203
209 virtual int setBool (bool value) override
210 {
211 array ();
212 if (value)
213 {
214 append4 ("true");
215 }
216 else
217 {
218 append5 ("false");
219 }
220 _first = false;
221 return 0;
222 }
223
229 virtual int setInt (int32_t value) override
230 {
231 array ();
232 writeInt (value);
233 _first = false;
234 return 0;
235 }
236
242 virtual int setUint (uint32_t value) override
243 {
244 array ();
245 writeUint (value);
246 _first = false;
247 return 0;
248 }
249
255 virtual int setInt64 (int64_t value) override
256 {
257 array ();
258 writeInt64 (value);
259 _first = false;
260 return 0;
261 }
262
268 virtual int setUint64 (uint64_t value) override
269 {
270 array ();
271 writeUint64 (value);
272 _first = false;
273 return 0;
274 }
275
281 virtual int setDouble (double value) override
282 {
283 array ();
284 uint64_t bits;
285 memcpy (&bits, &value, sizeof (bits));
286 const bool neg = (bits >> 63) != 0;
287 const uint64_t exp = (bits >> 52) & 0x7FFULL;
288 const uint64_t frac = bits & 0x000FFFFFFFFFFFFFULL;
289 if (exp != 0x7FFULL)
290 {
291 writeDouble (value);
292 }
293 else if (frac != 0)
294 {
295 if (neg)
296 {
297 append4 ("-NaN");
298 }
299 else
300 {
301 append3 ("NaN");
302 }
303 }
304 else
305 {
306 if (neg)
307 {
308 append4 ("-Inf");
309 }
310 else
311 {
312 append3 ("Inf");
313 }
314 }
315 _first = false;
316 return 0;
317 }
318
324 virtual int setString (const std::string& value) override
325 {
326 array ();
327 append ('"');
328 if (writeEscaped (value) == -1)
329 {
330 return -1;
331 }
332 append ('"');
333 _first = false;
334 return 0;
335 }
336
342 virtual int startArray ([[maybe_unused]] uint32_t size = 0) override
343 {
344 array ();
345 append ('[');
346 _tab.append (_indentation, ' ');
347 _first = true;
348 _stack.push (true);
349 return 0;
350 }
351
356 virtual int stopArray () override
357 {
358 _tab.erase (_tab.size () - _indentation);
359 if (!_first)
360 {
361 endLine ();
362 indent ();
363 }
364 append (']');
365 _first = false;
366 _stack.pop ();
367 return 0;
368 }
369
375 virtual int startObject ([[maybe_unused]] uint32_t size = 0) override
376 {
377 array ();
378 append ('{');
379 _tab.append (_indentation, ' ');
380 _first = true;
381 _stack.push (false);
382 return 0;
383 }
384
390 virtual int setKey (const std::string& key) override
391 {
392 comma ();
393 endLine ();
394 indent ();
395 append ('"');
396 if (writeEscaped (key) == -1)
397 {
398 return -1;
399 }
400 append ('"');
401 append (':');
402 space ();
403 _first = true;
404 return 0;
405 }
406
411 virtual int stopObject () override
412 {
413 _tab.erase (_tab.size () - _indentation);
414 if (!_first)
415 {
416 endLine ();
417 indent ();
418 }
419 append ('}');
420 _first = false;
421 _stack.pop ();
422 return 0;
423 }
424
425 protected:
430 virtual void writeInt (int32_t value)
431 {
432 if (value == std::numeric_limits <int32_t>::min ())
433 {
434 append ('-');
435 writeUint64 (static_cast <uint64_t> (std::numeric_limits <int32_t>::max ()) + 1);
436 return;
437 }
438
439 if (value < 0)
440 {
441 append ('-');
442 writeUint64 (static_cast <uint64_t> (-value));
443 return;
444 }
445
446 writeUint64 (static_cast <uint64_t> (value));
447 }
448
453 virtual void writeUint (uint32_t value)
454 {
455 writeUint64 (static_cast <uint64_t> (value));
456 }
457
462 virtual void writeInt64 (int64_t value)
463 {
464 if (value == std::numeric_limits <int64_t>::min ())
465 {
466 append ('-');
467 writeUint64 (static_cast <uint64_t> (std::numeric_limits <int64_t>::max ()) + 1);
468 return;
469 }
470
471 if (value < 0)
472 {
473 append ('-');
474 writeUint64 (static_cast <uint64_t> (-value));
475 return;
476 }
477
478 writeUint64 (static_cast <uint64_t> (value));
479 }
480
485 virtual void writeUint64 (uint64_t value)
486 {
487 if (value == 0)
488 {
489 append ('0');
490 return;
491 }
492
493 char buffer[20];
494 char* ptr = buffer + 20;
495
496 while (value >= 100)
497 {
498 uint64_t r = value % 100;
499 value /= 100;
500 ptr -= 2;
501 std::memcpy (ptr, &details::digitPairs[r * 2], 2);
502 }
503
504 if (value >= 10)
505 {
506 ptr -= 2;
507 std::memcpy (ptr, &details::digitPairs[value * 2], 2);
508 }
509 else
510 {
511 *--ptr = '0' + static_cast <char> (value);
512 }
513
514 size_t length = (buffer + 20) - ptr;
515 append (ptr, length);
516 }
517
522 virtual void writeDouble (double value)
523 {
524 char buf[25];
525 char* end = join::dtoa (buf, value);
526 append (buf, end - buf);
527 }
528
536 virtual int utf8Codepoint (std::string::const_iterator& cur, std::string::const_iterator& end, uint32_t& codepoint)
537 {
538 uint8_t u0 = static_cast <uint8_t> (*cur);
539 if (u0 < 0x80)
540 {
541 codepoint = u0;
542 return 0;
543 }
544
545 if (++cur == end)
546 {
547 return -1;
548 }
549
550 uint8_t u1 = static_cast <uint8_t> (*cur);
551 if (u0 < 0xE0)
552 {
553 codepoint = ((u0 & 0x1F) << 6) | (u1 & 0x3F);
554 if (codepoint < 0x80)
555 {
556 return -1;
557 }
558 return 0;
559 }
560
561 if (++cur == end)
562 {
563 return -1;
564 }
565
566 uint8_t u2 = static_cast <uint8_t> (*cur);
567 if (u0 < 0xF0)
568 {
569 codepoint = ((u0 & 0x0F) << 12) | ((u1 & 0x3F) << 6) | (u2 & 0x3F);
570 if ((codepoint > 0xD7FF) && (codepoint < 0xE000))
571 {
572 return -1;
573 }
574 if (codepoint < 0x800)
575 {
576 return -1;
577 }
578 return 0;
579 }
580
581 if (++cur == end)
582 {
583 return -1;
584 }
585
586 uint8_t u3 = static_cast <uint8_t> (*cur);
587 if (u0 < 0xF8)
588 {
589 codepoint = ((u0 & 0x07) << 18) | ((u1 & 0x3F) << 12) | ((u2 & 0x3F) << 6) | (u3 & 0x3F);
590 if (codepoint < 0x10000)
591 {
592 return -1;
593 }
594 return 0;
595 }
596
597 return -1;
598 }
599
605 virtual int writeEscaped(const std::string& value)
606 {
607 auto cur = value.cbegin ();
608 auto end = value.cend ();
609
610 while (cur != end)
611 {
612 auto beg = cur;
613
614 while (cur != end && details::unescapedLookup.data[static_cast <uint8_t> (*cur)] == 0)
615 {
616 ++cur;
617 }
618
619 if (cur != beg)
620 {
621 append (&(*beg), cur - beg);
622 }
623
624 if (cur == end)
625 {
626 break;
627 }
628
629 uint8_t ch = static_cast <uint8_t> (*cur);
630 uint8_t esc = details::unescapedLookup.data[ch];
631 if (esc == 'u')
632 {
633 uint32_t codepoint = 0;
634 char hex[5];
635
636 if (utf8Codepoint (cur, end, codepoint) == -1)
637 {
639 return -1;
640 }
641
642 if (codepoint <= 0xFFFF)
643 {
644 append2 ("\\u");
645 snprintf (hex, sizeof (hex), "%04x", uint16_t (codepoint));
646 append4 (hex);
647 }
648 else
649 {
650 codepoint -= 0x10000;
651 append2 ("\\u");
652 snprintf (hex, sizeof (hex), "%04x", uint16_t (0xD800 + ((codepoint >> 10) & 0x3FF)));
653 append4 (hex);
654 append2 ("\\u");
655 snprintf (hex, sizeof (hex), "%04x", uint16_t (0xDC00 + (codepoint & 0x3FF)));
656 append4 (hex);
657 }
658 }
659 else
660 {
661 char escapeSeq[2] = {'\\', static_cast <char> (esc)};
662 append2 (escapeSeq);
663 }
664
665 ++cur;
666 }
667
668 return 0;
669 }
670
674 inline void comma () noexcept
675 {
676 if (!_stack.empty () && !_first)
677 {
678 append (',');
679 }
680 }
681
685 inline void indent () noexcept
686 {
687 if (_indentation)
688 {
689 append (_tab.c_str (), _tab.size ());
690 }
691 }
692
696 inline void space () noexcept
697 {
698 if (_indentation)
699 {
700 append (' ');
701 }
702 }
703
707 inline void endLine () noexcept
708 {
709 if (_indentation)
710 {
711 append ('\n');
712 }
713 }
714
718 inline void array () noexcept
719 {
720 comma ();
721 if (!_stack.empty () && _stack.top ())
722 {
723 endLine ();
724 indent ();
725 }
726 }
727
729 std::stack <bool> _stack;
730
733
735 std::string _tab;
736
738 bool _first = true;
739 };
740
745 {
746 public:
751 JsonCanonicalizer (std::ostream& document)
752 : JsonWriter (document, 0)
753 {
754 }
755
760 JsonCanonicalizer (const JsonCanonicalizer& other) = delete;
761
768
774
781
785 virtual ~JsonCanonicalizer () = default;
786
792 virtual int setDouble (double value) override
793 {
794 array ();
795 if (std::isfinite (value))
796 {
797 if ((std::trunc (value) == value) &&
798 (value >= 0) &&
799 (value < static_cast <double> (std::numeric_limits <uint64_t>::max ())))
800 {
801 writeUint64 (static_cast <uint64_t> (value));
802 }
803 else if ((std::trunc (value) == value) &&
804 (value >= static_cast <double> (std::numeric_limits <int64_t>::min ())) &&
805 (value < static_cast <double> (std::numeric_limits <int64_t>::max ())))
806 {
807 writeInt64 (static_cast <int64_t> (value));
808 }
809 else
810 {
811 writeDouble (value);
812 }
813 }
814 else
815 {
816 append4 ("null");
817 }
818 _first = false;
819 return 0;
820 }
821
822 protected:
828 virtual int setObject (const Object& object) override
829 {
830 startObject (object.size ());
831 std::vector <const Member *> members;
832 std::transform (object.begin (), object.end (), std::back_inserter (members), [] (const Member &member) {return &member;});
833 std::sort (members.begin (), members.end (), [] (const Member *a, const Member *b) {
834 std::wstring_convert <std::codecvt_utf8_utf16 <char16_t>, char16_t> cvt_utf8_utf16;
835 std::u16string wa = cvt_utf8_utf16.from_bytes (a->first.data ());
836 std::u16string wb = cvt_utf8_utf16.from_bytes (b->first.data ());
837 return wa < wb;
838 });
839 for (auto const& member : members)
840 {
841 setKey (member->first);
842 setValue (member->second);
843 }
844 stopObject ();
845 return 0;
846 }
847
852 virtual void writeDouble (double value) noexcept override
853 {
854 char beg[25];
855 char* end = join::dtoa (beg, value);
856 for (char* pos = beg; pos < end; ++pos)
857 {
858 append (*pos);
859 if ((*pos == 'e') && (*(pos + 1) != '-'))
860 {
861 append ('+');
862 }
863 }
864 }
865 };
866
871 {
872 None = 0,
873 ParseComments = 1L << 0,
876 };
877
885 { return JsonReadMode (static_cast <int> (a) & static_cast <int> (b)); }
886
894 { return JsonReadMode (static_cast <int> (a) | static_cast <int> (b)); }
895
902 constexpr const JsonReadMode& operator&= (JsonReadMode& a, JsonReadMode b) noexcept
903 { return a = a & b; }
904
911 constexpr const JsonReadMode& operator|= (JsonReadMode& a, JsonReadMode b) noexcept
912 { return a = a | b; }
913
918 {
919 public:
925 : StreamReader (root)
926 {
927 }
928
933 JsonReader (const JsonReader& other) = delete;
934
940 JsonReader& operator= (const JsonReader& other) = delete;
941
946 JsonReader (JsonReader&& other) = delete;
947
953 JsonReader& operator= (JsonReader&& other) = delete;
954
958 virtual ~JsonReader () = default;
959
966 template <JsonReadMode ReadMode = JsonReadMode::None>
967 int deserialize (const char* document, size_t length)
968 {
969 StringView in (document, length);
970 return read <ReadMode> (in);
971 }
972
979 int deserialize (const char* document, size_t length) override
980 {
981 return deserialize <> (document, length);
982 }
983
990 template <JsonReadMode ReadMode = JsonReadMode::None>
991 int deserialize (const char* first, const char* last)
992 {
993 StringView in (first, last);
994 return read <ReadMode> (in);
995 }
996
1003 int deserialize (const char* first, const char* last) override
1004 {
1005 return deserialize <> (first, last);
1006 }
1007
1013 template <JsonReadMode ReadMode = JsonReadMode::None>
1014 int deserialize (const std::string& document)
1015 {
1016 StringView in (document.c_str (), document.size ());
1017 return read <ReadMode> (in);
1018 }
1019
1025 int deserialize (const std::string& document) override
1026 {
1027 return deserialize <> (document);
1028 }
1029
1035 template <JsonReadMode ReadMode = JsonReadMode::None>
1036 int deserialize (std::stringstream& document)
1037 {
1038 StringStreamView in (document);
1039 return read <ReadMode> (in);
1040 }
1041
1047 int deserialize (std::stringstream& document) override
1048 {
1049 return deserialize <> (document);
1050 }
1051
1057 template <JsonReadMode ReadMode = JsonReadMode::None>
1058 int deserialize (std::istringstream& document)
1059 {
1060 StringStreamView in (document);
1061 return read <ReadMode> (in);
1062 }
1063
1069 int deserialize (std::istringstream& document) override
1070 {
1071 return deserialize <> (document);
1072 }
1073
1079 template <JsonReadMode ReadMode = JsonReadMode::None>
1080 int deserialize (std::fstream& document)
1081 {
1082 FileStreamView in (document);
1083 return read <ReadMode> (in);
1084 }
1085
1091 int deserialize (std::fstream& document) override
1092 {
1093 return deserialize <> (document);
1094 }
1095
1101 template <JsonReadMode ReadMode = JsonReadMode::None>
1102 int deserialize (std::ifstream& document)
1103 {
1104 FileStreamView in (document);
1105 return read <ReadMode> (in);
1106 }
1107
1113 int deserialize (std::ifstream& document) override
1114 {
1115 return deserialize <> (document);
1116 }
1117
1123 template <JsonReadMode ReadMode = JsonReadMode::None>
1124 int deserialize (std::iostream& document)
1125 {
1126 StreamView in (document);
1127 return read <ReadMode> (in);
1128 }
1129
1135 int deserialize (std::iostream& document) override
1136 {
1137 return deserialize <> (document);
1138 }
1139
1145 template <JsonReadMode ReadMode = JsonReadMode::None>
1146 int deserialize (std::istream& document)
1147 {
1148 StreamView in (document);
1149 return read <ReadMode> (in);
1150 }
1151
1157 int deserialize (std::istream& document) override
1158 {
1159 return deserialize <> (document);
1160 }
1161
1162 protected:
1168 template <JsonReadMode ReadMode, typename ViewType>
1169 int read (ViewType& document)
1170 {
1171 if (skipWhitespaces <ReadMode> (document) != 0)
1172 {
1173 return -1;
1174 }
1175
1176 if (readValue <ReadMode> (document) != 0)
1177 {
1178 return -1;
1179 }
1180
1181 if (ReadMode & JsonReadMode::StopParsingOnDone)
1182 {
1183 return 0;
1184 }
1185
1186 if (skipWhitespaces <ReadMode> (document) != 0)
1187 {
1188 return -1;
1189 }
1190
1191 if (document.peek () != std::char_traits <char>::eof ())
1192 {
1194 return -1;
1195 }
1196
1197 return 0;
1198 }
1199
1205 template <JsonReadMode ReadMode, typename ViewType>
1206 int readValue (ViewType& document)
1207 {
1208 int ch = document.peek ();
1209 switch (ch)
1210 {
1211 case '[':
1212 document.get ();
1213 return readArray <ReadMode> (document);
1214 case '{':
1215 document.get ();
1216 return readObject <ReadMode> (document);
1217 case '"':
1218 document.get ();
1219 return readString (document);
1220 case 'n':
1221 document.get ();
1222 return readNull (document);
1223 case 't':
1224 document.get ();
1225 return readTrue (document);
1226 case 'f':
1227 document.get ();
1228 return readFalse (document);
1229 default:
1230 return readNumber (document);
1231 }
1232 }
1233
1239 template <typename ViewType>
1240 int readNull (ViewType& document)
1241 {
1242 if (JOIN_UNLIKELY ((document.get () != 'u') || (document.get () != 'l') || (document.get () != 'l')))
1243 {
1245 return -1;
1246 }
1247
1248 return setNull ();
1249 }
1250
1256 template <typename ViewType>
1257 int readTrue (ViewType& document)
1258 {
1259 if (JOIN_UNLIKELY ((document.get () != 'r') || (document.get () != 'u') || (document.get () != 'e')))
1260 {
1262 return -1;
1263 }
1264
1265 return setBool (true);
1266 }
1267
1273 template <typename ViewType>
1274 int readFalse (ViewType& document)
1275 {
1276 if (JOIN_UNLIKELY ((document.get () != 'a') || (document.get () != 'l') || (document.get () != 's') || (document.get () != 'e')))
1277 {
1279 return -1;
1280 }
1281
1282 return setBool (false);
1283 }
1284
1290 template <typename ViewType>
1291 int readInf (ViewType& document, bool negative)
1292 {
1293 if (JOIN_UNLIKELY (!(document.getIfNoCase ('n') && document.getIfNoCase ('f'))))
1294 {
1296 return -1;
1297 }
1298
1299 if (JOIN_UNLIKELY (document.getIfNoCase ('i') && !(document.getIfNoCase ('n') && document.getIfNoCase ('i') && document.getIfNoCase ('t') && document.getIfNoCase ('y'))))
1300 {
1302 return -1;
1303 }
1304
1305 return setDouble (negative ? -std::numeric_limits <double>::infinity () : std::numeric_limits <double>::infinity ());
1306 }
1307
1313 template <typename ViewType>
1314 int readNan (ViewType& document, bool negative)
1315 {
1316 if (JOIN_UNLIKELY (!(document.getIfNoCase ('a') && document.getIfNoCase ('n'))))
1317 {
1319 return -1;
1320 }
1321
1322 return setDouble (negative ? -std::numeric_limits <double>::quiet_NaN () : std::numeric_limits <double>::quiet_NaN ());
1323 }
1324
1334 inline void umul192 (uint64_t hi, uint64_t lo, uint64_t significand, uint64_t& high, uint64_t& middle, uint64_t& low) noexcept
1335 {
1336 #if defined(__SIZEOF_INT128__)
1337 __uint128_t h = static_cast <__uint128_t> (hi) * significand;
1338 __uint128_t l = static_cast <__uint128_t> (lo) * significand;
1339 __uint128_t s = h + (l >> 64);
1340
1341 high = static_cast <uint64_t> (s >> 64);
1342 middle = static_cast <uint64_t> (s);
1343 low = static_cast <uint64_t> (l);
1344 #else
1345 uint64_t hi_hi, hi_lo, lo_hi, lo_lo;
1346
1347 uint64_t m_lo = static_cast <uint32_t> (significand);
1348 uint64_t m_hi = significand >> 32;
1349 uint64_t p0 = (hi & 0xFFFFFFFF) * m_lo;
1350 uint64_t p1 = (hi >> 32) * m_lo;
1351 uint64_t p2 = (hi & 0xFFFFFFFF) * m_hi;
1352 uint64_t p3 = (hi >> 32) * m_hi;
1353 uint64_t carry = (p0 >> 32) + (p1 & 0xFFFFFFFF) + (p2 & 0xFFFFFFFF);
1354 hi_lo = (carry << 32) | (p0 & 0xFFFFFFFF);
1355 hi_hi = (carry >> 32) + (p1 >> 32) + (p2 >> 32) + p3;
1356
1357 p0 = (lo & 0xFFFFFFFF) * m_lo;
1358 p1 = (lo >> 32) * m_lo;
1359 p2 = (lo & 0xFFFFFFFF) * m_hi;
1360 p3 = (lo >> 32) * m_hi;
1361 carry = (p0 >> 32) + (p1 & 0xFFFFFFFF) + (p2 & 0xFFFFFFFF);
1362 lo_lo = (carry << 32) | (p0 & 0xFFFFFFFF);
1363 lo_hi = (carry >> 32) + (p1 >> 32) + (p2 >> 32) + p3;
1364
1365 low = lo_lo;
1366 middle = hi_lo + lo_hi;
1367 high = hi_hi + (middle < hi_lo ? 1 : 0);
1368 #endif
1369 }
1370
1378 inline bool strtodFast (uint64_t significand, int64_t exponent, double &value)
1379 {
1380 constexpr double pow10[] = {
1381 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
1382 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21,
1383 1e22
1384 };
1385
1386 value = static_cast <double> (significand);
1387
1388 if (JOIN_UNLIKELY ((exponent > 22) && (exponent < (22 + 16))))
1389 {
1390 value *= pow10[exponent - 22];
1391 exponent = 22;
1392 }
1393
1394 if (JOIN_LIKELY ((exponent >= -22) && (exponent <= 22) && (value <= 9007199254740991.0)))
1395 {
1396 value = (exponent < 0) ? (value / pow10[-exponent]) : (value * pow10[exponent]);
1397 return true;
1398 }
1399
1400 if (JOIN_UNLIKELY (value == 0.0))
1401 {
1402 return true;
1403 }
1404
1405 if (JOIN_UNLIKELY (exponent < -325 || exponent > 308))
1406 {
1407 return false;
1408 }
1409
1410 uint64_t high, middle, low;
1411 const details::Power& power = details::atodpow[exponent + 325];
1412 umul192 (power.hi, power.lo, significand, high, middle, low);
1413 int64_t exp = ((exponent * 217706) >> 16) + 1087;
1414
1415 int lz;
1416 if (high != 0)
1417 {
1418 lz = __builtin_clzll (high);
1419 exp -= lz;
1420 }
1421 else /*if (middle != 0)*/
1422 {
1423 lz = __builtin_clzll (middle);
1424 exp -= lz + 64;
1425 }
1426 // else
1427 // {
1428 // return false;
1429 // }
1430
1431 if (JOIN_UNLIKELY (exp <= 0 || exp >= 2047))
1432 {
1433 return false;
1434 }
1435
1436 if (high == 0)
1437 {
1438 high = middle << lz;
1439 middle = 0;
1440 }
1441 else if (lz != 0)
1442 {
1443 high = (high << lz) | (middle >> (64 - lz));
1444 middle <<= lz;
1445 }
1446
1447 middle |= (low != 0);
1448
1449 uint64_t mant = (high >> 11) & 0xFFFFFFFFFFFFF;
1450 uint64_t bits = (static_cast <uint64_t> (exp) << 52) | mant;
1451 uint64_t frac = high & 0x7FF;
1452
1453 bool roundUp = ((frac > 0x400) |
1454 ((frac == 0x400) && ((middle != 0) || (mant & 1))) |
1455 ((frac == 0x3FF) && ((middle != 0))));
1456
1457 bits += roundUp;
1458 std::memcpy (&value, &bits, sizeof (double));
1459
1460 return true;
1461 }
1462
1469 inline bool strtodSlow (const std::string& num, double& d)
1470 {
1471 static LocalePtr locale (newlocale (LC_ALL_MASK, "C", nullptr));
1472 char* end = nullptr;
1473 d = strtod_l (num.c_str (), &end, locale.get ());
1474 return (end && (*end == '\0'));
1475 }
1476
1482 template <typename ViewType>
1483 int readNumber (ViewType& document)
1484 {
1485 BufferingView <ViewType> view (document);
1486
1487 bool negative = view.getIf ('-');
1488
1489 uint64_t max64 = std::numeric_limits <uint64_t>::max ();
1490 if (negative)
1491 {
1492 max64 = static_cast <uint64_t> (std::numeric_limits <int64_t>::max ()) + 1;
1493 }
1494
1495 uint64_t digits = 0;
1496 bool isDouble = false;
1497 uint64_t u = 0;
1498
1499 if (JOIN_UNLIKELY (view.getIf ('0')))
1500 {
1501 if (JOIN_UNLIKELY (isDigit (view.peek ())))
1502 {
1504 return -1;
1505 }
1506 }
1507 else if (JOIN_LIKELY (isDigit (view.peek ())))
1508 {
1509 u = view.get () - '0';
1510 ++digits;
1511
1512 while (JOIN_LIKELY (isDigit (view.peek ())))
1513 {
1514 int digit = view.peek () - '0';
1515
1516 if (JOIN_UNLIKELY (u > ((max64 - digit) / 10)))
1517 {
1518 isDouble = true;
1519 break;
1520 }
1521
1522 u = (u * 10) + (view.get () - '0');
1523 ++digits;
1524 }
1525 }
1526 else if (JOIN_LIKELY (document.getIfNoCase ('i')))
1527 {
1528 return readInf (document, negative);
1529 }
1530 else if (JOIN_LIKELY (document.getIfNoCase ('n')))
1531 {
1532 return readNan (document, negative);
1533 }
1534 else
1535 {
1537 return -1;
1538 }
1539
1540 if (isDouble)
1541 {
1542 while (JOIN_LIKELY (isDigit (view.peek ())))
1543 {
1544 u = (u * 10) + (view.get () - '0');
1545 ++digits;
1546 }
1547 }
1548
1549 int64_t frac = 0;
1550 if (view.getIf ('.'))
1551 {
1552 isDouble = true;
1553
1554 while (JOIN_LIKELY (isDigit (view.peek ())))
1555 {
1556 u = (u * 10) + (view.get () - '0');
1557 if (JOIN_LIKELY (u || digits))
1558 {
1559 ++digits;
1560 }
1561 --frac;
1562 }
1563 }
1564
1565 int64_t exponent = 0;
1566 if (view.getIf ('e') || view.getIf ('E'))
1567 {
1568 isDouble = true;
1569
1570 bool negExp = false;
1571 if (isSign (view.peek ()))
1572 {
1573 negExp = (view.get () == '-');
1574 }
1575
1576 if (JOIN_LIKELY (isDigit (view.peek ())))
1577 {
1578 exponent = (view.get () - '0');
1579
1580 while (JOIN_LIKELY (isDigit (view.peek ())))
1581 {
1582 int digit = view.get () - '0';
1583
1584 if (JOIN_LIKELY (exponent <= ((std::numeric_limits <int>::max () - digit) / 10)))
1585 {
1586 exponent = (exponent * 10) + digit;
1587 }
1588 }
1589 }
1590 else
1591 {
1593 return -1;
1594 }
1595
1596 if (negExp)
1597 {
1598 exponent = -exponent;
1599 }
1600 }
1601
1602 if (!isDouble)
1603 {
1604 return negative ? setInt64 (-static_cast <int64_t> (u)) : setUint64 (u);
1605 }
1606
1607 if (JOIN_LIKELY (digits <= 19))
1608 {
1609 double d = 0.0;
1610 if (strtodFast (u, exponent + frac, d))
1611 {
1612 return setDouble (negative ? -d : d);
1613 }
1614 }
1615
1616 std::string number;
1617 view.snapshot (number);
1618
1619 double d = 0.0;
1620 if (strtodSlow (number, d))
1621 {
1622 return setDouble (d);
1623 }
1624
1626 return -1;
1627 }
1628
1635 template <typename ViewType>
1636 inline int readHex (ViewType& document, uint32_t& u)
1637 {
1638 for (int i = 0; i < 4; ++i)
1639 {
1640 char c = document.get ();
1641
1642 if (isDigit (c))
1643 {
1644 c -= '0';
1645 }
1646 else if (isUpperAlpha (c))
1647 {
1648 c = c - 'A' + 10;
1649 }
1650 else if (isLowerAlpha (c))
1651 {
1652 c = c - 'a' + 10;
1653 }
1654 else
1655 {
1657 return -1;
1658 }
1659
1660 u = (u << 4) + c;
1661 }
1662
1663 return 0;
1664 }
1665
1671 inline void encodeUtf8 (uint32_t codepoint, std::string& output)
1672 {
1673 if (codepoint < 0x80)
1674 {
1675 output.push_back (static_cast <char> (codepoint));
1676 }
1677 else if (codepoint < 0x800)
1678 {
1679 char buf[2];
1680 buf[0] = static_cast <char> (0xC0 | (codepoint >> 6));
1681 buf[1] = static_cast <char> (0x80 | (codepoint & 0x3F));
1682 output.append (buf, 2);
1683 }
1684 else if (codepoint < 0x10000)
1685 {
1686 char buf[3];
1687 buf[0] = static_cast <char> (0xE0 | (codepoint >> 12));
1688 buf[1] = static_cast <char> (0x80 | ((codepoint >> 6) & 0x3F));
1689 buf[2] = static_cast <char> (0x80 | (codepoint & 0x3F));
1690 output.append (buf, 3);
1691 }
1692 else
1693 {
1694 char buf[4];
1695 buf[0] = static_cast <char> (0xF0 | (codepoint >> 18));
1696 buf[1] = static_cast <char> (0x80 | ((codepoint >> 12) & 0x3F));
1697 buf[2] = static_cast <char> (0x80 | ((codepoint >> 6) & 0x3F));
1698 buf[3] = static_cast <char> (0x80 | (codepoint & 0x3F));
1699 output.append (buf, 4);
1700 }
1701 }
1702
1709 template <typename ViewType>
1710 inline int readUnicode (ViewType& document, std::string& output)
1711 {
1712 uint32_t u = 0;
1713
1714 if (readHex (document, u) == -1)
1715 {
1716 return -1;
1717 }
1718
1719 if (u >= 0xDC00 && u <= 0xDFFF)
1720 {
1722 return -1;
1723 }
1724
1725 if (u >= 0xD800 && u <= 0xDBFF)
1726 {
1727 if ((document.get () != '\\') || (document.get () != 'u'))
1728 {
1730 return -1;
1731 }
1732
1733 uint32_t v = 0;
1734
1735 if (readHex (document, v) == -1)
1736 {
1738 return -1;
1739 }
1740
1741 if (v < 0xDC00 || v > 0xDFFF)
1742 {
1744 return -1;
1745 }
1746
1747 u = 0x10000 + (((u - 0xD800) << 10) | (v - 0xDC00));
1748 }
1749
1750 if (u > 0x10FFFF)
1751 {
1753 return -1;
1754 }
1755
1756 encodeUtf8 (u, output);
1757
1758 return 0;
1759 }
1760
1767 template <typename ViewType>
1768 inline int readEscaped (ViewType& document, std::string& output)
1769 {
1770 int ch = document.get ();
1771 switch (ch)
1772 {
1773 case '"': output.push_back ('"'); break;
1774 case '\\': output.push_back ('\\'); break;
1775 case '/': output.push_back ('/'); break;
1776 case 'b': output.push_back ('\b'); break;
1777 case 'f': output.push_back ('\f'); break;
1778 case 'n': output.push_back ('\n'); break;
1779 case 'r': output.push_back ('\r'); break;
1780 case 't': output.push_back ('\t'); break;
1781 case 'u':
1782 return readUnicode (document, output);
1783 default:
1785 return -1;
1786 }
1787
1788 return 0;
1789 }
1790
1797 /*template <typename ViewType>
1798 inline int readUtf8 (ViewType& document, std::string& output) noexcept
1799 {
1800 size_t count = 0;
1801
1802 if (static_cast <uint8_t> (document.peek ()) < 0x80)
1803 {
1804 output.push_back (document.get ());
1805 }
1806 else if (static_cast <uint8_t> (document.peek ()) < 0xE0)
1807 {
1808 output.push_back (document.get ());
1809 count = 1;
1810 }
1811 else if (static_cast <uint8_t> (document.peek ()) < 0xF0)
1812 {
1813 output.push_back (document.get ());
1814 count = 2;
1815 }
1816 else if (static_cast <uint8_t> (document.peek ()) < 0xF8)
1817 {
1818 output.push_back (document.get ());
1819 count = 3;
1820 }
1821 else
1822 {
1823 join::lastError = make_error_code (JsonErrc::InvalidEncoding);
1824 return -1;
1825 }
1826
1827 for (size_t i = 0; i < count; ++i)
1828 {
1829 if (static_cast <uint8_t> (document.peek ()) < 0x80 || static_cast <uint8_t> (document.peek ()) > 0xBF)
1830 {
1831 join::lastError = make_error_code (JsonErrc::InvalidEncoding);
1832 return -1;
1833 }
1834
1835 output.push_back (document.get ());
1836 }
1837
1838 return 0;
1839 }*/
1840
1847 template <typename ViewType>
1848 int readString (ViewType& document, bool isKey = false)
1849 {
1850 thread_local std::string output;
1851 output.clear ();
1852 output.reserve (64);
1853
1854 for (;;)
1855 {
1856 document.readUntilEscaped (output);
1857 int ch = document.peek ();
1858
1859 if (ch == '"')
1860 {
1861 document.get ();
1862 break;
1863 }
1864
1865 if (ch == '\\')
1866 {
1867 document.get ();
1868 if (readEscaped (document, output) == -1)
1869 {
1870 return -1;
1871 }
1872 continue;
1873 }
1874
1875 /*if (static_cast <uint8_t> (ch) > 0x7F)
1876 {
1877 if (readUtf8 (document, output) == -1)
1878 {
1879 return -1;
1880 }
1881 continue;
1882 }*/
1883
1884 if (ch < 0x20)
1885 {
1887 return -1;
1888 }
1889 }
1890
1891 return isKey ? setKey (output) : setString (output);
1892 }
1893
1899 template <JsonReadMode ReadMode, typename ViewType>
1900 int readArray (ViewType& document)
1901 {
1902 if (JOIN_UNLIKELY (startArray () == -1))
1903 {
1904 return -1;
1905 }
1906
1907 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
1908 {
1909 return -1;
1910 }
1911
1912 if (document.getIf (']'))
1913 {
1914 return stopArray ();
1915 }
1916
1917 for (;;)
1918 {
1919 if (JOIN_UNLIKELY (readValue <ReadMode> (document) == -1))
1920 {
1921 return -1;
1922 }
1923
1924 int ch = document.get ();
1925
1926 if (JOIN_UNLIKELY (details::whitespaceLookup.data[static_cast <unsigned char> (ch)]))
1927 {
1928 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
1929 {
1930 return -1;
1931 }
1932 ch = document.get ();
1933 }
1934
1935 if (JOIN_LIKELY (ch == ','))
1936 {
1937 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
1938 {
1939 return -1;
1940 }
1941 continue;
1942 }
1943
1944 if (JOIN_LIKELY (ch == ']'))
1945 {
1946 break;
1947 }
1948
1950 return -1;
1951 }
1952
1953 return stopArray ();
1954 }
1955
1961 template <JsonReadMode ReadMode, typename ViewType>
1962 int readObject (ViewType& document)
1963 {
1964 if (JOIN_UNLIKELY (startObject () == -1))
1965 {
1966 return -1;
1967 }
1968
1969 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
1970 {
1971 return -1;
1972 }
1973
1974 if (document.getIf ('}'))
1975 {
1976 return stopObject ();
1977 }
1978
1979 for (;;)
1980 {
1981 if (JOIN_UNLIKELY (document.get () != '"'))
1982 {
1984 return -1;
1985 }
1986
1987 if (JOIN_UNLIKELY (readString (document, true) == -1))
1988 {
1989 return -1;
1990 }
1991
1992 if (document.peek () != ':')
1993 {
1994 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
1995 {
1996 return -1;
1997 }
1998 }
1999
2000 if (JOIN_UNLIKELY (document.get () != ':'))
2001 {
2003 return -1;
2004 }
2005
2006 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
2007 {
2008 return -1;
2009 }
2010
2011 if (JOIN_UNLIKELY (readValue <ReadMode> (document) == -1))
2012 {
2013 return -1;
2014 }
2015
2016 int ch = document.get ();
2017
2018 if (JOIN_UNLIKELY (details::whitespaceLookup.data[static_cast <unsigned char> (ch)]))
2019 {
2020 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
2021 {
2022 return -1;
2023 }
2024 ch = document.get ();
2025 }
2026
2027 if (JOIN_LIKELY (ch == ','))
2028 {
2029 if (JOIN_UNLIKELY (skipWhitespaces <ReadMode> (document) == -1))
2030 {
2031 return -1;
2032 }
2033 continue;
2034 }
2035
2036 if (JOIN_LIKELY (ch == '}'))
2037 {
2038 break;
2039 }
2040
2042 return -1;
2043 }
2044
2045 return stopObject ();
2046 }
2047
2053 template <JsonReadMode ReadMode, typename ViewType>
2054 inline typename std::enable_if <!(ReadMode & JsonReadMode::ParseComments), int>::type
2055 skipWhitespaces (ViewType& document)
2056 {
2057 return document.skipWhitespaces ();
2058 }
2059
2065 template <JsonReadMode ReadMode, typename ViewType>
2066 inline typename std::enable_if <(ReadMode & JsonReadMode::ParseComments), int>::type
2067 skipWhitespaces (ViewType& document)
2068 {
2069 return document.skipWhitespacesAndComments ();
2070 }
2071
2077 constexpr bool isUpperAlpha (char c) noexcept
2078 {
2079 return static_cast <unsigned char> (c - 'A') <= 5u;
2080 }
2081
2087 constexpr bool isLowerAlpha (char c) noexcept
2088 {
2089 return static_cast <unsigned char> (c - 'a') <= 5u;
2090 }
2091
2097 constexpr bool isDigit (char c) noexcept
2098 {
2099 return static_cast <unsigned char> (c - '0') <= 9u;
2100 }
2101
2107 constexpr bool isSign (char c) noexcept
2108 {
2109 return ((c ^ '+') & (c ^ '-')) == 0;
2110 }
2111 };
2112}
2113
2114namespace std
2115{
2117 template <> struct is_error_condition_enum <join::JsonErrc> : public true_type {};
2118}
2119
2120#endif
basic stream view.
Definition view.hpp:368
JSON canonicalizer class.
Definition json.hpp:745
virtual void writeDouble(double value) noexcept override
write real value.
Definition json.hpp:852
JsonCanonicalizer(std::ostream &document)
create instance.
Definition json.hpp:751
JsonCanonicalizer & operator=(const JsonCanonicalizer &other)=delete
copy assignment.
JsonCanonicalizer(JsonCanonicalizer &&other)=delete
move constructor.
JsonCanonicalizer(const JsonCanonicalizer &other)=delete
copy constructor.
virtual int setObject(const Object &object) override
set object value.
Definition json.hpp:828
virtual ~JsonCanonicalizer()=default
destroy instance.
virtual int setDouble(double value) override
set real value.
Definition json.hpp:792
JSON error category.
Definition json.hpp:108
virtual std::string message(int code) const
translate JSON error code to human readable error string.
Definition json.cpp:44
virtual const char * name() const noexcept
get JSON error category name.
Definition json.cpp:35
JSON reader class.
Definition json.hpp:918
bool strtodSlow(const std::string &num, double &d)
convert double using strtod.
Definition json.hpp:1469
constexpr bool isSign(char c) noexcept
check if sign.
Definition json.hpp:2107
JsonReader(const JsonReader &other)=delete
copy constructor.
int readValue(ViewType &document)
parse a JSON value.
Definition json.hpp:1206
int deserialize(std::istringstream &document) override
deserialize a document.
Definition json.hpp:1069
constexpr bool isUpperAlpha(char c) noexcept
check if upper case alphanumeric character.
Definition json.hpp:2077
int deserialize(const char *first, const char *last) override
deserialize a document.
Definition json.hpp:1003
int readInf(ViewType &document, bool negative)
parse an infinity value.
Definition json.hpp:1291
int deserialize(const char *document, size_t length)
deserialize a document.
Definition json.hpp:967
int readUnicode(ViewType &document, std::string &output)
parse unicode.
Definition json.hpp:1710
int deserialize(std::stringstream &document) override
deserialize a document.
Definition json.hpp:1047
int readHex(ViewType &document, uint32_t &u)
parse a 4-digit hexadecimal sequence..
Definition json.hpp:1636
int readEscaped(ViewType &document, std::string &output)
parse escaped sequence.
Definition json.hpp:1768
int deserialize(const char *document, size_t length) override
deserialize a document.
Definition json.hpp:979
int readString(ViewType &document, bool isKey=false)
parse UTF8.
Definition json.hpp:1848
std::enable_if<!(ReadMode &JsonReadMode::ParseComments), int >::type skipWhitespaces(ViewType &document)
skip whitespaces.
Definition json.hpp:2055
int deserialize(const char *first, const char *last)
deserialize a document.
Definition json.hpp:991
JsonReader(JsonReader &&other)=delete
move constructor.
int readObject(ViewType &document)
parse an object value.
Definition json.hpp:1962
virtual ~JsonReader()=default
destroy instance.
void umul192(uint64_t hi, uint64_t lo, uint64_t significand, uint64_t &high, uint64_t &middle, uint64_t &low) noexcept
multiply 192 bits unsigned integer by 64 bits unsigned integer.
Definition json.hpp:1334
int read(ViewType &document)
parse a document.
Definition json.hpp:1169
int deserialize(std::iostream &document)
deserialize a document.
Definition json.hpp:1124
int deserialize(std::fstream &document)
deserialize a document.
Definition json.hpp:1080
int readNan(ViewType &document, bool negative)
parse a nan value.
Definition json.hpp:1314
void encodeUtf8(uint32_t codepoint, std::string &output)
encode a Unicode codepoint to UTF-8.
Definition json.hpp:1671
JsonReader & operator=(const JsonReader &other)=delete
copy assignment.
int readNull(ViewType &document)
parse a null value.
Definition json.hpp:1240
int deserialize(std::istream &document) override
deserialize a document.
Definition json.hpp:1157
int deserialize(const std::string &document) override
deserialize a document.
Definition json.hpp:1025
int deserialize(std::ifstream &document) override
deserialize a document.
Definition json.hpp:1113
constexpr bool isLowerAlpha(char c) noexcept
check if lower case alphanumeric character.
Definition json.hpp:2087
int deserialize(std::iostream &document) override
deserialize a document.
Definition json.hpp:1135
constexpr bool isDigit(char c) noexcept
check if digit.
Definition json.hpp:2097
int deserialize(const std::string &document)
deserialize a document.
Definition json.hpp:1014
JsonReader(Value &root)
default constructor.
Definition json.hpp:924
int deserialize(std::istringstream &document)
deserialize a document.
Definition json.hpp:1058
int readNumber(ViewType &document)
parse a number value.
Definition json.hpp:1483
int readArray(ViewType &document)
parse an array value.
Definition json.hpp:1900
int deserialize(std::istream &document)
deserialize a document.
Definition json.hpp:1146
int deserialize(std::fstream &document) override
deserialize a document.
Definition json.hpp:1091
int readFalse(ViewType &document)
parse a false value.
Definition json.hpp:1274
int readTrue(ViewType &document)
parse a true value.
Definition json.hpp:1257
int deserialize(std::ifstream &document)
deserialize a document.
Definition json.hpp:1102
int deserialize(std::stringstream &document)
deserialize a document.
Definition json.hpp:1036
bool strtodFast(uint64_t significand, int64_t exponent, double &value)
convert double using fast path.
Definition json.hpp:1378
JSON writer class.
Definition json.hpp:148
std::string _tab
tabulation.
Definition json.hpp:735
virtual void writeUint(uint32_t value)
write unsigned integer value.
Definition json.hpp:453
void indent() noexcept
write indentation.
Definition json.hpp:685
size_t _indentation
indentation.
Definition json.hpp:732
virtual int utf8Codepoint(std::string::const_iterator &cur, std::string::const_iterator &end, uint32_t &codepoint)
get UTF8 codepoint.
Definition json.hpp:536
virtual int setInt(int32_t value) override
set integer value.
Definition json.hpp:229
virtual int setInt64(int64_t value) override
set 64 bits integer value.
Definition json.hpp:255
virtual void writeDouble(double value)
write real value.
Definition json.hpp:522
JsonWriter(std::ostream &document, size_t indentation=0)
create instance.
Definition json.hpp:155
virtual int stopArray() override
stop array.
Definition json.hpp:356
virtual ~JsonWriter()=default
destroy instance.
virtual int startArray(uint32_t size=0) override
start array.
Definition json.hpp:342
virtual void writeInt(int32_t value)
write integer value.
Definition json.hpp:430
virtual int setKey(const std::string &key) override
set key.
Definition json.hpp:390
void comma() noexcept
write comma.
Definition json.hpp:674
virtual int stopObject() override
stop object.
Definition json.hpp:411
virtual void writeUint64(uint64_t value)
write 64 bits unsigned integer value.
Definition json.hpp:485
void array() noexcept
add comma, go to line and indent if in array.
Definition json.hpp:718
virtual int setUint(uint32_t value) override
set unsigned integer value.
Definition json.hpp:242
virtual void writeInt64(int64_t value)
write 64 bits integer value.
Definition json.hpp:462
virtual int writeEscaped(const std::string &value)
escape string value.
Definition json.hpp:605
virtual int setDouble(double value) override
set real value.
Definition json.hpp:281
virtual int startObject(uint32_t size=0) override
start object.
Definition json.hpp:375
std::stack< bool > _stack
array stack.
Definition json.hpp:729
virtual int setNull() override
set null value.
Definition json.hpp:196
JsonWriter(const JsonWriter &other)=delete
copy constructor.
JsonWriter(JsonWriter &&other)=delete
move constructor.
virtual int setUint64(uint64_t value) override
set unsigned 64 bits integer value.
Definition json.hpp:268
virtual int setString(const std::string &value) override
set string value.
Definition json.hpp:324
void space() noexcept
write space.
Definition json.hpp:696
bool _first
is first element.
Definition json.hpp:738
void endLine() noexcept
write end of line.
Definition json.hpp:707
virtual int setBool(bool value) override
set boolean value.
Definition json.hpp:209
stream deserializer abstract class.
Definition sax.hpp:443
virtual int stopObject() override
stop object.
Definition sax.hpp:734
virtual int startArray(uint32_t size=0) override
start array.
Definition sax.hpp:636
virtual int setInt64(int64_t value) override
set 64 bits integer value.
Definition sax.hpp:596
virtual int setNull() override
set null value.
Definition sax.hpp:556
virtual int setUint64(uint64_t value) override
set unsigned 64 bits integer value.
Definition sax.hpp:606
virtual int setKey(const std::string &key) override
set key.
Definition sax.hpp:724
virtual int startObject(uint32_t size=0) override
start object.
Definition sax.hpp:687
virtual int setBool(bool value) override
set boolean value.
Definition sax.hpp:566
virtual int stopArray() override
stop array.
Definition sax.hpp:672
virtual int setDouble(double value) override
set real value.
Definition sax.hpp:616
virtual int setString(const std::string &value) override
set string value.
Definition sax.hpp:626
stream serializer abstract class.
Definition sax.hpp:243
int setValue(const Value &value)
set value.
Definition sax.hpp:300
void append(char data) noexcept
append character to output stream in batch.
Definition sax.hpp:373
void append4(const char *data) noexcept
append 4-character literal to output stream in batch.
Definition sax.hpp:403
string view.
Definition view.hpp:78
value class.
Definition value.hpp:63
const std::string key(65, 'a')
key.
constexpr UnescapedTable unescapedLookup
Definition json.hpp:72
constexpr char digitPairs[201]
Definition json.hpp:42
constexpr WhitespaceTable whitespaceLookup
Definition view.hpp:71
constexpr Power atodpow[]
Definition atodpow.hpp:40
Definition acceptor.hpp:32
std::pair< std::string, Value > Member
object member.
Definition value.hpp:54
std::unique_ptr< std::remove_pointer_t< locale_t >, LocaleDelete > LocalePtr
Definition json.hpp:85
std::error_code make_error_code(join::Errc code)
Create an std::error_code object.
Definition error.cpp:154
char * dtoa(char *buffer, double value)
double to string conversion.
Definition dtoa.hpp:215
constexpr const JsonReadMode & operator&=(JsonReadMode &a, JsonReadMode b) noexcept
perform binary AND on JsonReadMode.
Definition json.hpp:902
IpAddress operator&(const IpAddress &a, const IpAddress &b)
perform AND operation on IP address.
Definition ipaddress.cpp:1666
const std::error_category & jsonCategory() noexcept
get error category.
Definition json.cpp:77
constexpr const JsonReadMode & operator|=(JsonReadMode &a, JsonReadMode b) noexcept
perform binary OR on JsonReadMode.
Definition json.hpp:911
JsonReadMode
JSON deserialization mode.
Definition json.hpp:871
@ StopParsingOnDone
Definition json.hpp:875
@ ParseComments
Definition json.hpp:873
@ ValidateEncoding
Definition json.hpp:874
@ None
Definition json.hpp:872
std::vector< Member > Object
object.
Definition value.hpp:57
IpAddress operator|(const IpAddress &a, const IpAddress &b)
perform OR operation on IP address.
Definition ipaddress.cpp:1693
thread_local std::error_code lastError
last error.
Definition error.cpp:32
std::error_condition make_error_condition(join::Errc code)
Create an std::error_condition object.
Definition error.cpp:163
JsonErrc
JSON error codes.
Definition json.hpp:91
Definition error.hpp:106
Definition json.hpp:76
constexpr LocaleDelete() noexcept=default
Definition atodpow.hpp:35
uint64_t hi
Definition atodpow.hpp:36
uint64_t lo
Definition atodpow.hpp:37
Definition json.hpp:56
uint8_t data[256]
Definition json.hpp:57
constexpr UnescapedTable()
Definition json.hpp:59
#define JOIN_LIKELY(x)
Definition utils.hpp:46
#define JOIN_UNLIKELY(x)
Definition utils.hpp:47