msgpack C++ implementation: How to pack binary data?

mdb841 picture mdb841 · Jul 27, 2012 · Viewed 12.2k times · Source

I am making use of C++ msgpack implementation. I have hit a roadblock as to how to pack binary data. In terms of binary data I have a buffer of the following type:

unsigned char* data;

The data variable points to an array which is actually an image. What I want to do is pack this using msgpack. There seems to be no example of how to actually pack binary data. From the format specification raw bytes are supported, but I am not sure how to make use of the functionality.

I tried using a vector of character pointers like the following:

msgpack::sbuffer temp_sbuffer;
std::vector<char*> vec;
msgpack::pack(temp_sbuffer, vec);

But this results in a compiler error since there is no function template for T=std::vector.

I have also simply tried the following:

msgpack::pack(temp_sbuffer, "Hello");

But this also results in a compilation error (i.e. no function template for T=const char [6]

Thus, I was hoping someone could give me advice on how to use msgpack C++ to pack binary data represented as a char array.

Answer

mdb841 picture mdb841 · Jul 30, 2012

Josh provided a good answer but it requires the copying of byte buffers to a vector of char. I would rather minimize copying and use the buffer directly (if possible). The following is an alternative solution:

Looking through the source code and trying to determine how different data types are packed according to the specification I happened upon msgpack::packer<>::pack_raw(size_t l) and msgpack::packer<>::pack_raw_body(const char* b, size_t l). While there appears to be no documentation for these methods this is how I would described them.

  1. msgpack::packer<>::pack_raw(size_t l): This method appends the type identification to buffer (i.e. fix raw, raw16 or raw32) as well as the size information (which is an argument for the method).
  2. msgpack::packer<>::pack_raw_body(const char* b, size_t l): This method appends the raw data to the buffer.

The following is a simple example of how to pack a character array:

msgpack::sbuffer temp_sbuffer;
msgpack::packer<msgpack::sbuffer> packer(&temp_sbuffer);
packer.pack_raw(5);  // Indicate that you are packing 5 raw bytes
packer.pack_raw_body("Hello", 5); // Pack the 5 bytes

The above example can be extended to pack any binary data. This allows one to pack directly from byte arrays/buffers without having to copy to an intermediate (i.e. a vector of char).