Google的protobuf库中的MergeFrom*与ParseFrom*

mev*_*ron 3 c++ protocol-buffers

我似乎无法在protobuf中找到MessageLiteMergeFrom*ParseFrom*方法之间的明确区别.

我试图最小化我必须做的数据复制量,所以我在下面编写了以下代码来解码长度前缀消息:

bool StreamMessageDelimiter::receiveWithLengthPrefix(Message& message)
{
    google::protobuf::uint32 messageSize;
    auto_ptr<google::protobuf::uint8> prefixBuf(new google::protobuf::uint8[sizeof(messageSize)]);
    int receivedBytes = receiveNBytes(prefixBuf.get(), sizeof(messageSize));
    if(receivedBytes != sizeof(messageSize))
    {
        return false;
    }

    CodedInputStream prefixInput(prefixBuf.get(), sizeof(messageSize));
    prefixInput.ReadLittleEndian32(&messageSize);

    google::protobuf::uint8* payloadBuf = new google::protobuf::uint8[messageSize];
    receivedBytes = receiveNBytes(payloadBuf, messageSize);
    if(receivedBytes != messageSize)
    {
        return false;
    }

    ArrayInputStream rawInput(payloadBuf, messageSize);
    CodedInputStream codedInput(&rawInput);

    if(!message.MergeFromCodedStream(&codedInput))
    {
        return false;
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是使用MergeFromCodedStream原因message来获取所有权payloadBuf,还是message制作基础数据的副本?如果message确确实让副本,那么我显然应该使用auto_ptrpayloadBuf像我一样的prefixBuf.

感谢您的投入!

Arp*_*ius 5

首先,MergeFrom*不要像ParseFrom*方法一样工作.第一个像MergeFromMessage类一样工作:

除了将要合并的嵌入消息之外,将覆盖奇异字段.重复的字段将被连接.

ParseFrom是一个包装,Clear在打电话之前简单地打电话MergeFrom:

Clear()避免释放内存,假设将再次需要分配用于保存部分消息的任何内存来保存下一条消息.如果您确实要释放消息使用的内存,则必须将其删除.

因此,在您的消息被清除之前,所有重复的字段都将聚集新数据.

存储在序列化流中的数据是Varint编码的,因此通过解释流中的数据并复制到Message对象字段来完成解析.

解析完成后,消息本身不需要缓冲区.