object.hpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. //
  2. // MessagePack for C++ static resolution routine
  3. //
  4. // Copyright (C) 2008-2014 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_OBJECT_HPP
  11. #define MSGPACK_V1_OBJECT_HPP
  12. #include "msgpack/object_decl.hpp"
  13. #include "msgpack/adaptor/check_container_size.hpp"
  14. #include <cstring>
  15. #include <stdexcept>
  16. #include <typeinfo>
  17. #include <limits>
  18. #include <ostream>
  19. #include <typeinfo>
  20. #include <iomanip>
  21. namespace msgpack {
  22. /// @cond
  23. MSGPACK_API_VERSION_NAMESPACE(v1) {
  24. /// @endcond
  25. struct object_kv {
  26. msgpack::object key;
  27. msgpack::object val;
  28. };
  29. struct object::with_zone : msgpack::object {
  30. with_zone(msgpack::zone& z) : zone(z) { }
  31. msgpack::zone& zone;
  32. private:
  33. with_zone();
  34. };
  35. /// The class holds object and zone
  36. class object_handle {
  37. public:
  38. /// Constructor that creates nil object and null zone.
  39. object_handle() {}
  40. /// Constructor that creates an object_handle holding object `obj` and zone `z`.
  41. /**
  42. * @param obj object
  43. * @param z zone
  44. */
  45. object_handle(
  46. msgpack::object const& obj,
  47. #if defined(MSGPACK_USE_CPP03)
  48. msgpack::unique_ptr<msgpack::zone> z
  49. #else // defined(MSGPACK_USE_CPP03)
  50. msgpack::unique_ptr<msgpack::zone>&& z
  51. #endif // defined(MSGPACK_USE_CPP03)
  52. ) :
  53. m_obj(obj), m_zone(msgpack::move(z)) { }
  54. void set(msgpack::object const& obj)
  55. { m_obj = obj; }
  56. /// Get object reference
  57. /**
  58. * @return object
  59. */
  60. const msgpack::object& get() const
  61. { return m_obj; }
  62. /**
  63. * @return object (to mimic smart pointers).
  64. */
  65. const msgpack::object& operator*() const
  66. { return get(); }
  67. /**
  68. * @return the address of the object (to mimic smart pointers).
  69. */
  70. const msgpack::object* operator->() const
  71. { return &get(); }
  72. /// Get unique_ptr reference of zone.
  73. /**
  74. * @return unique_ptr reference of zone
  75. */
  76. msgpack::unique_ptr<msgpack::zone>& zone()
  77. { return m_zone; }
  78. /// Get unique_ptr const reference of zone.
  79. /**
  80. * @return unique_ptr const reference of zone
  81. */
  82. const msgpack::unique_ptr<msgpack::zone>& zone() const
  83. { return m_zone; }
  84. #if defined(MSGPACK_USE_CPP03)
  85. struct object_handle_ref {
  86. object_handle_ref(object_handle* oh):m_oh(oh) {}
  87. object_handle* m_oh;
  88. };
  89. object_handle(object_handle& other):
  90. m_obj(other.m_obj),
  91. m_zone(msgpack::move(other.m_zone)) {
  92. }
  93. object_handle(object_handle_ref ref):
  94. m_obj(ref.m_oh->m_obj),
  95. m_zone(msgpack::move(ref.m_oh->m_zone)) {
  96. }
  97. object_handle& operator=(object_handle& other) {
  98. m_obj = other.m_obj;
  99. m_zone = msgpack::move(other.m_zone);
  100. return *this;
  101. }
  102. object_handle& operator=(object_handle_ref ref) {
  103. m_obj = ref.m_oh->m_obj;
  104. m_zone = msgpack::move(ref.m_oh->m_zone);
  105. return *this;
  106. }
  107. operator object_handle_ref() {
  108. return object_handle_ref(this);
  109. }
  110. #endif // defined(MSGPACK_USE_CPP03)
  111. private:
  112. msgpack::object m_obj;
  113. msgpack::unique_ptr<msgpack::zone> m_zone;
  114. };
  115. namespace detail {
  116. template <std::size_t N>
  117. inline std::size_t add_ext_type_size(std::size_t size) {
  118. return size + 1;
  119. }
  120. template <>
  121. inline std::size_t add_ext_type_size<4>(std::size_t size) {
  122. return size == 0xffffffff ? size : size + 1;
  123. }
  124. } // namespace detail
  125. class object_parser {
  126. private:
  127. enum next_ret {
  128. cont,
  129. finish,
  130. abort
  131. };
  132. struct elem {
  133. elem(msgpack::object const* p, std::size_t r)
  134. : rest(r), is_map(false), is_key(false) {
  135. as.obj_ptr = p;
  136. }
  137. elem(msgpack::object_kv const* p, std::size_t r)
  138. : rest(r), is_map(true), is_key(true) {
  139. as.kv_ptr = p;
  140. }
  141. msgpack::object const& get() const {
  142. if (is_map) {
  143. if (is_key) {
  144. return as.kv_ptr->key;
  145. }
  146. else {
  147. return as.kv_ptr->val;
  148. }
  149. }
  150. else {
  151. return *as.obj_ptr;
  152. }
  153. }
  154. template <typename Visitor>
  155. next_ret next(Visitor& v) {
  156. if (rest == 0) {
  157. if (is_map) {
  158. if (!v.end_map()) return abort;
  159. }
  160. else {
  161. if (!v.end_array()) return abort;
  162. }
  163. return finish;
  164. }
  165. else {
  166. if (is_map) {
  167. if (is_key) {
  168. if (!v.end_map_key()) return abort;
  169. if (!v.start_map_value()) return abort;
  170. is_key = false;
  171. }
  172. else {
  173. if (!v.end_map_value()) return abort;
  174. --rest;
  175. if (rest == 0) {
  176. if (!v.end_map()) return abort;
  177. return finish;
  178. }
  179. if (!v.start_map_key()) return abort;
  180. ++as.kv_ptr;
  181. is_key = true;
  182. }
  183. }
  184. else {
  185. if (!v.end_array_item()) return abort;
  186. --rest;
  187. if (rest == 0) {
  188. if (!v.end_array()) return abort;
  189. return finish;
  190. }
  191. if (!v.start_array_item()) return abort;
  192. ++as.obj_ptr;
  193. }
  194. return cont;
  195. }
  196. }
  197. union {
  198. msgpack::object const* obj_ptr;
  199. msgpack::object_kv const* kv_ptr;
  200. } as;
  201. std::size_t rest;
  202. bool is_map;
  203. bool is_key;
  204. };
  205. public:
  206. explicit object_parser(msgpack::object const& obj):m_current(&obj) {}
  207. template <typename Visitor>
  208. void parse(Visitor& v) {
  209. while (true) {
  210. bool start_collection = false;
  211. switch(m_current->type) {
  212. case msgpack::type::NIL:
  213. if (!v.visit_nil()) return;
  214. break;
  215. case msgpack::type::BOOLEAN:
  216. if (!v.visit_boolean(m_current->via.boolean)) return;
  217. break;
  218. case msgpack::type::POSITIVE_INTEGER:
  219. if (!v.visit_positive_integer(m_current->via.u64)) return;
  220. break;
  221. case msgpack::type::NEGATIVE_INTEGER:
  222. if (!v.visit_negative_integer(m_current->via.i64)) return;
  223. break;
  224. case msgpack::type::FLOAT32:
  225. if (!v.visit_float32(static_cast<float>(m_current->via.f64))) return;
  226. break;
  227. case msgpack::type::FLOAT64:
  228. if (!v.visit_float64(m_current->via.f64)) return;
  229. break;
  230. case msgpack::type::STR:
  231. if (!v.visit_str(m_current->via.str.ptr, m_current->via.str.size)) return;
  232. break;
  233. case msgpack::type::BIN:
  234. if (!v.visit_bin(m_current->via.bin.ptr, m_current->via.bin.size)) return;
  235. break;
  236. case msgpack::type::EXT:
  237. msgpack::detail::check_container_size<sizeof(std::size_t)>(m_current->via.ext.size);
  238. if (!v.visit_ext(m_current->via.ext.ptr, m_current->via.ext.size + 1)) return;
  239. break;
  240. case msgpack::type::ARRAY:
  241. if (!v.start_array(m_current->via.array.size)) return;
  242. m_ctx.push_back(elem(m_current->via.array.ptr, m_current->via.array.size));
  243. start_collection = m_current->via.array.size != 0;
  244. if (start_collection) {
  245. if (!v.start_array_item()) return;
  246. }
  247. break;
  248. case msgpack::type::MAP:
  249. if (!v.start_map(m_current->via.map.size)) return;
  250. m_ctx.push_back(elem(m_current->via.map.ptr, m_current->via.map.size));
  251. start_collection = m_current->via.map.size != 0;
  252. if (start_collection) {
  253. if (!v.start_map_key()) return;
  254. }
  255. break;
  256. default:
  257. throw msgpack::type_error();
  258. break;
  259. }
  260. if (m_ctx.empty()) return;
  261. if (!start_collection) {
  262. while (true) {
  263. next_ret r = m_ctx.back().next(v);
  264. if (r == finish) {
  265. m_ctx.pop_back();
  266. if (m_ctx.empty()) return;
  267. }
  268. else if (r == cont) {
  269. break;
  270. }
  271. else {
  272. // abort
  273. return;
  274. }
  275. }
  276. }
  277. m_current = &m_ctx.back().get();
  278. }
  279. }
  280. private:
  281. msgpack::object const* m_current;
  282. std::vector<elem> m_ctx;
  283. };
  284. template <typename Stream>
  285. struct object_pack_visitor {
  286. explicit object_pack_visitor(msgpack::packer<Stream>& pk)
  287. :m_packer(pk) {}
  288. bool visit_nil() {
  289. m_packer.pack_nil();
  290. return true;
  291. }
  292. bool visit_boolean(bool v) {
  293. if (v) m_packer.pack_true();
  294. else m_packer.pack_false();
  295. return true;
  296. }
  297. bool visit_positive_integer(uint64_t v) {
  298. m_packer.pack_uint64(v);
  299. return true;
  300. }
  301. bool visit_negative_integer(int64_t v) {
  302. m_packer.pack_int64(v);
  303. return true;
  304. }
  305. bool visit_float32(float v) {
  306. m_packer.pack_float(v);
  307. return true;
  308. }
  309. bool visit_float64(double v) {
  310. m_packer.pack_double(v);
  311. return true;
  312. }
  313. bool visit_str(const char* v, uint32_t size) {
  314. m_packer.pack_str(size);
  315. m_packer.pack_str_body(v, size);
  316. return true;
  317. }
  318. bool visit_bin(const char* v, uint32_t size) {
  319. m_packer.pack_bin(size);
  320. m_packer.pack_bin_body(v, size);
  321. return true;
  322. }
  323. bool visit_ext(const char* v, uint32_t size) {
  324. m_packer.pack_ext(size, *v);
  325. m_packer.pack_ext_body(v, size);
  326. return true;
  327. }
  328. bool start_array(uint32_t num_elements) {
  329. m_packer.pack_array(num_elements);
  330. return true;
  331. }
  332. bool start_array_item() {
  333. return true;
  334. }
  335. bool end_array_item() {
  336. return true;
  337. }
  338. bool end_array() {
  339. return true;
  340. }
  341. bool start_map(uint32_t num_kv_pairs) {
  342. m_packer.pack_map(num_kv_pairs);
  343. return true;
  344. }
  345. bool start_map_key() {
  346. return true;
  347. }
  348. bool end_map_key() {
  349. return true;
  350. }
  351. bool start_map_value() {
  352. return true;
  353. }
  354. bool end_map_value() {
  355. return true;
  356. }
  357. bool end_map() {
  358. return true;
  359. }
  360. private:
  361. msgpack::packer<Stream>& m_packer;
  362. };
  363. struct object_stringize_visitor {
  364. explicit object_stringize_visitor(std::ostream& os)
  365. :m_os(os) {}
  366. bool visit_nil() {
  367. m_os << "null";
  368. return true;
  369. }
  370. bool visit_boolean(bool v) {
  371. if (v) m_os << "true";
  372. else m_os << "false";
  373. return true;
  374. }
  375. bool visit_positive_integer(uint64_t v) {
  376. m_os << v;
  377. return true;
  378. }
  379. bool visit_negative_integer(int64_t v) {
  380. m_os << v;
  381. return true;
  382. }
  383. bool visit_float32(float v) {
  384. m_os << v;
  385. return true;
  386. }
  387. bool visit_float64(double v) {
  388. m_os << v;
  389. return true;
  390. }
  391. bool visit_str(const char* v, uint32_t size) {
  392. m_os << '"';
  393. for (uint32_t i = 0; i < size; ++i) {
  394. char c = v[i];
  395. switch (c) {
  396. case '\\':
  397. m_os << "\\\\";
  398. break;
  399. case '"':
  400. m_os << "\\\"";
  401. break;
  402. case '/':
  403. m_os << "\\/";
  404. break;
  405. case '\b':
  406. m_os << "\\b";
  407. break;
  408. case '\f':
  409. m_os << "\\f";
  410. break;
  411. case '\n':
  412. m_os << "\\n";
  413. break;
  414. case '\r':
  415. m_os << "\\r";
  416. break;
  417. case '\t':
  418. m_os << "\\t";
  419. break;
  420. default: {
  421. unsigned int code = static_cast<unsigned int>(c);
  422. if (code < 0x20 || code == 0x7f) {
  423. std::ios::fmtflags flags(m_os.flags());
  424. m_os << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (code & 0xff);
  425. m_os.flags(flags);
  426. }
  427. else {
  428. m_os << c;
  429. }
  430. } break;
  431. }
  432. }
  433. m_os << '"';
  434. return true;
  435. }
  436. bool visit_bin(const char* v, uint32_t size) {
  437. (m_os << '"').write(v, size) << '"';
  438. return true;
  439. }
  440. bool visit_ext(const char* /*v*/, uint32_t /*size*/) {
  441. m_os << "EXT";
  442. return true;
  443. }
  444. bool start_array(uint32_t num_elements) {
  445. m_current_size.push_back(num_elements);
  446. m_os << "[";
  447. return true;
  448. }
  449. bool start_array_item() {
  450. return true;
  451. }
  452. bool end_array_item() {
  453. --m_current_size.back();
  454. if (m_current_size.back() != 0) {
  455. m_os << ",";
  456. }
  457. return true;
  458. }
  459. bool end_array() {
  460. m_current_size.pop_back();
  461. m_os << "]";
  462. return true;
  463. }
  464. bool start_map(uint32_t num_kv_pairs) {
  465. m_current_size.push_back(num_kv_pairs);
  466. m_os << "{";
  467. return true;
  468. }
  469. bool start_map_key() {
  470. return true;
  471. }
  472. bool end_map_key() {
  473. m_os << ":";
  474. return true;
  475. }
  476. bool start_map_value() {
  477. return true;
  478. }
  479. bool end_map_value() {
  480. --m_current_size.back();
  481. if (m_current_size.back() != 0) {
  482. m_os << ",";
  483. }
  484. return true;
  485. }
  486. bool end_map() {
  487. m_current_size.pop_back();
  488. m_os << "}";
  489. return true;
  490. }
  491. private:
  492. std::ostream& m_os;
  493. std::vector<uint32_t> m_current_size;
  494. };
  495. struct aligned_zone_size_visitor {
  496. explicit aligned_zone_size_visitor(std::size_t s)
  497. :m_size(s) {}
  498. bool visit_nil() {
  499. return true;
  500. }
  501. bool visit_boolean(bool) {
  502. return true;
  503. }
  504. bool visit_positive_integer(uint64_t) {
  505. return true;
  506. }
  507. bool visit_negative_integer(int64_t) {
  508. return true;
  509. }
  510. bool visit_float32(float) {
  511. return true;
  512. }
  513. bool visit_float64(double) {
  514. return true;
  515. }
  516. bool visit_str(const char*, uint32_t size) {
  517. m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
  518. return true;
  519. }
  520. bool visit_bin(const char*, uint32_t size) {
  521. m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
  522. return true;
  523. }
  524. bool visit_ext(const char*, uint32_t size) {
  525. m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
  526. return true;
  527. }
  528. bool start_array(uint32_t num_elements) {
  529. m_size += msgpack::aligned_size(
  530. sizeof(msgpack::object) * num_elements,
  531. MSGPACK_ZONE_ALIGNOF(msgpack::object));
  532. return true;
  533. }
  534. bool start_array_item() {
  535. return true;
  536. }
  537. bool end_array_item() {
  538. return true;
  539. }
  540. bool end_array() {
  541. return true;
  542. }
  543. bool start_map(uint32_t num_kv_pairs) {
  544. m_size += msgpack::aligned_size(
  545. sizeof(msgpack::object_kv) * num_kv_pairs,
  546. MSGPACK_ZONE_ALIGNOF(msgpack::object_kv));
  547. return true;
  548. }
  549. bool start_map_key() {
  550. return true;
  551. }
  552. bool end_map_key() {
  553. return true;
  554. }
  555. bool start_map_value() {
  556. return true;
  557. }
  558. bool end_map_value() {
  559. return true;
  560. }
  561. bool end_map() {
  562. return true;
  563. }
  564. private:
  565. std::size_t m_size;
  566. };
  567. inline std::size_t aligned_zone_size(msgpack::object const& obj) {
  568. std::size_t s = 0;
  569. aligned_zone_size_visitor vis(s);
  570. msgpack::object_parser(obj).parse(vis);
  571. return s;
  572. }
  573. /// clone object
  574. /**
  575. * Clone (deep copy) object.
  576. * The copied object is located on newly allocated zone.
  577. * @param obj copy source object
  578. *
  579. * @return object_handle that holds deep copied object and zone.
  580. */
  581. inline object_handle clone(msgpack::object const& obj) {
  582. std::size_t size = msgpack::aligned_zone_size(obj);
  583. msgpack::unique_ptr<msgpack::zone> z(size == 0 ? MSGPACK_NULLPTR : new msgpack::zone(size));
  584. msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj;
  585. return object_handle(newobj, msgpack::move(z));
  586. }
  587. template <typename T>
  588. inline object::implicit_type::operator T() { return obj.as<T>(); }
  589. namespace detail {
  590. template <typename Stream, typename T>
  591. struct packer_serializer {
  592. static msgpack::packer<Stream>& pack(msgpack::packer<Stream>& o, const T& v) {
  593. v.msgpack_pack(o);
  594. return o;
  595. }
  596. };
  597. } // namespace detail
  598. // Adaptor functors' member functions definitions.
  599. template <typename T, typename Enabler>
  600. inline
  601. msgpack::object const&
  602. adaptor::convert<T, Enabler>::operator()(msgpack::object const& o, T& v) const {
  603. v.msgpack_unpack(o.convert());
  604. return o;
  605. }
  606. template <typename T, typename Enabler>
  607. template <typename Stream>
  608. inline
  609. msgpack::packer<Stream>&
  610. adaptor::pack<T, Enabler>::operator()(msgpack::packer<Stream>& o, T const& v) const {
  611. return msgpack::detail::packer_serializer<Stream, T>::pack(o, v);
  612. }
  613. template <typename T, typename Enabler>
  614. inline
  615. void
  616. adaptor::object_with_zone<T, Enabler>::operator()(msgpack::object::with_zone& o, T const& v) const {
  617. v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone);
  618. }
  619. // Adaptor functor specialization to object
  620. namespace adaptor {
  621. template <>
  622. struct convert<msgpack::object> {
  623. msgpack::object const& operator()(msgpack::object const& o, msgpack::object& v) const {
  624. v = o;
  625. return o;
  626. }
  627. };
  628. template <>
  629. struct pack<msgpack::object> {
  630. template <typename Stream>
  631. msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, msgpack::object const& v) const {
  632. object_pack_visitor<Stream> vis(o);
  633. msgpack::object_parser(v).parse(vis);
  634. return o;
  635. }
  636. };
  637. template <>
  638. struct object_with_zone<msgpack::object> {
  639. void operator()(msgpack::object::with_zone& o, msgpack::object const& v) const {
  640. object_with_zone_visitor vis(o);
  641. msgpack::object_parser(v).parse(vis);
  642. }
  643. private:
  644. struct object_with_zone_visitor {
  645. explicit object_with_zone_visitor(msgpack::object::with_zone& owz)
  646. :m_zone(owz.zone), m_ptr(&owz) {
  647. m_objs.push_back(&owz);
  648. }
  649. bool visit_nil() {
  650. m_ptr->type = msgpack::type::NIL;
  651. return true;
  652. }
  653. bool visit_boolean(bool v) {
  654. m_ptr->type = msgpack::type::BOOLEAN;
  655. m_ptr->via.boolean = v;
  656. return true;
  657. }
  658. bool visit_positive_integer(uint64_t v) {
  659. m_ptr->type = msgpack::type::POSITIVE_INTEGER;
  660. m_ptr->via.u64 = v;
  661. return true;
  662. }
  663. bool visit_negative_integer(int64_t v) {
  664. m_ptr->type = msgpack::type::NEGATIVE_INTEGER;
  665. m_ptr->via.i64 = v;
  666. return true;
  667. }
  668. bool visit_float32(float v) {
  669. m_ptr->type = msgpack::type::FLOAT32;
  670. m_ptr->via.f64 = v;
  671. return true;
  672. }
  673. bool visit_float64(double v) {
  674. m_ptr->type = msgpack::type::FLOAT64;
  675. m_ptr->via.f64 = v;
  676. return true;
  677. }
  678. bool visit_str(const char* v, uint32_t size) {
  679. m_ptr->type = msgpack::type::STR;
  680. m_ptr->via.str.size = size;
  681. char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
  682. m_ptr->via.str.ptr = ptr;
  683. std::memcpy(ptr, v, size);
  684. return true;
  685. }
  686. bool visit_bin(const char* v, uint32_t size) {
  687. m_ptr->type = msgpack::type::BIN;
  688. m_ptr->via.bin.size = size;
  689. char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
  690. m_ptr->via.bin.ptr = ptr;
  691. std::memcpy(ptr, v, size);
  692. return true;
  693. }
  694. bool visit_ext(const char* v, uint32_t size) {
  695. m_ptr->type = msgpack::type::EXT;
  696. // v contains type but length(size) doesn't count the type byte.
  697. // See https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
  698. m_ptr->via.ext.size = size - 1;
  699. char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
  700. m_ptr->via.ext.ptr = ptr;
  701. std::memcpy(ptr, v, size);
  702. return true;
  703. }
  704. bool start_array(uint32_t num_elements) {
  705. m_ptr->type = msgpack::type::ARRAY;
  706. m_ptr->via.array.ptr = static_cast<msgpack::object*>(
  707. m_zone.allocate_align(
  708. sizeof(msgpack::object) * num_elements, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
  709. m_ptr->via.array.size = num_elements;
  710. m_objs.push_back(elem(m_ptr->via.array.ptr));
  711. return true;
  712. }
  713. bool start_array_item() {
  714. m_ptr = m_objs.back().get_item();
  715. return true;
  716. }
  717. bool end_array_item() {
  718. ++m_objs.back().as.obj;
  719. return true;
  720. }
  721. bool end_array() {
  722. m_objs.pop_back();
  723. return true;
  724. }
  725. bool start_map(uint32_t num_kv_pairs) {
  726. m_ptr->type = msgpack::type::MAP;
  727. m_ptr->via.map.ptr = (msgpack::object_kv*)m_zone.allocate_align(
  728. sizeof(msgpack::object_kv) * num_kv_pairs, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv));
  729. m_ptr->via.map.size = num_kv_pairs;
  730. m_objs.push_back(elem(m_ptr->via.map.ptr));
  731. return true;
  732. }
  733. bool start_map_key() {
  734. m_ptr = m_objs.back().get_key();
  735. return true;
  736. }
  737. bool end_map_key() {
  738. return true;
  739. }
  740. bool start_map_value() {
  741. m_ptr = m_objs.back().get_val();
  742. return true;
  743. }
  744. bool end_map_value() {
  745. ++m_objs.back().as.kv;
  746. return true;
  747. }
  748. bool end_map() {
  749. m_objs.pop_back();
  750. return true;
  751. }
  752. private:
  753. struct elem {
  754. elem(msgpack::object* obj)
  755. :is_obj(true) {
  756. as.obj = obj;
  757. }
  758. elem(msgpack::object_kv* kv)
  759. :is_obj(false) {
  760. as.kv = kv;
  761. }
  762. msgpack::object* get_item() {
  763. return as.obj;
  764. }
  765. msgpack::object* get_key() {
  766. return &as.kv->key;
  767. }
  768. msgpack::object* get_val() {
  769. return &as.kv->val;
  770. }
  771. union {
  772. msgpack::object* obj;
  773. msgpack::object_kv* kv;
  774. } as;
  775. bool is_obj;
  776. };
  777. std::vector<elem> m_objs;
  778. msgpack::zone& m_zone;
  779. msgpack::object* m_ptr;
  780. };
  781. };
  782. // Adaptor functor specialization to object::with_zone
  783. template <>
  784. struct object_with_zone<msgpack::object::with_zone> {
  785. void operator()(
  786. msgpack::object::with_zone& o,
  787. msgpack::object::with_zone const& v) const {
  788. o << static_cast<msgpack::object const&>(v);
  789. }
  790. };
  791. } // namespace adaptor
  792. // obsolete
  793. template <typename Type>
  794. class define : public Type {
  795. public:
  796. typedef Type msgpack_type;
  797. typedef define<Type> define_type;
  798. define() {}
  799. define(const msgpack_type& v) : msgpack_type(v) {}
  800. template <typename Packer>
  801. void msgpack_pack(Packer& o) const
  802. {
  803. msgpack::operator<<(o, static_cast<const msgpack_type&>(*this));
  804. }
  805. void msgpack_unpack(object const& o)
  806. {
  807. msgpack::operator>>(o, static_cast<msgpack_type&>(*this));
  808. }
  809. };
  810. // deconvert operator
  811. template <typename Stream>
  812. template <typename T>
  813. inline msgpack::packer<Stream>& packer<Stream>::pack(const T& v)
  814. {
  815. msgpack::operator<<(*this, v);
  816. return *this;
  817. }
  818. struct object_equal_visitor {
  819. object_equal_visitor(msgpack::object const& obj, bool& result)
  820. :m_ptr(&obj), m_result(result) {}
  821. bool visit_nil() {
  822. if (m_ptr->type != msgpack::type::NIL) {
  823. m_result = false;
  824. return false;
  825. }
  826. return true;
  827. }
  828. bool visit_boolean(bool v) {
  829. if (m_ptr->type != msgpack::type::BOOLEAN || m_ptr->via.boolean != v) {
  830. m_result = false;
  831. return false;
  832. }
  833. return true;
  834. }
  835. bool visit_positive_integer(uint64_t v) {
  836. if (m_ptr->type != msgpack::type::POSITIVE_INTEGER || m_ptr->via.u64 != v) {
  837. m_result = false;
  838. return false;
  839. }
  840. return true;
  841. }
  842. bool visit_negative_integer(int64_t v) {
  843. if (m_ptr->type != msgpack::type::NEGATIVE_INTEGER || m_ptr->via.i64 != v) {
  844. m_result = false;
  845. return false;
  846. }
  847. return true;
  848. }
  849. bool visit_float32(float v) {
  850. if (m_ptr->type != msgpack::type::FLOAT32 || m_ptr->via.f64 != v) {
  851. m_result = false;
  852. return false;
  853. }
  854. return true;
  855. }
  856. bool visit_float64(double v) {
  857. if (m_ptr->type != msgpack::type::FLOAT64 || m_ptr->via.f64 != v) {
  858. m_result = false;
  859. return false;
  860. }
  861. return true;
  862. }
  863. bool visit_str(const char* v, uint32_t size) {
  864. if (m_ptr->type != msgpack::type::STR ||
  865. m_ptr->via.str.size != size ||
  866. std::memcmp(m_ptr->via.str.ptr, v, size) != 0) {
  867. m_result = false;
  868. return false;
  869. }
  870. return true;
  871. }
  872. bool visit_bin(const char* v, uint32_t size) {
  873. if (m_ptr->type != msgpack::type::BIN ||
  874. m_ptr->via.bin.size != size ||
  875. std::memcmp(m_ptr->via.bin.ptr, v, size) != 0) {
  876. m_result = false;
  877. return false;
  878. }
  879. return true;
  880. }
  881. bool visit_ext(const char* v, uint32_t size) {
  882. if (m_ptr->type != msgpack::type::EXT ||
  883. m_ptr->via.ext.size != size ||
  884. std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) {
  885. m_result = false;
  886. return false;
  887. }
  888. return true;
  889. }
  890. bool start_array(uint32_t num_elements) {
  891. if (m_ptr->type != msgpack::type::ARRAY ||
  892. m_ptr->via.array.size != num_elements) {
  893. m_result = false;
  894. return false;
  895. }
  896. m_objs.push_back(elem(m_ptr->via.array.ptr));
  897. return true;
  898. }
  899. bool start_array_item() {
  900. m_ptr = m_objs.back().get_item();
  901. return true;
  902. }
  903. bool end_array_item() {
  904. ++m_objs.back().as.obj;
  905. return true;
  906. }
  907. bool end_array() {
  908. m_objs.pop_back();
  909. return true;
  910. }
  911. bool start_map(uint32_t num_kv_pairs) {
  912. if (m_ptr->type != msgpack::type::MAP ||
  913. m_ptr->via.array.size != num_kv_pairs) {
  914. m_result = false;
  915. return false;
  916. }
  917. m_objs.push_back(elem(m_ptr->via.map.ptr));
  918. return true;
  919. }
  920. bool start_map_key() {
  921. m_ptr = m_objs.back().get_key();
  922. return true;
  923. }
  924. bool end_map_key() {
  925. return true;
  926. }
  927. bool start_map_value() {
  928. m_ptr = m_objs.back().get_val();
  929. return true;
  930. }
  931. bool end_map_value() {
  932. ++m_objs.back().as.kv;
  933. return true;
  934. }
  935. bool end_map() {
  936. m_objs.pop_back();
  937. return true;
  938. }
  939. private:
  940. struct elem {
  941. elem(msgpack::object const* obj)
  942. :is_obj(true) {
  943. as.obj = obj;
  944. }
  945. elem(msgpack::object_kv const* kv)
  946. :is_obj(false) {
  947. as.kv = kv;
  948. }
  949. msgpack::object const* get_item() {
  950. return as.obj;
  951. }
  952. msgpack::object const* get_key() {
  953. return &as.kv->key;
  954. }
  955. msgpack::object const* get_val() {
  956. return &as.kv->val;
  957. }
  958. union {
  959. msgpack::object const* obj;
  960. msgpack::object_kv const* kv;
  961. } as;
  962. bool is_obj;
  963. };
  964. std::vector<elem> m_objs;
  965. msgpack::object const* m_ptr;
  966. bool& m_result;
  967. };
  968. inline bool operator==(const msgpack::object& x, const msgpack::object& y)
  969. {
  970. if(x.type != y.type) { return false; }
  971. bool b = true;
  972. object_equal_visitor vis(y, b);
  973. msgpack::object_parser(x).parse(vis);
  974. return b;
  975. }
  976. template <typename T>
  977. inline bool operator==(const msgpack::object& x, const T& y)
  978. try {
  979. return x == msgpack::object(y);
  980. } catch (msgpack::type_error&) {
  981. return false;
  982. }
  983. inline bool operator!=(const msgpack::object& x, const msgpack::object& y)
  984. { return !(x == y); }
  985. template <typename T>
  986. inline bool operator==(const T& y, const msgpack::object& x)
  987. { return x == y; }
  988. template <typename T>
  989. inline bool operator!=(const msgpack::object& x, const T& y)
  990. { return !(x == y); }
  991. template <typename T>
  992. inline bool operator!=(const T& y, const msgpack::object& x)
  993. { return x != y; }
  994. inline object::implicit_type object::convert() const
  995. {
  996. return object::implicit_type(*this);
  997. }
  998. template <typename T>
  999. inline
  1000. typename msgpack::enable_if<
  1001. !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value,
  1002. T&
  1003. >::type
  1004. object::convert(T& v) const
  1005. {
  1006. msgpack::operator>>(*this, v);
  1007. return v;
  1008. }
  1009. template <typename T, std::size_t N>
  1010. inline T(&object::convert(T(&v)[N]) const)[N]
  1011. {
  1012. msgpack::operator>>(*this, v);
  1013. return v;
  1014. }
  1015. #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
  1016. template <typename T>
  1017. inline
  1018. typename msgpack::enable_if<
  1019. msgpack::is_pointer<T>::value,
  1020. T
  1021. >::type
  1022. object::convert(T v) const
  1023. {
  1024. convert(*v);
  1025. return v;
  1026. }
  1027. #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
  1028. template <typename T>
  1029. inline bool object::convert_if_not_nil(T& v) const
  1030. {
  1031. if (is_nil()) {
  1032. return false;
  1033. }
  1034. convert(v);
  1035. return true;
  1036. }
  1037. #if defined(MSGPACK_USE_CPP03)
  1038. template <typename T>
  1039. inline T object::as() const
  1040. {
  1041. T v;
  1042. convert(v);
  1043. return v;
  1044. }
  1045. #else // defined(MSGPACK_USE_CPP03)
  1046. template <typename T>
  1047. inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const {
  1048. return msgpack::adaptor::as<T>()(*this);
  1049. }
  1050. template <typename T>
  1051. inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const {
  1052. T v;
  1053. convert(v);
  1054. return v;
  1055. }
  1056. #endif // defined(MSGPACK_USE_CPP03)
  1057. inline object::object()
  1058. {
  1059. type = msgpack::type::NIL;
  1060. }
  1061. template <typename T>
  1062. inline object::object(const T& v)
  1063. {
  1064. *this << v;
  1065. }
  1066. template <typename T>
  1067. inline object& object::operator=(const T& v)
  1068. {
  1069. *this = object(v);
  1070. return *this;
  1071. }
  1072. template <typename T>
  1073. inline object::object(const T& v, msgpack::zone& z)
  1074. {
  1075. with_zone oz(z);
  1076. msgpack::operator<<(oz, v);
  1077. type = oz.type;
  1078. via = oz.via;
  1079. }
  1080. template <typename T>
  1081. inline object::object(const T& v, msgpack::zone* z)
  1082. {
  1083. with_zone oz(*z);
  1084. msgpack::operator<<(oz, v);
  1085. type = oz.type;
  1086. via = oz.via;
  1087. }
  1088. inline object::object(const msgpack_object& o)
  1089. {
  1090. // FIXME beter way?
  1091. std::memcpy(this, &o, sizeof(o));
  1092. }
  1093. inline void operator<< (msgpack::object& o, const msgpack_object& v)
  1094. {
  1095. // FIXME beter way?
  1096. std::memcpy(static_cast<void*>(&o), &v, sizeof(v));
  1097. }
  1098. inline object::operator msgpack_object() const
  1099. {
  1100. // FIXME beter way?
  1101. msgpack_object obj;
  1102. std::memcpy(&obj, this, sizeof(obj));
  1103. return obj;
  1104. }
  1105. // obsolete
  1106. template <typename T>
  1107. inline void convert(T& v, msgpack::object const& o)
  1108. {
  1109. o.convert(v);
  1110. }
  1111. // obsolete
  1112. template <typename Stream, typename T>
  1113. inline void pack(msgpack::packer<Stream>& o, const T& v)
  1114. {
  1115. o.pack(v);
  1116. }
  1117. // obsolete
  1118. template <typename Stream, typename T>
  1119. inline void pack_copy(msgpack::packer<Stream>& o, T v)
  1120. {
  1121. pack(o, v);
  1122. }
  1123. template <typename Stream>
  1124. inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object& v)
  1125. {
  1126. object_pack_visitor<Stream> vis(o);
  1127. msgpack::object_parser(v).parse(vis);
  1128. return o;
  1129. }
  1130. template <typename Stream>
  1131. inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object::with_zone& v)
  1132. {
  1133. return o << static_cast<msgpack::object>(v);
  1134. }
  1135. inline std::ostream& operator<< (std::ostream& s, const msgpack::object& v)
  1136. {
  1137. object_stringize_visitor vis(s);
  1138. msgpack::object_parser(v).parse(vis);
  1139. return s;
  1140. }
  1141. /// @cond
  1142. } // MSGPACK_API_VERSION_NAMESPACE(v1)
  1143. /// @endcond
  1144. } // namespace msgpack
  1145. #endif // MSGPACK_V1_OBJECT_HPP