MessagePack for C++
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 
15 #include "msgpack/unpack_decl.hpp"
16 #include "msgpack/parse.hpp"
18 
19 namespace msgpack {
20 
24 
25 
26 struct 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 
35 class unpacker : public parser<unpacker, zone_push_finalizer>,
36  public detail::create_object_visitor {
37  typedef parser<unpacker, zone_push_finalizer> parser_t;
38 public:
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();
84 private:
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 
92 inline 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 
107 inline 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 
118  msgpack::zone* r = new msgpack::zone;
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 
127 inline void unpacker::reset_zone()
128 {
129  m_z->clear();
130 }
131 
132 inline 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;
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));
165  case PARSE_EXTRA_BYTES:
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 
202 inline void unpack(
203  msgpack::object_handle& result,
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;
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;
221  case PARSE_EXTRA_BYTES:
222  off = noff;
223  result.set(obj);
224  result.zone() = msgpack::move(z);
225  return;
226  default:
227  return;
228  }
229 }
230 
231 inline void unpack(
232  msgpack::object_handle& result,
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 
241 inline void unpack(
242  msgpack::object_handle& result,
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 
251 inline void unpack(
252  msgpack::object_handle& result,
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 
263 inline msgpack::object unpack(
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;
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;
279  case PARSE_EXTRA_BYTES:
280  off = noff;
281  return obj;
282  default:
283  break;
284  }
285  return obj;
286 }
287 
288 inline msgpack::object unpack(
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 
298 inline msgpack::object unpack(
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 
308 inline msgpack::object unpack(
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 
319 namespace detail {
320 
321 inline parse_return
322 unpack_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:66
The class holds object and zone.
Definition: object.hpp:44
msgpack::unique_ptr< msgpack::zone > & zone()
Get unique_ptr reference of zone.
Definition: object.hpp:90
void set(msgpack::object const &obj)
Definition: object.hpp:64
msgpack::zone * release_zone()
Definition: unpack.hpp:1278
void reset_zone()
Definition: unpack.hpp:1292
msgpack::object const & data()
Definition: unpack.hpp:1273
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:1313
bool next(msgpack::object_handle *result)
Unpack one msgpack::object. [obsolete].
Definition: unpack.hpp:1245
Definition: cpp03_zone.hpp:31
void push_finalizer(void(*func)(void *), void *data)
Definition: cpp03_zone.hpp:311
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:1353
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
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
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:1397
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