检查解析的Protocol Buffers(Protobuf)proto3消息是否有效

时间:2018-01-24 15:47:38

标签: c++ validation parsing serialization protocol-buffers

我目前需要通过网络传输给定类型Foo的Protobuf消息,并在接收时处理它。

我使用的是Protobuf 3.5.1和proto3语言。

接待时我会做以下事情:

  1. 创建预期类型Foo的空实例(通过工厂方法,因为它可能会更改)。
  2. 解析来自CodedInputStream的消息(根据从网络收到的数据构建)。
  3. 验证解析是否成功。
  4. 这是一个说明具体问题的最小代码段:

    // Create the empty Protobuf message of the EXPECTED type.
    std::shared_ptr<google::protobuf::Message> message = std::make_unique<Foo>();
    
    // Create the CodedInputStream from the network data.
    google::protobuf::io::CodedInputStream stream{receive_buffer_.data(), static_cast<int>(bytes_transferred)};
    
    if (message->ParseFromCodedStream(&stream) && stream.ConsumedEntireMessage() && message->IsInitialized()) {
      // Message is of correct type and correctly parsed.
    } else {
      // Message is NOT VALID.
      // TODO: This does not work if sending a message of type `Bar`.
    }
    

    如果发件人传输了预期类型Foo的邮件,那么一切都会完美无缺,但如果发送另一种类型Bar的邮件,事情会变得奇怪。

    两条消息都有类似的结构(它们只有oneof类型不同,它使用不同的类型(但可能使用相同的字段标识值):

    message Foo {
    
      First first = 1;
    
      oneof second {
    
        A a = 2;
        B b = 3;
      }
    }
    
    message Bar {
    
      First first = 1;
    
      oneof second {
    
        C c = 2;
        D d = 3;
      }
    }
    

    我还没有找到办法,检测收到的Protobuf消息类型是否“有效”。

    所以我的问题是:如何安全地检测解析后的Foo实例是否有效,而不是另一个实例(结构相似但完全不同)的Protobuf消息类型?我是否需要手动添加作为字段发送的消息的名称(这将是愚蠢的,但应该有效)?

0 个答案:

没有答案