REMARQUE:Ce site est obsolète. Le site sera désactivé après le 31 janvier 2023 et le trafic redirigera vers le nouveau site à l'adresse https://protobuf.dev. En attendant, les mises à jour ne seront effectuées que sur protobuf.dev.

zéro_copie_flux.h

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Ce fichier contient les interfaces ZeroCopyInputStream et ZeroCopyOutputStream, qui représentent des flux d'E/S abstraits vers et depuis lesquels des tampons de protocole peuvent être lus et écrits.

Pour découvrir quelques implémentations simples de ces interfaces, consultez zero_copy_stream_impl.h.

Ces interfaces diffèrent des flux d'E/S classiques dans la mesure où elles tentent de réduire la quantité de données à copier. Pour ce faire, la responsabilité de l'allocation des tampons est déplacée vers l'objet de flux au lieu de la responsabilité de l'appelant. Ainsi, le flux peut renvoyer un tampon qui pointe en fait directement dans la structure de données finale où les octets doivent être stockés, et l'appelant peut interagir directement avec ce tampon, éliminant ainsi une opération de copie intermédiaire.

À titre d'exemple, considérons le cas courant dans lequel vous lisez des octets à partir d'un tableau déjà en mémoire (ou peut-être un fichier mmap()). Avec les flux d'E/S classiques, vous pouvez:

char buffer[[]BUFFER_SIZE];
input->Read(buffer, BUFFER_SIZE);
DoSomething(buffer, BUFFER_SIZE);

Ensuite, le flux appelle simplement memcpy() pour copier les données du tableau dans votre tampon. Avec ZeroCopyInputStream, vous devez effectuer cette opération à la place:

const void* buffer;
int size;
input->Next(&buffer, &size);
DoSomething(buffer, size);

Ici, aucune copie n'est effectuée. Le flux d'entrée renvoie un pointeur directement dans le tableau secondaire, et l'appelant finit par lire directement.

Si vous souhaitez pouvoir lire à l'ancienne, vous pouvez créer un objet CodedInputStream ou CodedOutputStream encapsulant ces objets et utiliser leurs méthodes ReadRaw()/WriteRaw(). Bien entendu, ces étapes ajoutent une étape de copie, mais Coded*Stream gère la mise en mémoire tampon, du moins ce qui est raisonnablement efficace.

Exemple ZeroCopyInputStream:

// Read in a file and print its contents to stdout.
int fd = open("myfile", O_RDONLY);
ZeroCopyInputStream* input = new FileInputStream(fd);

const void* buffer;
int size;
while (input->Next(&buffer, &size)) {
  cout.write(buffer, size);
}

delete input;
close(fd);

Exemple ZeroCopyOutputStream:

// Copy the contents of "infile" to "outfile", using plain read() for
// "infile" but a ZeroCopyOutputStream for "outfile".
int infd = open("infile", O_RDONLY);
int outfd = open("outfile", O_WRONLY);
ZeroCopyOutputStream* output = new FileOutputStream(outfd);

void* buffer;
int size;
while (output->Next(&buffer, &size)) {
  int bytes = read(infd, buffer, size);
  if (bytes < size) {
    // Reached EOF.
    output->BackUp(size - bytes);
    break;
  }
}

delete output;
close(infd);
close(outfd);

Classes dans ce fichier

Interface abstraite semblable à un flux d'entrée, mais conçue pour minimiser la copie.
Interface abstraite semblable à un flux de sortie, mais conçue pour minimiser la copie.

Classe ZeroCopyInputStream

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Interface abstraite semblable à un flux d'entrée, mais conçue pour minimiser la copie.

Sous-classes connues:

Membres

ZeroCopyInputStream()
virtual
~ZeroCopyInputStream()
virtual bool
Next(const void ** data, int * size) = 0
Extrait un fragment de données du flux. plus...
virtual void
BackUp(int count) = 0
Sauvegarde un nombre d'octets, de sorte que le prochain appel à Next() renvoie à nouveau les données déjà renvoyées par le dernier appel à Next(). plus
virtual bool
Skip(int count) = 0
Ignore un certain nombre d'octets. plus...
virtual int64_t
ByteCount() const = 0
Renvoie le nombre total d'octets lus depuis la création de cet objet.

virtual bool ZeroCopyInputStream::Next(
        const void ** data,
        int * size) = 0

Extrait un fragment de données du flux.

Conditions préalables :

  • "size" et "data" ne sont pas NULL.

Conditions préalables:

  • Si la valeur renvoyée est "false", il n'y a plus de données à renvoyer ou une erreur s'est produite. Toutes les erreurs sont définitives.
  • Sinon, "taille" pointe vers le nombre réel d'octets lus et "données" pointe vers un pointeur vers un tampon contenant ces octets.
  • La propriété de ce tampon reste associée au flux, qui reste valide jusqu'à ce qu'une autre méthode du flux soit appelée ou que le flux soit détruit.
  • Il est normal que la mémoire tampon renvoyée ait une taille nulle, à condition que l'appel répété de Next() produise un tampon de taille non nulle.

