1 //
2 // MessagePack for C++ deserializing routine
3 //
4 // Copyright (C) 2008-2016 FURUHASHI Sadayuki and 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_V1_UNPACK_DECL_HPP
11 #define MSGPACK_V1_UNPACK_DECL_HPP
12 
13 #include "msgpack/versioning.hpp"
14 #include "msgpack/unpack_define.h"
15 #include "msgpack/object.hpp"
16 #include "msgpack/zone.hpp"
17 #include "msgpack/cpp_config.hpp"
18 #include "msgpack/sysdep.h"
19 #include "msgpack/parse_return.hpp"
20 
21 #include <memory>
22 #include <stdexcept>
23 
24 #if !defined(MSGPACK_USE_CPP03)
25 #include <atomic>
26 #endif
27 
28 
29 #if defined(_MSC_VER)
30 // avoiding confliction std::max, std::min, and macro in windows.h
31 #ifndef NOMINMAX
32 #define NOMINMAX
33 #endif
34 #endif // defined(_MSC_VER)
35 
36 #ifdef _msgpack_atomic_counter_header
37 #include _msgpack_atomic_counter_header
38 #endif
39 
40 const size_t COUNTER_SIZE = sizeof(_msgpack_atomic_counter_t);
41 
42 #ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE
43 #define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024)
44 #endif
45 
46 #ifndef MSGPACK_UNPACKER_RESERVE_SIZE
47 #define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024)
48 #endif
49 
50 
51 // backward compatibility
52 #ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
53 #define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE
54 #endif
55 
56 
57 namespace msgpack {
58 
59 /// @cond
MSGPACK_API_VERSION_NAMESPACE(v1)60 MSGPACK_API_VERSION_NAMESPACE(v1) {
61 /// @endcond
62 
63 /// The type of reference or copy judging function.
64 /**
65  * @param type msgpack data type.
66  * @param size msgpack data size.
67  * @param user_data The user_data that is set by msgpack::unpack functions.
68  *
69  * @return If the data should be referenced, then return true, otherwise (should be copied) false.
70  *
71  * This function is called when unpacking STR, BIN, or EXT.
72  *
73  */
74 typedef bool (*unpack_reference_func)(msgpack::type::object_type type, std::size_t size, void* user_data);
75 
76 struct unpack_error;
77 struct parse_error;
78 struct insufficient_bytes;
79 struct size_overflow;
80 struct array_size_overflow;
81 struct map_size_overflow;
82 struct str_size_overflow;
83 struct bin_size_overflow;
84 struct ext_size_overflow;
85 struct depth_size_overflow;
86 
87 class unpack_limit {
88 public:
89     unpack_limit(
90         std::size_t array = 0xffffffff,
91         std::size_t map = 0xffffffff,
92         std::size_t str = 0xffffffff,
93         std::size_t bin = 0xffffffff,
94         std::size_t ext = 0xffffffff,
95         std::size_t depth = 0xffffffff)
96         :array_(array),
97          map_(map),
98          str_(str),
99          bin_(bin),
100          ext_(ext),
101          depth_(depth) {}
102     std::size_t array() const { return array_; }
103     std::size_t map() const { return map_; }
104     std::size_t str() const { return str_; }
105     std::size_t bin() const { return bin_; }
106     std::size_t ext() const { return ext_; }
107     std::size_t depth() const { return depth_; }
108 
109 private:
110     std::size_t array_;
111     std::size_t map_;
112     std::size_t str_;
113     std::size_t bin_;
114     std::size_t ext_;
115     std::size_t depth_;
116 };
117 
118 namespace detail {
119 
120 class unpack_user;
121 
122 void unpack_uint8(uint8_t d, msgpack::object& o);
123 
124 void unpack_uint16(uint16_t d, msgpack::object& o);
125 
126 void unpack_uint32(uint32_t d, msgpack::object& o);
127 
128 void unpack_uint64(uint64_t d, msgpack::object& o);
129 
130 void unpack_int8(int8_t d, msgpack::object& o);
131 
132 void unpack_int16(int16_t d, msgpack::object& o);
133 
134 void unpack_int32(int32_t d, msgpack::object& o);
135 
136 void unpack_int64(int64_t d, msgpack::object& o);
137 
138 void unpack_float(float d, msgpack::object& o);
139 
140 void unpack_double(double d, msgpack::object& o);
141 
142 void unpack_nil(msgpack::object& o);
143 
144 void unpack_true(msgpack::object& o);
145 
146 void unpack_false(msgpack::object& o);
147 
148 struct unpack_array;
149 
150 void unpack_array_item(msgpack::object& c, msgpack::object const& o);
151 
152 struct unpack_map;
153 
154 void unpack_map_item(msgpack::object& c, msgpack::object const& k, msgpack::object const& v);
155 
156 void unpack_str(unpack_user& u, const char* p, uint32_t l, msgpack::object& o);
157 
158 void unpack_bin(unpack_user& u, const char* p, uint32_t l, msgpack::object& o);
159 
160 void unpack_ext(unpack_user& u, const char* p, std::size_t l, msgpack::object& o);
161 
162 class unpack_stack;
163 
164 void init_count(void* buffer);
165 
166 void decr_count(void* buffer);
167 
168 void incr_count(void* buffer);
169 
170 #if defined(MSGPACK_USE_CPP03)
171 
172 _msgpack_atomic_counter_t get_count(void* buffer);
173 
174 #else  // defined(MSGPACK_USE_CPP03)
175 
176 std::atomic<unsigned int> const& get_count(void* buffer);
177 
178 #endif // defined(MSGPACK_USE_CPP03)
179 
180 struct fix_tag {
181     char f1[65]; // FIXME unique size is required. or use is_same meta function.
182 };
183 
184 template <typename T>
185 struct value;
186 
187 template <typename T>
188 typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type load(uint32_t& dst, const char* n);
189 
190 template <typename T>
191 typename msgpack::enable_if<sizeof(T) == 1>::type load(T& dst, const char* n);
192 
193 template <typename T>
194 typename msgpack::enable_if<sizeof(T) == 2>::type load(T& dst, const char* n);
195 
196 template <typename T>
197 typename msgpack::enable_if<sizeof(T) == 4>::type load(T& dst, const char* n);
198 
199 template <typename T>
200 typename msgpack::enable_if<sizeof(T) == 8>::type load(T& dst, const char* n);
201 
202 class context;
203 
204 } // detail
205 
206 
207 typedef object_handle unpacked;
208 
209 /// Unpacking class for a stream deserialization.
210 class unpacker;
211 
212 /// Unpack msgpack::object from a buffer.
213 /**
214  * @param data The pointer to the buffer.
215  * @param len The length of the buffer.
216  * @param off The offset position of the buffer. It is read and overwritten.
217  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
218  * @param f A judging function that msgpack::object refer to the buffer.
219  * @param user_data This parameter is passed to f.
220  * @param limit The size limit information of msgpack::object.
221  *
222  * @return object_handle that contains unpacked data.
223  *
224  */
225 object_handle unpack(
226     const char* data, std::size_t len, std::size_t& off, bool& referenced,
227     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
228 
229 /// Unpack msgpack::object from a buffer.
230 /**
231  * @param data The pointer to the buffer.
232  * @param len The length of the buffer.
233  * @param off The offset position of the buffer. It is read and overwritten.
234  * @param f A judging function that msgpack::object refer to the buffer.
235  * @param user_data This parameter is passed to f.
236  * @param limit The size limit information of msgpack::object.
237  *
238  * @return object_handle that contains unpacked data.
239  *
240  */
241 object_handle unpack(
242     const char* data, std::size_t len, std::size_t& off,
243     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
244 
245 /// Unpack msgpack::object from a buffer.
246 /**
247  * @param data The pointer to the buffer.
248  * @param len The length of the buffer.
249  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
250  * @param f A judging function that msgpack::object refer to the buffer.
251  * @param user_data This parameter is passed to f.
252  * @param limit The size limit information of msgpack::object.
253  *
254  * @return object_handle that contains unpacked data.
255  *
256  */
257 object_handle unpack(
258     const char* data, std::size_t len, bool& referenced,
259     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
260 
261 /// Unpack msgpack::object from a buffer.
262 /**
263  * @param data The pointer to the buffer.
264  * @param len The length of the buffer.
265  * @param f A judging function that msgpack::object refer to the buffer.
266  * @param user_data This parameter is passed to f.
267  * @param limit The size limit information of msgpack::object.
268  *
269  * @return object_handle that contains unpacked data.
270  *
271  */
272 object_handle unpack(
273     const char* data, std::size_t len,
274     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
275 
276 
277 /// Unpack msgpack::object from a buffer.
278 /**
279  * @param result The object_handle that contains unpacked data.
280  * @param data The pointer to the buffer.
281  * @param len The length of the buffer.
282  * @param off The offset position of the buffer. It is read and overwritten.
283  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
284  * @param f A judging function that msgpack::object refer to the buffer.
285  * @param user_data This parameter is passed to f.
286  * @param limit The size limit information of msgpack::object.
287  *
288  *
289  */
290 void unpack(
291     object_handle& result,
292     const char* data, std::size_t len, std::size_t& off, bool& referenced,
293     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
294 
295 /// Unpack msgpack::object from a buffer.
296 /**
297  * @param result The object_handle that contains unpacked data.
298  * @param data The pointer to the buffer.
299  * @param len The length of the buffer.
300  * @param off The offset position of the buffer. It is read and overwritten.
301  * @param f A judging function that msgpack::object refer to the buffer.
302  * @param user_data This parameter is passed to f.
303  * @param limit The size limit information of msgpack::object.
304  *
305  *
306  */
307 void unpack(
308     object_handle& result,
309     const char* data, std::size_t len, std::size_t& off,
310     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
311 
312 /// Unpack msgpack::object from a buffer.
313 /**
314  * @param result The object_handle that contains unpacked data.
315  * @param data The pointer to the buffer.
316  * @param len The length of the buffer.
317  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
318  * @param f A judging function that msgpack::object refer to the buffer.
319  * @param user_data This parameter is passed to f.
320  * @param limit The size limit information of msgpack::object.
321  *
322  *
323  */
324 void unpack(
325     object_handle& result,
326     const char* data, std::size_t len, bool& referenced,
327     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
328 
329 /// Unpack msgpack::object from a buffer.
330 /**
331  * @param result The object_handle that contains unpacked data.
332  * @param data The pointer to the buffer.
333  * @param len The length of the buffer.
334  * @param f A judging function that msgpack::object refer to the buffer.
335  * @param user_data This parameter is passed to f.
336  * @param limit The size limit information of msgpack::object.
337  *
338  *
339  */
340 void unpack(
341     object_handle& result,
342     const char* data, std::size_t len,
343     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
344 
345 /// Unpack msgpack::object from a buffer.
346 /**
347  * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects.
348  * @param data The pointer to the buffer.
349  * @param len The length of the buffer.
350  * @param off The offset position of the buffer. It is read and overwritten.
351  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
352  * @param f A judging function that msgpack::object refer to the buffer.
353  * @param user_data This parameter is passed to f.
354  * @param limit The size limit information of msgpack::object.
355  *
356  * @return msgpack::object that contains unpacked data.
357  *
358  */
359 msgpack::object unpack(
360     msgpack::zone& z,
361     const char* data, std::size_t len, std::size_t& off, bool& referenced,
362     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
363 
364 /// Unpack msgpack::object from a buffer.
365 /**
366  * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects.
367  * @param data The pointer to the buffer.
368  * @param len The length of the buffer.
369  * @param off The offset position of the buffer. It is read and overwritten.
370  * @param f A judging function that msgpack::object refer to the buffer.
371  * @param user_data This parameter is passed to f.
372  * @param limit The size limit information of msgpack::object.
373  *
374  * @return msgpack::object that contains unpacked data.
375  *
376  */
377 msgpack::object unpack(
378     msgpack::zone& z,
379     const char* data, std::size_t len, std::size_t& off,
380     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
381 
382 /// Unpack msgpack::object from a buffer.
383 /**
384  * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects.
385  * @param data The pointer to the buffer.
386  * @param len The length of the buffer.
387  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
388  * @param f A judging function that msgpack::object refer to the buffer.
389  * @param user_data This parameter is passed to f.
390  * @param limit The size limit information of msgpack::object.
391  *
392  * @return msgpack::object that contains unpacked data.
393  *
394  */
395 msgpack::object unpack(
396     msgpack::zone& z,
397     const char* data, std::size_t len, bool& referenced,
398     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
399 
400 /// Unpack msgpack::object from a buffer.
401 /**
402  * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects.
403  * @param data The pointer to the buffer.
404  * @param len The length of the buffer.
405  * @param f A judging function that msgpack::object refer to the buffer.
406  * @param user_data This parameter is passed to f.
407  * @param limit The size limit information of msgpack::object.
408  *
409  * @return msgpack::object that contains unpacked data.
410  *
411  */
412 msgpack::object unpack(
413     msgpack::zone& z,
414     const char* data, std::size_t len,
415     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
416 
417 
418 /// Unpack msgpack::object from a buffer. [obsolete]
419 /**
420  * @param result The object_handle that contains unpacked data.
421  * @param data The pointer to the buffer.
422  * @param len The length of the buffer.
423  * @param off The offset position of the buffer. It is read and overwritten.
424  * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false.
425  * @param f A judging function that msgpack::object refer to the buffer.
426  * @param user_data This parameter is passed to f.
427  * @param limit The size limit information of msgpack::object.
428  *
429  * This function is obsolete. Use the reference inteface version of unpack functions instead of the pointer interface version.
430  */
431 void unpack(
432     object_handle* result,
433     const char* data, std::size_t len, std::size_t* off = MSGPACK_NULLPTR, bool* referenced = MSGPACK_NULLPTR,
434     unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
435 
436 
437 namespace detail {
438 
439 parse_return
440 unpack_imp(const char* data, std::size_t len, std::size_t& off,
441            msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
442            unpack_reference_func f, void* user_data,
443            unpack_limit const& limit);
444 
445 } // detail
446 
447 
448 /// @cond
449 }  // MSGPACK_API_VERSION_NAMESPACE(v1)
450 /// @endcond
451 
452 }  // namespace msgpack
453 
454 #endif // MSGPACK_V1_UNPACK_DECL_HPP
455