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 10#include <string> 11#include <iostream> 12#include <iomanip> 13#include <sstream> 14#include <cassert> 15 16#include <msgpack.hpp> 17 18class my_class { 19public: 20 my_class() {} // When you want to convert from msgpack::object to my_class, 21 // my_class should be default constractible. 22 my_class(std::string const& name, int age):name_(name), age_(age) {} 23 24 // my_class should provide getters for the data members you want to pack. 25 std::string const& get_name() const { return name_; } 26 int get_age() const { return age_; } 27 28 friend bool operator==(my_class const& lhs, my_class const& rhs) { 29 return lhs.name_ == rhs.name_ && lhs.age_ == rhs.age_; 30 } 31 32private: 33 std::string name_; 34 int age_; 35}; 36 37// User defined class template specialization 38namespace msgpack { 39MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { 40namespace adaptor { 41 42template<> 43struct convert<my_class> { 44 msgpack::object const& operator()(msgpack::object const& o, my_class& v) const { 45 if (o.type != msgpack::type::ARRAY) throw msgpack::type_error(); 46 if (o.via.array.size != 2) throw msgpack::type_error(); 47 v = my_class( 48 o.via.array.ptr[0].as<std::string>(), 49 o.via.array.ptr[1].as<int>()); 50 return o; 51 } 52}; 53 54template<> 55struct pack<my_class> { 56 template <typename Stream> 57 packer<Stream>& operator()(msgpack::packer<Stream>& o, my_class const& v) const { 58 // packing member variables as an array. 59 o.pack_array(2); 60 o.pack(v.get_name()); 61 o.pack(v.get_age()); 62 return o; 63 } 64}; 65 66template <> 67struct object_with_zone<my_class> { 68 void operator()(msgpack::object::with_zone& o, my_class const& v) const { 69 o.type = type::ARRAY; 70 o.via.array.size = 2; 71 o.via.array.ptr = static_cast<msgpack::object*>( 72 o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size)); 73 o.via.array.ptr[0] = msgpack::object(v.get_name(), o.zone); 74 o.via.array.ptr[1] = msgpack::object(v.get_age(), o.zone); 75 } 76}; 77 78} // namespace adaptor 79} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) 80} // namespace msgpack 81 82 83void print(std::string const& buf) { 84 for (std::string::const_iterator it = buf.begin(), end = buf.end(); 85 it != end; 86 ++it) { 87 std::cout 88 << std::setw(2) 89 << std::hex 90 << std::setfill('0') 91 << (static_cast<int>(*it) & 0xff) 92 << ' '; 93 } 94 std::cout << std::dec << std::endl; 95} 96 97int main() { 98 { // pack, unpack 99 my_class my("John Smith", 42); 100 std::stringstream ss; 101 msgpack::pack(ss, my); 102 103 print(ss.str()); 104 105 msgpack::unpacked unp; 106 msgpack::unpack(unp, ss.str().data(), ss.str().size()); 107 msgpack::object obj = unp.get(); 108 std::cout << obj << std::endl; 109 assert(obj.as<my_class>() == my); 110 } 111 { // create object with zone 112 my_class my("John Smith", 42); 113 msgpack::zone z; 114 msgpack::object obj(my, z); 115 std::cout << obj << std::endl; 116 assert(obj.as<my_class>() == my); 117 } 118} 119