| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224 |
- //
- // 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_type : msgpack::object {
- object_with_zone_type(msgpack::zone& z) : zone(z) { }
- msgpack::zone& zone;
- private:
- object_with_zone_type();
- };
- /// 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 - 1, static_cast<int8_t>(*v));
- m_packer.pack_ext_body(v + 1, size - 1);
- 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 << "\"BIN(size:" << size << ")\"";
- return true;
- }
- bool visit_ext(const char* v, uint32_t size) {
- if (size == 0) {
- m_os << "\"EXT(size:0)\"";
- }
- else {
- m_os << "\"EXT(type:" << static_cast<int>(v[0]) << ",size:" << size - 1 << ")\"";
- }
- 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 - 1 ||
- 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;
- }
- // 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
|