messagepack implementation for embedded systems (mbed / arduino)
Dependents: hello_message_pack
object.hpp
00001 // 00002 // MessagePack for C++ static resolution routine 00003 // 00004 // Copyright (C) 2008-2014 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_OBJECT_HPP 00011 #define MSGPACK_OBJECT_HPP 00012 00013 #include "msgpack/versioning.hpp" 00014 #include "msgpack/pack.hpp" 00015 #include "msgpack/zone.hpp" 00016 #include "msgpack/adaptor/adaptor_base.hpp" 00017 00018 #include <cstring> 00019 #include <stdexcept> 00020 #include <typeinfo> 00021 #include <limits> 00022 #include <ostream> 00023 #include <typeinfo> 00024 #include <iomanip> 00025 00026 namespace msgpack { 00027 00028 /// @cond 00029 MSGPACK_API_VERSION_NAMESPACE(v1) { 00030 /// @endcond 00031 00032 /// The class holds object and zone 00033 class object_handle { 00034 public: 00035 /// Constructor that creates nil object and null zone. 00036 object_handle() {} 00037 00038 /// Constructor that creates an object_handle holding object `obj` and zone `z`. 00039 /** 00040 * @param obj object 00041 * @param z zone 00042 */ 00043 object_handle(msgpack::object const& obj, msgpack::unique_ptr<msgpack::zone> z) : 00044 m_obj(obj), m_zone(msgpack::move(z)) { } 00045 00046 // obsolete 00047 void set(msgpack::object const& obj) 00048 { m_obj = obj; } 00049 00050 /// Get object reference 00051 /** 00052 * @return object 00053 */ 00054 const msgpack::object& get() const 00055 { return m_obj; } 00056 00057 /// Get unique_ptr reference of zone. 00058 /** 00059 * @return unique_ptr reference of zone 00060 */ 00061 msgpack::unique_ptr<msgpack::zone>& zone() 00062 { return m_zone; } 00063 00064 /// Get unique_ptr const reference of zone. 00065 /** 00066 * @return unique_ptr const reference of zone 00067 */ 00068 const msgpack::unique_ptr<msgpack::zone>& zone() const 00069 { return m_zone; } 00070 00071 #if defined(MSGPACK_USE_CPP03) 00072 struct object_handle_ref { 00073 object_handle_ref(object_handle * oh):m_oh(oh) {} 00074 object_handle* m_oh; 00075 }; 00076 00077 object_handle(object_handle& other): 00078 m_obj(other.m_obj), 00079 m_zone(msgpack::move(other.m_zone)) { 00080 } 00081 00082 object_handle(object_handle_ref ref): 00083 m_obj(ref.m_oh->m_obj), 00084 m_zone(msgpack::move(ref.m_oh->m_zone)) { 00085 } 00086 00087 object_handle& operator=(object_handle& other) { 00088 m_obj = other.m_obj; 00089 m_zone = msgpack::move(other.m_zone); 00090 return *this; 00091 } 00092 00093 object_handle& operator=(object_handle_ref ref) { 00094 m_obj = ref.m_oh->m_obj; 00095 m_zone = msgpack::move(ref.m_oh->m_zone); 00096 return *this; 00097 } 00098 00099 operator object_handle_ref() { 00100 return object_handle_ref(this); 00101 } 00102 #endif // defined(MSGPACK_USE_CPP03) 00103 00104 private: 00105 msgpack::object m_obj; 00106 msgpack::unique_ptr<msgpack::zone> m_zone; 00107 }; 00108 00109 namespace detail { 00110 00111 template <std::size_t N> 00112 inline std::size_t add_ext_type_size(std::size_t size) { 00113 return size + 1; 00114 } 00115 00116 template <> 00117 inline std::size_t add_ext_type_size<4>(std::size_t size) { 00118 return size == 0xffffffff ? size : size + 1; 00119 } 00120 00121 } // namespace detail 00122 00123 inline std::size_t aligned_zone_size(msgpack::object const& obj) { 00124 std::size_t s = 0; 00125 switch (obj.type) { 00126 case msgpack::type::ARRAY: 00127 s += sizeof(msgpack::object) * obj.via.array.size; 00128 for (uint32_t i = 0; i < obj.via.array.size; ++i) { 00129 s += msgpack::aligned_zone_size(obj.via.array.ptr[i]); 00130 } 00131 break; 00132 case msgpack::type::MAP: 00133 s += sizeof(msgpack::object_kv) * obj.via.map.size; 00134 for (uint32_t i = 0; i < obj.via.map.size; ++i) { 00135 s += msgpack::aligned_zone_size(obj.via.map.ptr[i].key); 00136 s += msgpack::aligned_zone_size(obj.via.map.ptr[i].val); 00137 } 00138 break; 00139 case msgpack::type::EXT: 00140 s += msgpack::aligned_size( 00141 detail::add_ext_type_size<sizeof(std::size_t)>(obj.via.ext.size)); 00142 break; 00143 case msgpack::type::STR: 00144 s += msgpack::aligned_size(obj.via.str.size); 00145 break; 00146 case msgpack::type::BIN: 00147 s += msgpack::aligned_size(obj.via.bin.size); 00148 break; 00149 default: 00150 break; 00151 } 00152 return s; 00153 } 00154 00155 /// clone object 00156 /** 00157 * Clone (deep copy) object. 00158 * The copied object is located on newly allocated zone. 00159 * @param obj copy source object 00160 * 00161 * @return object_handle that holds deep copied object and zone. 00162 */ 00163 inline object_handle clone(msgpack::object const& obj) { 00164 std::size_t size = msgpack::aligned_zone_size(obj); 00165 msgpack::unique_ptr<msgpack::zone> z(size == 0 ? nullptr : new msgpack::zone(size)); 00166 msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj; 00167 return object_handle(newobj, msgpack::move(z)); 00168 } 00169 00170 struct object::implicit_type { 00171 implicit_type(object const& o) : obj(o) { } 00172 ~implicit_type() { } 00173 00174 template <typename T> 00175 operator T() { return obj.as<T>(); } 00176 00177 private: 00178 msgpack::object const& obj; 00179 }; 00180 00181 namespace detail { 00182 template <typename Stream, typename T> 00183 struct packer_serializer { 00184 static msgpack::packer<Stream> & pack(msgpack::packer<Stream> & o, const T& v) { 00185 v.msgpack_pack(o); 00186 return o; 00187 } 00188 }; 00189 } // namespace detail 00190 00191 // Adaptor functors' member functions definitions. 00192 template <typename T, typename Enabler> 00193 inline 00194 msgpack::object const& 00195 msgpack::adaptor::convert<T, Enabler>::operator()(msgpack::object const& o, T& v) const { 00196 v.msgpack_unpack(o.convert()); 00197 return o; 00198 } 00199 00200 template <typename T, typename Enabler> 00201 template <typename Stream> 00202 inline 00203 msgpack::packer<Stream> & 00204 msgpack::adaptor::pack<T, Enabler>::operator()(msgpack::packer<Stream> & o, T const& v) const { 00205 return msgpack::detail::packer_serializer<Stream, T>::pack(o, v); 00206 } 00207 00208 template <typename T, typename Enabler> 00209 inline 00210 void 00211 msgpack::adaptor::object_with_zone<T, Enabler>::operator()(msgpack::object::with_zone& o, T const& v) const { 00212 v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone); 00213 } 00214 00215 // Adaptor functor specialization to object 00216 namespace adaptor { 00217 00218 template <> 00219 struct convert<msgpack::object> { 00220 msgpack::object const& operator()(msgpack::object const& o, msgpack::object& v) const { 00221 v = o; 00222 return o; 00223 } 00224 }; 00225 00226 template <> 00227 struct pack<msgpack::object> { 00228 template <typename Stream> 00229 msgpack::packer<Stream> & operator()(msgpack::packer<Stream> & o, msgpack::object const& v) const { 00230 switch(v.type) { 00231 case msgpack::type::NIL: 00232 o.pack_nil(); 00233 return o; 00234 00235 case msgpack::type::BOOLEAN: 00236 if(v.via.boolean) { 00237 o.pack_true(); 00238 } else { 00239 o.pack_false(); 00240 } 00241 return o; 00242 00243 case msgpack::type::POSITIVE_INTEGER: 00244 o.pack_uint64(v.via.u64); 00245 return o; 00246 00247 case msgpack::type::NEGATIVE_INTEGER: 00248 o.pack_int64(v.via.i64); 00249 return o; 00250 00251 case msgpack::type::FLOAT: 00252 o.pack_double(v.via.f64); 00253 return o; 00254 00255 case msgpack::type::STR: 00256 o.pack_str(v.via.str.size); 00257 o.pack_str_body(v.via.str.ptr, v.via.str.size); 00258 return o; 00259 00260 case msgpack::type::BIN: 00261 o.pack_bin(v.via.bin.size); 00262 o.pack_bin_body(v.via.bin.ptr, v.via.bin.size); 00263 return o; 00264 00265 case msgpack::type::EXT: 00266 o.pack_ext(v.via.ext.size, v.via.ext.type()); 00267 o.pack_ext_body(v.via.ext.data(), v.via.ext.size); 00268 return o; 00269 00270 case msgpack::type::ARRAY: 00271 o.pack_array(v.via.array.size); 00272 for(msgpack::object* p(v.via.array.ptr), 00273 * const pend(v.via.array.ptr + v.via.array.size); 00274 p < pend; ++p) { 00275 msgpack::operator<<(o, *p); 00276 } 00277 return o; 00278 00279 case msgpack::type::MAP: 00280 o.pack_map(v.via.map.size); 00281 for(msgpack::object_kv* p(v.via.map.ptr), 00282 * const pend(v.via.map.ptr + v.via.map.size); 00283 p < pend; ++p) { 00284 msgpack::operator<<(o, p->key); 00285 msgpack::operator<<(o, p->val); 00286 } 00287 return o; 00288 00289 default: 00290 throw msgpack::type_error(); 00291 } 00292 } 00293 }; 00294 00295 template <> 00296 struct object_with_zone<msgpack::object> { 00297 void operator()(msgpack::object::with_zone& o, msgpack::object const& v) const { 00298 o.type = v.type; 00299 00300 switch(v.type) { 00301 case msgpack::type::NIL: 00302 case msgpack::type::BOOLEAN: 00303 case msgpack::type::POSITIVE_INTEGER: 00304 case msgpack::type::NEGATIVE_INTEGER: 00305 case msgpack::type::FLOAT: 00306 std::memcpy(&o.via, &v.via, sizeof(v.via)); 00307 return; 00308 00309 case msgpack::type::STR: { 00310 char* ptr = static_cast<char*>(o.zone.allocate_align(v.via.str.size)); 00311 o.via.str.ptr = ptr; 00312 o.via.str.size = v.via.str.size; 00313 std::memcpy(ptr, v.via.str.ptr, v.via.str.size); 00314 return; 00315 } 00316 00317 case msgpack::type::BIN: { 00318 char* ptr = static_cast<char*>(o.zone.allocate_align(v.via.bin.size)); 00319 o.via.bin.ptr = ptr; 00320 o.via.bin.size = v.via.bin.size; 00321 std::memcpy(ptr, v.via.bin.ptr, v.via.bin.size); 00322 return; 00323 } 00324 00325 case msgpack::type::EXT: { 00326 char* ptr = static_cast<char*>(o.zone.allocate_align(v.via.ext.size + 1)); 00327 o.via.ext.ptr = ptr; 00328 o.via.ext.size = v.via.ext.size; 00329 std::memcpy(ptr, v.via.ext.ptr, v.via.ext.size + 1); 00330 return; 00331 } 00332 00333 case msgpack::type::ARRAY: 00334 o.via.array.ptr = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object) * v.via.array.size)); 00335 o.via.array.size = v.via.array.size; 00336 for (msgpack::object 00337 * po(o.via.array.ptr), 00338 * pv(v.via.array.ptr), 00339 * const pvend(v.via.array.ptr + v.via.array.size); 00340 pv < pvend; 00341 ++po, ++pv) { 00342 new (po) msgpack::object(*pv, o.zone); 00343 } 00344 return; 00345 00346 case msgpack::type::MAP: 00347 o.via.map.ptr = (msgpack::object_kv*)o.zone.allocate_align(sizeof(msgpack::object_kv) * v.via.map.size); 00348 o.via.map.size = v.via.map.size; 00349 for(msgpack::object_kv 00350 * po(o.via.map.ptr), 00351 * pv(v.via.map.ptr), 00352 * const pvend(v.via.map.ptr + v.via.map.size); 00353 pv < pvend; 00354 ++po, ++pv) { 00355 msgpack::object_kv* kv = new (po) msgpack::object_kv; 00356 new (&kv->key) msgpack::object(pv->key, o.zone); 00357 new (&kv->val) msgpack::object(pv->val, o.zone); 00358 } 00359 return; 00360 00361 default: 00362 ; 00363 // throw msgpack::type_error(); 00364 } 00365 00366 } 00367 }; 00368 00369 // Adaptor functor specialization to object::with_zone 00370 00371 template <> 00372 struct object_with_zone<msgpack::object::with_zone> { 00373 void operator()( 00374 msgpack::object::with_zone& o, 00375 msgpack::object::with_zone const& v) const { 00376 o << static_cast<msgpack::object const&>(v); 00377 } 00378 }; 00379 00380 00381 } // namespace adaptor 00382 00383 00384 // obsolete 00385 template <typename Type> 00386 class define : public Type { 00387 public: 00388 typedef Type msgpack_type; 00389 typedef define<Type> define_type; 00390 00391 define() {} 00392 define(const msgpack_type& v) : msgpack_type(v) {} 00393 00394 template <typename Packer> 00395 void msgpack_pack(Packer& o) const 00396 { 00397 msgpack::operator<<(o, static_cast<const msgpack_type&>(*this)); 00398 } 00399 00400 void msgpack_unpack(object const& o) 00401 { 00402 msgpack::operator>>(o, static_cast<msgpack_type&>(*this)); 00403 } 00404 }; 00405 00406 // deconvert operator 00407 00408 template <typename Stream> 00409 template <typename T> 00410 inline msgpack::packer<Stream> & packer<Stream>::pack(const T& v) 00411 { 00412 msgpack::operator<<(*this, v); 00413 return *this; 00414 } 00415 00416 inline bool operator==(const msgpack::object& x, const msgpack::object& y) 00417 { 00418 if(x.type != y.type) { return false; } 00419 00420 switch(x.type) { 00421 case msgpack::type::NIL: 00422 return true; 00423 00424 case msgpack::type::BOOLEAN: 00425 return x.via.boolean == y.via.boolean; 00426 00427 case msgpack::type::POSITIVE_INTEGER: 00428 return x.via.u64 == y.via.u64; 00429 00430 case msgpack::type::NEGATIVE_INTEGER: 00431 return x.via.i64 == y.via.i64; 00432 00433 case msgpack::type::FLOAT: 00434 return x.via.f64 == y.via.f64; 00435 00436 case msgpack::type::STR: 00437 return x.via.str.size == y.via.str.size && 00438 std::memcmp(x.via.str.ptr, y.via.str.ptr, x.via.str.size) == 0; 00439 00440 case msgpack::type::BIN: 00441 return x.via.bin.size == y.via.bin.size && 00442 std::memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0; 00443 00444 case msgpack::type::EXT: 00445 return x.via.ext.size == y.via.ext.size && 00446 std::memcmp(x.via.ext.ptr, y.via.ext.ptr, x.via.ext.size) == 0; 00447 00448 case msgpack::type::ARRAY: 00449 if(x.via.array.size != y.via.array.size) { 00450 return false; 00451 } else if(x.via.array.size == 0) { 00452 return true; 00453 } else { 00454 msgpack::object* px = x.via.array.ptr; 00455 msgpack::object* const pxend = x.via.array.ptr + x.via.array.size; 00456 msgpack::object* py = y.via.array.ptr; 00457 do { 00458 if(!(*px == *py)) { 00459 return false; 00460 } 00461 ++px; 00462 ++py; 00463 } while(px < pxend); 00464 return true; 00465 } 00466 00467 case msgpack::type::MAP: 00468 if(x.via.map.size != y.via.map.size) { 00469 return false; 00470 } else if(x.via.map.size == 0) { 00471 return true; 00472 } else { 00473 msgpack::object_kv* px = x.via.map.ptr; 00474 msgpack::object_kv* const pxend = x.via.map.ptr + x.via.map.size; 00475 msgpack::object_kv* py = y.via.map.ptr; 00476 do { 00477 if(!(px->key == py->key) || !(px->val == py->val)) { 00478 return false; 00479 } 00480 ++px; 00481 ++py; 00482 } while(px < pxend); 00483 return true; 00484 } 00485 00486 default: 00487 return false; 00488 } 00489 } 00490 00491 template <typename T> 00492 inline bool operator==(const msgpack::object& x, const T& y) 00493 try { 00494 return x == msgpack::object(y); 00495 } catch (msgpack::type_error&) { 00496 return false; 00497 } 00498 00499 inline bool operator!=(const msgpack::object& x, const msgpack::object& y) 00500 { return !(x == y); } 00501 00502 template <typename T> 00503 inline bool operator==(const T& y, const msgpack::object& x) 00504 { return x == y; } 00505 00506 template <typename T> 00507 inline bool operator!=(const msgpack::object& x, const T& y) 00508 { return !(x == y); } 00509 00510 template <typename T> 00511 inline bool operator!=(const T& y, const msgpack::object& x) 00512 { return x != y; } 00513 00514 00515 inline msgpack::object::implicit_type object::convert() const 00516 { 00517 return msgpack::object::implicit_type(*this); 00518 } 00519 00520 template <typename T> 00521 inline T& object::convert(T& v) const 00522 { 00523 msgpack::operator>>(*this, v); 00524 return v; 00525 } 00526 00527 #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT) 00528 template <typename T> 00529 inline T* object::convert(T* v) const 00530 { 00531 convert(*v); 00532 return v; 00533 } 00534 #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT) 00535 00536 template <typename T> 00537 inline bool object::convert_if_not_nil(T& v) const 00538 { 00539 if (is_nil()) { 00540 return false; 00541 } 00542 convert(v); 00543 return true; 00544 } 00545 00546 #if defined(MSGPACK_USE_CPP03) 00547 00548 template <typename T> 00549 inline T object::as() const 00550 { 00551 T v; 00552 convert(v); 00553 return v; 00554 } 00555 00556 #else // defined(MSGPACK_USE_CPP03) 00557 00558 template <typename T> 00559 inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const { 00560 return msgpack::adaptor::as<T>()(*this); 00561 } 00562 00563 template <typename T> 00564 inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const { 00565 T v; 00566 convert(v); 00567 return v; 00568 } 00569 00570 #endif // defined(MSGPACK_USE_CPP03) 00571 00572 inline object::object() 00573 { 00574 type = msgpack::type::NIL; 00575 } 00576 00577 template <typename T> 00578 inline object::object(const T& v) 00579 { 00580 msgpack::operator<<(*this, v); 00581 } 00582 00583 template <typename T> 00584 inline object& object::operator=(const T& v) 00585 { 00586 *this = object(v); 00587 return *this; 00588 } 00589 00590 template <typename T> 00591 object::object(const T& v, msgpack::zone& z) 00592 { 00593 with_zone oz(z); 00594 msgpack::operator<<(oz, v); 00595 type = oz.type; 00596 via = oz.via; 00597 } 00598 00599 template <typename T> 00600 object::object(const T& v, msgpack::zone* z) 00601 { 00602 with_zone oz(*z); 00603 msgpack::operator<<(oz, v); 00604 type = oz.type; 00605 via = oz.via; 00606 } 00607 00608 00609 inline object::object(const msgpack_object& o) 00610 { 00611 // FIXME beter way? 00612 std::memcpy(this, &o, sizeof(o)); 00613 } 00614 00615 inline void operator<< (msgpack::object& o, const msgpack_object& v) 00616 { 00617 // FIXME beter way? 00618 std::memcpy(&o, &v, sizeof(v)); 00619 } 00620 00621 inline object::operator msgpack_object() const 00622 { 00623 // FIXME beter way? 00624 msgpack_object obj; 00625 std::memcpy(&obj, this, sizeof(obj)); 00626 return obj; 00627 } 00628 00629 00630 // obsolete 00631 template <typename T> 00632 inline void convert(T& v, msgpack::object const& o) 00633 { 00634 o.convert(v); 00635 } 00636 00637 // obsolete 00638 template <typename Stream, typename T> 00639 inline void pack(msgpack::packer<Stream> & o, const T& v) 00640 { 00641 o.pack(v); 00642 } 00643 00644 // obsolete 00645 template <typename Stream, typename T> 00646 inline void pack_copy(msgpack::packer<Stream> & o, T v) 00647 { 00648 pack(o, v); 00649 } 00650 00651 00652 template <typename Stream> 00653 inline msgpack::packer<Stream> & operator<< (msgpack::packer<Stream>& o, const msgpack::object& v) 00654 { 00655 switch(v.type) { 00656 case msgpack::type::NIL: 00657 o.pack_nil(); 00658 return o; 00659 00660 case msgpack::type::BOOLEAN: 00661 if(v.via.boolean) { 00662 o.pack_true(); 00663 } else { 00664 o.pack_false(); 00665 } 00666 return o; 00667 00668 case msgpack::type::POSITIVE_INTEGER: 00669 o.pack_uint64(v.via.u64); 00670 return o; 00671 00672 case msgpack::type::NEGATIVE_INTEGER: 00673 o.pack_int64(v.via.i64); 00674 return o; 00675 00676 case msgpack::type::FLOAT: 00677 o.pack_double(v.via.f64); 00678 return o; 00679 00680 case msgpack::type::STR: 00681 o.pack_str(v.via.str.size); 00682 o.pack_str_body(v.via.str.ptr, v.via.str.size); 00683 return o; 00684 00685 case msgpack::type::BIN: 00686 o.pack_bin(v.via.bin.size); 00687 o.pack_bin_body(v.via.bin.ptr, v.via.bin.size); 00688 return o; 00689 00690 case msgpack::type::EXT: 00691 o.pack_ext(v.via.ext.size, v.via.ext.type()); 00692 o.pack_ext_body(v.via.ext.data(), v.via.ext.size); 00693 return o; 00694 00695 case msgpack::type::ARRAY: 00696 o.pack_array(v.via.array.size); 00697 for(msgpack::object* p(v.via.array.ptr), 00698 * const pend(v.via.array.ptr + v.via.array.size); 00699 p < pend; ++p) { 00700 msgpack::operator<<(o, *p); 00701 } 00702 return o; 00703 00704 case msgpack::type::MAP: 00705 o.pack_map(v.via.map.size); 00706 for(msgpack::object_kv* p(v.via.map.ptr), 00707 * const pend(v.via.map.ptr + v.via.map.size); 00708 p < pend; ++p) { 00709 msgpack::operator<<(o, p->key); 00710 msgpack::operator<<(o, p->val); 00711 } 00712 return o; 00713 00714 default: 00715 throw msgpack::type_error(); 00716 } 00717 } 00718 00719 template <typename Stream> 00720 msgpack::packer<Stream> & operator<< (msgpack::packer<Stream>& o, const msgpack::object::with_zone& v) 00721 { 00722 return o << static_cast<msgpack::object>(v); 00723 } 00724 00725 inline std::ostream& operator<< (std::ostream& s, const msgpack::object& o) 00726 { 00727 switch(o.type) { 00728 case msgpack::type::NIL: 00729 s << "nil"; 00730 break; 00731 00732 case msgpack::type::BOOLEAN: 00733 s << (o.via.boolean ? "true" : "false"); 00734 break; 00735 00736 case msgpack::type::POSITIVE_INTEGER: 00737 s << o.via.u64; 00738 break; 00739 00740 case msgpack::type::NEGATIVE_INTEGER: 00741 s << o.via.i64; 00742 break; 00743 00744 case msgpack::type::FLOAT: 00745 s << o.via.f64; 00746 break; 00747 00748 case msgpack::type::STR: 00749 s << '"'; 00750 for (uint32_t i = 0; i < o.via.str.size; ++i) { 00751 char c = o.via.str.ptr[i]; 00752 switch (c) { 00753 case '\\': 00754 s << "\\\\"; 00755 break; 00756 case '"': 00757 s << "\\\""; 00758 break; 00759 case '/': 00760 s << "\\/"; 00761 break; 00762 case '\b': 00763 s << "\\b"; 00764 break; 00765 case '\f': 00766 s << "\\f"; 00767 break; 00768 case '\n': 00769 s << "\\n"; 00770 break; 00771 case '\r': 00772 s << "\\r"; 00773 break; 00774 case '\t': 00775 s << "\\t"; 00776 break; 00777 default: { 00778 unsigned int code = static_cast<unsigned int>(c); 00779 if (code < 0x20 || code == 0x7f) { 00780 s << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (code & 0xff); 00781 } 00782 else { 00783 s << c; 00784 } 00785 } break; 00786 } 00787 } 00788 s << '"'; 00789 break; 00790 00791 case msgpack::type::BIN: 00792 (s << '"').write(o.via.bin.ptr, o.via.bin.size) << '"'; 00793 break; 00794 00795 case msgpack::type::EXT: 00796 s << "EXT"; 00797 break; 00798 00799 case msgpack::type::ARRAY: 00800 s << "["; 00801 if(o.via.array.size != 0) { 00802 msgpack::object* p(o.via.array.ptr); 00803 s << *p; 00804 ++p; 00805 for(msgpack::object* const pend(o.via.array.ptr + o.via.array.size); 00806 p < pend; ++p) { 00807 s << ", " << *p; 00808 } 00809 } 00810 s << "]"; 00811 break; 00812 00813 case msgpack::type::MAP: 00814 s << "{"; 00815 if(o.via.map.size != 0) { 00816 msgpack::object_kv* p(o.via.map.ptr); 00817 s << p->key << ':' << p->val; 00818 ++p; 00819 for(msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size); 00820 p < pend; ++p) { 00821 s << ", " << p->key << ':' << p->val; 00822 } 00823 } 00824 s << "}"; 00825 break; 00826 00827 default: 00828 // FIXME 00829 s << "#<UNKNOWN " << static_cast<uint16_t>(o.type) << ">"; 00830 } 00831 return s; 00832 } 00833 00834 /// @cond 00835 } // MSGPACK_API_VERSION_NAMESPACE(v1) 00836 /// @endcond 00837 00838 } // namespace msgpack 00839 00840 #include "msgpack/type.hpp" 00841 00842 #endif /* msgpack/object.hpp */
Generated on Tue Jul 12 2022 22:51:46 by 1.7.2