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>,
36 public detail::create_object_visitor {
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 detail::create_object_visitor& visitor() { return *this; }
53
66 bool next(msgpack::object_handle& result, bool& referenced);
67
69
80 bool next(msgpack::object_handle& result);
82 void reset_zone();
83 bool flush_zone();
84private:
85 static bool default_reference_func(msgpack::type::object_type /*type*/, std::size_t /*len*/, void*) {
86 return true;
87 }
88 msgpack::unique_ptr<msgpack::zone> m_z;
89 zone_push_finalizer m_finalizer;
90};
91
92inline bool unpacker::next(msgpack::object_handle& result, bool& referenced) {
93 bool ret = parser_t::next();
94 if (ret) {
96 result.zone().reset( release_zone() );
97 result.set(data());
98 reset();
99 }
100 else {
101 result.zone().reset();
102 result.set(msgpack::object());
103 }
104 return ret;
105}
106
107inline bool unpacker::next(msgpack::object_handle& result) {
108 bool referenced;
109 return next(result, referenced);
110}
111
113{
114 if(!flush_zone()) {
115 return MSGPACK_NULLPTR;
116 }
117
119 msgpack::zone* old = m_z.release();
120 m_z.reset(r);
121 set_zone(*m_z);
122 m_finalizer.set_zone(*m_z);
123
124 return old;
125}
126
127inline void unpacker::reset_zone()
128{
129 m_z->clear();
130}
131
132inline bool unpacker::flush_zone()
133{
134 if(referenced()) {
135 try {
136 m_z->push_finalizer(&detail::decr_count, get_raw_buffer());
137 } catch (...) {
138 return false;
139 }
140 set_referenced(false);
141
142 detail::incr_count(get_raw_buffer());
143 }
144
145 return true;
146}
147
149 const char* data, std::size_t len, std::size_t& off, bool& referenced,
150 unpack_reference_func f, void* user_data,
151 unpack_limit const& limit
152)
153{
154 msgpack::object obj;
155 msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
156 referenced = false;
157 std::size_t noff = off;
158 parse_return ret = detail::unpack_imp(
159 data, len, noff, *z, obj, referenced, f, user_data, limit);
160
161 switch(ret) {
162 case PARSE_SUCCESS:
163 off = noff;
164 return msgpack::object_handle(obj, msgpack::move(z));
166 off = noff;
167 return msgpack::object_handle(obj, msgpack::move(z));
168 default:
169 break;
170 }
171 return msgpack::object_handle();
172}
173
175 const char* data, std::size_t len, std::size_t& off,
176 unpack_reference_func f, void* user_data,
177 unpack_limit const& limit)
178{
179 bool referenced;
180 return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
181}
182
184 const char* data, std::size_t len, bool& referenced,
185 unpack_reference_func f, void* user_data,
186 unpack_limit const& limit)
187{
188 std::size_t off = 0;
189 return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
190}
191
193 const char* data, std::size_t len,
194 unpack_reference_func f, void* user_data,
195 unpack_limit const& limit)
196{
197 bool referenced;
198 std::size_t off = 0;
199 return msgpack::v2::unpack(data, len, off, referenced, f, user_data, limit);
200}
201
202inline void unpack(
204 const char* data, std::size_t len, std::size_t& off, bool& referenced,
205 unpack_reference_func f, void* user_data,
206 unpack_limit const& limit)
207{
208 msgpack::object obj;
209 msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
210 referenced = false;
211 std::size_t noff = off;
212 parse_return ret = detail::unpack_imp(
213 data, len, noff, *z, obj, referenced, f, user_data, limit);
214
215 switch(ret) {
216 case PARSE_SUCCESS:
217 off = noff;
218 result.set(obj);
219 result.zone() = msgpack::move(z);
220 return;
222 off = noff;
223 result.set(obj);
224 result.zone() = msgpack::move(z);
225 return;
226 default:
227 return;
228 }
229}
230
231inline void unpack(
233 const char* data, std::size_t len, std::size_t& off,
234 unpack_reference_func f, void* user_data,
235 unpack_limit const& limit)
236{
237 bool referenced;
238 msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
239}
240
241inline void unpack(
243 const char* data, std::size_t len, bool& referenced,
244 unpack_reference_func f, void* user_data,
245 unpack_limit const& limit)
246{
247 std::size_t off = 0;
248 msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
249}
250
251inline void unpack(
253 const char* data, std::size_t len,
254 unpack_reference_func f, void* user_data,
255 unpack_limit const& limit)
256{
257 bool referenced;
258 std::size_t off = 0;
259 msgpack::v2::unpack(result, data, len, off, referenced, f, user_data, limit);
260}
261
262
264 msgpack::zone& z,
265 const char* data, std::size_t len, std::size_t& off, bool& referenced,
266 unpack_reference_func f, void* user_data,
267 unpack_limit const& limit)
268{
269 msgpack::object obj;
270 std::size_t noff = off;
271 referenced = false;
272 parse_return ret = detail::unpack_imp(
273 data, len, noff, z, obj, referenced, f, user_data, limit);
274
275 switch(ret) {
276 case PARSE_SUCCESS:
277 off = noff;
278 return obj;
280 off = noff;
281 return obj;
282 default:
283 break;
284 }
285 return obj;
286}
287
289 msgpack::zone& z,
290 const char* data, std::size_t len, std::size_t& off,
291 unpack_reference_func f, void* user_data,
292 unpack_limit const& limit)
293{
294 bool referenced;
295 return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
296}
297
299 msgpack::zone& z,
300 const char* data, std::size_t len, bool& referenced,
301 unpack_reference_func f, void* user_data,
302 unpack_limit const& limit)
303{
304 std::size_t off = 0;
305 return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
306}
307
309 msgpack::zone& z,
310 const char* data, std::size_t len,
311 unpack_reference_func f, void* user_data,
312 unpack_limit const& limit)
313{
314 bool referenced;
315 std::size_t off = 0;
316 return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
317}
318
319namespace detail {
320
321inline parse_return
322unpack_imp(const char* data, std::size_t len, std::size_t& off,
323 msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
325 unpack_limit const& limit = unpack_limit())
326{
327 create_object_visitor v(f, user_data, limit);
328 v.set_zone(result_zone);
329 referenced = false;
330 v.set_referenced(referenced);
331 parse_return ret = parse_imp(data, len, off, v);
332 referenced = v.referenced();
333 result = v.data();
334 return ret;
335}
336
337} // namespace detail
338
339
341} // MSGPACK_API_VERSION_NAMESPACE(v2)
343
344} // namespace msgpack
345
346#endif // MSGPACK_DEFAULT_API_VERSION >= 2
347
348#endif // MSGPACK_V2_UNPACK_HPP
bool referenced() const
Definition create_object_visitor.hpp:65
The class holds object and zone.
Definition object.hpp:44
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
msgpack::zone * release_zone()
Definition unpack.hpp:1277
void reset_zone()
Definition unpack.hpp:1291
msgpack::object const & data()
Definition unpack.hpp:1272
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:1062
void reset()
Definition unpack.hpp:1312
bool next(msgpack::object_handle *result)
Unpack one msgpack::object. [obsolete].
Definition unpack.hpp:1244
Definition cpp03_zone.hpp:30
void push_finalizer(void(*func)(void *), void *data)
Definition cpp03_zone.hpp:310
parse_return parse_imp(const char *data, size_t len, size_t &off, Visitor &v)
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:1396
Object class that corresponding to MessagePack format object.
Definition object_fwd.hpp:75
#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