0

For my C++ project I use c++ msgpack library available in Ubuntu (14.04) standard repository under name libmsgpack-dev.

All works fine except when I try to pack some bools. There things go absolutely bananas. First I wrote simple test to study pack method. It turned out, that it can not be trusted for packing bools. Here is simple test showing the problem:

#include <msgpack.hpp>
TEST_CASE("bool packing", "[msgpack1]") {
    msgpack::sbuffer buf;
    msgpack::packer<msgpack::sbuffer> p(&buf);
    std::string key = "BoolValue";
    bool value      = true;

    p.pack_map(1);
    {
        p.pack(key);
        p.pack(value);
    }

    msgpack::unpacked msg;
    msgpack::unpack(&msg, buf.data(), buf.size());    

    std::map<std::string, msgpack::object> m;
    msg.get().convert(&m);

    bool loaded_value;
    m.at(key).convert(&loaded_value);

    INFO("We packed:  " << value);
    INFO("We loaded:  " << loaded_value);

    REQUIRE(value == loaded_value);
}

with result:

unit_tests/unit_msgpack.cpp:30: FAILED:
  REQUIRE( value == loaded_value )
with expansion:
  true == false
with messages:
  We packed:  1
  We loaded:  0

I thought OK, is there a way around? Yes, I discovered methods pack_true and pack_false. Right, so for packing bools I just need to call these two functions explicitly and it will work just fine. But no. For this test:

TEST_CASE("bool packing two elements", "[msgpack2]") {
    msgpack::sbuffer buf;
    msgpack::packer<msgpack::sbuffer> p(&buf);
    std::string key1 = "BoolValue1";
    std::string key2 = "BoolValue2";
    bool value1      = false;
    bool value2      = true;

    p.pack_map(2);
    {
        p.pack(key1);
        if (value1) {
            p.pack_true();
        } else {
            p.pack_false();
        }

        p.pack(key2);
        if (value2) {
            p.pack_true();
        } else {
            p.pack_false();
        }
    }

    msgpack::unpacked msg;
    msgpack::unpack(&msg, buf.data(), buf.size());

    std::map<std::string, msgpack::object> m;
    msg.get().convert(&m);

    bool loaded_value1;
    bool loaded_value2;
    m.at(key1).convert(&loaded_value1);
    m.at(key2).convert(&loaded_value2);

    INFO("We packed:  " << value1        << " : " << value2);
    INFO("We loaded:  " << loaded_value1 << " : " << loaded_value2);

    REQUIRE((value1 == loaded_value1 && value2 == loaded_value2));
}

I got following result:

unit_tests/unit_msgpack.cpp:72: FAILED:
  REQUIRE( (value1 == loaded_value1 && value2 == loaded_value2) )
with expansion:
  false
with messages:
  We packed:  0 : 1
  We loaded:  0 : 0

Can someone please help me out of this? Is there a bug in the library or am I doing anything wrong?

Jendas
  • 3,359
  • 3
  • 27
  • 55

1 Answers1

0

I don't really know what the problem was but I solved it by removing packages libmsgpackc2 and libmsgpack3 and installing msgpack from git repository. It is well described. The code than has to be compiled with -I msgpack-c/include flag.

I guess that the msgpack package in Ubuntu repository is very old and deprecated.

Jendas
  • 3,359
  • 3
  • 27
  • 55