Maison  >  Article  >  Java  >  Comment encoder et décoder les messages des tampons de protocole en C à l’aide d’E/S délimitées ?

Comment encoder et décoder les messages des tampons de protocole en C à l’aide d’E/S délimitées ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-28 17:14:29214parcourir

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

Équivalents C pour les tampons de protocole de Java, fonctions d'E/S délimitées

En C et Java, il est nécessaire de lire et d'écrire plusieurs protocoles Tamponne les messages des fichiers. Java version 2.1.0 propose un ensemble de fonctions d'E/S "Délimitées" à cet effet :

  • parseDelimitedFrom
  • mergeDelimitedFrom
  • writeDelimitedTo

Ces fonctions facilitent l'attachement de préfixes de longueur avant chaque message. Cependant, il reste difficile de savoir si de telles capacités existent en C.

Existence d'équivalents C

Au départ, il n'existait pas d'équivalents C directs à ces fonctions Java. Cependant, depuis la version 3.3.0, C propose désormais des fonctions utilitaires de message délimitées dans google/protobuf/util/delimited_message_util.h.

Format des préfixes de taille

Pour Pour les utilisateurs cherchant à implémenter leurs propres analyseurs en C avant la sortie de ces utilitaires officiels, il est important de comprendre le format wire pour les préfixes de taille attachés par l'API Java. Le format respecte les directives suivantes :

  • Les délimiteurs doivent être présents avant même le premier message.
  • La taille du message est codée comme une variante de 32 bits.
  • Un octet délimiteur de 1 octet (0x0A) termine chaque message et le message suivant avec préfixe de longueur commence immédiatement après.

Implémentations C optimisées

Suite à la sortie des fonctions officielles de l'utilitaire C, plusieurs optimisations ont été découvertes qui manquaient dans les implémentations initialement proposées. Ces fonctions optimisées, fournies ci-dessous, offrent des performances améliorées et évitent les erreurs potentielles :

<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>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn