Zakero's C++ Header Libraries
A collection of reusable C++ libraries
Zakero_MessagePack.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2021 Andrew Moore
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7  */
8 
9 #ifndef zakero_MessagePack_h
10 #define zakero_MessagePack_h
11 
154 /******************************************************************************
155  * Includes
156  */
157 
158 // C++
159 #include <cstring>
160 #include <string>
161 #include <limits>
162 #include <vector>
163 
164 // POSIX
165 #include <arpa/inet.h>
166 
167 // Linux
168 
169 
170 /******************************************************************************
171  * Macros
172  */
173 
174 // {{{ Macros
175 
189 #define ZAKERO_DISABLE_IMPLICIT_CASTS(func_name_) \
190  template <typename... T> \
191  void func_name_(T...) = delete
192 
209 #define ZAKERO_MESSAGEPACK__ERROR_DATA \
210  X(Error_None , 0 , "No Error" ) \
211  X(Error_Unknown , 1 , "An unknown error has occurred" ) \
212 
213 // }}}
214 
215 
216 namespace zakero
217 {
218  // {{{ Declaration
219 
221  {
222  public:
223  // Rename to Type
224  enum class DataType
225  { Null
226  , Bool
227  , Int64
228  , Uint64
229  , Float
230  , Double
231  , String
232  , Vector
233  };
234 
235  struct Object
236  {
237  DataType type;
238  union
239  {
240  bool bool_;
241  int64_t int64_;
242  uint64_t uint64_;
243  float float_;
244  double double_;
245  };
246  std::string string = {};
247  std::vector<uint8_t> vector = {};
248 
249  Object() noexcept;
250  Object(const Object&) noexcept;
251  Object(Object&&) noexcept;
252  Object(const bool) noexcept;
253  Object(const int64_t) noexcept;
254  Object(const uint64_t) noexcept;
255  Object(const float) noexcept;
256  Object(const double) noexcept;
257  Object(const std::string_view) noexcept;
258  Object(std::vector<uint8_t>) noexcept;
259  };
260 
261  MessagePack() = default;
262 
263  void append(const bool, size_t* const = nullptr) noexcept;
264  void append(const int64_t, size_t* const = nullptr) noexcept;
265  void append(const uint64_t, size_t* const = nullptr) noexcept;
266  void append(const float, size_t* = nullptr) noexcept;
267  void append(const double, size_t* = nullptr) noexcept;
268  void append(const std::string_view, size_t* = nullptr) noexcept;
269  void append(const std::vector<uint8_t>&, size_t* = nullptr) noexcept;
270  void append(uint8_t*, size_t, size_t* = nullptr);
271  //void appendArray(size_t* = nullptr);
272  //void appendExtension(int8_t, std::vector<uint8_t>&, size_t* = nullptr);
273  //void appendExtension(int8_t, uint8_t*, size_t, size_t* = nullptr);
274  //void appendMap(size_t* = nullptr);
275  void appendNull(size_t* const = nullptr) noexcept;
276  //void appendTimeStamp(uint64_t);
277 
278  [[nodiscard]] Object& object(const size_t index) noexcept;
279 
280  void clear() noexcept;
281  [[nodiscard]] size_t size() noexcept;
282 
283  void deserialize(const std::vector<uint8_t>&) noexcept;
284 
285  [[nodiscard]] std::vector<uint8_t> serialize() noexcept;
286 
287  private:
288  using VectorObject = std::vector<Object>;
289 
290  VectorObject object_vector = {};
291  }; // class MessagePack
292 
293  // }}}
294 }
295 
296 // {{{ Implementation
297 
298 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION
299 
300 // {{{ Macros
301 // {{{ Macros : Doxygen
302 
303 #ifdef ZAKERO__DOXYGEN_DEFINE_DOCS
304 
305 // Only used for generating Doxygen documentation
306 
318 #define ZAKERO_MESSAGEPACK_IMPLEMENTATION
319 
320 #endif
321 
322 // }}}
323 
335 #define ZAKERO_MESSAGEPACK__FORMAT_DATA \
336  /* Type Name Type Id Type Id Mask Type Spec Name */ \
337  X(Fixed_Int_Pos , 0x00 , 0b10000000 , "positive fixint" ) \
338  X(fixmap , 0x80 , 0b00000000 , "fixmap" ) \
339  X(fixarray , 0x90 , 0b00000000 , "fixarray" ) \
340  X(Fixed_Str , 0xa0 , 0b11100000 , "fixstr" ) \
341  X(Nill , 0xc0 , 0b00000000 , "nill" ) \
342  X(never_used , 0xc1 , 0b00000000 , "(never used)" ) \
343  X(False , 0xc2 , 0b00000000 , "false" ) \
344  X(True , 0xc3 , 0b00000000 , "true" ) \
345  X(Bin8 , 0xc4 , 0b11111111 , "bin 8" ) \
346  X(Bin16 , 0xc5 , 0b11111111 , "bin 16" ) \
347  X(Bin32 , 0xc6 , 0b11111111 , "bin 32" ) \
348  X(ext8 , 0xc7 , 0b00000000 , "ext 8" ) \
349  X(ext16 , 0xc8 , 0b00000000 , "ext 16" ) \
350  X(ext32 , 0xc9 , 0b00000000 , "ext 32" ) \
351  X(Float32 , 0xca , 0b11111111 , "float 32" ) \
352  X(Float64 , 0xcb , 0b11111111 , "float 64" ) \
353  X(Uint8 , 0xcc , 0b11111111 , "uint 8" ) \
354  X(Uint16 , 0xcd , 0b11111111 , "uint 16" ) \
355  X(Uint32 , 0xce , 0b11111111 , "uint 32" ) \
356  X(Uint64 , 0xcf , 0b11111111 , "uint 64" ) \
357  X(Int8 , 0xd0 , 0b11111111 , "int 8" ) \
358  X(Int16 , 0xd1 , 0b11111111 , "int 16" ) \
359  X(Int32 , 0xd2 , 0b11111111 , "int 32" ) \
360  X(Int64 , 0xd3 , 0b11111111 , "int 64" ) \
361  X(fixext1 , 0xd4 , 0b00000000 , "fixext 1" ) \
362  X(fixext2 , 0xd5 , 0b00000000 , "fixext 2" ) \
363  X(fixext4 , 0xd6 , 0b00000000 , "fixext 4" ) \
364  X(fixext8 , 0xd7 , 0b00000000 , "fixext 8" ) \
365  X(fixext16 , 0xd8 , 0b00000000 , "fixext 16" ) \
366  X(Str8 , 0xd9 , 0b00000000 , "str 8" ) \
367  X(Str16 , 0xda , 0b00000000 , "str 16" ) \
368  X(Str32 , 0xdb , 0b00000000 , "str 32" ) \
369  X(array16 , 0xdc , 0b00000000 , "array 16" ) \
370  X(array32 , 0xdd , 0b00000000 , "array 32" ) \
371  X(map16 , 0xde , 0b00000000 , "map 16" ) \
372  X(map32 , 0xdf , 0b00000000 , "map 32" ) \
373  X(Fixed_Int_Neg , 0xe0 , 0b11100000 , "negative fixint" ) \
374 
375 // }}}
376 // {{{ Documentation
377 
405 // }}}
406 
407 namespace zakero
408 {
409 // {{{ Anonymous Namespace
410 
411 namespace
412 {
413  enum class Type : uint8_t
414  {
418 #define X(type_, id_, mask_, text_) \
419  type_ = id_, \
420 
421  ZAKERO_MESSAGEPACK__FORMAT_DATA
422 #undef X
423  };
424 
429 #define X(type_, id_, mask_, text_) \
430  constexpr uint8_t type_ ## _Mask = mask_; \
431 
432  ZAKERO_MESSAGEPACK__FORMAT_DATA
433 #undef X
442 #define X(type_, id_, mask_, text_) \
443  constexpr uint8_t type_ ## _Value = (uint8_t)~mask_;\
444 
445  ZAKERO_MESSAGEPACK__FORMAT_DATA
446 #undef X
454  union
455  {
456  uint64_t uint64;
457  uint32_t uint32;
458  uint16_t uint16;
459  int64_t int64;
460  int32_t int32;
461  int16_t int16;
462  float float32;
463  double float64;
464  uint8_t uint8[8];
465  } Convert;
466 
471 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
472  uint8_t& Convert_Byte0 = Convert.uint8[7];
473  uint8_t& Convert_Byte1 = Convert.uint8[6];
474  uint8_t& Convert_Byte2 = Convert.uint8[5];
475  uint8_t& Convert_Byte3 = Convert.uint8[4];
476  uint8_t& Convert_Byte4 = Convert.uint8[3];
477  uint8_t& Convert_Byte5 = Convert.uint8[2];
478  uint8_t& Convert_Byte6 = Convert.uint8[1];
479  uint8_t& Convert_Byte7 = Convert.uint8[0];
480 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
481  uint8_t& Convert_Byte0 = Convert.uint8[0];
482  uint8_t& Convert_Byte1 = Convert.uint8[1];
483  uint8_t& Convert_Byte2 = Convert.uint8[2];
484  uint8_t& Convert_Byte3 = Convert.uint8[3];
485  uint8_t& Convert_Byte4 = Convert.uint8[4];
486  uint8_t& Convert_Byte5 = Convert.uint8[5];
487  uint8_t& Convert_Byte6 = Convert.uint8[6];
488  uint8_t& Convert_Byte7 = Convert.uint8[7];
489 #endif
493 }
494 
495 // }}}
496 // {{{ MessagePack
497 
511 void MessagePack::append(const bool value
512  , size_t* const index
513  ) noexcept
514 {
515  if(index != nullptr)
516  {
517  *index = object_vector.size();
518  }
519 
520  object_vector.emplace_back(value);
521 }
522 
523 
524 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
525 TEST_CASE("Append: Bool")
526 {
527  MessagePack mesg_pack;
528 
529  size_t index = 0;
530  mesg_pack.append(true, &index);
531 
532  CHECK(index == 0);
533  CHECK(mesg_pack.size() == 1);
534 
535  mesg_pack.append(false, &index);
536 
537  CHECK(index == 1);
538  CHECK(mesg_pack.size() == 2);
539 
540  // Check serialized data
541 
542  std::vector<uint8_t> data = mesg_pack.serialize();
543 
544  CHECK(data.size() == 2);
545  CHECK(data[0] == (uint8_t)Type::True);
546  CHECK(data[1] == (uint8_t)Type::False);
547 
548  // Check deserialized data
549 
550  mesg_pack.deserialize(data);
551  CHECK(mesg_pack.size() == 2);
552 
553  {
554  const MessagePack::Object& object = mesg_pack.object(0);
555  CHECK(object.type == MessagePack::DataType::Bool);
556  CHECK(object.bool_ == true);
557  }
558 
559  {
560  const MessagePack::Object& object = mesg_pack.object(1);
561  CHECK(object.type == MessagePack::DataType::Bool);
562  CHECK(object.bool_ == false);
563  }
564 }
565 #endif // }}}
566 
567 
581 void MessagePack::append(const int64_t value
582  , size_t* const index
583  ) noexcept
584 {
585  if(index != nullptr)
586  {
587  *index = object_vector.size();
588  }
589 
590  object_vector.emplace_back(value);
591 }
592 
593 
594 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
595 TEST_CASE("Append: Fixed_Int")
596 {
597  MessagePack mesg_pack;
598 
599  const int64_t fixint_zero = 0;
600  const int64_t fixint_max = 127;
601  const int64_t fixint_min = -32;
602  const int64_t fixint_p24 = 24;
603  const int64_t fixint_n24 = -24;
604  size_t count = 0;
605 
606  mesg_pack.append(fixint_zero); count++;
607  mesg_pack.append(fixint_max); count++;
608  mesg_pack.append(fixint_min); count++;
609  mesg_pack.append(fixint_p24); count++;
610  mesg_pack.append(fixint_n24); count++;
611 
612  CHECK(mesg_pack.size() == count);
613 
614  // Check serialized data
615 
616  std::vector<uint8_t> data = mesg_pack.serialize();
617 
618  size_t size = (count * sizeof(uint8_t));
619 
620  CHECK(data.size() == size);
621  CHECK((data[0] & Fixed_Int_Pos_Mask) == ((uint8_t)Type::Fixed_Int_Pos));
622  CHECK((data[0] & Fixed_Int_Pos_Value) == fixint_zero);
623  CHECK((data[1] & Fixed_Int_Pos_Mask) == ((uint8_t)Type::Fixed_Int_Pos));
624  CHECK((data[1] & Fixed_Int_Pos_Value) == fixint_max);
625  CHECK((data[2] & Fixed_Int_Neg_Mask) == ((uint8_t)Type::Fixed_Int_Neg));
626  CHECK(((data[2] & Fixed_Int_Neg_Value) - 32) == fixint_min);
627  CHECK((data[3] & Fixed_Int_Pos_Mask) == ((uint8_t)Type::Fixed_Int_Pos));
628  CHECK((data[3] & Fixed_Int_Pos_Value) == fixint_p24);
629  CHECK((data[4] & Fixed_Int_Neg_Mask) == ((uint8_t)Type::Fixed_Int_Neg));
630  CHECK(((data[4] & Fixed_Int_Neg_Value) - 32) == fixint_n24);
631 
632  // Check deserialized data
633 
634  mesg_pack.deserialize(data);
635  CHECK(mesg_pack.size() == count);
636 
637  {
638  const MessagePack::Object& object = mesg_pack.object(0);
639  CHECK(object.type == MessagePack::DataType::Int64);
640  CHECK(object.int64_ == fixint_zero);
641  }
642 
643  {
644  const MessagePack::Object& object = mesg_pack.object(1);
645  CHECK(object.type == MessagePack::DataType::Int64);
646  CHECK(object.int64_ == fixint_max);
647  }
648 
649  {
650  const MessagePack::Object& object = mesg_pack.object(2);
651  CHECK(object.type == MessagePack::DataType::Int64);
652  CHECK(object.int64_ == fixint_min);
653  }
654 
655  {
656  const MessagePack::Object& object = mesg_pack.object(3);
657  CHECK(object.type == MessagePack::DataType::Int64);
658  CHECK(object.int64_ == fixint_p24);
659  }
660 
661  {
662  const MessagePack::Object& object = mesg_pack.object(4);
663  CHECK(object.type == MessagePack::DataType::Int64);
664  CHECK(object.int64_ == fixint_n24);
665  }
666 }
667 
668 TEST_CASE("Append: Int8")
669 {
670  MessagePack mesg_pack;
671 
672  // Don't test the maximum Int8 value 127
673  // because that is handled by Fixed_Int_Pos
674 
675  const int64_t i8_min1 = std::numeric_limits<int8_t>::min();
676  const int64_t i8_min2 = -33;
677  size_t count = 0;
678 
679  mesg_pack.append(i8_min1); count++;
680  mesg_pack.append(i8_min2); count++;
681 
682  CHECK(mesg_pack.size() == count);
683 
684  // Check serialized data
685 
686  std::vector<uint8_t> data = mesg_pack.serialize();
687 
688  size_t size = (count * 2 * sizeof(uint8_t));
689  CHECK(data.size() == size);
690 
691  CHECK(data[0] == ((uint8_t)Type::Int8));
692  CHECK((int8_t)data[1] == i8_min1);
693  CHECK(data[2] == ((uint8_t)Type::Int8));
694  CHECK((int8_t)data[3] == i8_min2);
695 
696  // Check deserialized data
697 
698  mesg_pack.deserialize(data);
699 
700  CHECK(mesg_pack.size() == count);
701 
702  {
703  const MessagePack::Object& object = mesg_pack.object(0);
704  CHECK(object.type == MessagePack::DataType::Int64);
705  CHECK(object.int64_ == i8_min1);
706  }
707 
708  {
709  const MessagePack::Object& object = mesg_pack.object(1);
710  CHECK(object.type == MessagePack::DataType::Int64);
711  CHECK(object.int64_ == i8_min2);
712  }
713 }
714 
715 TEST_CASE("Append: Int16")
716 {
717  MessagePack mesg_pack;
718 
719  const int64_t i16_min1 = std::numeric_limits<int16_t>::min();
720  const int64_t i16_max1 = std::numeric_limits<int16_t>::max();
721  const int64_t i16_min2 = std::numeric_limits<int8_t>::min() - (int64_t)1;
722  const int64_t i16_max2 = std::numeric_limits<int8_t>::max() + (int64_t)1;
723  size_t count = 0;
724 
725  mesg_pack.clear();
726  mesg_pack.append(i16_min1); count++;
727  mesg_pack.append(i16_max1); count++;
728  mesg_pack.append(i16_min2); count++;
729  mesg_pack.append(i16_max2); count++;
730 
731  CHECK(mesg_pack.size() == count);
732 
733  // Check serialized data
734 
735  std::vector<uint8_t> data = mesg_pack.serialize();
736 
737  size_t size = (count * 3 * sizeof(uint8_t));
738  CHECK(data.size() == size);
739 
740  CHECK(data[0] == ((uint8_t)Type::Int16));
741 
742  Convert.uint64 = 0;
743  Convert_Byte1 = data[1];
744  Convert_Byte0 = data[2];
745  CHECK(Convert.int16 == i16_min1);
746 
747  CHECK(data[3] == ((uint8_t)Type::Int16));
748  Convert_Byte1 = data[4];
749  Convert_Byte0 = data[5];
750  CHECK(Convert.int16 == i16_max1);
751 
752  CHECK(data[6] == ((uint8_t)Type::Int16));
753  Convert_Byte1 = data[7];
754  Convert_Byte0 = data[8];
755  CHECK(Convert.int16 == i16_min2);
756 
757  CHECK(data[9] == ((uint8_t)Type::Int16));
758  Convert_Byte1 = data[10];
759  Convert_Byte0 = data[11];
760  CHECK(Convert.int16 == i16_max2);
761 
762  // Check deserialized data
763 
764  mesg_pack.deserialize(data);
765 
766  CHECK(mesg_pack.size() == count);
767 
768  {
769  const MessagePack::Object& object = mesg_pack.object(0);
770  CHECK(object.type == MessagePack::DataType::Int64);
771  CHECK(object.int64_ == i16_min1);
772  }
773 
774  {
775  const MessagePack::Object& object = mesg_pack.object(1);
776  CHECK(object.type == MessagePack::DataType::Int64);
777  CHECK(object.int64_ == i16_max1);
778  }
779 
780  {
781  const MessagePack::Object& object = mesg_pack.object(2);
782  CHECK(object.type == MessagePack::DataType::Int64);
783  CHECK(object.int64_ == i16_min2);
784  }
785 
786  {
787  const MessagePack::Object& object = mesg_pack.object(3);
788  CHECK(object.type == MessagePack::DataType::Int64);
789  CHECK(object.int64_ == i16_max2);
790  }
791 }
792 
793 TEST_CASE("Append: Int32")
794 {
795  MessagePack mesg_pack;
796 
797  const int64_t i32_min1 = std::numeric_limits<int32_t>::min();
798  const int64_t i32_max1 = std::numeric_limits<int32_t>::max();
799  const int64_t i32_min2 = std::numeric_limits<int16_t>::min() - (int64_t)1;
800  const int64_t i32_max2 = std::numeric_limits<int16_t>::max() + (int64_t)1;
801  size_t count = 0;
802 
803  mesg_pack.clear();
804  mesg_pack.append(i32_min1); count++;
805  mesg_pack.append(i32_max1); count++;
806  mesg_pack.append(i32_min2); count++;
807  mesg_pack.append(i32_max2); count++;
808 
809  CHECK(mesg_pack.size() == count);
810 
811  // Check serialized data
812 
813  std::vector<uint8_t> data = mesg_pack.serialize();
814 
815  size_t size = (count * 5 * sizeof(uint8_t));
816  CHECK(data.size() == size);
817 
818  CHECK(data[0] == ((uint8_t)Type::Int32));
819 
820  Convert.uint64 = 0;
821  Convert_Byte3 = data[1];
822  Convert_Byte2 = data[2];
823  Convert_Byte1 = data[3];
824  Convert_Byte0 = data[4];
825  CHECK(Convert.int32 == i32_min1);
826 
827  CHECK(data[5] == ((uint8_t)Type::Int32));
828  Convert_Byte3 = data[6];
829  Convert_Byte2 = data[7];
830  Convert_Byte1 = data[8];
831  Convert_Byte0 = data[9];
832  CHECK(Convert.int32 == i32_max1);
833 
834  CHECK(data[10] == ((uint8_t)Type::Int32));
835  Convert_Byte3 = data[11];
836  Convert_Byte2 = data[12];
837  Convert_Byte1 = data[13];
838  Convert_Byte0 = data[14];
839  CHECK(Convert.int32 == i32_min2);
840 
841  CHECK(data[15] == ((uint8_t)Type::Int32));
842  Convert_Byte3 = data[16];
843  Convert_Byte2 = data[17];
844  Convert_Byte1 = data[18];
845  Convert_Byte0 = data[19];
846  CHECK(Convert.int32 == i32_max2);
847 
848  // Check deserialized data
849 
850  mesg_pack.deserialize(data);
851 
852  CHECK(mesg_pack.size() == count);
853 
854  {
855  const MessagePack::Object& object = mesg_pack.object(0);
856  CHECK(object.type == MessagePack::DataType::Int64);
857  CHECK(object.int64_ == i32_min1);
858  }
859 
860  {
861  const MessagePack::Object& object = mesg_pack.object(1);
862  CHECK(object.type == MessagePack::DataType::Int64);
863  CHECK(object.int64_ == i32_max1);
864  }
865 
866  {
867  const MessagePack::Object& object = mesg_pack.object(2);
868  CHECK(object.type == MessagePack::DataType::Int64);
869  CHECK(object.int64_ == i32_min2);
870  }
871 
872  {
873  const MessagePack::Object& object = mesg_pack.object(3);
874  CHECK(object.type == MessagePack::DataType::Int64);
875  CHECK(object.int64_ == i32_max2);
876  }
877 }
878 
879 TEST_CASE("Append: Int64")
880 {
881  MessagePack mesg_pack;
882 
883  const int64_t i64_min1 = std::numeric_limits<int64_t>::min();
884  const int64_t i64_max1 = std::numeric_limits<int64_t>::max();
885  const int64_t i64_min2 = std::numeric_limits<int32_t>::min() - (int64_t)1;
886  const int64_t i64_max2 = std::numeric_limits<int32_t>::max() + (int64_t)1;
887  size_t count = 0;
888 
889  mesg_pack.clear();
890  mesg_pack.append(i64_min1); count++;
891  mesg_pack.append(i64_max1); count++;
892  mesg_pack.append(i64_min2); count++;
893  mesg_pack.append(i64_max2); count++;
894 
895  CHECK(mesg_pack.size() == count);
896 
897  // Check serialized data
898 
899  std::vector<uint8_t> data = mesg_pack.serialize();
900 
901  size_t size = (count * 9 * sizeof(uint8_t));
902  CHECK(data.size() == size);
903 
904  CHECK(data[0] == ((uint8_t)Type::Int64));
905 
906  Convert.uint64 = 0;
907  Convert_Byte7 = data[1];
908  Convert_Byte6 = data[2];
909  Convert_Byte5 = data[3];
910  Convert_Byte4 = data[4];
911  Convert_Byte3 = data[5];
912  Convert_Byte2 = data[6];
913  Convert_Byte1 = data[7];
914  Convert_Byte0 = data[8];
915  CHECK(Convert.int64 == i64_min1);
916 
917  CHECK(data[9] == ((uint8_t)Type::Int64));
918  Convert_Byte7 = data[10];
919  Convert_Byte6 = data[11];
920  Convert_Byte5 = data[12];
921  Convert_Byte4 = data[13];
922  Convert_Byte3 = data[14];
923  Convert_Byte2 = data[15];
924  Convert_Byte1 = data[16];
925  Convert_Byte0 = data[17];
926  CHECK(Convert.int64 == i64_max1);
927 
928  CHECK(data[18] == ((uint8_t)Type::Int64));
929  Convert_Byte7 = data[19];
930  Convert_Byte6 = data[20];
931  Convert_Byte5 = data[21];
932  Convert_Byte4 = data[22];
933  Convert_Byte3 = data[23];
934  Convert_Byte2 = data[24];
935  Convert_Byte1 = data[25];
936  Convert_Byte0 = data[26];
937  CHECK(Convert.int64 == i64_min2);
938 
939  CHECK(data[27] == ((uint8_t)Type::Int64));
940  Convert_Byte7 = data[28];
941  Convert_Byte6 = data[29];
942  Convert_Byte5 = data[30];
943  Convert_Byte4 = data[31];
944  Convert_Byte3 = data[32];
945  Convert_Byte2 = data[33];
946  Convert_Byte1 = data[34];
947  Convert_Byte0 = data[35];
948  CHECK(Convert.int64 == i64_max2);
949 
950  // Check deserialized data
951 
952  mesg_pack.deserialize(data);
953 
954  CHECK(mesg_pack.size() == count);
955 
956  {
957  const MessagePack::Object& object = mesg_pack.object(0);
958  CHECK(object.type == MessagePack::DataType::Int64);
959  CHECK(object.int64_ == i64_min1);
960  }
961 
962  {
963  const MessagePack::Object& object = mesg_pack.object(1);
964  CHECK(object.type == MessagePack::DataType::Int64);
965  CHECK(object.int64_ == i64_max1);
966 
967  }
968 
969  {
970  const MessagePack::Object& object = mesg_pack.object(2);
971  CHECK(object.type == MessagePack::DataType::Int64);
972  CHECK(object.int64_ == i64_min2);
973  }
974 
975  {
976  const MessagePack::Object& object = mesg_pack.object(3);
977  CHECK(object.type == MessagePack::DataType::Int64);
978  CHECK(object.int64_ == i64_max2);
979  }
980 }
981 #endif // }}}
982 
983 
997 void MessagePack::append(const uint64_t value
998  , size_t* const index
999  ) noexcept
1000 {
1001  if(index != nullptr)
1002  {
1003  *index = object_vector.size();
1004  }
1005 
1006  object_vector.emplace_back(value);
1007 }
1008 
1009 
1010 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1011 TEST_CASE("Append: Uint8")
1012 {
1013  MessagePack mesg_pack;
1014 
1015  const uint64_t u8_min = 0x00;
1016  const uint64_t u8_max = std::numeric_limits<uint8_t>::max();
1017  size_t count = 0;
1018 
1019  mesg_pack.append(u8_min); count++;
1020  mesg_pack.append(u8_max); count++;
1021 
1022  CHECK(mesg_pack.size() == count);
1023 
1024  // Check serialized data
1025 
1026  std::vector<uint8_t> data = mesg_pack.serialize();
1027 
1028  size_t size = (count * 2 * sizeof(uint8_t));
1029  CHECK(data.size() == size);
1030 
1031  CHECK(data[0] == ((uint8_t)Type::Uint8));
1032  CHECK(data[1] == u8_min);
1033  CHECK(data[2] == ((uint8_t)Type::Uint8));
1034  CHECK(data[3] == u8_max);
1035 
1036  // Check deserialized data
1037 
1038  mesg_pack.deserialize(data);
1039 
1040  CHECK(mesg_pack.size() == count);
1041 
1042  {
1043  const MessagePack::Object& object = mesg_pack.object(0);
1044  CHECK(object.type == MessagePack::DataType::Uint64);
1045  CHECK(object.uint64_ == u8_min);
1046  }
1047 
1048  {
1049  const MessagePack::Object& object = mesg_pack.object(1);
1050  CHECK(object.type == MessagePack::DataType::Uint64);
1051  CHECK(object.uint64_ == u8_max);
1052  }
1053 }
1054 
1055 TEST_CASE("Append: Uint16")
1056 {
1057  MessagePack mesg_pack;
1058 
1059  const uint64_t u16_min = std::numeric_limits<uint8_t>::max() + (uint64_t)1;
1060  const uint64_t u16_max = std::numeric_limits<uint16_t>::max();
1061  size_t count = 0;
1062 
1063  mesg_pack.append(u16_min); count++;
1064  mesg_pack.append(u16_max); count++;
1065 
1066  CHECK(mesg_pack.size() == count);
1067 
1068  // Check serialized data
1069 
1070  std::vector<uint8_t> data = mesg_pack.serialize();
1071 
1072  size_t size = (count * 3 * sizeof(uint8_t));
1073  CHECK(data.size() == size);
1074 
1075  CHECK(data[0] == ((uint8_t)Type::Uint16));
1076 
1077  Convert_Byte1 = data[1];
1078  Convert_Byte0 = data[2];
1079  CHECK(Convert.uint16 == u16_min);
1080 
1081  CHECK(data[3] == ((uint8_t)Type::Uint16));
1082  Convert_Byte1 = data[4];
1083  Convert_Byte0 = data[5];
1084  CHECK(Convert.uint16 == u16_max);
1085 
1086  // Check deserialized data
1087 
1088  mesg_pack.deserialize(data);
1089 
1090  CHECK(mesg_pack.size() == count);
1091 
1092  {
1093  const MessagePack::Object& object = mesg_pack.object(0);
1094  CHECK(object.type == MessagePack::DataType::Uint64);
1095  CHECK(object.uint64_ == u16_min);
1096  }
1097 
1098  {
1099  const MessagePack::Object& object = mesg_pack.object(1);
1100  CHECK(object.type == MessagePack::DataType::Uint64);
1101  CHECK(object.uint64_ == u16_max);
1102  }
1103 }
1104 
1105 TEST_CASE("Append: Uint32")
1106 {
1107  MessagePack mesg_pack;
1108 
1109  const uint64_t u32_min = std::numeric_limits<uint16_t>::max() + (uint64_t)1;
1110  const uint64_t u32_max = std::numeric_limits<uint32_t>::max();
1111  size_t count = 0;
1112 
1113  mesg_pack.append(u32_min); count++;
1114  mesg_pack.append(u32_max); count++;
1115 
1116  CHECK(mesg_pack.size() == count);
1117 
1118  // Check serialized data
1119 
1120  std::vector<uint8_t> data = mesg_pack.serialize();
1121 
1122  size_t size = (count * 5 * sizeof(uint8_t));
1123  CHECK(data.size() == size);
1124 
1125  CHECK(data[0] == ((uint8_t)Type::Uint32));
1126 
1127  Convert_Byte3 = data[1];
1128  Convert_Byte2 = data[2];
1129  Convert_Byte1 = data[3];
1130  Convert_Byte0 = data[4];
1131  CHECK(Convert.uint32 == u32_min);
1132 
1133  CHECK(data[5] == ((uint8_t)Type::Uint32));
1134  Convert_Byte3 = data[6];
1135  Convert_Byte2 = data[7];
1136  Convert_Byte1 = data[8];
1137  Convert_Byte0 = data[9];
1138  CHECK(Convert.uint32 == u32_max);
1139 
1140  // Check deserialized data
1141 
1142  mesg_pack.deserialize(data);
1143 
1144  CHECK(mesg_pack.size() == count);
1145 
1146  {
1147  const MessagePack::Object& object = mesg_pack.object(0);
1148  CHECK(object.type == MessagePack::DataType::Uint64);
1149  CHECK(object.uint64_ == u32_min);
1150  }
1151 
1152  {
1153  const MessagePack::Object& object = mesg_pack.object(1);
1154  CHECK(object.type == MessagePack::DataType::Uint64);
1155  CHECK(object.uint64_ == u32_max);
1156  }
1157 }
1158 
1159 TEST_CASE("Append: Uint64")
1160 {
1161  MessagePack mesg_pack;
1162 
1163  const uint64_t u64_min = std::numeric_limits<uint32_t>::max() + (uint64_t)1;
1164  const uint64_t u64_max = std::numeric_limits<uint64_t>::max();
1165  size_t count = 0;
1166 
1167  mesg_pack.append(u64_min); count++;
1168  mesg_pack.append(u64_max); count++;
1169 
1170  CHECK(mesg_pack.size() == count);
1171 
1172  // Check serialized data
1173 
1174  std::vector<uint8_t> data = mesg_pack.serialize();
1175 
1176  size_t size = (count * 9 * sizeof(uint8_t));
1177  CHECK(data.size() == size);
1178 
1179  CHECK(data[0] == ((uint8_t)Type::Uint64));
1180 
1181  Convert_Byte7 = data[1];
1182  Convert_Byte6 = data[2];
1183  Convert_Byte5 = data[3];
1184  Convert_Byte4 = data[4];
1185  Convert_Byte3 = data[5];
1186  Convert_Byte2 = data[6];
1187  Convert_Byte1 = data[7];
1188  Convert_Byte0 = data[8];
1189  CHECK(Convert.uint64 == u64_min);
1190 
1191  CHECK(data[9] == ((uint8_t)Type::Uint64));
1192  Convert_Byte7 = data[10];
1193  Convert_Byte6 = data[11];
1194  Convert_Byte5 = data[12];
1195  Convert_Byte4 = data[13];
1196  Convert_Byte3 = data[14];
1197  Convert_Byte2 = data[15];
1198  Convert_Byte1 = data[16];
1199  Convert_Byte0 = data[17];
1200  CHECK(Convert.uint64 == u64_max);
1201 
1202  // Check deserialized data
1203 
1204  mesg_pack.deserialize(data);
1205 
1206  CHECK(mesg_pack.size() == count);
1207 
1208  {
1209  const MessagePack::Object& object = mesg_pack.object(0);
1210  CHECK(object.type == MessagePack::DataType::Uint64);
1211  CHECK(object.uint64_ == u64_min);
1212  }
1213 
1214  {
1215  const MessagePack::Object& object = mesg_pack.object(1);
1216  CHECK(object.type == MessagePack::DataType::Uint64);
1217  CHECK(object.uint64_ == u64_max);
1218  }
1219 }
1220 #endif // }}}
1221 
1222 
1236 void MessagePack::append(const float value
1237  , size_t* const index
1238  ) noexcept
1239 {
1240  if(index != nullptr)
1241  {
1242  *index = object_vector.size();
1243  }
1244 
1245  object_vector.emplace_back(value);
1246 }
1247 
1248 
1249 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1250 TEST_CASE("Append: Float32")
1251 {
1252  MessagePack mesg_pack;
1253 
1254  const float f32_min = std::numeric_limits<float>::min();
1255  const float f32_max = std::numeric_limits<float>::max();
1256  const float f32_zero = 0.0f;
1257  size_t count = 0;
1258 
1259  mesg_pack.append(f32_min); count++;
1260  mesg_pack.append(f32_max); count++;
1261  mesg_pack.append(f32_zero); count++;
1262 
1263  CHECK(mesg_pack.size() == count);
1264 
1265  // Check serialized data
1266 
1267  std::vector<uint8_t> data = mesg_pack.serialize();
1268 
1269  size_t size = (count * 5 * sizeof(uint8_t));
1270  CHECK(data.size() == size);
1271 
1272  CHECK(data[0] == ((uint8_t)Type::Float32));
1273  Convert_Byte3 = data[1];
1274  Convert_Byte2 = data[2];
1275  Convert_Byte1 = data[3];
1276  Convert_Byte0 = data[4];
1277  CHECK(Convert.float32 == f32_min);
1278 
1279  CHECK(data[5] == ((uint8_t)Type::Float32));
1280  Convert_Byte3 = data[6];
1281  Convert_Byte2 = data[7];
1282  Convert_Byte1 = data[8];
1283  Convert_Byte0 = data[9];
1284  CHECK(Convert.float32 == f32_max);
1285 
1286  CHECK(data[10] == ((uint8_t)Type::Float32));
1287  Convert_Byte3 = data[11];
1288  Convert_Byte2 = data[12];
1289  Convert_Byte1 = data[13];
1290  Convert_Byte0 = data[14];
1291  CHECK(Convert.float32 == f32_zero);
1292 
1293  // Check deserialized data
1294 
1295  mesg_pack.deserialize(data);
1296 
1297  CHECK(mesg_pack.size() == count);
1298 
1299  {
1300  const MessagePack::Object& object = mesg_pack.object(0);
1301  CHECK(object.type == MessagePack::DataType::Float);
1302  CHECK(object.float_ == f32_min);
1303  }
1304 
1305  {
1306  const MessagePack::Object& object = mesg_pack.object(1);
1307  CHECK(object.type == MessagePack::DataType::Float);
1308  CHECK(object.float_ == f32_max);
1309  }
1310 
1311  {
1312  const MessagePack::Object& object = mesg_pack.object(2);
1313  CHECK(object.type == MessagePack::DataType::Float);
1314  CHECK(object.float_ == f32_zero);
1315  }
1316 }
1317 #endif // }}}
1318 
1319 
1333 void MessagePack::append(const double value
1334  , size_t* const index
1335  ) noexcept
1336 {
1337  if(index != nullptr)
1338  {
1339  *index = object_vector.size();
1340  }
1341 
1342  object_vector.emplace_back(value);
1343 }
1344 
1345 
1346 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1347 TEST_CASE("Append: Float64")
1348 {
1349  MessagePack mesg_pack;
1350 
1351  const double f64_min = std::numeric_limits<double>::min();
1352  const double f64_max = std::numeric_limits<double>::max();
1353  const double f64_zero = 0.0f;
1354  size_t count = 0;
1355 
1356  mesg_pack.append(f64_min); count++;
1357  mesg_pack.append(f64_max); count++;
1358  mesg_pack.append(f64_zero); count++;
1359 
1360  CHECK(mesg_pack.size() == count);
1361 
1362  // Check serialized data
1363 
1364  std::vector<uint8_t> data = mesg_pack.serialize();
1365 
1366  size_t size = (count * 9 * sizeof(uint8_t));
1367  CHECK(data.size() == size);
1368 
1369  CHECK(data[0] == ((uint8_t)Type::Float64));
1370  Convert_Byte7 = data[1];
1371  Convert_Byte6 = data[2];
1372  Convert_Byte5 = data[3];
1373  Convert_Byte4 = data[4];
1374  Convert_Byte3 = data[5];
1375  Convert_Byte2 = data[6];
1376  Convert_Byte1 = data[7];
1377  Convert_Byte0 = data[8];
1378  CHECK(Convert.float64 == f64_min);
1379 
1380  CHECK(data[9] == ((uint8_t)Type::Float64));
1381  Convert_Byte7 = data[10];
1382  Convert_Byte6 = data[11];
1383  Convert_Byte5 = data[12];
1384  Convert_Byte4 = data[13];
1385  Convert_Byte3 = data[14];
1386  Convert_Byte2 = data[15];
1387  Convert_Byte1 = data[16];
1388  Convert_Byte0 = data[17];
1389  CHECK(Convert.float64 == f64_max);
1390 
1391  CHECK(data[18] == ((uint8_t)Type::Float64));
1392  Convert_Byte7 = data[19];
1393  Convert_Byte6 = data[20];
1394  Convert_Byte5 = data[21];
1395  Convert_Byte4 = data[22];
1396  Convert_Byte3 = data[23];
1397  Convert_Byte2 = data[24];
1398  Convert_Byte1 = data[25];
1399  Convert_Byte0 = data[26];
1400  CHECK(Convert.float64 == f64_zero);
1401 
1402  // Check deserialized data
1403 
1404  mesg_pack.deserialize(data);
1405 
1406  CHECK(mesg_pack.size() == count);
1407 
1408  {
1409  const MessagePack::Object& object = mesg_pack.object(0);
1410  CHECK(object.type == MessagePack::DataType::Double);
1411  CHECK(object.double_ == f64_min);
1412  }
1413 
1414  {
1415  const MessagePack::Object& object = mesg_pack.object(1);
1416  CHECK(object.type == MessagePack::DataType::Double);
1417  CHECK(object.double_ == f64_max);
1418  }
1419 
1420  {
1421  const MessagePack::Object& object = mesg_pack.object(2);
1422  CHECK(object.type == MessagePack::DataType::Double);
1423  CHECK(object.double_ == f64_zero);
1424  }
1425 }
1426 #endif // }}}
1427 
1428 
1442 void MessagePack::append(const std::string_view value
1443  , size_t* const index
1444  ) noexcept
1445 {
1446  if(index != nullptr)
1447  {
1448  *index = object_vector.size();
1449  }
1450 
1451  object_vector.emplace_back(value);
1452 }
1453 
1454 
1455 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1456 TEST_CASE("Append: Fixed_Str")
1457 {
1458  MessagePack mesg_pack;
1459 
1460  const std::string str_empty;
1461  const std::string str_1("_");
1462  const std::string str_31(31, 'a');
1463  size_t count = 0;
1464 
1465  mesg_pack.append(str_empty); count++;
1466  mesg_pack.append(str_1); count++;
1467  mesg_pack.append(str_31); count++;
1468 
1469  CHECK(mesg_pack.size() == count);
1470 
1471  // Check serialized data
1472 
1473  std::vector<uint8_t> data = mesg_pack.serialize();
1474 
1475  size_t size = (count * 1 * sizeof(uint8_t))
1476  + str_empty.size()
1477  + str_1.size()
1478  + str_31.size()
1479  ;
1480  CHECK(data.size() == size);
1481 
1482  size_t str_len = 0;
1483  size_t index = 0;
1484  std::string_view str;
1485 
1486  CHECK((data[0] & Fixed_Str_Mask) == ((uint8_t)Type::Fixed_Str));
1487  str_len = data[0] & Fixed_Str_Value;
1488  CHECK(str_len == str_empty.size());
1489  index += str_len + 1;
1490 
1491  CHECK((data[index] & Fixed_Str_Mask) == ((uint8_t)Type::Fixed_Str));
1492  str_len = data[index] & Fixed_Str_Value;
1493  CHECK(str_len == str_1.size());
1494  index++;
1495  str = std::string_view((char*)&data[index], str_len);
1496  CHECK(str == str_1);
1497  index += str_len;
1498 
1499  CHECK((data[index] & Fixed_Str_Mask) == ((uint8_t)Type::Fixed_Str));
1500  str_len = data[index] & Fixed_Str_Value;
1501  CHECK(str_len == str_31.size());
1502  index++;
1503  str = std::string_view((char*)&data[index], str_len);
1504  CHECK(str == str_31);
1505 
1506  // Check deserialized data
1507 
1508  mesg_pack.deserialize(data);
1509 
1510  CHECK(mesg_pack.size() == count);
1511 
1512  {
1513  const MessagePack::Object& object = mesg_pack.object(0);
1514  CHECK(object.type == MessagePack::DataType::String);
1515  CHECK(object.string == str_empty);
1516  }
1517 
1518  {
1519  const MessagePack::Object& object = mesg_pack.object(1);
1520  CHECK(object.type == MessagePack::DataType::String);
1521  CHECK(object.string == str_1);
1522  }
1523 
1524  {
1525  const MessagePack::Object& object = mesg_pack.object(2);
1526  CHECK(object.type == MessagePack::DataType::String);
1527  CHECK(object.string == str_31);
1528  }
1529 }
1530 
1531 TEST_CASE("Append: Str8")
1532 {
1533  MessagePack mesg_pack;
1534 
1535  const std::string str_min(32 , '_');
1536  const std::string str_max(std::numeric_limits<uint8_t>::max(), 'X');
1537  size_t count = 0;
1538 
1539  mesg_pack.append(str_min); count++;
1540  mesg_pack.append(str_max); count++;
1541 
1542  CHECK(mesg_pack.size() == count);
1543 
1544  // Check serialized data
1545 
1546  std::vector<uint8_t> data = mesg_pack.serialize();
1547 
1548  size_t size = (count * 2 * sizeof(uint8_t))
1549  + str_min.size()
1550  + str_max.size()
1551  ;
1552  CHECK(data.size() == size);
1553 
1554  size_t str_len = 0;
1555  size_t index = 0;
1556  std::string_view str;
1557 
1558  CHECK(data[index] == ((uint8_t)Type::Str8));
1559  str_len = data[++index];
1560  CHECK(str_len == str_min.size());
1561  str = std::string_view((char*)&data[++index], str_len);
1562  CHECK(str == str_min);
1563  index += str_len;
1564 
1565  CHECK(data[index] == ((uint8_t)Type::Str8));
1566  str_len = data[++index];
1567  CHECK(str_len == str_max.size());
1568  str = std::string_view((char*)&data[++index], str_len);
1569  CHECK(str == str_max);
1570  index += str_len;
1571 
1572  // Check deserialized data
1573 
1574  mesg_pack.deserialize(data);
1575 
1576  CHECK(mesg_pack.size() == count);
1577 
1578  {
1579  const MessagePack::Object& object = mesg_pack.object(0);
1580  CHECK(object.type == MessagePack::DataType::String);
1581  CHECK(object.string == str_min);
1582  }
1583 
1584  {
1585  const MessagePack::Object& object = mesg_pack.object(1);
1586  CHECK(object.type == MessagePack::DataType::String);
1587  CHECK(object.string == str_max);
1588  }
1589 }
1590 
1591 TEST_CASE("Append: Str16")
1592 {
1593  MessagePack mesg_pack;
1594 
1595  const std::string str_min(std::numeric_limits<uint8_t>::max() + 1, '_');
1596  const std::string str_max(std::numeric_limits<uint16_t>::max() , 'X');
1597  size_t count = 0;
1598 
1599  mesg_pack.append(str_min); count++;
1600  mesg_pack.append(str_max); count++;
1601 
1602  CHECK(mesg_pack.size() == count);
1603 
1604  // Check serialized data
1605 
1606  std::vector<uint8_t> data = mesg_pack.serialize();
1607 
1608  size_t size = (count * 3 * sizeof(uint8_t))
1609  + str_min.size()
1610  + str_max.size()
1611  ;
1612  CHECK(data.size() == size);
1613 
1614  size_t str_len = 0;
1615  size_t index = 0;
1616  std::string_view str;
1617 
1618  CHECK(data[index] == ((uint8_t)Type::Str16));
1619  Convert_Byte1 = data[++index];
1620  Convert_Byte0 = data[++index];
1621  str_len = Convert.uint16;
1622  CHECK(str_len == str_min.size());
1623  str = std::string_view((char*)&data[++index], str_len);
1624  CHECK(str == str_min);
1625  index += str_len;
1626 
1627  CHECK(data[index] == ((uint8_t)Type::Str16));
1628  Convert_Byte1 = data[++index];
1629  Convert_Byte0 = data[++index];
1630  str_len = Convert.uint16;
1631  CHECK(str_len == str_max.size());
1632  str = std::string_view((char*)&data[++index], str_len);
1633  CHECK(str == str_max);
1634  index += str_len;
1635 
1636  // Check deserialized data
1637 
1638  mesg_pack.deserialize(data);
1639 
1640  CHECK(mesg_pack.size() == count);
1641 
1642  {
1643  const MessagePack::Object& object = mesg_pack.object(0);
1644  CHECK(object.type == MessagePack::DataType::String);
1645  CHECK(object.string == str_min);
1646  }
1647 
1648  {
1649  const MessagePack::Object& object = mesg_pack.object(1);
1650  CHECK(object.type == MessagePack::DataType::String);
1651  CHECK(object.string == str_max);
1652  }
1653 }
1654 
1655 TEST_CASE("Append: Str32")
1656 {
1657  MessagePack mesg_pack;
1658 
1659  const std::string str_min(std::numeric_limits<uint16_t>::max() + 1, '_');
1660  // This string size would be 4GB + overhead from std::string
1661  // Serializing would consume another 4GB.
1662  // For a total of 8GB to test the maximum Str32 length.
1663  //const std::string str_max(std::numeric_limits<uint32_t>::max() , 'X');
1664  size_t count = 0;
1665 
1666  mesg_pack.append(str_min); count++;
1667  //mesg_pack.append(str_max); count++;
1668 
1669  CHECK(mesg_pack.size() == count);
1670 
1671  // Check serialized data
1672 
1673  std::vector<uint8_t> data = mesg_pack.serialize();
1674 
1675  size_t size = (count * 5 * sizeof(uint8_t))
1676  + str_min.size()
1677  //+ str_max.size()
1678  ;
1679  CHECK(data.size() == size);
1680 
1681  size_t str_len = 0;
1682  size_t index = 0;
1683  std::string_view str;
1684 
1685  CHECK(data[index] == ((uint8_t)Type::Str32));
1686  Convert_Byte3 = data[++index];
1687  Convert_Byte2 = data[++index];
1688  Convert_Byte1 = data[++index];
1689  Convert_Byte0 = data[++index];
1690  str_len = Convert.uint32;
1691  CHECK(str_len == str_min.size());
1692  str = std::string_view((char*)&data[++index], str_len);
1693  CHECK(str == str_min);
1694  index += str_len;
1695 
1696  //CHECK(data[index] == ((uint8_t)Type::Str32));
1697  //Convert_Byte1 = data[++index];
1698  //Convert_Byte0 = data[++index];
1699  //str_len = Convert.uint16;
1700  //CHECK(str_len == str_max.size());
1701  //str = std::string_view((char*)&data[++index], str_len);
1702  //CHECK(str == str_max);
1703  //index += str_len;
1704 
1705  // Check deserialized data
1706 
1707  mesg_pack.deserialize(data);
1708 
1709  CHECK(mesg_pack.size() == count);
1710 
1711  {
1712  const MessagePack::Object& object = mesg_pack.object(0);
1713  CHECK(object.type == MessagePack::DataType::String);
1714  CHECK(object.string == str_min);
1715  }
1716 
1717  //{
1718  // const MessagePack::Object& object = mesg_pack.object(1);
1719  // CHECK(object.type == MessagePack::DataType::String);
1720  // CHECK(object.string == str_max);
1721  //}
1722 }
1723 #endif // }}}
1724 
1725 
1740 void MessagePack::append(const std::vector<uint8_t>& value
1741  , size_t* const index
1742  ) noexcept
1743 {
1744  if(index != nullptr)
1745  {
1746  *index = object_vector.size();
1747  }
1748 
1749  object_vector.emplace_back(value);
1750 }
1751 
1752 
1753 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1754 TEST_CASE("Append: Bin8")
1755 {
1756  MessagePack mesg_pack;
1757 
1758  const std::vector<uint8_t> bin_min = {};
1759  const std::vector<uint8_t> bin_max(std::numeric_limits<uint8_t>::max(), 'X');
1760  size_t count = 0;
1761 
1762  mesg_pack.append(bin_min); count++;
1763  mesg_pack.append(bin_max); count++;
1764 
1765  CHECK(mesg_pack.size() == count);
1766 
1767  // Check serialized data
1768 
1769  std::vector<uint8_t> data = mesg_pack.serialize();
1770 
1771  size_t size = (count * 2 * sizeof(uint8_t))
1772  + bin_min.size()
1773  + bin_max.size()
1774  ;
1775  CHECK(data.size() == size);
1776 
1777  size_t bin_len = 0;
1778  size_t index = 0;
1779 
1780  CHECK(data[index] == ((uint8_t)Type::Bin8));
1781  bin_len = data[++index];
1782  CHECK(bin_len == bin_min.size());
1783  for(size_t i = 0; i < bin_len; i++)
1784  {
1785  CHECK(data[++index] == bin_min[i]);
1786  }
1787 
1788  CHECK(data[++index] == ((uint8_t)Type::Bin8));
1789  bin_len = data[++index];
1790  CHECK(bin_len == bin_max.size());
1791  for(size_t i = 0; i < bin_len; i++)
1792  {
1793  CHECK(data[++index] == bin_max[i]);
1794  }
1795 
1796  // Check deserialized data
1797 
1798  mesg_pack.deserialize(data);
1799 
1800  CHECK(mesg_pack.size() == count);
1801 
1802  {
1803  const MessagePack::Object& object = mesg_pack.object(0);
1804  CHECK(object.type == MessagePack::DataType::Vector);
1805  CHECK(object.vector.size() == bin_min.size());
1806  for(size_t i = 0; i < bin_min.size(); i++)
1807  {
1808  CHECK(object.vector[i] == bin_min[i]);
1809  }
1810  }
1811 
1812  {
1813  const MessagePack::Object& object = mesg_pack.object(1);
1814  CHECK(object.type == MessagePack::DataType::Vector);
1815  CHECK(object.vector.size() == bin_max.size());
1816  for(size_t i = 0; i < bin_max.size(); i++)
1817  {
1818  CHECK(object.vector[i] == bin_max[i]);
1819  }
1820  }
1821 }
1822 
1823 TEST_CASE("Append: Bin16")
1824 {
1825  MessagePack mesg_pack;
1826 
1827  const std::vector<uint8_t> bin_min(std::numeric_limits<uint8_t>::max() + 1, '_');
1828  const std::vector<uint8_t> bin_max(std::numeric_limits<uint16_t>::max() , 'X');
1829  size_t count = 0;
1830 
1831  mesg_pack.append(bin_min); count++;
1832  mesg_pack.append(bin_max); count++;
1833 
1834  CHECK(mesg_pack.size() == count);
1835 
1836  // Check serialized data
1837 
1838  std::vector<uint8_t> data = mesg_pack.serialize();
1839 
1840  size_t size = (count * 3 * sizeof(uint8_t))
1841  + bin_min.size()
1842  + bin_max.size()
1843  ;
1844  CHECK(data.size() == size);
1845 
1846  size_t bin_len = 0;
1847  size_t index = 0;
1848 
1849  CHECK(data[index] == (uint8_t)Type::Bin16);
1850  Convert_Byte1 = data[++index];
1851  Convert_Byte0 = data[++index];
1852  bin_len = Convert.uint16;
1853  CHECK(bin_len == bin_min.size());
1854  for(size_t i = 0; i < bin_len; i++)
1855  {
1856  CHECK(data[++index] == bin_min[i]);
1857  }
1858 
1859  CHECK(data[++index] == ((uint8_t)Type::Bin16));
1860  Convert_Byte1 = data[++index];
1861  Convert_Byte0 = data[++index];
1862  bin_len = Convert.uint16;
1863  CHECK(bin_len == bin_max.size());
1864  for(size_t i = 0; i < bin_len; i++)
1865  {
1866  CHECK(data[++index] == bin_max[i]);
1867  }
1868 
1869  // Check deserialized data
1870 
1871  mesg_pack.deserialize(data);
1872 
1873  CHECK(mesg_pack.size() == count);
1874 
1875  {
1876  const MessagePack::Object& object = mesg_pack.object(0);
1877  CHECK(object.type == MessagePack::DataType::Vector);
1878  CHECK(object.vector.size() == bin_min.size());
1879  for(size_t i = 0; i < bin_min.size(); i++)
1880  {
1881  CHECK(object.vector[i] == bin_min[i]);
1882  }
1883  }
1884 
1885  {
1886  const MessagePack::Object& object = mesg_pack.object(1);
1887  CHECK(object.type == MessagePack::DataType::Vector);
1888  CHECK(object.vector.size() == bin_max.size());
1889  for(size_t i = 0; i < bin_max.size(); i++)
1890  {
1891  CHECK(object.vector[i] == bin_max[i]);
1892  }
1893  }
1894 }
1895 
1896 TEST_CASE("Append: Bin32")
1897 {
1898  MessagePack mesg_pack;
1899 
1900  const std::vector<uint8_t> bin_min(std::numeric_limits<uint16_t>::max() + 1, '_');
1901  // This vector size would be 4GB + overhead from std::vector
1902  // Serializing would consume another 4GB.
1903  // For a total of 8GB to test the maximum Bin32 length.
1904  //const std::vector<uint8_t> bin_max(std::numeric_limits<uint32_t>::max() , 'X');
1905  size_t count = 0;
1906 
1907  mesg_pack.append(bin_min); count++;
1908  //mesg_pack.append(bin_max); count++;
1909 
1910  CHECK(mesg_pack.size() == count);
1911 
1912  // Check serialized data
1913 
1914  std::vector<uint8_t> data = mesg_pack.serialize();
1915 
1916  size_t size = (count * 5 * sizeof(uint8_t))
1917  + bin_min.size()
1918  //+ bin_max.size()
1919  ;
1920  CHECK(data.size() == size);
1921 
1922  size_t bin_len = 0;
1923  size_t index = 0;
1924 
1925  CHECK(data[index] == (uint8_t)Type::Bin32);
1926  Convert_Byte3 = data[++index];
1927  Convert_Byte2 = data[++index];
1928  Convert_Byte1 = data[++index];
1929  Convert_Byte0 = data[++index];
1930  bin_len = Convert.uint32;
1931  CHECK(bin_len == bin_min.size());
1932  for(size_t i = 0; i < bin_len; i++)
1933  {
1934  CHECK(data[++index] == bin_min[i]);
1935  }
1936 
1937  //CHECK(data[++index] == ((uint8_t)Type::Bin32));
1938  //Convert_Byte3 = data[++index];
1939  //Convert_Byte2 = data[++index];
1940  //Convert_Byte1 = data[++index];
1941  //Convert_Byte0 = data[++index];
1942  //bin_len = Convert.uint32;
1943  //CHECK(bin_len == bin_max.size());
1944  //for(size_t i = 0; i < bin_len; i++)
1945  //{
1946  // CHECK(data[++index] == bin_max[i]);
1947  //}
1948 
1949  // Check deserialized data
1950 
1951  mesg_pack.deserialize(data);
1952 
1953  CHECK(mesg_pack.size() == count);
1954 
1955  {
1956  const MessagePack::Object& object = mesg_pack.object(0);
1957  CHECK(object.type == MessagePack::DataType::Vector);
1958  CHECK(object.vector.size() == bin_min.size());
1959  for(size_t i = 0; i < bin_min.size(); i++)
1960  {
1961  CHECK(object.vector[i] == bin_min[i]);
1962  }
1963  }
1964 
1965  //{
1966  // const MessagePack::Object& object = mesg_pack.object(1);
1967  // CHECK(object.type == MessagePack::DataType::Vector);
1968  // CHECK(object.vector.size() == bin_max.size());
1969  // for(size_t i = 0; i < bin_max.size(); i++)
1970  // {
1971  // CHECK(object.vector[i] == bin_max[i]);
1972  // }
1973  //}
1974 }
1975 #endif // }}}
1976 
1977 
1991 void MessagePack::appendNull(size_t* const index
1992  ) noexcept
1993 {
1994  if(index != nullptr)
1995  {
1996  *index = object_vector.size();
1997  }
1998 
1999  object_vector.emplace_back();
2000 }
2001 
2002 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2003 TEST_CASE("Append: Nill")
2004 {
2005  MessagePack mesg_pack;
2006 
2007  size_t index = 0;
2008  mesg_pack.appendNull(&index);
2009 
2010  CHECK(index == 0);
2011  CHECK(mesg_pack.size() == 1);
2012 
2013  mesg_pack.appendNull(&index);
2014 
2015  CHECK(index == 1);
2016  CHECK(mesg_pack.size() == 2);
2017 
2018  // Check serialized data
2019 
2020  std::vector<uint8_t> data = mesg_pack.serialize();
2021 
2022  CHECK(data.size() == 2);
2023  CHECK(data[0] == (uint8_t)Type::Nill);
2024  CHECK(data[1] == (uint8_t)Type::Nill);
2025 
2026  // Check deserialized data
2027 
2028  mesg_pack.deserialize(data);
2029  CHECK(mesg_pack.size() == 2);
2030 
2031  {
2032  const MessagePack::Object& object = mesg_pack.object(0);
2033  CHECK(object.type == MessagePack::DataType::Null);
2034  CHECK(object.int64_ == 0);
2035  }
2036 
2037  {
2038  const MessagePack::Object& object = mesg_pack.object(1);
2039  CHECK(object.type == MessagePack::DataType::Null);
2040  CHECK(object.int64_ == 0);
2041  }
2042 }
2043 #endif // }}}
2044 
2045 
2081 MessagePack::Object& MessagePack::object(const size_t index
2082  ) noexcept
2083 {
2084  return object_vector[index];
2085 }
2086 
2087 
2091 void MessagePack::clear() noexcept
2092 {
2093  object_vector.clear();
2094 }
2095 
2096 
2107 size_t MessagePack::size() noexcept
2108 {
2109  return object_vector.size();
2110 }
2111 
2112 
2113 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2114 // Nothing to test
2115 #endif // }}}
2116 
2117 
2148 void MessagePack::deserialize(const std::vector<uint8_t>& data
2149  ) noexcept
2150 {
2151  object_vector.clear();
2152 
2153  for(size_t index = 0; index < data.size(); index++)
2154  {
2155  uint8_t byte = data[index];
2156 
2157  if(byte == (uint8_t)Type::Nill)
2158  {
2159  appendNull();
2160  }
2161  else if(byte == (uint8_t)Type::False)
2162  {
2163  append(false);
2164  }
2165  else if(byte == (uint8_t)Type::True)
2166  {
2167  append(true);
2168  }
2169  else if((byte & (uint8_t)Fixed_Int_Pos_Mask) == (uint8_t)Type::Fixed_Int_Pos)
2170  {
2171  int64_t value = byte & (uint8_t)Fixed_Int_Pos_Value;
2172  append(value);
2173  }
2174  else if((byte & (uint8_t)Fixed_Int_Neg_Mask) == (uint8_t)Type::Fixed_Int_Neg)
2175  {
2176  int64_t value = (int8_t)(byte & Fixed_Int_Neg_Value) - 32;
2177  append(value);
2178  }
2179  else if(byte == (uint8_t)Type::Int8)
2180  {
2181  int64_t value = (int8_t)data[++index];
2182  append(value);
2183  }
2184  else if(byte == (uint8_t)Type::Int16)
2185  {
2186  Convert_Byte1 = data[++index];
2187  Convert_Byte0 = data[++index];
2188 
2189  int64_t value = Convert.int16;
2190  append(value);
2191  }
2192  else if(byte == (uint8_t)Type::Int32)
2193  {
2194  Convert_Byte3 = data[++index];
2195  Convert_Byte2 = data[++index];
2196  Convert_Byte1 = data[++index];
2197  Convert_Byte0 = data[++index];
2198 
2199  int64_t value = Convert.int32;
2200  append(value);
2201  }
2202  else if(byte == (uint8_t)Type::Int64)
2203  {
2204  Convert_Byte7 = data[++index];
2205  Convert_Byte6 = data[++index];
2206  Convert_Byte5 = data[++index];
2207  Convert_Byte4 = data[++index];
2208  Convert_Byte3 = data[++index];
2209  Convert_Byte2 = data[++index];
2210  Convert_Byte1 = data[++index];
2211  Convert_Byte0 = data[++index];
2212 
2213  int64_t value = Convert.int64;
2214  append(value);
2215  }
2216  else if(byte == (uint8_t)Type::Uint8)
2217  {
2218  uint64_t value = data[++index];
2219  append(value);
2220  }
2221  else if(byte == (uint8_t)Type::Uint16)
2222  {
2223  Convert_Byte1 = data[++index];
2224  Convert_Byte0 = data[++index];
2225 
2226  uint64_t value = Convert.uint16;
2227  append(value);
2228  }
2229  else if(byte == (uint8_t)Type::Uint32)
2230  {
2231  Convert_Byte3 = data[++index];
2232  Convert_Byte2 = data[++index];
2233  Convert_Byte1 = data[++index];
2234  Convert_Byte0 = data[++index];
2235 
2236  uint64_t value = Convert.uint32;
2237  append(value);
2238  }
2239  else if(byte == (uint8_t)Type::Uint64)
2240  {
2241  Convert_Byte7 = data[++index];
2242  Convert_Byte6 = data[++index];
2243  Convert_Byte5 = data[++index];
2244  Convert_Byte4 = data[++index];
2245  Convert_Byte3 = data[++index];
2246  Convert_Byte2 = data[++index];
2247  Convert_Byte1 = data[++index];
2248  Convert_Byte0 = data[++index];
2249 
2250  uint64_t value = Convert.uint64;
2251  append(value);
2252  }
2253  else if(byte == (uint8_t)Type::Float32)
2254  {
2255  Convert_Byte3 = data[++index];
2256  Convert_Byte2 = data[++index];
2257  Convert_Byte1 = data[++index];
2258  Convert_Byte0 = data[++index];
2259 
2260  float value = Convert.float32;
2261  append(value);
2262  }
2263  else if(byte == (uint8_t)Type::Float64)
2264  {
2265  Convert_Byte7 = data[++index];
2266  Convert_Byte6 = data[++index];
2267  Convert_Byte5 = data[++index];
2268  Convert_Byte4 = data[++index];
2269  Convert_Byte3 = data[++index];
2270  Convert_Byte2 = data[++index];
2271  Convert_Byte1 = data[++index];
2272  Convert_Byte0 = data[++index];
2273 
2274  double value = Convert.float64;
2275  append(value);
2276  }
2277  else if((byte & (uint8_t)Fixed_Str_Mask) == (uint8_t)Type::Fixed_Str)
2278  {
2279  size_t length = byte & Fixed_Str_Value;
2280 
2281  if(length == 0)
2282  {
2283  append(std::string_view(""));
2284  }
2285  else
2286  {
2287  std::string_view str((char*)&data[++index], length);
2288  append(str);
2289 
2290  index += length - 1;
2291  }
2292  }
2293  else if(byte == (uint8_t)Type::Str8)
2294  {
2295  size_t length = data[++index];
2296 
2297  std::string_view str((char*)&data[++index], length);
2298  append(str);
2299 
2300  index += length - 1;
2301  }
2302  else if(byte == (uint8_t)Type::Str16)
2303  {
2304  Convert_Byte1 = data[++index];
2305  Convert_Byte0 = data[++index];
2306 
2307  size_t length = Convert.uint16;
2308  std::string_view str((char*)&data[++index], length);
2309  append(str);
2310 
2311  index += length - 1;
2312  }
2313  else if(byte == (uint8_t)Type::Str32)
2314  {
2315  Convert_Byte3 = data[++index];
2316  Convert_Byte2 = data[++index];
2317  Convert_Byte1 = data[++index];
2318  Convert_Byte0 = data[++index];
2319 
2320  size_t length = Convert.uint32;
2321  std::string_view str((char*)&data[++index], length);
2322  append(str);
2323 
2324  index += length - 1;
2325  }
2326  else if(byte == (uint8_t)Type::Bin8)
2327  {
2328  size_t length = data[++index];
2329 
2330  std::vector<uint8_t> vector(length, 0);
2331  memcpy((void*)vector.data(), (void*)&data[++index], length);
2332  index += length - 1;
2333 
2334  append(vector);
2335  }
2336  else if(byte == (uint8_t)Type::Bin16)
2337  {
2338  Convert_Byte1 = data[++index];
2339  Convert_Byte0 = data[++index];
2340 
2341  size_t length = Convert.uint16;
2342 
2343  std::vector<uint8_t> vector(length, 0);
2344  memcpy((void*)vector.data(), (void*)&data[++index], length);
2345  index += length - 1;
2346 
2347  append(vector);
2348  }
2349  else if(byte == (uint8_t)Type::Bin32)
2350  {
2351  Convert_Byte3 = data[++index];
2352  Convert_Byte2 = data[++index];
2353  Convert_Byte1 = data[++index];
2354  Convert_Byte0 = data[++index];
2355 
2356  size_t length = Convert.uint32;
2357 
2358  std::vector<uint8_t> vector(length, 0);
2359  memcpy((void*)vector.data(), (void*)&data[++index], length);
2360  index += length - 1;
2361 
2362  append(vector);
2363  }
2364  }
2365 }
2366 
2367 
2387 std::vector<uint8_t> MessagePack::serialize() noexcept
2388 {
2389  std::vector<uint8_t> vector;
2390 
2391  for(const Object& object : object_vector)
2392  {
2393  if(object.type == DataType::Null)
2394  {
2395  vector.push_back((uint8_t)Type::Nill);
2396  }
2397  else if(object.type == DataType::Bool)
2398  {
2399  vector.push_back(object.bool_
2400  ? (uint8_t)Type::True
2401  : (uint8_t)Type::False
2402  );
2403  }
2404  else if(object.type == DataType::Int64)
2405  {
2406  if(object.int64_ < 0)
2407  {
2408  if(object.int64_ >= -32)
2409  {
2410  vector.push_back((uint8_t)Type::Fixed_Int_Neg
2411  | (uint8_t)(object.int64_ & Fixed_Int_Neg_Value)
2412  );
2413  }
2414  else if(object.int64_ >= std::numeric_limits<int8_t>::min())
2415  {
2416  vector.reserve(vector.size() + 2);
2417 
2418  vector.push_back((uint8_t)Type::Int8);
2419  vector.push_back((int8_t)object.int64_);
2420  }
2421  else if(object.int64_ >= std::numeric_limits<int16_t>::min())
2422  {
2423  vector.reserve(vector.size() + 3);
2424 
2425  vector.push_back((uint8_t)Type::Int16);
2426 
2427  Convert.int16 = (int16_t)object.int64_;
2428  vector.push_back(Convert_Byte1);
2429  vector.push_back(Convert_Byte0);
2430  }
2431  else if(object.int64_ >= std::numeric_limits<int32_t>::min())
2432  {
2433  vector.reserve(vector.size() + 5);
2434 
2435  vector.push_back((uint8_t)Type::Int32);
2436 
2437  Convert.int32 = (int32_t)object.int64_;
2438  vector.push_back(Convert_Byte3);
2439  vector.push_back(Convert_Byte2);
2440  vector.push_back(Convert_Byte1);
2441  vector.push_back(Convert_Byte0);
2442  }
2443  else if(object.int64_ >= std::numeric_limits<int64_t>::min())
2444  {
2445  vector.reserve(vector.size() + 9);
2446 
2447  vector.push_back((uint8_t)Type::Int64);
2448 
2449  Convert.int64 = (int64_t)object.int64_;
2450  vector.push_back(Convert_Byte7);
2451  vector.push_back(Convert_Byte6);
2452  vector.push_back(Convert_Byte5);
2453  vector.push_back(Convert_Byte4);
2454  vector.push_back(Convert_Byte3);
2455  vector.push_back(Convert_Byte2);
2456  vector.push_back(Convert_Byte1);
2457  vector.push_back(Convert_Byte0);
2458  }
2459  }
2460  else
2461  {
2462  if(object.int64_ <= std::numeric_limits<int8_t>::max())
2463  {
2464  vector.push_back((int8_t)object.int64_);
2465  }
2466  else if(object.int64_ <= std::numeric_limits<int16_t>::max())
2467  {
2468  vector.reserve(vector.size() + 3);
2469 
2470  vector.push_back((uint8_t)Type::Int16);
2471 
2472  Convert.int16 = (int16_t)object.int64_;
2473  vector.push_back(Convert_Byte1);
2474  vector.push_back(Convert_Byte0);
2475  }
2476  else if(object.int64_ <= std::numeric_limits<int32_t>::max())
2477  {
2478  vector.reserve(vector.size() + 5);
2479 
2480  vector.push_back((uint8_t)Type::Int32);
2481 
2482  Convert.int32 = (int32_t)object.int64_;
2483  vector.push_back(Convert_Byte3);
2484  vector.push_back(Convert_Byte2);
2485  vector.push_back(Convert_Byte1);
2486  vector.push_back(Convert_Byte0);
2487  }
2488  else if(object.int64_ <= std::numeric_limits<int64_t>::max())
2489  {
2490  vector.reserve(vector.size() + 9);
2491 
2492  vector.push_back((uint8_t)Type::Int64);
2493 
2494  Convert.int64 = (int64_t)object.int64_;
2495  vector.push_back(Convert_Byte7);
2496  vector.push_back(Convert_Byte6);
2497  vector.push_back(Convert_Byte5);
2498  vector.push_back(Convert_Byte4);
2499  vector.push_back(Convert_Byte3);
2500  vector.push_back(Convert_Byte2);
2501  vector.push_back(Convert_Byte1);
2502  vector.push_back(Convert_Byte0);
2503  }
2504  }
2505  }
2506  else if(object.type == DataType::Uint64)
2507  {
2508  if(object.uint64_ <= std::numeric_limits<uint8_t>::max())
2509  {
2510  vector.reserve(vector.size() + 2);
2511 
2512  vector.push_back((uint8_t)Type::Uint8);
2513  vector.push_back((uint8_t)object.uint64_);
2514  }
2515  else if(object.uint64_ <= std::numeric_limits<uint16_t>::max())
2516  {
2517  vector.reserve(vector.size() + 3);
2518 
2519  vector.push_back((uint8_t)Type::Uint16);
2520 
2521  Convert.uint16 = (uint16_t)object.uint64_;
2522  vector.push_back(Convert_Byte1);
2523  vector.push_back(Convert_Byte0);
2524  }
2525  else if(object.uint64_ <= std::numeric_limits<uint32_t>::max())
2526  {
2527  vector.reserve(vector.size() + 5);
2528 
2529  vector.push_back((uint8_t)Type::Uint32);
2530 
2531  Convert.uint32 = (uint32_t)object.uint64_;
2532  vector.push_back(Convert_Byte3);
2533  vector.push_back(Convert_Byte2);
2534  vector.push_back(Convert_Byte1);
2535  vector.push_back(Convert_Byte0);
2536  }
2537  else
2538  {
2539  vector.reserve(vector.size() + 9);
2540 
2541  vector.push_back((uint8_t)Type::Uint64);
2542 
2543  Convert.uint64 = object.uint64_;
2544  vector.push_back(Convert_Byte7);
2545  vector.push_back(Convert_Byte6);
2546  vector.push_back(Convert_Byte5);
2547  vector.push_back(Convert_Byte4);
2548  vector.push_back(Convert_Byte3);
2549  vector.push_back(Convert_Byte2);
2550  vector.push_back(Convert_Byte1);
2551  vector.push_back(Convert_Byte0);
2552  }
2553  }
2554  else if(object.type == DataType::Float)
2555  {
2556  vector.reserve(vector.size() + 5);
2557 
2558  vector.push_back((uint8_t)Type::Float32);
2559 
2560  Convert.float32 = object.float_;
2561  vector.push_back(Convert_Byte3);
2562  vector.push_back(Convert_Byte2);
2563  vector.push_back(Convert_Byte1);
2564  vector.push_back(Convert_Byte0);
2565  }
2566  else if(object.type == DataType::Double)
2567  {
2568  vector.reserve(vector.size() + 9);
2569 
2570  vector.push_back((uint8_t)Type::Float64);
2571 
2572  Convert.float64 = object.double_;
2573  vector.push_back(Convert_Byte7);
2574  vector.push_back(Convert_Byte6);
2575  vector.push_back(Convert_Byte5);
2576  vector.push_back(Convert_Byte4);
2577  vector.push_back(Convert_Byte3);
2578  vector.push_back(Convert_Byte2);
2579  vector.push_back(Convert_Byte1);
2580  vector.push_back(Convert_Byte0);
2581  }
2582  else if(object.type == DataType::String)
2583  {
2584  const size_t string_length = object.string.size();
2585 
2586  if(string_length <= 31)
2587  {
2588  vector.reserve(string_length + 1);
2589 
2590  vector.push_back((uint8_t)Type::Fixed_Str
2591  | (uint8_t)string_length
2592  );
2593 
2594  for(const auto& c : object.string)
2595  {
2596  vector.push_back((uint8_t)c);
2597  }
2598  }
2599  else if(string_length <= std::numeric_limits<uint8_t>::max())
2600  {
2601  vector.reserve(string_length + 2);
2602 
2603  vector.push_back((uint8_t)Type::Str8);
2604  vector.push_back((uint8_t)string_length);
2605 
2606  for(const auto& c : object.string)
2607  {
2608  vector.push_back((uint8_t)c);
2609  }
2610  }
2611  else if(string_length <= std::numeric_limits<uint16_t>::max())
2612  {
2613  vector.reserve(string_length + 3);
2614 
2615  vector.push_back((uint8_t)Type::Str16);
2616 
2617  Convert.uint16 = (uint16_t)string_length;
2618  vector.push_back(Convert_Byte1);
2619  vector.push_back(Convert_Byte0);
2620 
2621  for(const auto& c : object.string)
2622  {
2623  vector.push_back((uint8_t)c);
2624  }
2625  }
2626  else if(string_length <= std::numeric_limits<uint32_t>::max())
2627  {
2628  vector.reserve(string_length + 5);
2629 
2630  vector.push_back((uint8_t)Type::Str32);
2631 
2632  Convert.uint32 = (uint32_t)string_length;
2633  vector.push_back(Convert_Byte3);
2634  vector.push_back(Convert_Byte2);
2635  vector.push_back(Convert_Byte1);
2636  vector.push_back(Convert_Byte0);
2637 
2638  for(const auto& c : object.string)
2639  {
2640  vector.push_back((uint8_t)c);
2641  }
2642  }
2643  }
2644  else if(object.type == DataType::Vector)
2645  {
2646  const size_t vector_length = object.vector.size();
2647 
2648  if(vector_length <= std::numeric_limits<uint8_t>::max())
2649  {
2650  vector.reserve(vector_length + 2);
2651 
2652  vector.push_back((uint8_t)Type::Bin8);
2653  vector.push_back((uint8_t)vector_length);
2654 
2655  vector.insert(vector.end()
2656  , object.vector.begin()
2657  , object.vector.end()
2658  );
2659  }
2660  else if(vector_length <= std::numeric_limits<uint16_t>::max())
2661  {
2662  vector.reserve(vector_length + 3);
2663 
2664  vector.push_back((uint8_t)Type::Bin16);
2665 
2666  Convert.uint16 = (uint16_t)vector_length;
2667  vector.push_back(Convert_Byte1);
2668  vector.push_back(Convert_Byte0);
2669 
2670  vector.insert(vector.end()
2671  , object.vector.begin()
2672  , object.vector.end()
2673  );
2674  }
2675  else if(vector_length <= std::numeric_limits<uint32_t>::max())
2676  {
2677  vector.reserve(vector_length + 5);
2678 
2679  vector.push_back((uint8_t)Type::Bin32);
2680 
2681  Convert.uint32 = (uint32_t)vector_length;
2682  vector.push_back(Convert_Byte3);
2683  vector.push_back(Convert_Byte2);
2684  vector.push_back(Convert_Byte1);
2685  vector.push_back(Convert_Byte0);
2686 
2687  vector.insert(vector.end()
2688  , object.vector.begin()
2689  , object.vector.end()
2690  );
2691  }
2692  }
2693  }
2694 
2695  return vector;
2696 }
2697 
2698 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST
2699 // Nothing to test
2700 #endif
2701 
2702 // }}} MessagePack
2703 // {{{ MessagePack::Object
2704 
2723 /*
2724  * \var MessagePack::Object::bool_
2725  *
2726  * \brief A value.
2727  *
2728  * \note This variable is a member of a union.
2729  */
2730 
2731 /*
2732  * \var MessagePack::Object::int64_
2733  *
2734  * \brief A value.
2735  *
2736  * \note This variable is a member of a union.
2737  */
2738 
2739 /*
2740  * \var MessagePack::Object::uint64_
2741  *
2742  * \brief A value.
2743  *
2744  * \note This variable is a member of a union.
2745  */
2746 
2747 /*
2748  * \var MessagePack::Object::float_
2749  *
2750  * \brief A value.
2751  *
2752  * \note This variable is a member of a union.
2753  */
2754 
2755 /*
2756  * \var MessagePack::Object::double_
2757  *
2758  * \brief A value.
2759  *
2760  * \note This variable is a member of a union.
2761  */
2762 
2778 MessagePack::Object::Object() noexcept
2779  : type(DataType::Null)
2780  , uint64_(0)
2781 {
2782 }
2783 
2784 
2788 MessagePack::Object::Object(const Object& object
2789  ) noexcept
2790  : type(object.type)
2791  , uint64_(0)
2792 {
2793  switch(type)
2794  {
2795  case DataType::Null: break;
2796  case DataType::Bool: bool_ = object.bool_; break;
2797  case DataType::Int64: int64_ = object.int64_; break;
2798  case DataType::Uint64: uint64_ = object.uint64_; break;
2799  case DataType::Float: float_ = object.float_; break;
2800  case DataType::Double: double_ = object.double_; break;
2801  case DataType::String: string = object.string; break;
2802  case DataType::Vector: vector = object.vector; break;
2803  }
2804 }
2805 
2806 
2810 MessagePack::Object::Object(Object&& object
2811  ) noexcept
2812  : type(object.type)
2813  , uint64_(0)
2814 {
2815  switch(type)
2816  {
2817  case DataType::Null: break;
2818  case DataType::Bool: bool_ = object.bool_; break;
2819  case DataType::Int64: int64_ = object.int64_; break;
2820  case DataType::Uint64: uint64_ = object.uint64_; break;
2821  case DataType::Float: float_ = object.float_; break;
2822  case DataType::Double: double_ = object.double_; break;
2823  case DataType::String: string = object.string; break;
2824  case DataType::Vector: vector = object.vector; break;
2825  }
2826 
2827  object.type = DataType::Null;
2828  object.uint64_ = 0;
2829  object.string.clear();
2830  object.vector.clear();
2831 }
2832 
2833 
2837 MessagePack::Object::Object(const bool value
2838  ) noexcept
2839  : type(DataType::Bool)
2840  , bool_(value)
2841 {
2842 }
2843 
2844 
2848 MessagePack::Object::Object(const int64_t value
2849  ) noexcept
2850  : type(DataType::Int64)
2851  , int64_(value)
2852 {
2853 }
2854 
2855 
2859 MessagePack::Object::Object(const uint64_t value
2860  ) noexcept
2861  : type(DataType::Uint64)
2862  , uint64_(value)
2863 {
2864 }
2865 
2866 
2870 MessagePack::Object::Object(const float value
2871  ) noexcept
2872  : type(DataType::Float)
2873  , float_(value)
2874 {
2875 }
2876 
2877 
2881 MessagePack::Object::Object(const double value
2882  ) noexcept
2883  : type(DataType::Double)
2884  , double_(value)
2885 {
2886 }
2887 
2888 
2892 MessagePack::Object::Object(const std::string_view value
2893  ) noexcept
2894  : type(DataType::String)
2895  , string(value)
2896 {
2897  //std::cout << "t: '" << (uint32_t)type << "'\n";
2898  //std::cout << "v: '" << v << "'\n";
2899  //std::cout << "s: '" << string << "'\n";
2900 }
2901 
2902 
2906 MessagePack::Object::Object(std::vector<uint8_t> value
2907  ) noexcept
2908  : type(DataType::Vector)
2909  , vector(value)
2910 {
2911 }
2912 
2913 // }}} MessagePack::Object
2914 }
2915 
2916 #endif // ZAKERO_MESSAGEPACK_IMPLEMENTATION
2917 
2918 // }}}
2919 
2920 #endif // zakero_MessagePack_h
Object and Data Serialization.
Definition: Zakero_MessagePack.h:221
Object & object(const size_t index) noexcept
Access a data object.
Definition: Zakero_MessagePack.h:2081
void append(const bool, size_t *const =nullptr) noexcept
Append a boolean value.
Definition: Zakero_MessagePack.h:511
DataType
The supported C++ data-types.
Definition: Zakero_MessagePack.h:225
void appendNull(size_t *const =nullptr) noexcept
Append a "null" value.
Definition: Zakero_MessagePack.h:1991
size_t size() noexcept
Get the number of data objects.
Definition: Zakero_MessagePack.h:2107
std::vector< uint8_t > serialize() noexcept
Serialize MessagePack data.
Definition: Zakero_MessagePack.h:2387
void clear() noexcept
Remove all data from the MessagePack.
Definition: Zakero_MessagePack.h:2091
void deserialize(const std::vector< uint8_t > &) noexcept
Deserialize MessagePack data.
Definition: Zakero_MessagePack.h:2148
A Data Object.