Protocol Buffers 中的定界 I/O 函数:C 等效项
在从两个协议缓冲区中的文件读取或写入多个 Protocol Buffers 消息的情况下C 和 Java,有必要在消息中附加长度前缀。虽然 Java API 为此目的提供了专用的“定界”I/O 函数,但它们在 C 中的对应函数可能并不明显。
最近的更新表明,此类 C 等效函数现在驻留在 google/protobuf/util 中/delimited_message_util.h 作为版本 3.3.0 的一部分。然而,在此更新之前,有一些替代实现可以有效地满足此要求。
其中一个实现由 C 和 Java protobuf 库的前作者提供,包括防止 64MB 输入后潜在故障的优化。如下所示,这些实现对单个消息强制实施 64MB 限制,确保流式传输无缝继续进行,而不会超出总体限制。
C 的优化定界 I/O 实现
bool writeDelimitedTo(
const google::protobuf::MessageLite& message,
google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
// Initialize a CodedOutputStream for each message.
google::protobuf::io::CodedOutputStream output(rawOutput);
// Determine the message size and write it as a Varint.
int size = message.ByteSize();
output.WriteVarint32(size);
// Optimize for messages fitting into a single buffer.
uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL) message.SerializeWithCachedSizesToArray(buffer);
else message.SerializeWithCachedSizes(&output);
return true;
}
bool readDelimitedFrom(
google::protobuf::io::ZeroCopyInputStream* rawInput,
google::protobuf::MessageLite* message) {
// Initialize a CodedInputStream for each message.
google::protobuf::io::CodedInputStream input(rawInput);
// Read the message size.
uint32_t size;
if (!input.ReadVarint32(&size)) return false;
// Restrict reading to the determined message size.
google::protobuf::io::CodedInputStream::Limit limit =
input.PushLimit(size);
// Parse the message and verify it fits within the limit.
if (!message->MergeFromCodedStream(&input)) return false;
if (!input.ConsumedEntireMessage()) return false;
// Lift the reading restriction.
input.PopLimit(limit);
return true;
}
这些优化的实现有效地处理不同大小的消息,并为 C 中的分隔 I/O 提供可靠的解决方案。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3