Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to only pack or unpack certain fields? #1019

Open
dlandtaa opened this issue May 17, 2022 · 2 comments
Open

Is it possible to only pack or unpack certain fields? #1019

dlandtaa opened this issue May 17, 2022 · 2 comments

Comments

@dlandtaa
Copy link

Is there anyway to control which fields are packed or unpacked on a call by call basis?

Can I do something like this?

struct C
{
    int a;
    int b;
    int c;
    MSGPACK_DEFINE_MAP(a, b, c);
};

C c1;
c1.a = 1;
c1.b = 2;
c1.c = 3;

msgpack::sbuffer buff;
msgpack::packer<msgpack::sbuffer> packer(buff);

// only pack fields a and b
std::string fields1[] = { "a", "b" };
packer.pack(c1, fields1);

// only unpack field a
std::string fields2[] = { "a" };
msgpack::object_handle handle = msgpack::unpack(buff.data(), buff.size(), fields2);
msgpack::object obj = handle.get();
C c2;
obj.convert(c2);
@redboltz
Copy link
Contributor

redboltz commented May 17, 2022

https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion
msgpack-c has 3 concepts. They are pack/unpack/convert. (Creating object from T is not related in this context)

Can I do something like this?

pack

You can pack the only specific member variables but you need to call pack APIs directly.

See
https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_packer#pack-manually

unpack

You can't unpack only specific element using msgpack::unpack() function.
You need to unpack all elements.

If you really want to only specific element from MessagePack formatted byte stream, then you can use visitor APIs.
https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_visitor
It is like SAX api.

convert

If msgpack::object contains MAP like {"a":1,"b":2}, then you can get only "a":1 using direct access.
But no key serach are provided.
So first, convert to std::map<std::string, int> m and then get m["a"] is easy way.

@sigasigasiga
Copy link

Here's the way to somehow ignore certain fields:

struct C
{
    int a;
    int b;
    int c;
    MSGPACK_DEFINE_MAP(a, b, c);
};
msgpack::sbuffer buff;
msgpack::packer<msgpack::sbuffer> packer(buff);

struct C_fieldless
{
    int a;
    msgpack::object b, c; // the fields that are ignored
    MSGPACK_DEFINE_MAP(a, b, c);
};
msgpack::object_handle handle;
msgpack::unpack(handle, buff.data(), buff.size());
auto fieldless = handle.as<C_fieldsless>();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants