1// MessagePack for C++ example
2//
3// Copyright (C) 2015 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
18struct base1 {
19    base1():a("default") {}
20    std::string a;
21    MSGPACK_DEFINE_MAP(a);
22};
23
24struct v1 : base1 {
25    v1():name("default"), age(0) {}
26    std::string name;
27    int age;
28    MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(base1), name, age);
29};
30
31struct base2 {
32    base2():a("default") {}
33    std::string a;
34    MSGPACK_DEFINE_MAP(a);
35};
36
37// Removed: base1, name
38// Added  : base2, address
39struct v2 : base2 {
40    v2(): age(0), address("default") {}
41    int age;
42    std::string address;
43    MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(base2), age, address);
44};
45
46// The member variable "age" is in common between v1 and v2.
47
48void print(std::string const& buf) {
49    for (std::string::const_iterator it = buf.begin(), end = buf.end();
50         it != end;
51         ++it) {
52        std::cout
53            << std::setw(2)
54            << std::hex
55            << std::setfill('0')
56            << (static_cast<int>(*it) & 0xff)
57            << ' ';
58    }
59    std::cout << std::dec << std::endl;
60}
61
62int main() {
63    { // pack v1, unpack, convert to v2
64        v1 v;
65        v.a = "ABC";
66        v.name = "John Smith";
67        v.age = 35;
68
69        std::stringstream ss;
70        msgpack::pack(ss, v);
71
72        print(ss.str());
73
74        msgpack::unpacked unp = msgpack::unpack(ss.str().data(), ss.str().size());
75
76        msgpack::object obj = unp.get();
77        std::cout << obj << std::endl;
78
79        v2 newv = obj.as<v2>();
80
81        std::cout << "v2::a       " << newv.a << std::endl;
82        std::cout << "v2::age     " << newv.age << std::endl;
83        std::cout << "v2::address " << newv.address << std::endl;
84
85        // "age" is set from v1
86        assert(newv.a == "default");
87        assert(newv.age == 35);
88        assert(newv.address == "default");
89    }
90    { // create v2 object with zone, convert to v1
91        v2 v;
92        v.a = "DEF";
93        v.age = 42;
94        v.address = "Tokyo";
95
96        msgpack::zone z;
97        msgpack::object obj(v, z);
98        std::cout << obj << std::endl;
99
100        v1 newv = obj.as<v1>();
101
102        std::cout << "v1::a       " << newv.a << std::endl;
103        std::cout << "v1::name    " << newv.name << std::endl;
104        std::cout << "v1::age     " << newv.age << std::endl;
105
106        // "age" is set from v2
107        assert(newv.a == "default");
108        assert(newv.name == "default");
109        assert(newv.age == 42);
110    }
111}
112