join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
pack.hpp
Go to the documentation of this file.
1
25#ifndef __JOIN_PACK_HPP__
26#define __JOIN_PACK_HPP__
27
28// libjoin.
29#include <join/utils.hpp>
30#include <join/sax.hpp>
31
32// C++.
33#include <stdexcept>
34
35namespace join
36{
40 class PackWriter : public StreamWriter
41 {
42 public:
47 PackWriter (std::ostream& document)
48 : StreamWriter (document)
49 {
50 }
51
56 PackWriter (const PackWriter& other) = delete;
57
63 PackWriter& operator= (const PackWriter& other) = delete;
64
69 PackWriter (PackWriter&& other) = delete;
70
76 PackWriter& operator= (PackWriter&& other) = delete;
77
81 virtual ~PackWriter () = default;
82
87 virtual int setNull () override
88 {
89 append (0xc0);
90 return 0;
91 }
92
98 virtual int setBool (bool value) override
99 {
100 if (value)
101 {
102 append (0xc3);
103 }
104 else
105 {
106 append (0xc2);
107 }
108 return 0;
109 }
110
116 virtual int setInt (int32_t value) override
117 {
118 if (value < -(1 << 15))
119 {
120 append (0xd2);
121 pack (static_cast <uint32_t> (value));
122 }
123 else if (value < -(1 << 7))
124 {
125 append (0xd1);
126 pack (static_cast <uint16_t> (value));
127 }
128 else if (value < -(1 << 5))
129 {
130 append (0xd0);
131 pack (static_cast <uint8_t> (value));
132 }
133 else if (value < (1 << 7))
134 {
135 append (static_cast <uint8_t> (value));
136 }
137 else if (value < (1 << 8))
138 {
139 append (0xcc);
140 pack (static_cast <uint8_t> (value));
141 }
142 else if (value < (1 << 16))
143 {
144 append (0xcd);
145 pack (static_cast <uint16_t> (value));
146 }
147 else
148 {
149 append (0xce);
150 pack (static_cast <uint32_t> (value));
151 }
152 return 0;
153 }
154
160 virtual int setUint (uint32_t value) override
161 {
162 if (value < (1 << 7))
163 {
164 append (static_cast <uint8_t> (value));
165 }
166 else if (value < (1 << 8))
167 {
168 append (0xcc);
169 pack (static_cast <uint8_t> (value));
170 }
171 else if (value < (1 << 16))
172 {
173 append (0xcd);
174 pack (static_cast <uint16_t> (value));
175 }
176 else
177 {
178 append (0xce);
179 pack (value);
180 }
181 return 0;
182 }
183
189 virtual int setInt64 (int64_t value) override
190 {
191 if (value < -(1LL << 31))
192 {
193 append (0xd3);
194 pack (static_cast <uint64_t> (value));
195 }
196 else if (value < -(1LL << 15))
197 {
198 append (0xd2);
199 pack (static_cast <uint32_t> (value));
200 }
201 else if (value < -(1LL << 7))
202 {
203 append (0xd1);
204 pack (static_cast <uint16_t> (value));
205 }
206 else if (value < -(1LL << 5))
207 {
208 append (0xd0);
209 pack (static_cast <uint8_t> (value));
210 }
211 else if (value < (1LL << 7))
212 {
213 append (static_cast <uint8_t> (value));
214 }
215 else if (value < (1LL << 8))
216 {
217 append (0xcc);
218 pack (static_cast <uint8_t> (value));
219 }
220 else if (value < (1LL << 16))
221 {
222 append (0xcd);
223 pack (static_cast <uint16_t> (value));
224 }
225 else if (value < (1LL << 32))
226 {
227 append (0xce);
228 pack (static_cast <uint32_t> (value));
229 }
230 else
231 {
232 append (0xcf);
233 pack (static_cast <uint64_t> (value));
234 }
235 return 0;
236 }
237
243 virtual int setUint64 (uint64_t value) override
244 {
245 if (value < (1ULL << 7))
246 {
247 append (static_cast <uint8_t> (value));
248 }
249 else if (value < (1ULL << 8))
250 {
251 append (0xcc);
252 pack (static_cast <uint8_t> (value));
253 }
254 else if (value < (1ULL << 16))
255 {
256 append (0xcd);
257 pack (static_cast <uint16_t> (value));
258 }
259 else if (value < (1ULL << 32))
260 {
261 append (0xce);
262 pack (static_cast <uint32_t> (value));
263 }
264 else
265 {
266 append (0xcf);
267 pack (value);
268 }
269 return 0;
270 }
271
277 virtual int setDouble (double value) override
278 {
279 append (0xcb);
280 pack (value);
281 return 0;
282 }
283
289 virtual int setString (const std::string& value) override
290 {
291 if (value.size () < 32)
292 {
293 append (static_cast <char> (0xa0 | value.size ()));
294 }
295 else if (value.size () < 256)
296 {
297 append (0xd9);
298 pack (static_cast <uint8_t> (value.size ()));
299 }
300 else if (value.size () < 65536)
301 {
302 append (0xda);
303 pack (static_cast <uint16_t> (value.size ()));
304 }
305 else
306 {
307 append (0xdb);
308 pack (static_cast <uint32_t> (value.size ()));
309 }
310 append (value.c_str (), value.size ());
311 return 0;
312 }
313
319 virtual int startArray (uint32_t size = 0) override
320 {
321 if (size < 16)
322 {
323 append (static_cast <char> (0x90 | size));
324 }
325 else if (size < 65536)
326 {
327 append (0xdc);
328 pack (static_cast <uint16_t> (size));
329 }
330 else
331 {
332 append (0xdd);
333 pack (size);
334 }
335 return 0;
336 }
337
343 virtual int startObject (uint32_t size = 0) override
344 {
345 if (size < 16)
346 {
347 append (static_cast <char> (0x80 | size));
348 }
349 else if (size < 65536)
350 {
351 append (0xde);
352 pack (static_cast <uint16_t> (size));
353 }
354 else
355 {
356 append (0xdf);
357 pack (size);
358 }
359 return 0;
360 }
361
367 virtual int setKey (const std::string& key) override
368 {
369 return setString (key);
370 }
371
372 protected:
377 template <typename Type>
378 void pack (Type value)
379 {
380 append (reinterpret_cast <const char *> (&swap (value)), sizeof (value));
381 }
382 };
383
388 {
389 public:
395 : StreamReader (root)
396 {
397 }
398
403 PackReader (const PackReader& other) = delete;
404
410 PackReader& operator= (const PackReader& other) = delete;
411
416 PackReader (PackReader&& other) = delete;
417
423 PackReader& operator= (PackReader&& other) = delete;
424
428 virtual ~PackReader () = default;
429
436 int deserialize (const char* document, size_t length) override
437 {
438 StringView in (document, length);
439 return read (in);
440 }
441
448 int deserialize (const char* first, const char* last) override
449 {
450 StringView in (first, last);
451 return read (in);
452 }
453
459 int deserialize (const std::string& document) override
460 {
461 StringView in (document.c_str (), document.size ());
462 return read (in);
463 }
464
470 int deserialize (std::stringstream& document) override
471 {
472 StringStreamView in (document);
473 return read (in);
474 }
475
481 int deserialize (std::istringstream& document) override
482 {
483 StringStreamView in (document);
484 return read (in);
485 }
486
492 int deserialize (std::fstream& document) override
493 {
494 FileStreamView in (document);
495 return read (in);
496 }
497
503 int deserialize (std::ifstream& document) override
504 {
505 FileStreamView in (document);
506 return read (in);
507 }
508
514 int deserialize (std::iostream& document) override
515 {
516 StreamView in (document);
517 return read (in);
518 }
519
525 int deserialize (std::istream& document) override
526 {
527 StreamView in (document);
528 return read (in);
529 }
530
531 protected:
537 template <typename ViewType>
538 int read (ViewType& document)
539 {
540 if (JOIN_LIKELY (readValue (document) == 0))
541 {
542 if (JOIN_LIKELY (document.peek () == std::char_traits <char>::eof ()))
543 {
544 return 0;
545 }
546
548 }
549
550 return -1;
551 }
552
558 template <typename ViewType>
559 int readValue (ViewType& document)
560 {
561 uint8_t head = static_cast <uint8_t> (document.peek ());
562
563 try
564 {
565 if (isArray (head))
566 {
567 return readArray (document);
568 }
569 else if (isObject (head))
570 {
571 return readObject (document);
572 }
573 else if (isNull (head))
574 {
575 return readNull (document);
576 }
577 else if (isFalse (head))
578 {
579 return readFalse (document);
580 }
581 else if (isTrue (head))
582 {
583 return readTrue (document);
584 }
585 else if (isString (head))
586 {
587 return readString (document);
588 }
589 else if (isBin (head))
590 {
591 return readBin (document);
592 }
593 else if (isNumber (head))
594 {
595 return readNumber (document);
596 }
597 else
598 {
600 return -1;
601 }
602 }
603 catch (...)
604 {
606 return -1;
607 }
608
609 return 0;
610 }
611
617 template <typename ViewType>
618 int readNull (ViewType& document)
619 {
620 document.get ();
621 return setNull ();
622 }
623
629 template <typename ViewType>
630 int readFalse (ViewType& document)
631 {
632 document.get ();
633 return setBool (false);
634 }
635
641 template <typename ViewType>
642 int readTrue (ViewType& document)
643 {
644 document.get ();
645 return setBool (true);
646 }
647
653 template <typename ViewType>
654 int readArray (ViewType& document)
655 {
656 uint32_t len = 0;
657
658 if (document.getIf (0xdd))
659 {
660 len = unpack <uint32_t> (document);
661 }
662 else if (document.getIf (0xdc))
663 {
664 len = unpack <uint16_t> (document);
665 }
666 else
667 {
668 len = unpack <uint8_t> (document) & ~0x90;
669 }
670
671 if (JOIN_UNLIKELY (startArray (len) == -1))
672 {
673 return -1;
674 }
675
676 while (len)
677 {
678 if (JOIN_UNLIKELY (readValue (document) == -1))
679 {
680 return -1;
681 }
682
683 --len;
684 }
685
686 return stopArray ();
687 }
688
694 template <typename ViewType>
695 int readObject (ViewType& document)
696 {
697 uint32_t len = 0;
698
699 if (document.getIf (0xdf))
700 {
701 len = unpack <uint32_t> (document);
702 }
703 else if (document.getIf (0xde))
704 {
705 len = unpack <uint16_t> (document);
706 }
707 else
708 {
709 len = unpack <uint8_t> (document) & ~0x80;
710 }
711
712 if (JOIN_UNLIKELY (startObject (len) == -1))
713 {
714 return -1;
715 }
716
717 while (len)
718 {
719 if (JOIN_UNLIKELY (readString (document, true) == -1))
720 {
721 return -1;
722 }
723
724 if (JOIN_UNLIKELY (readValue (document) == -1))
725 {
726 return -1;
727 }
728
729 --len;
730 }
731
732 return stopObject ();
733 }
734
741 template <typename ViewType>
742 int readString (ViewType& document, bool isKey = false)
743 {
744 uint32_t len = 0;
745
746 if (document.getIf (0xdb))
747 {
748 len = unpack <uint32_t> (document);
749 }
750 else if (document.getIf (0xda))
751 {
752 len = unpack <uint16_t> (document);
753 }
754 else if (document.getIf (0xd9))
755 {
756 len = unpack <uint8_t> (document);
757 }
758 else
759 {
760 len = unpack <uint8_t> (document) & ~0xa0;
761 }
762
763 std::string output;
764 output.resize (len);
765
766 if (JOIN_UNLIKELY (document.read (&output[0], len) != len))
767 {
769 return -1;
770 }
771
772 return isKey ? setKey (output) : setString (output);
773 }
774
780 template <typename ViewType>
781 int readBin (ViewType& document)
782 {
783 uint32_t len = 0;
784
785 if (document.getIf (0xc6))
786 {
787 len = unpack <uint32_t> (document);
788 }
789 else if (document.getIf (0xc5))
790 {
791 len = unpack <uint16_t> (document);
792 }
793 else if (document.getIf (0xc4))
794 {
795 len = unpack <uint8_t> (document);
796 }
797
798 std::string output;
799 output.resize (len);
800
801 if (JOIN_UNLIKELY (document.read (&output[0], len) != len))
802 {
804 return -1;
805 }
806
807 return setString (output);
808 }
809
815 template <typename ViewType>
816 int readNumber (ViewType& document)
817 {
818 if (document.getIf (0xd3))
819 {
820 return setInt64 (unpack <int64_t> (document));
821 }
822 else if (document.getIf (0xcf))
823 {
824 return setUint64 (unpack <uint64_t> (document));
825 }
826 else if (document.getIf (0xcb))
827 {
828 return setDouble (unpack <double> (document));
829 }
830 else if (document.getIf (0xd2))
831 {
832 return setInt (unpack <int32_t> (document));
833 }
834 else if (document.getIf (0xce))
835 {
836 return setUint (unpack <uint32_t> (document));
837 }
838 else if (document.getIf (0xca))
839 {
840 return setDouble (unpack <float> (document));
841 }
842 else if (document.getIf (0xd1))
843 {
844 return setInt (unpack <int16_t> (document));
845 }
846 else if (document.getIf (0xcd))
847 {
848 return setUint (unpack <uint16_t> (document));
849 }
850 else if (document.getIf (0xd0))
851 {
852 return setInt (unpack <int8_t> (document));
853 }
854 else if (document.getIf (0xcc))
855 {
856 return setUint (unpack <uint8_t> (document));
857 }
858
859 return setInt (document.get ());
860 }
861
867 template <typename Type, typename ViewType>
868 std::enable_if_t <std::is_arithmetic <Type>::value, Type>
869 static unpack (ViewType& document)
870 {
871 Type value;
872 if (JOIN_UNLIKELY (document.read (reinterpret_cast <char *> (&value), sizeof (value)) != sizeof (value)))
873 {
874 throw std::range_error ("not enough data to unpack");
875 }
876 return swap (value);
877 }
878
884 constexpr bool isNull (uint8_t c)
885 {
886 return (c == 0xc0);
887 }
888
894 constexpr bool isFalse (uint8_t c)
895 {
896 return (c == 0xc2);
897 }
898
904 constexpr bool isTrue (uint8_t c)
905 {
906 return (c == 0xc3);
907 }
908
914 constexpr bool isInt (uint8_t c)
915 {
916 return ((c <= 0x7f) || (c >= 0xe0)) || (c == 0xd0) || (c == 0xd1) || (c == 0xd2) || (c == 0xd3);
917 }
918
924 constexpr bool isUint (uint8_t c)
925 {
926 return (c == 0xcc) || (c == 0xcd) || (c == 0xce);
927 }
928
934 constexpr bool isInt64 (uint8_t c)
935 {
936 return (c == 0xd3);
937 }
938
944 constexpr bool isUint64 (uint8_t c)
945 {
946 return (c == 0xcf);
947 }
948
954 constexpr bool isReal (uint8_t c)
955 {
956 return (c == 0xca) || (c == 0xcb);
957 }
958
964 constexpr bool isNumber (uint8_t c)
965 {
966 return isInt (c) || isUint (c) || isInt64 (c) || isUint64 (c) || isReal (c);
967 }
968
974 constexpr bool isString (uint8_t c)
975 {
976 return ((c >= 0xa0) && (c <= 0xbf)) || (c == 0xd9) || (c == 0xda) || (c == 0xdb);
977 }
978
984 constexpr bool isBin (uint8_t c)
985 {
986 return (c == 0xc4) || (c == 0xc5) || (c == 0xc6);
987 }
988
994 constexpr bool isArray (uint8_t c)
995 {
996 return ((c >= 0x90) && (c <= 0x9f)) || (c == 0xdc) || (c == 0xdd);
997 }
998
1004 constexpr bool isObject (uint8_t c)
1005 {
1006 return ((c >= 0x80) && (c <= 0x8f)) || (c == 0xde) || (c == 0xdf);
1007 }
1008 };
1009}
1010
1011#endif
basic stream view.
Definition view.hpp:368
message pack reader class.
Definition pack.hpp:388
constexpr bool isString(uint8_t c)
check if string.
Definition pack.hpp:974
int deserialize(std::ifstream &document) override
deserialize a document.
Definition pack.hpp:503
int readValue(ViewType &document)
parse value.
Definition pack.hpp:559
PackReader & operator=(const PackReader &other)=delete
copy assignment.
constexpr bool isInt64(uint8_t c)
check if 64 bits integer.
Definition pack.hpp:934
int deserialize(const char *document, size_t length) override
deserialize a document.
Definition pack.hpp:436
constexpr bool isInt(uint8_t c)
check if 32 bits integer.
Definition pack.hpp:914
constexpr bool isNull(uint8_t c)
check if null.
Definition pack.hpp:884
PackReader(const PackReader &other)=delete
copy constructor.
int deserialize(std::fstream &document) override
deserialize a document.
Definition pack.hpp:492
constexpr bool isTrue(uint8_t c)
check if true.
Definition pack.hpp:904
int read(ViewType &document)
parse a document.
Definition pack.hpp:538
int deserialize(const char *first, const char *last) override
deserialize a document.
Definition pack.hpp:448
int deserialize(std::iostream &document) override
deserialize a document.
Definition pack.hpp:514
int deserialize(std::stringstream &document) override
deserialize a document.
Definition pack.hpp:470
constexpr bool isObject(uint8_t c)
check if object.
Definition pack.hpp:1004
int readNull(ViewType &document)
parse a null value.
Definition pack.hpp:618
int readArray(ViewType &document)
parse an array value.
Definition pack.hpp:654
virtual ~PackReader()=default
destroy instance.
constexpr bool isUint(uint8_t c)
check if unsigned 32 bits integer.
Definition pack.hpp:924
int readTrue(ViewType &document)
parse a true value.
Definition pack.hpp:642
int readNumber(ViewType &document)
parse a number value.
Definition pack.hpp:816
constexpr bool isUint64(uint8_t c)
check if unsigned 64 bits integer.
Definition pack.hpp:944
constexpr bool isFalse(uint8_t c)
check if false.
Definition pack.hpp:894
constexpr bool isReal(uint8_t c)
check if real.
Definition pack.hpp:954
int deserialize(std::istringstream &document) override
deserialize a document.
Definition pack.hpp:481
PackReader(PackReader &&other)=delete
move constructor.
int readFalse(ViewType &document)
parse a false value.
Definition pack.hpp:630
static std::enable_if_t< std::is_arithmetic< Type >::value, Type > unpack(ViewType &document)
unpack value from stream.
Definition pack.hpp:869
int readObject(ViewType &document)
parse an object value.
Definition pack.hpp:695
int deserialize(const std::string &document) override
deserialize a document.
Definition pack.hpp:459
constexpr bool isNumber(uint8_t c)
check if number.
Definition pack.hpp:964
constexpr bool isBin(uint8_t c)
check if binary data.
Definition pack.hpp:984
int readString(ViewType &document, bool isKey=false)
parse a string value.
Definition pack.hpp:742
int deserialize(std::istream &document) override
deserialize a document.
Definition pack.hpp:525
constexpr bool isArray(uint8_t c)
check if array.
Definition pack.hpp:994
PackReader(Value &root)
default constructor.
Definition pack.hpp:394
int readBin(ViewType &document)
parse binary data.
Definition pack.hpp:781
message pack writer class.
Definition pack.hpp:41
virtual int setNull() override
set null value.
Definition pack.hpp:87
PackWriter(std::ostream &document)
create instance.
Definition pack.hpp:47
virtual int setDouble(double value) override
set real value.
Definition pack.hpp:277
virtual int setString(const std::string &value) override
set string value.
Definition pack.hpp:289
virtual int setInt64(int64_t value) override
set 64 bits integer value.
Definition pack.hpp:189
virtual int setUint(uint32_t value) override
set unsigned integer value.
Definition pack.hpp:160
virtual int setKey(const std::string &key) override
set key.
Definition pack.hpp:367
virtual int setBool(bool value) override
set boolean value.
Definition pack.hpp:98
virtual int setUint64(uint64_t value) override
set unsigned 64 bits integer value.
Definition pack.hpp:243
virtual ~PackWriter()=default
destroy instance.
virtual int startArray(uint32_t size=0) override
start array.
Definition pack.hpp:319
void pack(Type value)
pack value into stream.
Definition pack.hpp:378
PackWriter & operator=(const PackWriter &other)=delete
copy assignment.
virtual int setInt(int32_t value) override
set integer value.
Definition pack.hpp:116
virtual int startObject(uint32_t size=0) override
start object.
Definition pack.hpp:343
PackWriter(PackWriter &&other)=delete
move constructor.
PackWriter(const PackWriter &other)=delete
copy constructor.
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 setUint(uint32_t value) override
set unsigned integer value.
Definition sax.hpp:586
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 setInt(int32_t value) override
set integer value.
Definition sax.hpp:576
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
void append(char data) noexcept
append character to output stream in batch.
Definition sax.hpp:373
string view.
Definition view.hpp:78
value class.
Definition value.hpp:63
const std::string key(65, 'a')
key.
Definition acceptor.hpp:32
std::error_code make_error_code(join::Errc code)
Create an std::error_code object.
Definition error.cpp:154
__inline__ Type & swap(Type &val)
swaps byte orders.
Definition utils.hpp:176
thread_local std::error_code lastError
last error.
Definition error.cpp:32
#define JOIN_LIKELY(x)
Definition utils.hpp:46
#define JOIN_UNLIKELY(x)
Definition utils.hpp:47