区切り文字付き I/O を使用して C でプロトコル バッファー メッセージをエンコードおよびデコードするにはどうすればよいですか?

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?

C で Java のプロトコル バッファー区切り I/O 関数に相当するもの

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 に区切りメッセージ ユーティリティ関数を備えています。

サイズ プレフィックスの形式

これらの公式ユーティリティがリリースされる前に、C で独自のパーサーを実装しようとしているユーザーは、Java API によって付加されるサイズ プレフィックスのワイヤ形式を理解することが重要です。形式は次のガイドラインに従っています。

  • 最初のメッセージの前であっても区切り文字が存在する必要があります。
  • メッセージのサイズは 32 ビットのバリアントとしてエンコードされます。
  • 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 でプロトコル バッファー メッセージをエンコードおよびデコードするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!