object.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  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_type : msgpack::object {
  30. object_with_zone_type(msgpack::zone& z) : zone(z) { }
  31. msgpack::zone& zone;
  32. private:
  33. object_with_zone_type();
  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 - 1, static_cast<int8_t>(*v));
  325. m_packer.pack_ext_body(v + 1, size - 1);
  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 << "\"BIN(size:" << size << ")\"";
  438. return true;
  439. }
  440. bool visit_ext(const char* v, uint32_t size) {
  441. if (size == 0) {
  442. m_os << "\"EXT(size:0)\"";
  443. }
  444. else {
  445. m_os << "\"EXT(type:" << static_cast<int>(v[0]) << ",size:" << size - 1 << ")\"";
  446. }
  447. return true;
  448. }
  449. bool start_array(uint32_t num_elements) {
  450. m_current_size.push_back(num_elements);
  451. m_os << "[";
  452. return true;
  453. }
  454. bool start_array_item() {
  455. return true;
  456. }
  457. bool end_array_item() {
  458. --m_current_size.back();
  459. if (m_current_size.back() != 0) {
  460. m_os << ",";
  461. }
  462. return true;
  463. }
  464. bool end_array() {
  465. m_current_size.pop_back();
  466. m_os << "]";
  467. return true;
  468. }
  469. bool start_map(uint32_t num_kv_pairs) {
  470. m_current_size.push_back(num_kv_pairs);
  471. m_os << "{";
  472. return true;
  473. }
  474. bool start_map_key() {
  475. return true;
  476. }
  477. bool end_map_key() {
  478. m_os << ":";
  479. return true;
  480. }
  481. bool start_map_value() {
  482. return true;
  483. }
  484. bool end_map_value() {
  485. --m_current_size.back();
  486. if (m_current_size.back() != 0) {
  487. m_os << ",";
  488. }
  489. return true;
  490. }
  491. bool end_map() {
  492. m_current_size.pop_back();
  493. m_os << "}";
  494. return true;
  495. }
  496. private:
  497. std::ostream& m_os;
  498. std::vector<uint32_t> m_current_size;
  499. };
  500. struct aligned_zone_size_visitor {
  501. explicit aligned_zone_size_visitor(std::size_t& s)
  502. :m_size(s) {}
  503. bool visit_nil() {
  504. return true;
  505. }
  506. bool visit_boolean(bool) {
  507. return true;
  508. }
  509. bool visit_positive_integer(uint64_t) {
  510. return true;
  511. }
  512. bool visit_negative_integer(int64_t) {
  513. return true;
  514. }
  515. bool visit_float32(float) {
  516. return true;
  517. }
  518. bool visit_float64(double) {
  519. return true;
  520. }
  521. bool visit_str(const char*, uint32_t size) {
  522. m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
  523. return true;
  524. }
  525. bool visit_bin(const char*, uint32_t size) {
  526. m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
  527. return true;
  528. }
  529. bool visit_ext(const char*, uint32_t size) {
  530. m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
  531. return true;
  532. }
  533. bool start_array(uint32_t num_elements) {
  534. m_size += msgpack::aligned_size(
  535. sizeof(msgpack::object) * num_elements,
  536. MSGPACK_ZONE_ALIGNOF(msgpack::object));
  537. return true;
  538. }
  539. bool start_array_item() {
  540. return true;
  541. }
  542. bool end_array_item() {
  543. return true;
  544. }
  545. bool end_array() {
  546. return true;
  547. }
  548. bool start_map(uint32_t num_kv_pairs) {
  549. m_size += msgpack::aligned_size(
  550. sizeof(msgpack::object_kv) * num_kv_pairs,
  551. MSGPACK_ZONE_ALIGNOF(msgpack::object_kv));
  552. return true;
  553. }
  554. bool start_map_key() {
  555. return true;
  556. }
  557. bool end_map_key() {
  558. return true;
  559. }
  560. bool start_map_value() {
  561. return true;
  562. }
  563. bool end_map_value() {
  564. return true;
  565. }
  566. bool end_map() {
  567. return true;
  568. }
  569. private:
  570. std::size_t& m_size;
  571. };
  572. inline std::size_t aligned_zone_size(msgpack::object const& obj) {
  573. std::size_t s = 0;
  574. aligned_zone_size_visitor vis(s);
  575. msgpack::object_parser(obj).parse(vis);
  576. return s;
  577. }
  578. /// clone object
  579. /**
  580. * Clone (deep copy) object.
  581. * The copied object is located on newly allocated zone.
  582. * @param obj copy source object
  583. *
  584. * @return object_handle that holds deep copied object and zone.
  585. */
  586. inline object_handle clone(msgpack::object const& obj) {
  587. std::size_t size = msgpack::aligned_zone_size(obj);
  588. msgpack::unique_ptr<msgpack::zone> z(size == 0 ? MSGPACK_NULLPTR : new msgpack::zone(size));
  589. msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj;
  590. return object_handle(newobj, msgpack::move(z));
  591. }
  592. template <typename T>
  593. inline object::implicit_type::operator T() { return obj.as<T>(); }
  594. namespace detail {
  595. template <typename Stream, typename T>
  596. struct packer_serializer {
  597. static msgpack::packer<Stream>& pack(msgpack::packer<Stream>& o, const T& v) {
  598. v.msgpack_pack(o);
  599. return o;
  600. }
  601. };
  602. } // namespace detail
  603. // Adaptor functors' member functions definitions.
  604. template <typename T, typename Enabler>
  605. inline
  606. msgpack::object const&
  607. adaptor::convert<T, Enabler>::operator()(msgpack::object const& o, T& v) const {
  608. v.msgpack_unpack(o.convert());
  609. return o;
  610. }
  611. template <typename T, typename Enabler>
  612. template <typename Stream>
  613. inline
  614. msgpack::packer<Stream>&
  615. adaptor::pack<T, Enabler>::operator()(msgpack::packer<Stream>& o, T const& v) const {
  616. return msgpack::detail::packer_serializer<Stream, T>::pack(o, v);
  617. }
  618. template <typename T, typename Enabler>
  619. inline
  620. void
  621. adaptor::object_with_zone<T, Enabler>::operator()(msgpack::object::with_zone& o, T const& v) const {
  622. v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone);
  623. }
  624. // Adaptor functor specialization to object
  625. namespace adaptor {
  626. template <>
  627. struct convert<msgpack::object> {
  628. msgpack::object const& operator()(msgpack::object const& o, msgpack::object& v) const {
  629. v = o;
  630. return o;
  631. }
  632. };
  633. template <>
  634. struct pack<msgpack::object> {
  635. template <typename Stream>
  636. msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, msgpack::object const& v) const {
  637. object_pack_visitor<Stream> vis(o);
  638. msgpack::object_parser(v).parse(vis);
  639. return o;
  640. }
  641. };
  642. template <>
  643. struct object_with_zone<msgpack::object> {
  644. void operator()(msgpack::object::with_zone& o, msgpack::object const& v) const {
  645. object_with_zone_visitor vis(o);
  646. msgpack::object_parser(v).parse(vis);
  647. }
  648. private:
  649. struct object_with_zone_visitor {
  650. explicit object_with_zone_visitor(msgpack::object::with_zone& owz)
  651. :m_zone(owz.zone), m_ptr(&owz) {
  652. m_objs.push_back(&owz);
  653. }
  654. bool visit_nil() {
  655. m_ptr->type = msgpack::type::NIL;
  656. return true;
  657. }
  658. bool visit_boolean(bool v) {
  659. m_ptr->type = msgpack::type::BOOLEAN;
  660. m_ptr->via.boolean = v;
  661. return true;
  662. }
  663. bool visit_positive_integer(uint64_t v) {
  664. m_ptr->type = msgpack::type::POSITIVE_INTEGER;
  665. m_ptr->via.u64 = v;
  666. return true;
  667. }
  668. bool visit_negative_integer(int64_t v) {
  669. m_ptr->type = msgpack::type::NEGATIVE_INTEGER;
  670. m_ptr->via.i64 = v;
  671. return true;
  672. }
  673. bool visit_float32(float v) {
  674. m_ptr->type = msgpack::type::FLOAT32;
  675. m_ptr->via.f64 = v;
  676. return true;
  677. }
  678. bool visit_float64(double v) {
  679. m_ptr->type = msgpack::type::FLOAT64;
  680. m_ptr->via.f64 = v;
  681. return true;
  682. }
  683. bool visit_str(const char* v, uint32_t size) {
  684. m_ptr->type = msgpack::type::STR;
  685. m_ptr->via.str.size = size;
  686. char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
  687. m_ptr->via.str.ptr = ptr;
  688. std::memcpy(ptr, v, size);
  689. return true;
  690. }
  691. bool visit_bin(const char* v, uint32_t size) {
  692. m_ptr->type = msgpack::type::BIN;
  693. m_ptr->via.bin.size = size;
  694. char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
  695. m_ptr->via.bin.ptr = ptr;
  696. std::memcpy(ptr, v, size);
  697. return true;
  698. }
  699. bool visit_ext(const char* v, uint32_t size) {
  700. m_ptr->type = msgpack::type::EXT;
  701. // v contains type but length(size) doesn't count the type byte.
  702. // See https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
  703. m_ptr->via.ext.size = size - 1;
  704. char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
  705. m_ptr->via.ext.ptr = ptr;
  706. std::memcpy(ptr, v, size);
  707. return true;
  708. }
  709. bool start_array(uint32_t num_elements) {
  710. m_ptr->type = msgpack::type::ARRAY;
  711. m_ptr->via.array.ptr = static_cast<msgpack::object*>(
  712. m_zone.allocate_align(
  713. sizeof(msgpack::object) * num_elements, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
  714. m_ptr->via.array.size = num_elements;
  715. m_objs.push_back(elem(m_ptr->via.array.ptr));
  716. return true;
  717. }
  718. bool start_array_item() {
  719. m_ptr = m_objs.back().get_item();
  720. return true;
  721. }
  722. bool end_array_item() {
  723. ++m_objs.back().as.obj;
  724. return true;
  725. }
  726. bool end_array() {
  727. m_objs.pop_back();
  728. return true;
  729. }
  730. bool start_map(uint32_t num_kv_pairs) {
  731. m_ptr->type = msgpack::type::MAP;
  732. m_ptr->via.map.ptr = (msgpack::object_kv*)m_zone.allocate_align(
  733. sizeof(msgpack::object_kv) * num_kv_pairs, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv));
  734. m_ptr->via.map.size = num_kv_pairs;
  735. m_objs.push_back(elem(m_ptr->via.map.ptr));
  736. return true;
  737. }
  738. bool start_map_key() {
  739. m_ptr = m_objs.back().get_key();
  740. return true;
  741. }
  742. bool end_map_key() {
  743. return true;
  744. }
  745. bool start_map_value() {
  746. m_ptr = m_objs.back().get_val();
  747. return true;
  748. }
  749. bool end_map_value() {
  750. ++m_objs.back().as.kv;
  751. return true;
  752. }
  753. bool end_map() {
  754. m_objs.pop_back();
  755. return true;
  756. }
  757. private:
  758. struct elem {
  759. elem(msgpack::object* obj)
  760. :is_obj(true) {
  761. as.obj = obj;
  762. }
  763. elem(msgpack::object_kv* kv)
  764. :is_obj(false) {
  765. as.kv = kv;
  766. }
  767. msgpack::object* get_item() {
  768. return as.obj;
  769. }
  770. msgpack::object* get_key() {
  771. return &as.kv->key;
  772. }
  773. msgpack::object* get_val() {
  774. return &as.kv->val;
  775. }
  776. union {
  777. msgpack::object* obj;
  778. msgpack::object_kv* kv;
  779. } as;
  780. bool is_obj;
  781. };
  782. std::vector<elem> m_objs;
  783. msgpack::zone& m_zone;
  784. msgpack::object* m_ptr;
  785. };
  786. };
  787. // Adaptor functor specialization to object::with_zone
  788. template <>
  789. struct object_with_zone<msgpack::object::with_zone> {
  790. void operator()(
  791. msgpack::object::with_zone& o,
  792. msgpack::object::with_zone const& v) const {
  793. o << static_cast<msgpack::object const&>(v);
  794. }
  795. };
  796. } // namespace adaptor
  797. // obsolete
  798. template <typename Type>
  799. class define : public Type {
  800. public:
  801. typedef Type msgpack_type;
  802. typedef define<Type> define_type;
  803. define() {}
  804. define(const msgpack_type& v) : msgpack_type(v) {}
  805. template <typename Packer>
  806. void msgpack_pack(Packer& o) const
  807. {
  808. msgpack::operator<<(o, static_cast<const msgpack_type&>(*this));
  809. }
  810. void msgpack_unpack(object const& o)
  811. {
  812. msgpack::operator>>(o, static_cast<msgpack_type&>(*this));
  813. }
  814. };
  815. // deconvert operator
  816. template <typename Stream>
  817. template <typename T>
  818. inline msgpack::packer<Stream>& packer<Stream>::pack(const T& v)
  819. {
  820. msgpack::operator<<(*this, v);
  821. return *this;
  822. }
  823. struct object_equal_visitor {
  824. object_equal_visitor(msgpack::object const& obj, bool& result)
  825. :m_ptr(&obj), m_result(result) {}
  826. bool visit_nil() {
  827. if (m_ptr->type != msgpack::type::NIL) {
  828. m_result = false;
  829. return false;
  830. }
  831. return true;
  832. }
  833. bool visit_boolean(bool v) {
  834. if (m_ptr->type != msgpack::type::BOOLEAN || m_ptr->via.boolean != v) {
  835. m_result = false;
  836. return false;
  837. }
  838. return true;
  839. }
  840. bool visit_positive_integer(uint64_t v) {
  841. if (m_ptr->type != msgpack::type::POSITIVE_INTEGER || m_ptr->via.u64 != v) {
  842. m_result = false;
  843. return false;
  844. }
  845. return true;
  846. }
  847. bool visit_negative_integer(int64_t v) {
  848. if (m_ptr->type != msgpack::type::NEGATIVE_INTEGER || m_ptr->via.i64 != v) {
  849. m_result = false;
  850. return false;
  851. }
  852. return true;
  853. }
  854. bool visit_float32(float v) {
  855. if (m_ptr->type != msgpack::type::FLOAT32 || m_ptr->via.f64 != v) {
  856. m_result = false;
  857. return false;
  858. }
  859. return true;
  860. }
  861. bool visit_float64(double v) {
  862. if (m_ptr->type != msgpack::type::FLOAT64 || m_ptr->via.f64 != v) {
  863. m_result = false;
  864. return false;
  865. }
  866. return true;
  867. }
  868. bool visit_str(const char* v, uint32_t size) {
  869. if (m_ptr->type != msgpack::type::STR ||
  870. m_ptr->via.str.size != size ||
  871. std::memcmp(m_ptr->via.str.ptr, v, size) != 0) {
  872. m_result = false;
  873. return false;
  874. }
  875. return true;
  876. }
  877. bool visit_bin(const char* v, uint32_t size) {
  878. if (m_ptr->type != msgpack::type::BIN ||
  879. m_ptr->via.bin.size != size ||
  880. std::memcmp(m_ptr->via.bin.ptr, v, size) != 0) {
  881. m_result = false;
  882. return false;
  883. }
  884. return true;
  885. }
  886. bool visit_ext(const char* v, uint32_t size) {
  887. if (m_ptr->type != msgpack::type::EXT ||
  888. m_ptr->via.ext.size != size - 1 ||
  889. std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) {
  890. m_result = false;
  891. return false;
  892. }
  893. return true;
  894. }
  895. bool start_array(uint32_t num_elements) {
  896. if (m_ptr->type != msgpack::type::ARRAY ||
  897. m_ptr->via.array.size != num_elements) {
  898. m_result = false;
  899. return false;
  900. }
  901. m_objs.push_back(elem(m_ptr->via.array.ptr));
  902. return true;
  903. }
  904. bool start_array_item() {
  905. m_ptr = m_objs.back().get_item();
  906. return true;
  907. }
  908. bool end_array_item() {
  909. ++m_objs.back().as.obj;
  910. return true;
  911. }
  912. bool end_array() {
  913. m_objs.pop_back();
  914. return true;
  915. }
  916. bool start_map(uint32_t num_kv_pairs) {
  917. if (m_ptr->type != msgpack::type::MAP ||
  918. m_ptr->via.array.size != num_kv_pairs) {
  919. m_result = false;
  920. return false;
  921. }
  922. m_objs.push_back(elem(m_ptr->via.map.ptr));
  923. return true;
  924. }
  925. bool start_map_key() {
  926. m_ptr = m_objs.back().get_key();
  927. return true;
  928. }
  929. bool end_map_key() {
  930. return true;
  931. }
  932. bool start_map_value() {
  933. m_ptr = m_objs.back().get_val();
  934. return true;
  935. }
  936. bool end_map_value() {
  937. ++m_objs.back().as.kv;
  938. return true;
  939. }
  940. bool end_map() {
  941. m_objs.pop_back();
  942. return true;
  943. }
  944. private:
  945. struct elem {
  946. elem(msgpack::object const* obj)
  947. :is_obj(true) {
  948. as.obj = obj;
  949. }
  950. elem(msgpack::object_kv const* kv)
  951. :is_obj(false) {
  952. as.kv = kv;
  953. }
  954. msgpack::object const* get_item() {
  955. return as.obj;
  956. }
  957. msgpack::object const* get_key() {
  958. return &as.kv->key;
  959. }
  960. msgpack::object const* get_val() {
  961. return &as.kv->val;
  962. }
  963. union {
  964. msgpack::object const* obj;
  965. msgpack::object_kv const* kv;
  966. } as;
  967. bool is_obj;
  968. };
  969. std::vector<elem> m_objs;
  970. msgpack::object const* m_ptr;
  971. bool& m_result;
  972. };
  973. inline bool operator==(const msgpack::object& x, const msgpack::object& y)
  974. {
  975. if(x.type != y.type) { return false; }
  976. bool b = true;
  977. object_equal_visitor vis(y, b);
  978. msgpack::object_parser(x).parse(vis);
  979. return b;
  980. }
  981. template <typename T>
  982. inline bool operator==(const msgpack::object& x, const T& y)
  983. try {
  984. return x == msgpack::object(y);
  985. } catch (msgpack::type_error&) {
  986. return false;
  987. }
  988. inline bool operator!=(const msgpack::object& x, const msgpack::object& y)
  989. { return !(x == y); }
  990. template <typename T>
  991. inline bool operator==(const T& y, const msgpack::object& x)
  992. { return x == y; }
  993. template <typename T>
  994. inline bool operator!=(const msgpack::object& x, const T& y)
  995. { return !(x == y); }
  996. template <typename T>
  997. inline bool operator!=(const T& y, const msgpack::object& x)
  998. { return x != y; }
  999. inline object::implicit_type object::convert() const
  1000. {
  1001. return object::implicit_type(*this);
  1002. }
  1003. template <typename T>
  1004. inline
  1005. typename msgpack::enable_if<
  1006. !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value,
  1007. T&
  1008. >::type
  1009. object::convert(T& v) const
  1010. {
  1011. msgpack::operator>>(*this, v);
  1012. return v;
  1013. }
  1014. template <typename T, std::size_t N>
  1015. inline T(&object::convert(T(&v)[N]) const)[N]
  1016. {
  1017. msgpack::operator>>(*this, v);
  1018. return v;
  1019. }
  1020. #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
  1021. template <typename T>
  1022. inline
  1023. typename msgpack::enable_if<
  1024. msgpack::is_pointer<T>::value,
  1025. T
  1026. >::type
  1027. object::convert(T v) const
  1028. {
  1029. convert(*v);
  1030. return v;
  1031. }
  1032. #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT)
  1033. template <typename T>
  1034. inline bool object::convert_if_not_nil(T& v) const
  1035. {
  1036. if (is_nil()) {
  1037. return false;
  1038. }
  1039. convert(v);
  1040. return true;
  1041. }
  1042. #if defined(MSGPACK_USE_CPP03)
  1043. template <typename T>
  1044. inline T object::as() const
  1045. {
  1046. T v;
  1047. convert(v);
  1048. return v;
  1049. }
  1050. #else // defined(MSGPACK_USE_CPP03)
  1051. template <typename T>
  1052. inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const {
  1053. return msgpack::adaptor::as<T>()(*this);
  1054. }
  1055. template <typename T>
  1056. inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const {
  1057. T v;
  1058. convert(v);
  1059. return v;
  1060. }
  1061. #endif // defined(MSGPACK_USE_CPP03)
  1062. inline object::object()
  1063. {
  1064. type = msgpack::type::NIL;
  1065. }
  1066. template <typename T>
  1067. inline object::object(const T& v)
  1068. {
  1069. *this << v;
  1070. }
  1071. template <typename T>
  1072. inline object& object::operator=(const T& v)
  1073. {
  1074. *this = object(v);
  1075. return *this;
  1076. }
  1077. template <typename T>
  1078. inline object::object(const T& v, msgpack::zone& z)
  1079. {
  1080. with_zone oz(z);
  1081. msgpack::operator<<(oz, v);
  1082. type = oz.type;
  1083. via = oz.via;
  1084. }
  1085. template <typename T>
  1086. inline object::object(const T& v, msgpack::zone* z)
  1087. {
  1088. with_zone oz(*z);
  1089. msgpack::operator<<(oz, v);
  1090. type = oz.type;
  1091. via = oz.via;
  1092. }
  1093. // obsolete
  1094. template <typename T>
  1095. inline void convert(T& v, msgpack::object const& o)
  1096. {
  1097. o.convert(v);
  1098. }
  1099. // obsolete
  1100. template <typename Stream, typename T>
  1101. inline void pack(msgpack::packer<Stream>& o, const T& v)
  1102. {
  1103. o.pack(v);
  1104. }
  1105. // obsolete
  1106. template <typename Stream, typename T>
  1107. inline void pack_copy(msgpack::packer<Stream>& o, T v)
  1108. {
  1109. pack(o, v);
  1110. }
  1111. template <typename Stream>
  1112. inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object& v)
  1113. {
  1114. object_pack_visitor<Stream> vis(o);
  1115. msgpack::object_parser(v).parse(vis);
  1116. return o;
  1117. }
  1118. template <typename Stream>
  1119. inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object::with_zone& v)
  1120. {
  1121. return o << static_cast<msgpack::object>(v);
  1122. }
  1123. inline std::ostream& operator<< (std::ostream& s, const msgpack::object& v)
  1124. {
  1125. object_stringize_visitor vis(s);
  1126. msgpack::object_parser(v).parse(vis);
  1127. return s;
  1128. }
  1129. /// @cond
  1130. } // MSGPACK_API_VERSION_NAMESPACE(v1)
  1131. /// @endcond
  1132. } // namespace msgpack
  1133. #endif // MSGPACK_V1_OBJECT_HPP