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 << "\"BIN(size:" << size << ")\"";
471  return true;
472  }
473  bool visit_ext(const char* v, uint32_t size) {
474  if (size == 0) {
475  m_os << "\"EXT(size:0)\"";
476  }
477  else {
478  m_os << "\"EXT(type:" << static_cast<int>(v[0]) << ",size:" << size - 1 << ")\"";
479  }
480  return true;
481  }
482  bool start_array(uint32_t num_elements) {
483  m_current_size.push_back(num_elements);
484  m_os << "[";
485  return true;
486  }
488  return true;
489  }
490  bool end_array_item() {
491  --m_current_size.back();
492  if (m_current_size.back() != 0) {
493  m_os << ",";
494  }
495  return true;
496  }
497  bool end_array() {
498  m_current_size.pop_back();
499  m_os << "]";
500  return true;
501  }
502  bool start_map(uint32_t num_kv_pairs) {
503  m_current_size.push_back(num_kv_pairs);
504  m_os << "{";
505  return true;
506  }
507  bool start_map_key() {
508  return true;
509  }
510  bool end_map_key() {
511  m_os << ":";
512  return true;
513  }
515  return true;
516  }
517  bool end_map_value() {
518  --m_current_size.back();
519  if (m_current_size.back() != 0) {
520  m_os << ",";
521  }
522  return true;
523  }
524  bool end_map() {
525  m_current_size.pop_back();
526  m_os << "}";
527  return true;
528  }
529 private:
530  std::ostream& m_os;
531  std::vector<uint32_t> m_current_size;
532 };
533 
535  explicit aligned_zone_size_visitor(std::size_t& s)
536  :m_size(s) {}
537  bool visit_nil() {
538  return true;
539  }
540  bool visit_boolean(bool) {
541  return true;
542  }
543  bool visit_positive_integer(uint64_t) {
544  return true;
545  }
546  bool visit_negative_integer(int64_t) {
547  return true;
548  }
549  bool visit_float32(float) {
550  return true;
551  }
552  bool visit_float64(double) {
553  return true;
554  }
555  bool visit_str(const char*, uint32_t size) {
557  return true;
558  }
559  bool visit_bin(const char*, uint32_t size) {
561  return true;
562  }
563  bool visit_ext(const char*, uint32_t size) {
565  return true;
566  }
567  bool start_array(uint32_t num_elements) {
568  m_size += msgpack::aligned_size(
569  sizeof(msgpack::object) * num_elements,
571  return true;
572  }
574  return true;
575  }
576  bool end_array_item() {
577  return true;
578  }
579  bool end_array() {
580  return true;
581  }
582  bool start_map(uint32_t num_kv_pairs) {
583  m_size += msgpack::aligned_size(
584  sizeof(msgpack::object_kv) * num_kv_pairs,
586  return true;
587  }
588  bool start_map_key() {
589  return true;
590  }
591  bool end_map_key() {
592  return true;
593  }
595  return true;
596  }
597  bool end_map_value() {
598  return true;
599  }
600  bool end_map() {
601  return true;
602  }
603 private:
604  std::size_t& m_size;
605 };
606 
607 inline std::size_t aligned_zone_size(msgpack::object const& obj) {
608  std::size_t s = 0;
610  msgpack::object_parser(obj).parse(vis);
611  return s;
612 }
613 
615 
622 inline object_handle clone(msgpack::object const& obj) {
623  std::size_t size = msgpack::aligned_zone_size(obj);
624  msgpack::unique_ptr<msgpack::zone> z(size == 0 ? MSGPACK_NULLPTR : new msgpack::zone(size));
625  msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj;
626  return object_handle(newobj, msgpack::move(z));
627 }
628 
629 template <typename T>
630 inline object::implicit_type::operator T() { return obj.as<T>(); }
631 
632 namespace detail {
633 template <typename Stream, typename T>
636  v.msgpack_pack(o);
637  return o;
638  }
639 };
640 } // namespace detail
641 
642 // Adaptor functors' member functions definitions.
643 template <typename T, typename Enabler>
644 inline
645 msgpack::object const&
647  v.msgpack_unpack(o.convert());
648  return o;
649 }
650 
651 template <typename T, typename Enabler>
652 template <typename Stream>
653 inline
657 }
658 
659 template <typename T, typename Enabler>
660 inline
661 void
663  v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone);
664 }
665 
666 // Adaptor functor specialization to object
667 namespace adaptor {
668 
669 template <>
672  v = o;
673  return o;
674  }
675 };
676 
677 template <>
678 struct pack<msgpack::object> {
679  template <typename Stream>
683  return o;
684  }
685 };
686 
687 template <>
690  object_with_zone_visitor vis(o);
692  }
693 private:
694  struct object_with_zone_visitor {
695  explicit object_with_zone_visitor(msgpack::object::with_zone& owz)
696  :m_zone(owz.zone), m_ptr(&owz) {
697  m_objs.push_back(&owz);
698  }
699  bool visit_nil() {
700  m_ptr->type = msgpack::type::NIL;
701  return true;
702  }
703  bool visit_boolean(bool v) {
704  m_ptr->type = msgpack::type::BOOLEAN;
705  m_ptr->via.boolean = v;
706  return true;
707  }
708  bool visit_positive_integer(uint64_t v) {
709  m_ptr->type = msgpack::type::POSITIVE_INTEGER;
710  m_ptr->via.u64 = v;
711  return true;
712  }
713  bool visit_negative_integer(int64_t v) {
714  m_ptr->type = msgpack::type::NEGATIVE_INTEGER;
715  m_ptr->via.i64 = v;
716  return true;
717  }
718  bool visit_float32(float v) {
719  m_ptr->type = msgpack::type::FLOAT32;
720  m_ptr->via.f64 = v;
721  return true;
722  }
723  bool visit_float64(double v) {
724  m_ptr->type = msgpack::type::FLOAT64;
725  m_ptr->via.f64 = v;
726  return true;
727  }
728  bool visit_str(const char* v, uint32_t size) {
729  m_ptr->type = msgpack::type::STR;
730  m_ptr->via.str.size = size;
731  char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
732  m_ptr->via.str.ptr = ptr;
733  std::memcpy(ptr, v, size);
734  return true;
735  }
736  bool visit_bin(const char* v, uint32_t size) {
737  m_ptr->type = msgpack::type::BIN;
738  m_ptr->via.bin.size = size;
739  char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
740  m_ptr->via.bin.ptr = ptr;
741  std::memcpy(ptr, v, size);
742  return true;
743  }
744  bool visit_ext(const char* v, uint32_t size) {
745  m_ptr->type = msgpack::type::EXT;
746 
747  // v contains type but length(size) doesn't count the type byte.
748  // See https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
749  m_ptr->via.ext.size = size - 1;
750 
751  char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
752  m_ptr->via.ext.ptr = ptr;
753  std::memcpy(ptr, v, size);
754  return true;
755  }
756  bool start_array(uint32_t num_elements) {
757  m_ptr->type = msgpack::type::ARRAY;
758  m_ptr->via.array.ptr = static_cast<msgpack::object*>(
759  m_zone.allocate_align(
760  sizeof(msgpack::object) * num_elements, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
761  m_ptr->via.array.size = num_elements;
762  m_objs.push_back(elem(m_ptr->via.array.ptr));
763  return true;
764  }
765  bool start_array_item() {
766  m_ptr = m_objs.back().get_item();
767  return true;
768  }
769  bool end_array_item() {
770  ++m_objs.back().as.obj;
771  return true;
772  }
773  bool end_array() {
774  m_objs.pop_back();
775  return true;
776  }
777  bool start_map(uint32_t num_kv_pairs) {
778  m_ptr->type = msgpack::type::MAP;
779  m_ptr->via.map.ptr = (msgpack::object_kv*)m_zone.allocate_align(
781  m_ptr->via.map.size = num_kv_pairs;
782  m_objs.push_back(elem(m_ptr->via.map.ptr));
783  return true;
784  }
785  bool start_map_key() {
786  m_ptr = m_objs.back().get_key();
787  return true;
788  }
789  bool end_map_key() {
790  return true;
791  }
792  bool start_map_value() {
793  m_ptr = m_objs.back().get_val();
794  return true;
795  }
796  bool end_map_value() {
797  ++m_objs.back().as.kv;
798  return true;
799  }
800  bool end_map() {
801  m_objs.pop_back();
802  return true;
803  }
804  private:
805  struct elem {
806  elem(msgpack::object* obj)
807  :is_obj(true) {
808  as.obj = obj;
809  }
810  elem(msgpack::object_kv* kv)
811  :is_obj(false) {
812  as.kv = kv;
813  }
814  msgpack::object* get_item() {
815  return as.obj;
816  }
817  msgpack::object* get_key() {
818  return &as.kv->key;
819  }
820  msgpack::object* get_val() {
821  return &as.kv->val;
822  }
823  union {
824  msgpack::object* obj;
825  msgpack::object_kv* kv;
826  } as;
827  bool is_obj;
828  };
829  std::vector<elem> m_objs;
830  msgpack::zone& m_zone;
831  msgpack::object* m_ptr;
832  };
833 };
834 
835 // Adaptor functor specialization to object::with_zone
836 
837 template <>
838 struct object_with_zone<msgpack::object::with_zone> {
841  msgpack::object::with_zone const& v) const {
842  o << static_cast<msgpack::object const&>(v);
843  }
844 };
845 
846 
847 } // namespace adaptor
848 
849 
850 // obsolete
851 template <typename Type>
852 class define : public Type {
853 public:
854  typedef Type msgpack_type;
856  define() {}
857  define(const msgpack_type& v) : msgpack_type(v) {}
858 
859  template <typename Packer>
860  void msgpack_pack(Packer& o) const
861  {
862  msgpack::operator<<(o, static_cast<const msgpack_type&>(*this));
863  }
864 
865  void msgpack_unpack(object const& o)
866  {
867  msgpack::operator>>(o, static_cast<msgpack_type&>(*this));
868  }
869 };
870 
871 // deconvert operator
872 
873 template <typename Stream>
874 template <typename T>
876 {
877  msgpack::operator<<(*this, v);
878  return *this;
879 }
880 
882  object_equal_visitor(msgpack::object const& obj, bool& result)
883  :m_ptr(&obj), m_result(result) {}
884  bool visit_nil() {
885  if (m_ptr->type != msgpack::type::NIL) {
886  m_result = false;
887  return false;
888  }
889  return true;
890  }
891  bool visit_boolean(bool v) {
892  if (m_ptr->type != msgpack::type::BOOLEAN || m_ptr->via.boolean != v) {
893  m_result = false;
894  return false;
895  }
896  return true;
897  }
898  bool visit_positive_integer(uint64_t v) {
899  if (m_ptr->type != msgpack::type::POSITIVE_INTEGER || m_ptr->via.u64 != v) {
900  m_result = false;
901  return false;
902  }
903  return true;
904  }
905  bool visit_negative_integer(int64_t v) {
906  if (m_ptr->type != msgpack::type::NEGATIVE_INTEGER || m_ptr->via.i64 != v) {
907  m_result = false;
908  return false;
909  }
910  return true;
911  }
912  bool visit_float32(float v) {
913  if (m_ptr->type != msgpack::type::FLOAT32 || m_ptr->via.f64 != v) {
914  m_result = false;
915  return false;
916  }
917  return true;
918  }
919  bool visit_float64(double v) {
920  if (m_ptr->type != msgpack::type::FLOAT64 || m_ptr->via.f64 != v) {
921  m_result = false;
922  return false;
923  }
924  return true;
925  }
926  bool visit_str(const char* v, uint32_t size) {
927  if (m_ptr->type != msgpack::type::STR ||
928  m_ptr->via.str.size != size ||
929  std::memcmp(m_ptr->via.str.ptr, v, size) != 0) {
930  m_result = false;
931  return false;
932  }
933  return true;
934  }
935  bool visit_bin(const char* v, uint32_t size) {
936  if (m_ptr->type != msgpack::type::BIN ||
937  m_ptr->via.bin.size != size ||
938  std::memcmp(m_ptr->via.bin.ptr, v, size) != 0) {
939  m_result = false;
940  return false;
941  }
942  return true;
943  }
944  bool visit_ext(const char* v, uint32_t size) {
945  if (m_ptr->type != msgpack::type::EXT ||
946  m_ptr->via.ext.size != size - 1 ||
947  std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) {
948  m_result = false;
949  return false;
950  }
951  return true;
952  }
953  bool start_array(uint32_t num_elements) {
954  if (m_ptr->type != msgpack::type::ARRAY ||
955  m_ptr->via.array.size != num_elements) {
956  m_result = false;
957  return false;
958  }
959  m_objs.push_back(elem(m_ptr->via.array.ptr));
960  return true;
961  }
963  m_ptr = m_objs.back().get_item();
964  return true;
965  }
966  bool end_array_item() {
967  ++m_objs.back().as.obj;
968  return true;
969  }
970  bool end_array() {
971  m_objs.pop_back();
972  return true;
973  }
974  bool start_map(uint32_t num_kv_pairs) {
975  if (m_ptr->type != msgpack::type::MAP ||
976  m_ptr->via.array.size != num_kv_pairs) {
977  m_result = false;
978  return false;
979  }
980  m_objs.push_back(elem(m_ptr->via.map.ptr));
981  return true;
982  }
983  bool start_map_key() {
984  m_ptr = m_objs.back().get_key();
985  return true;
986  }
987  bool end_map_key() {
988  return true;
989  }
991  m_ptr = m_objs.back().get_val();
992  return true;
993  }
994  bool end_map_value() {
995  ++m_objs.back().as.kv;
996  return true;
997  }
998  bool end_map() {
999  m_objs.pop_back();
1000  return true;
1001  }
1002 private:
1003  struct elem {
1004  elem(msgpack::object const* obj)
1005  :is_obj(true) {
1006  as.obj = obj;
1007  }
1008  elem(msgpack::object_kv const* kv)
1009  :is_obj(false) {
1010  as.kv = kv;
1011  }
1012  msgpack::object const* get_item() {
1013  return as.obj;
1014  }
1015  msgpack::object const* get_key() {
1016  return &as.kv->key;
1017  }
1018  msgpack::object const* get_val() {
1019  return &as.kv->val;
1020  }
1021  union {
1022  msgpack::object const* obj;
1023  msgpack::object_kv const* kv;
1024  } as;
1025  bool is_obj;
1026  };
1027  std::vector<elem> m_objs;
1028  msgpack::object const* m_ptr;
1029  bool& m_result;
1030 };
1031 
1032 inline bool operator==(const msgpack::object& x, const msgpack::object& y)
1033 {
1034  if(x.type != y.type) { return false; }
1035  bool b = true;
1036  object_equal_visitor vis(y, b);
1037  msgpack::object_parser(x).parse(vis);
1038  return b;
1039 }
1040 
1041 template <typename T>
1042 inline bool operator==(const msgpack::object& x, const T& y)
1043 try {
1044  return x == msgpack::object(y);
1045 } catch (msgpack::type_error&) {
1046  return false;
1047 }
1048 
1049 inline bool operator!=(const msgpack::object& x, const msgpack::object& y)
1050 { return !(x == y); }
1051 
1052 template <typename T>
1053 inline bool operator==(const T& y, const msgpack::object& x)
1054 { return x == y; }
1055 
1056 template <typename T>
1057 inline bool operator!=(const msgpack::object& x, const T& y)
1058 { return !(x == y); }
1059 
1060 template <typename T>
1061 inline bool operator!=(const T& y, const msgpack::object& x)
1062 { return x != y; }
1063 
1064 
1066 {
1067  return object::implicit_type(*this);
1068 }
1069 
1070 template <typename T>
1071 inline
1072 typename msgpack::enable_if<
1073  !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value,
1074  T&
1075 >::type
1076 object::convert(T& v) const
1077 {
1078  msgpack::operator>>(*this, v);
1079  return v;
1080 }
1081 
1082 template <typename T, std::size_t N>
1083 inline T(&object::convert(T(&v)[N]) const)[N]
1084 {
1085  msgpack::operator>>(*this, v);
1086  return v;
1087 }
1088 
1089 #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
1090 template <typename T>
1091 inline
1092 typename msgpack::enable_if<
1093  msgpack::is_pointer<T>::value,
1094  T
1095 >::type
1097 {
1098  convert(*v);
1099  return v;
1100 }
1101 #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
1102 
1103 template <typename T>
1104 inline bool object::convert_if_not_nil(T& v) const
1105 {
1106  if (is_nil()) {
1107  return false;
1108  }
1109  convert(v);
1110  return true;
1111 }
1112 
1113 #if defined(MSGPACK_USE_CPP03)
1114 
1115 template <typename T>
1116 inline T object::as() const
1117 {
1118  T v;
1119  convert(v);
1120  return v;
1121 }
1122 
1123 #else // defined(MSGPACK_USE_CPP03)
1124 
1125 template <typename T>
1126 inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const {
1127  return msgpack::adaptor::as<T>()(*this);
1128 }
1129 
1130 template <typename T>
1131 inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const {
1132  T v;
1133  convert(v);
1134  return v;
1135 }
1136 
1137 #endif // defined(MSGPACK_USE_CPP03)
1138 
1140 {
1142 }
1143 
1144 template <typename T>
1145 inline object::object(const T& v)
1146 {
1147  *this << v;
1148 }
1149 
1150 template <typename T>
1151 inline object& object::operator=(const T& v)
1152 {
1153  *this = object(v);
1154  return *this;
1155 }
1156 
1157 template <typename T>
1158 inline object::object(const T& v, msgpack::zone& z)
1159 {
1160  with_zone oz(z);
1161  msgpack::operator<<(oz, v);
1162  type = oz.type;
1163  via = oz.via;
1164 }
1165 
1166 template <typename T>
1167 inline object::object(const T& v, msgpack::zone* z)
1168 {
1169  with_zone oz(*z);
1170  msgpack::operator<<(oz, v);
1171  type = oz.type;
1172  via = oz.via;
1173 }
1174 
1175 
1176 // obsolete
1177 template <typename T>
1178 inline void convert(T& v, msgpack::object const& o)
1179 {
1180  o.convert(v);
1181 }
1182 
1183 // obsolete
1184 template <typename Stream, typename T>
1185 inline void pack(msgpack::packer<Stream>& o, const T& v)
1186 {
1187  o.pack(v);
1188 }
1189 
1190 // obsolete
1191 template <typename Stream, typename T>
1193 {
1194  pack(o, v);
1195 }
1196 
1197 template <typename Stream>
1199 {
1200  object_pack_visitor<Stream> vis(o);
1201  msgpack::object_parser(v).parse(vis);
1202  return o;
1203 }
1204 
1205 template <typename Stream>
1207 {
1208  return o << static_cast<msgpack::object>(v);
1209 }
1210 
1211 inline std::ostream& operator<< (std::ostream& s, const msgpack::object& v)
1212 {
1213  object_stringize_visitor vis(s);
1214  msgpack::object_parser(v).parse(vis);
1215  return s;
1216 }
1217 
1219 } // MSGPACK_API_VERSION_NAMESPACE(v1)
1221 
1222 } // namespace msgpack
1223 
1224 #endif // MSGPACK_V1_OBJECT_HPP
Definition: object.hpp:852
define()
Definition: object.hpp:856
define(const msgpack_type &v)
Definition: object.hpp:857
void msgpack_pack(Packer &o) const
Definition: object.hpp:860
void msgpack_unpack(object const &o)
Definition: object.hpp:865
define< Type > define_type
Definition: object.hpp:855
Type msgpack_type
Definition: object.hpp:854
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:30
#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:1185
bool operator==(const msgpack::object &x, const msgpack::object &y)
Definition: object.hpp:1032
std::size_t aligned_size(std::size_t size, std::size_t align)
Definition: cpp03_zone.hpp:353
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:1192
object_handle clone(msgpack::object const &obj)
clone object
Definition: object.hpp:622
std::size_t aligned_zone_size(msgpack::object const &obj)
Definition: object.hpp:607
void convert(T &v, msgpack::object const &o)
Definition: object.hpp:1178
bool operator!=(const msgpack::object &x, const msgpack::object &y)
Definition: object.hpp:1049
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:671
Definition: adaptor_base.hpp:27
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: object.hpp:646
void operator()(msgpack::object::with_zone &o, msgpack::object const &v) const
Definition: object.hpp:689
void operator()(msgpack::object::with_zone &o, msgpack::object::with_zone const &v) const
Definition: object.hpp:839
Definition: adaptor_base.hpp:43
void operator()(msgpack::object::with_zone &o, T const &v) const
Definition: object.hpp:662
Definition: adaptor_base.hpp:38
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, msgpack::object const &v) const
Definition: object.hpp:680
Definition: adaptor_base.hpp:32
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, T const &v) const
Definition: object.hpp:655
Definition: object.hpp:534
bool visit_nil()
Definition: object.hpp:537
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:582
bool end_map()
Definition: object.hpp:600
bool visit_ext(const char *, uint32_t size)
Definition: object.hpp:563
bool start_map_key()
Definition: object.hpp:588
bool start_map_value()
Definition: object.hpp:594
bool visit_bin(const char *, uint32_t size)
Definition: object.hpp:559
bool visit_float32(float)
Definition: object.hpp:549
bool end_array()
Definition: object.hpp:579
aligned_zone_size_visitor(std::size_t &s)
Definition: object.hpp:535
bool start_array(uint32_t num_elements)
Definition: object.hpp:567
bool visit_boolean(bool)
Definition: object.hpp:540
bool start_array_item()
Definition: object.hpp:573
bool visit_negative_integer(int64_t)
Definition: object.hpp:546
bool visit_str(const char *, uint32_t size)
Definition: object.hpp:555
bool end_array_item()
Definition: object.hpp:576
bool end_map_key()
Definition: object.hpp:591
bool end_map_value()
Definition: object.hpp:597
bool visit_float64(double)
Definition: object.hpp:552
bool visit_positive_integer(uint64_t)
Definition: object.hpp:543
Definition: object.hpp:634
static msgpack::packer< Stream > & pack(msgpack::packer< Stream > &o, const T &v)
Definition: object.hpp:635
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:881
bool start_map_key()
Definition: object.hpp:983
bool visit_ext(const char *v, uint32_t size)
Definition: object.hpp:944
bool end_array_item()
Definition: object.hpp:966
bool visit_str(const char *v, uint32_t size)
Definition: object.hpp:926
bool visit_boolean(bool v)
Definition: object.hpp:891
bool visit_bin(const char *v, uint32_t size)
Definition: object.hpp:935
bool start_map_value()
Definition: object.hpp:990
bool start_array_item()
Definition: object.hpp:962
bool visit_nil()
Definition: object.hpp:884
bool visit_negative_integer(int64_t v)
Definition: object.hpp:905
bool visit_positive_integer(uint64_t v)
Definition: object.hpp:898
bool end_map_value()
Definition: object.hpp:994
bool visit_float64(double v)
Definition: object.hpp:919
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:974
bool start_array(uint32_t num_elements)
Definition: object.hpp:953
bool visit_float32(float v)
Definition: object.hpp:912
object_equal_visitor(msgpack::object const &obj, bool &result)
Definition: object.hpp:882
bool end_map_key()
Definition: object.hpp:987
bool end_array()
Definition: object.hpp:970
bool end_map()
Definition: object.hpp:998
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:517
bool start_array(uint32_t num_elements)
Definition: object.hpp:482
bool start_map_value()
Definition: object.hpp:514
bool visit_bin(const char *, uint32_t size)
Definition: object.hpp:469
bool visit_str(const char *v, uint32_t size)
Definition: object.hpp:424
bool end_array()
Definition: object.hpp:497
bool start_map(uint32_t num_kv_pairs)
Definition: object.hpp:502
bool visit_boolean(bool v)
Definition: object.hpp:403
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:490
bool start_map_key()
Definition: object.hpp:507
bool end_map()
Definition: object.hpp:524
bool visit_float64(double v)
Definition: object.hpp:420
bool visit_ext(const char *v, uint32_t size)
Definition: object.hpp:473
bool end_map_key()
Definition: object.hpp:510
bool visit_positive_integer(uint64_t v)
Definition: object.hpp:408
bool start_array_item()
Definition: object.hpp:487
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:1139
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition: object.hpp:1126
implicit_type convert() const
Definition: object.hpp:1065
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:1076
bool convert_if_not_nil(T &v) const
Convert the object if not nil.
Definition: object.hpp:1104
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:1151
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