MessagePack for C++
object.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 #ifndef MSGPACK_V1_OBJECT_HPP
11 #define MSGPACK_V1_OBJECT_HPP
12 
13 #include "msgpack/object_decl.hpp"
15 
16 #include <cstring>
17 #include <stdexcept>
18 #include <typeinfo>
19 #include <limits>
20 #include <ostream>
21 #include <typeinfo>
22 #include <iomanip>
23 
24 namespace msgpack {
25 
29 
30 struct object_kv {
33 };
34 
38 private:
39  with_zone();
40 };
41 
42 
45 public:
48 
50 
55  msgpack::object const& obj,
56 #if defined(MSGPACK_USE_CPP03)
57  msgpack::unique_ptr<msgpack::zone> z
58 #else // defined(MSGPACK_USE_CPP03)
59  msgpack::unique_ptr<msgpack::zone>&& z
60 #endif // defined(MSGPACK_USE_CPP03)
61  ) :
62  m_obj(obj), m_zone(msgpack::move(z)) { }
63 
64  void set(msgpack::object const& obj)
65  { m_obj = obj; }
66 
68 
71  const msgpack::object& get() const
72  { return m_obj; }
73 
77  const msgpack::object& operator*() const
78  { return get(); }
79 
83  const msgpack::object* operator->() const
84  { return &get(); }
85 
87 
90  msgpack::unique_ptr<msgpack::zone>& zone()
91  { return m_zone; }
92 
94 
97  const msgpack::unique_ptr<msgpack::zone>& zone() const
98  { return m_zone; }
99 
100 #if defined(MSGPACK_USE_CPP03)
101  struct object_handle_ref {
102  object_handle_ref(object_handle* oh):m_oh(oh) {}
103  object_handle* m_oh;
104  };
105 
107  m_obj(other.m_obj),
108  m_zone(msgpack::move(other.m_zone)) {
109  }
110 
111  object_handle(object_handle_ref ref):
112  m_obj(ref.m_oh->m_obj),
113  m_zone(msgpack::move(ref.m_oh->m_zone)) {
114  }
115 
116  object_handle& operator=(object_handle& other) {
117  m_obj = other.m_obj;
118  m_zone = msgpack::move(other.m_zone);
119  return *this;
120  }
121 
122  object_handle& operator=(object_handle_ref ref) {
123  m_obj = ref.m_oh->m_obj;
124  m_zone = msgpack::move(ref.m_oh->m_zone);
125  return *this;
126  }
127 
128  operator object_handle_ref() {
129  return object_handle_ref(this);
130  }
131 #endif // defined(MSGPACK_USE_CPP03)
132 
133 private:
134  msgpack::object m_obj;
135  msgpack::unique_ptr<msgpack::zone> m_zone;
136 };
137 
138 namespace detail {
139 
140 template <std::size_t N>
141 inline std::size_t add_ext_type_size(std::size_t size) {
142  return size + 1;
143 }
144 
145 template <>
146 inline std::size_t add_ext_type_size<4>(std::size_t size) {
147  return size == 0xffffffff ? size : size + 1;
148 }
149 
150 } // namespace detail
152 private:
153  enum next_ret {
154  cont,
155  finish,
156  abort
157  };
158  struct elem {
159  elem(msgpack::object const* p, std::size_t r)
160  : rest(r), is_map(false), is_key(false) {
161  as.obj_ptr = p;
162  }
163 
164  elem(msgpack::object_kv const* p, std::size_t r)
165  : rest(r), is_map(true), is_key(true) {
166  as.kv_ptr = p;
167  }
168 
169  msgpack::object const& get() const {
170  if (is_map) {
171  if (is_key) {
172  return as.kv_ptr->key;
173  }
174  else {
175  return as.kv_ptr->val;
176  }
177  }
178  else {
179  return *as.obj_ptr;
180  }
181  }
182 
183  template <typename Visitor>
184  next_ret next(Visitor& v) {
185  if (rest == 0) {
186  if (is_map) {
187  if (!v.end_map()) return abort;
188  }
189  else {
190  if (!v.end_array()) return abort;
191  }
192  return finish;
193  }
194  else {
195  if (is_map) {
196  if (is_key) {
197  if (!v.end_map_key()) return abort;
198  if (!v.start_map_value()) return abort;
199  is_key = false;
200  }
201  else {
202  if (!v.end_map_value()) return abort;
203  --rest;
204  if (rest == 0) {
205  if (!v.end_map()) return abort;
206  return finish;
207  }
208  if (!v.start_map_key()) return abort;
209  ++as.kv_ptr;
210  is_key = true;
211  }
212  }
213  else {
214  if (!v.end_array_item()) return abort;
215  --rest;
216  if (rest == 0) {
217  if (!v.end_array()) return abort;
218  return finish;
219  }
220  if (!v.start_array_item()) return abort;
221  ++as.obj_ptr;
222  }
223  return cont;
224  }
225  }
226 
227  union {
228  msgpack::object const* obj_ptr;
229  msgpack::object_kv const* kv_ptr;
230  } as;
231  std::size_t rest;
232  bool is_map;
233  bool is_key;
234  };
235 public:
236  explicit object_parser(msgpack::object const& obj):m_current(&obj) {}
237  template <typename Visitor>
238  void parse(Visitor& v) {
239  while (true) {
240  bool start_collection = false;
241  switch(m_current->type) {
242  case msgpack::type::NIL:
243  if (!v.visit_nil()) return;
244  break;
246  if (!v.visit_boolean(m_current->via.boolean)) return;
247  break;
249  if (!v.visit_positive_integer(m_current->via.u64)) return;
250  break;
252  if (!v.visit_negative_integer(m_current->via.i64)) return;
253  break;
255  if (!v.visit_float32(static_cast<float>(m_current->via.f64))) return;
256  break;
258  if (!v.visit_float64(m_current->via.f64)) return;
259  break;
260  case msgpack::type::STR:
261  if (!v.visit_str(m_current->via.str.ptr, m_current->via.str.size)) return;
262  break;
263  case msgpack::type::BIN:
264  if (!v.visit_bin(m_current->via.bin.ptr, m_current->via.bin.size)) return;
265  break;
266  case msgpack::type::EXT:
267  msgpack::detail::check_container_size<sizeof(std::size_t)>(m_current->via.ext.size);
268  if (!v.visit_ext(m_current->via.ext.ptr, m_current->via.ext.size + 1)) return;
269  break;
271  if (!v.start_array(m_current->via.array.size)) return;
272  m_ctx.push_back(elem(m_current->via.array.ptr, m_current->via.array.size));
273  start_collection = m_current->via.array.size != 0;
274  if (start_collection) {
275  if (!v.start_array_item()) return;
276  }
277  break;
278  case msgpack::type::MAP:
279  if (!v.start_map(m_current->via.map.size)) return;
280  m_ctx.push_back(elem(m_current->via.map.ptr, m_current->via.map.size));
281  start_collection = m_current->via.map.size != 0;
282  if (start_collection) {
283  if (!v.start_map_key()) return;
284  }
285  break;
286  default:
287  throw msgpack::type_error();
288  break;
289  }
290  if (m_ctx.empty()) return;
291  if (!start_collection) {
292  while (true) {
293  next_ret r = m_ctx.back().next(v);
294  if (r == finish) {
295  m_ctx.pop_back();
296  if (m_ctx.empty()) return;
297  }
298  else if (r == cont) {
299  break;
300  }
301  else {
302  // abort
303  return;
304  }
305  }
306  }
307  m_current = &m_ctx.back().get();
308  }
309  }
310 private:
311  msgpack::object const* m_current;
312  std::vector<elem> m_ctx;
313 };
314 
315 template <typename Stream>
318  :m_packer(pk) {}
319  bool visit_nil() {
320  m_packer.pack_nil();
321  return true;
322  }
323  bool visit_boolean(bool v) {
324  if (v) m_packer.pack_true();
325  else m_packer.pack_false();
326  return true;
327  }
328  bool visit_positive_integer(uint64_t v) {
329  m_packer.pack_uint64(v);
330  return true;
331  }
332  bool visit_negative_integer(int64_t v) {
333  m_packer.pack_int64(v);
334  return true;
335  }
336  bool visit_float32(float v) {
337  m_packer.pack_float(v);
338  return true;
339  }
340  bool visit_float64(double v) {
341  m_packer.pack_double(v);
342  return true;
343  }
344  bool visit_str(const char* v, uint32_t size) {
345  m_packer.pack_str(size);
346  m_packer.pack_str_body(v, size);
347  return true;
348  }
349  bool visit_bin(const char* v, uint32_t size) {
350  m_packer.pack_bin(size);
351  m_packer.pack_bin_body(v, size);
352  return true;
353  }
354  bool visit_ext(const char* v, uint32_t size) {
355  m_packer.pack_ext(size - 1, static_cast<int8_t>(*v));
356  m_packer.pack_ext_body(v + 1, size - 1);
357  return true;
358  }
359  bool start_array(uint32_t num_elements) {
360  m_packer.pack_array(num_elements);
361  return true;
362  }
364  return true;
365  }
366  bool end_array_item() {
367  return true;
368  }
369  bool end_array() {
370  return true;
371  }
372  bool start_map(uint32_t num_kv_pairs) {
373  m_packer.pack_map(num_kv_pairs);
374  return true;
375  }
376  bool start_map_key() {
377  return true;
378  }
379  bool end_map_key() {
380  return true;
381  }
383  return true;
384  }
385  bool end_map_value() {
386  return true;
387  }
388  bool end_map() {
389  return true;
390  }
391 private:
392  msgpack::packer<Stream>& m_packer;
393 };
394 
395 
397  explicit object_stringize_visitor(std::ostream& os)
398  :m_os(os) {}
399  bool visit_nil() {
400  m_os << "null";
401  return true;
402  }
403  bool visit_boolean(bool v) {
404  if (v) m_os << "true";
405  else m_os << "false";
406  return true;
407  }
408  bool visit_positive_integer(uint64_t v) {
409  m_os << v;
410  return true;
411  }
412  bool visit_negative_integer(int64_t v) {
413  m_os << v;
414  return true;
415  }
416  bool visit_float32(float v) {
417  m_os << v;
418  return true;
419  }
420  bool visit_float64(double v) {
421  m_os << v;
422  return true;
423  }
424  bool visit_str(const char* v, uint32_t size) {
425  m_os << '"';
426  for (uint32_t i = 0; i < size; ++i) {
427  char c = v[i];
428  switch (c) {
429  case '\\':
430  m_os << "\\\\";
431  break;
432  case '"':
433  m_os << "\\\"";
434  break;
435  case '/':
436  m_os << "\\/";
437  break;
438  case '\b':
439  m_os << "\\b";
440  break;
441  case '\f':
442  m_os << "\\f";
443  break;
444  case '\n':
445  m_os << "\\n";
446  break;
447  case '\r':
448  m_os << "\\r";
449  break;
450  case '\t':
451  m_os << "\\t";
452  break;
453  default: {
454  unsigned int code = static_cast<unsigned int>(c);
455  if (code < 0x20 || code == 0x7f) {
456  std::ios::fmtflags flags(m_os.flags());
457  m_os << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (code & 0xff);
458  m_os.flags(flags);
459  }
460  else {
461  m_os << c;
462  }
463  } break;
464  }
465  }
466  m_os << '"';
467  return true;
468  }
469  bool visit_bin(const char* v, uint32_t size) {
470  (m_os << '"').write(v, static_cast<std::streamsize>(size)) << '"';
471  return true;
472  }
473  bool visit_ext(const char* /*v*/, uint32_t /*size*/) {
474  m_os << "EXT";
475  return true;
476  }
477  bool start_array(uint32_t num_elements) {
478  m_current_size.push_back(num_elements);
479  m_os << "[";
480  return true;
481  }
483  return true;
484  }
485  bool end_array_item() {
486  --m_current_size.back();
487  if (m_current_size.back() != 0) {
488  m_os << ",";
489  }
490  return true;
491  }
492  bool end_array() {
493  m_current_size.pop_back();
494  m_os << "]";
495  return true;
496  }
497  bool start_map(uint32_t num_kv_pairs) {
498  m_current_size.push_back(num_kv_pairs);
499  m_os << "{";
500  return true;
501  }
502  bool start_map_key() {
503  return true;
504  }
505  bool end_map_key() {
506  m_os << ":";
507  return true;
508  }
510  return true;
511  }
512  bool end_map_value() {
513  --m_current_size.back();
514  if (m_current_size.back() != 0) {
515  m_os << ",";
516  }
517  return true;
518  }
519  bool end_map() {
520  m_current_size.pop_back();
521  m_os << "}";
522  return true;
523  }
524 private:
525  std::ostream& m_os;
526  std::vector<uint32_t> m_current_size;
527 };
528 
530  explicit aligned_zone_size_visitor(std::size_t& s)
531  :m_size(s) {}
532  bool visit_nil() {
533  return true;
534  }
535  bool visit_boolean(bool) {
536  return true;
537  }
538  bool visit_positive_integer(uint64_t) {
539  return true;
540  }
541  bool visit_negative_integer(int64_t) {
542  return true;
543  }
544  bool visit_float32(float) {
545  return true;
546  }
547  bool visit_float64(double) {
548  return true;
549  }
550  bool visit_str(const char*, uint32_t size) {
552  return true;
553  }
554  bool visit_bin(const char*, uint32_t size) {
556  return true;
557  }
558  bool visit_ext(const char*, uint32_t size) {
560  return true;
561  }
562  bool start_array(uint32_t num_elements) {
563  m_size += msgpack::aligned_size(
564  sizeof(msgpack::object) * num_elements,
566  return true;
567  }
569  return true;
570  }
571  bool end_array_item() {
572  return true;
573  }
574  bool end_array() {
575  return true;
576  }
577  bool start_map(uint32_t num_kv_pairs) {
578  m_size += msgpack::aligned_size(
579  sizeof(msgpack::object_kv) * num_kv_pairs,
581  return true;
582  }
583  bool start_map_key() {
584  return true;
585  }
586  bool end_map_key() {
587  return true;
588  }
590  return true;
591  }
592  bool end_map_value() {
593  return true;
594  }
595  bool end_map() {
596  return true;
597  }
598 private:
599  std::size_t& m_size;
600 };
601 
602 inline std::size_t aligned_zone_size(msgpack::object const& obj) {
603  std::size_t s = 0;
605  msgpack::object_parser(obj).parse(vis);
606  return s;
607 }
608 
610 
617 inline object_handle clone(msgpack::object const& obj) {
618  std::size_t size = msgpack::aligned_zone_size(obj);
619  msgpack::unique_ptr<msgpack::zone> z(size == 0 ? MSGPACK_NULLPTR : new msgpack::zone(size));
620  msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj;
621  return object_handle(newobj, msgpack::move(z));
622 }
623 
624 template <typename T>
625 inline object::implicit_type::operator T() { return obj.as<T>(); }
626 
627 namespace detail {
628 template <typename Stream, typename T>
631  v.msgpack_pack(o);
632  return o;
633  }
634 };
635 } // namespace detail
636 
637 // Adaptor functors' member functions definitions.
638 template <typename T, typename Enabler>
639 inline
640 msgpack::object const&
642  v.msgpack_unpack(o.convert());
643  return o;
644 }
645 
646 template <typename T, typename Enabler>
647 template <typename Stream>
648 inline
652 }
653 
654 template <typename T, typename Enabler>
655 inline
656 void
658  v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone);
659 }
660 
661 // Adaptor functor specialization to object
662 namespace adaptor {
663 
664 template <>
667  v = o;
668  return o;
669  }
670 };
671 
672 template <>
673 struct pack<msgpack::object> {
674  template <typename Stream>
678  return o;
679  }
680 };
681 
682 template <>
685  object_with_zone_visitor vis(o);
687  }
688 private:
689  struct object_with_zone_visitor {
690  explicit object_with_zone_visitor(msgpack::object::with_zone& owz)
691  :m_zone(owz.zone), m_ptr(&owz) {
692  m_objs.push_back(&owz);
693  }
694  bool visit_nil() {
695  m_ptr->type = msgpack::type::NIL;
696  return true;
697  }
698  bool visit_boolean(bool v) {
699  m_ptr->type = msgpack::type::BOOLEAN;
700  m_ptr->via.boolean = v;
701  return true;
702  }
703  bool visit_positive_integer(uint64_t v) {
704  m_ptr->type = msgpack::type::POSITIVE_INTEGER;
705  m_ptr->via.u64 = v;
706  return true;
707  }
708  bool visit_negative_integer(int64_t v) {
709  m_ptr->type = msgpack::type::NEGATIVE_INTEGER;
710  m_ptr->via.i64 = v;
711  return true;
712  }
713  bool visit_float32(float v) {
714  m_ptr->type = msgpack::type::FLOAT32;
715  m_ptr->via.f64 = v;
716  return true;
717  }
718  bool visit_float64(double v) {
719  m_ptr->type = msgpack::type::FLOAT64;
720  m_ptr->via.f64 = v;
721  return true;
722  }
723  bool visit_str(const char* v, uint32_t size) {
724  m_ptr->type = msgpack::type::STR;
725  m_ptr->via.str.size = size;
726  char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
727  m_ptr->via.str.ptr = ptr;
728  std::memcpy(ptr, v, size);
729  return true;
730  }
731  bool visit_bin(const char* v, uint32_t size) {
732  m_ptr->type = msgpack::type::BIN;
733  m_ptr->via.bin.size = size;
734  char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
735  m_ptr->via.bin.ptr = ptr;
736  std::memcpy(ptr, v, size);
737  return true;
738  }
739  bool visit_ext(const char* v, uint32_t size) {
740  m_ptr->type = msgpack::type::EXT;
741 
742  // v contains type but length(size) doesn't count the type byte.
743  // See https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
744  m_ptr->via.ext.size = size - 1;
745 
746  char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
747  m_ptr->via.ext.ptr = ptr;
748  std::memcpy(ptr, v, size);
749  return true;
750  }
751  bool start_array(uint32_t num_elements) {
752  m_ptr->type = msgpack::type::ARRAY;
753  m_ptr->via.array.ptr = static_cast<msgpack::object*>(
754  m_zone.allocate_align(
755  sizeof(msgpack::object) * num_elements, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
756  m_ptr->via.array.size = num_elements;
757  m_objs.push_back(elem(m_ptr->via.array.ptr));
758  return true;
759  }
760  bool start_array_item() {
761  m_ptr = m_objs.back().get_item();
762  return true;
763  }
764  bool end_array_item() {
765  ++m_objs.back().as.obj;
766  return true;
767  }
768  bool end_array() {
769  m_objs.pop_back();
770  return true;
771  }
772  bool start_map(uint32_t num_kv_pairs) {
773  m_ptr->type = msgpack::type::MAP;
774  m_ptr->via.map.ptr = (msgpack::object_kv*)m_zone.allocate_align(
776  m_ptr->via.map.size = num_kv_pairs;
777  m_objs.push_back(elem(m_ptr->via.map.ptr));
778  return true;
779  }
780  bool start_map_key() {
781  m_ptr = m_objs.back().get_key();
782  return true;
783  }
784  bool end_map_key() {
785  return true;
786  }
787  bool start_map_value() {
788  m_ptr = m_objs.back().get_val();
789  return true;
790  }
791  bool end_map_value() {
792  ++m_objs.back().as.kv;
793  return true;
794  }
795  bool end_map() {
796  m_objs.pop_back();
797  return true;
798  }
799  private:
800  struct elem {
801  elem(msgpack::object* obj)
802  :is_obj(true) {
803  as.obj = obj;
804  }
805  elem(msgpack::object_kv* kv)
806  :is_obj(false) {
807  as.kv = kv;
808  }
809  msgpack::object* get_item() {
810  return as.obj;
811  }
812  msgpack::object* get_key() {
813  return &as.kv->key;
814  }
815  msgpack::object* get_val() {
816  return &as.kv->val;
817  }
818  union {
819  msgpack::object* obj;
820  msgpack::object_kv* kv;
821  } as;
822  bool is_obj;
823  };
824  std::vector<elem> m_objs;
825  msgpack::zone& m_zone;
826  msgpack::object* m_ptr;
827  };
828 };
829 
830 // Adaptor functor specialization to object::with_zone
831 
832 template <>
833 struct object_with_zone<msgpack::object::with_zone> {
836  msgpack::object::with_zone const& v) const {
837  o << static_cast<msgpack::object const&>(v);
838  }
839 };
840 
841 
842 } // namespace adaptor
843 
844 
845 // obsolete
846 template <typename Type>
847 class define : public Type {
848 public:
849  typedef Type msgpack_type;
851  define() {}
852  define(const msgpack_type& v) : msgpack_type(v) {}
853 
854  template <typename Packer>
855  void msgpack_pack(Packer& o) const
856  {
857  msgpack::operator<<(o, static_cast<const msgpack_type&>(*this));
858  }
859 
860  void msgpack_unpack(object const& o)
861  {
862  msgpack::operator>>(o, static_cast<msgpack_type&>(*this));
863  }
864 };
865 
866 // deconvert operator
867 
868 template <typename Stream>
869 template <typename T>
871 {
872  msgpack::operator<<(*this, v);
873  return *this;
874 }
875 
877  object_equal_visitor(msgpack::object const& obj, bool& result)
878  :m_ptr(&obj), m_result(result) {}
879  bool visit_nil() {
880  if (m_ptr->type != msgpack::type::NIL) {
881  m_result = false;
882  return false;
883  }
884  return true;
885  }
886  bool visit_boolean(bool v) {
887  if (m_ptr->type != msgpack::type::BOOLEAN || m_ptr->via.boolean != v) {
888  m_result = false;
889  return false;
890  }
891  return true;
892  }
893  bool visit_positive_integer(uint64_t v) {
894  if (m_ptr->type != msgpack::type::POSITIVE_INTEGER || m_ptr->via.u64 != v) {
895  m_result = false;
896  return false;
897  }
898  return true;
899  }
900  bool visit_negative_integer(int64_t v) {
901  if (m_ptr->type != msgpack::type::NEGATIVE_INTEGER || m_ptr->via.i64 != v) {
902  m_result = false;
903  return false;
904  }
905  return true;
906  }
907  bool visit_float32(float v) {
908  if (m_ptr->type != msgpack::type::FLOAT32 || m_ptr->via.f64 != v) {
909  m_result = false;
910  return false;
911  }
912  return true;
913  }
914  bool visit_float64(double v) {
915  if (m_ptr->type != msgpack::type::FLOAT64 || m_ptr->via.f64 != v) {
916  m_result = false;
917  return false;
918  }
919  return true;
920  }
921  bool visit_str(const char* v, uint32_t size) {
922  if (m_ptr->type != msgpack::type::STR ||
923  m_ptr->via.str.size != size ||
924  std::memcmp(m_ptr->via.str.ptr, v, size) != 0) {
925  m_result = false;
926  return false;
927  }
928  return true;
929  }
930  bool visit_bin(const char* v, uint32_t size) {
931  if (m_ptr->type != msgpack::type::BIN ||
932  m_ptr->via.bin.size != size ||
933  std::memcmp(m_ptr->via.bin.ptr, v, size) != 0) {
934  m_result = false;
935  return false;
936  }
937  return true;
938  }
939  bool visit_ext(const char* v, uint32_t size) {
940  if (m_ptr->type != msgpack::type::EXT ||
941  m_ptr->via.ext.size != size - 1 ||
942  std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) {
943  m_result = false;
944  return false;
945  }
946  return true;
947  }
948  bool start_array(uint32_t num_elements) {
949  if (m_ptr->type != msgpack::type::ARRAY ||
950  m_ptr->via.array.size != num_elements) {
951  m_result = false;
952  return false;
953  }
954  m_objs.push_back(elem(m_ptr->via.array.ptr));
955  return true;
956  }
958  m_ptr = m_objs.back().get_item();
959  return true;
960  }
961  bool end_array_item() {
962  ++m_objs.back().as.obj;
963  return true;
964  }
965  bool end_array() {
966  m_objs.pop_back();
967  return true;
968  }
969  bool start_map(uint32_t num_kv_pairs) {
970  if (m_ptr->type != msgpack::type::MAP ||
971  m_ptr->via.array.size != num_kv_pairs) {
972  m_result = false;
973  return false;
974  }
975  m_objs.push_back(elem(m_ptr->via.map.ptr));
976  return true;
977  }
978  bool start_map_key() {
979  m_ptr = m_objs.back().get_key();
980  return true;
981  }
982  bool end_map_key() {
983  return true;
984  }
986  m_ptr = m_objs.back().get_val();
987  return true;
988  }
989  bool end_map_value() {
990  ++m_objs.back().as.kv;
991  return true;
992  }
993  bool end_map() {
994  m_objs.pop_back();
995  return true;
996  }
997 private:
998  struct elem {
999  elem(msgpack::object const* obj)
1000  :is_obj(true) {
1001  as.obj = obj;
1002  }
1003  elem(msgpack::object_kv const* kv)
1004  :is_obj(false) {
1005  as.kv = kv;
1006  }
1007  msgpack::object const* get_item() {
1008  return as.obj;
1009  }
1010  msgpack::object const* get_key() {
1011  return &as.kv->key;
1012  }
1013  msgpack::object const* get_val() {
1014  return &as.kv->val;
1015  }
1016  union {
1017  msgpack::object const* obj;
1018  msgpack::object_kv const* kv;
1019  } as;
1020  bool is_obj;
1021  };
1022  std::vector<elem> m_objs;
1023  msgpack::object const* m_ptr;
1024  bool& m_result;
1025 };
1026 
1027 inline bool operator==(const msgpack::object& x, const msgpack::object& y)
1028 {
1029  if(x.type != y.type) { return false; }
1030  bool b = true;
1031  object_equal_visitor vis(y, b);
1032  msgpack::object_parser(x).parse(vis);
1033  return b;
1034 }
1035 
1036 template <typename T>
1037 inline bool operator==(const msgpack::object& x, const T& y)
1038 try {
1039  return x == msgpack::object(y);
1040 } catch (msgpack::type_error&) {
1041  return false;
1042 }
1043 
1044 inline bool operator!=(const msgpack::object& x, const msgpack::object& y)
1045 { return !(x == y); }
1046 
1047 template <typename T>
1048 inline bool operator==(const T& y, const msgpack::object& x)
1049 { return x == y; }
1050 
1051 template <typename T>
1052 inline bool operator!=(const msgpack::object& x, const T& y)
1053 { return !(x == y); }
1054 
1055 template <typename T>
1056 inline bool operator!=(const T& y, const msgpack::object& x)
1057 { return x != y; }
1058 
1059 
1061 {
1062  return object::implicit_type(*this);
1063 }
1064 
1065 template <typename T>
1066 inline
1067 typename msgpack::enable_if<
1068  !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value,
1069  T&
1070 >::type
1071 object::convert(T& v) const
1072 {
1073  msgpack::operator>>(*this, v);
1074  return v;
1075 }
1076 
1077 template <typename T, std::size_t N>
1078 inline T(&object::convert(T(&v)[N]) const)[N]
1079 {
1080  msgpack::operator>>(*this, v);
1081  return v;
1082 }
1083 
1084 #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
1085 template <typename T>
1086 inline
1087 typename msgpack::enable_if<
1088  msgpack::is_pointer<T>::value,
1089  T
1090 >::type
1092 {
1093  convert(*v);
1094  return v;
1095 }
1096 #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
1097 
1098 template <typename T>
1099 inline bool object::convert_if_not_nil(T& v) const
1100 {
1101  if (is_nil()) {
1102  return false;
1103  }
1104  convert(v);
1105  return true;
1106 }
1107 
1108 #if defined(MSGPACK_USE_CPP03)
1109 
1110 template <typename T>
1111 inline T object::as() const
1112 {
1113  T v;
1114  convert(v);
1115  return v;
1116 }
1117 
1118 #else // defined(MSGPACK_USE_CPP03)
1119 
1120 template <typename T>
1121 inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const {
1122  return msgpack::adaptor::as<T>()(*this);
1123 }
1124 
1125 template <typename T>
1126 inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const {
1127  T v;
1128  convert(v);
1129  return v;
1130 }
1131 
1132 #endif // defined(MSGPACK_USE_CPP03)
1133 
1135 {
1137 }
1138 
1139 template <typename T>
1140 inline object::object(const T& v)
1141 {
1142  *this << v;
1143 }
1144 
1145 template <typename T>
1146 inline object& object::operator=(const T& v)
1147 {
1148  *this = object(v);
1149  return *this;
1150 }
1151 
1152 template <typename T>
1153 inline object::object(const T& v, msgpack::zone& z)
1154 {
1155  with_zone oz(z);
1156  msgpack::operator<<(oz, v);
1157  type = oz.type;
1158  via = oz.via;
1159 }
1160 
1161 template <typename T>
1162 inline object::object(const T& v, msgpack::zone* z)
1163 {
1164  with_zone oz(*z);
1165  msgpack::operator<<(oz, v);
1166  type = oz.type;
1167  via = oz.via;
1168 }
1169 
1170 
1171 // obsolete
1172 template <typename T>
1173 inline void convert(T& v, msgpack::object const& o)
1174 {
1175  o.convert(v);
1176 }
1177 
1178 // obsolete
1179 template <typename Stream, typename T>
1180 inline void pack(msgpack::packer<Stream>& o, const T& v)
1181 {
1182  o.pack(v);
1183 }
1184 
1185 // obsolete
1186 template <typename Stream, typename T>
1188 {
1189  pack(o, v);
1190 }
1191 
1192 template <typename Stream>
1194 {
1195  object_pack_visitor<Stream> vis(o);
1196  msgpack::object_parser(v).parse(vis);
1197  return o;
1198 }
1199 
1200 template <typename Stream>
1202 {
1203  return o << static_cast<msgpack::object>(v);
1204 }
1205 
1206 inline std::ostream& operator<< (std::ostream& s, const msgpack::object& v)
1207 {
1208  object_stringize_visitor vis(s);
1209  msgpack::object_parser(v).parse(vis);
1210  return s;
1211 }
1212 
1214 } // MSGPACK_API_VERSION_NAMESPACE(v1)
1216 
1217 } // namespace msgpack
1218 
1219 #endif // MSGPACK_V1_OBJECT_HPP
Definition: object.hpp:847
define()
Definition: object.hpp:851
define(const msgpack_type &v)
Definition: object.hpp:852
void msgpack_pack(Packer &o) const
Definition: object.hpp:855
void msgpack_unpack(object const &o)
Definition: object.hpp:860
define< Type > define_type
Definition: object.hpp:850
Type msgpack_type
Definition: object.hpp:849
The class holds object and zone.
Definition: object.hpp:44
object_handle(msgpack::object const &obj, msgpack::unique_ptr< msgpack::zone > &&z)
Constructor that creates an object_handle holding object obj and zone z.
Definition: object.hpp:54
const msgpack::object & get() const
Get object reference.
Definition: object.hpp:71
const msgpack::unique_ptr< msgpack::zone > & zone() const
Get unique_ptr const reference of zone.
Definition: object.hpp:97
const msgpack::object * operator->() const
Definition: object.hpp:83
const msgpack::object & operator*() const
Definition: object.hpp:77
msgpack::unique_ptr< msgpack::zone > & zone()
Get unique_ptr reference of zone.
Definition: object.hpp:90
void set(msgpack::object const &obj)
Definition: object.hpp:64
object_handle()
Constructor that creates nil object and null zone.
Definition: object.hpp:47
Definition: object.hpp:151
void parse(Visitor &v)
Definition: object.hpp:238
object_parser(msgpack::object const &obj)
Definition: object.hpp:236
The class template that supports continuous packing.
Definition: pack.hpp:33
packer< Stream > & pack(const T &v)
Packing function template.
Definition: object_fwd.hpp:231
Definition: cpp03_zone.hpp:31
#define MSGPACK_USE_CPP03
Definition: cpp_version.hpp:9
std::size_t add_ext_type_size< 4 >(std::size_t size)
Definition: object.hpp:146
std::size_t add_ext_type_size(std::size_t size)
Definition: object.hpp:141
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
@ EXT
Definition: object_fwd_decl.hpp:42
@ FLOAT64
Definition: object_fwd_decl.hpp:33
@ BOOLEAN
Definition: object_fwd_decl.hpp:29
@ MAP
Definition: object_fwd_decl.hpp:41
@ NIL
Definition: object_fwd_decl.hpp:28
@ STR
Definition: object_fwd_decl.hpp:38
@ ARRAY
Definition: object_fwd_decl.hpp:40
@ BIN
Definition: object_fwd_decl.hpp:39
@ POSITIVE_INTEGER
Definition: object_fwd_decl.hpp:30
@ NEGATIVE_INTEGER
Definition: object_fwd_decl.hpp:31
@ FLOAT32
Definition: object_fwd_decl.hpp:32
Definition: adaptor_base.hpp:15
void pack(msgpack::packer< Stream > &o, const T &v)
Definition: object.hpp:1180
bool operator==(const msgpack::object &x, const msgpack::object &y)
Definition: object.hpp:1027
std::size_t aligned_size(std::size_t size, std::size_t align)
Definition: cpp03_zone.hpp:354
msgpack::enable_if< !is_array< T >::value, msgpack::packer< Stream > & >::type operator<<(msgpack::packer< Stream > &o, T const &v)
Definition: adaptor_base.hpp:72
void pack_copy(msgpack::packer< Stream > &o, T v)
Definition: object.hpp:1187
object_handle clone(msgpack::object const &obj)
clone object
Definition: object.hpp:617
std::size_t aligned_zone_size(msgpack::object const &obj)
Definition: object.hpp:602
void convert(T &v, msgpack::object const &o)
Definition: object.hpp:1173
bool operator!=(const msgpack::object &x, const msgpack::object &y)
Definition: object.hpp:1044
msgpack::enable_if< !is_array< T >::value, msgpack::object const & >::type operator>>(msgpack::object const &o, T &v)
Definition: adaptor_base.hpp:57
Definition: object_fwd_decl.hpp:61
msgpack::object const & operator()(msgpack::object const &o, msgpack::object &v) const
Definition: object.hpp:666
Definition: adaptor_base.hpp:27
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: object.hpp:641
void operator()(msgpack::object::with_zone &o, msgpack::object const &v) const
Definition: object.hpp:684
void operator()(msgpack::object::with_zone &o, msgpack::object::with_zone const &v) const
Definition: object.hpp:834
Definition: adaptor_base.hpp:43
void operator()(msgpack::object::with_zone &o, T const &v) const
Definition: object.hpp:657
Definition: adaptor_base.hpp:38
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, msgpack::object const &v) const
Definition: object.hpp:675
Definition: adaptor_base.hpp:32
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, T const &v) const
Definition: object.hpp:650
Definition: object.hpp:529
bool visit_nil()
Definition: object.hpp:532
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:577
bool end_map()
Definition: object.hpp:595
bool visit_ext(const char *, uint32_t size)
Definition: object.hpp:558
bool start_map_key()
Definition: object.hpp:583
bool start_map_value()
Definition: object.hpp:589
bool visit_bin(const char *, uint32_t size)
Definition: object.hpp:554
bool visit_float32(float)
Definition: object.hpp:544
bool end_array()
Definition: object.hpp:574
aligned_zone_size_visitor(std::size_t &s)
Definition: object.hpp:530
bool start_array(uint32_t num_elements)
Definition: object.hpp:562
bool visit_boolean(bool)
Definition: object.hpp:535
bool start_array_item()
Definition: object.hpp:568
bool visit_negative_integer(int64_t)
Definition: object.hpp:541
bool visit_str(const char *, uint32_t size)
Definition: object.hpp:550
bool end_array_item()
Definition: object.hpp:571
bool end_map_key()
Definition: object.hpp:586
bool end_map_value()
Definition: object.hpp:592
bool visit_float64(double)
Definition: object.hpp:547
bool visit_positive_integer(uint64_t)
Definition: object.hpp:538
Definition: object.hpp:629
static msgpack::packer< Stream > & pack(msgpack::packer< Stream > &o, const T &v)
Definition: object.hpp:630
Definition: object_fwd.hpp:233
Definition: object.hpp:35
with_zone(msgpack::zone &z)
Definition: object.hpp:36
msgpack::zone & zone
Definition: object.hpp:37
uint32_t size
Definition: object_fwd.hpp:23
msgpack::object * ptr
Definition: object_fwd.hpp:24
uint32_t size
Definition: object_fwd.hpp:38
const char * ptr
Definition: object_fwd.hpp:39
Definition: object.hpp:876
bool start_map_key()
Definition: object.hpp:978
bool visit_ext(const char *v, uint32_t size)
Definition: object.hpp:939
bool end_array_item()
Definition: object.hpp:961
bool visit_str(const char *v, uint32_t size)
Definition: object.hpp:921
bool visit_boolean(bool v)
Definition: object.hpp:886
bool visit_bin(const char *v, uint32_t size)
Definition: object.hpp:930
bool start_map_value()
Definition: object.hpp:985
bool start_array_item()
Definition: object.hpp:957
bool visit_nil()
Definition: object.hpp:879
bool visit_negative_integer(int64_t v)
Definition: object.hpp:900
bool visit_positive_integer(uint64_t v)
Definition: object.hpp:893
bool end_map_value()
Definition: object.hpp:989
bool visit_float64(double v)
Definition: object.hpp:914
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:969
bool start_array(uint32_t num_elements)
Definition: object.hpp:948
bool visit_float32(float v)
Definition: object.hpp:907
object_equal_visitor(msgpack::object const &obj, bool &result)
Definition: object.hpp:877
bool end_map_key()
Definition: object.hpp:982
bool end_array()
Definition: object.hpp:965
bool end_map()
Definition: object.hpp:993
const char * ptr
Definition: object_fwd.hpp:46
uint32_t size
Definition: object_fwd.hpp:45
Definition: object.hpp:30
msgpack::object val
Definition: object.hpp:32
msgpack::object key
Definition: object.hpp:31
uint32_t size
Definition: object_fwd.hpp:28
msgpack::object_kv * ptr
Definition: object_fwd.hpp:29
Definition: object.hpp:316
bool start_map_value()
Definition: object.hpp:382
object_pack_visitor(msgpack::packer< Stream > &pk)
Definition: object.hpp:317
bool visit_float32(float v)
Definition: object.hpp:336
bool start_array_item()
Definition: object.hpp:363
bool visit_float64(double v)
Definition: object.hpp:340
bool end_map_key()
Definition: object.hpp:379
bool end_map()
Definition: object.hpp:388
bool end_map_value()
Definition: object.hpp:385
bool visit_boolean(bool v)
Definition: object.hpp:323
bool end_array()
Definition: object.hpp:369
bool visit_negative_integer(int64_t v)
Definition: object.hpp:332
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:372
bool start_map_key()
Definition: object.hpp:376
bool end_array_item()
Definition: object.hpp:366
bool visit_bin(const char *v, uint32_t size)
Definition: object.hpp:349
bool start_array(uint32_t num_elements)
Definition: object.hpp:359
bool visit_positive_integer(uint64_t v)
Definition: object.hpp:328
bool visit_ext(const char *v, uint32_t size)
Definition: object.hpp:354
bool visit_nil()
Definition: object.hpp:319
bool visit_str(const char *v, uint32_t size)
Definition: object.hpp:344
const char * ptr
Definition: object_fwd.hpp:34
uint32_t size
Definition: object_fwd.hpp:33
Definition: object.hpp:396
bool end_map_value()
Definition: object.hpp:512
bool start_array(uint32_t num_elements)
Definition: object.hpp:477
bool start_map_value()
Definition: object.hpp:509
bool visit_str(const char *v, uint32_t size)
Definition: object.hpp:424
bool end_array()
Definition: object.hpp:492
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:497
bool visit_boolean(bool v)
Definition: object.hpp:403
bool visit_ext(const char *, uint32_t)
Definition: object.hpp:473
bool visit_negative_integer(int64_t v)
Definition: object.hpp:412
bool visit_float32(float v)
Definition: object.hpp:416
object_stringize_visitor(std::ostream &os)
Definition: object.hpp:397
bool end_array_item()
Definition: object.hpp:485
bool start_map_key()
Definition: object.hpp:502
bool end_map()
Definition: object.hpp:519
bool visit_bin(const char *v, uint32_t size)
Definition: object.hpp:469
bool visit_float64(double v)
Definition: object.hpp:420
bool end_map_key()
Definition: object.hpp:505
bool visit_positive_integer(uint64_t v)
Definition: object.hpp:408
bool start_array_item()
Definition: object.hpp:482
bool visit_nil()
Definition: object.hpp:399
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
object()
Default constructor. The object is set to nil.
Definition: object.hpp:1134
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition: object.hpp:1121
implicit_type convert() const
Definition: object.hpp:1060
union_type via
Definition: object_fwd.hpp:93
msgpack::enable_if< !msgpack::is_array< T >::value &&!msgpack::is_pointer< T >::value, T & >::type convert(T &v) const
Convert the object.
Definition: object.hpp:1071
bool convert_if_not_nil(T &v) const
Convert the object if not nil.
Definition: object.hpp:1099
msgpack::type::object_type type
Definition: object_fwd.hpp:92
bool is_nil() const
Cheking nil.
Definition: object_fwd.hpp:99
object & operator=(const T &v)
Definition: object.hpp:1146
bool boolean
Definition: object_fwd.hpp:77
msgpack::object_array array
Definition: object_fwd.hpp:85
msgpack::object_ext ext
Definition: object_fwd.hpp:89
msgpack::object_str str
Definition: object_fwd.hpp:87
uint64_t u64
Definition: object_fwd.hpp:78
int64_t i64
Definition: object_fwd.hpp:79
msgpack::object_bin bin
Definition: object_fwd.hpp:88
double f64
Definition: object_fwd.hpp:84
msgpack::object_map map
Definition: object_fwd.hpp:86
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:85
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66