class_non_intrusive.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // MessagePack for C++ example
  2. //
  3. // Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. #include <string>
  10. #include <iostream>
  11. #include <iomanip>
  12. #include <sstream>
  13. #include <cassert>
  14. #include <msgpack.hpp>
  15. class my_class {
  16. public:
  17. my_class() {} // When you want to convert from msgpack::object to my_class,
  18. // my_class should be default constractible.
  19. my_class(std::string const& name, int age):name_(name), age_(age) {}
  20. // my_class should provide getters for the data members you want to pack.
  21. std::string const& get_name() const { return name_; }
  22. int get_age() const { return age_; }
  23. friend bool operator==(my_class const& lhs, my_class const& rhs) {
  24. return lhs.name_ == rhs.name_ && lhs.age_ == rhs.age_;
  25. }
  26. private:
  27. std::string name_;
  28. int age_;
  29. };
  30. // User defined class template specialization
  31. namespace msgpack {
  32. MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
  33. namespace adaptor {
  34. template<>
  35. struct convert<my_class> {
  36. msgpack::object const& operator()(msgpack::object const& o, my_class& v) const {
  37. if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
  38. if (o.via.array.size != 2) throw msgpack::type_error();
  39. v = my_class(
  40. o.via.array.ptr[0].as<std::string>(),
  41. o.via.array.ptr[1].as<int>());
  42. return o;
  43. }
  44. };
  45. template<>
  46. struct pack<my_class> {
  47. template <typename Stream>
  48. packer<Stream>& operator()(msgpack::packer<Stream>& o, my_class const& v) const {
  49. // packing member variables as an array.
  50. o.pack_array(2);
  51. o.pack(v.get_name());
  52. o.pack(v.get_age());
  53. return o;
  54. }
  55. };
  56. template <>
  57. struct object_with_zone<my_class> {
  58. void operator()(msgpack::object::with_zone& o, my_class const& v) const {
  59. o.type = type::ARRAY;
  60. o.via.array.size = 2;
  61. o.via.array.ptr = static_cast<msgpack::object*>(
  62. o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
  63. o.via.array.ptr[0] = msgpack::object(v.get_name(), o.zone);
  64. o.via.array.ptr[1] = msgpack::object(v.get_age(), o.zone);
  65. }
  66. };
  67. } // namespace adaptor
  68. } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
  69. } // namespace msgpack
  70. void print(std::string const& buf) {
  71. for (std::string::const_iterator it = buf.begin(), end = buf.end();
  72. it != end;
  73. ++it) {
  74. std::cout
  75. << std::setw(2)
  76. << std::hex
  77. << std::setfill('0')
  78. << (static_cast<int>(*it) & 0xff)
  79. << ' ';
  80. }
  81. std::cout << std::dec << std::endl;
  82. }
  83. int main() {
  84. { // pack, unpack
  85. my_class my("John Smith", 42);
  86. std::stringstream ss;
  87. msgpack::pack(ss, my);
  88. print(ss.str());
  89. msgpack::object_handle oh =
  90. msgpack::unpack(ss.str().data(), ss.str().size());
  91. msgpack::object obj = oh.get();
  92. std::cout << obj << std::endl;
  93. assert(obj.as<my_class>() == my);
  94. }
  95. { // create object with zone
  96. my_class my("John Smith", 42);
  97. msgpack::zone z;
  98. msgpack::object obj(my, z);
  99. std::cout << obj << std::endl;
  100. assert(obj.as<my_class>() == my);
  101. }
  102. }