123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- #ifndef MSGPACK_V2_UNPACK_HPP
- #define MSGPACK_V2_UNPACK_HPP
- #if MSGPACK_DEFAULT_API_VERSION >= 2
- #include "msgpack/unpack_decl.hpp"
- #include "msgpack/parse.hpp"
- #include "msgpack/create_object_visitor.hpp"
- namespace msgpack {
- MSGPACK_API_VERSION_NAMESPACE(v2) {
- struct zone_push_finalizer {
- zone_push_finalizer(msgpack::zone& z):m_z(&z) {}
- void set_zone(msgpack::zone& z) { m_z = &z; }
- void operator()(char* buffer) {
- m_z->push_finalizer(&detail::decr_count, buffer);
- }
- msgpack::zone* m_z;
- };
- class unpacker : public parser<unpacker, zone_push_finalizer>,
- public detail::create_object_visitor {
- typedef parser<unpacker, zone_push_finalizer> parser_t;
- public:
- unpacker(unpack_reference_func f = &unpacker::default_reference_func,
- void* user_data = MSGPACK_NULLPTR,
- std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
- unpack_limit const& limit = unpack_limit())
- :parser_t(m_finalizer, initial_buffer_size),
- detail::create_object_visitor(f, user_data, limit),
- m_z(new msgpack::zone),
- m_finalizer(*m_z) {
- set_zone(*m_z);
- set_referenced(false);
- }
- detail::create_object_visitor& visitor() { return *this; }
-
-
- bool next(msgpack::object_handle& result, bool& referenced);
-
-
- bool next(msgpack::object_handle& result);
- msgpack::zone* release_zone();
- void reset_zone();
- bool flush_zone();
- private:
- static bool default_reference_func(msgpack::type::object_type , std::size_t , void*) {
- return true;
- }
- msgpack::unique_ptr<msgpack::zone> m_z;
- zone_push_finalizer m_finalizer;
- };
- inline bool unpacker::next(msgpack::object_handle& result, bool& referenced) {
- bool ret = parser_t::next();
- if (ret) {
- referenced = detail::create_object_visitor::referenced();
- result.zone().reset( release_zone() );
- result.set(data());
- reset();
- }
- else {
- result.zone().reset();
- result.set(msgpack::object());
- }
- return ret;
- }
- inline bool unpacker::next(msgpack::object_handle& result) {
- bool referenced;
- return next(result, referenced);
- }
- inline msgpack::zone* unpacker::release_zone()
- {
- if(!flush_zone()) {
- return MSGPACK_NULLPTR;
- }
- msgpack::zone* r = new msgpack::zone;
- msgpack::zone* old = m_z.release();
- m_z.reset(r);
- set_zone(*m_z);
- m_finalizer.set_zone(*m_z);
- return old;
- }
- inline void unpacker::reset_zone()
- {
- m_z->clear();
- }
- inline bool unpacker::flush_zone()
- {
- if(referenced()) {
- try {
- m_z->push_finalizer(&detail::decr_count, get_raw_buffer());
- } catch (...) {
- return false;
- }
- set_referenced(false);
- detail::incr_count(get_raw_buffer());
- }
- return true;
- }
- inline msgpack::object_handle unpack(
- const char* data, std::size_t len, std::size_t& off, bool& referenced,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit
- )
- {
- msgpack::object obj;
- msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
- referenced = false;
- std::size_t noff = off;
- parse_return ret = detail::unpack_imp(
- data, len, noff, *z, obj, referenced, f, user_data, limit);
- switch(ret) {
- case PARSE_SUCCESS:
- off = noff;
- return msgpack::object_handle(obj, msgpack::move(z));
- case PARSE_EXTRA_BYTES:
- off = noff;
- return msgpack::object_handle(obj, msgpack::move(z));
- default:
- break;
- }
- return msgpack::object_handle();
- }
- inline msgpack::object_handle unpack(
- const char* data, std::size_t len, std::size_t& off,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- bool referenced;
- return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
- }
- inline msgpack::object_handle unpack(
- const char* data, std::size_t len, bool& referenced,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- std::size_t off = 0;
- return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
- }
- inline msgpack::object_handle unpack(
- const char* data, std::size_t len,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- bool referenced;
- std::size_t off = 0;
- return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
- }
- inline void unpack(
- msgpack::object_handle& result,
- const char* data, std::size_t len, std::size_t& off, bool& referenced,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- msgpack::object obj;
- msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
- referenced = false;
- std::size_t noff = off;
- parse_return ret = detail::unpack_imp(
- data, len, noff, *z, obj, referenced, f, user_data, limit);
- switch(ret) {
- case PARSE_SUCCESS:
- off = noff;
- result.set(obj);
- result.zone() = msgpack::move(z);
- return;
- case PARSE_EXTRA_BYTES:
- off = noff;
- result.set(obj);
- result.zone() = msgpack::move(z);
- return;
- default:
- return;
- }
- }
- inline void unpack(
- msgpack::object_handle& result,
- const char* data, std::size_t len, std::size_t& off,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- bool referenced;
- msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
- }
- inline void unpack(
- msgpack::object_handle& result,
- const char* data, std::size_t len, bool& referenced,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- std::size_t off = 0;
- msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
- }
- inline void unpack(
- msgpack::object_handle& result,
- const char* data, std::size_t len,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- bool referenced;
- std::size_t off = 0;
- msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
- }
- inline msgpack::object unpack(
- msgpack::zone& z,
- const char* data, std::size_t len, std::size_t& off, bool& referenced,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- msgpack::object obj;
- std::size_t noff = off;
- referenced = false;
- parse_return ret = detail::unpack_imp(
- data, len, noff, z, obj, referenced, f, user_data, limit);
- switch(ret) {
- case PARSE_SUCCESS:
- off = noff;
- return obj;
- case PARSE_EXTRA_BYTES:
- off = noff;
- return obj;
- default:
- break;
- }
- return obj;
- }
- inline msgpack::object unpack(
- msgpack::zone& z,
- const char* data, std::size_t len, std::size_t& off,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- bool referenced;
- return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
- }
- inline msgpack::object unpack(
- msgpack::zone& z,
- const char* data, std::size_t len, bool& referenced,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- std::size_t off = 0;
- return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
- }
- inline msgpack::object unpack(
- msgpack::zone& z,
- const char* data, std::size_t len,
- unpack_reference_func f, void* user_data,
- unpack_limit const& limit)
- {
- bool referenced;
- std::size_t off = 0;
- return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
- }
- namespace detail {
- inline parse_return
- unpack_imp(const char* data, std::size_t len, std::size_t& off,
- msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
- unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
- unpack_limit const& limit = unpack_limit())
- {
- create_object_visitor v(f, user_data, limit);
- v.set_zone(result_zone);
- referenced = false;
- v.set_referenced(referenced);
- parse_return ret = parse_imp(data, len, off, v);
- referenced = v.referenced();
- result = v.data();
- return ret;
- }
- }
- }
- }
- #endif
- #endif
|