1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240 |
- //
- // MessagePack for C++ static resolution routine
- //
- // Copyright (C) 2008-2014 FURUHASHI Sadayuki and KONDO Takatoshi
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef MSGPACK_V1_OBJECT_HPP
- #define MSGPACK_V1_OBJECT_HPP
- #include "msgpack/object_decl.hpp"
- #include "msgpack/adaptor/check_container_size.hpp"
- #include <cstring>
- #include <stdexcept>
- #include <typeinfo>
- #include <limits>
- #include <ostream>
- #include <typeinfo>
- #include <iomanip>
- namespace msgpack {
- /// @cond
- MSGPACK_API_VERSION_NAMESPACE(v1) {
- /// @endcond
- struct object_kv {
- msgpack::object key;
- msgpack::object val;
- };
- struct object::with_zone : msgpack::object {
- with_zone(msgpack::zone& z) : zone(z) { }
- msgpack::zone& zone;
- private:
- with_zone();
- };
- /// The class holds object and zone
- class object_handle {
- public:
- /// Constructor that creates nil object and null zone.
- object_handle() {}
- /// Constructor that creates an object_handle holding object `obj` and zone `z`.
- /**
- * @param obj object
- * @param z zone
- */
- object_handle(
- msgpack::object const& obj,
- #if defined(MSGPACK_USE_CPP03)
- msgpack::unique_ptr<msgpack::zone> z
- #else // defined(MSGPACK_USE_CPP03)
- msgpack::unique_ptr<msgpack::zone>&& z
- #endif // defined(MSGPACK_USE_CPP03)
- ) :
- m_obj(obj), m_zone(msgpack::move(z)) { }
- void set(msgpack::object const& obj)
- { m_obj = obj; }
- /// Get object reference
- /**
- * @return object
- */
- const msgpack::object& get() const
- { return m_obj; }
- /**
- * @return object (to mimic smart pointers).
- */
- const msgpack::object& operator*() const
- { return get(); }
- /**
- * @return the address of the object (to mimic smart pointers).
- */
- const msgpack::object* operator->() const
- { return &get(); }
- /// Get unique_ptr reference of zone.
- /**
- * @return unique_ptr reference of zone
- */
- msgpack::unique_ptr<msgpack::zone>& zone()
- { return m_zone; }
- /// Get unique_ptr const reference of zone.
- /**
- * @return unique_ptr const reference of zone
- */
- const msgpack::unique_ptr<msgpack::zone>& zone() const
- { return m_zone; }
- #if defined(MSGPACK_USE_CPP03)
- struct object_handle_ref {
- object_handle_ref(object_handle* oh):m_oh(oh) {}
- object_handle* m_oh;
- };
- object_handle(object_handle& other):
- m_obj(other.m_obj),
- m_zone(msgpack::move(other.m_zone)) {
- }
- object_handle(object_handle_ref ref):
- m_obj(ref.m_oh->m_obj),
- m_zone(msgpack::move(ref.m_oh->m_zone)) {
- }
- object_handle& operator=(object_handle& other) {
- m_obj = other.m_obj;
- m_zone = msgpack::move(other.m_zone);
- return *this;
- }
- object_handle& operator=(object_handle_ref ref) {
- m_obj = ref.m_oh->m_obj;
- m_zone = msgpack::move(ref.m_oh->m_zone);
- return *this;
- }
- operator object_handle_ref() {
- return object_handle_ref(this);
- }
- #endif // defined(MSGPACK_USE_CPP03)
- private:
- msgpack::object m_obj;
- msgpack::unique_ptr<msgpack::zone> m_zone;
- };
- namespace detail {
- template <std::size_t N>
- inline std::size_t add_ext_type_size(std::size_t size) {
- return size + 1;
- }
- template <>
- inline std::size_t add_ext_type_size<4>(std::size_t size) {
- return size == 0xffffffff ? size : size + 1;
- }
- } // namespace detail
- class object_parser {
- private:
- enum next_ret {
- cont,
- finish,
- abort
- };
- struct elem {
- elem(msgpack::object const* p, std::size_t r)
- : rest(r), is_map(false), is_key(false) {
- as.obj_ptr = p;
- }
- elem(msgpack::object_kv const* p, std::size_t r)
- : rest(r), is_map(true), is_key(true) {
- as.kv_ptr = p;
- }
- msgpack::object const& get() const {
- if (is_map) {
- if (is_key) {
- return as.kv_ptr->key;
- }
- else {
- return as.kv_ptr->val;
- }
- }
- else {
- return *as.obj_ptr;
- }
- }
- template <typename Visitor>
- next_ret next(Visitor& v) {
- if (rest == 0) {
- if (is_map) {
- if (!v.end_map()) return abort;
- }
- else {
- if (!v.end_array()) return abort;
- }
- return finish;
- }
- else {
- if (is_map) {
- if (is_key) {
- if (!v.end_map_key()) return abort;
- if (!v.start_map_value()) return abort;
- is_key = false;
- }
- else {
- if (!v.end_map_value()) return abort;
- --rest;
- if (rest == 0) {
- if (!v.end_map()) return abort;
- return finish;
- }
- if (!v.start_map_key()) return abort;
- ++as.kv_ptr;
- is_key = true;
- }
- }
- else {
- if (!v.end_array_item()) return abort;
- --rest;
- if (rest == 0) {
- if (!v.end_array()) return abort;
- return finish;
- }
- if (!v.start_array_item()) return abort;
- ++as.obj_ptr;
- }
- return cont;
- }
- }
- union {
- msgpack::object const* obj_ptr;
- msgpack::object_kv const* kv_ptr;
- } as;
- std::size_t rest;
- bool is_map;
- bool is_key;
- };
- public:
- explicit object_parser(msgpack::object const& obj):m_current(&obj) {}
- template <typename Visitor>
- void parse(Visitor& v) {
- while (true) {
- bool start_collection = false;
- switch(m_current->type) {
- case msgpack::type::NIL:
- if (!v.visit_nil()) return;
- break;
- case msgpack::type::BOOLEAN:
- if (!v.visit_boolean(m_current->via.boolean)) return;
- break;
- case msgpack::type::POSITIVE_INTEGER:
- if (!v.visit_positive_integer(m_current->via.u64)) return;
- break;
- case msgpack::type::NEGATIVE_INTEGER:
- if (!v.visit_negative_integer(m_current->via.i64)) return;
- break;
- case msgpack::type::FLOAT32:
- if (!v.visit_float32(static_cast<float>(m_current->via.f64))) return;
- break;
- case msgpack::type::FLOAT64:
- if (!v.visit_float64(m_current->via.f64)) return;
- break;
- case msgpack::type::STR:
- if (!v.visit_str(m_current->via.str.ptr, m_current->via.str.size)) return;
- break;
- case msgpack::type::BIN:
- if (!v.visit_bin(m_current->via.bin.ptr, m_current->via.bin.size)) return;
- break;
- case msgpack::type::EXT:
- msgpack::detail::check_container_size<sizeof(std::size_t)>(m_current->via.ext.size);
- if (!v.visit_ext(m_current->via.ext.ptr, m_current->via.ext.size + 1)) return;
- break;
- case msgpack::type::ARRAY:
- if (!v.start_array(m_current->via.array.size)) return;
- m_ctx.push_back(elem(m_current->via.array.ptr, m_current->via.array.size));
- start_collection = m_current->via.array.size != 0;
- if (start_collection) {
- if (!v.start_array_item()) return;
- }
- break;
- case msgpack::type::MAP:
- if (!v.start_map(m_current->via.map.size)) return;
- m_ctx.push_back(elem(m_current->via.map.ptr, m_current->via.map.size));
- start_collection = m_current->via.map.size != 0;
- if (start_collection) {
- if (!v.start_map_key()) return;
- }
- break;
- default:
- throw msgpack::type_error();
- break;
- }
- if (m_ctx.empty()) return;
- if (!start_collection) {
- while (true) {
- next_ret r = m_ctx.back().next(v);
- if (r == finish) {
- m_ctx.pop_back();
- if (m_ctx.empty()) return;
- }
- else if (r == cont) {
- break;
- }
- else {
- // abort
- return;
- }
- }
- }
- m_current = &m_ctx.back().get();
- }
- }
- private:
- msgpack::object const* m_current;
- std::vector<elem> m_ctx;
- };
- template <typename Stream>
- struct object_pack_visitor {
- explicit object_pack_visitor(msgpack::packer<Stream>& pk)
- :m_packer(pk) {}
- bool visit_nil() {
- m_packer.pack_nil();
- return true;
- }
- bool visit_boolean(bool v) {
- if (v) m_packer.pack_true();
- else m_packer.pack_false();
- return true;
- }
- bool visit_positive_integer(uint64_t v) {
- m_packer.pack_uint64(v);
- return true;
- }
- bool visit_negative_integer(int64_t v) {
- m_packer.pack_int64(v);
- return true;
- }
- bool visit_float32(float v) {
- m_packer.pack_float(v);
- return true;
- }
- bool visit_float64(double v) {
- m_packer.pack_double(v);
- return true;
- }
- bool visit_str(const char* v, uint32_t size) {
- m_packer.pack_str(size);
- m_packer.pack_str_body(v, size);
- return true;
- }
- bool visit_bin(const char* v, uint32_t size) {
- m_packer.pack_bin(size);
- m_packer.pack_bin_body(v, size);
- return true;
- }
- bool visit_ext(const char* v, uint32_t size) {
- m_packer.pack_ext(size, *v);
- m_packer.pack_ext_body(v, size);
- return true;
- }
- bool start_array(uint32_t num_elements) {
- m_packer.pack_array(num_elements);
- return true;
- }
- bool start_array_item() {
- return true;
- }
- bool end_array_item() {
- return true;
- }
- bool end_array() {
- return true;
- }
- bool start_map(uint32_t num_kv_pairs) {
- m_packer.pack_map(num_kv_pairs);
- return true;
- }
- bool start_map_key() {
- return true;
- }
- bool end_map_key() {
- return true;
- }
- bool start_map_value() {
- return true;
- }
- bool end_map_value() {
- return true;
- }
- bool end_map() {
- return true;
- }
- private:
- msgpack::packer<Stream>& m_packer;
- };
- struct object_stringize_visitor {
- explicit object_stringize_visitor(std::ostream& os)
- :m_os(os) {}
- bool visit_nil() {
- m_os << "null";
- return true;
- }
- bool visit_boolean(bool v) {
- if (v) m_os << "true";
- else m_os << "false";
- return true;
- }
- bool visit_positive_integer(uint64_t v) {
- m_os << v;
- return true;
- }
- bool visit_negative_integer(int64_t v) {
- m_os << v;
- return true;
- }
- bool visit_float32(float v) {
- m_os << v;
- return true;
- }
- bool visit_float64(double v) {
- m_os << v;
- return true;
- }
- bool visit_str(const char* v, uint32_t size) {
- m_os << '"';
- for (uint32_t i = 0; i < size; ++i) {
- char c = v[i];
- switch (c) {
- case '\\':
- m_os << "\\\\";
- break;
- case '"':
- m_os << "\\\"";
- break;
- case '/':
- m_os << "\\/";
- break;
- case '\b':
- m_os << "\\b";
- break;
- case '\f':
- m_os << "\\f";
- break;
- case '\n':
- m_os << "\\n";
- break;
- case '\r':
- m_os << "\\r";
- break;
- case '\t':
- m_os << "\\t";
- break;
- default: {
- unsigned int code = static_cast<unsigned int>(c);
- if (code < 0x20 || code == 0x7f) {
- std::ios::fmtflags flags(m_os.flags());
- m_os << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (code & 0xff);
- m_os.flags(flags);
- }
- else {
- m_os << c;
- }
- } break;
- }
- }
- m_os << '"';
- return true;
- }
- bool visit_bin(const char* v, uint32_t size) {
- (m_os << '"').write(v, size) << '"';
- return true;
- }
- bool visit_ext(const char* /*v*/, uint32_t /*size*/) {
- m_os << "EXT";
- return true;
- }
- bool start_array(uint32_t num_elements) {
- m_current_size.push_back(num_elements);
- m_os << "[";
- return true;
- }
- bool start_array_item() {
- return true;
- }
- bool end_array_item() {
- --m_current_size.back();
- if (m_current_size.back() != 0) {
- m_os << ",";
- }
- return true;
- }
- bool end_array() {
- m_current_size.pop_back();
- m_os << "]";
- return true;
- }
- bool start_map(uint32_t num_kv_pairs) {
- m_current_size.push_back(num_kv_pairs);
- m_os << "{";
- return true;
- }
- bool start_map_key() {
- return true;
- }
- bool end_map_key() {
- m_os << ":";
- return true;
- }
- bool start_map_value() {
- return true;
- }
- bool end_map_value() {
- --m_current_size.back();
- if (m_current_size.back() != 0) {
- m_os << ",";
- }
- return true;
- }
- bool end_map() {
- m_current_size.pop_back();
- m_os << "}";
- return true;
- }
- private:
- std::ostream& m_os;
- std::vector<uint32_t> m_current_size;
- };
- struct aligned_zone_size_visitor {
- explicit aligned_zone_size_visitor(std::size_t s)
- :m_size(s) {}
- bool visit_nil() {
- return true;
- }
- bool visit_boolean(bool) {
- return true;
- }
- bool visit_positive_integer(uint64_t) {
- return true;
- }
- bool visit_negative_integer(int64_t) {
- return true;
- }
- bool visit_float32(float) {
- return true;
- }
- bool visit_float64(double) {
- return true;
- }
- bool visit_str(const char*, uint32_t size) {
- m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
- return true;
- }
- bool visit_bin(const char*, uint32_t size) {
- m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
- return true;
- }
- bool visit_ext(const char*, uint32_t size) {
- m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
- return true;
- }
- bool start_array(uint32_t num_elements) {
- m_size += msgpack::aligned_size(
- sizeof(msgpack::object) * num_elements,
- MSGPACK_ZONE_ALIGNOF(msgpack::object));
- return true;
- }
- bool start_array_item() {
- return true;
- }
- bool end_array_item() {
- return true;
- }
- bool end_array() {
- return true;
- }
- bool start_map(uint32_t num_kv_pairs) {
- m_size += msgpack::aligned_size(
- sizeof(msgpack::object_kv) * num_kv_pairs,
- MSGPACK_ZONE_ALIGNOF(msgpack::object_kv));
- return true;
- }
- bool start_map_key() {
- return true;
- }
- bool end_map_key() {
- return true;
- }
- bool start_map_value() {
- return true;
- }
- bool end_map_value() {
- return true;
- }
- bool end_map() {
- return true;
- }
- private:
- std::size_t m_size;
- };
- inline std::size_t aligned_zone_size(msgpack::object const& obj) {
- std::size_t s = 0;
- aligned_zone_size_visitor vis(s);
- msgpack::object_parser(obj).parse(vis);
- return s;
- }
- /// clone object
- /**
- * Clone (deep copy) object.
- * The copied object is located on newly allocated zone.
- * @param obj copy source object
- *
- * @return object_handle that holds deep copied object and zone.
- */
- inline object_handle clone(msgpack::object const& obj) {
- std::size_t size = msgpack::aligned_zone_size(obj);
- msgpack::unique_ptr<msgpack::zone> z(size == 0 ? MSGPACK_NULLPTR : new msgpack::zone(size));
- msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj;
- return object_handle(newobj, msgpack::move(z));
- }
- template <typename T>
- inline object::implicit_type::operator T() { return obj.as<T>(); }
- namespace detail {
- template <typename Stream, typename T>
- struct packer_serializer {
- static msgpack::packer<Stream>& pack(msgpack::packer<Stream>& o, const T& v) {
- v.msgpack_pack(o);
- return o;
- }
- };
- } // namespace detail
- // Adaptor functors' member functions definitions.
- template <typename T, typename Enabler>
- inline
- msgpack::object const&
- adaptor::convert<T, Enabler>::operator()(msgpack::object const& o, T& v) const {
- v.msgpack_unpack(o.convert());
- return o;
- }
- template <typename T, typename Enabler>
- template <typename Stream>
- inline
- msgpack::packer<Stream>&
- adaptor::pack<T, Enabler>::operator()(msgpack::packer<Stream>& o, T const& v) const {
- return msgpack::detail::packer_serializer<Stream, T>::pack(o, v);
- }
- template <typename T, typename Enabler>
- inline
- void
- adaptor::object_with_zone<T, Enabler>::operator()(msgpack::object::with_zone& o, T const& v) const {
- v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone);
- }
- // Adaptor functor specialization to object
- namespace adaptor {
- template <>
- struct convert<msgpack::object> {
- msgpack::object const& operator()(msgpack::object const& o, msgpack::object& v) const {
- v = o;
- return o;
- }
- };
- template <>
- struct pack<msgpack::object> {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, msgpack::object const& v) const {
- object_pack_visitor<Stream> vis(o);
- msgpack::object_parser(v).parse(vis);
- return o;
- }
- };
- template <>
- struct object_with_zone<msgpack::object> {
- void operator()(msgpack::object::with_zone& o, msgpack::object const& v) const {
- object_with_zone_visitor vis(o);
- msgpack::object_parser(v).parse(vis);
- }
- private:
- struct object_with_zone_visitor {
- explicit object_with_zone_visitor(msgpack::object::with_zone& owz)
- :m_zone(owz.zone), m_ptr(&owz) {
- m_objs.push_back(&owz);
- }
- bool visit_nil() {
- m_ptr->type = msgpack::type::NIL;
- return true;
- }
- bool visit_boolean(bool v) {
- m_ptr->type = msgpack::type::BOOLEAN;
- m_ptr->via.boolean = v;
- return true;
- }
- bool visit_positive_integer(uint64_t v) {
- m_ptr->type = msgpack::type::POSITIVE_INTEGER;
- m_ptr->via.u64 = v;
- return true;
- }
- bool visit_negative_integer(int64_t v) {
- m_ptr->type = msgpack::type::NEGATIVE_INTEGER;
- m_ptr->via.i64 = v;
- return true;
- }
- bool visit_float32(float v) {
- m_ptr->type = msgpack::type::FLOAT32;
- m_ptr->via.f64 = v;
- return true;
- }
- bool visit_float64(double v) {
- m_ptr->type = msgpack::type::FLOAT64;
- m_ptr->via.f64 = v;
- return true;
- }
- bool visit_str(const char* v, uint32_t size) {
- m_ptr->type = msgpack::type::STR;
- m_ptr->via.str.size = size;
- char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
- m_ptr->via.str.ptr = ptr;
- std::memcpy(ptr, v, size);
- return true;
- }
- bool visit_bin(const char* v, uint32_t size) {
- m_ptr->type = msgpack::type::BIN;
- m_ptr->via.bin.size = size;
- char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
- m_ptr->via.bin.ptr = ptr;
- std::memcpy(ptr, v, size);
- return true;
- }
- bool visit_ext(const char* v, uint32_t size) {
- m_ptr->type = msgpack::type::EXT;
- // v contains type but length(size) doesn't count the type byte.
- // See https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
- m_ptr->via.ext.size = size - 1;
- char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
- m_ptr->via.ext.ptr = ptr;
- std::memcpy(ptr, v, size);
- return true;
- }
- bool start_array(uint32_t num_elements) {
- m_ptr->type = msgpack::type::ARRAY;
- m_ptr->via.array.ptr = static_cast<msgpack::object*>(
- m_zone.allocate_align(
- sizeof(msgpack::object) * num_elements, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
- m_ptr->via.array.size = num_elements;
- m_objs.push_back(elem(m_ptr->via.array.ptr));
- return true;
- }
- bool start_array_item() {
- m_ptr = m_objs.back().get_item();
- return true;
- }
- bool end_array_item() {
- ++m_objs.back().as.obj;
- return true;
- }
- bool end_array() {
- m_objs.pop_back();
- return true;
- }
- bool start_map(uint32_t num_kv_pairs) {
- m_ptr->type = msgpack::type::MAP;
- m_ptr->via.map.ptr = (msgpack::object_kv*)m_zone.allocate_align(
- sizeof(msgpack::object_kv) * num_kv_pairs, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv));
- m_ptr->via.map.size = num_kv_pairs;
- m_objs.push_back(elem(m_ptr->via.map.ptr));
- return true;
- }
- bool start_map_key() {
- m_ptr = m_objs.back().get_key();
- return true;
- }
- bool end_map_key() {
- return true;
- }
- bool start_map_value() {
- m_ptr = m_objs.back().get_val();
- return true;
- }
- bool end_map_value() {
- ++m_objs.back().as.kv;
- return true;
- }
- bool end_map() {
- m_objs.pop_back();
- return true;
- }
- private:
- struct elem {
- elem(msgpack::object* obj)
- :is_obj(true) {
- as.obj = obj;
- }
- elem(msgpack::object_kv* kv)
- :is_obj(false) {
- as.kv = kv;
- }
- msgpack::object* get_item() {
- return as.obj;
- }
- msgpack::object* get_key() {
- return &as.kv->key;
- }
- msgpack::object* get_val() {
- return &as.kv->val;
- }
- union {
- msgpack::object* obj;
- msgpack::object_kv* kv;
- } as;
- bool is_obj;
- };
- std::vector<elem> m_objs;
- msgpack::zone& m_zone;
- msgpack::object* m_ptr;
- };
- };
- // Adaptor functor specialization to object::with_zone
- template <>
- struct object_with_zone<msgpack::object::with_zone> {
- void operator()(
- msgpack::object::with_zone& o,
- msgpack::object::with_zone const& v) const {
- o << static_cast<msgpack::object const&>(v);
- }
- };
- } // namespace adaptor
- // obsolete
- template <typename Type>
- class define : public Type {
- public:
- typedef Type msgpack_type;
- typedef define<Type> define_type;
- define() {}
- define(const msgpack_type& v) : msgpack_type(v) {}
- template <typename Packer>
- void msgpack_pack(Packer& o) const
- {
- msgpack::operator<<(o, static_cast<const msgpack_type&>(*this));
- }
- void msgpack_unpack(object const& o)
- {
- msgpack::operator>>(o, static_cast<msgpack_type&>(*this));
- }
- };
- // deconvert operator
- template <typename Stream>
- template <typename T>
- inline msgpack::packer<Stream>& packer<Stream>::pack(const T& v)
- {
- msgpack::operator<<(*this, v);
- return *this;
- }
- struct object_equal_visitor {
- object_equal_visitor(msgpack::object const& obj, bool& result)
- :m_ptr(&obj), m_result(result) {}
- bool visit_nil() {
- if (m_ptr->type != msgpack::type::NIL) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_boolean(bool v) {
- if (m_ptr->type != msgpack::type::BOOLEAN || m_ptr->via.boolean != v) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_positive_integer(uint64_t v) {
- if (m_ptr->type != msgpack::type::POSITIVE_INTEGER || m_ptr->via.u64 != v) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_negative_integer(int64_t v) {
- if (m_ptr->type != msgpack::type::NEGATIVE_INTEGER || m_ptr->via.i64 != v) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_float32(float v) {
- if (m_ptr->type != msgpack::type::FLOAT32 || m_ptr->via.f64 != v) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_float64(double v) {
- if (m_ptr->type != msgpack::type::FLOAT64 || m_ptr->via.f64 != v) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_str(const char* v, uint32_t size) {
- if (m_ptr->type != msgpack::type::STR ||
- m_ptr->via.str.size != size ||
- std::memcmp(m_ptr->via.str.ptr, v, size) != 0) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_bin(const char* v, uint32_t size) {
- if (m_ptr->type != msgpack::type::BIN ||
- m_ptr->via.bin.size != size ||
- std::memcmp(m_ptr->via.bin.ptr, v, size) != 0) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool visit_ext(const char* v, uint32_t size) {
- if (m_ptr->type != msgpack::type::EXT ||
- m_ptr->via.ext.size != size ||
- std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) {
- m_result = false;
- return false;
- }
- return true;
- }
- bool start_array(uint32_t num_elements) {
- if (m_ptr->type != msgpack::type::ARRAY ||
- m_ptr->via.array.size != num_elements) {
- m_result = false;
- return false;
- }
- m_objs.push_back(elem(m_ptr->via.array.ptr));
- return true;
- }
- bool start_array_item() {
- m_ptr = m_objs.back().get_item();
- return true;
- }
- bool end_array_item() {
- ++m_objs.back().as.obj;
- return true;
- }
- bool end_array() {
- m_objs.pop_back();
- return true;
- }
- bool start_map(uint32_t num_kv_pairs) {
- if (m_ptr->type != msgpack::type::MAP ||
- m_ptr->via.array.size != num_kv_pairs) {
- m_result = false;
- return false;
- }
- m_objs.push_back(elem(m_ptr->via.map.ptr));
- return true;
- }
- bool start_map_key() {
- m_ptr = m_objs.back().get_key();
- return true;
- }
- bool end_map_key() {
- return true;
- }
- bool start_map_value() {
- m_ptr = m_objs.back().get_val();
- return true;
- }
- bool end_map_value() {
- ++m_objs.back().as.kv;
- return true;
- }
- bool end_map() {
- m_objs.pop_back();
- return true;
- }
- private:
- struct elem {
- elem(msgpack::object const* obj)
- :is_obj(true) {
- as.obj = obj;
- }
- elem(msgpack::object_kv const* kv)
- :is_obj(false) {
- as.kv = kv;
- }
- msgpack::object const* get_item() {
- return as.obj;
- }
- msgpack::object const* get_key() {
- return &as.kv->key;
- }
- msgpack::object const* get_val() {
- return &as.kv->val;
- }
- union {
- msgpack::object const* obj;
- msgpack::object_kv const* kv;
- } as;
- bool is_obj;
- };
- std::vector<elem> m_objs;
- msgpack::object const* m_ptr;
- bool& m_result;
- };
- inline bool operator==(const msgpack::object& x, const msgpack::object& y)
- {
- if(x.type != y.type) { return false; }
- bool b = true;
- object_equal_visitor vis(y, b);
- msgpack::object_parser(x).parse(vis);
- return b;
- }
- template <typename T>
- inline bool operator==(const msgpack::object& x, const T& y)
- try {
- return x == msgpack::object(y);
- } catch (msgpack::type_error&) {
- return false;
- }
- inline bool operator!=(const msgpack::object& x, const msgpack::object& y)
- { return !(x == y); }
- template <typename T>
- inline bool operator==(const T& y, const msgpack::object& x)
- { return x == y; }
- template <typename T>
- inline bool operator!=(const msgpack::object& x, const T& y)
- { return !(x == y); }
- template <typename T>
- inline bool operator!=(const T& y, const msgpack::object& x)
- { return x != y; }
- inline object::implicit_type object::convert() const
- {
- return object::implicit_type(*this);
- }
- template <typename T>
- inline
- typename msgpack::enable_if<
- !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value,
- T&
- >::type
- object::convert(T& v) const
- {
- msgpack::operator>>(*this, v);
- return v;
- }
- template <typename T, std::size_t N>
- inline T(&object::convert(T(&v)[N]) const)[N]
- {
- msgpack::operator>>(*this, v);
- return v;
- }
- #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
- template <typename T>
- inline
- typename msgpack::enable_if<
- msgpack::is_pointer<T>::value,
- T
- >::type
- object::convert(T v) const
- {
- convert(*v);
- return v;
- }
- #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
- template <typename T>
- inline bool object::convert_if_not_nil(T& v) const
- {
- if (is_nil()) {
- return false;
- }
- convert(v);
- return true;
- }
- #if defined(MSGPACK_USE_CPP03)
- template <typename T>
- inline T object::as() const
- {
- T v;
- convert(v);
- return v;
- }
- #else // defined(MSGPACK_USE_CPP03)
- template <typename T>
- inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const {
- return msgpack::adaptor::as<T>()(*this);
- }
- template <typename T>
- inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const {
- T v;
- convert(v);
- return v;
- }
- #endif // defined(MSGPACK_USE_CPP03)
- inline object::object()
- {
- type = msgpack::type::NIL;
- }
- template <typename T>
- inline object::object(const T& v)
- {
- *this << v;
- }
- template <typename T>
- inline object& object::operator=(const T& v)
- {
- *this = object(v);
- return *this;
- }
- template <typename T>
- inline object::object(const T& v, msgpack::zone& z)
- {
- with_zone oz(z);
- msgpack::operator<<(oz, v);
- type = oz.type;
- via = oz.via;
- }
- template <typename T>
- inline object::object(const T& v, msgpack::zone* z)
- {
- with_zone oz(*z);
- msgpack::operator<<(oz, v);
- type = oz.type;
- via = oz.via;
- }
- inline object::object(const msgpack_object& o)
- {
- // FIXME beter way?
- std::memcpy(this, &o, sizeof(o));
- }
- inline void operator<< (msgpack::object& o, const msgpack_object& v)
- {
- // FIXME beter way?
- std::memcpy(static_cast<void*>(&o), &v, sizeof(v));
- }
- inline object::operator msgpack_object() const
- {
- // FIXME beter way?
- msgpack_object obj;
- std::memcpy(&obj, this, sizeof(obj));
- return obj;
- }
- // obsolete
- template <typename T>
- inline void convert(T& v, msgpack::object const& o)
- {
- o.convert(v);
- }
- // obsolete
- template <typename Stream, typename T>
- inline void pack(msgpack::packer<Stream>& o, const T& v)
- {
- o.pack(v);
- }
- // obsolete
- template <typename Stream, typename T>
- inline void pack_copy(msgpack::packer<Stream>& o, T v)
- {
- pack(o, v);
- }
- template <typename Stream>
- inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object& v)
- {
- object_pack_visitor<Stream> vis(o);
- msgpack::object_parser(v).parse(vis);
- return o;
- }
- template <typename Stream>
- inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object::with_zone& v)
- {
- return o << static_cast<msgpack::object>(v);
- }
- inline std::ostream& operator<< (std::ostream& s, const msgpack::object& v)
- {
- object_stringize_visitor vis(s);
- msgpack::object_parser(v).parse(vis);
- return s;
- }
- /// @cond
- } // MSGPACK_API_VERSION_NAMESPACE(v1)
- /// @endcond
- } // namespace msgpack
- #endif // MSGPACK_V1_OBJECT_HPP
|