I'm processing some SerializeToString
serialized data, the data might be message A
or message B
, I can ParseFromString
using A or B. But how can I determine that I'm using the right type?
message A {
int32 a = 1;
double b = 2;
repeated int32 c = 3;
};
message B {
int32 a = 1;
repeated int32 c = 2;
};
CodePudding user response:
Protocol buffers do not serialise other metadata than the field number. 1, 2 and 3 for A
and 1 and 2 for B
. The solution of your problem is making the field tag of field a
and c
match in both messages and deserialise with any message:
message A {
int32 a = 1;
double b = 2;
repeated int32 c = 3;
};
message B {
int32 a = 1;
repeated int32 c = 3;
};
and with that it will not matter if you deserialise with A
or B
. I recommend deserialising with the one that has more fields though. This will set the b
in A
either to its default (0) if it's no value is deserialised or to the number that was serialised. So then you can just do something like:
A a;
if (!a.ParseFromString(serialised_data)) {
// error
}
if (a.b == 0) {
// This is a message B
}
else {
// This is a message A
}
This is possible because Protocol buffers rely only on tag for serialisation and deserialisation.
Note
As I mentioned the default of b
in A
will be 0. If 0 has business meaning (it's not recommended but understandable), you will not be able to identify if the b
field was set or if it wasn't. For that case, you could either go with Ramsay's response or you could add an extra metadata in front of the serialised message which will indicate which type to deserialise it with.
CodePudding user response:
If you are sure that the message type of serialized string is only either message A
or message B
, you could do something like this:
std::string serialized_data;
if(A.ParseFromString(serialized_data)){
// it's message A
}else{
// it's message B.
}