unpack.hpp
Go to the documentation of this file.
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2016 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_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 /*type*/, std::size_t /*len*/, 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;
}
} // namespace detail
} // MSGPACK_API_VERSION_NAMESPACE(v2)
} // namespace msgpack
#endif // MSGPACK_DEFAULT_API_VERSION >= 2
#endif // MSGPACK_V2_UNPACK_HPP
msgpack::unpack
void unpack(msgpack::object_handle &result, const char *data, std::size_t len, std::size_t &off, msgpack::v3::unpack_reference_func f, void *user_data, msgpack::unpack_limit const &limit)
Definition: unpack.hpp:100
msgpack::detail::incr_count
void incr_count(void *buffer)
Definition: unpack.hpp:248
v2
MSGPACK_UNPACKER_INIT_BUFFER_SIZE
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE
Definition: unpack_decl.hpp:43
msgpack::parse_return
parse_return
Definition: parse_return.hpp:23
msgpack::detail::unpack_imp
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())
Definition: unpack.hpp:1338
msgpack::object_handle::set
void set(msgpack::object const &obj)
Definition: object.hpp:64
msgpack::unpack_reference_func
bool(* unpack_reference_func)(msgpack::type::object_type type, std::size_t size, void *user_data)
The type of reference or copy judging function.
Definition: unpack_decl.hpp:74
msgpack::detail::create_object_visitor::referenced
bool referenced() const
Definition: create_object_visitor.hpp:64
msgpack
Definition: adaptor_base.hpp:15
msgpack::zone
Definition: cpp03_zone.hpp:22
msgpack::type::object_type
object_type
Definition: object_fwd_decl.hpp:28
msgpack::unpack
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)
Unpack msgpack::object from a buffer.
Definition: unpack.hpp:1382
msgpack::unique_ptr< msgpack::zone >
msgpack::zone::push_finalizer
void push_finalizer(void(*func)(void *), void *data)
Definition: cpp03_zone.hpp:301
msgpack::unpacker::reset_zone
void reset_zone()
Definition: unpack.hpp:1277
msgpack::unpacker::release_zone
msgpack::zone * release_zone()
Definition: unpack.hpp:1263
unpack_decl.hpp
create_object_visitor.hpp
msgpack::object
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
MSGPACK_API_VERSION_NAMESPACE
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
msgpack::PARSE_SUCCESS
Definition: parse_return.hpp:24
msgpack::detail::parse_imp
parse_return parse_imp(const char *data, size_t len, size_t &off, Visitor &v)
parse.hpp
msgpack::PARSE_EXTRA_BYTES
Definition: parse_return.hpp:25
msgpack::object_handle::zone
msgpack::unique_ptr< msgpack::zone > & zone()
Get unique_ptr reference of zone.
Definition: object.hpp:90
msgpack::detail::decr_count
void decr_count(void *buffer)
Definition: unpack.hpp:235
MSGPACK_NULLPTR
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
msgpack::move
T & move(T &t)
msgpack::unpacker::next
bool next(msgpack::object_handle *result)
Unpack one msgpack::object. [obsolete].
Definition: unpack.hpp:1230
msgpack::object_handle
The class holds object and zone.
Definition: object.hpp:44