virtual void ZeroCopyInputStream::BackUp(
        int count) = 0

Sauvegarde un nombre d'octets, de sorte que le prochain appel à Next() renvoie à nouveau les données déjà renvoyées par le dernier appel à Next().

Cela est utile lorsque vous écrivez des procédures qui ne sont censées lire qu'à un certain point dans l'entrée, puis revenir. Si Next() renvoie un tampon qui dépasse ce que vous souhaitiez lire, vous pouvez utiliser BackUp() pour revenir au point où vous souhaitez terminer l'opération.

Conditions préalables :

  • La dernière méthode appelée doit être Next().
  • La valeur "count" doit être inférieure ou égale à la taille du dernier tampon renvoyé par Next().

Conditions préalables:

  • Les derniers "count" octets du dernier tampon renvoyés par Next() seront réintégrés dans le flux. Les appels ultérieurs à Next() renverront les mêmes données avant de produire de nouvelles données.

virtual bool ZeroCopyInputStream::Skip(
        int count) = 0

Ignore un certain nombre d'octets.

Renvoie la valeur "false" si la fin du flux est atteinte ou si une erreur de saisie s'est produite. Dans le cas de fin de flux, la diffusion est avancée à la fin du flux (ByteCount() renvoie donc la taille totale du flux).

Classe ZeroCopyOutputStream

#include <google/protobuf/io/zero_copy_stream.h>
namespace google::protobuf::io

Interface abstraite semblable à un flux de sortie, mais conçue pour minimiser la copie.

Sous-classes connues:

Membres

ZeroCopyOutputStream()
virtual
~ZeroCopyOutputStream()
virtual bool
Next(void ** data, int * size) = 0
Récupère un tampon dans lequel les données peuvent être écrites. plus...
virtual void
BackUp(int count) = 0
Sauvegarde un nombre d'octets, de sorte que la fin du dernier tampon renvoyé par Next() ne soit pas réellement écrite. plus...
virtual int64_t
ByteCount() const = 0
Renvoie le nombre total d'octets écrits depuis la création de cet objet.
virtual bool
WriteAliasedRaw(const void * data, int size)
Écrire un fragment de données dans la sortie plus...
virtual bool
AllowsAliasing() const

virtual bool ZeroCopyOutputStream::Next(
        void ** data,
        int * size) = 0

Récupère un tampon dans lequel les données peuvent être écrites.

Toutes les données écrites dans ce tampon finissent éventuellement par être écrites dans la sortie (éventuellement instantanément).

Conditions préalables :

  • "size" et "data" ne sont pas NULL.

Conditions préalables:

  • Si la valeur renvoyée est "false", une erreur s'est produite. Toutes les erreurs sont définitives.
  • Sinon, "taille" pointe vers le nombre réel d'octets dans la mémoire tampon et "données" pointe vers la mémoire tampon.
  • La propriété de ce tampon reste associée au flux, qui reste valide jusqu'à ce qu'une autre méthode du flux soit appelée ou que le flux soit détruit.
  • Toutes les données stockées par l'appelant dans ce tampon seront à terme écrites dans la sortie (sauf si BackUp() est appelé).
  • Il est normal que la mémoire tampon renvoyée ait une taille nulle, à condition que l'appel répété de Next() produise un tampon de taille non nulle.

virtual void ZeroCopyOutputStream::BackUp(
        int count) = 0

Sauvegarde un nombre d'octets, de sorte que la fin du dernier tampon renvoyé par Next() ne soit pas réellement écrite.

Cela est nécessaire lorsque vous avez fini d'écrire toutes les données que vous souhaitez écrire, mais que le tampon était trop volumineux. Vous ne souhaitez pas écrire de mémoire inutile après la fin de vos données. Vous utilisez donc BackUp() pour effectuer une sauvegarde.

Conditions préalables :

  • La dernière méthode appelée doit être Next().
  • La valeur "count" doit être inférieure ou égale à la taille du dernier tampon renvoyé par Next().
  • L'appelant ne doit rien avoir écrit sur les derniers "count" octets de ce tampon.

Conditions préalables:

  • Les derniers "count" octets du dernier tampon renvoyé par Next() seront ignorés.

virtual bool ZeroCopyOutputStream::WriteAliasedRaw(
        const void * data,
        int size)

Écrire un fragment de données dans la sortie

Certains flux de sortie peuvent l'implémenter de manière à éviter la copie. Cochez "AllowAliasing()" avant d'appeler WriteAliasedRaw(). GOOGLE_CHECK échoue si WriteAliasedRaw() est appelé sur un flux qui n'autorise pas les alias.

REMARQUE: Il est de la responsabilité de l'appelant de s'assurer que le fragment de mémoire reste actif jusqu'à ce que toutes les données aient été consommées du flux.