我有一些二进制数据,它是通过序列化谷歌协议缓冲区类获得的。如何在运行时找出为其序列化数据的类。
例如,假设我有一个类 abc。我将这个类 abc 序列化为二进制数据。有没有办法验证这个二进制数据是通过序列化类 abc而不是其他类获得的?
此外,如果我通过类 xyz的 parse 方法解析类 abc 的二进制数据,我怎么知道解析是否成功。
我有一些二进制数据,它是通过序列化谷歌协议缓冲区类获得的。如何在运行时找出为其序列化数据的类。
例如,假设我有一个类 abc。我将这个类 abc 序列化为二进制数据。有没有办法验证这个二进制数据是通过序列化类 abc而不是其他类获得的?
此外,如果我通过类 xyz的 parse 方法解析类 abc 的二进制数据,我怎么知道解析是否成功。
protobuf 不包含在线路上的任何类型信息(除非您自己在 protobuf 外部执行此操作)。因此,您无法严格验证 - 这实际上是一件好事,因为这意味着类型是可互换和兼容的。只要class abc
有与其他类型兼容的合约,它就可以工作。这里的“兼容”是指:对于两者共有的任何字段编号,它们具有兼容的线型。如果abc
将字段 4 声明为字符串,而另一个类将字段 4 声明为双精度数,则反序列化将失败。
您可以使用的另一个“信号”是required
字段的省略:如果abc
始终包含字段 3,但您获得的数据省略了字段 3,那么它可能不是abc
. 请注意,protobuf 被设计为具有版本容错性:您不能假设额外的字段意味着它不是abc
,因为可能是数据正在使用更高版本的合约,或者正在使用扩展字段。同样,丢失的可选字段可能会丢失,因为他们只是选择不提供值,或者该字段未在他们使用的合约版本上声明。
重新测试成功解析:这将是特定于实现的。我想C ++ 实现要么有一个返回值来检查,要么有一个标志字段来检查。我自己不使用那个api,所以我不能说。在其他一些平台上,如果出现严重问题,我希望会引发异常(java、.net 等)。