简体   繁体   中英

How to deserialize a std::string to a concrete message in Cap'n Proto C++?

I need to decode a message from a std::string object.

I can see how to do this in Java by using a ByteBuffer , but I failed to find a simple C++ equivalent.

More precisely, how to implement this?

const std::string serialized_data = ...; // Source
SomeDataType data = ???; // How to convert from serialized_data to data?

You can write code like this:

std::string serialized_data = ...;
kj::ArrayPtr<const capnp::word> words(
    reinterpret_cast<const capnp::word*>(serialized_data.begin()),
    serialized_data.size() / sizeof(capnp::word));
capnp::FlatAraryMessageReader reader(words);

Note that this assumes that the backing buffer of an std::string is always word-aligned. I think this is true, but I am not sure. If it is not aligned, you will get exceptions saying so. In this case it may be necessary to copy the data into an aligned buffer:

auto words = kj::heapArray<capnp::word>(
    serialized_data.size() / sizeof(capnp::word));
memcpy(words.begin(), serialized_data.begin(), words.asBytes().size());
capnp::FlatAraryMessageReader reader(words);

Note that while std::string is technically able to store arbitrary bytes, it is not a particularly good data structure for this purpose, since it is optimized for text. For example, it may re-allocate and copy your buffer in order to add a NUL terminator to support .c_str() . I would recommend using a more data-oriented type for byte arrays.

My own answer is very similar to Kenton's:

std::string serialized_data = ...;
kj::ArrayPtr<const kj::byte> arr(
  reinterpret_cast<const kj::byte*>(serialized_data.data()),
  serialized_data.size());
kj::ArrayInputStream stream(arr);
capnp::InputStreamMessageReader reader(stream);
auto data = reader.getRoot<SomeDataType>();

This is isomorphic to the Java version, and it has no alignment requirements.

But Kenton's solution is more straightforward than this. Therefore I will simplify my program further.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM