I am able to write code to deserialize a proto message that contains a oneof section without having to know beforehand what the oneof section contains. I can not figure out how to write a similar set of struct definitions that I can deserialize the same way using Cereal.
I was using Protobufs to serialize/deserialize some data, but I ran into the same problem as piaoxu. So I switched to using Cereal.
I have been able to convert all of the original proto definitions to C++ struct definitions that can be serialized using Cereal, except the proto definitions that use the oneof functionality.
Here is an example set of a proto definitions that I'd like to convert to structs:
syntax = "proto3";
package Messages;
message A {}
message B {}
message Message {
oneof contents {
A a = 1;
B b = 2;
}
}
Here is the corresponding C++ code I had written to deserialize and parse a received Message
. Using the generated protobuf code, I was able to deserialize a Message
without first knowing if it contains an A
or a B
:
void ParseData(const string& data) {
{
auto message = new Messages::Message();
message->ParseFromString(data);
switch (message->contents_case()) {
case Messages::Message::kA:
std::cout << "I got an A!" << std::endl;
break;
case Messages::Message::kB:
std::cout << "I got a B!" << std::endl;
break;
default:
break;
}
}
And here is my attempt at making an equivalent set of struct definitions:
struct A {};
struct B {};
template <class Contents>
struct Message {
enum Type {
A,
B,
};
Type type;
Contents contents;
template <class Archive>
void serialize(Archive& archive) {
archive(type, contents);
}
};
And I'm using these structs to serialize and send a message like so:
bool SendA() {
Message<A> message{};
ostringstream stream;
message.type = Message::Type::A;
message.contents = new A{};
{
cereal::PortableBinaryOutputArchive archive(stream);
archive(message);
}
return SendData(stream.str());
}
This approach works until I try to deserialize a received Message
. I would like to be able to deserialize a Message
without first knowing if it contains an A
or a B
, but AFAIK this is not possible.
Is this indeed not possible using my current approach? And if so, is there another approach that will allow me to deserialize a similar set of structs without first knowing what it contains?