messagepack implementation for embedded systems (mbed / arduino)
Dependents: hello_message_pack
unpack.hpp
00001 // 00002 // MessagePack for C++ deserializing routine 00003 // 00004 // Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi 00005 // 00006 // Distributed under the Boost Software License, Version 1.0. 00007 // (See accompanying file LICENSE_1_0.txt or copy at 00008 // http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 #ifndef MSGPACK_UNPACK_HPP 00011 #define MSGPACK_UNPACK_HPP 00012 00013 #include "msgpack/versioning.hpp" 00014 #include "object.hpp" 00015 #include "zone.hpp" 00016 #include "../unpack_define.h" 00017 #include "cpp_config.hpp" 00018 #include "../sysdep.h" 00019 00020 #include <memory> 00021 #include <stdexcept> 00022 00023 #if !defined(MSGPACK_USE_CPP03) 00024 #include <atomic> 00025 #endif 00026 00027 00028 #if defined(_MSC_VER) 00029 // avoiding confliction std::max, std::min, and macro in windows.h 00030 #ifndef NOMINMAX 00031 #define NOMINMAX 00032 #endif 00033 #endif // defined(_MSC_VER) 00034 00035 #ifdef _msgpack_atomic_counter_header 00036 #include _msgpack_atomic_counter_header 00037 #endif 00038 00039 00040 const size_t COUNTER_SIZE = sizeof(_msgpack_atomic_counter_t); 00041 00042 #ifndef MSGPACK_UNPACKER_INIT_BUFFER_SIZE 00043 #if defined(__MBED__) 00044 #define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (32*32) 00045 #elif defined(__AVR__) 00046 #define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (8*32) 00047 #else 00048 #define MSGPACK_UNPACKER_INIT_BUFFER_SIZE (64*1024) 00049 #endif 00050 #endif 00051 00052 #ifndef MSGPACK_UNPACKER_RESERVE_SIZE 00053 #if defined(__MBED__) 00054 #define MSGPACK_UNPACKER_RESERVE_SIZE (16*32) 00055 #elif defined(__AVR__) 00056 #define MSGPACK_UNPACKER_RESERVE_SIZE (4*32) 00057 #else 00058 #define MSGPACK_UNPACKER_RESERVE_SIZE (32*1024) 00059 #endif 00060 #endif 00061 00062 00063 // backward compatibility 00064 #ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE 00065 #define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE 00066 #endif 00067 00068 00069 namespace msgpack { 00070 00071 /// @cond 00072 MSGPACK_API_VERSION_NAMESPACE(v1) { 00073 /// @endcond 00074 00075 /// The type of reference or copy judging function. 00076 /** 00077 * @param type msgpack data type. 00078 * @param size msgpack data size. 00079 * @param user_data The user_data that is set by msgpack::unpack functions. 00080 * 00081 * @return If the data should be referenced, then return true, otherwise (should be copied) false. 00082 * 00083 * This function is called when unpacking STR, BIN, or EXT. 00084 * 00085 */ 00086 typedef bool (*unpack_reference_func)(msgpack::type::object_type type, std::size_t size, void* user_data); 00087 00088 struct unpack_error : public std::runtime_error { 00089 explicit unpack_error(const std::string& msg) 00090 :std::runtime_error(msg) {} 00091 #if !defined(MSGPACK_USE_CPP03) 00092 explicit unpack_error(const char* msg): 00093 std::runtime_error(msg) {} 00094 #endif // !defined(MSGPACK_USE_CPP03) 00095 }; 00096 00097 struct parse_error : public unpack_error { 00098 explicit parse_error(const std::string& msg) 00099 :unpack_error(msg) {} 00100 #if !defined(MSGPACK_USE_CPP03) 00101 explicit parse_error(const char* msg) 00102 :unpack_error(msg) {} 00103 #endif // !defined(MSGPACK_USE_CPP03) 00104 }; 00105 00106 struct insufficient_bytes : public unpack_error { 00107 explicit insufficient_bytes(const std::string& msg) 00108 :unpack_error(msg) {} 00109 #if !defined(MSGPACK_USE_CPP03) 00110 explicit insufficient_bytes(const char* msg) 00111 :unpack_error(msg) {} 00112 #endif // !defined(MSGPACK_USE_CPP03) 00113 }; 00114 00115 struct size_overflow : public unpack_error { 00116 explicit size_overflow(const std::string& msg) 00117 :unpack_error(msg) {} 00118 #if !defined(MSGPACK_USE_CPP03) 00119 explicit size_overflow(const char* msg) 00120 :unpack_error(msg) {} 00121 #endif 00122 }; 00123 00124 struct array_size_overflow : public size_overflow { 00125 array_size_overflow(const std::string& msg) 00126 :size_overflow(msg) {} 00127 #if !defined(MSGPACK_USE_CPP03) 00128 array_size_overflow(const char* msg) 00129 :size_overflow(msg) {} 00130 #endif 00131 }; 00132 00133 struct map_size_overflow : public size_overflow { 00134 map_size_overflow(const std::string& msg) 00135 :size_overflow(msg) {} 00136 #if !defined(MSGPACK_USE_CPP03) 00137 map_size_overflow(const char* msg) 00138 :size_overflow(msg) {} 00139 #endif 00140 }; 00141 00142 struct str_size_overflow : public size_overflow { 00143 str_size_overflow(const std::string& msg) 00144 :size_overflow(msg) {} 00145 #if !defined(MSGPACK_USE_CPP03) 00146 str_size_overflow(const char* msg) 00147 :size_overflow(msg) {} 00148 #endif 00149 }; 00150 00151 struct bin_size_overflow : public size_overflow { 00152 bin_size_overflow(const std::string& msg) 00153 :size_overflow(msg) {} 00154 #if !defined(MSGPACK_USE_CPP03) 00155 bin_size_overflow(const char* msg) 00156 :size_overflow(msg) {} 00157 #endif 00158 }; 00159 00160 struct ext_size_overflow : public size_overflow { 00161 ext_size_overflow(const std::string& msg) 00162 :size_overflow(msg) {} 00163 #if !defined(MSGPACK_USE_CPP03) 00164 ext_size_overflow(const char* msg) 00165 :size_overflow(msg) {} 00166 #endif 00167 }; 00168 00169 struct depth_size_overflow : public size_overflow { 00170 depth_size_overflow(const std::string& msg) 00171 :size_overflow(msg) {} 00172 #if !defined(MSGPACK_USE_CPP03) 00173 depth_size_overflow(const char* msg) 00174 :size_overflow(msg) {} 00175 #endif 00176 }; 00177 00178 class unpack_limit { 00179 public: 00180 unpack_limit( 00181 std::size_t array = 0xffffffff, 00182 std::size_t map = 0xffffffff, 00183 std::size_t str = 0xffffffff, 00184 std::size_t bin = 0xffffffff, 00185 std::size_t ext = 0xffffffff, 00186 std::size_t depth = 0xffffffff) 00187 :array_(array), 00188 map_(map), 00189 str_(str), 00190 bin_(bin), 00191 ext_(ext), 00192 depth_(depth) {} 00193 std::size_t array() const { return array_; } 00194 std::size_t map() const { return map_; } 00195 std::size_t str() const { return str_; } 00196 std::size_t bin() const { return bin_; } 00197 std::size_t ext() const { return ext_; } 00198 std::size_t depth() const { return depth_; } 00199 00200 private: 00201 std::size_t array_; 00202 std::size_t map_; 00203 std::size_t str_; 00204 std::size_t bin_; 00205 std::size_t ext_; 00206 std::size_t depth_; 00207 }; 00208 00209 namespace detail { 00210 00211 class unpack_user { 00212 public: 00213 unpack_user(unpack_reference_func f = nullptr, 00214 void* user_data = nullptr, 00215 unpack_limit const& limit = unpack_limit()) 00216 :m_func(f), m_user_data(user_data), m_limit(limit) {} 00217 msgpack::zone const& zone() const { return *m_zone; } 00218 msgpack::zone& zone() { return *m_zone; } 00219 void set_zone(msgpack::zone& zone) { m_zone = &zone; } 00220 bool referenced() const { return m_referenced; } 00221 void set_referenced(bool referenced) { m_referenced = referenced; } 00222 unpack_reference_func reference_func() const { return m_func; } 00223 void* user_data() const { return m_user_data; } 00224 unpack_limit const& limit() const { return m_limit; } 00225 unpack_limit& limit() { return m_limit; } 00226 00227 private: 00228 msgpack::zone* m_zone; 00229 bool m_referenced; 00230 unpack_reference_func m_func; 00231 void* m_user_data; 00232 unpack_limit m_limit; 00233 }; 00234 00235 inline void unpack_uint8(uint8_t d, msgpack::object& o) 00236 { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00237 00238 inline void unpack_uint16(uint16_t d, msgpack::object& o) 00239 { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00240 00241 inline void unpack_uint32(uint32_t d, msgpack::object& o) 00242 { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00243 00244 inline void unpack_uint64(uint64_t d, msgpack::object& o) 00245 { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00246 00247 inline void unpack_int8(int8_t d, msgpack::object& o) 00248 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00249 else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } } 00250 00251 inline void unpack_int16(int16_t d, msgpack::object& o) 00252 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00253 else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } } 00254 00255 inline void unpack_int32(int32_t d, msgpack::object& o) 00256 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00257 else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } } 00258 00259 inline void unpack_int64(int64_t d, msgpack::object& o) 00260 { if(d >= 0) { o.type = msgpack::type::POSITIVE_INTEGER; o.via.u64 = d; } 00261 else { o.type = msgpack::type::NEGATIVE_INTEGER; o.via.i64 = d; } } 00262 00263 inline void unpack_float(float d, msgpack::object& o) 00264 { o.type = msgpack::type::FLOAT; o.via.f64 = d; } 00265 00266 inline void unpack_double(double d, msgpack::object& o) 00267 { o.type = msgpack::type::FLOAT; o.via.f64 = d; } 00268 00269 inline void unpack_nil(msgpack::object& o) 00270 { o.type = msgpack::type::NIL; } 00271 00272 inline void unpack_true(msgpack::object& o) 00273 { o.type = msgpack::type::BOOLEAN; o.via.boolean = true; } 00274 00275 inline void unpack_false(msgpack::object& o) 00276 { o.type = msgpack::type::BOOLEAN; o.via.boolean = false; } 00277 00278 struct unpack_array { 00279 void operator()(unpack_user& u, uint32_t n, msgpack::object& o) const { 00280 if (n > u.limit().array()) 00281 printf("array size overflow\n"); 00282 // throw msgpack::array_size_overflow("array size overflow"); 00283 o.type = msgpack::type::ARRAY; 00284 o.via.array.size = 0; 00285 o.via.array.ptr = static_cast<msgpack::object*>(u.zone().allocate_align(n*sizeof(msgpack::object))); 00286 } 00287 }; 00288 00289 inline void unpack_array_item(msgpack::object& c, msgpack::object const& o) 00290 { 00291 #if defined(__GNUC__) && !defined(__clang__) 00292 std::memcpy(&c.via.array.ptr[c.via.array.size++], &o, sizeof(msgpack::object)); 00293 #else /* __GNUC__ && !__clang__ */ 00294 c.via.array.ptr[c.via.array.size++] = o; 00295 #endif /* __GNUC__ && !__clang__ */ 00296 } 00297 00298 struct unpack_map { 00299 void operator()(unpack_user& u, uint32_t n, msgpack::object& o) const { 00300 if (n > u.limit().map()) 00301 printf("map size overflow\n"); 00302 // throw msgpack::map_size_overflow("map size overflow"); 00303 o.type = msgpack::type::MAP; 00304 o.via.map.size = 0; 00305 o.via.map.ptr = static_cast<msgpack::object_kv*>(u.zone().allocate_align(n*sizeof(msgpack::object_kv))); 00306 } 00307 }; 00308 00309 inline void unpack_map_item(msgpack::object& c, msgpack::object const& k, msgpack::object const& v) 00310 { 00311 #if defined(__GNUC__) && !defined(__clang__) 00312 std::memcpy(&c.via.map.ptr[c.via.map.size].key, &k, sizeof(msgpack::object)); 00313 std::memcpy(&c.via.map.ptr[c.via.map.size].val, &v, sizeof(msgpack::object)); 00314 #else /* __GNUC__ && !__clang__ */ 00315 c.via.map.ptr[c.via.map.size].key = k; 00316 c.via.map.ptr[c.via.map.size].val = v; 00317 #endif /* __GNUC__ && !__clang__ */ 00318 ++c.via.map.size; 00319 } 00320 00321 inline void unpack_str(unpack_user& u, const char* p, uint32_t l, msgpack::object& o) 00322 { 00323 o.type = msgpack::type::STR; 00324 if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) { 00325 o.via.str.ptr = p; 00326 u.set_referenced(true); 00327 } 00328 else { 00329 if (l > u.limit().str()) 00330 printf("str size overflow\n"); 00331 // throw msgpack::str_size_overflow("str size overflow"); 00332 char* tmp = static_cast<char*>(u.zone().allocate_align(l)); 00333 std::memcpy(tmp, p, l); 00334 o.via.str.ptr = tmp; 00335 } 00336 o.via.str.size = l; 00337 } 00338 00339 inline void unpack_bin(unpack_user& u, const char* p, uint32_t l, msgpack::object& o) 00340 { 00341 o.type = msgpack::type::BIN; 00342 if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) { 00343 o.via.bin.ptr = p; 00344 u.set_referenced(true); 00345 } 00346 else { 00347 if (l > u.limit().bin()) 00348 printf("bin size overflow\n"); 00349 // throw msgpack::bin_size_overflow("bin size overflow"); 00350 char* tmp = static_cast<char*>(u.zone().allocate_align(l)); 00351 std::memcpy(tmp, p, l); 00352 o.via.bin.ptr = tmp; 00353 } 00354 o.via.bin.size = l; 00355 } 00356 00357 inline void unpack_ext(unpack_user& u, const char* p, std::size_t l, msgpack::object& o) 00358 { 00359 o.type = msgpack::type::EXT; 00360 if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) { 00361 o.via.ext.ptr = p; 00362 u.set_referenced(true); 00363 } 00364 else { 00365 if (l > u.limit().ext()) 00366 printf("ext size overflow\n"); 00367 // throw msgpack::ext_size_overflow("ext size overflow"); 00368 char* tmp = static_cast<char*>(u.zone().allocate_align(l)); 00369 std::memcpy(tmp, p, l); 00370 o.via.ext.ptr = tmp; 00371 } 00372 o.via.ext.size = static_cast<uint32_t>(l - 1); 00373 } 00374 00375 00376 class unpack_stack { 00377 public: 00378 msgpack::object const& obj() const { return m_obj; } 00379 msgpack::object& obj() { return m_obj; } 00380 void set_obj(msgpack::object const& obj) { m_obj = obj; } 00381 std::size_t count() const { return m_count; } 00382 void set_count(std::size_t count) { m_count = count; } 00383 std::size_t decr_count() { return --m_count; } 00384 uint32_t container_type() const { return m_container_type; } 00385 void set_container_type(uint32_t container_type) { m_container_type = container_type; } 00386 msgpack::object const& map_key() const { return m_map_key; } 00387 void set_map_key(msgpack::object const& map_key) { m_map_key = map_key; } 00388 private: 00389 msgpack::object m_obj; 00390 std::size_t m_count; 00391 uint32_t m_container_type; 00392 msgpack::object m_map_key; 00393 }; 00394 00395 inline void init_count(void* buffer) 00396 { 00397 #if defined(MSGPACK_USE_CPP03) 00398 *reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer) = 1; 00399 #else // defined(MSGPACK_USE_CPP03) 00400 new (buffer) std::atomic<unsigned int>(1); 00401 #endif // defined(MSGPACK_USE_CPP03) 00402 } 00403 00404 inline void decr_count(void* buffer) 00405 { 00406 #if defined(MSGPACK_USE_CPP03) 00407 if(_msgpack_sync_decr_and_fetch(reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer)) == 0) { 00408 free(buffer); 00409 } 00410 #else // defined(MSGPACK_USE_CPP03) 00411 if (--*reinterpret_cast<std::atomic<unsigned int>*>(buffer) == 0) { 00412 free(buffer); 00413 } 00414 #endif // defined(MSGPACK_USE_CPP03) 00415 } 00416 00417 inline void incr_count(void* buffer) 00418 { 00419 #if defined(MSGPACK_USE_CPP03) 00420 _msgpack_sync_incr_and_fetch(reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer)); 00421 #else // defined(MSGPACK_USE_CPP03) 00422 ++*reinterpret_cast<std::atomic<unsigned int>*>(buffer); 00423 #endif // defined(MSGPACK_USE_CPP03) 00424 } 00425 00426 #if defined(MSGPACK_USE_CPP03) 00427 inline _msgpack_atomic_counter_t get_count(void* buffer) 00428 { 00429 return *reinterpret_cast<volatile _msgpack_atomic_counter_t*>(buffer); 00430 } 00431 #else // defined(MSGPACK_USE_CPP03) 00432 inline std::atomic<unsigned int> const& get_count(void* buffer) 00433 { 00434 return *reinterpret_cast<std::atomic<unsigned int>*>(buffer); 00435 } 00436 #endif // defined(MSGPACK_USE_CPP03) 00437 00438 struct fix_tag { 00439 char f1[65]; // FIXME unique size is required. or use is_same meta function. 00440 }; 00441 00442 template <typename T> 00443 struct value { 00444 typedef T type; 00445 }; 00446 template <> 00447 struct value<fix_tag> { 00448 typedef uint32_t type; 00449 }; 00450 00451 template <typename T> 00452 inline void load(uint32_t& dst, const char* n, typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type* = nullptr) { 00453 dst = static_cast<uint32_t>(*reinterpret_cast<const uint8_t*>(n)) & 0x0f; 00454 } 00455 00456 template <typename T> 00457 inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 1>::type* = nullptr) { 00458 dst = static_cast<T>(*reinterpret_cast<const uint8_t*>(n)); 00459 } 00460 00461 template <typename T> 00462 inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 2>::type* = nullptr) { 00463 _msgpack_load16(T, n, &dst); 00464 } 00465 00466 template <typename T> 00467 inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 4>::type* = nullptr) { 00468 _msgpack_load32(T, n, &dst); 00469 } 00470 00471 template <typename T> 00472 inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) == 8>::type* = nullptr) { 00473 _msgpack_load64(T, n, &dst); 00474 } 00475 00476 class context { 00477 public: 00478 context(unpack_reference_func f, void* user_data, unpack_limit const& limit) 00479 :m_trail(0), m_user(f, user_data, limit), m_cs(MSGPACK_CS_HEADER) 00480 { 00481 m_stack.reserve(MSGPACK_EMBED_STACK_SIZE); 00482 m_stack.push_back(unpack_stack()); 00483 } 00484 00485 void init() 00486 { 00487 m_cs = MSGPACK_CS_HEADER; 00488 m_trail = 0; 00489 m_stack.resize(1); 00490 m_stack[0].set_obj(msgpack::object()); 00491 } 00492 00493 msgpack::object const& data() const 00494 { 00495 return m_stack[0].obj(); 00496 } 00497 00498 unpack_user& user() 00499 { 00500 return m_user; 00501 } 00502 00503 unpack_user const& user() const 00504 { 00505 return m_user; 00506 } 00507 00508 int execute(const char* data, std::size_t len, std::size_t& off); 00509 00510 private: 00511 template <typename T> 00512 static uint32_t next_cs(T p) 00513 { 00514 return static_cast<uint32_t>(*p) & 0x1f; 00515 } 00516 00517 template <typename T, typename Func> 00518 int push_aggregate( 00519 Func const& f, 00520 uint32_t container_type, 00521 msgpack::object& obj, 00522 const char* load_pos, 00523 std::size_t& off) { 00524 typename value<T>::type tmp; 00525 load<T>(tmp, load_pos); 00526 f(m_user, tmp, m_stack.back().obj()); 00527 if(tmp == 0) { 00528 obj = m_stack.back().obj(); 00529 int ret = push_proc(obj, off); 00530 if (ret != 0) return ret; 00531 } 00532 else { 00533 m_stack.back().set_container_type(container_type); 00534 m_stack.back().set_count(tmp); 00535 if (m_stack.size() <= m_user.limit().depth()) { 00536 m_stack.push_back(unpack_stack()); 00537 } 00538 else { 00539 printf("depth size overflow\n"); 00540 // throw msgpack::depth_size_overflow("depth size overflow"); 00541 } 00542 m_cs = MSGPACK_CS_HEADER; 00543 ++m_current; 00544 } 00545 return 0; 00546 } 00547 00548 int push_item(msgpack::object& obj) { 00549 bool finish = false; 00550 while (!finish) { 00551 if(m_stack.size() == 1) { 00552 return 1; 00553 } 00554 unpack_stack& sp = *(m_stack.end() - 2); 00555 switch(sp.container_type()) { 00556 case MSGPACK_CT_ARRAY_ITEM: 00557 unpack_array_item(sp.obj(), obj); 00558 if(sp.decr_count() == 0) { 00559 obj = sp.obj(); 00560 m_stack.pop_back(); 00561 } 00562 else { 00563 finish = true; 00564 } 00565 break; 00566 case MSGPACK_CT_MAP_KEY: 00567 sp.set_map_key(obj); 00568 sp.set_container_type(MSGPACK_CT_MAP_VALUE); 00569 finish = true; 00570 break; 00571 case MSGPACK_CT_MAP_VALUE: 00572 unpack_map_item(sp.obj(), sp.map_key(), obj); 00573 if(sp.decr_count() == 0) { 00574 obj = sp.obj(); 00575 m_stack.pop_back(); 00576 } 00577 else { 00578 sp.set_container_type(MSGPACK_CT_MAP_KEY); 00579 finish = true; 00580 } 00581 break; 00582 default: 00583 return -1; 00584 } 00585 } 00586 return 0; 00587 } 00588 00589 int push_proc(msgpack::object& obj, std::size_t& off) { 00590 int ret = push_item(obj); 00591 if (ret > 0) { 00592 m_stack[0].set_obj(obj); 00593 ++m_current; 00594 /*printf("-- finish --\n"); */ 00595 off = m_current - m_start; 00596 } 00597 else if (ret < 0) { 00598 off = m_current - m_start; 00599 } 00600 else { 00601 m_cs = MSGPACK_CS_HEADER; 00602 ++m_current; 00603 } 00604 return ret; 00605 } 00606 00607 template <std::size_t N> 00608 static void check_ext_size(std::size_t /*size*/) { 00609 } 00610 00611 private: 00612 char const* m_start; 00613 char const* m_current; 00614 00615 std::size_t m_trail; 00616 unpack_user m_user; 00617 uint32_t m_cs; 00618 std::vector<unpack_stack> m_stack; 00619 }; 00620 00621 template <> 00622 inline void context::check_ext_size<4>(std::size_t size) { 00623 if (size == 0xffffffff) 00624 printf("ext size overflow\n"); 00625 // throw msgpack::ext_size_overflow("ext size overflow"); 00626 } 00627 00628 inline int context::execute(const char* data, std::size_t len, std::size_t& off) 00629 { 00630 assert(len >= off); 00631 00632 m_start = data; 00633 m_current = data + off; 00634 const char* const pe = data + len; 00635 const char* n = nullptr; 00636 00637 msgpack::object obj; 00638 00639 if(m_current == pe) { 00640 off = m_current - m_start; 00641 return 0; 00642 } 00643 bool fixed_trail_again = false; 00644 do { 00645 if (m_cs == MSGPACK_CS_HEADER) { 00646 fixed_trail_again = false; 00647 int selector = *reinterpret_cast<const unsigned char*>(m_current); 00648 if (0x00 <= selector && selector <= 0x7f) { // Positive Fixnum 00649 unpack_uint8(*reinterpret_cast<const uint8_t*>(m_current), obj); 00650 int ret = push_proc(obj, off); 00651 if (ret != 0) return ret; 00652 } else if(0xe0 <= selector && selector <= 0xff) { // Negative Fixnum 00653 unpack_int8(*reinterpret_cast<const int8_t*>(m_current), obj); 00654 int ret = push_proc(obj, off); 00655 if (ret != 0) return ret; 00656 } else if (0xc4 <= selector && selector <= 0xdf) { 00657 const uint32_t trail[] = { 00658 1, // bin 8 0xc4 00659 2, // bin 16 0xc5 00660 4, // bin 32 0xc6 00661 1, // ext 8 0xc7 00662 2, // ext 16 0xc8 00663 4, // ext 32 0xc9 00664 4, // float 32 0xca 00665 8, // float 64 0xcb 00666 1, // uint 8 0xcc 00667 2, // uint 16 0xcd 00668 4, // uint 32 0xce 00669 8, // uint 64 0xcf 00670 1, // int 8 0xd0 00671 2, // int 16 0xd1 00672 4, // int 32 0xd2 00673 8, // int 64 0xd3 00674 2, // fixext 1 0xd4 00675 3, // fixext 2 0xd5 00676 5, // fixext 4 0xd6 00677 9, // fixext 8 0xd7 00678 17,// fixext 16 0xd8 00679 1, // str 8 0xd9 00680 2, // str 16 0xda 00681 4, // str 32 0xdb 00682 2, // array 16 0xdc 00683 4, // array 32 0xdd 00684 2, // map 16 0xde 00685 4, // map 32 0xdf 00686 }; 00687 m_trail = trail[selector - 0xc4]; 00688 m_cs = next_cs(m_current); 00689 fixed_trail_again = true; 00690 } else if(0xa0 <= selector && selector <= 0xbf) { // FixStr 00691 m_trail = static_cast<uint32_t>(*m_current) & 0x1f; 00692 if(m_trail == 0) { 00693 unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); 00694 int ret = push_proc(obj, off); 00695 if (ret != 0) return ret; 00696 } 00697 else { 00698 m_cs = MSGPACK_ACS_STR_VALUE; 00699 fixed_trail_again = true; 00700 } 00701 00702 } else if(0x90 <= selector && selector <= 0x9f) { // FixArray 00703 int ret = push_aggregate<fix_tag>( 00704 unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, m_current, off); 00705 if (ret != 0) return ret; 00706 } else if(0x80 <= selector && selector <= 0x8f) { // FixMap 00707 int ret = push_aggregate<fix_tag>( 00708 unpack_map(), MSGPACK_CT_MAP_KEY, obj, m_current, off); 00709 if (ret != 0) return ret; 00710 } else if(selector == 0xc2) { // false 00711 unpack_false(obj); 00712 int ret = push_proc(obj, off); 00713 if (ret != 0) return ret; 00714 } else if(selector == 0xc3) { // true 00715 unpack_true(obj); 00716 int ret = push_proc(obj, off); 00717 if (ret != 0) return ret; 00718 } else if(selector == 0xc0) { // nil 00719 unpack_nil(obj); 00720 int ret = push_proc(obj, off); 00721 if (ret != 0) return ret; 00722 } else { 00723 off = m_current - m_start; 00724 return -1; 00725 } 00726 // end MSGPACK_CS_HEADER 00727 } 00728 if (m_cs != MSGPACK_CS_HEADER || fixed_trail_again) { 00729 if (fixed_trail_again) { 00730 ++m_current; 00731 fixed_trail_again = false; 00732 } 00733 if(static_cast<std::size_t>(pe - m_current) < m_trail) { 00734 off = m_current - m_start; 00735 return 0; 00736 } 00737 n = m_current; 00738 m_current += m_trail - 1; 00739 switch(m_cs) { 00740 //case MSGPACK_CS_ 00741 //case MSGPACK_CS_ 00742 case MSGPACK_CS_FLOAT: { 00743 union { uint32_t i; float f; } mem; 00744 load<uint32_t>(mem.i, n); 00745 unpack_float(mem.f, obj); 00746 int ret = push_proc(obj, off); 00747 if (ret != 0) return ret; 00748 } break; 00749 case MSGPACK_CS_DOUBLE: { 00750 union { uint64_t i; double f; } mem; 00751 load<uint64_t>(mem.i, n); 00752 #if defined(TARGET_OS_IPHONE) 00753 // ok 00754 #elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi 00755 // https://github.com/msgpack/msgpack-perl/pull/1 00756 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL); 00757 #endif 00758 unpack_double(mem.f, obj); 00759 int ret = push_proc(obj, off); 00760 if (ret != 0) return ret; 00761 } break; 00762 case MSGPACK_CS_UINT_8: { 00763 uint8_t tmp; 00764 load<uint8_t>(tmp, n); 00765 unpack_uint8(tmp, obj); 00766 int ret = push_proc(obj, off); 00767 if (ret != 0) return ret; 00768 } break; 00769 case MSGPACK_CS_UINT_16: { 00770 uint16_t tmp; 00771 load<uint16_t>(tmp, n); 00772 unpack_uint16(tmp, obj); 00773 int ret = push_proc(obj, off); 00774 if (ret != 0) return ret; 00775 } break; 00776 case MSGPACK_CS_UINT_32: { 00777 uint32_t tmp; 00778 load<uint32_t>(tmp, n); 00779 unpack_uint32(tmp, obj); 00780 int ret = push_proc(obj, off); 00781 if (ret != 0) return ret; 00782 } break; 00783 case MSGPACK_CS_UINT_64: { 00784 uint64_t tmp; 00785 load<uint64_t>(tmp, n); 00786 unpack_uint64(tmp, obj); 00787 int ret = push_proc(obj, off); 00788 if (ret != 0) return ret; 00789 } break; 00790 case MSGPACK_CS_INT_8: { 00791 int8_t tmp; 00792 load<int8_t>(tmp, n); 00793 unpack_int8(tmp, obj); 00794 int ret = push_proc(obj, off); 00795 if (ret != 0) return ret; 00796 } break; 00797 case MSGPACK_CS_INT_16: { 00798 int16_t tmp; 00799 load<int16_t>(tmp, n); 00800 unpack_int16(tmp, obj); 00801 int ret = push_proc(obj, off); 00802 if (ret != 0) return ret; 00803 } break; 00804 case MSGPACK_CS_INT_32: { 00805 int32_t tmp; 00806 load<int32_t>(tmp, n); 00807 unpack_int32(tmp, obj); 00808 int ret = push_proc(obj, off); 00809 if (ret != 0) return ret; 00810 } break; 00811 case MSGPACK_CS_INT_64: { 00812 int64_t tmp; 00813 load<int64_t>(tmp, n); 00814 unpack_int64(tmp, obj); 00815 int ret = push_proc(obj, off); 00816 if (ret != 0) return ret; 00817 } break; 00818 case MSGPACK_CS_FIXEXT_1: { 00819 unpack_ext(m_user, n, 1+1, obj); 00820 int ret = push_proc(obj, off); 00821 if (ret != 0) return ret; 00822 } break; 00823 case MSGPACK_CS_FIXEXT_2: { 00824 unpack_ext(m_user, n, 2+1, obj); 00825 int ret = push_proc(obj, off); 00826 if (ret != 0) return ret; 00827 } break; 00828 case MSGPACK_CS_FIXEXT_4: { 00829 unpack_ext(m_user, n, 4+1, obj); 00830 int ret = push_proc(obj, off); 00831 if (ret != 0) return ret; 00832 } break; 00833 case MSGPACK_CS_FIXEXT_8: { 00834 unpack_ext(m_user, n, 8+1, obj); 00835 int ret = push_proc(obj, off); 00836 if (ret != 0) return ret; 00837 } break; 00838 case MSGPACK_CS_FIXEXT_16: { 00839 unpack_ext(m_user, n, 16+1, obj); 00840 int ret = push_proc(obj, off); 00841 if (ret != 0) return ret; 00842 } break; 00843 case MSGPACK_CS_STR_8: { 00844 uint8_t tmp; 00845 load<uint8_t>(tmp, n); 00846 m_trail = tmp; 00847 if(m_trail == 0) { 00848 unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); 00849 int ret = push_proc(obj, off); 00850 if (ret != 0) return ret; 00851 } 00852 else { 00853 m_cs = MSGPACK_ACS_STR_VALUE; 00854 fixed_trail_again = true; 00855 } 00856 } break; 00857 case MSGPACK_CS_BIN_8: { 00858 uint8_t tmp; 00859 load<uint8_t>(tmp, n); 00860 m_trail = tmp; 00861 if(m_trail == 0) { 00862 unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); 00863 int ret = push_proc(obj, off); 00864 if (ret != 0) return ret; 00865 } 00866 else { 00867 m_cs = MSGPACK_ACS_BIN_VALUE; 00868 fixed_trail_again = true; 00869 } 00870 } break; 00871 case MSGPACK_CS_EXT_8: { 00872 uint8_t tmp; 00873 load<uint8_t>(tmp, n); 00874 m_trail = tmp + 1; 00875 if(m_trail == 0) { 00876 unpack_ext(m_user, n, m_trail, obj); 00877 int ret = push_proc(obj, off); 00878 if (ret != 0) return ret; 00879 } 00880 else { 00881 m_cs = MSGPACK_ACS_EXT_VALUE; 00882 fixed_trail_again = true; 00883 } 00884 } break; 00885 case MSGPACK_CS_STR_16: { 00886 uint16_t tmp; 00887 load<uint16_t>(tmp, n); 00888 m_trail = tmp; 00889 if(m_trail == 0) { 00890 unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); 00891 int ret = push_proc(obj, off); 00892 if (ret != 0) return ret; 00893 } 00894 else { 00895 m_cs = MSGPACK_ACS_STR_VALUE; 00896 fixed_trail_again = true; 00897 } 00898 } break; 00899 case MSGPACK_CS_BIN_16: { 00900 uint16_t tmp; 00901 load<uint16_t>(tmp, n); 00902 m_trail = tmp; 00903 if(m_trail == 0) { 00904 unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); 00905 int ret = push_proc(obj, off); 00906 if (ret != 0) return ret; 00907 } 00908 else { 00909 m_cs = MSGPACK_ACS_BIN_VALUE; 00910 fixed_trail_again = true; 00911 } 00912 } break; 00913 case MSGPACK_CS_EXT_16: { 00914 uint16_t tmp; 00915 load<uint16_t>(tmp, n); 00916 m_trail = tmp + 1; 00917 if(m_trail == 0) { 00918 unpack_ext(m_user, n, m_trail, obj); 00919 int ret = push_proc(obj, off); 00920 if (ret != 0) return ret; 00921 } 00922 else { 00923 m_cs = MSGPACK_ACS_EXT_VALUE; 00924 fixed_trail_again = true; 00925 } 00926 } break; 00927 case MSGPACK_CS_STR_32: { 00928 uint32_t tmp; 00929 load<uint32_t>(tmp, n); 00930 m_trail = tmp; 00931 if(m_trail == 0) { 00932 unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); 00933 int ret = push_proc(obj, off); 00934 if (ret != 0) return ret; 00935 } 00936 else { 00937 m_cs = MSGPACK_ACS_STR_VALUE; 00938 fixed_trail_again = true; 00939 } 00940 } break; 00941 case MSGPACK_CS_BIN_32: { 00942 uint32_t tmp; 00943 load<uint32_t>(tmp, n); 00944 m_trail = tmp; 00945 if(m_trail == 0) { 00946 unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); 00947 int ret = push_proc(obj, off); 00948 if (ret != 0) return ret; 00949 } 00950 else { 00951 m_cs = MSGPACK_ACS_BIN_VALUE; 00952 fixed_trail_again = true; 00953 } 00954 } break; 00955 case MSGPACK_CS_EXT_32: { 00956 uint32_t tmp; 00957 load<uint32_t>(tmp, n); 00958 check_ext_size<sizeof(std::size_t)>(tmp); 00959 m_trail = tmp; 00960 ++m_trail; 00961 if(m_trail == 0) { 00962 unpack_ext(m_user, n, m_trail, obj); 00963 int ret = push_proc(obj, off); 00964 if (ret != 0) return ret; 00965 } 00966 else { 00967 m_cs = MSGPACK_ACS_EXT_VALUE; 00968 fixed_trail_again = true; 00969 } 00970 } break; 00971 case MSGPACK_ACS_STR_VALUE: { 00972 unpack_str(m_user, n, static_cast<uint32_t>(m_trail), obj); 00973 int ret = push_proc(obj, off); 00974 if (ret != 0) return ret; 00975 } break; 00976 case MSGPACK_ACS_BIN_VALUE: { 00977 unpack_bin(m_user, n, static_cast<uint32_t>(m_trail), obj); 00978 int ret = push_proc(obj, off); 00979 if (ret != 0) return ret; 00980 } break; 00981 case MSGPACK_ACS_EXT_VALUE: { 00982 unpack_ext(m_user, n, m_trail, obj); 00983 int ret = push_proc(obj, off); 00984 if (ret != 0) return ret; 00985 } break; 00986 case MSGPACK_CS_ARRAY_16: { 00987 int ret = push_aggregate<uint16_t>( 00988 unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, n, off); 00989 if (ret != 0) return ret; 00990 } break; 00991 case MSGPACK_CS_ARRAY_32: { 00992 /* FIXME security guard */ 00993 int ret = push_aggregate<uint32_t>( 00994 unpack_array(), MSGPACK_CT_ARRAY_ITEM, obj, n, off); 00995 if (ret != 0) return ret; 00996 } break; 00997 case MSGPACK_CS_MAP_16: { 00998 int ret = push_aggregate<uint16_t>( 00999 unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off); 01000 if (ret != 0) return ret; 01001 } break; 01002 case MSGPACK_CS_MAP_32: { 01003 /* FIXME security guard */ 01004 int ret = push_aggregate<uint32_t>( 01005 unpack_map(), MSGPACK_CT_MAP_KEY, obj, n, off); 01006 if (ret != 0) return ret; 01007 } break; 01008 default: 01009 off = m_current - m_start; 01010 return -1; 01011 } 01012 } 01013 } while(m_current != pe); 01014 01015 off = m_current - m_start; 01016 return 0; 01017 } 01018 01019 } // detail 01020 01021 01022 typedef object_handle unpacked; 01023 01024 /// Unpacking class for a stream deserialization. 01025 class unpacker { 01026 public: 01027 /// Constructor 01028 /** 01029 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01030 * @param f A judging function that msgpack::object refer to the buffer. 01031 * @param user_data This parameter is passed to f. 01032 * @param initial_buffer_size The memory size to allocate when unpacker is constructed. 01033 * @param limit The size limit information of msgpack::object. 01034 * 01035 */ 01036 unpacker(unpack_reference_func f = &unpacker::default_reference_func, 01037 void* user_data = nullptr, 01038 std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE, 01039 unpack_limit const& limit = unpack_limit()); 01040 01041 #if !defined(MSGPACK_USE_CPP03) 01042 unpacker(unpacker&& other); 01043 unpacker& operator=(unpacker&& other); 01044 #endif // !defined(MSGPACK_USE_CPP03) 01045 01046 ~unpacker(); 01047 01048 public: 01049 /// Reserve a buffer memory. 01050 /** 01051 * @param size The size of allocating memory. 01052 * 01053 * After returning this function, buffer_capacity() returns at least 'size'. 01054 * See: 01055 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01056 */ 01057 void reserve_buffer(std::size_t size = MSGPACK_UNPACKER_RESERVE_SIZE); 01058 01059 /// Get buffer pointer. 01060 /** 01061 * You need to care about the memory is enable between buffer() and buffer() + buffer_capacity() 01062 * See: 01063 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01064 */ 01065 char* buffer(); 01066 01067 /// Get buffer capacity. 01068 /** 01069 * @return The memory size that you can write. 01070 * 01071 * See: 01072 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01073 */ 01074 std::size_t buffer_capacity() const; 01075 01076 /// Notify a buffer consumed information to msgpack::unpacker. 01077 /** 01078 * @param size The size of memory that you consumed. 01079 * 01080 * After copying the data to the memory that is pointed by buffer(), you need to call the 01081 * function to notify how many bytes are consumed. Then you can call next() functions. 01082 * 01083 * See: 01084 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01085 */ 01086 void buffer_consumed(std::size_t size); 01087 01088 /// Unpack one msgpack::object. [obsolete] 01089 /** 01090 * 01091 * @param result The object that contains unpacked data. 01092 * 01093 * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete 01094 * and additional data is required, then return false. If data format is invalid, throw 01095 * msgpack::parse_error. 01096 * 01097 * See: 01098 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01099 * This function is obsolete. Use the reference inteface version of next() function instead of 01100 * the pointer interface version. 01101 */ 01102 bool next(unpacked* result); 01103 01104 /// Unpack one msgpack::object. 01105 /** 01106 * 01107 * @param result The object that contains unpacked data. 01108 * @param referenced If the unpacked object contains reference of the buffer, 01109 * then set as true, otherwise false. 01110 * 01111 * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete 01112 * and additional data is required, then return false. If data format is invalid, throw 01113 * msgpack::parse_error. 01114 * 01115 * See: 01116 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01117 */ 01118 bool next(unpacked& result, bool& referenced); 01119 01120 /// Unpack one msgpack::object. 01121 /** 01122 * 01123 * @param result The object that contains unpacked data. 01124 * 01125 * @return If one msgpack::object is unpacked, then return true, if msgpack::object is incomplete 01126 * and additional data is required, then return false. If data format is invalid, throw 01127 * msgpack::parse_error. 01128 * 01129 * See: 01130 * https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_unpacker#msgpack-controls-a-buffer 01131 */ 01132 bool next(unpacked& result); 01133 01134 /// Get message size. 01135 /** 01136 * @return Returns parsed_size() + nonparsed_size() 01137 */ 01138 std::size_t message_size() const; 01139 01140 /*! for backward compatibility */ 01141 bool execute (); 01142 01143 /*! for backward compatibility */ 01144 msgpack::object const& data (); 01145 01146 /*! for backward compatibility */ 01147 msgpack::zone* release_zone (); 01148 01149 /*! for backward compatibility */ 01150 void reset_zone (); 01151 01152 /*! for backward compatibility */ 01153 void reset (); 01154 01155 public: 01156 /// Get parsed message size. 01157 /** 01158 * @return Parsed message size. 01159 * 01160 * This function is usable when non-MessagePack message follows after 01161 * MessagePack message. 01162 */ 01163 std::size_t parsed_size() const; 01164 01165 /// Get the address that is not parsed in the buffer. 01166 /** 01167 * @return Address of the buffer that is not parsed 01168 * 01169 * This function is usable when non-MessagePack message follows after 01170 * MessagePack message. 01171 */ 01172 char* nonparsed_buffer(); 01173 01174 /// Get the size of the buffer that is not parsed. 01175 /** 01176 * @return Size of the buffer that is not parsed 01177 * 01178 * This function is usable when non-MessagePack message follows after 01179 * MessagePack message. 01180 */ 01181 std::size_t nonparsed_size() const; 01182 01183 /// Skip the specified size of non-parsed buffer. 01184 /** 01185 * @param size to skip 01186 * 01187 * Note that the `size' argument must be smaller than nonparsed_size(). 01188 * This function is usable when non-MessagePack message follows after 01189 * MessagePack message. 01190 */ 01191 void skip_nonparsed_buffer(std::size_t size); 01192 01193 /// Remove nonparsed buffer and reset the current position as a new start point. 01194 /** 01195 * This function is usable when non-MessagePack message follows after 01196 * MessagePack message. 01197 */ 01198 void remove_nonparsed_buffer(); 01199 01200 private: 01201 void expand_buffer(std::size_t size); 01202 int execute_imp(); 01203 bool flush_zone(); 01204 static bool default_reference_func(msgpack::type::object_type type, std::size_t len, void*); 01205 01206 private: 01207 char* m_buffer; 01208 std::size_t m_used; 01209 std::size_t m_free; 01210 std::size_t m_off; 01211 std::size_t m_parsed; 01212 msgpack::unique_ptr<msgpack::zone> m_z; 01213 std::size_t m_initial_buffer_size; 01214 detail::context m_ctx; 01215 01216 #if defined(MSGPACK_USE_CPP03) 01217 private: 01218 unpacker(const unpacker&); 01219 unpacker& operator=(const unpacker&); 01220 #else // defined(MSGPACK_USE_CPP03) 01221 unpacker(const unpacker&) = delete; 01222 unpacker& operator=(const unpacker&) = delete; 01223 #endif // defined(MSGPACK_USE_CPP03) 01224 }; 01225 01226 /// Unpack msgpack::object from a buffer. 01227 /** 01228 * @param data The pointer to the buffer. 01229 * @param len The length of the buffer. 01230 * @param off The offset position of the buffer. It is read and overwritten. 01231 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01232 * @param f A judging function that msgpack::object refer to the buffer. 01233 * @param user_data This parameter is passed to f. 01234 * @param limit The size limit information of msgpack::object. 01235 * 01236 * @return unpacked object that contains unpacked data. 01237 * 01238 */ 01239 unpacked unpack( 01240 const char* data, std::size_t len, std::size_t& off, bool& referenced, 01241 unpack_reference_func f = nullptr, void* user_data = nullptr, 01242 unpack_limit const& limit = unpack_limit()); 01243 01244 /// Unpack msgpack::object from a buffer. 01245 /** 01246 * @param data The pointer to the buffer. 01247 * @param len The length of the buffer. 01248 * @param off The offset position of the buffer. It is read and overwritten. 01249 * @param f A judging function that msgpack::object refer to the buffer. 01250 * @param user_data This parameter is passed to f. 01251 * @param limit The size limit information of msgpack::object. 01252 * 01253 * @return unpacked object that contains unpacked data. 01254 * 01255 */ 01256 unpacked unpack( 01257 const char* data, std::size_t len, std::size_t& off, 01258 unpack_reference_func f = nullptr, void* user_data = nullptr, 01259 unpack_limit const& limit = unpack_limit()); 01260 01261 /// Unpack msgpack::object from a buffer. 01262 /** 01263 * @param data The pointer to the buffer. 01264 * @param len The length of the buffer. 01265 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01266 * @param f A judging function that msgpack::object refer to the buffer. 01267 * @param user_data This parameter is passed to f. 01268 * @param limit The size limit information of msgpack::object. 01269 * 01270 * @return unpacked object that contains unpacked data. 01271 * 01272 */ 01273 unpacked unpack( 01274 const char* data, std::size_t len, bool& referenced, 01275 unpack_reference_func f = nullptr, void* user_data = nullptr, 01276 unpack_limit const& limit = unpack_limit()); 01277 01278 /// Unpack msgpack::object from a buffer. 01279 /** 01280 * @param data The pointer to the buffer. 01281 * @param len The length of the buffer. 01282 * @param f A judging function that msgpack::object refer to the buffer. 01283 * @param user_data This parameter is passed to f. 01284 * @param limit The size limit information of msgpack::object. 01285 * 01286 * @return unpacked object that contains unpacked data. 01287 * 01288 */ 01289 unpacked unpack( 01290 const char* data, std::size_t len, 01291 unpack_reference_func f = nullptr, void* user_data = nullptr, 01292 unpack_limit const& limit = unpack_limit()); 01293 01294 01295 /// Unpack msgpack::object from a buffer. 01296 /** 01297 * @param result The object that contains unpacked data. 01298 * @param data The pointer to the buffer. 01299 * @param len The length of the buffer. 01300 * @param off The offset position of the buffer. It is read and overwritten. 01301 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01302 * @param f A judging function that msgpack::object refer to the buffer. 01303 * @param user_data This parameter is passed to f. 01304 * @param limit The size limit information of msgpack::object. 01305 * 01306 * 01307 */ 01308 void unpack(unpacked& result, 01309 const char* data, std::size_t len, std::size_t& off, bool& referenced, 01310 unpack_reference_func f = nullptr, void* user_data = nullptr, 01311 unpack_limit const& limit = unpack_limit()); 01312 01313 /// Unpack msgpack::object from a buffer. 01314 /** 01315 * @param result The object that contains unpacked data. 01316 * @param data The pointer to the buffer. 01317 * @param len The length of the buffer. 01318 * @param off The offset position of the buffer. It is read and overwritten. 01319 * @param f A judging function that msgpack::object refer to the buffer. 01320 * @param user_data This parameter is passed to f. 01321 * @param limit The size limit information of msgpack::object. 01322 * 01323 * 01324 */ 01325 void unpack(unpacked& result, 01326 const char* data, std::size_t len, std::size_t& off, 01327 unpack_reference_func f = nullptr, void* user_data = nullptr, 01328 unpack_limit const& limit = unpack_limit()); 01329 01330 /// Unpack msgpack::object from a buffer. 01331 /** 01332 * @param result The object that contains unpacked data. 01333 * @param data The pointer to the buffer. 01334 * @param len The length of the buffer. 01335 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01336 * @param f A judging function that msgpack::object refer to the buffer. 01337 * @param user_data This parameter is passed to f. 01338 * @param limit The size limit information of msgpack::object. 01339 * 01340 * 01341 */ 01342 void unpack(unpacked& result, 01343 const char* data, std::size_t len, bool& referenced, 01344 unpack_reference_func f = nullptr, void* user_data = nullptr, 01345 unpack_limit const& limit = unpack_limit()); 01346 01347 /// Unpack msgpack::object from a buffer. 01348 /** 01349 * @param result The object that contains unpacked data. 01350 * @param data The pointer to the buffer. 01351 * @param len The length of the buffer. 01352 * @param f A judging function that msgpack::object refer to the buffer. 01353 * @param user_data This parameter is passed to f. 01354 * @param limit The size limit information of msgpack::object. 01355 * 01356 * 01357 */ 01358 void unpack(unpacked& result, 01359 const char* data, std::size_t len, 01360 unpack_reference_func f = nullptr, void* user_data = nullptr, 01361 unpack_limit const& limit = unpack_limit()); 01362 01363 /// Unpack msgpack::object from a buffer. 01364 /** 01365 * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects. 01366 * @param data The pointer to the buffer. 01367 * @param len The length of the buffer. 01368 * @param off The offset position of the buffer. It is read and overwritten. 01369 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01370 * @param f A judging function that msgpack::object refer to the buffer. 01371 * @param user_data This parameter is passed to f. 01372 * @param limit The size limit information of msgpack::object. 01373 * 01374 * @return msgpack::object that contains unpacked data. 01375 * 01376 */ 01377 msgpack::object unpack( 01378 msgpack::zone& z, 01379 const char* data, std::size_t len, std::size_t& off, bool& referenced, 01380 unpack_reference_func f = nullptr, void* user_data = nullptr, 01381 unpack_limit const& limit = unpack_limit()); 01382 01383 /// Unpack msgpack::object from a buffer. 01384 /** 01385 * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects. 01386 * @param data The pointer to the buffer. 01387 * @param len The length of the buffer. 01388 * @param off The offset position of the buffer. It is read and overwritten. 01389 * @param f A judging function that msgpack::object refer to the buffer. 01390 * @param user_data This parameter is passed to f. 01391 * @param limit The size limit information of msgpack::object. 01392 * 01393 * @return msgpack::object that contains unpacked data. 01394 * 01395 */ 01396 msgpack::object unpack( 01397 msgpack::zone& z, 01398 const char* data, std::size_t len, std::size_t& off, 01399 unpack_reference_func f = nullptr, void* user_data = nullptr, 01400 unpack_limit const& limit = unpack_limit()); 01401 01402 /// Unpack msgpack::object from a buffer. 01403 /** 01404 * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects. 01405 * @param data The pointer to the buffer. 01406 * @param len The length of the buffer. 01407 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01408 * @param f A judging function that msgpack::object refer to the buffer. 01409 * @param user_data This parameter is passed to f. 01410 * @param limit The size limit information of msgpack::object. 01411 * 01412 * @return msgpack::object that contains unpacked data. 01413 * 01414 */ 01415 msgpack::object unpack( 01416 msgpack::zone& z, 01417 const char* data, std::size_t len, bool& referenced, 01418 unpack_reference_func f = nullptr, void* user_data = nullptr, 01419 unpack_limit const& limit = unpack_limit()); 01420 01421 /// Unpack msgpack::object from a buffer. 01422 /** 01423 * @param z The msgpack::zone that is used as a memory of unpacked msgpack objects. 01424 * @param data The pointer to the buffer. 01425 * @param len The length of the buffer. 01426 * @param f A judging function that msgpack::object refer to the buffer. 01427 * @param user_data This parameter is passed to f. 01428 * @param limit The size limit information of msgpack::object. 01429 * 01430 * @return msgpack::object that contains unpacked data. 01431 * 01432 */ 01433 msgpack::object unpack( 01434 msgpack::zone& z, 01435 const char* data, std::size_t len, 01436 unpack_reference_func f = nullptr, void* user_data = nullptr, 01437 unpack_limit const& limit = unpack_limit()); 01438 01439 01440 /// Unpack msgpack::object from a buffer. [obsolete] 01441 /** 01442 * @param result The object that contains unpacked data. 01443 * @param data The pointer to the buffer. 01444 * @param len The length of the buffer. 01445 * @param off The offset position of the buffer. It is read and overwritten. 01446 * @param referenced If the unpacked object contains reference of the buffer, then set as true, otherwise false. 01447 * @param f A judging function that msgpack::object refer to the buffer. 01448 * @param user_data This parameter is passed to f. 01449 * @param limit The size limit information of msgpack::object. 01450 * 01451 * This function is obsolete. Use the reference inteface version of unpack functions instead of the pointer interface version. 01452 */ 01453 void unpack(unpacked* result, 01454 const char* data, std::size_t len, std::size_t* off = nullptr, bool* referenced = nullptr, 01455 unpack_reference_func f = nullptr, void* user_data = nullptr, 01456 unpack_limit const& limit = unpack_limit()); 01457 01458 01459 // for internal use 01460 typedef enum { 01461 UNPACK_SUCCESS = 2, 01462 UNPACK_EXTRA_BYTES = 1, 01463 UNPACK_CONTINUE = 0, 01464 UNPACK_PARSE_ERROR = -1 01465 } unpack_return; 01466 01467 inline unpacker::unpacker(unpack_reference_func f, 01468 void* user_data, 01469 std::size_t initial_buffer_size, 01470 unpack_limit const& limit) 01471 :m_z(new msgpack::zone), m_ctx(f, user_data, limit) 01472 { 01473 if(initial_buffer_size < COUNTER_SIZE) { 01474 initial_buffer_size = COUNTER_SIZE; 01475 } 01476 01477 char* buffer = static_cast<char*>(::malloc(initial_buffer_size)); 01478 if(!buffer) { 01479 printf("std::bad_alloc()\n"); 01480 // throw std::bad_alloc(); 01481 } 01482 01483 m_buffer = buffer; 01484 m_used = COUNTER_SIZE; 01485 m_free = initial_buffer_size - m_used; 01486 m_off = COUNTER_SIZE; 01487 m_parsed = 0; 01488 m_initial_buffer_size = initial_buffer_size; 01489 01490 detail::init_count(m_buffer); 01491 01492 m_ctx.init(); 01493 m_ctx.user().set_zone(*m_z); 01494 m_ctx.user().set_referenced(false); 01495 } 01496 01497 #if !defined(MSGPACK_USE_CPP03) 01498 // Move constructor and move assignment operator 01499 01500 inline unpacker::unpacker(unpacker&& other) 01501 :m_buffer(other.m_buffer), 01502 m_used(other.m_used), 01503 m_free(other.m_free), 01504 m_off(other.m_off), 01505 m_parsed(other.m_parsed), 01506 m_z(std::move(other.m_z)), 01507 m_initial_buffer_size(other.m_initial_buffer_size), 01508 m_ctx(other.m_ctx) { 01509 other.m_buffer = nullptr; 01510 } 01511 01512 inline unpacker& unpacker::operator=(unpacker&& other) { 01513 this->~unpacker(); 01514 new (this) unpacker(std::move(other)); 01515 return *this; 01516 } 01517 01518 #endif // !defined(MSGPACK_USE_CPP03) 01519 01520 01521 inline unpacker::~unpacker() 01522 { 01523 // These checks are required for move operations. 01524 if (m_buffer) detail::decr_count(m_buffer); 01525 } 01526 01527 01528 inline void unpacker::reserve_buffer(std::size_t size) 01529 { 01530 if(m_free >= size) return; 01531 expand_buffer(size); 01532 } 01533 01534 inline void unpacker::expand_buffer(std::size_t size) 01535 { 01536 if(m_used == m_off && detail::get_count(m_buffer) == 1 01537 && !m_ctx.user().referenced()) { 01538 // rewind buffer 01539 m_free += m_used - COUNTER_SIZE; 01540 m_used = COUNTER_SIZE; 01541 m_off = COUNTER_SIZE; 01542 01543 if(m_free >= size) return; 01544 } 01545 01546 if(m_off == COUNTER_SIZE) { 01547 std::size_t next_size = (m_used + m_free) * 2; // include COUNTER_SIZE 01548 while(next_size < size + m_used) { 01549 std::size_t tmp_next_size = next_size * 2; 01550 if (tmp_next_size <= next_size) { 01551 next_size = size + m_used; 01552 break; 01553 } 01554 next_size = tmp_next_size; 01555 } 01556 01557 char* tmp = static_cast<char*>(::realloc(m_buffer, next_size)); 01558 if(!tmp) { 01559 printf("std::bad_alloc()\n"); 01560 // throw std::bad_alloc(); 01561 } 01562 01563 m_buffer = tmp; 01564 m_free = next_size - m_used; 01565 01566 } else { 01567 std::size_t next_size = m_initial_buffer_size; // include COUNTER_SIZE 01568 std::size_t not_parsed = m_used - m_off; 01569 while(next_size < size + not_parsed + COUNTER_SIZE) { 01570 std::size_t tmp_next_size = next_size * 2; 01571 if (tmp_next_size <= next_size) { 01572 next_size = size + not_parsed + COUNTER_SIZE; 01573 break; 01574 } 01575 next_size = tmp_next_size; 01576 } 01577 01578 char* tmp = static_cast<char*>(::malloc(next_size)); 01579 if(!tmp) { 01580 printf("std::bad_alloc()\n"); 01581 // throw std::bad_alloc(); 01582 } 01583 01584 detail::init_count(tmp); 01585 01586 std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed); 01587 01588 if(m_ctx.user().referenced()) { 01589 // try { 01590 printf("try\n"); 01591 m_z->push_finalizer(&detail::decr_count, m_buffer); 01592 // } 01593 // catch (...) { 01594 // ::free(tmp); 01595 // throw; 01596 // } 01597 m_ctx.user().set_referenced(false); 01598 } else { 01599 detail::decr_count(m_buffer); 01600 } 01601 01602 m_buffer = tmp; 01603 m_used = not_parsed + COUNTER_SIZE; 01604 m_free = next_size - m_used; 01605 m_off = COUNTER_SIZE; 01606 } 01607 } 01608 01609 inline char* unpacker::buffer() 01610 { 01611 return m_buffer + m_used; 01612 } 01613 01614 inline std::size_t unpacker::buffer_capacity() const 01615 { 01616 return m_free; 01617 } 01618 01619 inline void unpacker::buffer_consumed(std::size_t size) 01620 { 01621 m_used += size; 01622 m_free -= size; 01623 } 01624 01625 inline bool unpacker::next(unpacked& result, bool& referenced) 01626 { 01627 referenced = false; 01628 int ret = execute_imp(); 01629 if(ret < 0) { 01630 printf("parse_error\n"); 01631 // throw msgpack::parse_error("parse error"); 01632 } 01633 01634 if(ret == 0) { 01635 result.zone().reset(); 01636 result.set(object()); 01637 return false; 01638 01639 } else { 01640 referenced = m_ctx.user().referenced(); 01641 result.zone().reset( release_zone () ); 01642 result.set(data ()); 01643 reset (); 01644 return true; 01645 } 01646 } 01647 01648 inline bool unpacker::next(unpacked& result) 01649 { 01650 bool referenced; 01651 return next(result, referenced); 01652 } 01653 01654 inline bool unpacker::next(unpacked* result) 01655 { 01656 return next(*result); 01657 } 01658 01659 01660 inline bool unpacker::execute () 01661 { 01662 int ret = execute_imp(); 01663 if(ret < 0) { 01664 printf("parse_error\n"); 01665 return false; 01666 // throw msgpack::parse_error("parse error"); 01667 } else if(ret == 0) { 01668 return false; 01669 } else { 01670 return true; 01671 } 01672 } 01673 01674 inline int unpacker::execute_imp() 01675 { 01676 std::size_t off = m_off; 01677 int ret = m_ctx.execute(m_buffer, m_used, m_off); 01678 if(m_off > off) { 01679 m_parsed += m_off - off; 01680 } 01681 return ret; 01682 } 01683 01684 inline msgpack::object const& unpacker::data () 01685 { 01686 return m_ctx.data(); 01687 } 01688 01689 inline msgpack::zone* unpacker::release_zone () 01690 { 01691 if(!flush_zone()) { 01692 return nullptr; 01693 } 01694 01695 msgpack::zone* r = new msgpack::zone; 01696 msgpack::zone* old = m_z.release(); 01697 m_z.reset(r); 01698 m_ctx.user().set_zone(*m_z); 01699 01700 return old; 01701 } 01702 01703 inline void unpacker::reset_zone () 01704 { 01705 m_z->clear(); 01706 } 01707 01708 inline bool unpacker::flush_zone() 01709 { 01710 if(m_ctx.user().referenced()) { 01711 // try { 01712 m_z->push_finalizer(&detail::decr_count, m_buffer); 01713 // } catch (...) { 01714 // return false; 01715 // } 01716 m_ctx.user().set_referenced(false); 01717 01718 detail::incr_count(m_buffer); 01719 } 01720 01721 return true; 01722 } 01723 01724 inline void unpacker::reset () 01725 { 01726 m_ctx.init(); 01727 // don't reset referenced flag 01728 m_parsed = 0; 01729 } 01730 01731 inline std::size_t unpacker::message_size() const 01732 { 01733 return m_parsed - m_off + m_used; 01734 } 01735 01736 inline std::size_t unpacker::parsed_size() const 01737 { 01738 return m_parsed; 01739 } 01740 01741 inline char* unpacker::nonparsed_buffer() 01742 { 01743 return m_buffer + m_off; 01744 } 01745 01746 inline std::size_t unpacker::nonparsed_size() const 01747 { 01748 return m_used - m_off; 01749 } 01750 01751 inline void unpacker::skip_nonparsed_buffer(std::size_t size) 01752 { 01753 m_off += size; 01754 } 01755 01756 inline void unpacker::remove_nonparsed_buffer() 01757 { 01758 m_used = m_off; 01759 } 01760 01761 namespace detail { 01762 01763 inline unpack_return 01764 unpack_imp(const char* data, std::size_t len, std::size_t& off, 01765 msgpack::zone& result_zone, msgpack::object& result, bool& referenced, 01766 unpack_reference_func f = nullptr, void* user_data = nullptr, 01767 unpack_limit const& limit = unpack_limit()) 01768 { 01769 std::size_t noff = off; 01770 01771 if(len <= noff) { 01772 // FIXME 01773 return UNPACK_CONTINUE; 01774 } 01775 01776 detail::context ctx(f, user_data, limit); 01777 ctx.init(); 01778 01779 ctx.user().set_zone(result_zone); 01780 ctx.user().set_referenced(false); 01781 referenced = false; 01782 01783 int e = ctx.execute(data, len, noff); 01784 if(e < 0) { 01785 return UNPACK_PARSE_ERROR; 01786 } 01787 01788 referenced = ctx.user().referenced(); 01789 off = noff; 01790 01791 if(e == 0) { 01792 return UNPACK_CONTINUE; 01793 } 01794 01795 result = ctx.data(); 01796 01797 if(noff < len) { 01798 return UNPACK_EXTRA_BYTES; 01799 } 01800 01801 return UNPACK_SUCCESS; 01802 } 01803 01804 } // detail 01805 01806 // reference version 01807 01808 inline unpacked unpack( 01809 const char* data, std::size_t len, std::size_t& off, bool& referenced, 01810 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01811 { 01812 msgpack::object obj; 01813 msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone); 01814 referenced = false; 01815 std::size_t noff = off; 01816 unpack_return ret = detail::unpack_imp( 01817 data, len, noff, *z, obj, referenced, f, user_data, limit); 01818 01819 switch(ret) { 01820 case UNPACK_SUCCESS: 01821 off = noff; 01822 return unpacked(obj, msgpack::move(z)); 01823 case UNPACK_EXTRA_BYTES: 01824 off = noff; 01825 return unpacked(obj, msgpack::move(z)); 01826 case UNPACK_CONTINUE: 01827 printf("insufficient bytes\n"); 01828 // throw msgpack::insufficient_bytes("insufficient bytes"); 01829 case UNPACK_PARSE_ERROR: 01830 default: 01831 printf("parse error\n"); 01832 // throw msgpack::parse_error("parse error"); 01833 } 01834 return unpacked(); 01835 } 01836 01837 inline unpacked unpack( 01838 const char* data, std::size_t len, std::size_t& off, 01839 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01840 { 01841 bool referenced; 01842 return unpack(data, len, off, referenced, f, user_data, limit); 01843 } 01844 01845 inline unpacked unpack( 01846 const char* data, std::size_t len, bool& referenced, 01847 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01848 { 01849 std::size_t off = 0; 01850 return unpack(data, len, off, referenced, f, user_data, limit); 01851 } 01852 01853 inline unpacked unpack( 01854 const char* data, std::size_t len, 01855 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01856 { 01857 bool referenced; 01858 std::size_t off = 0; 01859 return unpack(data, len, off, referenced, f, user_data, limit); 01860 } 01861 01862 inline void unpack(unpacked& result, 01863 const char* data, std::size_t len, std::size_t& off, bool& referenced, 01864 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01865 { 01866 msgpack::object obj; 01867 msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone); 01868 referenced = false; 01869 std::size_t noff = off; 01870 unpack_return ret = detail::unpack_imp( 01871 data, len, noff, *z, obj, referenced, f, user_data, limit); 01872 01873 switch(ret) { 01874 case UNPACK_SUCCESS: 01875 off = noff; 01876 result.set(obj); 01877 result.zone() = msgpack::move(z); 01878 return; 01879 case UNPACK_EXTRA_BYTES: 01880 off = noff; 01881 result.set(obj); 01882 result.zone() = msgpack::move(z); 01883 return; 01884 case UNPACK_CONTINUE: 01885 printf("insufficient bytes\n"); 01886 // throw msgpack::insufficient_bytes("insufficient bytes"); 01887 case UNPACK_PARSE_ERROR: 01888 default: 01889 printf("parse error\n"); 01890 // throw msgpack::parse_error("parse error"); 01891 } 01892 } 01893 01894 inline void unpack(unpacked& result, 01895 const char* data, std::size_t len, std::size_t& off, 01896 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01897 { 01898 bool referenced; 01899 unpack(result, data, len, off, referenced, f, user_data, limit); 01900 } 01901 01902 inline void unpack(unpacked& result, 01903 const char* data, std::size_t len, bool& referenced, 01904 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01905 { 01906 std::size_t off = 0; 01907 unpack(result, data, len, off, referenced, f, user_data, limit); 01908 } 01909 01910 inline void unpack(unpacked& result, 01911 const char* data, std::size_t len, 01912 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01913 { 01914 bool referenced; 01915 std::size_t off = 0; 01916 unpack(result, data, len, off, referenced, f, user_data, limit); 01917 } 01918 01919 01920 inline msgpack::object unpack( 01921 msgpack::zone& z, 01922 const char* data, std::size_t len, std::size_t& off, bool& referenced, 01923 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01924 { 01925 msgpack::object obj; 01926 std::size_t noff = off; 01927 referenced = false; 01928 unpack_return ret = detail::unpack_imp( 01929 data, len, noff, z, obj, referenced, f, user_data, limit); 01930 01931 switch(ret) { 01932 case UNPACK_SUCCESS: 01933 off = noff; 01934 return obj; 01935 case UNPACK_EXTRA_BYTES: 01936 off = noff; 01937 return obj; 01938 case UNPACK_CONTINUE: 01939 printf("insufficient bytes\n"); 01940 // throw msgpack::insufficient_bytes("insufficient bytes"); 01941 case UNPACK_PARSE_ERROR: 01942 default: 01943 printf("parse error\n"); 01944 // throw msgpack::parse_error("parse error"); 01945 } 01946 return obj; 01947 } 01948 01949 inline msgpack::object unpack( 01950 msgpack::zone& z, 01951 const char* data, std::size_t len, std::size_t& off, 01952 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01953 { 01954 bool referenced; 01955 return unpack(z, data, len, off, referenced, f, user_data, limit); 01956 } 01957 01958 inline msgpack::object unpack( 01959 msgpack::zone& z, 01960 const char* data, std::size_t len, bool& referenced, 01961 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01962 { 01963 std::size_t off = 0; 01964 return unpack(z, data, len, off, referenced, f, user_data, limit); 01965 } 01966 01967 inline msgpack::object unpack( 01968 msgpack::zone& z, 01969 const char* data, std::size_t len, 01970 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01971 { 01972 bool referenced; 01973 std::size_t off = 0; 01974 return unpack(z, data, len, off, referenced, f, user_data, limit); 01975 } 01976 01977 // obsolete 01978 // pointer version 01979 inline void unpack(unpacked* result, 01980 const char* data, std::size_t len, std::size_t* off, bool* referenced, 01981 unpack_reference_func f, void* user_data, unpack_limit const& limit) 01982 { 01983 if (off) { 01984 if (referenced) unpack(*result, data, len, *off, *referenced, f, user_data, limit); 01985 else unpack(*result, data, len, *off, f, user_data, limit); 01986 } else { 01987 if (referenced) unpack(*result, data, len, *referenced, f, user_data, limit); 01988 else unpack(*result, data, len, f, user_data, limit); 01989 } 01990 } 01991 01992 inline bool unpacker::default_reference_func(msgpack::type::object_type /*type*/, std::size_t /*len*/, void*) 01993 { 01994 return true; 01995 } 01996 01997 /// @cond 01998 } // MSGPACK_API_VERSION_NAMESPACE(v1) 01999 /// @endcond 02000 02001 } // namespace msgpack 02002 02003 02004 #endif /* msgpack/unpack.hpp */
Generated on Tue Jul 12 2022 22:51:46 by
![doxygen](doxygen.png)