Home >Backend Development >C++ >How to Achieve Java Protocol Buffers Delimited I/O Functionality in C ?

How to Achieve Java Protocol Buffers Delimited I/O Functionality in C ?

Barbara Streisand
Barbara StreisandOriginal
2024-12-05 02:32:091019browse

How to Achieve Java Protocol Buffers Delimited I/O Functionality in C  ?

C Equivalents for Java Protocol Buffers Delimited I/O Functions

Problem:
Developers attempting to read and write multiple Protocol Buffers messages from files in both C and Java may encounter issues using the "Delimited" I/O functions available in Java but not seemingly accessible in C .

Solution:
As of version 3.3.0, equivalent functions for reading and writing delimited messages have been introduced in C within the header file google/protobuf/util/delimited_message_util.h. These functions are:

  • writeDelimitedTo(): Writes a delimited message to a google::protobuf::io::ZeroCopyOutputStream.
  • readDelimitedFrom(): Reads a delimited message from a google::protobuf::io::ZeroCopyInputStream.

Note:
An alternative implementation, provided by the original author of the C and Java protobuf libraries, offers optimizations not present in the official library implementations. This implementation, shown below, prevents potential failures after 64MB of input while still enforcing the 64MB limit on individual messages:

bool writeDelimitedTo(
    const google::protobuf::MessageLite& message,
    google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
  // We create a new coded stream for each message.  Don't worry, this is fast.
  google::protobuf::io::CodedOutputStream output(rawOutput);

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

  uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
  if (buffer != NULL) {
    // Optimization:  The message fits in one buffer, so use the faster
    // direct-to-array serialization path.
    message.SerializeWithCachedSizesToArray(buffer);
  } else {
    // Slightly-slower path when the message is multiple buffers.
    message.SerializeWithCachedSizes(&output);
    if (output.HadError()) return false;
  }

  return true;
}

bool readDelimitedFrom(
    google::protobuf::io::ZeroCopyInputStream* rawInput,
    google::protobuf::MessageLite* message) {
  // We create a new coded stream for each message.  Don't worry, this is fast,
  // and it makes sure the 64MB total size limit is imposed per-message rather
  // than on the whole stream.  (See the CodedInputStream interface for more
  // info on this limit.)
  google::protobuf::io::CodedInputStream input(rawInput);

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

  // Tell the stream not to read beyond that size.
  google::protobuf::io::CodedInputStream::Limit limit =
      input.PushLimit(size);

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

  // Release the limit.
  input.PopLimit(limit);

  return true;
}

The above is the detailed content of How to Achieve Java Protocol Buffers Delimited I/O Functionality in C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn