-
Notifications
You must be signed in to change notification settings - Fork 881
v1_1_cpp_adaptor
When you want to pack to msgpack::object from a various type object, you need an adaptor. Converting to msgpack::object from a various type object and vice versa, it requires an adaptor too.
See conversion.
msgpack-c provides predefined adaptors for C++ primitive types and standard libraries.
C++ type | msgpack::object type |
---|---|
bool | bool |
char* | str |
std::deque | array |
char | positive/negative integer |
signed ints *1 | positive/negative integer |
unsigned ints *2 | positive integer |
std::list | array |
std::map | array |
std::pair | array |
std::set | array |
std::string | str |
std::vector | array |
std::vector<char> | bin |
C++11 type | msgpack::object type |
---|---|
std::array | array |
std::array<char> | bin |
std::forward_list | array |
std::tuple | array |
std::array | array |
std::unordered_map | array |
std::unordered_set | array |
*1 signed ints signed char, signed short, signed int, signed long, signed long long
*2 unsigned ints unsigned char, unsigned short, unsigned int, signed long, signed long long
msgpack::object type is defined as follows: https://github.com/msgpack/msgpack/blob/master/spec.md
These adaptors are defined in the following directory: https://github.com/msgpack/msgpack-c/tree/master/include/msgpack/adaptor
When you want to adapt your class to msgpack, use MSGPACK_DEFINE macro.
#include <msgpack.hpp>
struct your_class {
int a;
std::string b;
MSGPACK_DEFINE(a, b);
};
// ...
The macro MSGPACK_DEFINE provides packing, converting to msgpack object with zone, and converting to your_class from msgpack::object functionalities. your_class is packed/converted as msgpack array.
https://github.com/msgpack/msgpack-c/blob/master/example/cpp03/class_intrusive.cpp
When you don't want to modify your class, you can use non-intrusive approach. msgpack-c provides the following four functor class template.
class template name | operator() signature |
---|---|
convert | msgpack::object const& operator()(msgpack::object const&, T&) const |
pack | template msgpack::packer& operator()(msgpack::packer&, T const&) const |
object | void operator()(msgpack::object&, T const&) const |
object_with_zone | void operator()(msgpack::object::with_zone&, T const&) const |
- convert
- Converting from msgpack::object to T.
- pack
- Packing from T into msgpack::packer.
- object
- Set msgpack::object by T.
- object_with_zone
- Set msgpack::object::with_zone by T.
#include <msgpack.hpp>
struct your_class {
int a;
std::string b;
};
namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {
// Place class template specialization here
template<>
struct convert<my_class> {
msgpack::object const& operator()(msgpack::object const& o, my_class& v) const {
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
if (o.via.array.size != 2) throw msgpack::type_error();
v = my_class(
o.via.array.ptr[0].as<std::string>(),
o.via.array.ptr[1].as<int>());
return o;
}
};
template<>
struct pack<my_class> {
template <typename Stream>
packer<Stream>& operator()(msgpack::packer<Stream>& o, my_class const& v) const {
// packing member variables as an array.
o.pack_array(2);
o.pack(v.get_name());
o.pack(v.get_age());
return o;
}
};
template <>
struct object_with_zone<my_class> {
void operator()(msgpack::object::with_zone& o, my_class const& v) const {
o.type = type::ARRAY;
o.via.array.size = 2;
o.via.array.ptr = static_cast<msgpack::object*>(
o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size));
o.via.array.ptr[0] = msgpack::object(v.get_name(), o.zone);
o.via.array.ptr[1] = msgpack::object(v.get_age(), o.zone);
}
};
} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack
https://github.com/msgpack/msgpack-c/blob/master/example/cpp03/class_non_intrusive.cpp
When you want to adapt enum or enum class to msgpack, use MSGPACK_ADD_ENUM macro.
#include <msgpack.hpp>
enum your_enum {
elem1,
elem2
};
MSGPACK_ADD_ENUM(your_enum);
enum class your_enum_class {
elem1,
elem2
};
MSGPACK_ADD_ENUM(your_enum_class);
// ...
You need to use MSGPACK_ADD_ENUM in the global namespace.
The macro MSGPACK_DEFINE provides packing, converting to msgpack object with or without zone, and converting to your_enum from msgpack::object functionalities. your_enum is packed/converted as msgpack positive/negative integer.
See an example.
-
Home
- Q&A
- v2.0.x or later
- v1.1.x - v1.4.x
- v1.0.x