0

When writing a custom serializer for msgpack_c one also needs to implement object_with_zone.

The documentation how to implement this is very sparse ( https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor ).

In what circumstances is this method called?

Doctor Pickle
  • 63
  • 1
  • 8
JE42
  • 4,881
  • 6
  • 41
  • 51

1 Answers1

1

You can create a msgpack::object from C++ types. See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion

When you call msgpack::object constructor with zone like msgpack::object(mc, z);, object_with_zone<T>::operator() is called internally.

If you don't want to create msgpack::object from C++ types, you don't need to define object_with_zone specialization. Packing, unpacking, and converting to C++ types from msgpack::object don't require it.

Here is an example:

#include <iostream>
#include <msgpack.hpp>

class my_class {
public:
    my_class(std::string const& name, int age):name_(name), age_(age) {}

    std::string const& get_name() const { return name_; }
    int get_age() const { return age_; }

private:
    std::string name_;
    int age_;
};

// User defined class template specialization
namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {

template <>
struct object_with_zone<my_class> {
    void operator()(msgpack::object::with_zone& o, my_class const& v) const {
        std::cout << "object_with_zone<my_class> is called" << std::endl;
        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, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
        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

int main() {
    my_class mc("John", 42);
    msgpack::zone z;
    auto obj = msgpack::object(mc, z);
    std::cout << obj << std::endl;
}

Output:

object_with_zone<my_class> is called
["John", 42]

Running demo: https://wandbox.org/permlink/dNmZX1FpUL3w8D5m

updated

Additional question. Why would i want to use the zone ?

Answer:

A zone is used internally when you unpack MessagePack formatted byte stream. You get msgpack::object_handle. msgpack::object_handle has a zone and a msgpack::object. See https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#what-is-msgpackobject.

The reason of using msgpack::zone is for performance. If msgpack::object is STR, BIN, or EXT, the msgpack::object need to allocate a memory dynamically. The msgpack::object can have a handle of the memory by itself but it is inefficient. The destructor of msgpack::object need to deallocate memory, if the msgpack::object allocate memory. msgpack::object is a composite data structure. That means the destructor cannot be inlined.

One of the goal of msgpack-c is efficient unpacking. So msgpack-c uses msgpack::zone.

It is unpacking story. msgpack::zone is also used when msgpack::object is created from C++ types. I'm not sure when users want to do, is is up to users.

Takatoshi Kondo
  • 3,111
  • 17
  • 36
  • OK. clear now which call triggers this function! Why would i want to use the zone ? The zone docs: http://c.msgpack.org/cpp/classmsgpack_1_1zone.html are empty :( – JE42 Jul 29 '17 at 08:47