msgpack/example/boost/msgpack_variant_mapbased.cpp
Takatoshi Kondo ba15089d86 Version 1.3.0.
Updated the license from the license from the Apache License Version 2.0
to the Boost Software License, Version 1.0.
Removed unused files.
2015-11-21 12:41:46 +09:00

93 lines
3.3 KiB
C++

// MessagePack for C++ example
//
// Copyright (C) 2015 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <string>
#include <sstream>
#include <iostream>
#include <msgpack.hpp>
struct user {
std::string name;
int age;
std::string address;
MSGPACK_DEFINE_MAP(name, age, address);
};
struct proc:boost::static_visitor<void> {
// msgpack::type::MAP is converted to std::multimap, not std::map.
void operator()(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>& v) const {
std::cout << "match map" << std::endl;
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator it = v.begin();
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator end = v.end();
while(it != end) {
boost::string_ref const& key = it->first.as_boost_string_ref();
if (key == "name") {
boost::string_ref const& value = it->second.as_boost_string_ref();
if (value == "Takatoshi Kondo") {
// You can add values to msgpack::type::variant_ref.
v.insert(
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::value_type(
"role",
"msgpack-c committer"
)
);
}
++it;
}
else if (key == "age") {
// You can remove key-value pair from msgpack::type::variant_ref
#if defined(MSGPACK_USE_CPP03)
v.erase(it++);
#else // defined(MSGPACK_USE_CPP03)
# if MSGPACK_LIB_STD_CXX
it = v.erase(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::const_iterator(it));
# else // MSGPACK_LIB_STD_CXX
it = v.erase(it);
# endif // MSGPACK_LIB_STD_CXX
#endif // defined(MSGPACK_USE_CPP03)
}
else if (key == "address") {
// When you want to append string
// "Tokyo" -> "Tokyo, JAPAN"
// Use msgpack::type::variant instead of msgpack::type::variant_ref
// or do as follows:
boost::string_ref const& value = it->second.as_boost_string_ref();
it->second = std::string(&value.front(), value.size()) + ", JAPAN";
++it;
}
}
}
template <typename T>
void operator()(T const&) const {
std::cout << " match others" << std::endl;
}
};
int main() {
std::stringstream ss;
user u;
u.name = "Takatoshi Kondo";
u.age = 42;
u.address = "Tokyo";
msgpack::pack(ss, u);
msgpack::unpacked unp = msgpack::unpack(ss.str().data(), ss.str().size());
msgpack::object const& obj = unp.get();
std::cout << "Unpacked msgpack object." << std::endl;
std::cout << obj << std::endl;
msgpack::type::variant_ref v = obj.as<msgpack::type::variant_ref>();
std::cout << "Applying proc..." << std::endl;
boost::apply_visitor(proc(), v);
msgpack::zone z;
std::cout << "Applied msgpack object." << std::endl;
std::cout << msgpack::object(v, z) << std::endl;
}