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, value. 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 
182 /******************************************************************************
183  * Includes
184  */
185 
186 // C++
187 #include <cstring>
188 #include <ctime>
189 #include <limits>
190 #include <string>
191 #include <system_error>
192 #include <variant>
193 #include <vector>
194 
195 // POSIX
196 #include <arpa/inet.h>
197 
198 // Linux
199 
200 
201 /******************************************************************************
202  * Macros
203  */
204 
205 // {{{ Macros
206 
223 #define ZAKERO_MESSAGEPACK__ERROR_DATA \
224  X(Error_None , 0 , "No Error" ) \
225  X(Error_Unknown , 1 , "An unknown error has occurred" ) \
226  X(Error_Incomplete , 2 , "The data to deserialize is incomplete" ) \
227  X(Error_Invalid_Format_Type , 3 , "An invalid Format Type was encountered" ) \
228  X(Error_Invalid_Index , 4 , "Invalid starting index to deserialize" ) \
229  X(Error_No_Data , 5 , "No data to deserialize" ) \
230  X(Error_Array_Too_Big , 6 , "The array is too large to serialize" ) \
231  X(Error_Ext_Too_Big , 7 , "The extension is too large to serialize" ) \
232  X(Error_Map_Too_Big , 8 , "The map is too large to serialize" ) \
233 
234 // }}}
235 
236 
237 /******************************************************************************
238  * Objects
239  */
240 
241 namespace zakero::messagepack
242 {
243  // {{{ Error
244 
246  : public std::error_category
247  {
248  public:
249  constexpr ErrorCategory_() noexcept {};
250 
251  [[nodiscard]] const char* name() const noexcept final override;
252  [[nodiscard]] std::string message(int condition) const noexcept final override;
253  };
254 
255  extern ErrorCategory_ ErrorCategory;
256 
257 #define X(name_, val_, mesg_) \
258  const std::error_code name_(val_, ErrorCategory);
259  ZAKERO_MESSAGEPACK__ERROR_DATA
260 #undef X
261 
262  // }}}
263 
264  struct Array;
265  struct Ext;
266  struct Map;
267  struct Object;
268 
269  // {{{ Array
270 
271  struct Array
272  {
273  [[]] size_t append(const bool) noexcept;
274  [[]] size_t append(const int64_t) noexcept;
275  [[]] size_t append(const uint64_t) noexcept;
276  [[]] size_t append(const float) noexcept;
277  [[]] size_t append(const double) noexcept;
278  [[]] size_t append(const std::string_view) noexcept;
279  [[]] size_t append(const std::vector<uint8_t>&) noexcept;
280  [[]] size_t append(std::vector<uint8_t>&) noexcept;
281  [[]] size_t append(const Array&) noexcept;
282  [[]] size_t append(Array&) noexcept;
283  [[]] size_t append(const Ext&) noexcept;
284  [[]] size_t append(Ext&) noexcept;
285  [[]] size_t append(const Map&) noexcept;
286  [[]] size_t append(Map&) noexcept;
287  [[]] size_t append(const Object&) noexcept;
288  [[]] size_t append(Object&) noexcept;
289  [[]] size_t appendNull() noexcept;
290 
291  [[nodiscard]] inline Object& object(const size_t index) noexcept { return object_vector[index]; }
292  [[nodiscard]] inline const Object& object(const size_t index) const noexcept { return object_vector[index]; }
293 
294  [[]] inline void clear() noexcept { return object_vector.clear(); };
295  [[nodiscard]] inline size_t size() const noexcept { return object_vector.size(); };
296 
297  std::vector<Object> object_vector = {};
298  };
299 
300  // }}} Array
301  // {{{ Ext
302 
303  struct Ext
304  {
305  std::vector<uint8_t> data = {};
306  int8_t type = 0;
307  };
308 
309  // }}} Ext
310  // {{{ Map
311 
312  struct Map
313  {
314  [[]] std::error_code set(Object&, Object&) noexcept;
315  [[]] std::error_code set(const Object&, const Object&) noexcept;
316  [[nodiscard]] bool keyExists(const Object&) const noexcept;
317  [[nodiscard]] Object& at(Object&) noexcept;
318  [[nodiscard]] const Object& at(const Object&) const noexcept;
319 
320  [[]] void erase(const Object&) noexcept;
321  [[]] inline void clear() noexcept;
322  [[nodiscard]] inline size_t size() const noexcept;
323 
324  std::vector<Object> null_map = {};
325  std::map<bool, Object> bool_map = {};
326  std::map<int64_t, Object> int64_map = {};
327  std::map<uint64_t, Object> uint64_map = {};
328  std::map<float, Object> float_map = {};
329  std::map<double, Object> double_map = {};
330  std::map<std::string, Object> string_map = {};
331  };
332 
333  // }}} Map
334  // {{{ Object
335 
336  struct Object
337  {
338  std::variant<std::monostate
339  , bool
340  , int64_t
341  , uint64_t
342  , float
343  , double
344  , std::string
345  , std::vector<uint8_t>
349  > value;
350 
351  template<typename T>
352  [[nodiscard]] T& as() noexcept { return std::get<T>(value); };
353  template<typename T>
354  [[nodiscard]] const T& as() const noexcept { return std::get<T>(value); };
355 
356  [[nodiscard]] messagepack::Array& asArray() noexcept { return std::get<messagepack::Array>(value); };
357  [[nodiscard]] const messagepack::Array& asArray() const noexcept { return std::get<messagepack::Array>(value); };
358  [[nodiscard]] messagepack::Ext& asExt() noexcept { return std::get<messagepack::Ext>(value); };
359  [[nodiscard]] const messagepack::Ext& asExt() const noexcept { return std::get<messagepack::Ext>(value); };
360  [[nodiscard]] messagepack::Map& asMap() noexcept { return std::get<messagepack::Map>(value); };
361  [[nodiscard]] const messagepack::Map& asMap() const noexcept { return std::get<messagepack::Map>(value); };
362  [[nodiscard]] std::vector<uint8_t>& asBinary() noexcept { return std::get<std::vector<uint8_t>>(value); };
363  [[nodiscard]] const std::vector<uint8_t>& asBinary() const noexcept { return std::get<std::vector<uint8_t>>(value); };
364  [[nodiscard]] const std::string& asString() const noexcept { return std::get<std::string>(value); };
365 
366  template<typename T>
367  [[nodiscard]] constexpr bool is() const noexcept { return std::holds_alternative<T>(value); };
368 
369  [[nodiscard]] constexpr bool isArray() const noexcept { return std::holds_alternative<messagepack::Array>(value); };
370  [[nodiscard]] constexpr bool isBinary() const noexcept { return std::holds_alternative<std::vector<uint8_t>>(value); };
371  [[nodiscard]] constexpr bool isExt() const noexcept { return std::holds_alternative<messagepack::Ext>(value); };
372  [[nodiscard]] constexpr bool isMap() const noexcept { return std::holds_alternative<messagepack::Map>(value); };
373  [[nodiscard]] constexpr bool isNull() const noexcept { return std::holds_alternative<std::monostate>(value); };
374  [[nodiscard]] constexpr bool isString() const noexcept { return std::holds_alternative<std::string>(value); };
375  };
376 
377  // }}} Object
378  // {{{ Extensions
379 
380  [[nodiscard]] bool extensionTimestampCheck(const Object&) noexcept;
381  [[nodiscard]] struct timespec extensionTimestampConvert(const Object&) noexcept;
382  [[nodiscard]] Object extensionTimestampConvert(const struct timespec&) noexcept;
383 
384  // }}} Extensions
385  // {{{ Utilities
386 
387  [[nodiscard]] Object deserialize(const std::vector<uint8_t>&) noexcept;
388  [[nodiscard]] Object deserialize(const std::vector<uint8_t>&, std::error_code&) noexcept;
389  [[nodiscard]] Object deserialize(const std::vector<uint8_t>&, size_t&) noexcept;
390  [[nodiscard]] Object deserialize(const std::vector<uint8_t>&, size_t&, std::error_code&) noexcept;
391  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Array&) noexcept;
392  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Array&, std::error_code&) noexcept;
393  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Ext&) noexcept;
394  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Ext&, std::error_code&) noexcept;
395  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Map&) noexcept;
396  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Map&, std::error_code&) noexcept;
397  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Object&) noexcept;
398  [[nodiscard]] std::vector<uint8_t> serialize(const messagepack::Object&, std::error_code&) noexcept;
399  [[nodiscard]] std::string to_string(const messagepack::Array&) noexcept;
400  [[nodiscard]] std::string to_string(const messagepack::Ext&) noexcept;
401  [[nodiscard]] std::string to_string(const messagepack::Map&) noexcept;
402  [[nodiscard]] std::string to_string(const messagepack::Object&) noexcept;
403 
404  // }}} Utilities
405 } // zakero::messagepack
406 
407 // {{{ Operators
408 
409 std::ostream& operator<<(std::ostream&, const zakero::messagepack::Array&) noexcept;
410 std::ostream& operator<<(std::ostream&, const zakero::messagepack::Ext&) noexcept;
411 std::ostream& operator<<(std::ostream&, const zakero::messagepack::Map&) noexcept;
412 std::ostream& operator<<(std::ostream&, const zakero::messagepack::Object&) noexcept;
413 
414 bool operator==(const zakero::messagepack::Object& lhs, const zakero::messagepack::Object& rhs) noexcept;
415 bool operator!=(const zakero::messagepack::Object& lhs, const zakero::messagepack::Object& rhs) noexcept;
416 
417 // }}}
418 // {{{ Implementation
419 
420 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION
421 
422 // {{{ Macros
423 // {{{ Macros : Doxygen
424 
425 #ifdef ZAKERO__DOXYGEN_DEFINE_DOCS
426 
427 // Only used for generating Doxygen documentation
428 
439 #define ZAKERO_MESSAGEPACK_IMPLEMENTATION
440 
447 #endif
448 
449 // }}}
450 
463 #define ZAKERO_MESSAGEPACK__FORMAT_TYPE \
464  /* Variable Id Mask Size Name */ \
465  X(Fixed_Int_Pos , 0x00 , 0b10000000 , 1 , "positive fixint" ) \
466  X(Fixed_Map , 0x80 , 0b11110000 , 1 , "fixmap" ) \
467  X(Fixed_Array , 0x90 , 0b11110000 , 1 , "fixarray" ) \
468  X(Fixed_Str , 0xa0 , 0b11100000 , 1 , "fixstr" ) \
469  X(Nill , 0xc0 , 0b11111111 , 1 , "nill" ) \
470  X(Never_Used , 0xc1 , 0b11111111 , 1 , "(never used)" ) \
471  X(False , 0xc2 , 0b11111111 , 1 , "false" ) \
472  X(True , 0xc3 , 0b11111111 , 1 , "true" ) \
473  X(Bin8 , 0xc4 , 0b11111111 , 2 , "bin 8" ) \
474  X(Bin16 , 0xc5 , 0b11111111 , 259 , "bin 16" ) \
475  X(Bin32 , 0xc6 , 0b11111111 , 65541 , "bin 32" ) \
476  X(Ext8 , 0xc7 , 0b11111111 , 3 , "ext 8" ) \
477  X(Ext16 , 0xc8 , 0b11111111 , 260 , "ext 16" ) \
478  X(Ext32 , 0xc9 , 0b11111111 , 65542 , "ext 32" ) \
479  X(Float32 , 0xca , 0b11111111 , 5 , "float 32" ) \
480  X(Float64 , 0xcb , 0b11111111 , 9 , "float 64" ) \
481  X(Uint8 , 0xcc , 0b11111111 , 2 , "uint 8" ) \
482  X(Uint16 , 0xcd , 0b11111111 , 3 , "uint 16" ) \
483  X(Uint32 , 0xce , 0b11111111 , 5 , "uint 32" ) \
484  X(Uint64 , 0xcf , 0b11111111 , 9 , "uint 64" ) \
485  X(Int8 , 0xd0 , 0b11111111 , 2 , "int 8" ) \
486  X(Int16 , 0xd1 , 0b11111111 , 3 , "int 16" ) \
487  X(Int32 , 0xd2 , 0b11111111 , 5 , "int 32" ) \
488  X(Int64 , 0xd3 , 0b11111111 , 9 , "int 64" ) \
489  X(Fixed_Ext1 , 0xd4 , 0b11111111 , 3 , "fixext 1" ) \
490  X(Fixed_Ext2 , 0xd5 , 0b11111111 , 4 , "fixext 2" ) \
491  X(Fixed_Ext4 , 0xd6 , 0b11111111 , 6 , "fixext 4" ) \
492  X(Fixed_Ext8 , 0xd7 , 0b11111111 , 10 , "fixext 8" ) \
493  X(Fixed_Ext16 , 0xd8 , 0b11111111 , 18 , "fixext 16" ) \
494  X(Str8 , 0xd9 , 0b11111111 , 34 , "str 8" ) \
495  X(Str16 , 0xda , 0b11111111 , 259 , "str 16" ) \
496  X(Str32 , 0xdb , 0b11111111 , 65541 , "str 32" ) \
497  X(Array16 , 0xdc , 0b11111111 , 19 , "array 16" ) \
498  X(Array32 , 0xdd , 0b11111111 , 65541 , "array 32" ) \
499  X(Map16 , 0xde , 0b11111111 , 35 , "map 16" ) \
500  X(Map32 , 0xdf , 0b11111111 , 327429 , "map 32" ) \
501  X(Fixed_Int_Neg , 0xe0 , 0b11100000 , 1 , "negative fixint" ) \
502 
508 // }}}
509 
510 namespace zakero::messagepack
511 {
512 // {{{ Documentation
513 
520 // }}}
521 // {{{ Anonymous Namespace
522 
523 namespace
524 {
528  enum class Format : uint8_t
529  {
530 #define X(type_, id_, mask_, size_, text_) \
531  type_ = id_, \
532 
533  ZAKERO_MESSAGEPACK__FORMAT_TYPE
534 #undef X
535  };
536 
537 
557 #define X(type_, id_, mask_, size_, text_) \
558  constexpr uint8_t type_ ## _Mask = mask_; \
559 
560  ZAKERO_MESSAGEPACK__FORMAT_TYPE
561 #undef X
571 #define X(type_, id_, mask_, size_, text_) \
572  constexpr uint8_t type_ ## _Value = (uint8_t)~mask_;\
573 
574  ZAKERO_MESSAGEPACK__FORMAT_TYPE
575 #undef X
584  union
585  {
586  uint64_t uint64;
587  uint32_t uint32;
588  uint16_t uint16;
589  uint8_t uint8;
590  int64_t int64;
591  int32_t int32;
592  int16_t int16;
593  int8_t int8;
594  float float32;
595  double float64;
596  uint8_t uint8_[8];
597  } Convert;
598 
599 
604 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
605  uint8_t& Convert_Byte0 = Convert.uint8_[7];
606  uint8_t& Convert_Byte1 = Convert.uint8_[6];
607  uint8_t& Convert_Byte2 = Convert.uint8_[5];
608  uint8_t& Convert_Byte3 = Convert.uint8_[4];
609  uint8_t& Convert_Byte4 = Convert.uint8_[3];
610  uint8_t& Convert_Byte5 = Convert.uint8_[2];
611  uint8_t& Convert_Byte6 = Convert.uint8_[1];
612  uint8_t& Convert_Byte7 = Convert.uint8_[0];
613 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
614  uint8_t& Convert_Byte0 = Convert.uint8_[0];
615  uint8_t& Convert_Byte1 = Convert.uint8_[1];
616  uint8_t& Convert_Byte2 = Convert.uint8_[2];
617  uint8_t& Convert_Byte3 = Convert.uint8_[3];
618  uint8_t& Convert_Byte4 = Convert.uint8_[4];
619  uint8_t& Convert_Byte5 = Convert.uint8_[5];
620  uint8_t& Convert_Byte6 = Convert.uint8_[6];
621  uint8_t& Convert_Byte7 = Convert.uint8_[7];
622 #endif
633  constexpr size_t formatSize(Format id
634  ) noexcept
635  {
636  switch(id)
637  {
638 #define X(type_, id_, mask_, size_, text_) \
639  case Format::type_: return size_;
640  ZAKERO_MESSAGEPACK__FORMAT_TYPE
641 #undef X
642  default: return 0;
643  }
644  }
645 
646  std::error_code serialize_(const messagepack::Array&, std::vector<uint8_t>&) noexcept;
647  std::error_code serialize_(const messagepack::Ext&, std::vector<uint8_t>&) noexcept;
648  std::error_code serialize_(const messagepack::Map&, std::vector<uint8_t>&) noexcept;
649 
658  std::error_code serialize_(const messagepack::Object& object
659  , std::vector<uint8_t>& vector
660  ) noexcept
661  {
662  if(object.isNull())
663  {
664  vector.push_back((uint8_t)Format::Nill);
665 
666  return Error_None;
667  }
668 
669  if(object.is<bool>())
670  {
671  vector.push_back(object.as<bool>()
672  ? (uint8_t)Format::True
673  : (uint8_t)Format::False
674  );
675 
676  return Error_None;
677  }
678 
679  if(object.is<int64_t>())
680  {
681  const int64_t value = object.as<int64_t>();
682 
683  if(value < 0)
684  {
685  if(value >= -32)
686  {
687  vector.push_back((uint8_t)Format::Fixed_Int_Neg
688  | (uint8_t)(value & Fixed_Int_Neg_Value)
689  );
690  }
691  else if(value >= std::numeric_limits<int8_t>::min())
692  {
693  vector.reserve(vector.size() + 2);
694 
695  vector.push_back((uint8_t)Format::Int8);
696  vector.push_back((int8_t)value);
697  }
698  else if(value >= std::numeric_limits<int16_t>::min())
699  {
700  vector.reserve(vector.size() + 3);
701 
702  vector.push_back((uint8_t)Format::Int16);
703 
704  Convert.int16 = (int16_t)value;
705  vector.push_back(Convert_Byte1);
706  vector.push_back(Convert_Byte0);
707  }
708  else if(value >= std::numeric_limits<int32_t>::min())
709  {
710  vector.reserve(vector.size() + 5);
711 
712  vector.push_back((uint8_t)Format::Int32);
713 
714  Convert.int32 = (int32_t)value;
715  vector.push_back(Convert_Byte3);
716  vector.push_back(Convert_Byte2);
717  vector.push_back(Convert_Byte1);
718  vector.push_back(Convert_Byte0);
719  }
720  else if(value >= std::numeric_limits<int64_t>::min())
721  {
722  vector.reserve(vector.size() + 9);
723 
724  vector.push_back((uint8_t)Format::Int64);
725 
726  Convert.int64 = (int64_t)value;
727  vector.push_back(Convert_Byte7);
728  vector.push_back(Convert_Byte6);
729  vector.push_back(Convert_Byte5);
730  vector.push_back(Convert_Byte4);
731  vector.push_back(Convert_Byte3);
732  vector.push_back(Convert_Byte2);
733  vector.push_back(Convert_Byte1);
734  vector.push_back(Convert_Byte0);
735  }
736  }
737  else
738  {
739  if(value <= std::numeric_limits<int8_t>::max())
740  {
741  vector.push_back((int8_t)value);
742  }
743  else if(value <= std::numeric_limits<int16_t>::max())
744  {
745  vector.reserve(vector.size() + 3);
746 
747  vector.push_back((uint8_t)Format::Int16);
748 
749  Convert.int16 = (int16_t)value;
750  vector.push_back(Convert_Byte1);
751  vector.push_back(Convert_Byte0);
752  }
753  else if(value <= std::numeric_limits<int32_t>::max())
754  {
755  vector.reserve(vector.size() + 5);
756 
757  vector.push_back((uint8_t)Format::Int32);
758 
759  Convert.int32 = (int32_t)value;
760  vector.push_back(Convert_Byte3);
761  vector.push_back(Convert_Byte2);
762  vector.push_back(Convert_Byte1);
763  vector.push_back(Convert_Byte0);
764  }
765  else if(value <= std::numeric_limits<int64_t>::max())
766  {
767  vector.reserve(vector.size() + 9);
768 
769  vector.push_back((uint8_t)Format::Int64);
770 
771  Convert.int64 = (int64_t)value;
772  vector.push_back(Convert_Byte7);
773  vector.push_back(Convert_Byte6);
774  vector.push_back(Convert_Byte5);
775  vector.push_back(Convert_Byte4);
776  vector.push_back(Convert_Byte3);
777  vector.push_back(Convert_Byte2);
778  vector.push_back(Convert_Byte1);
779  vector.push_back(Convert_Byte0);
780  }
781  }
782 
783  return Error_None;
784  }
785 
786  if(object.is<uint64_t>())
787  {
788  const uint64_t value = object.as<uint64_t>();
789 
790  if(value <= std::numeric_limits<uint8_t>::max())
791  {
792  vector.reserve(vector.size() + 2);
793 
794  vector.push_back((uint8_t)Format::Uint8);
795  vector.push_back((uint8_t)value);
796  }
797  else if(value <= std::numeric_limits<uint16_t>::max())
798  {
799  vector.reserve(vector.size() + 3);
800 
801  vector.push_back((uint8_t)Format::Uint16);
802 
803  Convert.uint16 = (uint16_t)value;
804  vector.push_back(Convert_Byte1);
805  vector.push_back(Convert_Byte0);
806  }
807  else if(value <= std::numeric_limits<uint32_t>::max())
808  {
809  vector.reserve(vector.size() + 5);
810 
811  vector.push_back((uint8_t)Format::Uint32);
812 
813  Convert.uint32 = (uint32_t)value;
814  vector.push_back(Convert_Byte3);
815  vector.push_back(Convert_Byte2);
816  vector.push_back(Convert_Byte1);
817  vector.push_back(Convert_Byte0);
818  }
819  else
820  {
821  vector.reserve(vector.size() + 9);
822 
823  vector.push_back((uint8_t)Format::Uint64);
824 
825  Convert.uint64 = value;
826  vector.push_back(Convert_Byte7);
827  vector.push_back(Convert_Byte6);
828  vector.push_back(Convert_Byte5);
829  vector.push_back(Convert_Byte4);
830  vector.push_back(Convert_Byte3);
831  vector.push_back(Convert_Byte2);
832  vector.push_back(Convert_Byte1);
833  vector.push_back(Convert_Byte0);
834  }
835 
836  return Error_None;
837  }
838 
839  if(object.is<float>())
840  {
841  float value = object.as<float>();
842 
843  vector.reserve(vector.size() + 5);
844 
845  vector.push_back((uint8_t)Format::Float32);
846 
847  Convert.float32 = value;
848  vector.push_back(Convert_Byte3);
849  vector.push_back(Convert_Byte2);
850  vector.push_back(Convert_Byte1);
851  vector.push_back(Convert_Byte0);
852 
853  return Error_None;
854  }
855 
856  if(object.is<double>())
857  {
858  double value = object.as<double>();
859 
860  vector.push_back((uint8_t)Format::Float64);
861 
862  Convert.float64 = value;
863  vector.push_back(Convert_Byte7);
864  vector.push_back(Convert_Byte6);
865  vector.push_back(Convert_Byte5);
866  vector.push_back(Convert_Byte4);
867  vector.push_back(Convert_Byte3);
868  vector.push_back(Convert_Byte2);
869  vector.push_back(Convert_Byte1);
870  vector.push_back(Convert_Byte0);
871 
872  return Error_None;
873  }
874 
875  if(object.isString())
876  {
877  const std::string& value = object.asString();
878 
879  const size_t string_length = value.size();
880 
881  if(string_length <= 31)
882  {
883  vector.reserve(string_length + 1);
884 
885  vector.push_back((uint8_t)Format::Fixed_Str
886  | (uint8_t)string_length
887  );
888 
889  for(const auto& c : value)
890  {
891  vector.push_back((uint8_t)c);
892  }
893  }
894  else if(string_length <= std::numeric_limits<uint8_t>::max())
895  {
896  vector.reserve(string_length + 2);
897 
898  vector.push_back((uint8_t)Format::Str8);
899  vector.push_back((uint8_t)string_length);
900 
901  for(const auto& c : value)
902  {
903  vector.push_back((uint8_t)c);
904  }
905  }
906  else if(string_length <= std::numeric_limits<uint16_t>::max())
907  {
908  vector.reserve(string_length + 3);
909 
910  vector.push_back((uint8_t)Format::Str16);
911 
912  Convert.uint16 = (uint16_t)string_length;
913  vector.push_back(Convert_Byte1);
914  vector.push_back(Convert_Byte0);
915 
916  for(const auto& c : value)
917  {
918  vector.push_back((uint8_t)c);
919  }
920  }
921  else if(string_length <= std::numeric_limits<uint32_t>::max())
922  {
923  vector.reserve(string_length + 5);
924 
925  vector.push_back((uint8_t)Format::Str32);
926 
927  Convert.uint32 = (uint32_t)string_length;
928  vector.push_back(Convert_Byte3);
929  vector.push_back(Convert_Byte2);
930  vector.push_back(Convert_Byte1);
931  vector.push_back(Convert_Byte0);
932 
933  for(const auto& c : value)
934  {
935  vector.push_back((uint8_t)c);
936  }
937  }
938 
939  return Error_None;
940  }
941 
942  if(object.isBinary())
943  {
944  const std::vector<uint8_t>& value = object.asBinary();
945 
946  const size_t vector_length = value.size();
947 
948  if(vector_length <= std::numeric_limits<uint8_t>::max())
949  {
950  vector.reserve(vector_length + 2);
951 
952  vector.push_back((uint8_t)Format::Bin8);
953  vector.push_back((uint8_t)vector_length);
954 
955  vector.insert(vector.end()
956  , value.begin()
957  , value.end()
958  );
959  }
960  else if(vector_length <= std::numeric_limits<uint16_t>::max())
961  {
962  vector.reserve(vector_length + 3);
963 
964  vector.push_back((uint8_t)Format::Bin16);
965 
966  Convert.uint16 = (uint16_t)vector_length;
967  vector.push_back(Convert_Byte1);
968  vector.push_back(Convert_Byte0);
969 
970  vector.insert(vector.end()
971  , value.begin()
972  , value.end()
973  );
974  }
975  else if(vector_length <= std::numeric_limits<uint32_t>::max())
976  {
977  vector.reserve(vector_length + 5);
978 
979  vector.push_back((uint8_t)Format::Bin32);
980 
981  Convert.uint32 = (uint32_t)vector_length;
982  vector.push_back(Convert_Byte3);
983  vector.push_back(Convert_Byte2);
984  vector.push_back(Convert_Byte1);
985  vector.push_back(Convert_Byte0);
986 
987  vector.insert(vector.end()
988  , value.begin()
989  , value.end()
990  );
991  }
992 
993  return Error_None;
994  }
995 
996  if(object.isArray())
997  {
998  const messagepack::Array& array = object.asArray();
999 
1000  std::error_code error = serialize_(array, vector);
1001 
1002  return error;
1003  }
1004 
1005  if(object.isExt())
1006  {
1007  const messagepack::Ext& ext = object.asExt();
1008 
1009  std::error_code error = serialize_(ext, vector);
1010 
1011  return error;
1012  }
1013 
1014  if(object.isMap())
1015  {
1016  const messagepack::Map& map = object.asMap();
1017 
1018  std::error_code error = serialize_(map, vector);
1019 
1020  return error;
1021  }
1022 
1023  return Error_Invalid_Format_Type;
1024  }
1025 
1026 
1035  std::error_code serialize_(const messagepack::Array& array
1036  , std::vector<uint8_t>& vector
1037  ) noexcept
1038  {
1039  const size_t array_size = array.size();
1040 
1041  if(array_size < 16)
1042  {
1043  vector.push_back((uint8_t)Format::Fixed_Array
1044  | (uint8_t)array_size
1045  );
1046  }
1047  else if(array_size <= std::numeric_limits<uint16_t>::max())
1048  {
1049  vector.push_back((uint8_t)Format::Array16);
1050 
1051  Convert.uint16 = (uint16_t)array_size;
1052  vector.push_back(Convert_Byte1);
1053  vector.push_back(Convert_Byte0);
1054  }
1055  else if(array_size <= std::numeric_limits<uint32_t>::max())
1056  {
1057  vector.push_back((uint8_t)Format::Array32);
1058 
1059  Convert.uint32 = (uint32_t)array_size;
1060  vector.push_back(Convert_Byte3);
1061  vector.push_back(Convert_Byte2);
1062  vector.push_back(Convert_Byte1);
1063  vector.push_back(Convert_Byte0);
1064  }
1065  else
1066  {
1067  return Error_Array_Too_Big;
1068  }
1069 
1070  for(const messagepack::Object& object : array.object_vector)
1071  {
1072  std::error_code error = serialize_(object, vector);
1073 
1074  if(error)
1075  {
1076  return error;
1077  }
1078  }
1079 
1080  return Error_None;
1081  }
1082 
1083 
1092  std::error_code serialize_(const messagepack::Ext& ext
1093  , std::vector<uint8_t>& vector
1094  ) noexcept
1095  {
1096  const size_t data_size = ext.data.size();
1097 
1098  if(data_size == 1)
1099  {
1100  vector.push_back((uint8_t)Format::Fixed_Ext1);
1101  }
1102  else if(data_size == 2)
1103  {
1104  vector.push_back((uint8_t)Format::Fixed_Ext2);
1105  }
1106  else if(data_size == 4)
1107  {
1108  vector.push_back((uint8_t)Format::Fixed_Ext4);
1109  }
1110  else if(data_size == 8)
1111  {
1112  vector.push_back((uint8_t)Format::Fixed_Ext8);
1113  }
1114  else if(data_size == 16)
1115  {
1116  vector.push_back((uint8_t)Format::Fixed_Ext16);
1117  }
1118  else if(data_size == 0
1119  || data_size <= std::numeric_limits<uint8_t>::max()
1120  )
1121  {
1122  vector.push_back((uint8_t)Format::Ext8);
1123  vector.push_back((uint8_t)data_size);
1124  }
1125  else if(data_size <= std::numeric_limits<uint16_t>::max())
1126  {
1127  vector.push_back((uint8_t)Format::Ext16);
1128 
1129  Convert.uint64 = data_size;
1130  vector.push_back(Convert_Byte1);
1131  vector.push_back(Convert_Byte0);
1132  }
1133  else if(data_size <= std::numeric_limits<uint32_t>::max())
1134  {
1135  vector.push_back((uint8_t)Format::Ext32);
1136 
1137  Convert.uint64 = data_size;
1138  vector.push_back(Convert_Byte3);
1139  vector.push_back(Convert_Byte2);
1140  vector.push_back(Convert_Byte1);
1141  vector.push_back(Convert_Byte0);
1142  }
1143  else
1144  {
1145  return Error_Ext_Too_Big;
1146  }
1147 
1148  Convert.uint64 = 0;
1149  Convert.int8 = ext.type;
1150  vector.push_back(Convert.uint8);
1151 
1152  if(data_size > 0)
1153  {
1154  size_t index = vector.size();
1155  vector.resize(vector.size() + data_size);
1156  memcpy((void*)(vector.data() + index), (void*)ext.data.data(), data_size);
1157  }
1158 
1159  return Error_None;
1160  }
1161 
1162 
1171  std::error_code serialize_(const messagepack::Map& map
1172  , std::vector<uint8_t>& vector
1173  ) noexcept
1174  {
1175  const size_t map_size = map.size();
1176 
1177  if(map_size < 16)
1178  {
1179  vector.push_back((uint8_t)Format::Fixed_Map
1180  | (uint8_t)map_size
1181  );
1182  }
1183  else if(map_size <= std::numeric_limits<uint16_t>::max())
1184  {
1185  vector.push_back((uint8_t)Format::Map16);
1186 
1187  Convert.uint16 = (uint16_t)map_size;
1188  vector.push_back(Convert_Byte1);
1189  vector.push_back(Convert_Byte0);
1190  }
1191  else if(map_size <= std::numeric_limits<uint32_t>::max())
1192  {
1193  vector.push_back((uint8_t)Format::Map32);
1194 
1195  Convert.uint32 = (uint32_t)map_size;
1196  vector.push_back(Convert_Byte3);
1197  vector.push_back(Convert_Byte2);
1198  vector.push_back(Convert_Byte1);
1199  vector.push_back(Convert_Byte0);
1200  }
1201  else
1202  {
1203  return Error_Map_Too_Big;
1204  }
1205 
1206  std::error_code error = Error_None;
1207 
1208  if(map.null_map.empty() == false)
1209  {
1210  error = serialize_(Object{}, vector);
1211 
1212  if(error)
1213  {
1214  return error;
1215  }
1216 
1217  error = serialize_(map.null_map[0], vector);
1218 
1219  if(error)
1220  {
1221  return error;
1222  }
1223  }
1224 
1225  for(const auto& [key, value] : map.bool_map)
1226  {
1227  error = serialize_(Object{key}, vector);
1228 
1229  if(error)
1230  {
1231  return error;
1232  }
1233 
1234  error = serialize_(value, vector);
1235 
1236  if(error)
1237  {
1238  return error;
1239  }
1240  }
1241 
1242  for(const auto& [key, value] : map.int64_map)
1243  {
1244  error = serialize_(Object{key}, vector);
1245 
1246  if(error)
1247  {
1248  return error;
1249  }
1250 
1251  error = serialize_(value, vector);
1252 
1253  if(error)
1254  {
1255  return error;
1256  }
1257  }
1258 
1259  for(const auto& [key, value] : map.uint64_map)
1260  {
1261  error = serialize_(Object{key}, vector);
1262 
1263  if(error)
1264  {
1265  return error;
1266  }
1267 
1268  error = serialize_(value, vector);
1269 
1270  if(error)
1271  {
1272  return error;
1273  }
1274  }
1275 
1276  for(const auto& [key, value] : map.float_map)
1277  {
1278  error = serialize_(Object{key}, vector);
1279 
1280  if(error)
1281  {
1282  return error;
1283  }
1284 
1285  error = serialize_(value, vector);
1286 
1287  if(error)
1288  {
1289  return error;
1290  }
1291  }
1292 
1293  for(const auto& [key, value] : map.double_map)
1294  {
1295  error = serialize_(Object{key}, vector);
1296 
1297  if(error)
1298  {
1299  return error;
1300  }
1301 
1302  error = serialize_(value, vector);
1303 
1304  if(error)
1305  {
1306  return error;
1307  }
1308  }
1309 
1310  for(const auto& [key, value] : map.string_map)
1311  {
1312  error = serialize_(Object{key}, vector);
1313 
1314  if(error)
1315  {
1316  return error;
1317  }
1318 
1319  error = serialize_(value, vector);
1320 
1321  if(error)
1322  {
1323  return error;
1324  }
1325  }
1326 
1327  return Error_None;
1328  }
1329 }
1330 
1331 // }}}
1332 // {{{ Error
1333 
1356 const char* ErrorCategory_::name() const noexcept
1357 {
1358  return "zakero::messagepack";
1359 }
1360 
1361 
1367 std::string ErrorCategory_::message(int condition
1368  ) const noexcept
1369 {
1370  switch(condition)
1371  {
1372 #define X(name_, val_, mesg_) \
1373  case val_: return mesg_;
1374  ZAKERO_MESSAGEPACK__ERROR_DATA
1375 #undef X
1376  }
1377 
1378  return "Unknown error condition";
1379 }
1380 
1381 
1387 ErrorCategory_ ErrorCategory;
1388 
1389 // }}}
1390 // {{{ Array
1391 
1429 size_t Array::append(const bool value
1430  ) noexcept
1431 {
1432  const size_t index = object_vector.size();
1433 
1434  object_vector.emplace_back(Object{value});
1435 
1436  return index;
1437 }
1438 
1439 
1440 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1441 TEST_CASE("array/append/bool")
1442 {
1443  Array array;
1444 
1445  size_t index = array.append(true);
1446 
1447  CHECK(index == 0);
1448  CHECK(array.size() == 1);
1449 
1450  index = array.append(false);
1451 
1452  CHECK(index == 1);
1453  CHECK(array.size() == 2);
1454 
1455  // Check serialized data
1456 
1457  std::vector<uint8_t> data = serialize(array);
1458  CHECK(data.size() == 3);
1459 
1460  index = 0;
1461  CHECK((data[index] & Fixed_Array_Mask) == (uint8_t)Format::Fixed_Array);
1462  CHECK((data[index++] & Fixed_Array_Value) == 2);
1463  CHECK(data[index++] == (uint8_t)Format::True);
1464  CHECK(data[index++] == (uint8_t)Format::False);
1465 
1466  // Check deserialized data
1467 
1468  Object object = deserialize(data);
1469 
1470  CHECK(object.isArray());
1471  Array& test = object.asArray();
1472  CHECK(test.size() == 2);
1473 
1474  {
1475  const messagepack::Object& object = array.object(0);
1476  CHECK(object.is<bool>());
1477  CHECK(object.as<bool>() == true);
1478  }
1479 
1480  {
1481  const messagepack::Object& object = array.object(1);
1482  CHECK(object.is<bool>());
1483  CHECK(object.as<bool>() == false);
1484  }
1485 }
1486 #endif // }}}
1487 
1488 
1501 size_t Array::append(const int64_t value
1502  ) noexcept
1503 {
1504  const size_t index = object_vector.size();
1505 
1506  object_vector.emplace_back(Object{value});
1507 
1508  return index;
1509 }
1510 
1511 
1512 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1513 TEST_CASE("array/append/int64_t")
1514 {
1515  const int64_t i8_min = -31;
1516  const int64_t i8_max = 127;
1517  const int64_t i16_min = std::numeric_limits<int16_t>::min();
1518  const int64_t i16_max = std::numeric_limits<int16_t>::max();
1519  const int64_t i32_min = std::numeric_limits<int32_t>::min();
1520  const int64_t i32_max = std::numeric_limits<int32_t>::max();
1521  const int64_t i64_min = std::numeric_limits<int64_t>::min();
1522  const int64_t i64_max = std::numeric_limits<int64_t>::max();
1523  size_t count = 0;
1524 
1525  Array array;
1526  array.append(i8_min); count++;
1527  array.append(i8_max); count++;
1528  array.append(i16_min); count++;
1529  array.append(i16_max); count++;
1530  array.append(i32_min); count++;
1531  array.append(i32_max); count++;
1532  array.append(i64_min); count++;
1533  array.append(i64_max); count++;
1534 
1535  CHECK(array.size() == count);
1536 
1537  // Check serialized data
1538 
1539  std::vector<uint8_t> data = serialize(array);
1540 
1541  // Check deserialized data
1542 
1543  Object object = deserialize(data);
1544 
1545  CHECK(object.isArray());
1546  Array& test = object.asArray();
1547  CHECK(test.size() == count);
1548 
1549  size_t index = 0;
1550  CHECK(test.object(index).is<int64_t>());
1551  CHECK(test.object(index).as<int64_t>() == i8_min);
1552 
1553  index++;
1554  CHECK(test.object(index).is<int64_t>());
1555  CHECK(test.object(index).as<int64_t>() == i8_max);
1556 
1557  index++;
1558  CHECK(test.object(index).is<int64_t>());
1559  CHECK(test.object(index).as<int64_t>() == i16_min);
1560 
1561  index++;
1562  CHECK(test.object(index).is<int64_t>());
1563  CHECK(test.object(index).as<int64_t>() == i16_max);
1564 
1565  index++;
1566  CHECK(test.object(index).is<int64_t>());
1567  CHECK(test.object(index).as<int64_t>() == i32_min);
1568 
1569  index++;
1570  CHECK(test.object(index).is<int64_t>());
1571  CHECK(test.object(index).as<int64_t>() == i32_max);
1572 
1573  index++;
1574  CHECK(test.object(index).is<int64_t>());
1575  CHECK(test.object(index).as<int64_t>() == i64_min);
1576 
1577  index++;
1578  CHECK(test.object(index).is<int64_t>());
1579  CHECK(test.object(index).as<int64_t>() == i64_max);
1580 }
1581 #endif // }}}
1582 
1583 
1596 size_t Array::append(const uint64_t value
1597  ) noexcept
1598 {
1599  const size_t index = object_vector.size();
1600 
1601  object_vector.emplace_back(Object{value});
1602 
1603  return index;
1604 }
1605 
1606 
1607 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1608 TEST_CASE("array/append/uint64_t")
1609 {
1610  const uint64_t u8_min = -31;
1611  const uint64_t u8_max = 127;
1612  const uint64_t u16_min = std::numeric_limits<uint16_t>::min();
1613  const uint64_t u16_max = std::numeric_limits<uint16_t>::max();
1614  const uint64_t u32_min = std::numeric_limits<uint32_t>::min();
1615  const uint64_t u32_max = std::numeric_limits<uint32_t>::max();
1616  const uint64_t u64_min = std::numeric_limits<uint64_t>::min();
1617  const uint64_t u64_max = std::numeric_limits<uint64_t>::max();
1618  size_t count = 0;
1619 
1620  Array array;
1621  array.append(u8_min); count++;
1622  array.append(u8_max); count++;
1623  array.append(u16_min); count++;
1624  array.append(u16_max); count++;
1625  array.append(u32_min); count++;
1626  array.append(u32_max); count++;
1627  array.append(u64_min); count++;
1628  array.append(u64_max); count++;
1629 
1630  CHECK(array.size() == count);
1631 
1632  // Check serialized data
1633 
1634  std::vector<uint8_t> data = serialize(array);
1635 
1636  // Check deserialized data
1637 
1638  Object object = deserialize(data);
1639 
1640  CHECK(object.isArray());
1641  Array& test = object.asArray();
1642  CHECK(test.size() == count);
1643 
1644  size_t index = 0;
1645  CHECK(test.object(index).is<uint64_t>());
1646  CHECK(test.object(index).as<uint64_t>() == u8_min);
1647 
1648  index++;
1649  CHECK(test.object(index).is<uint64_t>());
1650  CHECK(test.object(index).as<uint64_t>() == u8_max);
1651 
1652  index++;
1653  CHECK(test.object(index).is<uint64_t>());
1654  CHECK(test.object(index).as<uint64_t>() == u16_min);
1655 
1656  index++;
1657  CHECK(test.object(index).is<uint64_t>());
1658  CHECK(test.object(index).as<uint64_t>() == u16_max);
1659 
1660  index++;
1661  CHECK(test.object(index).is<uint64_t>());
1662  CHECK(test.object(index).as<uint64_t>() == u32_min);
1663 
1664  index++;
1665  CHECK(test.object(index).is<uint64_t>());
1666  CHECK(test.object(index).as<uint64_t>() == u32_max);
1667 
1668  index++;
1669  CHECK(test.object(index).is<uint64_t>());
1670  CHECK(test.object(index).as<uint64_t>() == u64_min);
1671 
1672  index++;
1673  CHECK(test.object(index).is<uint64_t>());
1674  CHECK(test.object(index).as<uint64_t>() == u64_max);
1675 }
1676 #endif // }}}
1677 
1678 
1691 size_t Array::append(const float value
1692  ) noexcept
1693 {
1694  const size_t index = object_vector.size();
1695 
1696  object_vector.emplace_back(Object{value});
1697 
1698  return index;
1699 }
1700 
1701 
1702 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1703 TEST_CASE("array/append/float")
1704 {
1705  const float f32_min = std::numeric_limits<float>::min();
1706  const float f32_max = std::numeric_limits<float>::max();
1707  size_t count = 0;
1708 
1709  Array array;
1710  array.append(f32_min); count++;
1711  array.append(f32_max); count++;
1712 
1713  CHECK(array.size() == count);
1714 
1715  // Check serialized data
1716 
1717  std::vector<uint8_t> data = serialize(array);
1718 
1719  // Check deserialized data
1720 
1721  Object object = deserialize(data);
1722 
1723  CHECK(object.isArray());
1724  Array& test = object.asArray();
1725  CHECK(test.size() == count);
1726 
1727  size_t index = 0;
1728  CHECK(test.object(index).is<float>());
1729  CHECK(test.object(index).as<float>() == f32_min);
1730 
1731  index++;
1732  CHECK(test.object(index).is<float>());
1733  CHECK(test.object(index).as<float>() == f32_max);
1734 }
1735 #endif // }}}
1736 
1737 
1750 size_t Array::append(const double value
1751  ) noexcept
1752 {
1753  const size_t index = object_vector.size();
1754 
1755  object_vector.emplace_back(Object{value});
1756 
1757  return index;
1758 }
1759 
1760 
1761 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1762 TEST_CASE("array/append/double")
1763 {
1764  const double f64_min = std::numeric_limits<double>::min();
1765  const double f64_max = std::numeric_limits<double>::max();
1766  size_t count = 0;
1767 
1768  Array array;
1769  array.append(f64_min); count++;
1770  array.append(f64_max); count++;
1771 
1772  CHECK(array.size() == count);
1773 
1774  // Check serialized data
1775 
1776  std::vector<uint8_t> data = serialize(array);
1777 
1778  // Check deserialized data
1779 
1780  Object object = deserialize(data);
1781 
1782  CHECK(object.isArray());
1783  Array& test = object.asArray();
1784  CHECK(test.size() == count);
1785 
1786  size_t index = 0;
1787  CHECK(test.object(index).is<double>());
1788  CHECK(test.object(index).as<double>() == f64_min);
1789 
1790  index++;
1791  CHECK(test.object(index).is<double>());
1792  CHECK(test.object(index).as<double>() == f64_max);
1793 }
1794 #endif // }}}
1795 
1796 
1809 size_t Array::append(const std::string_view value
1810  ) noexcept
1811 {
1812  const size_t index = object_vector.size();
1813 
1814  object_vector.emplace_back(Object{std::string(value)});
1815 
1816  return index;
1817 }
1818 
1819 
1820 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1821 TEST_CASE("array/append/string")
1822 {
1823  const std::string str_0;
1824  const std::string str_f (31, '_');
1825  const std::string str_8 (32, 'X');
1826  const std::string str_16(std::numeric_limits<uint8_t>::max() + 1 , '*');
1827  const std::string str_32(std::numeric_limits<uint16_t>::max() + 1, '|');
1828  size_t count = 0;
1829 
1830  Array array;
1831  array.append(str_0); count++;
1832  array.append(str_f); count++;
1833  array.append(str_8); count++;
1834  array.append(str_16); count++;
1835  array.append(str_32); count++;
1836 
1837  CHECK(array.size() == count);
1838 
1839  // Check serialized data
1840 
1841  std::vector<uint8_t> data = serialize(array);
1842 
1843  // Check deserialized data
1844 
1845  Object object = deserialize(data);
1846 
1847  CHECK(object.isArray());
1848  Array& test = object.asArray();
1849  CHECK(test.size() == count);
1850 
1851  size_t index = 0;
1852  CHECK(test.object(index).is<std::string>());
1853  CHECK(test.object(index).as<std::string>() == str_0);
1854 
1855  index++;
1856  CHECK(test.object(index).is<std::string>());
1857  CHECK(test.object(index).as<std::string>() == str_f);
1858 
1859  index++;
1860  CHECK(test.object(index).is<std::string>());
1861  CHECK(test.object(index).as<std::string>() == str_8);
1862 
1863  index++;
1864  CHECK(test.object(index).is<std::string>());
1865  CHECK(test.object(index).as<std::string>() == str_16);
1866 
1867  index++;
1868  CHECK(test.object(index).is<std::string>());
1869  CHECK(test.object(index).as<std::string>() == str_32);
1870 }
1871 #endif // }}}
1872 
1873 
1887 size_t Array::append(const std::vector<uint8_t>& value
1888  ) noexcept
1889 {
1890  const size_t index = object_vector.size();
1891 
1892  object_vector.emplace_back(Object{value});
1893 
1894  return index;
1895 }
1896 
1897 
1898 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1899 TEST_CASE("array/append/binary (copy)")
1900 {
1901  const std::vector<uint8_t> bin_0;
1902  const std::vector<uint8_t> bin_8 (32, 'X');
1903  const std::vector<uint8_t> bin_16(std::numeric_limits<uint8_t>::max() + 1 , '-');
1904  const std::vector<uint8_t> bin_32(std::numeric_limits<uint16_t>::max() + 1, '|');
1905  size_t count = 0;
1906 
1907  Array array;
1908  array.append(bin_0); count++;
1909  array.append(bin_8); count++;
1910  array.append(bin_16); count++;
1911  array.append(bin_32); count++;
1912 
1913  CHECK(array.size() == count);
1914 
1915  // Check serialized data
1916 
1917  std::vector<uint8_t> data = serialize(array);
1918 
1919  // Check deserialized data
1920 
1921  Object object = deserialize(data);
1922 
1923  CHECK(object.isArray());
1924  Array& test = object.asArray();
1925  CHECK(test.size() == count);
1926 
1927  size_t index = 0;
1928  CHECK(test.object(index).is<std::vector<uint8_t>>());
1929  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_0);
1930 
1931  index++;
1932  CHECK(test.object(index).is<std::vector<uint8_t>>());
1933  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_8);
1934 
1935  index++;
1936  CHECK(test.object(index).is<std::vector<uint8_t>>());
1937  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_16);
1938 
1939  index++;
1940  CHECK(test.object(index).is<std::vector<uint8_t>>());
1941  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_32);
1942 }
1943 #endif // }}}
1944 
1945 
1959 size_t Array::append(std::vector<uint8_t>& value
1960  ) noexcept
1961 {
1962  const size_t index = object_vector.size();
1963 
1964  object_vector.emplace_back(Object{std::move(value)});
1965 
1966  return index;
1967 }
1968 
1969 
1970 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
1971 TEST_CASE("array/append/binary (move)")
1972 {
1973  const std::vector<uint8_t> bin_0;
1974  const std::vector<uint8_t> bin_8 (32, 'X');
1975  const std::vector<uint8_t> bin_16(std::numeric_limits<uint8_t>::max() + 1 , '-');
1976  const std::vector<uint8_t> bin_32(std::numeric_limits<uint16_t>::max() + 1, '|');
1977  size_t count = 0;
1978 
1979  std::vector<uint8_t> tmp_0(bin_0);
1980  std::vector<uint8_t> tmp_8(bin_8);
1981  std::vector<uint8_t> tmp_16(bin_16);
1982  std::vector<uint8_t> tmp_32(bin_32);
1983 
1984  Array array;
1985  array.append(tmp_0); count++;
1986  array.append(tmp_8); count++;
1987  array.append(tmp_16); count++;
1988  array.append(tmp_32); count++;
1989 
1990  CHECK(array.size() == count);
1991  CHECK(tmp_0.empty());
1992  CHECK(tmp_8.empty());
1993  CHECK(tmp_16.empty());
1994  CHECK(tmp_32.empty());
1995 
1996  // Check serialized data
1997 
1998  std::vector<uint8_t> data = serialize(array);
1999 
2000  // Check deserialized data
2001 
2002  Object object = deserialize(data);
2003 
2004  CHECK(object.isArray());
2005  Array& test = object.asArray();
2006  CHECK(test.size() == count);
2007 
2008  size_t index = 0;
2009  CHECK(test.object(index).is<std::vector<uint8_t>>());
2010  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_0);
2011 
2012  index++;
2013  CHECK(test.object(index).is<std::vector<uint8_t>>());
2014  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_8);
2015 
2016  index++;
2017  CHECK(test.object(index).is<std::vector<uint8_t>>());
2018  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_16);
2019 
2020  index++;
2021  CHECK(test.object(index).is<std::vector<uint8_t>>());
2022  CHECK(test.object(index).as<std::vector<uint8_t>>() == bin_32);
2023 }
2024 #endif // }}}
2025 
2026 
2043 size_t Array::append(const Array& array
2044  ) noexcept
2045 {
2046  size_t index = object_vector.size();
2047  object_vector.emplace_back(Object{Array{}});
2048 
2049  Array& sub_array = object_vector[index].asArray();
2050  sub_array.object_vector = array.object_vector;
2051 
2052  return index;
2053 }
2054 
2055 
2056 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2057 TEST_CASE("array/append/array (copy)")
2058 {
2059  messagepack::Array sub_0;
2060  messagepack::Array sub_1;
2061  sub_1.appendNull();
2062  messagepack::Array sub_2;
2063  sub_2.append(true);
2064  sub_2.append(false);
2065  messagepack::Array sub_3;
2066  sub_3.append(std::string_view("Hello"));
2067  sub_3.append(std::string_view("World"));
2068  size_t count = 0;
2069 
2070  const messagepack::Array tmp_0 = sub_0;
2071  const messagepack::Array tmp_1 = sub_1;
2072  const messagepack::Array tmp_2 = sub_2;
2073  const messagepack::Array tmp_3 = sub_3;
2074 
2075  Array array;
2076  array.append(tmp_0); count++;
2077  array.append(tmp_1); count++;
2078  array.append(tmp_2); count++;
2079  array.append(tmp_3); count++;
2080 
2081  CHECK(array.size() == count);
2082  CHECK(tmp_0.size() == 0);
2083  CHECK(tmp_1.size() == 1);
2084  CHECK(tmp_2.size() == 2);
2085  CHECK(tmp_3.size() == 2);
2086 
2087  // Check serialized data
2088 
2089  std::vector<uint8_t> data = serialize(array);
2090 
2091  // Check deserialized data
2092 
2093  Object object = deserialize(data);
2094 
2095  CHECK(object.isArray());
2096  Array& test = object.asArray();
2097  CHECK(test.size() == count);
2098 
2099  size_t index = 0;
2100  CHECK(test.object(index).isArray());
2101  CHECK(test.object(index).asArray().size() == 0);
2102 
2103  index++;
2104  CHECK(test.object(index).isArray());
2105  CHECK(test.object(index).asArray().size() == 1);
2106  CHECK(test.object(index).asArray().object(0).isNull());
2107 
2108  index++;
2109  CHECK(test.object(index).isArray());
2110  CHECK(test.object(index).asArray().size() == 2);
2111  CHECK(test.object(index).asArray().object(0).is<bool>());
2112  CHECK(test.object(index).asArray().object(0).as<bool>() == true);
2113  CHECK(test.object(index).asArray().object(1).is<bool>());
2114  CHECK(test.object(index).asArray().object(1).as<bool>() == false);
2115 
2116  index++;
2117  CHECK(test.object(index).isArray());
2118  CHECK(test.object(index).asArray().size() == 2);
2119  CHECK(test.object(index).asArray().object(0).is<std::string>());
2120  CHECK(test.object(index).asArray().object(0).as<std::string>() == "Hello");
2121  CHECK(test.object(index).asArray().object(1).is<std::string>());
2122  CHECK(test.object(index).asArray().object(1).as<std::string>() == "World");
2123 }
2124 #endif // }}}
2125 
2126 
2143 size_t Array::append(Array& array
2144  ) noexcept
2145 {
2146  size_t index = object_vector.size();
2147  object_vector.emplace_back(Object{Array{}});
2148 
2149  Array& sub_array = object_vector[index].asArray();
2150  sub_array.object_vector = std::move(array.object_vector);
2151 
2152  return index;
2153 }
2154 
2155 
2156 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2157 TEST_CASE("array/append/array (move)")
2158 {
2159  messagepack::Array sub_0;
2160  messagepack::Array sub_1;
2161  sub_1.appendNull();
2162  messagepack::Array sub_2;
2163  sub_2.append(true);
2164  sub_2.append(false);
2165  messagepack::Array sub_3;
2166  sub_3.append(std::string_view("Hello"));
2167  sub_3.append(std::string_view("World"));
2168  size_t count = 0;
2169 
2170  messagepack::Array tmp_0 = sub_0;
2171  messagepack::Array tmp_1 = sub_1;
2172  messagepack::Array tmp_2 = sub_2;
2173  messagepack::Array tmp_3 = sub_3;
2174 
2175  Array array;
2176  array.append(tmp_0); count++;
2177  array.append(tmp_1); count++;
2178  array.append(tmp_2); count++;
2179  array.append(tmp_3); count++;
2180 
2181  CHECK(array.size() == count);
2182  CHECK(tmp_0.size() == 0);
2183  CHECK(tmp_1.size() == 0);
2184  CHECK(tmp_2.size() == 0);
2185  CHECK(tmp_3.size() == 0);
2186 
2187  // Check serialized data
2188 
2189  std::vector<uint8_t> data = serialize(array);
2190 
2191  // Check deserialized data
2192 
2193  Object object = deserialize(data);
2194 
2195  CHECK(object.isArray());
2196  Array& test = object.asArray();
2197  CHECK(test.size() == count);
2198 
2199  size_t index = 0;
2200  CHECK(test.object(index).isArray());
2201  CHECK(test.object(index).asArray().size() == 0);
2202 
2203  index++;
2204  CHECK(test.object(index).isArray());
2205  CHECK(test.object(index).asArray().size() == 1);
2206  CHECK(test.object(index).asArray().object(0).isNull());
2207 
2208  index++;
2209  CHECK(test.object(index).isArray());
2210  CHECK(test.object(index).asArray().size() == 2);
2211  CHECK(test.object(index).asArray().object(0).is<bool>());
2212  CHECK(test.object(index).asArray().object(0).as<bool>() == true);
2213  CHECK(test.object(index).asArray().object(1).is<bool>());
2214  CHECK(test.object(index).asArray().object(1).as<bool>() == false);
2215 
2216  index++;
2217  CHECK(test.object(index).isArray());
2218  CHECK(test.object(index).asArray().size() == 2);
2219  CHECK(test.object(index).asArray().object(0).is<std::string>());
2220  CHECK(test.object(index).asArray().object(0).as<std::string>() == "Hello");
2221  CHECK(test.object(index).asArray().object(1).is<std::string>());
2222  CHECK(test.object(index).asArray().object(1).as<std::string>() == "World");
2223 }
2224 #endif // }}}
2225 
2226 
2243 size_t Array::append(const Ext& ext
2244  ) noexcept
2245 {
2246  size_t index = object_vector.size();
2247  object_vector.emplace_back(Object{ext});
2248 
2249  return index;
2250 }
2251 
2252 
2253 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2254 TEST_CASE("array/append/ext (copy)")
2255 {
2256  const uint8_t chr_16 = '-';
2257  const uint8_t chr_32 = '|';
2258 
2259  Ext ext_0;
2260  ext_0.type = 0;
2261  ext_0.data = {};
2262 
2263  const Ext ext_16 =
2264  { .data = std::vector<uint8_t>(16, chr_16)
2265  , .type = 16
2266  };
2267 
2268  const Ext ext_32 =
2269  { .data = std::vector<uint8_t>(32, chr_32)
2270  , .type = 32
2271  };
2272 
2273  size_t count = 0;
2274  Array array;
2275  array.append(ext_0); count++;
2276  array.append(ext_16); count++;
2277  array.append(ext_32); count++;
2278 
2279  CHECK(array.size() == count);
2280  CHECK(ext_0.data.size() == 0);
2281  CHECK(ext_16.data.size() == 16);
2282  CHECK(ext_32.data.size() == 32);
2283 
2284  // Check serialized data
2285 
2286  std::vector<uint8_t> data = serialize(array);
2287 
2288  // Check deserialized data
2289 
2290  Object object = deserialize(data);
2291 
2292  CHECK(object.isArray());
2293  Array& test = object.asArray();
2294  CHECK(test.size() == count);
2295 
2296  size_t index = 0;
2297  CHECK(test.object(index).isExt() == true);
2298  CHECK(test.object(index).asExt().type == 0);
2299  CHECK(test.object(index).asExt().data.size() == 0);
2300 
2301  index++;
2302  CHECK(test.object(index).isExt() == true);
2303  CHECK(test.object(index).asExt().type == 16);
2304  CHECK(test.object(index).asExt().data.size() == 16);
2305  for(size_t i = 0; i < test.object(index).asExt().data.size(); i++)
2306  {
2307  CHECK(test.object(index).asExt().data[i] == chr_16);
2308  }
2309 
2310  index++;
2311  CHECK(test.object(index).isExt() == true);
2312  CHECK(test.object(index).asExt().type == 32);
2313  CHECK(test.object(index).asExt().data.size() == 32);
2314  for(size_t i = 0; i < test.object(index).asExt().data.size(); i++)
2315  {
2316  CHECK(test.object(index).asExt().data[i] == chr_32);
2317  }
2318 }
2319 #endif // }}}
2320 
2321 
2338 size_t Array::append(Ext& ext
2339  ) noexcept
2340 {
2341  size_t index = object_vector.size();
2342  object_vector.push_back(Object{std::move(ext)});
2343 
2344  return index;
2345 }
2346 
2347 
2348 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2349 TEST_CASE("array/append/ext (move)")
2350 {
2351  const uint8_t chr_16 = '-';
2352  const uint8_t chr_32 = '|';
2353 
2354  Ext ext_0;
2355  ext_0.type = 0;
2356  ext_0.data = {};
2357 
2358  Ext ext_16;
2359  ext_16.type = 16;
2360  ext_16.data = std::vector<uint8_t>(16, chr_16);
2361 
2362  Ext ext_32;
2363  ext_32.type = 32;
2364  ext_32.data = std::vector<uint8_t>(32, chr_32);
2365 
2366  size_t count = 0;
2367  Array array;
2368  array.append(ext_0); count++;
2369  array.append(ext_16); count++;
2370  array.append(ext_32); count++;
2371 
2372  CHECK(array.size() == count);
2373  CHECK(ext_16.data.size() == 0);
2374  CHECK(ext_32.data.size() == 0);
2375 
2376  // Check serialized data
2377 
2378  std::vector<uint8_t> data = serialize(array);
2379 
2380  // Check deserialized data
2381 
2382  Object object = deserialize(data);
2383 
2384  CHECK(object.isArray());
2385  Array& test = object.asArray();
2386  CHECK(test.size() == count);
2387 
2388  size_t index = 0;
2389  CHECK(test.object(index).isExt());
2390  CHECK(test.object(index).asExt().type == 0);
2391  CHECK(test.object(index).asExt().data.size() == 0);
2392 
2393  index++;
2394  CHECK(test.object(index).isExt());
2395  CHECK(test.object(index).asExt().type == 16);
2396  CHECK(test.object(index).asExt().data.size() == 16);
2397  for(size_t i = 0; i < test.object(index).asExt().data.size(); i++)
2398  {
2399  CHECK(test.object(index).asExt().data[i] == chr_16);
2400  }
2401 
2402  index++;
2403  CHECK(test.object(index).isExt());
2404  CHECK(test.object(index).asExt().type == 32);
2405  CHECK(test.object(index).asExt().data.size() == 32);
2406  for(size_t i = 0; i < test.object(index).asExt().data.size(); i++)
2407  {
2408  CHECK(test.object(index).asExt().data[i] == chr_32);
2409  }
2410 }
2411 #endif // }}}
2412 
2413 
2429 size_t Array::append(const Map& map
2430  ) noexcept
2431 {
2432  size_t index = object_vector.size();
2433  object_vector.emplace_back(Object{map});
2434 
2435  return index;
2436 }
2437 
2438 
2439 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2440 TEST_CASE("array/append/map (copy)")
2441 {
2442  const Object key_1 = Object{true};
2443  const Object key_2 = Object{int64_t(0)};
2444 
2445  const std::string str("Hello, World!");
2446  const uint64_t num(21);
2447 
2448  const Object val_1 = Object{str};
2449  const Object val_2 = Object{num};
2450 
2451  Map map_1;
2452  map_1.set(key_1, val_1);
2453  map_1.set(key_2, val_2);
2454 
2455  Map map_2;
2456  map_2.set(val_1, key_1);
2457  map_2.set(val_2, key_2);
2458 
2459  size_t count = 0;
2460  Array array;
2461  array.append((const Map)map_1); count++;
2462  array.append((const Map)map_2); count++;
2463 
2464  CHECK(map_1.size() == 2);
2465  CHECK(map_2.size() == 2);
2466  CHECK(array.size() == count);
2467 
2468  // Check serialized data
2469 
2470  std::vector<uint8_t> data = serialize(array);
2471 
2472  // Check deserialized data
2473 
2474  Object object = deserialize(data);
2475 
2476  CHECK(object.isArray());
2477  Array& test = object.asArray();
2478  CHECK(test.size() == count);
2479 
2480  size_t index = 0;
2481  CHECK(test.object(index).isMap());
2482  CHECK(test.object(index).asMap().size() == 2);
2483  CHECK(test.object(index).asMap().keyExists(key_1) == true);
2484  CHECK(test.object(index).asMap().at(key_1) == val_1);
2485  CHECK(test.object(index).asMap().keyExists(key_2) == true);
2486  CHECK(test.object(index).asMap().at(key_2) == val_2);
2487 
2488  index++;
2489  CHECK(test.object(index).isMap());
2490  CHECK(test.object(index).asMap().size() == 2);
2491  CHECK(test.object(index).asMap().keyExists(val_1) == true);
2492  CHECK(test.object(index).asMap().at(val_1) == key_1);
2493  CHECK(test.object(index).asMap().keyExists(val_2) == true);
2494  CHECK(test.object(index).asMap().at(val_2) == key_2);
2495 }
2496 #endif // }}}
2497 
2498 
2514 size_t Array::append(Map& map
2515  ) noexcept
2516 {
2517  size_t index = object_vector.size();
2518  object_vector.push_back(Object{std::move(map)});
2519 
2520  return index;
2521 }
2522 
2523 
2524 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2525 TEST_CASE("array/append/map (move)")
2526 {
2527  const Object key_1 = Object{true};
2528  const Object key_2 = Object{int64_t(0)};
2529 
2530  const std::string str("Hello, World!");
2531  const uint64_t num(21);
2532 
2533  const Object val_1 = Object{str};
2534  const Object val_2 = Object{num};
2535 
2536  Map map_1;
2537  map_1.set(key_1, val_1);
2538  map_1.set(key_2, val_2);
2539 
2540  Map map_2;
2541  map_2.set(val_1, key_1);
2542  map_2.set(val_2, key_2);
2543 
2544  size_t count = 0;
2545  Array array;
2546  array.append(map_1); count++;
2547  array.append(map_2); count++;
2548 
2549  CHECK(array.size() == count);
2550  CHECK(map_1.size() == 0);
2551  CHECK(map_2.size() == 0);
2552 
2553  // Check serialized data
2554 
2555  std::vector<uint8_t> data = serialize(array);
2556 
2557  // Check deserialized data
2558 
2559  Object object = deserialize(data);
2560 
2561  CHECK(object.isArray());
2562  Array& test = object.asArray();
2563  CHECK(test.size() == count);
2564 
2565  size_t index = 0;
2566  CHECK(test.object(index).isMap());
2567  CHECK(test.object(index).asMap().size() == 2);
2568  CHECK(test.object(index).asMap().keyExists(key_1) == true);
2569  CHECK(test.object(index).asMap().at(key_1) == val_1);
2570  CHECK(test.object(index).asMap().keyExists(key_2) == true);
2571  CHECK(test.object(index).asMap().at(key_2) == val_2);
2572 
2573  index++;
2574  CHECK(test.object(index).isMap());
2575  CHECK(test.object(index).asMap().size() == 2);
2576  CHECK(test.object(index).asMap().keyExists(val_1) == true);
2577  CHECK(test.object(index).asMap().at(val_1) == key_1);
2578  CHECK(test.object(index).asMap().keyExists(val_2) == true);
2579  CHECK(test.object(index).asMap().at(val_2) == key_2);
2580 }
2581 #endif // }}}
2582 
2583 
2597 size_t Array::append(const Object& object
2598  ) noexcept
2599 {
2600  const size_t index = object_vector.size();
2601 
2602  object_vector.push_back(object);
2603 
2604  return index;
2605 }
2606 
2607 
2608 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2609 TEST_CASE("array/append/object (copy)")
2610 {
2611  messagepack::Object obj_0 = Object{true};
2612  messagepack::Object obj_1 = Object{(uint64_t)42};
2613  messagepack::Object obj_2 = Object{std::string("foo")};
2614 
2615  const messagepack::Object tmp_0 = obj_0;
2616  const messagepack::Object tmp_1 = obj_1;
2617  const messagepack::Object tmp_2 = obj_2;
2618  size_t count = 0;
2619 
2620  Array array;
2621  array.append(tmp_0); count++;
2622  array.append(tmp_1); count++;
2623  array.append(tmp_2); count++;
2624 
2625  CHECK(array.size() == count);
2626  CHECK(tmp_0.isNull() == false);
2627  CHECK(tmp_1.isNull() == false);
2628  CHECK(tmp_2.isNull() == false);
2629 
2630  // Check serialized data
2631 
2632  std::vector<uint8_t> data = serialize(array);
2633 
2634  // Check deserialized data
2635 
2636  Object object = deserialize(data);
2637 
2638  CHECK(object.isArray());
2639  Array& test = object.asArray();
2640  CHECK(test.size() == count);
2641 
2642  size_t index = 0;
2643  CHECK(test.object(index).is<bool>());
2644  CHECK(test.object(index).as<bool>() == true);
2645 
2646  index++;
2647  CHECK(test.object(index).is<uint64_t>());
2648  CHECK(test.object(index).as<uint64_t>() == 42);
2649 
2650  index++;
2651  CHECK(test.object(index).is<std::string>());
2652  CHECK(test.object(index).as<std::string>() == "foo");
2653 }
2654 #endif // }}}
2655 
2656 
2669 size_t Array::append(Object& object
2670  ) noexcept
2671 {
2672  const size_t index = object_vector.size();
2673 
2674  object_vector.push_back(std::move(object));
2675  object = {};
2676 
2677  return index;
2678 }
2679 
2680 
2681 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2682 TEST_CASE("array/append/object (move)")
2683 {
2684  messagepack::Object obj_0 = Object{true};
2685  messagepack::Object obj_1 = Object{(uint64_t)42};
2686  messagepack::Object obj_2 = Object{std::string("foo")};
2687 
2688  messagepack::Object tmp_0 = obj_0;
2689  messagepack::Object tmp_1 = obj_1;
2690  messagepack::Object tmp_2 = obj_2;
2691  size_t count = 0;
2692 
2693  Array array;
2694  array.append(tmp_0); count++;
2695  array.append(tmp_1); count++;
2696  array.append(tmp_2); count++;
2697 
2698  CHECK(array.size() == count);
2699  CHECK(tmp_0.isNull() == true);
2700  CHECK(tmp_1.isNull() == true);
2701  CHECK(tmp_2.isNull() == true);
2702 
2703  // Check serialized data
2704 
2705  std::vector<uint8_t> data = serialize(array);
2706 
2707  // Check deserialized data
2708 
2709  Object object = deserialize(data);
2710 
2711  CHECK(object.isArray());
2712  Array& test = object.asArray();
2713  CHECK(test.size() == count);
2714 
2715  size_t index = 0;
2716  CHECK(test.object(index).is<bool>());
2717  CHECK(test.object(index).as<bool>() == true);
2718 
2719  index++;
2720  CHECK(test.object(index).is<uint64_t>());
2721  CHECK(test.object(index).as<uint64_t>() == 42);
2722 
2723  index++;
2724  CHECK(test.object(index).is<std::string>());
2725  CHECK(test.object(index).as<std::string>() == "foo");
2726 }
2727 #endif // }}}
2728 
2729 
2742 size_t Array::appendNull() noexcept
2743 {
2744  const size_t index = object_vector.size();
2745 
2746  object_vector.emplace_back();
2747 
2748  return index;
2749 }
2750 
2751 
2752 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
2753 TEST_CASE("array/append/null")
2754 {
2755  const size_t count = std::numeric_limits<uint16_t>::max() + 1;
2756  Array array;
2757 
2758  for(size_t i = 0; i < count; i++)
2759  {
2760  array.append(Object{true});
2761  }
2762 
2763  CHECK(array.size() == count);
2764 
2765  // Check serialized data
2766 
2767  std::vector<uint8_t> data = serialize(array);
2768 
2769  // Check deserialized data
2770 
2771  Object object = deserialize(data);
2772 
2773  CHECK(object.isArray());
2774  Array& test = object.asArray();
2775  CHECK(test.size() == count);
2776 
2777  for(size_t i = 0; i < count; i++)
2778  {
2779  CHECK(test.object(i).is<bool>());
2780  CHECK(test.object(i).as<bool>() == true);
2781  }
2782 }
2783 #endif // }}}
2784 
2785 
2822 // No tests needed, functionality is tested else where.
2823 
2824 
2859 // No tests needed, functionality is tested else where.
2860 
2861 
2871 // No tests needed, a pass-thru to the std::vector<Object>.
2872 
2873 
2883 // No tests needed, a pass-thru to the std::vector<Object>.
2884 
2885 // }}} Array
2886 // {{{ Ext
2887 
2950 // }}} Ext
2951 // {{{ Map
2952 
2988 std::error_code Map::set(const Object& key
2989  , const Object& value
2990  ) noexcept
2991 {
2992  if(keyExists(key))
2993  {
2994  erase(key);
2995  }
2996 
2997  if(key.isNull())
2998  {
2999  null_map.clear();
3000  null_map.push_back(value);
3001  }
3002  else if(key.is<bool>())
3003  {
3004  bool_map[key.as<bool>()] = value;
3005  }
3006  else if(key.is<int64_t>())
3007  {
3008  int64_map[key.as<int64_t>()] = value;
3009  }
3010  else if(key.is<uint64_t>())
3011  {
3012  uint64_map[key.as<uint64_t>()] = value;
3013  }
3014  else if(key.is<float>())
3015  {
3016  float_map[key.as<float>()] = value;
3017  }
3018  else if(key.is<double>())
3019  {
3020  double_map[key.as<double>()] = value;
3021  }
3022  else if(key.is<std::string>())
3023  {
3024  string_map[key.as<std::string>()] = value;
3025  }
3026 
3027  return Error_Invalid_Format_Type;
3028 }
3029 
3030 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3031 TEST_CASE("map/set (copy)")
3032 {
3033  const Object key_null = {};
3034  const Object key_zero = {int64_t(0)};
3035  const Object val_null = {};
3036  const Object val_zero = {int64_t(0)};
3037 
3038  Map map;
3039 
3040  SUBCASE("Same Key, Same Value")
3041  {
3042  map.set(key_null, val_null);
3043  CHECK(map.size() == 1);
3044  const Object& obj_1 = map.at(key_null);
3045  CHECK(obj_1 == val_null);
3046  CHECK(&obj_1 != &val_null);
3047 
3048  map.set(key_null, val_null);
3049  CHECK(map.size() == 1);
3050  const Object& obj_2 = map.at(key_null);
3051  CHECK(obj_2 == val_null);
3052  CHECK(&obj_2 != &val_null);
3053  }
3054 
3055  SUBCASE("Same Key, Differnt Value")
3056  {
3057  map.set(key_null, val_null);
3058  CHECK(map.size() == 1);
3059  const Object& obj_1 = map.at(key_null);
3060  CHECK(obj_1 == val_null);
3061 
3062  map.set(key_null, val_zero);
3063  CHECK(map.size() == 1);
3064  const Object& obj_2 = map.at(key_null);
3065  CHECK(obj_2 == val_zero);
3066  }
3067 
3068  SUBCASE("Different Key, Same Value")
3069  {
3070  map.set(key_null, val_null);
3071  map.set(key_zero, val_null);
3072  CHECK(map.size() == 2);
3073 
3074  const Object& obj_1 = map.at(key_null);
3075  CHECK(obj_1 == val_null);
3076 
3077  const Object& obj_2 = map.at(key_zero);
3078  CHECK(obj_2 == val_null);
3079  }
3080 
3081  SUBCASE("Different Key, Different Value")
3082  {
3083  map.set(key_null, val_null);
3084  map.set(key_zero, val_zero);
3085  CHECK(map.size() == 2);
3086 
3087  const Object& obj_1 = map.at(key_null);
3088  CHECK(obj_1 == val_null);
3089 
3090  const Object& obj_2 = map.at(key_zero);
3091  CHECK(obj_2 == val_zero);
3092  }
3093 }
3094 #endif // }}}
3095 
3096 
3112 std::error_code Map::set(Object& key
3113  , Object& value
3114  ) noexcept
3115 {
3116  if(keyExists(key))
3117  {
3118  erase(key);
3119  }
3120 
3121  if(key.isNull())
3122  {
3123  null_map.clear();
3124  null_map.push_back(value);
3125  }
3126  else if(key.is<bool>())
3127  {
3128  bool_map[key.as<bool>()] = value;
3129  }
3130  else if(key.is<int64_t>())
3131  {
3132  int64_map[key.as<int64_t>()] = value;
3133  }
3134  else if(key.is<uint64_t>())
3135  {
3136  uint64_map[key.as<uint64_t>()] = value;
3137  }
3138  else if(key.is<float>())
3139  {
3140  float_map[key.as<float>()] = value;
3141  }
3142  else if(key.is<double>())
3143  {
3144  double_map[key.as<double>()] = value;
3145  }
3146  else if(key.is<std::string>())
3147  {
3148  string_map[key.as<std::string>()] = value;
3149  }
3150 
3151  return Error_Invalid_Format_Type;
3152 }
3153 
3154 
3155 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3156 TEST_CASE("map/set")
3157 {
3158  Object key_true = Object{true};
3159  Object key_zero = Object{int64_t(0)};
3160  Object val_true = Object{true};
3161  Object val_zero = Object{int64_t(0)};
3162 
3163  Map map;
3164 
3165  SUBCASE("Same Key, Same Value")
3166  {
3167  map.set(key_true, val_true);
3168  CHECK(map.size() == 1);
3169 
3170  Object& obj_1 = map.at(key_true);
3171  CHECK(obj_1 == val_true);
3172  obj_1 = {val_zero};
3173  CHECK(map.at(key_true) == val_zero);
3174 
3175  map.set(key_true, val_zero);
3176  CHECK(map.size() == 1);
3177 
3178  Object& obj_2 = map.at(key_true);
3179  CHECK(obj_2 == val_zero);
3180  }
3181 
3182  SUBCASE("Same Key, Differnt Value")
3183  {
3184  map.set(key_true, val_true);
3185  CHECK(map.size() == 1);
3186 
3187  CHECK(map.at(key_true) == val_true);
3188 
3189  map.set(key_true, val_zero);
3190  CHECK(map.size() == 1);
3191  CHECK(map.at(key_true) == val_zero);
3192  }
3193 
3194  SUBCASE("Different Key, Same Value")
3195  {
3196  map.set(key_true, val_true);
3197  map.set(key_zero, val_true);
3198  CHECK(map.size() == 2);
3199  CHECK(map.at(key_true) == val_true);
3200  CHECK(map.at(key_zero) == val_true);
3201  }
3202 
3203  SUBCASE("Different Key, Different Value")
3204  {
3205  map.set(key_true, val_true);
3206  map.set(key_zero, val_zero);
3207  CHECK(map.size() == 2);
3208  CHECK(map.at(key_true) == val_true);
3209  CHECK(map.at(key_zero) == val_zero);
3210  }
3211 }
3212 #endif // }}}
3213 
3214 
3231 void Map::erase(const Object& key
3232  ) noexcept
3233 {
3234  if(key.isNull())
3235  {
3236  null_map.clear();
3237  }
3238  else if(key.is<bool>())
3239  {
3240  bool_map.erase(key.as<bool>());
3241  }
3242  else if(key.is<int64_t>())
3243  {
3244  int64_map.erase(key.as<int64_t>());
3245  }
3246  else if(key.is<uint64_t>())
3247  {
3248  uint64_map.erase(key.as<uint64_t>());
3249  }
3250  else if(key.is<float>())
3251  {
3252  float_map.erase(key.as<float>());
3253  }
3254  else if(key.is<double>())
3255  {
3256  double_map.erase(key.as<double>());
3257  }
3258  else if(key.is<std::string>())
3259  {
3260  string_map.erase(key.as<std::string>());
3261  }
3262 }
3263 
3264 
3265 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3266 TEST_CASE("map/erase")
3267 {
3268  Object key_nope = Object{};
3269  Object key_true = Object{true};
3270  Object key_zero = Object{int64_t(0)};
3271  Object val_null = Object{};
3272 
3273  Map map;
3274 
3275  map.erase(key_nope); // Nothing should happen
3276 
3277  map.set(key_true, val_null);
3278  map.set(key_zero, val_null);
3279  CHECK(map.keyExists(key_true) == true);
3280  CHECK(map.keyExists(key_zero) == true);
3281 
3282  map.erase(key_nope); // Nothing should happen
3283  CHECK(map.size() == 2);
3284 
3285  map.erase(key_true);
3286  CHECK(map.size() == 1);
3287  CHECK(map.keyExists(key_true) == false);
3288  CHECK(map.keyExists(key_zero) == true);
3289 
3290  map.erase(key_true);
3291  CHECK(map.size() == 1);
3292  CHECK(map.keyExists(key_true) == false);
3293  CHECK(map.keyExists(key_zero) == true);
3294 
3295  map.erase(key_zero);
3296  CHECK(map.size() == 0);
3297  CHECK(map.keyExists(key_true) == false);
3298  CHECK(map.keyExists(key_zero) == false);
3299 
3300  map.erase(key_zero);
3301  CHECK(map.size() == 0);
3302  CHECK(map.keyExists(key_true) == false);
3303  CHECK(map.keyExists(key_zero) == false);
3304 }
3305 #endif // }}}
3306 
3307 
3327 bool Map::keyExists(const Object& key
3328  ) const noexcept
3329 {
3330  if(key.isNull())
3331  {
3332  return (null_map.empty() == false);
3333  }
3334  else if(key.is<bool>())
3335  {
3336  return bool_map.contains(key.as<bool>());
3337  }
3338  else if(key.is<int64_t>())
3339  {
3340  return int64_map.contains(key.as<int64_t>());
3341  }
3342  else if(key.is<uint64_t>())
3343  {
3344  return uint64_map.contains(key.as<uint64_t>());
3345  }
3346  else if(key.is<float>())
3347  {
3348  return float_map.contains(key.as<float>());
3349  }
3350  else if(key.is<double>())
3351  {
3352  return double_map.contains(key.as<double>());
3353  }
3354  else if(key.is<std::string>())
3355  {
3356  return string_map.contains(key.as<std::string>());
3357  }
3358 
3359  return false;
3360 }
3361 
3362 
3363 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3364 TEST_CASE("map/keyexists")
3365 {
3366  const Object key_true = Object{true};
3367  const Object key_zero = Object{int64_t(0)};
3368  const Object val_null = Object{};
3369 
3370  Map map;
3371 
3372  CHECK(map.size() == 0);
3373  CHECK(map.keyExists(key_true) == false);
3374  CHECK(map.keyExists(key_zero) == false);
3375 
3376  map.set(key_true, val_null);
3377  CHECK(map.keyExists(key_true) == true);
3378  CHECK(map.keyExists(key_zero) == false);
3379 
3380  map.set(key_zero, val_null);
3381  CHECK(map.keyExists(key_true) == true);
3382  CHECK(map.keyExists(key_zero) == true);
3383 }
3384 #endif // }}}
3385 
3386 
3409 const Object& Map::at(const Object& key
3410  ) const noexcept
3411 {
3412  if(keyExists(key) == false)
3413  {
3414  return key;
3415  }
3416 
3417  if(key.isNull())
3418  {
3419  return null_map.at(0);
3420  }
3421  else if(key.is<bool>())
3422  {
3423  return bool_map.at(key.as<bool>());
3424  }
3425  else if(key.is<int64_t>())
3426  {
3427  return int64_map.at(key.as<int64_t>());
3428  }
3429  else if(key.is<uint64_t>())
3430  {
3431  return uint64_map.at(key.as<uint64_t>());
3432  }
3433  else if(key.is<float>())
3434  {
3435  return float_map.at(key.as<float>());
3436  }
3437  else if(key.is<double>())
3438  {
3439  return double_map.at(key.as<double>());
3440  }
3441  else if(key.is<std::string>())
3442  {
3443  return string_map.at(key.as<std::string>());
3444  }
3445 
3446  return key;
3447 }
3448 
3449 
3450 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3451 TEST_CASE("map/valueof (const)")
3452 {
3453  Map map;
3454 
3455  SUBCASE("Exists")
3456  {
3457  const Object key_null = {};
3458  const Object key_bool = {true};
3459  const Object key_int64 = {int64_t(0)};
3460  const Object key_uint64 = {uint64_t(0)};
3461  const Object key_float = {float(0)};
3462  const Object key_double = {double(0)};
3463  const Object key_string = {std::string("_")};
3464 
3465  const Object value_0 = {uint64_t(0)};
3466  const Object value_1 = {uint64_t(1)};
3467  const Object value_2 = {uint64_t(2)};
3468  const Object value_3 = {uint64_t(3)};
3469  const Object value_4 = {uint64_t(4)};
3470  const Object value_5 = {uint64_t(5)};
3471  const Object value_6 = {uint64_t(6)};
3472 
3473  map.set(key_null, value_0);
3474  map.set(key_bool, value_1);
3475  map.set(key_int64, value_2);
3476  map.set(key_uint64, value_3);
3477  map.set(key_float, value_4);
3478  map.set(key_double, value_5);
3479  map.set(key_string, value_6);
3480 
3481  CHECK(map.at(key_null) == value_0);
3482  CHECK(map.at(key_bool) == value_1);
3483  CHECK(map.at(key_int64) == value_2);
3484  CHECK(map.at(key_uint64) == value_3);
3485  CHECK(map.at(key_float) == value_4);
3486  CHECK(map.at(key_double) == value_5);
3487  CHECK(map.at(key_string) == value_6);
3488  }
3489 
3490  SUBCASE("Not Exists")
3491  {
3492  const Object bad_key = {};
3493  const Object& bad_val = map.at(bad_key);
3494  CHECK(&bad_key == &bad_val);
3495  }
3496 }
3497 #endif // }}}
3498 
3499 
3525 Object& Map::at(Object& key
3526  ) noexcept
3527 {
3528  if(keyExists(key) == false)
3529  {
3530  return key;
3531  }
3532 
3533  if(key.isNull())
3534  {
3535  return null_map.at(0);
3536  }
3537  else if(key.is<bool>())
3538  {
3539  return bool_map.at(key.as<bool>());
3540  }
3541  else if(key.is<int64_t>())
3542  {
3543  return int64_map.at(key.as<int64_t>());
3544  }
3545  else if(key.is<uint64_t>())
3546  {
3547  return uint64_map.at(key.as<uint64_t>());
3548  }
3549  else if(key.is<float>())
3550  {
3551  return float_map.at(key.as<float>());
3552  }
3553  else if(key.is<double>())
3554  {
3555  return double_map.at(key.as<double>());
3556  }
3557  else if(key.is<std::string>())
3558  {
3559  return string_map.at(key.as<std::string>());
3560  }
3561 
3562  return key;
3563 }
3564 
3565 
3566 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3567 TEST_CASE("map/valueof")
3568 {
3569  Map map;
3570 
3571  SUBCASE("Exists")
3572  {
3573  Object key_null = {};
3574  Object key_bool = {true};
3575  Object key_int64 = {int64_t(0)};
3576  Object key_uint64 = {uint64_t(0)};
3577  Object key_float = {float(0)};
3578  Object key_double = {double(0)};
3579  Object key_string = {std::string("_")};
3580 
3581  Object value_0 = {uint64_t(0)};
3582  Object value_1 = {uint64_t(1)};
3583  Object value_2 = {uint64_t(2)};
3584  Object value_3 = {uint64_t(3)};
3585  Object value_4 = {uint64_t(4)};
3586  Object value_5 = {uint64_t(5)};
3587  Object value_6 = {uint64_t(6)};
3588 
3589  map.set(key_null, value_0);
3590  map.set(key_bool, value_1);
3591  map.set(key_int64, value_2);
3592  map.set(key_uint64, value_3);
3593  map.set(key_float, value_4);
3594  map.set(key_double, value_5);
3595  map.set(key_string, value_6);
3596 
3597  CHECK(map.at(key_null) == value_0);
3598  CHECK(map.at(key_bool) == value_1);
3599  CHECK(map.at(key_int64) == value_2);
3600  CHECK(map.at(key_uint64) == value_3);
3601  CHECK(map.at(key_float) == value_4);
3602  CHECK(map.at(key_double) == value_5);
3603  CHECK(map.at(key_string) == value_6);
3604 
3605  map.at(key_null) = {false};
3606  CHECK(map.at(key_null) == Object{false});
3607  }
3608 
3609  SUBCASE("Not Exists")
3610  {
3611  Object bad_key = {};
3612  Object& bad_val = map.at(bad_key);
3613  CHECK(&bad_key == &bad_val);
3614  }
3615 }
3616 #endif // }}}
3617 
3618 
3626 void Map::clear() noexcept
3627 {
3628  null_map.clear();
3629  bool_map.clear();
3630  int64_map.clear();
3631  uint64_map.clear();
3632  float_map.clear();
3633  double_map.clear();
3634  string_map.clear();
3635 }
3636 
3637 
3643 size_t Map::size() const noexcept
3644 {
3645  const size_t size = null_map.size()
3646  + bool_map.size()
3647  + int64_map.size()
3648  + uint64_map.size()
3649  + float_map.size()
3650  + double_map.size()
3651  + string_map.size()
3652  ;
3653 
3654  return size;
3655 }
3656 
3657 
3658 // }}} Map
3659 // {{{ Object
3660 
3948 // }}} Object
3949 // {{{ Extensions
3950 // {{{ Extensions: Timestamp
3951 
3971 bool extensionTimestampCheck(const Object& object
3972  ) noexcept
3973 {
3974  if(object.isExt() == true)
3975  {
3976  const Ext& ext = object.asExt();
3977 
3978  if(ext.type == -1)
3979  {
3980  if(ext.data.size() == 4
3981  || ext.data.size() == 8
3982  || ext.data.size() == 12
3983  )
3984  {
3985  return true;
3986  }
3987  }
3988  }
3989 
3990  return false;
3991 }
3992 
3993 
3994 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
3995 TEST_CASE("extension/timestamp/check")
3996 {
3997  Object object = {Ext{}};
3998  Ext& ext = object.asExt();
3999 
4000  CHECK(extensionTimestampCheck(object) == false);
4001 
4002  // --- Bad Ext.type value --- //
4003 
4004  ext.data = std::vector<uint8_t>();
4005  CHECK(extensionTimestampCheck(object) == false);
4006 
4007  ext.data = std::vector<uint8_t>(1, 0);
4008  CHECK(extensionTimestampCheck(object) == false);
4009 
4010  ext.data = std::vector<uint8_t>(4, 0);
4011  CHECK(extensionTimestampCheck(object) == false);
4012 
4013  ext.data = std::vector<uint8_t>(8, 0);
4014  CHECK(extensionTimestampCheck(object) == false);
4015 
4016  ext.data = std::vector<uint8_t>(12, 0);
4017  CHECK(extensionTimestampCheck(object) == false);
4018 
4019  // --- Good Ext.type value --- //
4020 
4021  ext.type = -1;
4022  ext.data = std::vector<uint8_t>();
4023  CHECK(extensionTimestampCheck(object) == false);
4024 
4025  ext.data = std::vector<uint8_t>();
4026  CHECK(extensionTimestampCheck(object) == false);
4027 
4028  ext.data = std::vector<uint8_t>(1, 0);
4029  CHECK(extensionTimestampCheck(object) == false);
4030 
4031  ext.data = std::vector<uint8_t>(4, 0);
4032  CHECK(extensionTimestampCheck(object) == true);
4033 
4034  ext.data = std::vector<uint8_t>(8, 0);
4035  CHECK(extensionTimestampCheck(object) == true);
4036 
4037  ext.data = std::vector<uint8_t>(12, 0);
4038  CHECK(extensionTimestampCheck(object) == true);
4039 }
4040 #endif // }}}
4041 
4042 
4062 struct timespec extensionTimestampConvert(const Object& object
4063  ) noexcept
4064 {
4065  if(object.isExt() == false)
4066  {
4067  return {};
4068  }
4069 
4070  const Ext& ext = object.asExt();
4071 
4072  if(ext.type != -1)
4073  {
4074  return {};
4075  }
4076 
4077  switch(ext.data.size())
4078  {
4079  case 4:
4080  {
4081  Convert.uint64 = 0;
4082  Convert_Byte3 = ext.data[0];
4083  Convert_Byte2 = ext.data[1];
4084  Convert_Byte1 = ext.data[2];
4085  Convert_Byte0 = ext.data[3];
4086 
4087  timespec ts =
4088  { .tv_sec = Convert.uint32
4089  , .tv_nsec = 0
4090  };
4091 
4092  return ts;
4093  }
4094 
4095  case 8:
4096  {
4097  Convert.uint64 = 0;
4098  Convert_Byte3 = ext.data[0];
4099  Convert_Byte2 = ext.data[1];
4100  Convert_Byte1 = ext.data[2];
4101  Convert_Byte0 = ext.data[3];
4102  const uint32_t nsec = Convert.uint32 >> 2;
4103 
4104  Convert.uint64 = 0;
4105  Convert_Byte4 = ext.data[3];
4106  Convert_Byte3 = ext.data[4];
4107  Convert_Byte2 = ext.data[5];
4108  Convert_Byte1 = ext.data[6];
4109  Convert_Byte0 = ext.data[7];
4110  const int64_t sec = Convert.int64 & 0x0000'0003'ffff'ffff;
4111 
4112  timespec ts =
4113  { .tv_sec = sec
4114  , .tv_nsec = nsec
4115  };
4116 
4117  return ts;
4118  }
4119 
4120  case 12:
4121  {
4122  Convert.uint64 = 0;
4123  Convert_Byte3 = ext.data[0];
4124  Convert_Byte2 = ext.data[1];
4125  Convert_Byte1 = ext.data[2];
4126  Convert_Byte0 = ext.data[3];
4127  const uint32_t nsec = Convert.uint32;
4128 
4129  Convert.uint64 = 0;
4130  Convert_Byte7 = ext.data[ 4];
4131  Convert_Byte6 = ext.data[ 5];
4132  Convert_Byte5 = ext.data[ 6];
4133  Convert_Byte4 = ext.data[ 7];
4134  Convert_Byte3 = ext.data[ 8];
4135  Convert_Byte2 = ext.data[ 9];
4136  Convert_Byte1 = ext.data[10];
4137  Convert_Byte0 = ext.data[11];
4138  const int64_t sec = Convert.int64;
4139 
4140  timespec ts =
4141  { .tv_sec = sec
4142  , .tv_nsec = nsec
4143  };
4144 
4145  return ts;
4146  }
4147  }
4148 
4149  return {};
4150 }
4151 
4152 
4153 // Test is below
4154 
4155 
4174 Object extensionTimestampConvert(const struct timespec& ts
4175  ) noexcept
4176 {
4177  Object object = {Ext{}};
4178  Ext& ext = object.asExt();
4179 
4180  if((ts.tv_sec >> 34) == 0)
4181  {
4182  Convert.uint64 = (ts.tv_nsec << 34) | ts.tv_sec;
4183  if((Convert.uint64 & 0xffff'ffff'0000'0000) == 0)
4184  {
4185  ext.type = -1;
4186  ext.data.resize(4);
4187 
4188  size_t index = 0;
4189  ext.data[index++] = Convert_Byte3;
4190  ext.data[index++] = Convert_Byte2;
4191  ext.data[index++] = Convert_Byte1;
4192  ext.data[index++] = Convert_Byte0;
4193 
4194  return object;
4195  }
4196 
4197  ext.type = -1;
4198  ext.data.resize(8);
4199 
4200  size_t index = 0;
4201  ext.data[index++] = Convert_Byte7;
4202  ext.data[index++] = Convert_Byte6;
4203  ext.data[index++] = Convert_Byte5;
4204  ext.data[index++] = Convert_Byte4;
4205  ext.data[index++] = Convert_Byte3;
4206  ext.data[index++] = Convert_Byte2;
4207  ext.data[index++] = Convert_Byte1;
4208  ext.data[index++] = Convert_Byte0;
4209 
4210  return object;
4211  }
4212 
4213  ext.type = -1;
4214  ext.data.resize(12);
4215 
4216  size_t index = 0;
4217  Convert.uint64 = ts.tv_nsec;
4218  ext.data[index++] = Convert_Byte3;
4219  ext.data[index++] = Convert_Byte2;
4220  ext.data[index++] = Convert_Byte1;
4221  ext.data[index++] = Convert_Byte0;
4222 
4223  Convert.uint64 = ts.tv_sec;
4224  ext.data[index++] = Convert_Byte7;
4225  ext.data[index++] = Convert_Byte6;
4226  ext.data[index++] = Convert_Byte5;
4227  ext.data[index++] = Convert_Byte4;
4228  ext.data[index++] = Convert_Byte3;
4229  ext.data[index++] = Convert_Byte2;
4230  ext.data[index++] = Convert_Byte1;
4231  ext.data[index++] = Convert_Byte0;
4232 
4233  return object;
4234 }
4235 
4236 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
4237 TEST_CASE("extension/timestamp/convert/32bit")
4238 {
4239  SUBCASE("min")
4240  {
4241  const uint64_t sec = 0;
4242  const uint32_t nsec = 0;
4243 
4244  struct timespec time =
4245  { .tv_sec = sec
4246  , .tv_nsec = nsec
4247  };
4248 
4249  Object object = extensionTimestampConvert(time);
4250  {
4251  Ext& ext = object.asExt();
4252  CHECK(ext.type == -1);
4253  CHECK(ext.data.size() == 4);
4254  }
4255 
4256  std::vector<uint8_t> data = serialize(object);
4257  CHECK(data.size() == 6);
4258  size_t index = 0;
4259  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext4);
4260  CHECK(data[index++] == (uint8_t)-1);
4261  CHECK(data[index++] == 0);
4262  CHECK(data[index++] == 0);
4263  CHECK(data[index++] == 0);
4264  CHECK(data[index++] == 0);
4265 
4266  object = deserialize(data);
4267  CHECK(object.isExt() == true);
4268 
4269  Ext& ext = object.asExt();
4270  CHECK(ext.type == -1);
4271  CHECK(ext.data.size() == 4);
4272 
4273  time = extensionTimestampConvert(object);
4274  CHECK(time.tv_sec == sec);
4275  CHECK(time.tv_nsec == nsec);
4276  }
4277 
4278  SUBCASE("max")
4279  {
4280  const uint64_t sec = 0x0000'0000'ffff'ffff;
4281  const uint32_t nsec = 0;
4282 
4283  struct timespec time =
4284  { .tv_sec = sec
4285  , .tv_nsec = nsec
4286  };
4287 
4288  Object object = extensionTimestampConvert(time);
4289  {
4290  Ext& ext = object.asExt();
4291  CHECK(ext.type == -1);
4292  CHECK(ext.data.size() == 4);
4293  }
4294 
4295  std::vector<uint8_t> data = serialize(object);
4296  CHECK(data.size() == 6);
4297  size_t index = 0;
4298  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext4);
4299  CHECK(data[index++] == (uint8_t)-1);
4300  CHECK(data[index++] == 0xff);
4301  CHECK(data[index++] == 0xff);
4302  CHECK(data[index++] == 0xff);
4303  CHECK(data[index++] == 0xff);
4304 
4305  object = deserialize(data);
4306  CHECK(object.isExt() == true);
4307 
4308  Ext& ext = object.asExt();
4309  CHECK(ext.type == -1);
4310  CHECK(ext.data.size() == 4);
4311 
4312  time = extensionTimestampConvert(object);
4313  CHECK(time.tv_sec == sec);
4314  CHECK(time.tv_nsec == nsec);
4315  }
4316 
4317  SUBCASE("pattern")
4318  {
4319  const uint64_t sec = 0x12345678;
4320  const uint32_t nsec = 0;
4321 
4322  struct timespec time =
4323  { .tv_sec = sec
4324  , .tv_nsec = nsec
4325  };
4326 
4327  Object object = extensionTimestampConvert(time);
4328  {
4329  Ext& ext = object.asExt();
4330  CHECK(ext.type == -1);
4331  CHECK(ext.data.size() == 4);
4332  }
4333 
4334  std::vector<uint8_t> data = serialize(object);
4335  CHECK(data.size() == 6);
4336  size_t index = 0;
4337  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext4);
4338  CHECK(data[index++] == (uint8_t)-1);
4339  CHECK(data[index++] == 0x12);
4340  CHECK(data[index++] == 0x34);
4341  CHECK(data[index++] == 0x56);
4342  CHECK(data[index++] == 0x78);
4343 
4344  object = deserialize(data);
4345  CHECK(object.isExt() == true);
4346 
4347  Ext& ext = object.asExt();
4348  CHECK(ext.type == -1);
4349  CHECK(ext.data.size() == 4);
4350 
4351  time = extensionTimestampConvert(object);
4352  CHECK(time.tv_sec == sec);
4353  CHECK(time.tv_nsec == nsec);
4354  }
4355 }
4356 
4357 TEST_CASE("extension/timestamp/convert/64bit")
4358 {
4359  SUBCASE("min")
4360  {
4361  const uint64_t sec = 0x0000'0002'0000'0000;
4362  const uint32_t nsec = 0;
4363 
4364  struct timespec time =
4365  { .tv_sec = sec
4366  , .tv_nsec = nsec
4367  };
4368 
4369  Object object = extensionTimestampConvert(time);
4370  {
4371  Ext& ext = object.asExt();
4372  CHECK(ext.type == -1);
4373  CHECK(ext.data.size() == 8);
4374  }
4375 
4376  std::vector<uint8_t> data = serialize(object);
4377  CHECK(data.size() == 10);
4378  size_t index = 0;
4379  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext8);
4380  CHECK(data[index++] == (uint8_t)-1);
4381  CHECK(data[index++] == 0x00);
4382  CHECK(data[index++] == 0x00);
4383  CHECK(data[index++] == 0x00);
4384  CHECK(data[index++] == 0x02);
4385  CHECK(data[index++] == 0x00);
4386  CHECK(data[index++] == 0x00);
4387  CHECK(data[index++] == 0x00);
4388  CHECK(data[index++] == 0x00);
4389 
4390  object = deserialize(data);
4391  CHECK(object.isExt() == true);
4392 
4393  Ext& ext = object.asExt();
4394  CHECK(ext.type == -1);
4395  CHECK(ext.data.size() == 8);
4396 
4397  time = extensionTimestampConvert(object);
4398  CHECK(time.tv_sec == sec);
4399  CHECK(time.tv_nsec == nsec);
4400  }
4401 
4402  SUBCASE("max")
4403  {
4404  const uint64_t sec = 0x0000'0003'ffff'ffff;
4405  const uint32_t nsec = 0x3fff'ffff;
4406 
4407  struct timespec time =
4408  { .tv_sec = sec
4409  , .tv_nsec = nsec
4410  };
4411 
4412  Object object = extensionTimestampConvert(time);
4413  {
4414  Ext& ext = object.asExt();
4415  CHECK(ext.type == -1);
4416  CHECK(ext.data.size() == 8);
4417  }
4418 
4419  std::vector<uint8_t> data = serialize(object);
4420  CHECK(data.size() == 10);
4421  size_t index = 0;
4422  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext8);
4423  CHECK(data[index++] == (uint8_t)-1);
4424  CHECK(data[index++] == 0xff);
4425  CHECK(data[index++] == 0xff);
4426  CHECK(data[index++] == 0xff);
4427  CHECK(data[index++] == 0xff);
4428  CHECK(data[index++] == 0xff);
4429  CHECK(data[index++] == 0xff);
4430  CHECK(data[index++] == 0xff);
4431  CHECK(data[index++] == 0xff);
4432 
4433  object = deserialize(data);
4434  CHECK(object.isExt() == true);
4435 
4436  Ext& ext = object.asExt();
4437  CHECK(ext.type == -1);
4438  CHECK(ext.data.size() == 8);
4439 
4440  time = extensionTimestampConvert(object);
4441  CHECK(time.tv_sec == sec);
4442  CHECK(time.tv_nsec == nsec);
4443  }
4444 
4445  SUBCASE("pattern")
4446  {
4447  const uint64_t sec = 0x0000'0001'2345'6789;
4448  const uint32_t nsec = 0x0fed'cba9;
4449  // 0x0fed'cba9
4450  // 0b0000'1111'1110'1101'1100'1011'1010'1001
4451  // << 2
4452  // 0b0011'1111'1011'0111'0010'1110'1010'0100
4453  // 0x3fb7'2ea4
4454 
4455  struct timespec time =
4456  { .tv_sec = sec
4457  , .tv_nsec = nsec
4458  };
4459 
4460  Object object = extensionTimestampConvert(time);
4461  {
4462  Ext& ext = object.asExt();
4463  CHECK(ext.type == -1);
4464  CHECK(ext.data.size() == 8);
4465  }
4466 
4467  std::vector<uint8_t> data = serialize(object);
4468  CHECK(data.size() == 10);
4469  size_t index = 0;
4470  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext8);
4471  CHECK(data[index++] == (uint8_t)-1);
4472  CHECK(data[index++] == 0x3f);
4473  CHECK(data[index++] == 0xb7);
4474  CHECK(data[index++] == 0x2e);
4475  CHECK(data[index++] == 0xa5); // 0xa4 | 0x01
4476  CHECK(data[index++] == 0x23);
4477  CHECK(data[index++] == 0x45);
4478  CHECK(data[index++] == 0x67);
4479  CHECK(data[index++] == 0x89);
4480 
4481  object = deserialize(data);
4482  CHECK(object.isExt() == true);
4483 
4484  Ext& ext = object.asExt();
4485  CHECK(ext.type == -1);
4486  CHECK(ext.data.size() == 8);
4487 
4488  time = extensionTimestampConvert(object);
4489  CHECK(time.tv_sec == sec);
4490  CHECK(time.tv_nsec == nsec);
4491  }
4492 }
4493 
4494 TEST_CASE("extension/timestamp/convert/96bit")
4495 {
4496  SUBCASE("min")
4497  {
4498  const int64_t sec = 0x0000'0004'0000'0000;
4499  const uint64_t nsec = 0x0000'0000;
4500 
4501  struct timespec time =
4502  { .tv_sec = sec
4503  , .tv_nsec = nsec
4504  };
4505 
4506  Object object = extensionTimestampConvert(time);
4507  {
4508  Ext& ext = object.asExt();
4509  CHECK(ext.type == -1);
4510  CHECK(ext.data.size() == 12);
4511  }
4512 
4513  std::vector<uint8_t> data = serialize(object);
4514  CHECK(data.size() == 15);
4515  size_t index = 0;
4516  CHECK(data[index++] == (uint8_t)Format::Ext8);
4517  CHECK(data[index++] == 12);
4518  CHECK(data[index++] == (uint8_t)-1);
4519  // nsec
4520  CHECK(data[index++] == 0x00);
4521  CHECK(data[index++] == 0x00);
4522  CHECK(data[index++] == 0x00);
4523  CHECK(data[index++] == 0x00);
4524  // sec
4525  CHECK(data[index++] == 0x00);
4526  CHECK(data[index++] == 0x00);
4527  CHECK(data[index++] == 0x00);
4528  CHECK(data[index++] == 0x04);
4529  CHECK(data[index++] == 0x00);
4530  CHECK(data[index++] == 0x00);
4531  CHECK(data[index++] == 0x00);
4532  CHECK(data[index++] == 0x00);
4533 
4534  object = deserialize(data);
4535  CHECK(object.isExt() == true);
4536 
4537  Ext& ext = object.asExt();
4538  CHECK(ext.type == -1);
4539  CHECK(ext.data.size() == 12);
4540 
4541  time = extensionTimestampConvert(object);
4542  CHECK(time.tv_sec == sec);
4543  CHECK(time.tv_nsec == nsec);
4544  }
4545 
4546  SUBCASE("max")
4547  {
4548  const int64_t sec = 0x7fff'ffff'ffff'ffff;
4549  const uint64_t nsec = 0xffff'ffff;
4550 
4551  struct timespec time =
4552  { .tv_sec = sec
4553  , .tv_nsec = nsec
4554  };
4555 
4556  Object object = extensionTimestampConvert(time);
4557  {
4558  Ext& ext = object.asExt();
4559  CHECK(ext.type == -1);
4560  CHECK(ext.data.size() == 12);
4561  }
4562 
4563  std::vector<uint8_t> data = serialize(object);
4564  CHECK(data.size() == 15);
4565  size_t index = 0;
4566  CHECK(data[index++] == (uint8_t)Format::Ext8);
4567  CHECK(data[index++] == 12);
4568  CHECK(data[index++] == (uint8_t)-1);
4569  // nsec
4570  CHECK(data[index++] == 0xff);
4571  CHECK(data[index++] == 0xff);
4572  CHECK(data[index++] == 0xff);
4573  CHECK(data[index++] == 0xff);
4574  // sec
4575  CHECK(data[index++] == 0x7f);
4576  CHECK(data[index++] == 0xff);
4577  CHECK(data[index++] == 0xff);
4578  CHECK(data[index++] == 0xff);
4579  CHECK(data[index++] == 0xff);
4580  CHECK(data[index++] == 0xff);
4581  CHECK(data[index++] == 0xff);
4582  CHECK(data[index++] == 0xff);
4583 
4584  object = deserialize(data);
4585  CHECK(object.isExt() == true);
4586 
4587  Ext& ext = object.asExt();
4588  CHECK(ext.type == -1);
4589  CHECK(ext.data.size() == 12);
4590 
4591  time = extensionTimestampConvert(object);
4592  CHECK(time.tv_sec == sec);
4593  CHECK(time.tv_nsec == nsec);
4594  }
4595 
4596  SUBCASE("pattern")
4597  {
4598  const int64_t sec = 0x1234'5678'9abc'def0;
4599  const uint64_t nsec = 0xfedc'ba98;
4600 
4601  struct timespec time =
4602  { .tv_sec = sec
4603  , .tv_nsec = nsec
4604  };
4605 
4606  Object object = extensionTimestampConvert(time);
4607  {
4608  Ext& ext = object.asExt();
4609  CHECK(ext.type == -1);
4610  CHECK(ext.data.size() == 12);
4611  }
4612 
4613  std::vector<uint8_t> data = serialize(object);
4614  CHECK(data.size() == 15);
4615  size_t index = 0;
4616  CHECK(data[index++] == (uint8_t)Format::Ext8);
4617  CHECK(data[index++] == 12);
4618  CHECK(data[index++] == (uint8_t)-1);
4619  // nsec
4620  CHECK(data[index++] == 0xfe);
4621  CHECK(data[index++] == 0xdc);
4622  CHECK(data[index++] == 0xba);
4623  CHECK(data[index++] == 0x98);
4624  // sec
4625  CHECK(data[index++] == 0x12);
4626  CHECK(data[index++] == 0x34);
4627  CHECK(data[index++] == 0x56);
4628  CHECK(data[index++] == 0x78);
4629  CHECK(data[index++] == 0x9a);
4630  CHECK(data[index++] == 0xbc);
4631  CHECK(data[index++] == 0xde);
4632  CHECK(data[index++] == 0xf0);
4633 
4634  object = deserialize(data);
4635  CHECK(object.isExt() == true);
4636 
4637  Ext& ext = object.asExt();
4638  CHECK(ext.type == -1);
4639  CHECK(ext.data.size() == 12);
4640 
4641  time = extensionTimestampConvert(object);
4642  CHECK(time.tv_sec == sec);
4643  CHECK(time.tv_nsec == nsec);
4644  }
4645 }
4646 #endif // }}}
4647 // }}} Extensions: Timestamp
4648 // }}} Extensions
4649 // {{{ Utilities
4650 // {{{ Utilities::deserialize
4651 
4682 Object deserialize(const std::vector<uint8_t>& data
4683  ) noexcept
4684 {
4685  size_t index = 0;
4686  std::error_code error = {};
4687 
4688  return deserialize(data, index, error);
4689 }
4690 
4691 
4723 Object deserialize(const std::vector<uint8_t>& data
4724  , std::error_code& error
4725  ) noexcept
4726 {
4727  size_t index = 0;
4728 
4729  return deserialize(data, index, error);
4730 }
4731 
4732 
4764 Object deserialize(const std::vector<uint8_t>& data
4765  , size_t& index
4766  ) noexcept
4767 {
4768  std::error_code error = {};
4769 
4770  return deserialize(data, index, error);
4771 }
4772 
4773 
4809 Object deserialize(const std::vector<uint8_t>& data
4810  , size_t& index
4811  , std::error_code& error
4812  ) noexcept
4813 {
4814  error = Error_None;
4815 
4816  if(data.size() == 0)
4817  {
4818  error = Error_No_Data;
4819  return {};
4820  }
4821 
4822  if(index >= data.size())
4823  {
4824  error = Error_Invalid_Index;
4825  return {};
4826  }
4827 
4828  const uint8_t format_byte = data[index];
4829  const Format format_type = (Format)format_byte;
4830 
4831  if((index + formatSize(format_type)) > data.size())
4832  {
4833  error = Error_Incomplete;
4834  return {};
4835  }
4836 
4837  if(format_type == Format::Never_Used)
4838  {
4839  error = Error_Invalid_Format_Type;
4840  return {};
4841  }
4842 
4843  index++;
4844 
4845  switch(format_type)
4846  {
4847  case Format::Nill:
4848  return Object{};
4849 
4850  case Format::False:
4851  return Object{false};
4852 
4853  case Format::True:
4854  return Object{true};
4855 
4856  case Format::Int8:
4857  Convert.int64 = (int8_t)data[index++];
4858  return Object{Convert.int64};
4859 
4860  case Format::Int16:
4861  Convert.uint64 = 0;
4862  Convert_Byte1 = data[index++];
4863  Convert_Byte0 = data[index++];
4864  return Object{int64_t(Convert.int16)};
4865 
4866  case Format::Int32:
4867  Convert.uint64 = 0;
4868  Convert_Byte3 = data[index++];
4869  Convert_Byte2 = data[index++];
4870  Convert_Byte1 = data[index++];
4871  Convert_Byte0 = data[index++];
4872  return Object{int64_t(Convert.int32)};
4873 
4874  case Format::Int64:
4875  Convert_Byte7 = data[index++];
4876  Convert_Byte6 = data[index++];
4877  Convert_Byte5 = data[index++];
4878  Convert_Byte4 = data[index++];
4879  Convert_Byte3 = data[index++];
4880  Convert_Byte2 = data[index++];
4881  Convert_Byte1 = data[index++];
4882  Convert_Byte0 = data[index++];
4883  return Object{Convert.int64};
4884 
4885  case Format::Uint8:
4886  Convert.uint64 = data[index++];
4887  return Object{Convert.uint64};
4888 
4889  case Format::Uint16:
4890  Convert.uint64 = 0;
4891  Convert_Byte1 = data[index++];
4892  Convert_Byte0 = data[index++];
4893  return Object{Convert.uint64};
4894 
4895  case Format::Uint32:
4896  Convert.uint64 = 0;
4897  Convert_Byte3 = data[index++];
4898  Convert_Byte2 = data[index++];
4899  Convert_Byte1 = data[index++];
4900  Convert_Byte0 = data[index++];
4901  return Object{Convert.uint64};
4902 
4903  case Format::Uint64:
4904  Convert_Byte7 = data[index++];
4905  Convert_Byte6 = data[index++];
4906  Convert_Byte5 = data[index++];
4907  Convert_Byte4 = data[index++];
4908  Convert_Byte3 = data[index++];
4909  Convert_Byte2 = data[index++];
4910  Convert_Byte1 = data[index++];
4911  Convert_Byte0 = data[index++];
4912  return Object{Convert.uint64};
4913 
4914  case Format::Float32:
4915  Convert.uint64 = 0;
4916  Convert_Byte3 = data[index++];
4917  Convert_Byte2 = data[index++];
4918  Convert_Byte1 = data[index++];
4919  Convert_Byte0 = data[index++];
4920  return Object{Convert.float32};
4921 
4922  case Format::Float64:
4923  Convert_Byte7 = data[index++];
4924  Convert_Byte6 = data[index++];
4925  Convert_Byte5 = data[index++];
4926  Convert_Byte4 = data[index++];
4927  Convert_Byte3 = data[index++];
4928  Convert_Byte2 = data[index++];
4929  Convert_Byte1 = data[index++];
4930  Convert_Byte0 = data[index++];
4931  return Object{Convert.float64};
4932 
4933  case Format::Str8:
4934  {
4935  const size_t length = data[index++];
4936 
4937  if((index + length) > data.size())
4938  {
4939  error = Error_Incomplete;
4940  return Object{};
4941  }
4942 
4943  std::string_view str((char*)&data[index], length);
4944 
4945  index += length;
4946 
4947  return Object{std::string(str)};
4948  }
4949 
4950  case Format::Str16:
4951  {
4952  Convert.uint64 = 0;
4953  Convert_Byte1 = data[index++];
4954  Convert_Byte0 = data[index++];
4955  const size_t length = Convert.uint64;
4956 
4957  if((index + length) > data.size())
4958  {
4959  error = Error_Incomplete;
4960  return Object{};
4961  }
4962 
4963  const std::string_view str((char*)&data[index], length);
4964 
4965  index += length;
4966 
4967  return Object{std::string(str)};
4968  }
4969 
4970  case Format::Str32:
4971  {
4972  Convert.uint64 = 0;
4973  Convert_Byte3 = data[index++];
4974  Convert_Byte2 = data[index++];
4975  Convert_Byte1 = data[index++];
4976  Convert_Byte0 = data[index++];
4977  const size_t length = Convert.uint64;
4978 
4979  if((index + length) > data.size())
4980  {
4981  error = Error_Incomplete;
4982  return Object{};
4983  }
4984 
4985  const std::string_view str((char*)&data[index], length);
4986 
4987  index += length;
4988 
4989  return Object{std::string(str)};
4990  }
4991 
4992  case Format::Bin8:
4993  {
4994  const size_t length = data[index++];
4995 
4996  if((index + length) > data.size())
4997  {
4998  error = Error_Incomplete;
4999  return Object{};
5000  }
5001 
5002  std::vector<uint8_t> vector(length);
5003  memcpy((void*)vector.data(), (void*)&data[index], length);
5004 
5005  index += length;
5006 
5007  return Object{std::move(vector)};
5008  }
5009 
5010  case Format::Bin16:
5011  {
5012  Convert.uint64 = 0;
5013  Convert_Byte1 = data[index++];
5014  Convert_Byte0 = data[index++];
5015  const size_t length = Convert.uint64;
5016 
5017  if((index + length) > data.size())
5018  {
5019  error = Error_Incomplete;
5020  return Object{};
5021  }
5022 
5023  std::vector<uint8_t> vector(length);
5024  memcpy((void*)vector.data(), (void*)&data[index], length);
5025 
5026  index += length;
5027 
5028  return Object{std::move(vector)};
5029  }
5030 
5031  case Format::Bin32:
5032  {
5033  Convert.uint64 = 0;
5034  Convert_Byte3 = data[index++];
5035  Convert_Byte2 = data[index++];
5036  Convert_Byte1 = data[index++];
5037  Convert_Byte0 = data[index++];
5038  const size_t length = Convert.uint64;
5039 
5040  if((index + length) > data.size())
5041  {
5042  error = Error_Incomplete;
5043  return Object{};
5044  }
5045 
5046  std::vector<uint8_t> vector(length);
5047  memcpy((void*)vector.data(), (void*)&data[index], length);
5048 
5049  index += length;
5050 
5051  return Object{std::move(vector)};
5052  }
5053 
5054  case Format::Array16:
5055  {
5056  Object object = {Array{}};
5057 
5058  Convert.uint64 = 0;
5059  Convert_Byte1 = data[index++];
5060  Convert_Byte0 = data[index++];
5061  const size_t count = Convert.uint64;
5062 
5063  for(size_t i = 0; i < count; i++)
5064  {
5065  object.asArray().append(deserialize(data, index, error));
5066  if(error)
5067  {
5068  return {};
5069  }
5070  }
5071 
5072  return object;
5073  }
5074 
5075  case Format::Array32:
5076  {
5077  Object object = {Array{}};
5078 
5079  Convert.uint64 = 0;
5080  Convert_Byte3 = data[index++];
5081  Convert_Byte2 = data[index++];
5082  Convert_Byte1 = data[index++];
5083  Convert_Byte0 = data[index++];
5084  const size_t count = Convert.uint64;
5085 
5086  for(size_t i = 0; i < count; i++)
5087  {
5088  object.asArray().append(deserialize(data, index, error));
5089  if(error)
5090  {
5091  return {};
5092  }
5093  }
5094 
5095  return object;
5096  }
5097 
5098  case Format::Map16:
5099  {
5100  Object object = {Map{}};
5101 
5102  Convert.uint64 = 0;
5103  Convert_Byte1 = data[index++];
5104  Convert_Byte0 = data[index++];
5105  const size_t count = Convert.uint64;
5106 
5107  for(size_t i = 0; i < count; i++)
5108  {
5109  Object key = deserialize(data, index, error);
5110  if(error)
5111  {
5112  return {};
5113  }
5114 
5115  Object val = deserialize(data, index, error);
5116  if(error)
5117  {
5118  return {};
5119  }
5120 
5121  object.asMap().set(std::move(key), std::move(val));
5122  }
5123 
5124  return object;
5125  }
5126 
5127  case Format::Map32:
5128  {
5129  Object object = {Map{}};
5130 
5131  Convert.uint64 = 0;
5132  Convert_Byte3 = data[index++];
5133  Convert_Byte2 = data[index++];
5134  Convert_Byte1 = data[index++];
5135  Convert_Byte0 = data[index++];
5136  const size_t count = Convert.uint64;
5137 
5138  for(size_t i = 0; i < count; i++)
5139  {
5140  Object key = deserialize(data, index, error);
5141  if(error)
5142  {
5143  return {};
5144  }
5145 
5146  Object val = deserialize(data, index, error);
5147  if(error)
5148  {
5149  return {};
5150  }
5151 
5152  object.asMap().set(std::move(key), std::move(val));
5153  }
5154 
5155  return object;
5156  }
5157 
5158  case Format::Fixed_Ext1:
5159  {
5160  Object object = {Ext{}};
5161  Ext& ext = object.asExt();
5162 
5163  Convert.uint64 = 0;
5164  Convert.uint8 = data[index++];
5165  ext.type = Convert.int8;
5166 
5167  ext.data.push_back(data[index++]);
5168 
5169  return object;
5170  }
5171 
5172  case Format::Fixed_Ext2:
5173  {
5174  Object object = {Ext{}};
5175  Ext& ext = object.asExt();
5176 
5177  Convert.uint64 = 0;
5178  Convert.uint8 = data[index++];
5179  ext.type = Convert.int8;
5180 
5181  ext.data.push_back(data[index++]);
5182  ext.data.push_back(data[index++]);
5183 
5184  return object;
5185  }
5186 
5187  case Format::Fixed_Ext4:
5188  {
5189  Object object = {Ext{}};
5190  Ext& ext = object.asExt();
5191 
5192  Convert.uint64 = 0;
5193  Convert.uint8 = data[index++];
5194  ext.type = Convert.int8;
5195 
5196  ext.data.push_back(data[index++]);
5197  ext.data.push_back(data[index++]);
5198  ext.data.push_back(data[index++]);
5199  ext.data.push_back(data[index++]);
5200 
5201  return object;
5202  }
5203 
5204  case Format::Fixed_Ext8:
5205  {
5206  Object object = {Ext{}};
5207  Ext& ext = object.asExt();
5208 
5209  Convert.uint64 = 0;
5210  Convert.uint8 = data[index++];
5211  ext.type = Convert.int8;
5212 
5213  const size_t data_size = 8;
5214  ext.data.reserve(data_size);
5215 
5216  for(size_t i = 0; i < data_size; i++)
5217  {
5218  ext.data.push_back(data[index++]);
5219  }
5220 
5221  return object;
5222  }
5223 
5224  case Format::Fixed_Ext16:
5225  {
5226  Object object = {Ext{}};
5227  Ext& ext = object.asExt();
5228 
5229  Convert.uint64 = 0;
5230  Convert.uint8 = data[index++];
5231  ext.type = Convert.int8;
5232 
5233  const size_t data_size = 16;
5234  ext.data.reserve(data_size);
5235 
5236  for(size_t i = 0; i < data_size; i++)
5237  {
5238  ext.data.push_back(data[index++]);
5239  }
5240 
5241  return object;
5242  }
5243 
5244  case Format::Ext8:
5245  {
5246  Object object = {Ext{}};
5247  Ext& ext = object.asExt();
5248 
5249  const size_t data_size = data[index++];
5250 
5251  if((index + data_size) > data.size())
5252  {
5253  error = Error_Incomplete;
5254  return Object{};
5255  }
5256 
5257  Convert.uint64 = 0;
5258  Convert.uint8 = data[index++];
5259  ext.type = Convert.int8;
5260 
5261  if(data_size > 0)
5262  {
5263  ext.data.resize(data_size);
5264  memcpy((void*)ext.data.data(), (void*)&data[index], data_size);
5265  index += data_size;
5266  }
5267 
5268  return object;
5269  }
5270 
5271  case Format::Ext16:
5272  {
5273  Object object = {Ext{}};
5274  Ext& ext = object.asExt();
5275 
5276  Convert.uint64 = 0;
5277  Convert_Byte1 = data[index++];
5278  Convert_Byte0 = data[index++];
5279  const size_t data_size = Convert.uint16;
5280 
5281  if((index + data_size) > data.size())
5282  {
5283  error = Error_Incomplete;
5284  return Object{};
5285  }
5286 
5287  Convert.uint64 = 0;
5288  Convert.uint8 = data[index++];
5289  ext.type = Convert.int8;
5290 
5291  ext.data.resize(data_size);
5292  memcpy((void*)ext.data.data(), (void*)&data[index], data_size);
5293 
5294  index += data_size + 1;
5295 
5296  return object;
5297  }
5298 
5299  case Format::Ext32:
5300  {
5301  Object object = {Ext{}};
5302  Ext& ext = object.asExt();
5303 
5304  Convert.uint64 = 0;
5305  Convert_Byte3 = data[index++];
5306  Convert_Byte2 = data[index++];
5307  Convert_Byte1 = data[index++];
5308  Convert_Byte0 = data[index++];
5309  const size_t data_size = Convert.uint32;
5310 
5311  if((index + data_size) > data.size())
5312  {
5313  error = Error_Incomplete;
5314  return Object{};
5315  }
5316 
5317  Convert.uint64 = 0;
5318  Convert.uint8 = data[index++];
5319  ext.type = Convert.int8;
5320 
5321  ext.data.resize(data_size);
5322  memcpy((void*)ext.data.data(), (void*)&data[index], data_size);
5323 
5324  index += data_size + 1;
5325 
5326  return object;
5327  }
5328 
5329  case Format::Fixed_Int_Pos:
5330  case Format::Fixed_Int_Neg:
5331  case Format::Fixed_Array:
5332  case Format::Fixed_Str:
5333  case Format::Fixed_Map:
5334  case Format::Never_Used:
5335  // Handled outside of this swith() statement
5336  break;
5337  }
5338 
5339  if((format_byte & (uint8_t)Fixed_Int_Pos_Mask) == (uint8_t)Format::Fixed_Int_Pos)
5340  {
5341  const int64_t value = format_byte & (uint8_t)Fixed_Int_Pos_Value;
5342 
5343  return Object{value};
5344  }
5345 
5346  if((format_byte & (uint8_t)Fixed_Int_Neg_Mask) == (uint8_t)Format::Fixed_Int_Neg)
5347  {
5348  const int64_t value = (int8_t)(format_byte & Fixed_Int_Neg_Value) - 32;
5349 
5350  return Object{value};
5351  }
5352 
5353  if((format_byte & (uint8_t)Fixed_Str_Mask) == (uint8_t)Format::Fixed_Str)
5354  {
5355  const size_t length = format_byte & Fixed_Str_Value;
5356 
5357  if(length == 0)
5358  {
5359  return Object{std::string("")};
5360  }
5361  else
5362  {
5363  if((index + length) > data.size())
5364  {
5365  error = Error_Incomplete;
5366  return Object{};
5367  }
5368 
5369  std::string_view str((char*)&data[index], length);
5370 
5371  index += length;
5372 
5373  return Object{std::string(str)};
5374  }
5375  }
5376 
5377  if((format_byte & (uint8_t)Fixed_Array_Mask) == (uint8_t)Format::Fixed_Array)
5378  {
5379  Object object = {Array{}};
5380 
5381  const size_t count = format_byte & (uint8_t)Fixed_Array_Value;
5382 
5383  for(size_t i = 0; i < count; i++)
5384  {
5385  object.asArray().append(deserialize(data, index, error));
5386 
5387  if(error)
5388  {
5389  return {};
5390  }
5391  }
5392 
5393  return object;
5394  }
5395 
5396  if((format_byte & (uint8_t)Fixed_Map_Mask) == (uint8_t)Format::Fixed_Map)
5397  {
5398  Object object = {Map{}};
5399 
5400  const size_t count = format_byte & (uint8_t)Fixed_Map_Value;
5401 
5402  for(size_t i = 0; i < count; i++)
5403  {
5404  Object key = deserialize(data, index, error);
5405  if(error)
5406  {
5407  return {};
5408  }
5409 
5410  Object val = deserialize(data, index, error);
5411  if(error)
5412  {
5413  return {};
5414  }
5415 
5416  object.asMap().set(std::move(key), std::move(val));
5417  }
5418 
5419  return object;
5420  }
5421 
5422  return {};
5423 }
5424 
5425 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
5426 TEST_CASE("deserialize/error")
5427 {
5428  std::vector<uint8_t> data = {};
5429  std::error_code error = {};
5430  Object object = {};
5431  size_t index = 0;
5432 
5433  SUBCASE("no data")
5434  {
5435  object = deserialize(data, index, error);
5436  CHECK(error == Error_No_Data);
5437  CHECK(index == 0);
5438  CHECK(object.isNull() == true);
5439  }
5440 
5441  SUBCASE("invalid index")
5442  {
5443  data.push_back(0);
5444  index = 10;
5445 
5446  object = deserialize(data, index, error);
5447  CHECK(error == Error_Invalid_Index);
5448  CHECK(index == 10);
5449  CHECK(object.isNull() == true);
5450  }
5451 
5452  SUBCASE("Never_Used")
5453  {
5454  data.push_back((uint8_t)Format::Never_Used);
5455 
5456  object = deserialize(data, index, error);
5457  CHECK(error == Error_Invalid_Format_Type);
5458  CHECK(index == 0);
5459  CHECK(object.isNull() == true);
5460  }
5461 
5462  // The following format ID's can not be tested for incomplete data
5463  // because the value is encoded in the Format ID itself:
5464  // - Nill
5465  // - True
5466  // - False
5467  // - Fixed_Int_Pos
5468  // - Fixed_Int_Neg
5469 
5470  SUBCASE("Uint8")
5471  {
5472  object = Object{(uint64_t)std::numeric_limits<uint8_t>::max()};
5473  object = Object{uint64_t(0xff)};
5474  data = serialize(object);
5475  data.resize(data.size() - 1);
5476 
5477  object = deserialize(data, index, error);
5478  CHECK(data[0] == (uint8_t)Format::Uint8);
5479  CHECK(error == Error_Incomplete);
5480  CHECK(index == index);
5481  CHECK(object.isNull() == true);
5482  }
5483 
5484  SUBCASE("Uint16")
5485  {
5486  object = Object{(uint64_t)std::numeric_limits<uint16_t>::max()};
5487  data = serialize(object);
5488  data.resize(data.size() - 1);
5489 
5490  object = deserialize(data, index, error);
5491  CHECK(data[0] == (uint8_t)Format::Uint16);
5492  CHECK(error == Error_Incomplete);
5493  CHECK(index == index);
5494  CHECK(object.isNull() == true);
5495  }
5496 
5497  SUBCASE("Uint32")
5498  {
5499  object = Object{(uint64_t)std::numeric_limits<uint32_t>::max()};
5500  data = serialize(object);
5501  data.resize(data.size() - 1);
5502 
5503  object = deserialize(data, index, error);
5504  CHECK(data[0] == (uint8_t)Format::Uint32);
5505  CHECK(error == Error_Incomplete);
5506  CHECK(index == index);
5507  CHECK(object.isNull() == true);
5508  }
5509 
5510  SUBCASE("Uint64")
5511  {
5512  object = Object{(uint64_t)std::numeric_limits<uint64_t>::max()};
5513  data = serialize(object);
5514  data.resize(data.size() - 1);
5515 
5516  object = deserialize(data, index, error);
5517  CHECK(data[0] == (uint8_t)Format::Uint64);
5518  CHECK(error == Error_Incomplete);
5519  CHECK(index == index);
5520  CHECK(object.isNull() == true);
5521  }
5522 
5523  SUBCASE("Int8")
5524  {
5525  object = Object{int64_t(std::numeric_limits<int8_t>::min())};
5526  data = serialize(object);
5527  data.resize(data.size() - 1);
5528 
5529  object = deserialize(data, index, error);
5530  CHECK(data[0] == (uint8_t)Format::Int8);
5531  CHECK(error == Error_Incomplete);
5532  CHECK(index == index);
5533  CHECK(object.isNull() == true);
5534  }
5535 
5536  SUBCASE("Int16")
5537  {
5538  object = Object{int64_t(std::numeric_limits<int16_t>::min())};
5539  data = serialize(object);
5540  data.resize(data.size() - 1);
5541 
5542  object = deserialize(data, index, error);
5543  CHECK(data[0] == (uint8_t)Format::Int16);
5544  CHECK(error == Error_Incomplete);
5545  CHECK(index == index);
5546  CHECK(object.isNull() == true);
5547  }
5548 
5549  SUBCASE("Int32")
5550  {
5551  object = Object{int64_t(std::numeric_limits<int32_t>::min())};
5552  data = serialize(object);
5553  data.resize(data.size() - 1);
5554 
5555  object = deserialize(data, index, error);
5556  CHECK(data[0] == (uint8_t)Format::Int32);
5557  CHECK(error == Error_Incomplete);
5558  CHECK(index == index);
5559  CHECK(object.isNull() == true);
5560  }
5561 
5562  SUBCASE("Int64")
5563  {
5564  object = Object{std::numeric_limits<int64_t>::min()};
5565  data = serialize(object);
5566  data.resize(data.size() - 1);
5567 
5568  object = deserialize(data, index, error);
5569  CHECK(data[0] == (uint8_t)Format::Int64);
5570  CHECK(error == Error_Incomplete);
5571  CHECK(index == index);
5572  CHECK(object.isNull() == true);
5573  }
5574 
5575  SUBCASE("Float32")
5576  {
5577  object = Object{std::numeric_limits<float>::min()};
5578  data = serialize(object);
5579  data.resize(data.size() - 1);
5580 
5581  object = deserialize(data, index, error);
5582  CHECK(data[0] == (uint8_t)Format::Float32);
5583  CHECK(error == Error_Incomplete);
5584  CHECK(index == index);
5585  CHECK(object.isNull() == true);
5586  }
5587 
5588  SUBCASE("Float64")
5589  {
5590  object = Object{std::numeric_limits<double>::min()};
5591  data = serialize(object);
5592  data.resize(data.size() - 1);
5593 
5594  object = deserialize(data, index, error);
5595  CHECK(data[0] == (uint8_t)Format::Float64);
5596  CHECK(error == Error_Incomplete);
5597  CHECK(index == index);
5598  CHECK(object.isNull() == true);
5599  }
5600 
5601  SUBCASE("Fixed_Str")
5602  {
5603  object = Object{std::string(16, 'X')};
5604  data = serialize(object);
5605  data.resize(data.size() - 1);
5606 
5607  object = deserialize(data, index, error);
5608  CHECK((data[0] & Fixed_Str_Mask) == (uint8_t)Format::Fixed_Str);
5609  CHECK(error == Error_Incomplete);
5610  CHECK(index == index);
5611  CHECK(object.isNull() == true);
5612  }
5613 
5614  SUBCASE("Str8")
5615  {
5616  object = Object{std::string(32, 'X')};
5617  data = serialize(object);
5618  data.resize(data.size() - 1);
5619 
5620  object = deserialize(data, index, error);
5621  CHECK(data[0] == (uint8_t)Format::Str8);
5622  CHECK(error == Error_Incomplete);
5623  CHECK(index == index);
5624  CHECK(object.isNull() == true);
5625  }
5626 
5627  SUBCASE("Str16")
5628  {
5629  object = Object{std::string(std::numeric_limits<uint8_t>::max() + 1, 'X')};
5630  data = serialize(object);
5631  data.resize(data.size() - 1);
5632 
5633  object = deserialize(data, index, error);
5634  CHECK(data[0] == (uint8_t)Format::Str16);
5635  CHECK(error == Error_Incomplete);
5636  CHECK(index == index);
5637  CHECK(object.isNull() == true);
5638  }
5639 
5640  SUBCASE("Str32")
5641  {
5642  object = Object{std::string(std::numeric_limits<uint16_t>::max() + 1, 'X')};
5643  data = serialize(object);
5644  data.resize(data.size() - 1);
5645 
5646  object = deserialize(data, index, error);
5647  CHECK(data[0] == (uint8_t)Format::Str32);
5648  CHECK(error == Error_Incomplete);
5649  CHECK(index == index);
5650  CHECK(object.isNull() == true);
5651  }
5652 
5653  SUBCASE("Bin8")
5654  {
5655  object = Object{std::vector<uint8_t>(0, 'X')};
5656  data = serialize(object);
5657  data.resize(data.size() - 1);
5658 
5659  object = deserialize(data, index, error);
5660  CHECK(data[0] == (uint8_t)Format::Bin8);
5661  CHECK(error == Error_Incomplete);
5662  CHECK(index == index);
5663  CHECK(object.isNull() == true);
5664  }
5665 
5666  SUBCASE("Bin16")
5667  {
5668  object = Object{std::vector<uint8_t>(std::numeric_limits<uint8_t>::max() + 1, 'X')};
5669  data = serialize(object);
5670  data.resize(data.size() - 1);
5671 
5672  object = deserialize(data, index, error);
5673  CHECK(data[0] == (uint8_t)Format::Bin16);
5674  CHECK(error == Error_Incomplete);
5675  CHECK(index == index);
5676  CHECK(object.isNull() == true);
5677  }
5678 
5679  SUBCASE("Bin32")
5680  {
5681  object = Object{std::vector<uint8_t>(std::numeric_limits<uint16_t>::max() + 1, 'X')};
5682  data = serialize(object);
5683  data.resize(data.size() - 1);
5684 
5685  object = deserialize(data, index, error);
5686  CHECK(data[0] == (uint8_t)Format::Bin32);
5687  CHECK(error == Error_Incomplete);
5688  CHECK(index == index);
5689  CHECK(object.isNull() == true);
5690  }
5691 
5692  SUBCASE("Fixed_Array")
5693  {
5694  // Check the Array itself
5695  Array array;
5696  array.object_vector = std::vector<Object>(8, Object{});
5697  data = serialize(array);
5698  data.resize(data.size() - 1);
5699 
5700  object = deserialize(data, index, error);
5701  CHECK((data[0] & Fixed_Array_Mask) == (uint8_t)Format::Fixed_Array);
5702  CHECK(error == Error_Invalid_Index);
5703  CHECK(index == index);
5704  CHECK(object.isNull() == true);
5705 
5706  // Check the contents of the Array
5707  index = 0;
5708  array.object_vector = std::vector<Object>(1, Object{});
5709  array.object(0) = Object{std::string("ABC")};
5710  data = serialize(array);
5711  data.resize(data.size() - 1);
5712 
5713  object = deserialize(data, index, error);
5714  CHECK((data[0] & Fixed_Array_Mask) == (uint8_t)Format::Fixed_Array);
5715  CHECK(error == Error_Incomplete);
5716  CHECK(index == index);
5717  CHECK(object.isNull() == true);
5718  }
5719 
5720  SUBCASE("Array16")
5721  {
5722  Array array;
5723  array.object_vector = std::vector<Object>(16, Object{});
5724  data = serialize(array);
5725  data.resize(data.size() - 1);
5726 
5727  object = deserialize(data, index, error);
5728  CHECK(data[0] == (uint8_t)Format::Array16);
5729  CHECK(error == Error_Incomplete);
5730  CHECK(index == index);
5731  CHECK(object.isNull() == true);
5732  }
5733 
5734  SUBCASE("Array32")
5735  {
5736  Array array;
5737  array.object_vector = std::vector<Object>(std::numeric_limits<uint16_t>::max() + 1, Object{});
5738  data = serialize(array);
5739  data.resize(data.size() - 1);
5740 
5741  object = deserialize(data, index, error);
5742  CHECK(data[0] == (uint8_t)Format::Array32);
5743  CHECK(error == Error_Incomplete);
5744  CHECK(index == index);
5745  CHECK(object.isNull() == true);
5746  }
5747 
5748  SUBCASE("Fixed_Map")
5749  {
5750  // Check the Map itself
5751  Map map;
5752  map.set(Object{}, Object{});
5753  data = serialize(map);
5754  data.resize(data.size() - 1);
5755 
5756  object = deserialize(data, index, error);
5757  CHECK((data[0] & Fixed_Map_Mask) == (uint8_t)Format::Fixed_Map);
5758  CHECK(error == Error_Invalid_Index);
5759  CHECK(index == index);
5760  CHECK(object.isNull() == true);
5761 
5762  // Check the contents of the Map
5763  index = 0;
5764  map.set(Object{int64_t(0)}, Object{});
5765  map.set(Object{int64_t(1)}, Object{std::string("Hello, World")});
5766  data = serialize(map);
5767  data.resize(data.size() - 1);
5768 
5769  object = deserialize(data, index, error);
5770  CHECK((data[0] & Fixed_Map_Mask) == (uint8_t)Format::Fixed_Map);
5771  CHECK(error == Error_Incomplete);
5772  CHECK(index == index);
5773  CHECK(object.isNull() == true);
5774  }
5775 
5776  SUBCASE("Map16")
5777  {
5778  Map map;
5779  for(size_t i = 0; i < 16; i++)
5780  {
5781  map.set(Object{int64_t(i)}, Object{});
5782  }
5783  data = serialize(map);
5784  data.resize(data.size() - 1);
5785 
5786  object = deserialize(data, index, error);
5787  CHECK(data[0] == (uint8_t)Format::Map16);
5788  CHECK(data[1] == (uint8_t)Format::Fixed_Int_Pos);
5789  CHECK(error == Error_Incomplete);
5790  CHECK(index == index);
5791  CHECK(object.isNull() == true);
5792  }
5793 
5794  SUBCASE("Map32")
5795  {
5796  Map map;
5797  for(size_t i = 0; i < (std::numeric_limits<uint16_t>::max() + 1) ; i++)
5798  {
5799  map.set(Object{int64_t(i)}, Object{});
5800  }
5801  data = serialize(map);
5802  data.resize(data.size() - 1);
5803 
5804  object = deserialize(data, index, error);
5805  CHECK(data[0] == (uint8_t)Format::Map32);
5806  CHECK(data[1] == (uint8_t)Format::Fixed_Int_Pos);
5807  CHECK(error == Error_Incomplete);
5808  CHECK(index == index);
5809  CHECK(object.isNull() == true);
5810  }
5811 
5812  SUBCASE("Fixed_Ext1")
5813  {
5814  Ext ext;
5815  ext.data = std::vector<uint8_t>(1, 'X');
5816  data = serialize(ext);
5817  data.resize(data.size() - 1);
5818 
5819  object = deserialize(data, index, error);
5820  CHECK(data[0] == (uint8_t)Format::Fixed_Ext1);
5821  CHECK(error == Error_Incomplete);
5822  CHECK(index == index);
5823  CHECK(object.isNull() == true);
5824  }
5825 
5826  SUBCASE("Fixed_Ext2")
5827  {
5828  Ext ext;
5829  ext.data = std::vector<uint8_t>(2, 'X');
5830  data = serialize(ext);
5831  data.resize(data.size() - 1);
5832 
5833  object = deserialize(data, index, error);
5834  CHECK(data[0] == (uint8_t)Format::Fixed_Ext2);
5835  CHECK(error == Error_Incomplete);
5836  CHECK(index == index);
5837  CHECK(object.isNull() == true);
5838  }
5839 
5840  SUBCASE("Fixed_Ext4")
5841  {
5842  Ext ext;
5843  ext.data = std::vector<uint8_t>(4, 'X');
5844  data = serialize(ext);
5845  data.resize(data.size() - 1);
5846 
5847  object = deserialize(data, index, error);
5848  CHECK(data[0] == (uint8_t)Format::Fixed_Ext4);
5849  CHECK(error == Error_Incomplete);
5850  CHECK(index == index);
5851  CHECK(object.isNull() == true);
5852  }
5853 
5854  SUBCASE("Fixed_Ext8")
5855  {
5856  Ext ext;
5857  ext.data = std::vector<uint8_t>(8, 'X');
5858  data = serialize(ext);
5859  data.resize(data.size() - 1);
5860 
5861  object = deserialize(data, index, error);
5862  CHECK(data[0] == (uint8_t)Format::Fixed_Ext8);
5863  CHECK(error == Error_Incomplete);
5864  CHECK(index == index);
5865  CHECK(object.isNull() == true);
5866  }
5867 
5868  SUBCASE("Fixed_Ext16")
5869  {
5870  Ext ext;
5871  ext.data = std::vector<uint8_t>(16, 'X');
5872  data = serialize(ext);
5873  data.resize(data.size() - 1);
5874 
5875  object = deserialize(data, index, error);
5876  CHECK(data[0] == (uint8_t)Format::Fixed_Ext16);
5877  CHECK(error == Error_Incomplete);
5878  CHECK(index == index);
5879  CHECK(object.isNull() == true);
5880  }
5881 
5882  SUBCASE("Ext8")
5883  {
5884  Ext ext;
5885  ext.data = std::vector<uint8_t>(0, 'X');
5886  data = serialize(ext);
5887  data.resize(data.size() - 1);
5888 
5889  object = deserialize(data, index, error);
5890  CHECK(data[0] == (uint8_t)Format::Ext8);
5891  CHECK(error == Error_Incomplete);
5892  CHECK(index == index);
5893  CHECK(object.isNull() == true);
5894  }
5895 
5896  SUBCASE("Ext16")
5897  {
5898  Ext ext;
5899  ext.data = std::vector<uint8_t>(std::numeric_limits<uint8_t>::max() + 1, 'X');
5900  data = serialize(ext);
5901  data.resize(data.size() - 1);
5902 
5903  object = deserialize(data, index, error);
5904  CHECK(data[0] == (uint8_t)Format::Ext16);
5905  CHECK(error == Error_Incomplete);
5906  CHECK(index == index);
5907  CHECK(object.isNull() == true);
5908  }
5909 
5910  SUBCASE("Ext32")
5911  {
5912  Ext ext;
5913  ext.data = std::vector<uint8_t>(std::numeric_limits<uint16_t>::max() + 1, 'X');
5914  data = serialize(ext);
5915  data.resize(data.size() - 1);
5916 
5917  object = deserialize(data, index, error);
5918  CHECK(data[0] == (uint8_t)Format::Ext32);
5919  CHECK(error == Error_Incomplete);
5920  CHECK(index == index);
5921  CHECK(object.isNull() == true);
5922  }
5923 }
5924 #endif // }}}
5925 
5926 // }}} Utilities::deserialize
5927 // {{{ Utilities::serialize
5928 
5947 std::vector<uint8_t> serialize(const Array& array
5948  ) noexcept
5949 {
5950  std::error_code error;
5951 
5952  return serialize(array, error);
5953 }
5954 
5955 
5983 std::vector<uint8_t> serialize(const Array& array
5984  , std::error_code& error
5985  ) noexcept
5986 {
5987  std::vector<uint8_t> vector;
5988 
5989  error = serialize_(array, vector);
5990 
5991  return vector;
5992 }
5993 
5994 
6010 std::vector<uint8_t> serialize(const Ext& ext
6011  ) noexcept
6012 {
6013  std::error_code error;
6014 
6015  return serialize(ext, error);
6016 }
6017 
6018 
6035 std::vector<uint8_t> serialize(const Ext& ext
6036  , std::error_code& error
6037  ) noexcept
6038 {
6039  std::vector<uint8_t> vector;
6040 
6041  error = serialize_(ext, vector);
6042 
6043  return vector;
6044 }
6045 
6046 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
6047 TEST_CASE("serialize/ext (fixed_ext1)")
6048 {
6049  Ext ext;
6050  std::vector<uint8_t> data;
6051  const size_t data_len = 1;
6052  const int8_t type = 42;
6053 
6054  ext.type = type;
6055  ext.data = std::vector<uint8_t>(data_len, '_');
6056 
6057  data = serialize(ext);
6058  CHECK(data.size() == 3);
6059  size_t index = 0;
6060  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext1);
6061  CHECK(data[index++] == type);
6062  CHECK(data[index++] == '_');
6063 
6064  Object object = deserialize(data);
6065  CHECK(object.isExt() == true);
6066 
6067  CHECK(object.asExt().type == type);
6068  CHECK(object.asExt().data.size() == 1);
6069  CHECK(object.asExt().data[0] == '_');
6070 }
6071 
6072 TEST_CASE("serialize/ext (fixed_ext2)")
6073 {
6074  Ext ext;
6075  std::vector<uint8_t> data;
6076  const size_t data_len = 2;
6077  const int8_t type = 42;
6078 
6079  ext.type = type;
6080  ext.data = std::vector<uint8_t>(data_len, '_');
6081 
6082  data = serialize(ext);
6083  CHECK(data.size() == 4);
6084  size_t index = 0;
6085  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext2);
6086  CHECK(data[index++] == type);
6087 
6088  Object object = deserialize(data);
6089  CHECK(object.isExt() == true);
6090 
6091  CHECK(object.asExt().type == type);
6092  CHECK(object.asExt().data.size() == data_len);
6093 
6094  for(size_t i = 0; i < data_len; i++)
6095  {
6096  CHECK(object.asExt().data[i] == '_');
6097  }
6098 }
6099 
6100 TEST_CASE("serialize/ext (fixed_ext4)")
6101 {
6102  Ext ext;
6103  std::vector<uint8_t> data;
6104  const size_t data_len = 4;
6105  const int8_t type = 42;
6106 
6107  ext.type = type;
6108  ext.data = std::vector<uint8_t>(data_len, '_');
6109 
6110  data = serialize(ext);
6111  CHECK(data.size() == 6);
6112  size_t index = 0;
6113  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext4);
6114  CHECK(data[index++] == type);
6115 
6116  Object object = deserialize(data);
6117  CHECK(object.isExt() == true);
6118 
6119  CHECK(object.asExt().type == type);
6120  CHECK(object.asExt().data.size() == data_len);
6121 
6122  for(size_t i = 0; i < data_len; i++)
6123  {
6124  CHECK(object.asExt().data[i] == '_');
6125  }
6126 }
6127 
6128 TEST_CASE("serialize/ext (fixed_ext8)")
6129 {
6130  Ext ext;
6131  std::vector<uint8_t> data;
6132  const size_t data_len = 8;
6133  const int8_t type = 42;
6134 
6135  ext.type = type;
6136  ext.data = std::vector<uint8_t>(data_len, '_');
6137 
6138  data = serialize(ext);
6139  CHECK(data.size() == 10);
6140  size_t index = 0;
6141  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext8);
6142  CHECK(data[index++] == type);
6143 
6144  Object object = deserialize(data);
6145  CHECK(object.isExt() == true);
6146 
6147  CHECK(object.asExt().type == type);
6148  CHECK(object.asExt().data.size() == data_len);
6149 
6150  for(size_t i = 0; i < data_len; i++)
6151  {
6152  CHECK(object.asExt().data[i] == '_');
6153  }
6154 }
6155 
6156 TEST_CASE("serialize/ext (fixed_ext16)")
6157 {
6158  Ext ext;
6159  std::vector<uint8_t> data;
6160  const size_t data_len = 16;
6161  const int8_t type = 42;
6162 
6163  ext.type = type;
6164  ext.data = std::vector<uint8_t>(data_len, '_');
6165 
6166  data = serialize(ext);
6167  CHECK(data.size() == 18);
6168  size_t index = 0;
6169  CHECK(data[index++] == (uint8_t)Format::Fixed_Ext16);
6170  CHECK(data[index++] == type);
6171 
6172  Object object = deserialize(data);
6173  CHECK(object.isExt() == true);
6174 
6175  CHECK(object.asExt().type == type);
6176  CHECK(object.asExt().data.size() == data_len);
6177 
6178  for(size_t i = 0; i < data_len; i++)
6179  {
6180  CHECK(object.asExt().data[i] == '_');
6181  }
6182 }
6183 
6184 TEST_CASE("serialize/ext (ext8)")
6185 {
6186  std::vector<uint8_t> data;
6187  const int8_t type = 42;
6188 
6189  Ext ext;
6190  ext.type = type;
6191 
6192  SUBCASE("length=0")
6193  {
6194  const size_t data_len = 0;
6195  ext.data = std::vector<uint8_t>(data_len, '_');
6196 
6197  data = serialize(ext);
6198  CHECK(data.size() == 3);
6199  size_t index = 0;
6200  CHECK(data[index++] == (uint8_t)Format::Ext8);
6201  CHECK(data[index++] == data_len);
6202  CHECK(data[index++] == type);
6203 
6204  Object object = deserialize(data);
6205  CHECK(object.isExt() == true);
6206 
6207  CHECK(object.asExt().type == type);
6208  CHECK(object.asExt().data.size() == data_len);
6209 
6210  for(size_t i = 0; i < data_len; i++)
6211  {
6212  CHECK(object.asExt().data[i] == '_');
6213  }
6214  }
6215 
6216  SUBCASE("length=5")
6217  {
6218  const size_t data_len = 5;
6219  ext.data = std::vector<uint8_t>(data_len, '_');
6220 
6221  data = serialize(ext);
6222  CHECK(data.size() == 8);
6223  size_t index = 0;
6224  CHECK(data[index++] == (uint8_t)Format::Ext8);
6225  CHECK(data[index++] == data_len);
6226  CHECK(data[index++] == type);
6227 
6228  Object object = deserialize(data);
6229  CHECK(object.isExt() == true);
6230 
6231  CHECK(object.asExt().type == type);
6232  CHECK(object.asExt().data.size() == data_len);
6233 
6234  for(size_t i = 0; i < data_len; i++)
6235  {
6236  CHECK(object.asExt().data[i] == '_');
6237  }
6238  }
6239 
6240  SUBCASE("length=max")
6241  {
6242  const size_t data_len = std::numeric_limits<uint8_t>::max();
6243  ext.data = std::vector<uint8_t>(data_len, '_');
6244 
6245  data = serialize(ext);
6246  CHECK(data.size() == 258);
6247  size_t index = 0;
6248  CHECK(data[index++] == (uint8_t)Format::Ext8);
6249  CHECK(data[index++] == data_len);
6250  CHECK(data[index++] == type);
6251 
6252  Object object = deserialize(data);
6253  CHECK(object.isExt() == true);
6254 
6255  CHECK(object.asExt().type == type);
6256  CHECK(object.asExt().data.size() == data_len);
6257 
6258  for(size_t i = 0; i < data_len; i++)
6259  {
6260  CHECK(object.asExt().data[i] == '_');
6261  }
6262  }
6263 }
6264 
6265 TEST_CASE("serialize/ext (ext16)")
6266 {
6267  std::vector<uint8_t> data;
6268  const int8_t type = 42;
6269 
6270  Ext ext;
6271  ext.type = type;
6272 
6273  SUBCASE("length=min")
6274  {
6275  const size_t data_len = std::numeric_limits<uint8_t>::max() + (size_t)1;
6276  ext.data = std::vector<uint8_t>(data_len, '_');
6277 
6278  data = serialize(ext);
6279  CHECK(data.size() == (data_len + 4));
6280  size_t index = 0;
6281  CHECK(data[index++] == (uint8_t)Format::Ext16);
6282  Convert.uint64 = 0;
6283  Convert_Byte1 = data[index++];
6284  Convert_Byte0 = data[index++];
6285  CHECK(Convert.uint16 == data_len);
6286  CHECK(data[index++] == type);
6287 
6288  Object object = deserialize(data);
6289  CHECK(object.isExt() == true);
6290 
6291  CHECK(object.asExt().type == type);
6292  CHECK(object.asExt().data.size() == data_len);
6293 
6294  for(size_t i = 0; i < data_len; i++)
6295  {
6296  CHECK(object.asExt().data[i] == '_');
6297  }
6298  }
6299 
6300  SUBCASE("length=max")
6301  {
6302  const size_t data_len = std::numeric_limits<uint16_t>::max();
6303  ext.data = std::vector<uint8_t>(data_len, '_');
6304 
6305  data = serialize(ext);
6306  CHECK(data.size() == (data_len + 4));
6307  size_t index = 0;
6308  CHECK(data[index++] == (uint8_t)Format::Ext16);
6309  Convert.uint64 = 0;
6310  Convert_Byte1 = data[index++];
6311  Convert_Byte0 = data[index++];
6312  CHECK(Convert.uint16 == data_len);
6313  CHECK(data[index++] == type);
6314 
6315  Object object = deserialize(data);
6316  CHECK(object.isExt() == true);
6317 
6318  CHECK(object.asExt().type == type);
6319  CHECK(object.asExt().data.size() == data_len);
6320 
6321  for(size_t i = 0; i < data_len; i++)
6322  {
6323  CHECK(object.asExt().data[i] == '_');
6324  }
6325  }
6326 }
6327 
6328 TEST_CASE("serialize/ext (ext32)")
6329 {
6330  std::vector<uint8_t> data;
6331  const int8_t type = 42;
6332 
6333  Ext ext;
6334  ext.type = type;
6335 
6336  SUBCASE("length=min")
6337  {
6338  const size_t data_len = std::numeric_limits<uint16_t>::max() + (size_t)1;
6339  ext.data = std::vector<uint8_t>(data_len, '_');
6340 
6341  data = serialize(ext);
6342  CHECK(data.size() == (data_len + 6));
6343  size_t index = 0;
6344  CHECK(data[index++] == (uint8_t)Format::Ext32);
6345  Convert.uint64 = 0;
6346  Convert_Byte3 = data[index++];
6347  Convert_Byte2 = data[index++];
6348  Convert_Byte1 = data[index++];
6349  Convert_Byte0 = data[index++];
6350  CHECK(Convert.uint32 == data_len);
6351  CHECK(data[index++] == type);
6352 
6353  Object object = deserialize(data);
6354  CHECK(object.isExt() == true);
6355 
6356  CHECK(object.asExt().type == type);
6357  CHECK(object.asExt().data.size() == data_len);
6358 
6359  for(size_t i = 0; i < data_len; i++)
6360  {
6361  CHECK(object.asExt().data[i] == '_');
6362  }
6363  }
6364 
6365 #if 0 // Uses too much RAM and takes too long.
6366  SUBCASE("length=max")
6367  {
6368  const size_t data_len = std::numeric_limits<uint32_t>::max();
6369  ext.data = std::vector<uint8_t>(data_len, '_');
6370 
6371  data = serialize(ext);
6372  CHECK(data.size() == (data_len + 6));
6373  size_t index = 0;
6374  CHECK(data[index++] == (uint8_t)Format::Ext32);
6375  Convert.uint64 = 0;
6376  Convert_Byte3 = data[index++];
6377  Convert_Byte2 = data[index++];
6378  Convert_Byte1 = data[index++];
6379  Convert_Byte0 = data[index++];
6380  CHECK(Convert.uint32 == data_len);
6381  CHECK(data[index++] == type);
6382 
6383  Object object = deserialize(data);
6384  CHECK(object.isExt() == true);
6385 
6386  CHECK(object.asExt().type == type);
6387  CHECK(object.asExt().data.size() == data_len);
6388 
6389  for(size_t i = 0; i < data_len; i++)
6390  {
6391  CHECK(object.asExt().data[i] == '_');
6392  }
6393  }
6394 #endif
6395 }
6396 #endif // }}}
6397 
6398 
6415 std::vector<uint8_t> serialize(const Map& map
6416  ) noexcept
6417 {
6418  std::error_code error;
6419 
6420  return serialize(map, error);
6421 }
6422 
6423 
6441 std::vector<uint8_t> serialize(const Map& map
6442  , std::error_code& error
6443  ) noexcept
6444 {
6445  std::vector<uint8_t> vector;
6446 
6447  error = serialize_(map, vector);
6448 
6449  return vector;
6450 }
6451 
6452 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
6453 TEST_CASE("serialize/map (fixed_map)")
6454 {
6455  Map map;
6456  std::vector<uint8_t> data;
6457 
6458  SUBCASE("empty")
6459  {
6460  data = serialize(map);
6461  CHECK(data.size() == 1);
6462  CHECK((data[0] & Fixed_Map_Mask) == (uint8_t)Format::Fixed_Map);
6463  CHECK((data[0] & Fixed_Map_Value) == 0);
6464 
6465  Object object = deserialize(data);
6466  CHECK(object.isMap() == true);
6467  CHECK(object.asMap().size() == 0);
6468  }
6469 
6470  SUBCASE("max")
6471  {
6472  size_t max = 15;
6473 
6474  for(size_t i = 0; i < max; i++)
6475  {
6476  // i ==> 1 byte
6477  // str(0-9) ==> 2 bytes
6478  // str(10-14) ==> 3 bytes
6479  map.set(Object{int64_t(i)}, Object{std::to_string(i)});
6480  }
6481 
6482  data = serialize(map);
6483  CHECK(data.size() == 51);
6484  CHECK((data[0] & Fixed_Map_Mask) == (uint8_t)Format::Fixed_Map);
6485  CHECK((data[0] & Fixed_Map_Value) == max);
6486 
6487  Object object = deserialize(data);
6488  CHECK(object.isMap() == true);
6489  CHECK(object.asMap().size() == max);
6490 
6491  for(size_t i = 0; i < max; i++)
6492  {
6493  Object key = Object{int64_t(i)};
6494  CHECK(map.keyExists(key) == true);
6495 
6496  Object value = map.at(key);
6497  CHECK(value.asString() == std::to_string(i));
6498  }
6499  }
6500 }
6501 
6502 
6503 TEST_CASE("serialize/map (map16)")
6504 {
6505  Map map;
6506  std::vector<uint8_t> data;
6507 
6508  SUBCASE("min")
6509  {
6510  const size_t min = 16;
6511 
6512  for(size_t i = 0; i < min; i++)
6513  {
6514  map.set(Object{int64_t(i)}, Object{std::to_string(i)});
6515  }
6516 
6517  data = serialize(map);
6518  CHECK(data.size() == 57);
6519  CHECK(data[0] == (uint8_t)Format::Map16);
6520  Convert.uint64 = 0;
6521  Convert_Byte1 = data[1];
6522  Convert_Byte0 = data[2];
6523  CHECK(Convert.uint16 == min);
6524 
6525  Object object = deserialize(data);
6526  CHECK(object.isMap() == true);
6527  CHECK(object.asMap().size() == min);
6528 
6529  for(size_t i = 0; i < min; i++)
6530  {
6531  Object key = Object{int64_t(i)};
6532  CHECK(map.keyExists(key) == true);
6533 
6534  Object value = map.at(key);
6535  CHECK(value.asString() == std::to_string(i));
6536  }
6537  }
6538 
6539  SUBCASE("max")
6540  {
6541  const size_t max = std::numeric_limits<uint16_t>::max();
6542 
6543  //printf("Generating %lu Map entries\n", max);
6544  for(size_t i = 0; i < max; i++)
6545  {
6546  Object key = {int64_t(i)};
6547  Object val = {std::to_string(i)};
6548  map.set(std::move(key), std::move(val));
6549 
6550  //if(i % 1000 == 0) { printf("%lu/%lu\n", i, max); }
6551  }
6552 
6553  data = serialize(map);
6554  CHECK(data.size() == 643986);
6555  CHECK(data[0] == (uint8_t)Format::Map16);
6556  Convert.uint64 = 0;
6557  Convert_Byte1 = data[1];
6558  Convert_Byte0 = data[2];
6559  CHECK(Convert.uint16 == max);
6560 
6561  Object object = deserialize(data);
6562  CHECK(object.isMap() == true);
6563  CHECK(object.asMap().size() == max);
6564 
6565  for(size_t i = 0; i < max; i++)
6566  {
6567  Object key = Object{int64_t(i)};
6568  CHECK(map.keyExists(key) == true);
6569 
6570  Object value = map.at(key);
6571  CHECK(value.asString() == std::to_string(i));
6572  }
6573  }
6574 }
6575 
6576 
6577 TEST_CASE("serialize/map (map32)")
6578 {
6579  Map map;
6580  std::vector<uint8_t> data;
6581 
6582  SUBCASE("min")
6583  {
6584  const size_t min = std::numeric_limits<uint16_t>::max() + 1;
6585 
6586  //printf("Generating %lu Map entries\n", min);
6587  for(size_t i = 0; i < min; i++)
6588  {
6589  Object key = {int64_t(i)};
6590  Object val = {std::to_string(i)};
6591  map.set(std::move(key), std::move(val));
6592 
6593  //if(i % 1000 == 0) { printf("%lu/%lu\n", i, min); }
6594  }
6595 
6596  data = serialize(map);
6597  CHECK(data.size() == 643999);
6598  CHECK(data[0] == (uint8_t)Format::Map32);
6599  Convert.uint64 = 0;
6600  Convert_Byte3 = data[1];
6601  Convert_Byte2 = data[2];
6602  Convert_Byte1 = data[3];
6603  Convert_Byte0 = data[4];
6604  CHECK(Convert.uint32 == min);
6605 
6606  Object object = deserialize(data);
6607  CHECK(object.isMap() == true);
6608  CHECK(object.asMap().size() == min);
6609 
6610  for(size_t i = 0; i < min; i++)
6611  {
6612  Object key = Object{int64_t(i)};
6613  CHECK(map.keyExists(key) == true);
6614 
6615  Object value = map.at(key);
6616  CHECK(value.asString() == std::to_string(i));
6617  }
6618  }
6619 
6620 #if 0 // Will use too much memory and take to long
6621  SUBCASE("max")
6622  {
6623  const size_t max = std::numeric_limits<uint32_t>::max();
6624  map.object_key.reserve(max);
6625  map.object_value.reserve(max);
6626 
6627  printf("Generating %lu Map entries\n", max);
6628  for(size_t i = 0; i < max; i++)
6629  {
6630  Object key = {int64_t(i)};
6631  Object val = {std::to_string(i)};
6632  map.set(std::move(key), std::move(val));
6633 
6634  if(i % 1000 == 0) { printf("%lu/%lu\n", i, max); }
6635  }
6636 
6637  data = serialize(map);
6638  CHECK(data.size() == 0); // Unknown
6639  CHECK(data[0] == (uint8_t)Format::Map32);
6640  Convert.uint64 = 0;
6641  Convert_Byte3 = data[1];
6642  Convert_Byte2 = data[2];
6643  Convert_Byte1 = data[3];
6644  Convert_Byte0 = data[4];
6645  CHECK(Convert.uint32 == max);
6646 
6647  Object object = deserialize(data);
6648  CHECK(object.isMap() == true);
6649  CHECK(object.asMap().size() == max);
6650 
6651  for(size_t i = 0; i < max; i++)
6652  {
6653  Object key = Object{int64_t(i)};
6654  CHECK(map.keyExists(key) == true);
6655 
6656  Object value = map.at(key);
6657  CHECK(value.asString() == std::to_string(i));
6658  }
6659  }
6660 #endif
6661 }
6662 #endif // }}}
6663 
6664 
6680 std::vector<uint8_t> serialize(const Object& object
6681  ) noexcept
6682 {
6683  std::error_code error;
6684 
6685  return serialize(object, error);
6686 }
6687 
6688 
6705 std::vector<uint8_t> serialize(const Object& object
6706  , std::error_code& error
6707  ) noexcept
6708 {
6709  std::vector<uint8_t> vector;
6710 
6711  error = serialize_(object, vector);
6712 
6713  return vector;
6714 }
6715 
6716 
6717 #ifdef ZAKERO_MESSAGEPACK_IMPLEMENTATION_TEST // {{{
6718 
6719 TEST_CASE("serialize/object/nill")
6720 {
6721  Object object = {};
6722  CHECK(object.isNull());
6723 
6724  // Check serialized data
6725 
6726  std::vector<uint8_t> data = serialize(object);
6727  CHECK(data.size() == 1);
6728 
6729  // Check deserialized data
6730 
6731  size_t index = 0;
6732  CHECK(data[index] == (uint8_t)Format::Nill);
6733 
6734  object = deserialize(data);
6735  CHECK(object.isNull());
6736 }
6737 
6738 
6739 TEST_CASE("serialize/object/bool")
6740 {
6741  Object object;
6742  std::vector<uint8_t> data;
6743  size_t index = 0;
6744 
6745  SUBCASE("True")
6746  {
6747  object = {true};
6748  CHECK(object.is<bool>());
6749 
6750  // Check serialized data
6751 
6752  data = serialize(object);
6753  CHECK(data.size() == 1);
6754 
6755  index = 0;
6756  CHECK(data[index] == (uint8_t)Format::True);
6757 
6758  // Check deserialized data
6759 
6760  object = deserialize(data);
6761  CHECK(object.is<bool>());
6762  CHECK(object.as<bool>() == true);
6763  }
6764 
6765  SUBCASE("False")
6766  {
6767  object = {false};
6768  CHECK(object.is<bool>());
6769 
6770  // Check serialized data
6771 
6772  data = serialize(object);
6773  CHECK(data.size() == 1);
6774  index = 0;
6775  CHECK(data[index] == (uint8_t)Format::False);
6776 
6777  // Check deserialized data
6778 
6779  object = deserialize(data);
6780  CHECK(object.is<bool>());
6781  CHECK(object.as<bool>() == false);
6782  }
6783 }
6784 
6785 
6786 TEST_CASE("serialize/object/fixed_int")
6787 {
6788  Object object;
6789  std::vector<uint8_t> data;
6790  size_t index;
6791 
6792  // -------------------------------------------------------------------
6793 
6794  SUBCASE("Zero")
6795  {
6796  const int64_t fixint_zero = 0;
6797 
6798  object = {fixint_zero};
6799  CHECK(object.is<int64_t>());
6800 
6801  // Check serialized data
6802 
6803  data = serialize(object);
6804  CHECK(data.size() == 1);
6805 
6806  index = 0;
6807  CHECK((data[index] & Fixed_Int_Pos_Mask) == (uint8_t)Format::Fixed_Int_Pos);
6808  CHECK((data[index] & Fixed_Int_Pos_Value) == fixint_zero);
6809 
6810  // Check deserialized data
6811 
6812  object = deserialize(data);
6813  CHECK(object.is<int64_t>());
6814  CHECK(object.as<int64_t>() == fixint_zero);
6815  }
6816 
6817  // -------------------------------------------------------------------
6818 
6819  SUBCASE("Max")
6820  {
6821  const int64_t fixint_max = 127;
6822 
6823  object = {fixint_max};
6824  CHECK(object.is<int64_t>());
6825 
6826  // Check serialized data
6827 
6828  data = serialize(object);
6829  CHECK(data.size() == 1);
6830 
6831  index = 0;
6832  CHECK((data[index] & Fixed_Int_Pos_Mask) == (uint8_t)Format::Fixed_Int_Pos);
6833  CHECK((data[index] & Fixed_Int_Pos_Value) == fixint_max);
6834 
6835  // Check deserialized data
6836 
6837  object = deserialize(data);
6838  CHECK(object.is<int64_t>());
6839  CHECK(object.as<int64_t>() == fixint_max);
6840  }
6841 
6842  // -------------------------------------------------------------------
6843 
6844  SUBCASE("Min")
6845  {
6846  const int64_t fixint_min = -32;
6847 
6848  object = {fixint_min};
6849  CHECK(object.is<int64_t>());
6850 
6851  // Check serialized data
6852 
6853  data = serialize(object);
6854  CHECK(data.size() == 1);
6855 
6856  index = 0;
6857  CHECK((data[index] & Fixed_Int_Neg_Mask) == (uint8_t)Format::Fixed_Int_Neg);
6858  CHECK(((data[index] & Fixed_Int_Neg_Value) - 32) == fixint_min);
6859 
6860  // Check deserialized data
6861 
6862  object = deserialize(data);
6863  CHECK(object.is<int64_t>());
6864  CHECK(object.as<int64_t>() == fixint_min);
6865  }
6866 
6867  // -------------------------------------------------------------------
6868 
6869  SUBCASE("Value: 24")
6870  {
6871  const int64_t fixint_p24 = 24;
6872 
6873  object = {fixint_p24};
6874  CHECK(object.is<int64_t>());
6875 
6876  // Check serialized data
6877 
6878  data = serialize(object);
6879  CHECK(data.size() == 1);
6880 
6881  index = 0;
6882  CHECK((data[index] & Fixed_Int_Pos_Mask) == (uint8_t)Format::Fixed_Int_Pos);
6883  CHECK((data[index] & Fixed_Int_Pos_Value) == fixint_p24);
6884 
6885  // Check deserialized data
6886 
6887  object = deserialize(data);
6888  CHECK(object.is<int64_t>());
6889  CHECK(object.as<int64_t>() == fixint_p24);
6890  }
6891 
6892  // -------------------------------------------------------------------
6893 
6894  SUBCASE("Value: -24")
6895  {
6896  const int64_t fixint_n24 = -24;
6897 
6898  object = {fixint_n24};
6899  CHECK(object.is<int64_t>());
6900 
6901  // Check serialized data
6902 
6903  data = serialize(object);
6904  CHECK(data.size() == 1);
6905 
6906  index = 0;
6907  CHECK((data[index] & Fixed_Int_Neg_Mask) == (uint8_t)Format::Fixed_Int_Neg);
6908  CHECK(((data[index] & Fixed_Int_Neg_Value) - 32) == fixint_n24);
6909 
6910  // Check deserialized data
6911 
6912  object = deserialize(data);
6913  CHECK(object.is<int64_t>());
6914  CHECK(object.as<int64_t>() == fixint_n24);
6915  }
6916 }
6917 
6918 
6919 TEST_CASE("serialize/object/int8")
6920 {
6921  Object object;
6922  std::vector<uint8_t> data;
6923  size_t index;
6924 
6925  // Don't test the maximum Int8 value 127
6926  // because that is handled by Fixed_Int_Pos
6927 
6928  // -------------------------------------------------------------------
6929 
6930  SUBCASE("Min")
6931  {
6932  const int64_t i8_min = std::numeric_limits<int8_t>::min();
6933 
6934  object = {i8_min};
6935  CHECK(object.is<int64_t>());
6936 
6937  // Check serialized data
6938 
6939  data = serialize(object);
6940  CHECK(data.size() == 2);
6941 
6942  index = 0;
6943  CHECK(data[index] == (uint8_t)Format::Int8);
6944  index++;
6945  CHECK((int8_t)data[index] == i8_min);
6946 
6947  // Check deserialized data
6948 
6949  object = deserialize(data);
6950  CHECK(object.is<int64_t>());
6951  CHECK(object.as<int64_t>() == i8_min);
6952  }
6953 
6954  // -------------------------------------------------------------------
6955 
6956  SUBCASE("Value: -33")
6957  {
6958  const int64_t i8_min = -33;
6959 
6960  object = {i8_min};
6961  CHECK(object.is<int64_t>());
6962 
6963  // Check serialized data
6964 
6965  data = serialize(object);
6966  CHECK(data.size() == 2);
6967 
6968  index = 0;
6969  CHECK(data[index] == (uint8_t)Format::Int8);
6970  index++;
6971  CHECK((int8_t)data[index] == i8_min);
6972 
6973  // Check deserialized data
6974 
6975  object = deserialize(data);
6976  CHECK(object.is<int64_t>());
6977  CHECK(object.as<int64_t>() == i8_min);
6978  }
6979 }
6980 
6981 
6982 TEST_CASE("serialize/object/int16")
6983 {
6984  Object object;
6985  std::vector<uint8_t> data;
6986  size_t index;
6987 
6988  // -------------------------------------------------------------------
6989 
6990  SUBCASE("Min16")
6991  {
6992  const int64_t i16_min = std::numeric_limits<int16_t>::min();
6993 
6994  object = {i16_min};
6995  CHECK(object.is<int64_t>());
6996 
6997  // Check serialized data
6998 
6999  data = serialize(object);
7000  CHECK(data.size() == 3);
7001 
7002  index = 0;
7003  CHECK(data[index++] == (uint8_t)Format::Int16);
7004 
7005  Convert.uint64 = 0;
7006  Convert_Byte1 = data[index++];
7007  Convert_Byte0 = data[index++];
7008  CHECK(Convert.int16 == i16_min);
7009 
7010  // Check deserialized data
7011 
7012  object = deserialize(data);
7013  CHECK(object.is<int64_t>());
7014  CHECK(object.as<int64_t>() == i16_min);
7015  }
7016 
7017  // -------------------------------------------------------------------
7018 
7019  SUBCASE("Min8-1")
7020  {
7021  const int64_t i16_min = std::numeric_limits<int8_t>::min() - (int64_t)1;
7022 
7023  object = {i16_min};
7024  CHECK(object.is<int64_t>());
7025 
7026  // Check serialized data
7027 
7028  data = serialize(object);
7029  CHECK(data.size() == 3);
7030 
7031  index = 0;
7032  CHECK(data[index++] == (uint8_t)Format::Int16);
7033 
7034  Convert.uint64 = 0;
7035  Convert_Byte1 = data[index++];
7036  Convert_Byte0 = data[index++];
7037  CHECK(Convert.int16 == i16_min);
7038 
7039  // Check deserialized data
7040 
7041  object = deserialize(data);
7042  CHECK(object.is<int64_t>());
7043  CHECK(object.as<int64_t>() == i16_min);
7044  }
7045 
7046  // -------------------------------------------------------------------
7047 
7048  SUBCASE("Max16")
7049  {
7050  const int64_t i16_max = std::numeric_limits<int16_t>::max();
7051 
7052  object = {i16_max};
7053  CHECK(object.is<int64_t>());
7054 
7055  // Check serialized data
7056 
7057  data = serialize(object);
7058  CHECK(data.size() == 3);
7059 
7060  index = 0;
7061  CHECK(data[index++] == (uint8_t)Format::Int16);
7062 
7063  Convert.uint64 = 0;
7064  Convert_Byte1 = data[index++];
7065  Convert_Byte0 = data[index++];
7066  CHECK(Convert.int16 == i16_max);
7067 
7068  // Check deserialized data
7069 
7070  object = deserialize(data);
7071  CHECK(object.is<int64_t>());
7072  CHECK(object.as<int64_t>() == i16_max);
7073  }
7074 
7075  // -------------------------------------------------------------------
7076 
7077  SUBCASE("Max8+1")
7078  {
7079  const int64_t i16_max = std::numeric_limits<int16_t>::max();
7080 
7081  object = {i16_max};
7082  CHECK(object.is<int64_t>());
7083 
7084  // Check serialized data
7085 
7086  data = serialize(object);
7087  CHECK(data.size() == 3);
7088 
7089  index = 0;
7090  CHECK(data[index++] == (uint8_t)Format::Int16);
7091 
7092  Convert.uint64 = 0;
7093  Convert_Byte1 = data[index++];
7094  Convert_Byte0 = data[index++];
7095  CHECK(Convert.int16 == i16_max);
7096 
7097  // Check deserialized data
7098 
7099  object = deserialize(data);
7100  CHECK(object.is<int64_t>());
7101  CHECK(object.as<int64_t>() == i16_max);
7102  }
7103 }
7104 
7105 
7106 TEST_CASE("serialize/object/int32")
7107 {
7108  Object object;
7109  std::vector<uint8_t> data;
7110  size_t index;
7111 
7112  // -------------------------------------------------------------------
7113 
7114  SUBCASE("Min32")
7115  {
7116  const int64_t i32_min = std::numeric_limits<int32_t>::min();
7117 
7118  object = {i32_min};
7119  CHECK(object.is<int64_t>());
7120 
7121  // Check serialized data
7122 
7123  data = serialize(object);
7124  CHECK(data.size() == 5);
7125 
7126  index = 0;
7127  CHECK(data[index++] == (uint8_t)Format::Int32);
7128 
7129  Convert.uint64 = 0;
7130  Convert_Byte3 = data[index++];
7131  Convert_Byte2 = data[index++];
7132  Convert_Byte1 = data[index++];
7133  Convert_Byte0 = data[index++];
7134  CHECK(Convert.int32 == i32_min);
7135 
7136  // Check deserialized data
7137 
7138  object = deserialize(data);
7139  CHECK(object.is<int64_t>());
7140  CHECK(object.as<int64_t>() == i32_min);
7141  }
7142 
7143  // -------------------------------------------------------------------
7144 
7145  SUBCASE("Min16-1")
7146  {
7147  const int64_t i32_min = std::numeric_limits<int16_t>::min() - (int64_t)1;
7148 
7149  object = {i32_min};
7150  CHECK(object.is<int64_t>());
7151 
7152  // Check serialized data
7153 
7154  data = serialize(object);
7155  CHECK(data.size() == 5);
7156 
7157  index = 0;
7158  CHECK(data[index++] == (uint8_t)Format::Int32);
7159 
7160  Convert.uint64 = 0;
7161  Convert_Byte3 = data[index++];
7162  Convert_Byte2 = data[index++];
7163  Convert_Byte1 = data[index++];
7164  Convert_Byte0 = data[index++];
7165  CHECK(Convert.int32 == i32_min);
7166 
7167  // Check deserialized data
7168 
7169  object = deserialize(data);
7170  CHECK(object.is<int64_t>());
7171  CHECK(object.as<int64_t>() == i32_min);
7172  }
7173 
7174  // -------------------------------------------------------------------
7175 
7176  SUBCASE("Max32")
7177  {
7178  const int64_t i32_max = std::numeric_limits<int32_t>::max();
7179 
7180  object = {i32_max};
7181  CHECK(object.is<int64_t>());
7182 
7183  // Check serialized data
7184 
7185  data = serialize(object);
7186  CHECK(data.size() == 5);
7187 
7188  index = 0;
7189  CHECK(data[index++] == (uint8_t)Format::Int32);
7190 
7191  Convert.uint64 = 0;
7192  Convert_Byte3 = data[index++];
7193  Convert_Byte2 = data[index++];
7194  Convert_Byte1 = data[index++];
7195  Convert_Byte0 = data[index++];
7196  CHECK(Convert.int32 == i32_max);
7197 
7198  // Check deserialized data
7199 
7200  object = deserialize(data);
7201  CHECK(object.is<int64_t>());
7202  CHECK(object.as<int64_t>() == i32_max);
7203  }
7204 
7205  // -------------------------------------------------------------------
7206 
7207  SUBCASE("Max16+1")
7208  {
7209  const int64_t i32_max = std::numeric_limits<int16_t>::max() + 1;
7210 
7211  object = {i32_max};
7212  CHECK(object.is<int64_t>());
7213 
7214  // Check serialized data
7215 
7216  data = serialize(object);
7217  CHECK(data.size() == 5);
7218 
7219  index = 0;
7220  CHECK(data[index++] == (uint8_t)Format::Int32);
7221 
7222  Convert.uint64 = 0;
7223  Convert_Byte3 = data[index++];
7224  Convert_Byte2 = data[index++];
7225  Convert_Byte1 = data[index++];
7226  Convert_Byte0 = data[index++];
7227  CHECK(Convert.int32 == i32_max);
7228 
7229  // Check deserialized data
7230 
7231  object = deserialize(data);
7232  CHECK(object.is<int64_t>());
7233  CHECK(object.as<int64_t>() == i32_max);
7234  }
7235 }
7236 
7237 
7238 TEST_CASE("serialize/object/int64")
7239 {
7240  Object object;
7241  std::vector<uint8_t> data;
7242  size_t index;
7243 
7244  // -------------------------------------------------------------------
7245 
7246  SUBCASE("Min64")
7247  {
7248  const int64_t i64_min = std::numeric_limits<int64_t>::min();
7249 
7250  object = {i64_min};
7251  CHECK(object.is<int64_t>());
7252 
7253  // Check serialized data
7254 
7255  data = serialize(object);
7256  CHECK(data.size() == 9);
7257 
7258  index = 0;
7259  CHECK(data[index++] == (uint8_t)Format::Int64);
7260 
7261  Convert.uint64 = 0;
7262  Convert_Byte7 = data[index++];
7263  Convert_Byte6 = data[index++];
7264  Convert_Byte5 = data[index++];
7265  Convert_Byte4 = data[index++];
7266  Convert_Byte3 = data[index++];
7267  Convert_Byte2 = data[index++];
7268  Convert_Byte1 = data[index++];
7269  Convert_Byte0 = data[index++];
7270  CHECK(Convert.int64 == i64_min);
7271 
7272  // Check deserialized data
7273 
7274  object = deserialize(data);
7275  CHECK(object.is<int64_t>());
7276  CHECK(object.as<int64_t>() == i64_min);
7277  }
7278 
7279  // -------------------------------------------------------------------
7280 
7281  SUBCASE("Min32-1")
7282  {
7283  const int64_t i64_min = std::numeric_limits<int32_t>::min() - (int64_t)1;
7284 
7285  object = {i64_min};
7286  CHECK(object.is<int64_t>());
7287 
7288  // Check serialized data
7289 
7290  data = serialize(object);
7291  CHECK(data.size() == 9);
7292 
7293  index = 0;
7294  CHECK(data[index++] == (uint8_t)Format::Int64);
7295 
7296  Convert.uint64 = 0;
7297  Convert_Byte7 = data[index++];
7298  Convert_Byte6 = data[index++];
7299  Convert_Byte5 = data[index++];
7300  Convert_Byte4 = data[index++];
7301  Convert_Byte3 = data[index++];
7302  Convert_Byte2 = data[index++];
7303  Convert_Byte1 = data[index++];
7304  Convert_Byte0 = data[index++];
7305  CHECK(Convert.int64 == i64_min);
7306 
7307  // Check deserialized data
7308 
7309  object = deserialize(data);
7310  CHECK(object.is<int64_t>());
7311  CHECK(object.as<int64_t>() == i64_min);
7312  }
7313 
7314  // -------------------------------------------------------------------
7315 
7316  SUBCASE("Max64")
7317  {
7318  const int64_t i64_max = std::numeric_limits<int64_t>::max();
7319 
7320  object = {i64_max};
7321  CHECK(object.is<int64_t>());
7322 
7323  // Check serialized data
7324 
7325  data = serialize(object);
7326  CHECK(data.size() == 9);
7327 
7328  index = 0;
7329  CHECK(data[index++] == (uint8_t)Format::Int64);
7330 
7331  Convert.uint64 = 0;
7332  Convert_Byte7 = data[index++];
7333  Convert_Byte6 = data[index++];
7334  Convert_Byte5 = data[index++];
7335  Convert_Byte4 = data[index++];
7336  Convert_Byte3 = data[index++];
7337  Convert_Byte2 = data[index++];
7338  Convert_Byte1 = data[index++];
7339  Convert_Byte0 = data[index++];
7340  CHECK(Convert.int64 == i64_max);
7341 
7342  // Check deserialized data
7343 
7344  object = deserialize(data);
7345  CHECK(object.is<int64_t>());
7346  CHECK(object.as<int64_t>() == i64_max);
7347  }
7348 
7349  // -------------------------------------------------------------------
7350 
7351  SUBCASE("Max32+1")
7352  {
7353  const int64_t i64_max = std::numeric_limits<int32_t>::max() + (int64_t)1;
7354 
7355  object = {i64_max};
7356  CHECK(object.is<int64_t>());
7357 
7358  // Check serialized data
7359 
7360  data = serialize(object);
7361  CHECK(data.size() == 9);
7362 
7363  index = 0;
7364  CHECK(data[index++] == (uint8_t)Format::Int64);
7365 
7366  Convert.uint64 = 0;
7367  Convert_Byte7 = data[index++];
7368  Convert_Byte6 = data[index++];
7369  Convert_Byte5 = data[index++];
7370  Convert_Byte4 = data[index++];
7371  Convert_Byte3 = data[index++];
7372  Convert_Byte2 = data[index++];
7373  Convert_Byte1 = data[index++];
7374  Convert_Byte0 = data[index++];
7375  CHECK(Convert.int64 == i64_max);
7376 
7377  // Check deserialized data
7378 
7379  object = deserialize(data);
7380  CHECK(object.is<int64_t>());
7381  CHECK(object.as<int64_t>() == i64_max);
7382  }
7383 }
7384 
7385 
7386 TEST_CASE("serialize/object/uint8")
7387 {
7388  Object object;
7389  std::vector<uint8_t> data;
7390  size_t index;
7391 
7392  // -------------------------------------------------------------------
7393 
7394  SUBCASE("Min")
7395  {
7396  const uint64_t u8_min = 0;
7397 
7398  object = {u8_min};
7399  CHECK(object.is<uint64_t>());
7400 
7401  // Check serialized data
7402 
7403  data = serialize(object);
7404  CHECK(data.size() == 2);
7405 
7406  index = 0;
7407  CHECK(data[index++] == (uint8_t)Format::Uint8);
7408  CHECK(data[index++] == u8_min);
7409 
7410  // Check deserialized data
7411 
7412  object = deserialize(data);
7413  CHECK(object.is<uint64_t>());
7414  CHECK(object.as<uint64_t>() == u8_min);
7415  }
7416 
7417  // -------------------------------------------------------------------
7418 
7419  SUBCASE("Max")
7420  {
7421  const uint64_t u8_max = std::numeric_limits<uint8_t>::max();
7422 
7423  object = {u8_max};
7424  CHECK(object.is<uint64_t>());
7425 
7426  // Check serialized data
7427 
7428  data = serialize(object);
7429  CHECK(data.size() == 2);
7430 
7431  index = 0;
7432  CHECK(data[index++] == (uint8_t)Format::Uint8);
7433  CHECK(data[index++] == u8_max);
7434 
7435  // Check deserialized data
7436 
7437  object = deserialize(data);
7438  CHECK(object.is<uint64_t>());
7439  CHECK(object.as<uint64_t>() == u8_max);
7440  }
7441 }
7442 
7443 
7444 TEST_CASE("serialize/object/uint16")
7445 {
7446  Object object;
7447  std::vector<uint8_t> data;
7448  size_t index;
7449 
7450  // -------------------------------------------------------------------
7451 
7452  SUBCASE("Min")
7453  {
7454  const uint64_t u16_min = std::numeric_limits<uint8_t>::max() + (uint64_t)1;
7455 
7456  object = {u16_min};
7457  CHECK(object.is<uint64_t>());
7458 
7459  // Check serialized data
7460 
7461  data = serialize(object);
7462  CHECK(data.size() == 3);
7463 
7464  index = 0;
7465  CHECK(data[index++] == (uint8_t)Format::Uint16);
7466  Convert_Byte1 = data[index++];
7467  Convert_Byte0 = data[index++];
7468  CHECK(Convert.uint16 == u16_min);
7469 
7470  // Check deserialized data
7471 
7472  object = deserialize(data);
7473  CHECK(object.is<uint64_t>());
7474  CHECK(object.as<uint64_t>() == u16_min);
7475  }
7476 
7477  // -------------------------------------------------------------------
7478 
7479  SUBCASE("Max")
7480  {
7481  const uint64_t u16_max = std::numeric_limits<uint16_t>::max();
7482 
7483  object = {u16_max};
7484  CHECK(object.is<uint64_t>());
7485 
7486  // Check serialized data
7487 
7488  data = serialize(object);
7489  CHECK(data.size() == 3);
7490 
7491  index = 0;
7492  CHECK(data[index++] == (uint8_t)Format::Uint16);
7493  Convert_Byte1 = data[index++];
7494  Convert_Byte0 = data[index++];
7495  CHECK(Convert.uint16 == u16_max);
7496 
7497  // Check deserialized data
7498 
7499  object = deserialize(data);
7500  CHECK(object.is<uint64_t>());
7501  CHECK(object.as<uint64_t>() == u16_max);
7502  }
7503 }
7504 
7505 
7506 TEST_CASE("serialize/object/uint32")
7507 {
7508  Object object;
7509  std::vector<uint8_t> data;
7510  size_t index;
7511 
7512  // -------------------------------------------------------------------
7513 
7514  SUBCASE("Min")
7515  {
7516  const uint64_t u32_min = std::numeric_limits<uint16_t>::max() + (uint64_t)1;
7517 
7518  object = {u32_min};
7519  CHECK(object.is<uint64_t>());
7520 
7521  // Check serialized data
7522 
7523  data = serialize(object);
7524  CHECK(data.size() == 5);
7525 
7526  index = 0;
7527  CHECK(data[index++] == (uint8_t)Format::Uint32);
7528  Convert_Byte3 = data[index++];
7529  Convert_Byte2 = data[index++];
7530  Convert_Byte1 = data[index++];
7531  Convert_Byte0 = data[index++];
7532  CHECK(Convert.uint32 == u32_min);
7533 
7534  // Check deserialized data
7535 
7536  object = deserialize(data);
7537  CHECK(object.is<uint64_t>());
7538  CHECK(object.as<uint64_t>() == u32_min);
7539  }
7540 
7541  // -------------------------------------------------------------------
7542 
7543  SUBCASE("Max")
7544  {
7545  const uint64_t u32_max = std::numeric_limits<uint32_t>::max();
7546 
7547  object = {u32_max};
7548  CHECK(object.is<uint64_t>());
7549 
7550  // Check serialized data
7551 
7552  data = serialize(object);
7553  CHECK(data.size() == 5);
7554 
7555  index = 0;
7556  CHECK(data[index++] == (uint8_t)Format::Uint32);
7557  Convert_Byte3 = data[index++];
7558  Convert_Byte2 = data[index++];
7559  Convert_Byte1 = data[index++];
7560  Convert_Byte0 = data[index++];
7561  CHECK(Convert.uint32 == u32_max);
7562 
7563  // Check deserialized data
7564 
7565  object = deserialize(data);
7566  CHECK(object.is<uint64_t>());
7567  CHECK(object.as<uint64_t>() == u32_max);
7568  }
7569 }
7570 
7571 
7572 TEST_CASE("serialize/object/uint64")
7573 {
7574  Object object;
7575  std::vector<uint8_t> data;
7576  size_t index;
7577 
7578  // -------------------------------------------------------------------
7579 
7580  SUBCASE("Min")
7581  {
7582  const uint64_t u64_min = std::numeric_limits<uint32_t>::max() + (uint64_t)1;
7583 
7584  object = {u64_min};
7585  CHECK(object.is<uint64_t>());
7586 
7587  // Check serialized data
7588 
7589  data = serialize(object);
7590  CHECK(data.size() == 9);
7591 
7592  index = 0;
7593  CHECK(data[index++] == (uint8_t)Format::Uint64);
7594  Convert_Byte7 = data[index++];
7595  Convert_Byte6 = data[index++];
7596  Convert_Byte5 = data[index++];
7597  Convert_Byte4 = data[index++];
7598  Convert_Byte3 = data[index++];
7599  Convert_Byte2 = data[index++];
7600  Convert_Byte1 = data[index++];
7601  Convert_Byte0 = data[index++];
7602  CHECK(Convert.uint64 == u64_min);
7603 
7604  // Check deserialized data
7605 
7606  object = deserialize(data);
7607  CHECK(object.is<uint64_t>());
7608  CHECK(object.as<uint64_t>() == u64_min);
7609  }
7610 
7611  // -------------------------------------------------------------------
7612 
7613  SUBCASE("Max")
7614  {
7615  const uint64_t u64_max = std::numeric_limits<uint64_t>::max();
7616 
7617  object = {u64_max};
7618  CHECK(object.is<uint64_t>());
7619 
7620  // Check serialized data
7621 
7622  data = serialize(object);
7623  CHECK(data.size() == 9);
7624 
7625  index = 0;
7626  CHECK(data[index++] == (uint8_t)Format::Uint64);
7627  Convert_Byte7 = data[index++];
7628  Convert_Byte6 = data[index++];
7629  Convert_Byte5 = data[index++];
7630  Convert_Byte4 = data[index++];
7631  Convert_Byte3 = data[index++];
7632  Convert_Byte2 = data[index++];
7633  Convert_Byte1 = data[index++];
7634  Convert_Byte0 = data[index++];
7635  CHECK(Convert.uint64 == u64_max);
7636 
7637  // Check deserialized data
7638 
7639  object = deserialize(data);
7640  CHECK(object.is<uint64_t>());
7641  CHECK(object.as<uint64_t>() == u64_max);
7642  }
7643 }
7644 
7645 
7646 TEST_CASE("serialize/object/float32")
7647 {
7648  Object object;
7649  std::vector<uint8_t> data;
7650  size_t index;
7651 
7652  // -------------------------------------------------------------------
7653 
7654  SUBCASE("Zero")
7655  {
7656  const float f32_zero = 0;
7657 
7658  object = {f32_zero};
7659  CHECK(object.is<float>());
7660 
7661  // Check serialized data
7662 
7663  data = serialize(object);
7664  CHECK(data.size() == 5);
7665 
7666  index = 0;
7667  CHECK(data[index++] == (uint8_t)Format::Float32);
7668  Convert_Byte3 = data[index++];
7669  Convert_Byte2 = data[index++];
7670  Convert_Byte1 = data[index++];
7671  Convert_Byte0 = data[index++];
7672  CHECK(Convert.float32 == f32_zero);
7673 
7674  // Check deserialized data
7675 
7676  object = deserialize(data);
7677  CHECK(object.is<float>());
7678  CHECK(object.as<float>() == f32_zero);
7679  }
7680 
7681  // -------------------------------------------------------------------
7682 
7683  SUBCASE("Min")
7684  {
7685  const float f32_min = std::numeric_limits<float>::min();
7686 
7687  object = {f32_min};
7688  CHECK(object.is<float>());
7689 
7690  // Check serialized data
7691 
7692  data = serialize(object);
7693  CHECK(data.size() == 5);
7694 
7695  index = 0;
7696  CHECK(data[index++] == (uint8_t)Format::Float32);
7697  Convert_Byte3 = data[index++];
7698  Convert_Byte2 = data[index++];
7699  Convert_Byte1 = data[index++];
7700  Convert_Byte0 = data[index++];
7701  CHECK(Convert.float32 == f32_min);
7702 
7703  // Check deserialized data
7704 
7705  object = deserialize(data);
7706  CHECK(object.is<float>());
7707  CHECK(object.as<float>() == f32_min);
7708  }
7709 
7710  // -------------------------------------------------------------------
7711 
7712  SUBCASE("Max")
7713  {
7714  const float f32_max = std::numeric_limits<float>::max();
7715 
7716  object = {f32_max};
7717  CHECK(object.is<float>());
7718 
7719  // Check serialized data
7720 
7721  data = serialize(object);
7722  CHECK(data.size() == 5);
7723 
7724  index = 0;
7725  CHECK(data[index++] == (uint8_t)Format::Float32);
7726  Convert_Byte3 = data[index++];
7727  Convert_Byte2 = data[index++];
7728  Convert_Byte1 = data[index++];
7729  Convert_Byte0 = data[index++];
7730  CHECK(Convert.float32 == f32_max);
7731 
7732  // Check deserialized data
7733 
7734  object = deserialize(data);
7735  CHECK(object.is<float>());
7736  CHECK(object.as<float>() == f32_max);
7737  }
7738 }
7739 
7740 
7741 TEST_CASE("serialize/object/float64")
7742 {
7743  Object object;
7744  std::vector<uint8_t> data;
7745  size_t index;
7746 
7747  // -------------------------------------------------------------------
7748 
7749  SUBCASE("Zero")
7750  {
7751  const double f64_zero = 0;
7752 
7753  object = {f64_zero};
7754  CHECK(object.is<double>());
7755 
7756  // Check serialized data
7757 
7758  data = serialize(object);
7759  CHECK(data.size() == 9);
7760 
7761  index = 0;
7762  CHECK(data[index++] == (uint8_t)Format::Float64);
7763  Convert_Byte7 = data[index++];
7764  Convert_Byte6 = data[index++];
7765  Convert_Byte5 = data[index++];
7766  Convert_Byte4 = data[index++];
7767  Convert_Byte3 = data[index++];
7768  Convert_Byte2 = data[index++];
7769  Convert_Byte1 = data[index++];
7770  Convert_Byte0 = data[index++];
7771  CHECK(Convert.float64 == f64_zero);
7772 
7773  // Check deserialized data
7774 
7775  object = deserialize(data);
7776  CHECK(object.is<double>());
7777  CHECK(object.as<double>() == f64_zero);
7778  }
7779 
7780  // -------------------------------------------------------------------
7781 
7782  SUBCASE("Min")
7783  {
7784  const double f64_min = std::numeric_limits<double>::min();
7785 
7786  object = {f64_min};
7787  CHECK(object.is<double>());
7788 
7789  // Check serialized data
7790 
7791  data = serialize(object);
7792  CHECK(data.size() == 9);
7793 
7794  index = 0;
7795  CHECK(data[index++] == (uint8_t)Format::Float64);
7796  Convert_Byte7 = data[index++];
7797  Convert_Byte6 = data[index++];
7798  Convert_Byte5 = data[index++];
7799  Convert_Byte4 = data[index++];
7800  Convert_Byte3 = data[index++];
7801  Convert_Byte2 = data[index++];
7802  Convert_Byte1 = data[index++];
7803  Convert_Byte0 = data[index++];
7804  CHECK(Convert.float64 == f64_min);
7805 
7806  // Check deserialized data
7807 
7808  object = deserialize(data);
7809  CHECK(object.is<double>());
7810  CHECK(object.as<double>() == f64_min);
7811  }
7812 
7813  // -------------------------------------------------------------------
7814 
7815  SUBCASE("Max")
7816  {
7817  const double f64_max = std::numeric_limits<double>::max();
7818 
7819  object = {f64_max};
7820  CHECK(object.is<double>());
7821 
7822  // Check serialized data
7823 
7824  data = serialize(object);
7825  CHECK(data.size() == 9);
7826 
7827  index = 0;
7828  CHECK(data[index++] == (uint8_t)Format::Float64);
7829  Convert_Byte7 = data[index++];
7830  Convert_Byte6 = data[index++];
7831  Convert_Byte5 = data[index++];
7832  Convert_Byte4 = data[index++];
7833  Convert_Byte3 = data[index++];
7834  Convert_Byte2 = data[index++];
7835  Convert_Byte1 = data[index++];
7836  Convert_Byte0 = data[index++];
7837  CHECK(Convert.float64 == f64_max);
7838 
7839  // Check deserialized data
7840 
7841  object = deserialize(data);
7842  CHECK(object.is<double>());
7843  CHECK(object.as<double>() == f64_max);
7844  }
7845 }
7846 
7847 
7848 TEST_CASE("serialize/object/fixed_str")
7849 {
7850  Object object;
7851  std::vector<uint8_t> data;
7852  size_t index;
7853  size_t str_len;
7854 
7855  // -------------------------------------------------------------------
7856 
7857  SUBCASE("Empty")
7858  {
7859  const std::string string;
7860 
7861  object = {string};
7862  CHECK(object.is<std::string>());
7863 
7864  // Check serialized data
7865 
7866  data = serialize(object);
7867  CHECK(data.size() == 1);
7868 
7869  index = 0;
7870  CHECK((data[index] & Fixed_Str_Mask) == (uint8_t)Format::Fixed_Str);
7871  str_len = data[index] & Fixed_Str_Value;
7872  CHECK(str_len == string.size());
7873 
7874  // Check deserialized data
7875 
7876  object = deserialize(data);
7877  CHECK(object.is<std::string>());
7878  CHECK(object.as<std::string>() == string);
7879  }
7880 
7881  // -------------------------------------------------------------------
7882 
7883  SUBCASE("Len_1")
7884  {
7885  const std::string string(1, '_');
7886 
7887  object = {string};
7888  CHECK(object.is<std::string>());
7889 
7890  // Check serialized data
7891 
7892  data = serialize(object);
7893  CHECK(data.size() == string.size() + 1);
7894 
7895  index = 0;
7896  CHECK((data[index] & Fixed_Str_Mask) == (uint8_t)Format::Fixed_Str);
7897  str_len = data[index] & Fixed_Str_Value;
7898  CHECK(str_len == string.size());
7899 
7900  // Check deserialized data
7901 
7902  object = deserialize(data);
7903  CHECK(object.is<std::string>());
7904  CHECK(object.as<std::string>() == string);
7905  }
7906 
7907  // -------------------------------------------------------------------
7908 
7909  SUBCASE("Len_31")
7910  {
7911  const std::string string(31, 'X');
7912 
7913  object = {string};
7914  CHECK(object.is<std::string>());
7915 
7916  // Check serialized data
7917 
7918  data = serialize(object);
7919  CHECK(data.size() == string.size() + 1);
7920 
7921  index = 0;
7922  CHECK((data[index] & Fixed_Str_Mask) == (uint8_t)Format::Fixed_Str);
7923  str_len = data[index] & Fixed_Str_Value;
7924  CHECK(str_len == string.size());
7925 
7926  // Check deserialized data
7927 
7928  object = deserialize(data);
7929  CHECK(object.is<std::string>());
7930  CHECK(object.as<std::string>() == string);
7931  }
7932 }
7933 
7934 
7935 TEST_CASE("serialize/object/str8")
7936 {
7937  Object object;
7938  std::vector<uint8_t> data;
7939  size_t index;
7940  size_t str_len;
7941 
7942  // -------------------------------------------------------------------
7943 
7944  SUBCASE("Min")
7945  {
7946  const std::string string(32, '_');
7947 
7948  object = {string};
7949  CHECK(object.is<std::string>());
7950 
7951  // Check serialized data
7952 
7953  data = serialize(object);
7954  CHECK(data.size() == string.size() + 2);
7955 
7956  index = 0;
7957  CHECK(data[index++] == (uint8_t)Format::Str8);
7958  str_len = data[index++];
7959  CHECK(str_len == string.size());
7960 
7961  // Check deserialized data
7962 
7963  object = deserialize(data);
7964  CHECK(object.is<std::string>());
7965  CHECK(object.as<std::string>() == string);
7966  }
7967 
7968  // -------------------------------------------------------------------
7969 
7970  SUBCASE("Max")
7971  {
7972  const std::string string(std::numeric_limits<uint8_t>::max(), 'X');
7973 
7974  object = {string};
7975  CHECK(object.is<std::string>());
7976 
7977  // Check serialized data
7978 
7979  data = serialize(object);
7980  CHECK(data.size() == (string.size() + 2));
7981 
7982  index = 0;
7983  CHECK(data[index++] == (uint8_t)Format::Str8);
7984  str_len = data[index++];
7985  CHECK(str_len == string.size());
7986 
7987  // Check deserialized data
7988 
7989  object = deserialize(data);
7990  CHECK(object.is<std::string>());
7991  CHECK(object.as<std::string>() == string);
7992  }
7993 }
7994 
7995 
7996 TEST_CASE("serialize/object/str16")
7997 {
7998  Object object;
7999  std::vector<uint8_t> data;
8000  size_t index;
8001  size_t str_len;
8002 
8003  // -------------------------------------------------------------------
8004 
8005  SUBCASE("Min")
8006  {
8007  const std::string string(std::numeric_limits<uint8_t>::max() + 1, '_');
8008 
8009  object = {string};
8010  CHECK(object.is<std::string>());
8011 
8012  // Check serialized data
8013 
8014  data = serialize(object);
8015  CHECK(data.size() == string.size() + 3);
8016 
8017  index = 0;
8018  CHECK(data[index++] == (uint8_t)Format::Str16);
8019  Convert_Byte1 = data[index++];
8020  Convert_Byte0 = data[index++];
8021  str_len = Convert.uint16;
8022  CHECK(str_len == string.size());
8023 
8024  // Check deserialized data
8025 
8026  object = deserialize(data);
8027  CHECK(object.is<std::string>());
8028  CHECK(object.as<std::string>() == string);
8029  }
8030 
8031  // -------------------------------------------------------------------
8032 
8033  SUBCASE("Max")
8034  {
8035  const std::string string(std::numeric_limits<uint16_t>::max(), 'X');
8036 
8037  object = {string};
8038  CHECK(object.is<std::string>());
8039 
8040  // Check serialized data
8041 
8042  data = serialize(object);
8043  CHECK(data.size() == (string.size() + 3));
8044 
8045  index = 0;
8046  CHECK(data[index++] == (uint8_t)Format::Str16);
8047  Convert_Byte1 = data[index++];
8048  Convert_Byte0 = data[index++];
8049  str_len = Convert.uint16;
8050  CHECK(str_len == string.size());
8051 
8052  // Check deserialized data
8053 
8054  object = deserialize(data);
8055  CHECK(object.is<std::string>());
8056  CHECK(object.as<std::string>() == string);
8057  }
8058 }
8059 
8060 
8061 TEST_CASE("serialize/object/str32")
8062 {
8063  Object object;
8064  std::vector<uint8_t> data;
8065  size_t index;
8066  size_t str_len;
8067 
8068  // -------------------------------------------------------------------
8069 
8070  SUBCASE("Min")
8071  {
8072  const std::string string(std::numeric_limits<uint16_t>::max() + 1, '_');
8073 
8074  object = {string};
8075  CHECK(object.is<std::string>());
8076 
8077  // Check serialized data
8078 
8079  data = serialize(object);
8080  CHECK(data.size() == string.size() + 5);
8081 
8082  index = 0;
8083  CHECK(data[index++] == (uint8_t)Format::Str32);
8084  Convert_Byte3 = data[index++];
8085  Convert_Byte2 = data[index++];
8086  Convert_Byte1 = data[index++];
8087  Convert_Byte0 = data[index++];
8088  str_len = Convert.uint32;
8089  CHECK(str_len == string.size());
8090 
8091  // Check deserialized data
8092 
8093  object = deserialize(data);
8094  CHECK(object.is<std::string>());
8095  CHECK(object.as<std::string>() == string);
8096  }
8097 
8098  // -------------------------------------------------------------------
8099 
8100  SUBCASE("Max")
8101  {
8102  /*
8103  * This string would be 4GB + overhead from std::string
8104  * Serializing would consume another 4GB.
8105  * For a total of 8GB to test the maximum Str32 length.
8106  const std::string string(std::numeric_limits<uint32_t>::max(), 'X');
8107 
8108  object = {string};
8109  CHECK(object.is<std::string>());
8110 
8111  // Check serialized data
8112 
8113  data = serialize(object);
8114  CHECK(data.size() == (string.size() + 3));
8115 
8116  index = 0;
8117  CHECK(data[index++] == (uint8_t)Format::Str32);
8118  Convert_Byte3 = data[index++];
8119  Convert_Byte2 = data[index++];
8120  Convert_Byte1 = data[index++];
8121  Convert_Byte0 = data[index++];
8122  str_len = Convert.uint32;
8123  CHECK(str_len == string.size());
8124 
8125  // Check deserialized data
8126 
8127  object = deserialize(data);
8128  CHECK(object.is<std::string>());
8129  CHECK(object.as<std::string>() == string);
8130  */
8131  }
8132 }
8133 
8134 
8135 TEST_CASE("serialize/object/bin8")
8136 {
8137  Object object;
8138  std::vector<uint8_t> data;
8139  size_t index;
8140  size_t bin_len;
8141 
8142  // -------------------------------------------------------------------
8143 
8144  SUBCASE("Min")
8145  {
8146  const std::vector<uint8_t> bin = {};
8147 
8148  object = {bin};
8149  CHECK(object.isBinary());
8150 
8151  // Check serialized data
8152 
8153  data = serialize(object);
8154  CHECK(data.size() == bin.size() + 2);
8155 
8156  index = 0;
8157  CHECK(data[index++] == (uint8_t)Format::Bin8);
8158  bin_len = data[index++];
8159  CHECK(bin_len == bin.size());
8160 
8161  // Check deserialized data
8162 
8163  object = deserialize(data);
8164  CHECK(object.isBinary());
8165 
8166  const std::vector<uint8_t>& vector = object.asBinary();
8167  for(size_t i = 0; i < bin_len; i++)
8168  {
8169  CHECK(vector[i] == bin[i]);
8170  }
8171  }
8172 
8173  // -------------------------------------------------------------------
8174 
8175  SUBCASE("Max")
8176  {
8177  const std::vector<uint8_t> bin(std::numeric_limits<uint8_t>::max(), 'X');
8178 
8179  object = {bin};
8180  CHECK(object.isBinary());
8181 
8182  // Check serialized data
8183 
8184  data = serialize(object);
8185  CHECK(data.size() == bin.size() + 2);
8186 
8187  index = 0;
8188  CHECK(data[index++] == (uint8_t)Format::Bin8);
8189  bin_len = data[index++];
8190  CHECK(bin_len == bin.size());
8191 
8192  // Check deserialized data
8193 
8194  object = deserialize(data);
8195  CHECK(object.isBinary());
8196 
8197  const std::vector<uint8_t>& vector = object.asBinary();
8198  for(size_t i = 0; i < bin_len; i++)
8199  {
8200  CHECK(vector[i] == bin[i]);
8201  }
8202  }
8203 }
8204 
8205 
8206 TEST_CASE("serialize/object/bin16")
8207 {
8208  Object object;
8209  std::vector<uint8_t> data;
8210  size_t index;
8211  size_t bin_len;
8212 
8213  // -------------------------------------------------------------------
8214 
8215  SUBCASE("Min")
8216  {
8217  const std::vector<uint8_t> bin(std::numeric_limits<uint8_t>::max() + 1, '_');
8218 
8219  object = {bin};
8220  CHECK(object.isBinary());
8221 
8222  // Check serialized data
8223 
8224  data = serialize(object);
8225  CHECK(data.size() == bin.size() + 3);
8226 
8227  index = 0;
8228  CHECK(data[index++] == (uint8_t)Format::Bin16);
8229  Convert_Byte1 = data[index++];
8230  Convert_Byte0 = data[index++];
8231  bin_len = Convert.uint16;
8232  CHECK(bin_len == bin.size());
8233 
8234  // Check deserialized data
8235 
8236  object = deserialize(data);
8237  CHECK(object.isBinary());
8238 
8239  const std::vector<uint8_t>& vector = object.asBinary();
8240  for(size_t i = 0; i < bin_len; i++)
8241  {
8242  CHECK(vector[i] == bin[i]);
8243  }
8244  }
8245 
8246  // -------------------------------------------------------------------
8247 
8248  SUBCASE("Max")
8249  {
8250  const std::vector<uint8_t> bin(std::numeric_limits<uint16_t>::max(), 'X');
8251 
8252  object = {bin};
8253  CHECK(object.isBinary());
8254 
8255  // Check serialized data
8256 
8257  data = serialize(object);
8258  CHECK(data.size() == bin.size() + 3);
8259 
8260  index = 0;
8261  CHECK(data[index++] == (uint8_t)Format::Bin16);
8262  Convert_Byte1 = data[index++];
8263  Convert_Byte0 = data[index++];
8264  bin_len = Convert.uint16;
8265  CHECK(bin_len == bin.size());
8266 
8267  // Check deserialized data
8268 
8269  object = deserialize(data);
8270  CHECK(object.isBinary());
8271 
8272  const std::vector<uint8_t>& vector = object.asBinary();
8273  for(size_t i = 0; i < bin_len; i++)
8274  {
8275  CHECK(vector[i] == bin[i]);
8276  }
8277  }
8278 }
8279 
8280 
8281 TEST_CASE("serialize/object/bin32")
8282 {
8283  Object object;
8284  std::vector<uint8_t> data;
8285  size_t index;
8286  size_t bin_len;
8287 
8288  // -------------------------------------------------------------------
8289 
8290  SUBCASE("Min")
8291  {
8292  const std::vector<uint8_t> bin(std::numeric_limits<uint16_t>::max() + 1, '_');
8293 
8294  object = {bin};
8295  CHECK(object.isBinary());
8296 
8297  // Check serialized data
8298 
8299  data = serialize(object);
8300  CHECK(data.size() == bin.size() + 5);
8301 
8302  index = 0;
8303  CHECK(data[index++] == (uint8_t)Format::Bin32);
8304  Convert_Byte3 = data[index++];
8305  Convert_Byte2 = data[index++];
8306  Convert_Byte1 = data[index++];
8307  Convert_Byte0 = data[index++];
8308  bin_len = Convert.uint32;
8309  CHECK(bin_len == bin.size());
8310 
8311  // Check deserialized data
8312 
8313  object = deserialize(data);
8314  CHECK(object.isBinary());
8315 
8316  const std::vector<uint8_t>& vector = object.asBinary();
8317  for(size_t i = 0; i < bin_len; i++)
8318  {
8319  CHECK(vector[i] == bin[i]);
8320  }
8321  }
8322 
8323  // -------------------------------------------------------------------
8324 
8325  SUBCASE("Max")
8326  {
8327  /*
8328  * This vector would be 4GB + overhead from std::vector
8329  * Serializing would consume another 4GB.
8330  * For a total of 8GB to test the maximum Str32 length.
8331  const std::vector<uint8_t> bin(std::numeric_limits<uint32_t>::max(), 'X');
8332 
8333  object = {bin};
8334  CHECK(object.isBinary());
8335 
8336  // Check serialized data
8337 
8338  data = serialize(object);
8339  CHECK(data.size() == (bin.size() + 5));
8340 
8341  index = 0;
8342  CHECK(data[index++] == (uint8_t)Format::Bin32);
8343  Convert_Byte3 = data[index++];
8344  Convert_Byte2 = data[index++];
8345  Convert_Byte1 = data[index++];
8346  Convert_Byte0 = data[index++];
8347  bin_len = Convert.uint32;
8348  CHECK(bin_len == bin.size());
8349 
8350  // Check deserialized data
8351 
8352  object = deserialize(data);
8353  CHECK(object.isBinary());
8354 
8355  const std::vector<uint8_t>& vector = object.asBinary();
8356  for(size_t i = 0; i < bin_len; i++)
8357  {
8358  CHECK(vector[i] == bin[i]);
8359  }
8360  */
8361  }
8362 }
8363 
8364 
8365 TEST_CASE("serialize/object/fixed_array")
8366 {
8367  Object object;
8368  std::vector<uint8_t> data;
8369  size_t index;
8370  size_t array_len;
8371 
8372  // -------------------------------------------------------------------
8373 
8374  SUBCASE("Empty")
8375  {
8376  object = {Array{}};
8377  CHECK(object.isArray());
8378  CHECK(object.asArray().size() == 0);
8379 
8380  // Check serialized data
8381 
8382  data = serialize(object);
8383  CHECK(data.size() == 1);
8384 
8385  index = 0;
8386  CHECK((data[index] & Fixed_Array_Mask) == (uint8_t)Format::Fixed_Array);
8387  array_len = data[index] & Fixed_Array_Value;
8388  CHECK(array_len == 0);
8389 
8390  // Check deserialized data
8391 
8392  object = deserialize(data);
8393  CHECK(object.isArray());
8394  CHECK(object.asArray().size() == 0);
8395  }
8396 
8397  // -------------------------------------------------------------------
8398 
8399  SUBCASE("Len 15")
8400  {
8401  object = {Array{}};
8402  CHECK(object.isArray());
8403 
8404  for(size_t i = 0; i < 15; i++)
8405  {
8406  object.asArray().appendNull();
8407  }
8408 
8409  array_len = object.asArray().size();
8410  CHECK(array_len == 15);
8411 
8412  // Check serialized data
8413 
8414  data = serialize(object);
8415  CHECK(data.size() == (array_len + 1));
8416 
8417  index = 0;
8418  CHECK((data[index] & Fixed_Array_Mask) == (uint8_t)Format::Fixed_Array);
8419  array_len = data[index] & Fixed_Array_Value;
8420  CHECK(array_len == 15);
8421 
8422  // Check deserialized data
8423 
8424  object = deserialize(data);
8425  CHECK(object.isArray());
8426  CHECK(object.asArray().size() == 15);
8427 
8428  for(size_t i = 0; i < 15; i++)
8429  {
8430  CHECK(object.asArray().object(i).isNull());
8431  }
8432  }
8433 }
8434 
8435 
8436 TEST_CASE("serialize/object/array16")
8437 {
8438  Object object;
8439  std::vector<uint8_t> data;
8440  size_t index;
8441  size_t array_len;
8442 
8443  // -------------------------------------------------------------------
8444 
8445  SUBCASE("Min")
8446  {
8447  object = {Array{}};
8448  CHECK(object.isArray());
8449 
8450  for(size_t i = 0; i < 16; i++)
8451  {
8452  object.asArray().append(true);
8453  }
8454 
8455  array_len = object.asArray().size();
8456  CHECK(array_len == 16);
8457 
8458  // Check serialized data
8459 
8460  data = serialize(object);
8461  CHECK(data.size() == (array_len + 3));
8462 
8463  index = 0;
8464  CHECK(data[index++] == (uint8_t)Format::Array16);
8465  Convert_Byte1 = data[index++];
8466  Convert_Byte0 = data[index++];
8467  array_len = Convert.uint16;
8468  CHECK(array_len == 16);
8469 
8470  // Check deserialized data
8471 
8472  object = deserialize(data);
8473  CHECK(object.isArray());
8474  CHECK(object.asArray().size() == 16);
8475 
8476  for(size_t i = 0; i < 16; i++)
8477  {
8478  CHECK(object.asArray().object(i).is<bool>());
8479  CHECK(object.asArray().object(i).as<bool>() == true);
8480  }
8481  }
8482 
8483  // -------------------------------------------------------------------
8484 
8485  SUBCASE("Max")
8486  {
8487  object = {Array{}};
8488  CHECK(object.isArray());
8489 
8490  for(size_t i = 0; i < std::numeric_limits<uint16_t>::max(); i++)
8491  {
8492  object.asArray().append(false);
8493  }
8494 
8495  array_len = object.asArray().size();
8496  CHECK(array_len == std::numeric_limits<uint16_t>::max());
8497 
8498  // Check serialized data
8499 
8500  data = serialize(object);
8501  CHECK(data.size() == (array_len + 3));
8502 
8503  index = 0;
8504  CHECK(data[index++] == (uint8_t)Format::Array16);
8505  Convert_Byte1 = data[index++];
8506  Convert_Byte0 = data[index++];
8507  array_len = Convert.uint16;
8508  CHECK(array_len == std::numeric_limits<uint16_t>::max());
8509 
8510  // Check deserialized data
8511 
8512  object = deserialize(data);
8513  CHECK(object.isArray());
8514  CHECK(array_len == std::numeric_limits<uint16_t>::max());
8515 
8516  for(int i = 0; i < std::numeric_limits<uint16_t>::max(); i++)
8517  {
8518  CHECK(object.asArray().object(i).is<bool>());
8519  CHECK(object.asArray().object(i).as<bool>() == false);
8520  }
8521  }
8522 }
8523 
8524 
8525 TEST_CASE("serialize/object/array32")
8526 {
8527  Object object;
8528  std::vector<uint8_t> data;
8529  size_t index;
8530  size_t array_len;
8531 
8532  // -------------------------------------------------------------------
8533 
8534  SUBCASE("Min")
8535  {
8536  object = {Array{}};
8537  CHECK(object.isArray());
8538 
8539  for(size_t i = 0; i < std::numeric_limits<uint16_t>::max() + 1; i++)
8540  {
8541  object.asArray().append(true);
8542  }
8543 
8544  array_len = object.asArray().size();
8545  CHECK(array_len == (std::numeric_limits<uint16_t>::max() + 1));
8546 
8547  // Check serialized data
8548 
8549  data = serialize(object);
8550  CHECK(data.size() == (array_len + 5));
8551 
8552  index = 0;
8553  CHECK(data[index++] == (uint8_t)Format::Array32);
8554  Convert_Byte3 = data[index++];
8555  Convert_Byte2 = data[index++];
8556  Convert_Byte1 = data[index++];
8557  Convert_Byte0 = data[index++];
8558  array_len = Convert.uint32;
8559  CHECK(array_len == (std::numeric_limits<uint16_t>::max() + 1));
8560 
8561  // Check deserialized data
8562 
8563  object = deserialize(data);
8564  CHECK(object.isArray());
8565  CHECK(object.asArray().size() == (std::numeric_limits<uint16_t>::max() + 1));
8566 
8567  for(size_t i = 0; i < std::numeric_limits<uint16_t>::max() + 1; i++)
8568  {
8569  CHECK(object.asArray().object(i).is<bool>());
8570  CHECK(object.asArray().object(i).as<bool>() == true);
8571  }
8572  }
8573 
8574  // -------------------------------------------------------------------
8575 
8576  SUBCASE("Max")
8577  {
8578  /*
8579  * This vector would be 4GB + overhead from std::vector
8580  * Serializing would consume another 4GB.
8581  * For a total of 8GB to test the maximum Array32 length.
8582  object = {Array{}};
8583  CHECK(object.isArray());
8584 
8585  for(size_t i = 0; i < std::numeric_limits<uint32_t>::max(); i++)
8586  {
8587  object.asArray().append(false);
8588  }
8589 
8590  array_len = object.asArray().size();
8591  CHECK(array_len == std::numeric_limits<uint32_t>::max());
8592 
8593  // Check serialized data
8594 
8595  data = serialize(object);
8596  CHECK(data.size() == (array_len + 5));
8597 
8598  index = 0;
8599  CHECK(data[index++] == (uint8_t)Format::Array32);
8600  Convert_Byte3 = data[index++];
8601  Convert_Byte2 = data[index++];
8602  Convert_Byte1 = data[index++];
8603  Convert_Byte0 = data[index++];
8604  array_len = Convert.uint32;
8605  CHECK(array_len == std::numeric_limits<uint32_t>::max());
8606 
8607  // Check deserialized data
8608 
8609  object = deserialize(data);
8610  CHECK(object.isArray());
8611  CHECK(array_len == std::numeric_limits<uint32_t>::max());
8612 
8613  for(int i = 0; i < std::numeric_limits<uint32_t>::max(); i++)
8614  {
8615  CHECK(object.asArray().object(i).is<bool>());
8616  CHECK(object.asArray().object(i).as<bool>() == false);
8617  }
8618  */
8619  }
8620 }
8621 
8622 #endif // }}}
8623 
8624 // }}} Utilities::serialize
8625 // {{{ Utilities::to_string
8626 
8632 std::string to_string(const messagepack::Array& array
8633  ) noexcept
8634 {
8635  std::string s = "[";
8636 
8637  std::string prefix = " ";
8638 
8639  for(size_t i = 0; i < array.size(); i++)
8640  {
8641  s += prefix + to_string(array.object(i));
8642 
8643  if(i == 0)
8644  {
8645  prefix = ", ";
8646  }
8647  }
8648 
8649  s += " ]";
8650 
8651  return s;
8652 }
8653 
8654 
8660 std::string to_string(const messagepack::Ext& ext
8661  ) noexcept
8662 {
8663  std::string s = "";
8664 
8665  s += "( 'type': " + std::to_string(ext.type);
8666  s += ", 'data': [";
8667 
8668  std::string prefix = " ";
8669 
8670  for(size_t i = 0; i < ext.data.size(); i++)
8671  {
8672  s += prefix + std::to_string(ext.data[i]);
8673 
8674  if(i == 0)
8675  {
8676  prefix = ", ";
8677  }
8678  }
8679 
8680  s += " ]";
8681  s += " )";
8682 
8683  return s;
8684 }
8685 
8686 
8692 std::string to_string(const messagepack::Map& map
8693  ) noexcept
8694 {
8695  std::string s = "{";
8696 
8697  std::string prefix = " ";
8698 
8699  if(map.null_map.empty() == false)
8700  {
8701  s += prefix
8702  + to_string(Object{})
8703  + ": "
8704  + to_string(map.null_map[0])
8705  ;
8706 
8707  prefix = ", ";
8708  }
8709 
8710  for(const auto& [key, value] : map.bool_map)
8711  {
8712  s += prefix
8713  + to_string(Object{key})
8714  + ": "
8715  + to_string(value)
8716  ;
8717 
8718  prefix = ", ";
8719  }
8720 
8721  for(const auto& [key, value] : map.int64_map)
8722  {
8723  s += prefix
8724  + to_string(Object{key})
8725  + ": "
8726  + to_string(value)
8727  ;
8728 
8729  prefix = ", ";
8730  }
8731 
8732  for(const auto& [key, value] : map.uint64_map)
8733  {
8734  s += prefix
8735  + to_string(Object{key})
8736  + ": "
8737  + to_string(value)
8738  ;
8739 
8740  prefix = ", ";
8741  }
8742 
8743  for(const auto& [key, value] : map.float_map)
8744  {
8745  s += prefix
8746  + to_string(Object{key})
8747  + ": "
8748  + to_string(value)
8749  ;
8750 
8751  prefix = ", ";
8752  }
8753 
8754  for(const auto& [key, value] : map.double_map)
8755  {
8756  s += prefix
8757  + to_string(Object{key})
8758  + ": "
8759  + to_string(value)
8760  ;
8761 
8762  prefix = ", ";
8763  }
8764 
8765  for(const auto& [key, value] : map.string_map)
8766  {
8767  s += prefix
8768  + to_string(Object{key})
8769  + ": "
8770  + to_string(value)
8771  ;
8772 
8773  prefix = ", ";
8774  }
8775 
8776  s += " }";
8777 
8778  return s;
8779 }
8780 
8781 
8787 std::string to_string(const messagepack::Object& object
8788  ) noexcept
8789 {
8790  std::string s = "{ ";
8791 
8792  if(object.isNull())
8793  {
8794  s += "'type': 'null'";
8795  }
8796  else if(object.is<bool>())
8797  {
8798  s += "'type': 'bool', 'value': ";
8799  if(object.as<bool>() == true)
8800  {
8801  s += "true";
8802  }
8803  else
8804  {
8805  s += "false";
8806  }
8807  }
8808  else if(object.is<int64_t>())
8809  {
8810  s += "'type': 'int64_t', 'value': "
8811  + std::to_string(object.as<int64_t>())
8812  ;
8813  }
8814  else if(object.is<uint64_t>())
8815  {
8816  s += "'type': 'uint64_t', 'value': "
8817  + std::to_string(object.as<uint64_t>())
8818  ;
8819  }
8820  else if(object.is<float>())
8821  {
8822  s += "'type': 'float', 'value': "
8823  + std::to_string(object.as<float>())
8824  ;
8825  }
8826  else if(object.is<double>())
8827  {
8828  s += "'type': 'double', 'value': "
8829  + std::to_string(object.as<double>())
8830  ;
8831  }
8832  else if(object.is<std::string>())
8833  {
8834  s += "'type': 'std::string', 'value': '"
8835  + object.as<std::string>()
8836  + "'"
8837  ;
8838  }
8839  else if(object.is<std::vector<uint8_t>>())
8840  {
8841  s += "'type': 'std::vector<uint8_t>', 'value': ["
8842  ;
8843 
8844  std::string prefix = " ";
8845 
8846  const std::vector<uint8_t>& data = object.as<std::vector<uint8_t>>();
8847  for(size_t i = 0; i < data.size(); i++)
8848  {
8849  s += prefix + std::to_string(data[i]);
8850 
8851  if(i == 0)
8852  {
8853  prefix = ", ";
8854  }
8855  }
8856 
8857  s += " ]";
8858  }
8859  else if(object.isArray())
8860  {
8861  s += "'type': 'zakero::messagepack::Array', 'value': "
8862  + zakero::messagepack::to_string(object.asArray())
8863  ;
8864  }
8865  else if(object.isExt())
8866  {
8867  s += "'type': 'zakero::messagepack::Ext', 'value': "
8868  + zakero::messagepack::to_string(object.asExt())
8869  ;
8870  }
8871  else if(object.isMap())
8872  {
8873  s += "'type': 'zakero::messagepack::Ext', 'value': "
8874  + zakero::messagepack::to_string(object.asMap())
8875  ;
8876  }
8877 
8878  s += " }";
8879 
8880  return s;
8881 }
8882 // }}} Utilities::to_string
8883 // }}} Utilities
8884 } // zakero::messagepack
8885 
8886 // {{{ Operators
8887 
8896 std::ostream& operator<<(std::ostream& stream
8897  , const zakero::messagepack::Array& array
8898  ) noexcept
8899 {
8900  stream << zakero::messagepack::to_string(array);
8901 
8902  return stream;
8903 }
8904 
8905 
8914 std::ostream& operator<<(std::ostream& stream
8915  , const zakero::messagepack::Ext& ext
8916  ) noexcept
8917 {
8918  stream << zakero::messagepack::to_string(ext);
8919 
8920  return stream;
8921 }
8922 
8923 
8932 std::ostream& operator<<(std::ostream& stream
8933  , const zakero::messagepack::Map& map
8934  ) noexcept
8935 {
8936  stream << zakero::messagepack::to_string(map);
8937 
8938  return stream;
8939 }
8940 
8941 
8950 std::ostream& operator<<(std::ostream& stream
8951  , const zakero::messagepack::Object& object
8952  ) noexcept
8953 {
8954  stream << zakero::messagepack::to_string(object);
8955 
8956  return stream;
8957 }
8958 
8968 bool operator==(const zakero::messagepack::Object& lhs
8969  , const zakero::messagepack::Object& rhs
8970  ) noexcept
8971 {
8972  if(&lhs == &rhs)
8973  {
8974  return true;
8975  }
8976 
8977  if(lhs.isNull() && rhs.isNull())
8978  {
8979  return true;
8980  }
8981 
8982  if(lhs.is<bool>() && rhs.is<bool>())
8983  {
8984  return (lhs.as<bool>() == rhs.as<bool>());
8985  }
8986 
8987  if(lhs.is<int64_t>() && rhs.is<int64_t>())
8988  {
8989  return (lhs.as<int64_t>() == rhs.as<int64_t>());
8990  }
8991 
8992  if(lhs.is<uint64_t>() && rhs.is<uint64_t>())
8993  {
8994  return (lhs.as<uint64_t>() == rhs.as<uint64_t>());
8995  }
8996 
8997  if(lhs.is<float>() && rhs.is<float>())
8998  {
8999  return (lhs.as<float>() == rhs.as<float>());
9000  }
9001 
9002  if(lhs.is<double>() && rhs.is<double>())
9003  {
9004  return (lhs.as<double>() == rhs.as<double>());
9005  }
9006 
9007  if(lhs.isString() && rhs.isString())
9008  {
9009  return (lhs.asString() == rhs.asString());
9010  }
9011 
9012  if(lhs.isBinary() && rhs.isBinary())
9013  {
9014  return (lhs.asBinary() == rhs.asBinary());
9015  }
9016 
9017  if(lhs.isArray() && rhs.isArray())
9018  {
9019  const zakero::messagepack::Array& l_array = lhs.asArray();
9020  const zakero::messagepack::Array& r_array = rhs.asArray();
9021 
9022  if(l_array.size() != r_array.size())
9023  {
9024  return false;
9025  }
9026 
9027  for(size_t i = 0; i < l_array.size(); i++)
9028  {
9029  if(l_array.object(i) != r_array.object(i))
9030  {
9031  return false;
9032  }
9033  }
9034 
9035  return true;
9036  }
9037 
9038  return false;
9039 }
9040 
9041 
9051 bool operator!=(const zakero::messagepack::Object& lhs
9052  , const zakero::messagepack::Object& rhs
9053  ) noexcept
9054 {
9055  return !(lhs == rhs);
9056 }
9057 
9058 // }}}
9059 
9060 #endif // ZAKERO_MESSAGEPACK_IMPLEMENTATION
9061 
9062 // }}}
9063 
9064 #endif // zakero_MessagePack_h
std::string to_string(const bool value) noexcept
Convert a bool into a string.
Definition: Zakero_Base.h:561
ErrorCategory_ ErrorCategory
A single instance.
Definition: Zakero_MessagePack.h:1383
std::ostream & operator<<(std::ostream &, const zakero::messagepack::Array &) noexcept
OStream operator.
Definition: Zakero_MessagePack.h:8892
Object deserialize(const std::vector< uint8_t > &) noexcept
Deserialize MessagePack data.
Definition: Zakero_MessagePack.h:4678
bool extensionTimestampCheck(const Object &) noexcept
Timestamp Extension Check.
Definition: Zakero_MessagePack.h:3967
bool operator!=(const zakero::messagepack::Object &lhs, const zakero::messagepack::Object &rhs) noexcept
Compare two Objects for inequality.
Definition: Zakero_MessagePack.h:9047
bool operator==(const zakero::messagepack::Object &lhs, const zakero::messagepack::Object &rhs) noexcept
Compare two Objects for equality.
Definition: Zakero_MessagePack.h:8964
std::string to_string(const messagepack::Array &) noexcept
Convert to a JSON formatted string.
Definition: Zakero_MessagePack.h:8628
struct timespec extensionTimestampConvert(const Object &) noexcept
Convert MessagePack Timestamp extension into a struct timespec.
Definition: Zakero_MessagePack.h:4058
std::vector< uint8_t > serialize(const messagepack::Array &) noexcept
Serialize Array data.
Definition: Zakero_MessagePack.h:5943
MessagePack Error Categories.
Definition: Zakero_MessagePack.h:247
std::string message(int condition) const noexcept final override
A description message.
Definition: Zakero_MessagePack.h:1363
const char * name() const noexcept final override
The name of the error category.
Definition: Zakero_MessagePack.h:1352
constexpr ErrorCategory_() noexcept
Constructor.
Definition: Zakero_MessagePack.h:249
An array of Objects.
Definition: Zakero_MessagePack.h:272
Object & object(const size_t index) noexcept
Access a data object.
Definition: Zakero_MessagePack.h:291
size_t append(const bool) noexcept
Append a boolean value.
Definition: Zakero_MessagePack.h:1425
std::vector< Object > object_vector
Store the Object data.
Definition: Zakero_MessagePack.h:297
size_t size() const noexcept
Get the size of the Array.
Definition: Zakero_MessagePack.h:295
void clear() noexcept
Remove all data from the Array.
Definition: Zakero_MessagePack.h:294
const Object & object(const size_t index) const noexcept
Access a data object.
Definition: Zakero_MessagePack.h:292
size_t appendNull() noexcept
Append a "Null" value.
Definition: Zakero_MessagePack.h:2738
Extension Data.
Definition: Zakero_MessagePack.h:304
A Key/Value collection of Objects.
Definition: Zakero_MessagePack.h:313
void clear() noexcept
Remove the contents of the Map.
Definition: Zakero_MessagePack.h:3622
std::error_code set(Object &, Object &) noexcept
Set a key/value pair.
Definition: Zakero_MessagePack.h:3108
size_t size() const noexcept
Get the size of the Map.
Definition: Zakero_MessagePack.h:3639
Object & at(Object &) noexcept
Get the value of a key.
Definition: Zakero_MessagePack.h:3521
bool keyExists(const Object &) const noexcept
Check if a key exists.
Definition: Zakero_MessagePack.h:3323
void erase(const Object &) noexcept
Erase a key/value pair.
Definition: Zakero_MessagePack.h:3227
A Data Object.
Definition: Zakero_MessagePack.h:337
constexpr bool isExt() const noexcept
Is Object an Ext?
Definition: Zakero_MessagePack.h:371
constexpr bool isString() const noexcept
Is Object a std::string?
Definition: Zakero_MessagePack.h:374
const messagepack::Array & asArray() const noexcept
Convert to an Array.
Definition: Zakero_MessagePack.h:357
messagepack::Array & asArray() noexcept
Convert to an Array.
Definition: Zakero_MessagePack.h:356
messagepack::Map & asMap() noexcept
Convert to a Map.
Definition: Zakero_MessagePack.h:360
const std::vector< uint8_t > & asBinary() const noexcept
Convert to a std::vector<uint8_t>.
Definition: Zakero_MessagePack.h:363
const std::string & asString() const noexcept
Convert to a std::string.
Definition: Zakero_MessagePack.h:364
constexpr bool is() const noexcept
Is Object of type T.
Definition: Zakero_MessagePack.h:367
constexpr bool isNull() const noexcept
Does the Object represent a null?
Definition: Zakero_MessagePack.h:373
constexpr bool isArray() const noexcept
Is Object an Array?
Definition: Zakero_MessagePack.h:369
const messagepack::Map & asMap() const noexcept
Convert to a Map.
Definition: Zakero_MessagePack.h:361
constexpr bool isMap() const noexcept
Is Object a Map?
Definition: Zakero_MessagePack.h:372
std::vector< uint8_t > & asBinary() noexcept
Convert to a std::vector<uint8_t>.
Definition: Zakero_MessagePack.h:362
const T & as() const noexcept
Convert to type T.
Definition: Zakero_MessagePack.h:354
T & as() noexcept
Convert to type T.
Definition: Zakero_MessagePack.h:352
constexpr bool isBinary() const noexcept
Is Object binary data?
Definition: Zakero_MessagePack.h:370
messagepack::Ext & asExt() noexcept
Convert to an Ext.
Definition: Zakero_MessagePack.h:358
const messagepack::Ext & asExt() const noexcept
Convert to an Ext.
Definition: Zakero_MessagePack.h:359