首页 > Java > java教程 > 正文

如何使用定界 I/O 在 C 中编码和解码 Protocol Buffers 消息?

Mary-Kate Olsen
发布: 2024-10-28 17:14:29
原创
215 人浏览过

How Do You Encode and Decode Protocol Buffers Messages in C   Using Delimited I/O?

Java 协议缓冲区分隔 I/O 函数的 C 等效项

在 C 和 Java 中,都需要读写多个协议缓冲来自文件的消息。 Java 版本 2.1.0 为此提供了一组“分隔”I/O 函数:

  • parseDelimitedFrom
  • mergeDelimitedFrom
  • writeDelimitedTo

这些函数有助于在每条消息之前附加长度前缀。然而,目前尚不清楚 C 中是否存在这样的功能。

C 等效项的存在

最初,这些 Java 函数没有直接的 C 等效项。然而,从版本 3.3.0 开始,C 现在在 google/protobuf/util/delimited_message_util.h 中提供了分隔消息实用函数。

大小前缀格式

For如果用户希望在这些官方实用程序发布之前用 C 语言实现自己的解析器,那么了解 Java API 附加的大小前缀的传输格式非常重要。该格式遵循以下准则:

  • 分隔符甚至必须出现在第一条消息之前。
  • 消息的大小被编码为 32 位 varint。
  • 1 字节分隔符字节 (0x0A) 终止每条消息,下一条长度前缀消息紧随其后开始。

优化的 C 实现

官方 C 实用函数发布后,发现了最初提出的实现中缺少的一些优化。下面提供的这些优化函数可提高性能并避免潜在错误:

<code class="cpp">bool writeDelimitedTo(
    const google::protobuf::MessageLite&amp; message,
    google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
  // Create a new coded stream for each message.
  google::protobuf::io::CodedOutputStream output(rawOutput);

  // Write the message size.
  const int size = message.ByteSize();
  output.WriteVarint32(size);

  // Serialize the message directly to the output buffer if possible.
  uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
  if (buffer != NULL) {
    message.SerializeWithCachedSizesToArray(buffer);
  } else {
    // Use a slower path if the message spans multiple buffers.
    message.SerializeWithCachedSizes(&amp;output);
    if (output.HadError()) return false;
  }

  return true;
}

bool readDelimitedFrom(
    google::protobuf::io::ZeroCopyInputStream* rawInput,
    google::protobuf::MessageLite* message) {
  // Create a new coded stream for each message.
  google::protobuf::io::CodedInputStream input(rawInput);

  // Read the message size.
  uint32_t size;
  if (!input.ReadVarint32(&amp;size)) return false;

  // Set a read limit to enforce the 64 MB per-message size constraint.
  google::protobuf::io::CodedInputStream::Limit limit =
      input.PushLimit(size);

  // Parse the message.
  if (!message->MergeFromCodedStream(&amp;input)) return false;
  if (!input.ConsumedEntireMessage()) return false;

  // Remove the read limit.
  input.PopLimit(limit);

  return true;
}</code>
登录后复制

以上是如何使用定界 I/O 在 C 中编码和解码 Protocol Buffers 消息?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!