join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
pack.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_DATA_PACK_HPP
26#define JOIN_DATA_PACK_HPP
27
28// dconv.
29#include <dconv/probe.hpp>
30
31// libjoin.
33#include <join/value.hpp>
34#include <join/utils.hpp>
35#include <join/sax.hpp>
36
37// C++.
38#include <algorithm>
39#include <sstream>
40#include <fstream>
41
42// C.
43#include <cstring>
44
45namespace join
46{
51 {
52 public:
57 explicit PackWriter (std::ostream& document)
58 : _out (document.rdbuf ())
59 {
60 }
61
66 PackWriter (const PackWriter& other) = delete;
67
73 PackWriter& operator= (const PackWriter& other) = delete;
74
79 PackWriter (PackWriter&& other) = delete;
80
86 PackWriter& operator= (PackWriter&& other) = delete;
87
91 ~PackWriter () = default;
92
97 int setNull ()
98 {
99 append (0xc0);
100 endValue ();
101 return 0;
102 }
103
109 int setBool (bool value)
110 {
111 if (value)
112 {
113 append (0xc3);
114 }
115 else
116 {
117 append (0xc2);
118 }
119 endValue ();
120 return 0;
121 }
122
128 int setInt (int32_t value)
129 {
130 if (value < -(1 << 15))
131 {
132 append (0xd2);
133 pack (static_cast<uint32_t> (value));
134 }
135 else if (value < -(1 << 7))
136 {
137 append (0xd1);
138 pack (static_cast<uint16_t> (value));
139 }
140 else if (value < -(1 << 5))
141 {
142 append (0xd0);
143 pack (static_cast<uint8_t> (value));
144 }
145 else if (value < (1 << 7))
146 {
147 append (static_cast<uint8_t> (value));
148 }
149 else if (value < (1 << 8))
150 {
151 append (0xcc);
152 pack (static_cast<uint8_t> (value));
153 }
154 else if (value < (1 << 16))
155 {
156 append (0xcd);
157 pack (static_cast<uint16_t> (value));
158 }
159 else
160 {
161 append (0xce);
162 pack (static_cast<uint32_t> (value));
163 }
164 endValue ();
165 return 0;
166 }
167
173 int setUint (uint32_t value)
174 {
175 if (value < (1 << 7))
176 {
177 append (static_cast<uint8_t> (value));
178 }
179 else if (value < (1 << 8))
180 {
181 append (0xcc);
182 pack (static_cast<uint8_t> (value));
183 }
184 else if (value < (1 << 16))
185 {
186 append (0xcd);
187 pack (static_cast<uint16_t> (value));
188 }
189 else
190 {
191 append (0xce);
192 pack (value);
193 }
194 endValue ();
195 return 0;
196 }
197
203 int setInt64 (int64_t value)
204 {
205 if (value < -(1LL << 31))
206 {
207 append (0xd3);
208 pack (static_cast<uint64_t> (value));
209 }
210 else if (value < -(1LL << 15))
211 {
212 append (0xd2);
213 pack (static_cast<uint32_t> (value));
214 }
215 else if (value < -(1LL << 7))
216 {
217 append (0xd1);
218 pack (static_cast<uint16_t> (value));
219 }
220 else if (value < -(1LL << 5))
221 {
222 append (0xd0);
223 pack (static_cast<uint8_t> (value));
224 }
225 else if (value < (1LL << 7))
226 {
227 append (static_cast<uint8_t> (value));
228 }
229 else if (value < (1LL << 8))
230 {
231 append (0xcc);
232 pack (static_cast<uint8_t> (value));
233 }
234 else if (value < (1LL << 16))
235 {
236 append (0xcd);
237 pack (static_cast<uint16_t> (value));
238 }
239 else if (value < (1LL << 32))
240 {
241 append (0xce);
242 pack (static_cast<uint32_t> (value));
243 }
244 else
245 {
246 append (0xcf);
247 pack (static_cast<uint64_t> (value));
248 }
249 endValue ();
250 return 0;
251 }
252
258 int setUint64 (uint64_t value)
259 {
260 if (value < (1ULL << 7))
261 {
262 append (static_cast<uint8_t> (value));
263 }
264 else if (value < (1ULL << 8))
265 {
266 append (0xcc);
267 pack (static_cast<uint8_t> (value));
268 }
269 else if (value < (1ULL << 16))
270 {
271 append (0xcd);
272 pack (static_cast<uint16_t> (value));
273 }
274 else if (value < (1ULL << 32))
275 {
276 append (0xce);
277 pack (static_cast<uint32_t> (value));
278 }
279 else
280 {
281 append (0xcf);
282 pack (value);
283 }
284 endValue ();
285 return 0;
286 }
287
293 int setDouble (double value)
294 {
295 float f = static_cast<float> (value);
296 if (std::isfinite (value) && static_cast<double> (f) == value)
297 {
298 append (0xca);
299 pack (f);
300 }
301 else
302 {
303 append (0xcb);
304 pack (value);
305 }
306 endValue ();
307 return 0;
308 }
309
315 int setString (std::string_view value)
316 {
317 if (value.size () < 32)
318 {
319 append (static_cast<char> (0xa0 | value.size ()));
320 }
321 else if (value.size () < 256)
322 {
323 append (0xd9);
324 pack (static_cast<uint8_t> (value.size ()));
325 }
326 else if (value.size () < 65536)
327 {
328 append (0xda);
329 pack (static_cast<uint16_t> (value.size ()));
330 }
331 else
332 {
333 append (0xdb);
334 pack (static_cast<uint32_t> (value.size ()));
335 }
336 append (value.data (), static_cast<uint32_t> (value.size ()));
337 endValue ();
338 return 0;
339 }
340
346 int startArray (uint32_t size)
347 {
348 if (size < 16)
349 {
350 append (static_cast<char> (0x90 | size));
351 }
352 else if (size < 65536)
353 {
354 append (0xdc);
355 pack (static_cast<uint16_t> (size));
356 }
357 else
358 {
359 append (0xdd);
360 pack (size);
361 }
362 ++_depth;
363 return 0;
364 }
365
371 {
372 if (JOIN_UNLIKELY (_depth == 0))
373 {
375 reset ();
376 return -1;
377 }
378 --_depth;
379 endValue ();
380 return 0;
381 }
382
388 int startObject (uint32_t size)
389 {
390 if (size < 16)
391 {
392 append (static_cast<char> (0x80 | size));
393 }
394 else if (size < 65536)
395 {
396 append (0xde);
397 pack (static_cast<uint16_t> (size));
398 }
399 else
400 {
401 append (0xdf);
402 pack (size);
403 }
404 ++_depth;
405 return 0;
406 }
407
413 const Object& members (const Object& object) const noexcept
414 {
415 return object;
416 }
417
423 int setKey ([[maybe_unused]] std::nullptr_t key)
424 {
425 if (JOIN_UNLIKELY (_depth == 0))
426 {
428 reset ();
429 return -1;
430 }
431 return setNull ();
432 }
433
439 int setKey (bool key)
440 {
441 if (JOIN_UNLIKELY (_depth == 0))
442 {
444 reset ();
445 return -1;
446 }
447 return setBool (key);
448 }
449
455 int setKey (int32_t key)
456 {
457 if (JOIN_UNLIKELY (_depth == 0))
458 {
460 reset ();
461 return -1;
462 }
463 return setInt (key);
464 }
465
471 int setKey (uint32_t key)
472 {
473 if (JOIN_UNLIKELY (_depth == 0))
474 {
476 reset ();
477 return -1;
478 }
479 return setUint (key);
480 }
481
487 int setKey (int64_t key)
488 {
489 if (JOIN_UNLIKELY (_depth == 0))
490 {
492 reset ();
493 return -1;
494 }
495 return setInt64 (key);
496 }
497
503 int setKey (uint64_t key)
504 {
505 if (JOIN_UNLIKELY (_depth == 0))
506 {
508 reset ();
509 return -1;
510 }
511 return setUint64 (key);
512 }
513
519 int setKey (double key)
520 {
521 if (JOIN_UNLIKELY (_depth == 0))
522 {
524 reset ();
525 return -1;
526 }
527 return setDouble (key);
528 }
529
535 int setKey (std::string_view key)
536 {
537 if (JOIN_UNLIKELY (_depth == 0))
538 {
540 reset ();
541 return -1;
542 }
543 return setString (key);
544 }
545
551 int setKey (const char* key)
552 {
553 return setKey (std::string_view (key));
554 }
555
561 {
562 if (JOIN_UNLIKELY (_depth == 0))
563 {
565 reset ();
566 return -1;
567 }
568 --_depth;
569 endValue ();
570 return 0;
571 }
572
576 void flush ()
577 {
578 if (_size)
579 {
580 _out->sputn (_buffer, _size);
581 _size = 0;
582 }
583 }
584
588 void reset () noexcept
589 {
590 _size = 0;
591 _depth = 0;
592 }
593
594 protected:
599 inline void append (char data)
600 {
601 if (JOIN_UNLIKELY (_size == sizeof (_buffer)))
602 {
603 flush ();
604 }
605 _buffer[_size++] = data;
606 }
607
613 inline void append (const char* data, uint32_t size)
614 {
615 if (JOIN_UNLIKELY (size > sizeof (_buffer) - _size))
616 {
617 flush ();
618 if (size >= sizeof (_buffer))
619 {
620 _out->sputn (data, size);
621 return;
622 }
623 }
624 std::memcpy (_buffer + _size, data, size);
625 _size += size;
626 }
627
632 template <typename Type>
633 void pack (Type value)
634 {
635 append (reinterpret_cast<const char*> (&swap (value)), sizeof (value));
636 }
637
641 inline void endValue ()
642 {
643 if (_depth == 0)
644 {
645 flush ();
646 }
647 }
648
650 std::streambuf* _out;
651
653 char _buffer[1024] = {};
654
656 size_t _size = 0;
657
659 size_t _depth = 0;
660 };
661
666 {
667 public:
671 PackReader () = default;
672
677 PackReader (const PackReader& other) = delete;
678
684 PackReader& operator= (const PackReader& other) = delete;
685
690 PackReader (PackReader&& other) = delete;
691
697 PackReader& operator= (PackReader&& other) = delete;
698
702 ~PackReader () = default;
703
711 template <typename Handler>
712 int deserialize (const char* document, size_t length, Handler& handler)
713 {
714 dconv::StringProbe in (document, length);
715 return read (in, handler);
716 }
717
725 template <typename Handler>
726 int deserialize (const char* first, const char* last, Handler& handler)
727 {
728 dconv::StringProbe in (first, last);
729 return read (in, handler);
730 }
731
738 template <typename Handler>
739 int deserialize (std::string_view document, Handler& handler)
740 {
741 dconv::StringProbe in (document.data (), document.size ());
742 return read (in, handler);
743 }
744
751 template <typename Handler>
752 int deserialize (std::stringstream& document, Handler& handler)
753 {
754 dconv::StreamProbe in (document);
755 return read (in, handler);
756 }
757
764 template <typename Handler>
765 int deserialize (std::istringstream& document, Handler& handler)
766 {
767 dconv::StreamProbe in (document);
768 return read (in, handler);
769 }
770
777 template <typename Handler>
778 int deserialize (std::fstream& document, Handler& handler)
779 {
780 dconv::StreamProbe in (document);
781 return read (in, handler);
782 }
783
790 template <typename Handler>
791 int deserialize (std::ifstream& document, Handler& handler)
792 {
793 dconv::StreamProbe in (document);
794 return read (in, handler);
795 }
796
803 template <typename Handler>
804 int deserialize (std::iostream& document, Handler& handler)
805 {
806 dconv::StreamProbe in (document);
807 return read (in, handler);
808 }
809
816 template <typename Handler>
817 int deserialize (std::istream& document, Handler& handler)
818 {
819 dconv::StreamProbe in (document);
820 return read (in, handler);
821 }
822
823 protected:
830 template <typename ProbeType>
831 int read (ProbeType& document, Value& value)
832 {
833 return read (document, ValueBuilder (value));
834 }
835
842 template <typename ProbeType, typename Handler>
843 int read (ProbeType& document, Handler&& handler)
844 {
845 try
846 {
847 if (JOIN_LIKELY (readValue (document, handler, 0) == 0))
848 {
849 if (JOIN_LIKELY (document.peek () == std::char_traits<char>::eof ()))
850 {
851 return 0;
852 }
853
855 }
856 }
857 catch (...)
858 {
859 handler.reset ();
860 throw;
861 }
862 handler.reset ();
863 return -1;
864 }
865
873 template <typename ProbeType, typename Handler>
874 int readValue (ProbeType& document, Handler& handler, size_t depth)
875 {
876 int ch = document.peek ();
877 if (JOIN_UNLIKELY (ch == std::char_traits<char>::eof ()))
878 {
880 return -1;
881 }
882
883 uint8_t head = static_cast<uint8_t> (ch);
884
885 if (isArray (head))
886 {
887 return readArray (document, handler, depth);
888 }
889 else if (isObject (head))
890 {
891 return readObject (document, handler, depth);
892 }
893 else if (isNull (head))
894 {
895 return readNull (document, handler);
896 }
897 else if (isFalse (head))
898 {
899 return readFalse (document, handler);
900 }
901 else if (isTrue (head))
902 {
903 return readTrue (document, handler);
904 }
905 else if (isString (head))
906 {
907 return readString (document, handler);
908 }
909 else if (isBin (head))
910 {
911 return readBin (document, handler);
912 }
913 else if (isNumber (head))
914 {
915 return readNumber (document, handler);
916 }
917 else
918 {
920 return -1;
921 }
922 }
923
931 template <typename ProbeType, typename Handler>
932 int readNull (ProbeType& document, Handler& handler, bool isKey = false)
933 {
934 document.get ();
935 return (isKey) ? handler.setKey (nullptr) : handler.setNull ();
936 }
937
945 template <typename ProbeType, typename Handler>
946 int readFalse (ProbeType& document, Handler& handler, bool isKey = false)
947 {
948 document.get ();
949 return (isKey) ? handler.setKey (false) : handler.setBool (false);
950 }
951
959 template <typename ProbeType, typename Handler>
960 int readTrue (ProbeType& document, Handler& handler, bool isKey = false)
961 {
962 document.get ();
963 return (isKey) ? handler.setKey (true) : handler.setBool (true);
964 }
965
973 template <typename ProbeType, typename Handler>
974 int readArray (ProbeType& document, Handler& handler, size_t depth)
975 {
976 if (JOIN_UNLIKELY (depth == saxMaxDepth))
977 {
979 return -1;
980 }
981
982 uint32_t len = 0;
983
984 if (document.getIf (0xdd))
985 {
986 if (JOIN_UNLIKELY (unpack<uint32_t> (document, len) == -1))
987 {
988 return -1;
989 }
990 }
991 else if (document.getIf (0xdc))
992 {
993 if (JOIN_UNLIKELY (unpack<uint16_t> (document, len) == -1))
994 {
995 return -1;
996 }
997 }
998 else
999 {
1000 len = static_cast<uint8_t> (document.get ()) & ~0x90u;
1001 }
1002
1003 if (JOIN_UNLIKELY (handler.startArray (len) == -1))
1004 {
1005 return -1;
1006 }
1007
1008 while (len)
1009 {
1010 if (JOIN_UNLIKELY (readValue (document, handler, depth + 1) == -1))
1011 {
1012 return -1;
1013 }
1014
1015 --len;
1016 }
1017
1018 return handler.stopArray ();
1019 }
1020
1028 template <typename ProbeType, typename Handler>
1029 int readObject (ProbeType& document, Handler& handler, size_t depth)
1030 {
1031 if (JOIN_UNLIKELY (depth == saxMaxDepth))
1032 {
1034 return -1;
1035 }
1036
1037 uint32_t len = 0;
1038
1039 if (document.getIf (0xdf))
1040 {
1041 if (JOIN_UNLIKELY (unpack<uint32_t> (document, len) == -1))
1042 {
1043 return -1;
1044 }
1045 }
1046 else if (document.getIf (0xde))
1047 {
1048 if (JOIN_UNLIKELY (unpack<uint16_t> (document, len) == -1))
1049 {
1050 return -1;
1051 }
1052 }
1053 else
1054 {
1055 len = static_cast<uint8_t> (document.get ()) & ~0x80u;
1056 }
1057
1058 if (JOIN_UNLIKELY (handler.startObject (len) == -1))
1059 {
1060 return -1;
1061 }
1062
1063 while (len)
1064 {
1065 if (JOIN_UNLIKELY (readKey (document, handler) == -1))
1066 {
1067 return -1;
1068 }
1069
1070 if (JOIN_UNLIKELY (readValue (document, handler, depth + 1) == -1))
1071 {
1072 return -1;
1073 }
1074
1075 --len;
1076 }
1077
1078 return handler.stopObject ();
1079 }
1080
1087 template <typename ProbeType, typename Handler>
1088 int readKey (ProbeType& document, Handler& handler)
1089 {
1090 int ch = document.peek ();
1091 if (JOIN_UNLIKELY (ch == std::char_traits<char>::eof ()))
1092 {
1094 return -1;
1095 }
1096
1097 uint8_t head = static_cast<uint8_t> (ch);
1098
1099 if (isNull (head))
1100 {
1101 return readNull (document, handler, true);
1102 }
1103 else if (isFalse (head))
1104 {
1105 return readFalse (document, handler, true);
1106 }
1107 else if (isTrue (head))
1108 {
1109 return readTrue (document, handler, true);
1110 }
1111 else if (isString (head))
1112 {
1113 return readString (document, handler, true);
1114 }
1115 else if (isNumber (head))
1116 {
1117 return readNumber (document, handler, true);
1118 }
1119 else
1120 {
1122 return -1;
1123 }
1124 }
1125
1133 template <typename ProbeType, typename Handler>
1134 int readString (ProbeType& document, Handler& handler, bool isKey = false)
1135 {
1136 uint32_t len = 0;
1137
1138 if (document.getIf (0xdb))
1139 {
1140 if (JOIN_UNLIKELY (unpack<uint32_t> (document, len) == -1))
1141 {
1142 return -1;
1143 }
1144 }
1145 else if (document.getIf (0xda))
1146 {
1147 if (JOIN_UNLIKELY (unpack<uint16_t> (document, len) == -1))
1148 {
1149 return -1;
1150 }
1151 }
1152 else if (document.getIf (0xd9))
1153 {
1154 if (JOIN_UNLIKELY (unpack<uint8_t> (document, len) == -1))
1155 {
1156 return -1;
1157 }
1158 }
1159 else
1160 {
1161 len = static_cast<uint8_t> (document.get ()) & ~0xa0u;
1162 }
1163
1164 thread_local std::string cache;
1165 std::string output = std::move (cache);
1166 output.clear ();
1167 if (JOIN_UNLIKELY (readBytes (document, len, output) == -1))
1168 {
1169 return -1;
1170 }
1171
1172 int result = isKey ? handler.setKey (output) : handler.setString (output);
1173 cache = std::move (output);
1174 return result;
1175 }
1176
1183 template <typename ProbeType, typename Handler>
1184 int readBin (ProbeType& document, Handler& handler)
1185 {
1186 uint32_t len = 0;
1187
1188 if (document.getIf (0xc6))
1189 {
1190 if (JOIN_UNLIKELY (unpack<uint32_t> (document, len) == -1))
1191 {
1192 return -1;
1193 }
1194 }
1195 else if (document.getIf (0xc5))
1196 {
1197 if (JOIN_UNLIKELY (unpack<uint16_t> (document, len) == -1))
1198 {
1199 return -1;
1200 }
1201 }
1202 else if (document.getIf (0xc4))
1203 {
1204 if (JOIN_UNLIKELY (unpack<uint8_t> (document, len) == -1))
1205 {
1206 return -1;
1207 }
1208 }
1209
1210 thread_local std::string cache;
1211 std::string output = std::move (cache);
1212 output.clear ();
1213 if (JOIN_UNLIKELY (readBytes (document, len, output) == -1))
1214 {
1215 return -1;
1216 }
1217
1218 int result = handler.setString (output);
1219 cache = std::move (output);
1220 return result;
1221 }
1222
1230 template <typename ProbeType, typename Handler>
1231 int readNumber (ProbeType& document, Handler& handler, bool isKey = false)
1232 {
1233 uint8_t head = document.get ();
1234
1235 if (head <= 0x7f)
1236 {
1237 auto number = uint32_t (head);
1238 return isKey ? handler.setKey (number) : handler.setUint (number);
1239 }
1240 else if (head >= 0xe0)
1241 {
1242 auto number = int32_t (static_cast<int8_t> (head));
1243 return isKey ? handler.setKey (number) : handler.setInt (number);
1244 }
1245 else if (head == 0xd3)
1246 {
1247 int64_t number;
1248 if (JOIN_UNLIKELY (unpack<int64_t> (document, number) == -1))
1249 {
1250 return -1;
1251 }
1252 return isKey ? handler.setKey (number) : handler.setInt64 (number);
1253 }
1254 else if (head == 0xcf)
1255 {
1256 uint64_t number;
1257 if (JOIN_UNLIKELY (unpack<uint64_t> (document, number) == -1))
1258 {
1259 return -1;
1260 }
1261 return isKey ? handler.setKey (number) : handler.setUint64 (number);
1262 }
1263 else if (head == 0xcb)
1264 {
1265 double number;
1266 if (JOIN_UNLIKELY (unpack<double> (document, number) == -1))
1267 {
1268 return -1;
1269 }
1270 return isKey ? handler.setKey (number) : handler.setDouble (number);
1271 }
1272 else if (head == 0xd2)
1273 {
1274 int32_t number;
1275 if (JOIN_UNLIKELY (unpack<int32_t> (document, number) == -1))
1276 {
1277 return -1;
1278 }
1279 return isKey ? handler.setKey (number) : handler.setInt (number);
1280 }
1281 else if (head == 0xce)
1282 {
1283 uint32_t number;
1284 if (JOIN_UNLIKELY (unpack<uint32_t> (document, number) == -1))
1285 {
1286 return -1;
1287 }
1288 return isKey ? handler.setKey (number) : handler.setUint (number);
1289 }
1290 else if (head == 0xca)
1291 {
1292 double number;
1293 if (JOIN_UNLIKELY (unpack<float> (document, number) == -1))
1294 {
1295 return -1;
1296 }
1297 return isKey ? handler.setKey (number) : handler.setDouble (number);
1298 }
1299 else if (head == 0xd1)
1300 {
1301 int32_t number;
1302 if (JOIN_UNLIKELY (unpack<int16_t> (document, number) == -1))
1303 {
1304 return -1;
1305 }
1306 return isKey ? handler.setKey (number) : handler.setInt (number);
1307 }
1308 else if (head == 0xcd)
1309 {
1310 uint32_t number;
1311 if (JOIN_UNLIKELY (unpack<uint16_t> (document, number) == -1))
1312 {
1313 return -1;
1314 }
1315 return isKey ? handler.setKey (number) : handler.setUint (number);
1316 }
1317 else if (head == 0xd0)
1318 {
1319 int32_t number;
1320 if (JOIN_UNLIKELY (unpack<int8_t> (document, number) == -1))
1321 {
1322 return -1;
1323 }
1324 return isKey ? handler.setKey (number) : handler.setInt (number);
1325 }
1326 else if (head == 0xcc)
1327 {
1328 uint32_t number;
1329 if (JOIN_UNLIKELY (unpack<uint8_t> (document, number) == -1))
1330 {
1331 return -1;
1332 }
1333 return isKey ? handler.setKey (number) : handler.setUint (number);
1334 }
1335 else
1336 {
1337 // LCOV_EXCL_START
1339 return -1;
1340 // LCOV_EXCL_STOP
1341 }
1342 }
1343
1351 template <typename ProbeType>
1352 static int readBytes (ProbeType& document, uint32_t len, std::string& output)
1353 {
1354 while (len)
1355 {
1356 size_t pos = output.size ();
1357 size_t chunk = std::min<size_t> (len, 65536);
1358 output.resize (pos + chunk);
1359 if (JOIN_UNLIKELY (document.read (&output[pos], chunk) != chunk))
1360 {
1362 return -1;
1363 }
1364 len -= chunk;
1365 }
1366 return 0;
1367 }
1368
1375 template <typename Type, typename ProbeType, typename Output>
1376 static int unpack (ProbeType& document, Output& output)
1377 requires std::is_arithmetic_v<Type>
1378 {
1379 Type value;
1380 if (JOIN_UNLIKELY (document.read (reinterpret_cast<char*> (&value), sizeof (value)) != sizeof (value)))
1381 {
1383 return -1;
1384 }
1385 output = static_cast<Output> (swap (value));
1386 return 0;
1387 }
1388
1394 constexpr bool isNull (uint8_t c)
1395 {
1396 return (c == 0xc0);
1397 }
1398
1404 constexpr bool isFalse (uint8_t c)
1405 {
1406 return (c == 0xc2);
1407 }
1408
1414 constexpr bool isTrue (uint8_t c)
1415 {
1416 return (c == 0xc3);
1417 }
1418
1424 constexpr bool isInt (uint8_t c)
1425 {
1426 return ((c <= 0x7f) || (c >= 0xe0)) || (c == 0xd0) || (c == 0xd1) || (c == 0xd2);
1427 }
1428
1434 constexpr bool isUint (uint8_t c)
1435 {
1436 return (c == 0xcc) || (c == 0xcd) || (c == 0xce);
1437 }
1438
1444 constexpr bool isInt64 (uint8_t c)
1445 {
1446 return (c == 0xd3);
1447 }
1448
1454 constexpr bool isUint64 (uint8_t c)
1455 {
1456 return (c == 0xcf);
1457 }
1458
1464 constexpr bool isReal (uint8_t c)
1465 {
1466 return (c == 0xca) || (c == 0xcb);
1467 }
1468
1474 constexpr bool isNumber (uint8_t c)
1475 {
1476 return isInt (c) || isUint (c) || isInt64 (c) || isUint64 (c) || isReal (c);
1477 }
1478
1484 constexpr bool isString (uint8_t c)
1485 {
1486 return ((c >= 0xa0) && (c <= 0xbf)) || (c == 0xd9) || (c == 0xda) || (c == 0xdb);
1487 }
1488
1494 constexpr bool isBin (uint8_t c)
1495 {
1496 return (c == 0xc4) || (c == 0xc5) || (c == 0xc6);
1497 }
1498
1504 constexpr bool isArray (uint8_t c)
1505 {
1506 return ((c >= 0x90) && (c <= 0x9f)) || (c == 0xdc) || (c == 0xdd);
1507 }
1508
1514 constexpr bool isObject (uint8_t c)
1515 {
1516 return ((c >= 0x80) && (c <= 0x8f)) || (c == 0xde) || (c == 0xdf);
1517 }
1518 };
1519}
1520
1521#endif
message pack reader class.
Definition pack.hpp:666
int readTrue(ProbeType &document, Handler &handler, bool isKey=false)
parse a true value.
Definition pack.hpp:960
constexpr bool isString(uint8_t c)
check if string.
Definition pack.hpp:1484
PackReader & operator=(const PackReader &other)=delete
copy assignment.
constexpr bool isInt64(uint8_t c)
check if 64 bits integer.
Definition pack.hpp:1444
int deserialize(std::stringstream &document, Handler &handler)
deserialize a document.
Definition pack.hpp:752
constexpr bool isInt(uint8_t c)
check if 32 bits integer.
Definition pack.hpp:1424
constexpr bool isNull(uint8_t c)
check if null.
Definition pack.hpp:1394
int deserialize(const char *first, const char *last, Handler &handler)
deserialize a document.
Definition pack.hpp:726
int deserialize(std::istream &document, Handler &handler)
deserialize a document.
Definition pack.hpp:817
int deserialize(std::iostream &document, Handler &handler)
deserialize a document.
Definition pack.hpp:804
PackReader(const PackReader &other)=delete
copy constructor.
int deserialize(std::string_view document, Handler &handler)
deserialize a document.
Definition pack.hpp:739
static int unpack(ProbeType &document, Output &output)
unpack value from stream.
Definition pack.hpp:1376
int readValue(ProbeType &document, Handler &handler, size_t depth)
parse value.
Definition pack.hpp:874
constexpr bool isTrue(uint8_t c)
check if true.
Definition pack.hpp:1414
int read(ProbeType &document, Handler &&handler)
parse a document, resetting the handler on failure.
Definition pack.hpp:843
constexpr bool isObject(uint8_t c)
check if object.
Definition pack.hpp:1514
int readObject(ProbeType &document, Handler &handler, size_t depth)
parse an object value.
Definition pack.hpp:1029
~PackReader()=default
destroy instance.
int readFalse(ProbeType &document, Handler &handler, bool isKey=false)
parse a false value.
Definition pack.hpp:946
int deserialize(std::fstream &document, Handler &handler)
deserialize a document.
Definition pack.hpp:778
int readBin(ProbeType &document, Handler &handler)
parse binary data.
Definition pack.hpp:1184
int readNumber(ProbeType &document, Handler &handler, bool isKey=false)
parse a number value.
Definition pack.hpp:1231
int deserialize(std::ifstream &document, Handler &handler)
deserialize a document.
Definition pack.hpp:791
constexpr bool isUint(uint8_t c)
check if unsigned 32 bits integer.
Definition pack.hpp:1434
int readString(ProbeType &document, Handler &handler, bool isKey=false)
parse a string value.
Definition pack.hpp:1134
static int readBytes(ProbeType &document, uint32_t len, std::string &output)
read bytes by chunks.
Definition pack.hpp:1352
constexpr bool isUint64(uint8_t c)
check if unsigned 64 bits integer.
Definition pack.hpp:1454
int deserialize(std::istringstream &document, Handler &handler)
deserialize a document.
Definition pack.hpp:765
int read(ProbeType &document, Value &value)
parse a document into a value.
Definition pack.hpp:831
constexpr bool isFalse(uint8_t c)
check if false.
Definition pack.hpp:1404
constexpr bool isReal(uint8_t c)
check if real.
Definition pack.hpp:1464
PackReader()=default
default constructor.
PackReader(PackReader &&other)=delete
move constructor.
int readKey(ProbeType &document, Handler &handler)
parse a key of any type.
Definition pack.hpp:1088
int deserialize(const char *document, size_t length, Handler &handler)
deserialize a document.
Definition pack.hpp:712
constexpr bool isNumber(uint8_t c)
check if number.
Definition pack.hpp:1474
constexpr bool isBin(uint8_t c)
check if binary data.
Definition pack.hpp:1494
int readNull(ProbeType &document, Handler &handler, bool isKey=false)
parse a null value.
Definition pack.hpp:932
constexpr bool isArray(uint8_t c)
check if array.
Definition pack.hpp:1504
int readArray(ProbeType &document, Handler &handler, size_t depth)
parse an array value.
Definition pack.hpp:974
message pack writer class.
Definition pack.hpp:51
size_t _size
output buffer size.
Definition pack.hpp:656
int setKey(int32_t key)
set integer key.
Definition pack.hpp:455
int setKey(uint32_t key)
set unsigned integer key.
Definition pack.hpp:471
PackWriter(std::ostream &document)
create instance.
Definition pack.hpp:57
int setKey(const char *key)
set string key.
Definition pack.hpp:551
int setInt(int32_t value)
set integer value.
Definition pack.hpp:128
int setNull()
set null value.
Definition pack.hpp:97
int stopArray()
stop array.
Definition pack.hpp:370
~PackWriter()=default
destroy instance.
int setKey(std::string_view key)
set string key.
Definition pack.hpp:535
int setUint(uint32_t value)
set unsigned integer value.
Definition pack.hpp:173
int startObject(uint32_t size)
start object.
Definition pack.hpp:388
std::streambuf * _out
underlying output stream.
Definition pack.hpp:650
int startArray(uint32_t size)
start array.
Definition pack.hpp:346
int setKey(bool key)
set boolean key.
Definition pack.hpp:439
int setKey(double key)
set real key.
Definition pack.hpp:519
int setInt64(int64_t value)
set 64 bits integer value.
Definition pack.hpp:203
int setKey(std::nullptr_t key)
set null key.
Definition pack.hpp:423
void append(char data)
append character to output stream in batch.
Definition pack.hpp:599
void pack(Type value)
pack value into stream.
Definition pack.hpp:633
PackWriter & operator=(const PackWriter &other)=delete
copy assignment.
void append(const char *data, uint32_t size)
append data to output stream in batch.
Definition pack.hpp:613
void endValue()
mark the end of a value, flushing the document once complete.
Definition pack.hpp:641
int setBool(bool value)
set boolean value.
Definition pack.hpp:109
int setString(std::string_view value)
set string value.
Definition pack.hpp:315
PackWriter(PackWriter &&other)=delete
move constructor.
int setDouble(double value)
set real value.
Definition pack.hpp:293
int setKey(uint64_t key)
set unsigned 64 bits integer key.
Definition pack.hpp:503
char _buffer[1024]
output buffer.
Definition pack.hpp:653
int setKey(int64_t key)
set 64 bits integer key.
Definition pack.hpp:487
PackWriter(const PackWriter &other)=delete
copy constructor.
void reset() noexcept
reset the writer state, discarding buffered data.
Definition pack.hpp:588
size_t _depth
number of open containers.
Definition pack.hpp:659
void flush()
flush buffered data to output stream.
Definition pack.hpp:576
int stopObject()
stop object.
Definition pack.hpp:560
int setUint64(uint64_t value)
set unsigned 64 bits integer value.
Definition pack.hpp:258
const Object & members(const Object &object) const noexcept
get object members in writing order.
Definition pack.hpp:413
value builder class, filled by balanced SAX calls.
Definition value_builder.hpp:49
value class.
Definition value.hpp:92
const std::string key(65, 'a')
key.
Definition acceptor.hpp:32
Type & swap(Type &val)
swaps byte orders.
Definition utils.hpp:86
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
constexpr size_t saxMaxDepth
max number of nested containers.
Definition sax.hpp:42
thread_local std::error_code lastError
last error.
Definition error.cpp:32
std::vector< Member > Object
object.
Definition value.hpp:86
#define JOIN_LIKELY(x)
Definition utils.hpp:50
#define JOIN_UNLIKELY(x)
Definition utils.hpp:51