MessagePack for C++
Loading...
Searching...
No Matches
unpack.hpp
Go to the documentation of this file.
1//
2// MessagePack for C++ deserializing routine
3//
4// Copyright (C) 2016 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_V2_UNPACK_HPP
11#define MSGPACK_V2_UNPACK_HPP
12
13#if MSGPACK_DEFAULT_API_VERSION >= 2
14
16#include "msgpack/parse.hpp"
18
19namespace msgpack {
20
24
25
26struct zone_push_finalizer {
27 zone_push_finalizer(msgpack::zone& z):m_z(&z) {}
28 void set_zone(msgpack::zone& z) { m_z = &z; }
29 void operator()(char* buffer) {
30 m_z->push_finalizer(&detail::decr_count, buffer);
31 }
32 msgpack::zone* m_z;
33};
34
35class unpacker : public parser<unpacker, zone_push_finalizer>,
37 typedef parser<unpacker, zone_push_finalizer> parser_t;
38public:
39 unpacker(unpack_reference_func f = &unpacker::default_reference_func,
40 void* user_data = MSGPACK_NULLPTR,
41 std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
42 unpack_limit const& limit = unpack_limit())
43 :parser_t(m_finalizer, initial_buffer_size),
44 detail::create_object_visitor(f, user_data, limit),
45 m_z(new msgpack::zone),
46 m_finalizer(*m_z) {
47 set_zone(*m_z);
48 set_referenced(false);
49 }
50
51#if !defined(MSGPACK_USE_CPP03)
52 unpacker(unpacker&& other)
53 :parser_t(std::move(other)),
54 detail::create_object_visitor(std::move(other)),
55 m_z(std::move(other.m_z)),
56 m_finalizer(std::move(other.m_finalizer)) {
57 // The parser base copied a hook pointer that still refers to the
58 // moved-from object's m_finalizer; re-point it to our own. The zone
59 // itself is heap-allocated and only ownership moved, so the zone
60 // pointers held by the visitor and by m_finalizer stay valid.
61 parser_t::set_referenced_buffer_hook(m_finalizer);
62 }
63 unpacker& operator=(unpacker&& other) {
64 if (this != &other) {
65 this->~unpacker();
66 new (this) unpacker(std::move(other));
67 }
68 return *this;
69 }
70#endif // !defined(MSGPACK_USE_CPP03)
71
72 detail::create_object_visitor& visitor() { return *this; }
74
87 bool next(msgpack::object_handle& result, bool& referenced);
88
90
101 bool next(msgpack::object_handle& result);
102 msgpack::zone* release_zone();
103 void reset_zone();
104 bool flush_zone();
105private:
106 static bool default_reference_func(msgpack::type::object_type /*type*/, std::size_t /*len*/, void*) {
107 return true;
108 }
109 msgpack::unique_ptr<msgpack::zone> m_z;
110 zone_push_finalizer m_finalizer;
111};
112
113inline bool unpacker::next(msgpack::object_handle& result, bool& referenced) {
114 bool ret = parser_t::next();
115 if (ret) {
117 result.zone().reset( release_zone() );
118 result.set(data());
119 reset();
120 }
121 else {
122 result.zone().reset();
123 result.set(msgpack::object());
124 }
125 return ret;
126}
127
128inline bool unpacker::next(msgpack::object_handle& result) {
129 bool referenced;
130 return next(result, referenced);
131}
132
133inline msgpack::zone* unpacker::release_zone()
134{
135 if(!flush_zone()) {
136 return MSGPACK_NULLPTR;
137 }
138
139 msgpack::zone* r = new msgpack::zone;
140 msgpack::zone* old = m_z.release();
141 m_z.reset(r);
142 set_zone(*m_z);
143 m_finalizer.set_zone(*m_z);
144
145 return old;
146}
147
148inline void unpacker::reset_zone()
149{
150 m_z->clear();
151}
152
153inline bool unpacker::flush_zone()
154{
155 if(referenced()) {
156 try {
157 m_z->push_finalizer(&detail::decr_count, get_raw_buffer());
158 } catch (...) {
159 return false;
160 }
161 set_referenced(false);
162
163 detail::incr_count(get_raw_buffer());
164 }
165
166 return true;
167}
168
169inline msgpack::object_handle unpack(
170 const char* data, std::size_t len, std::size_t& off, bool& referenced,
171 unpack_reference_func f, void* user_data,
172 unpack_limit const& limit
173)
174{
175 msgpack::object obj;
176 msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
177 referenced = false;
178 std::size_t noff = off;
180 data, len, noff, *z, obj, referenced, f, user_data, limit);
181
182 switch(ret) {
183 case PARSE_SUCCESS:
184 off = noff;
185 return msgpack::object_handle(obj, msgpack::move(z));
187 off = noff;
188 return msgpack::object_handle(obj, msgpack::move(z));
189 default:
190 break;
191 }
192 return msgpack::object_handle();
193}
194
195inline msgpack::object_handle unpack(
196 const char* data, std::size_t len, std::size_t& off,
197 unpack_reference_func f, void* user_data,
198 unpack_limit const& limit)
199{
200 bool referenced;
201 return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
202}
203
204inline msgpack::object_handle unpack(
205 const char* data, std::size_t len, bool& referenced,
206 unpack_reference_func f, void* user_data,
207 unpack_limit const& limit)
208{
209 std::size_t off = 0;
210 return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
211}
212
213inline msgpack::object_handle unpack(
214 const char* data, std::size_t len,
215 unpack_reference_func f, void* user_data,
216 unpack_limit const& limit)
217{
218 bool referenced;
219 std::size_t off = 0;
220 return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
221}
222
223inline void unpack(
224 msgpack::object_handle& result,
225 const char* data, std::size_t len, std::size_t& off, bool& referenced,
226 unpack_reference_func f, void* user_data,
227 unpack_limit const& limit)
228{
229 msgpack::object obj;
230 msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
231 referenced = false;
232 std::size_t noff = off;
234 data, len, noff, *z, obj, referenced, f, user_data, limit);
235
236 switch(ret) {
237 case PARSE_SUCCESS:
238 off = noff;
239 result.set(obj);
240 result.zone() = msgpack::move(z);
241 return;
243 off = noff;
244 result.set(obj);
245 result.zone() = msgpack::move(z);
246 return;
247 default:
248 return;
249 }
250}
251
252inline void unpack(
253 msgpack::object_handle& result,
254 const char* data, std::size_t len, std::size_t& off,
255 unpack_reference_func f, void* user_data,
256 unpack_limit const& limit)
257{
258 bool referenced;
259 msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
260}
261
262inline void unpack(
263 msgpack::object_handle& result,
264 const char* data, std::size_t len, bool& referenced,
265 unpack_reference_func f, void* user_data,
266 unpack_limit const& limit)
267{
268 std::size_t off = 0;
269 msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
270}
271
272inline void unpack(
273 msgpack::object_handle& result,
274 const char* data, std::size_t len,
275 unpack_reference_func f, void* user_data,
276 unpack_limit const& limit)
277{
278 bool referenced;
279 std::size_t off = 0;
280 msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
281}
282
283
284inline msgpack::object unpack(
285 msgpack::zone& z,
286 const char* data, std::size_t len, std::size_t& off, bool& referenced,
287 unpack_reference_func f, void* user_data,
288 unpack_limit const& limit)
289{
290 msgpack::object obj;
291 std::size_t noff = off;
292 referenced = false;
294 data, len, noff, z, obj, referenced, f, user_data, limit);
295
296 switch(ret) {
297 case PARSE_SUCCESS:
298 off = noff;
299 return obj;
301 off = noff;
302 return obj;
303 default:
304 break;
305 }
306 return obj;
307}
308
309inline msgpack::object unpack(
310 msgpack::zone& z,
311 const char* data, std::size_t len, std::size_t& off,
312 unpack_reference_func f, void* user_data,
313 unpack_limit const& limit)
314{
315 bool referenced;
316 return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
317}
318
319inline msgpack::object unpack(
320 msgpack::zone& z,
321 const char* data, std::size_t len, bool& referenced,
322 unpack_reference_func f, void* user_data,
323 unpack_limit const& limit)
324{
325 std::size_t off = 0;
326 return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
327}
328
329inline msgpack::object unpack(
330 msgpack::zone& z,
331 const char* data, std::size_t len,
332 unpack_reference_func f, void* user_data,
333 unpack_limit const& limit)
334{
335 bool referenced;
336 std::size_t off = 0;
337 return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
338}
339
340namespace detail {
341
342inline parse_return
343unpack_imp(const char* data, std::size_t len, std::size_t& off,
344 msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
346 unpack_limit const& limit = unpack_limit())
347{
348 create_object_visitor v(f, user_data, limit);
349 v.set_zone(result_zone);
350 referenced = false;
351 v.set_referenced(referenced);
352 parse_return ret = parse_imp(data, len, off, v);
353 referenced = v.referenced();
354 result = v.data();
355 return ret;
356}
357
358} // namespace detail
359
360
362} // MSGPACK_API_VERSION_NAMESPACE(v2)
364
365} // namespace msgpack
366
367#endif // MSGPACK_DEFAULT_API_VERSION >= 2
368
369#endif // MSGPACK_V2_UNPACK_HPP
Definition create_object_visitor.hpp:27
bool referenced() const
Definition create_object_visitor.hpp:67
void set(msgpack::object const &obj)
Definition object.hpp:64
msgpack::unique_ptr< msgpack::zone > & zone()
Get unique_ptr reference of zone.
Definition object.hpp:90
Parsing class for a stream deserialization.
Definition parse_decl.hpp:32
Definition unpack_decl.hpp:87
Unpacking class for a stream deserialization.
Definition unpack.hpp:862
msgpack::zone * release_zone()
Definition unpack.hpp:1286
void reset_zone()
Definition unpack.hpp:1300
~unpacker()
Definition unpack.hpp:1118
msgpack::object const & data()
Definition unpack.hpp:1281
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())
Constructor.
Definition unpack.hpp:1063
void reset()
Definition unpack.hpp:1321
unpacker & operator=(unpacker &&other)
Definition unpack.hpp:1107
bool next(msgpack::object_handle *result)
Unpack one msgpack::object. [obsolete].
Definition unpack.hpp:1253
void clear()
Definition cpp03_zone.hpp:325
void push_finalizer(void(*func)(void *), void *data)
Definition cpp03_zone.hpp:314
Definition check_container_size.hpp:31
parse_return parse_imp(const char *data, size_t len, size_t &off, Visitor &v)
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:1361
void decr_count(void *buffer)
Definition unpack.hpp:250
void incr_count(void *buffer)
Definition unpack.hpp:263
object_type
Definition object_fwd_decl.hpp:27
Definition adaptor_base.hpp:15
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
parse_return
Definition parse_return.hpp:23
@ PARSE_EXTRA_BYTES
Definition parse_return.hpp:25
@ PARSE_SUCCESS
Definition parse_return.hpp:24
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:1405
#define MSGPACK_NULLPTR
Definition cpp_config_decl.hpp:85
#define MSGPACK_UNPACKER_INIT_BUFFER_SIZE
Definition unpack_decl.hpp:43
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition versioning.hpp:66