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.

Codage_flux.h

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

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

Ce fichier contient les classes CodedInputStream et CodedOutputStream, qui encapsulent respectivement ZeroCopyInputStream et ZeroCopyOutputStream, et permettent de lire ou d'écrire des données individuelles dans différents formats.

Plus particulièrement, ils implémentent l'encodage "Varint" pour les entiers, un encodage de longueur variable simple dans lequel les nombres plus petits prennent moins d'octets.

En règle générale, ces classes ne sont utilisées en interne que par la bibliothèque de tampons de protocole afin d'encoder et de décoder des tampons de protocole. Les clients de la bibliothèque n'ont besoin de connaître cette classe que s'ils souhaitent écrire des procédures personnalisées d'analyse ou de sérialisation de messages.

Exemple CodedOutputStream:

// Write some data to "myfile".  First we write a 4-byte "magic number"
// to identify the file type, then write a length-delimited string.  The
// string is composed of a varint giving the length followed by the raw
// bytes.
int fd = open("myfile", O_CREAT | O_WRONLY);
ZeroCopyOutputStream* raw_output = new FileOutputStream(fd);
CodedOutputStream* coded_output = new CodedOutputStream(raw_output);

int magic_number = 1234;
char text[[]] = "Hello world!";
coded_output->WriteLittleEndian32(magic_number);
coded_output->WriteVarint32(strlen(text));
coded_output->WriteRaw(text, strlen(text));

delete coded_output;
delete raw_output;
close(fd);

Exemple CodedInputStream:

// Read a file created by the above code.
int fd = open("myfile", O_RDONLY);
ZeroCopyInputStream* raw_input = new FileInputStream(fd);
CodedInputStream* coded_input = new CodedInputStream(raw_input);

coded_input->ReadLittleEndian32(&magic_number);
if (magic_number != 1234) {
  cerr << "File not in expected format." << endl;
  return;
}

uint32 size;
coded_input->ReadVarint32(&size);

char* text = new char[[]size + 1];
coded_input->ReadRaw(buffer, size);
text[[]size] = '\0';

delete coded_input;
delete raw_input;
close(fd);

cout << "Text is: " << text << endl;
delete [[]] text;

Pour ceux qui sont intéressés, l'encodage de variables est défini comme suit:

L'encodage fonctionne sur des entiers non signés d'une longueur maximale de 64 bits. Chaque octet de la valeur encodée a le format suivant:

  • bits 0 à 6: sept bits du nombre encodé.
  • bit 7: zéro s'il s'agit du dernier octet de l'encodage (dans ce cas, tous les bits restants du nombre sont zéro) ou 1 si plusieurs octets sont suivis. Le premier octet contient les 7 bits les moins significatifs du nombre, le second octet (le cas échéant) les 7 bits de moindre importance, etc. Ainsi, le nombre binaire 1011000101011 est encodé en deux octets sous la forme "10101011 00101100".

En théorie, la variable peut être utilisée pour encoder des entiers de n'importe quelle longueur. Toutefois, pour des raisons pratiques, nous définissons une limite de 64 bits. La longueur maximale encodée d'un nombre est donc de 10 octets.

Classes dans ce fichier

Classe qui lit et décode des données binaires composées d'entiers encodés à la variance et d'éléments à largeur fixe.
EpsCopyOutputStream enveloppe un objet ZeroCopyOutputStream et expose un nouveau flux. La propriété vous permet d'écrire des kSlopBytes (16 octets) à partir de la position actuelle sans limites.
Classe qui encode et écrit des données binaires composées d'entiers encodés en variance et d'éléments à largeur fixe.
Équivalent de compilation de VarintSize32().

Classe CodedInputStream

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

Classe qui lit et décode des données binaires composées d'entiers encodés à la variance et d'éléments à largeur fixe.

Encapsule un objet ZeroCopyInputStream. La plupart des utilisateurs n'ont pas besoin de gérer CodedInputStream.

La plupart des méthodes de CodedInputStream qui renvoient un bool renvoient false si une erreur d'E/S sous-jacente se produit ou si les données sont incorrectes. Lorsqu'un tel échec se produit, le CodedInputStream est endommagé et n'est plus utile. Après un échec, les appelants devraient également supposer que des écritures vers des arguments "out" ont eu lieu, bien que rien ne puisse être déterminé à partir de ces écritures.

Membres

explicit
CodedInputStream(ZeroCopyInputStream * input)
Crée un objet CodedInputStream qui lit les données du ZeroCopyInputStream donné.
explicit
CodedInputStream(const uint8 * buffer, int size)
Crée un CodedInputStream qui lit le tableau plat donné. plus...
~CodedInputStream()
Détruisez CodedInputStream et positionnez ZeroCopyInputStream sous-jacent sur le premier octet non lu. plus...
bool
IsFlat() const
Renvoie la valeur "true" si cet objet CodedInputStream lit un tableau plat au lieu d'un objet ZeroCopyInputStream.
bool
Skip(int count)
Ignore un certain nombre d'octets. plus...
bool
GetDirectBufferPointer(const void ** data, int * size)
Définit les *données de sorte qu'elles pointent directement vers la partie non lue du tampon sous-jacent de CodedInputStream, et *s'adaptent à la taille de ce tampon, sans pour autant avancer la position actuelle du flux. plus...
void
GetDirectBufferPointerInline(const void ** data, int * size)
Semblable à GetDirectBufferPointer, mais cette méthode est intégrée et n'essaie pas d'actualiser() si le tampon est actuellement vide.
bool
ReadRaw(void * buffer, int size)
Lire les octets bruts, en les copiant dans le tampon donné.
bool
ReadString(std::string * buffer, int size)
Comme ReadRaw, mais lit dans une chaîne.
bool
ReadLittleEndian32(uint32 * value)
Lire un entier endend de 32 bits.
bool
ReadLittleEndian64(uint64 * value)
Lire un entier endend de 64 bits.
bool
ReadVarint32(uint32 * value)
Lire un entier non signé avec encodage Varint et tronquant à 32 bits plus...
bool
ReadVarint64(uint64 * value)
Lire un entier non signé avec un encodage Varint
bool
ReadVarintSizeAsInt(int * value)
Lit une variable du fil en "int". plus...
uint32
ReadTag()
Lire un tag plus...
uint32
ReadTagNoLastTag()
std::pair< uint32, bool >
ReadTagWithCutoff(uint32 cutoff)
Cette solution est généralement plus rapide que la méthode ReadTag() lorsque la coupure est une constante du fichier manifeste. plus...
std::pair< uint32, bool >
ReadTagWithCutoffNoLastTag(uint32 cutoff)
bool
ExpectTag(uint32 expected)
Cette fonction renvoie généralement "true" si l'appel de ReadVarint32() génère la valeur donnée. plus...
bool
ExpectAtEnd()
Cette fonction renvoie généralement la valeur "true" si aucun autre octet ne peut être lu. plus...
bool
LastTagWas(uint32 expected)
Si le dernier appel à ReadTag() ou ReadTagWithCutoff() a renvoyé la valeur donnée, la valeur "true" est renvoyée. plus...
void
SetLastTag(uint32 tag)
bool
ConsumedEntireMessage()
Lors de l'analyse d'un message (mais PAS d'un groupe), cette méthode doit être appelée immédiatement après le retour de la méthode MergeFromCodedStream() (si elle renvoie la valeur "true"), afin de vérifier que le message s'est terminé de façon légitime. plus...
void
SetConsumed()
static const uint8 *
ReadLittleEndian32FromArray(const uint8 * buffer, uint32 * value)
Ces méthodes lisent des données à partir d'un tampon fourni en externe. plus...
static const uint8 *
ReadLittleEndian64FromArray(const uint8 * buffer, uint64 * value)
Lire un entier endend de 64 bits. plus...
static const uint8 *
ExpectTagFromArray(const uint8 * buffer, uint32 expected)
Comme ci-dessus, sauf les lectures à partir du tampon spécifié. plus...

Limites

Les limites sont utilisées lors de l'analyse des messages intégrés délimités par la longueur. Une fois la longueur du message lue, PushLimit() permet d'empêcher CodedInputStream de lire au-delà de cette durée. Une fois le message intégré analysé, la méthode PopLimit() est appelée pour annuler la limite.
typedef
int Limit
Type d'opaque utilisé avec PushLimit() et PopLimit(). En savoir plus
Limit
PushLimit(int byte_limit)
Place une limite sur le nombre d'octets pouvant être lus par le flux, à partir de la position actuelle. plus...
void
PopLimit(Limit limit)
Affiche la dernière limite transmise par PushLimit(). En savoir plus
int
BytesUntilLimit() const
Renvoie le nombre d'octets restants jusqu'à ce que la limite la plus proche soit atteinte sur la pile, ou -1 si aucune limite n'est définie.
int
CurrentPosition() const
Renvoie la position actuelle par rapport au début du flux d'entrée.

Limite totale d'octets

Pour éviter que des utilisateurs malveillants envoient des messages trop volumineux et provoquent un épuisement de la mémoire, CodedInputStream impose une limite stricte au nombre total d'octets lus.
int = { SetTotalBytesLimit(total_bytes_limit)
void
SetTotalBytesLimit(int total_bytes_limit)
Définit le nombre maximal d'octets lus par cet objet CodedInputStream avant de continuer. plus...
PROTOBUF_DEPRECATED_MSG("Please use the single parameter version of SetTotalBytesLimit(). The " "second parameter is ignored." )
int
BytesUntilTotalBytesLimit() const
Limite du nombre total d'octets moins la position actuelle, ou -1 si le nombre total d'octets est de INT_MAX.

Limite de récursion

Afin d'éviter que des messages corrompus ou malveillants ne provoquent un dépassement de pile, nous devons suivre la profondeur de récursion lors de l'analyse des messages et des groupes intégrés.

CodedInputStream en assure le suivi, car il s'agit du seul objet transmis dans la pile lors de l'analyse.

void
SetRecursionLimit(int limit)
Définit la profondeur de récursion maximale. La valeur par défaut est 100.
int
RecursionBudget()
bool
IncrementRecursionDepth()
Augmente la profondeur de récursion actuelle. plus...
void
DecrementRecursionDepth()
Si possible, diminue la profondeur de récursion.
void
UnsafeDecrementRecursionDepth()
Décrémente la profondeur de récursion de manière aveugle. plus...
std::pair< CodedInputStream::Limit, int >
IncrementRecursionDepthAndPushLimit(int byte_limit)
Raccourci de make_pair(PushLimit(byte_limit), –recursion_budget_). plus...
Limit
ReadLengthAndPushLimit()
Raccourci pour PushLimit(ReadVarint32(&length) ? length : 0).
bool
DecrementRecursionDepthAndPopLimit(Limit limit)
Outil d'aide équivalent à: { bool result = ConsumedFullscreenMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); return result; } Cela peut réduire la taille du code et sa complexité dans certains cas. plus...
bool
CheckEntireMessageConsumedAndPopLimit(Limit limit)
Outil d'aide équivalent à: { bool result = ConsumedFullscreenMessage(); PopLimit(limit); return result; } Cela peut réduire la taille du code et sa complexité dans certains cas.
static int
GetDefaultRecursionLimit()

Registre des extensions

UTILISATION AVANCÉE: 99,9% des utilisateurs peuvent ignorer cette section.

Par défaut, lors de l'analyse des extensions, l'analyseur recherche des définitions d'extensions dans le pool qui possède le descripteur du message externe. Toutefois, vous pouvez appeler SetExtensionRegistry() pour fournir un autre pool. Cela permet, par exemple, d'analyser un message à l'aide d'une classe générée, mais de représenter certaines extensions à l'aide de DynamicMessage.

void
SetExtensionRegistry(const DescriptorPool * pool, MessageFactory * factory)
Définissez le pool utilisé pour rechercher les extensions. plus...
const DescriptorPool *
GetExtensionPool()
Obtenez la valeur DescriptorPool définie via SetExtensionRegistry(), ou NULL si aucun pool n'a été fourni.
MessageFactory *
GetExtensionFactory()
Obtenez la valeur MessageFactory via SetExtensionRegistry() ou NULL si aucune fabrique n'a été spécifiée.

explicit CodedInputStream::CodedInputStream(
        const uint8 * buffer,
        int size)

Crée un CodedInputStream qui lit le tableau plat donné.

Cela est plus rapide que d'utiliser un ArrayInputStream. La fonction PushLimit(size) est implicite par ce constructeur.


CodedInputStream::~CodedInputStream()

Détruisez CodedInputStream et positionnez ZeroCopyInputStream sous-jacent sur le premier octet non lu.

Si une erreur s'est produite lors de la lecture (avec une méthode renvoyant la valeur "false"), la position exacte du flux d'entrée peut se situer entre la dernière valeur lue et la limite d'octets du flux.


bool CodedInputStream::Skip(
        int count)

Ignore un certain nombre d'octets.

Affiche la valeur "false" si une erreur de lecture sous-jacente se produit.


bool CodedInputStream::GetDirectBufferPointer(
        const void ** data,
        int * size)

Définit les *données de sorte qu'elles pointent directement vers la partie non lue du tampon sous-jacent de CodedInputStream, et *s'adaptent à la taille de ce tampon, sans pour autant avancer la position actuelle du flux.

Cela génère toujours un tampon non vide ou renvoie la valeur "false". Si l'appelant utilise l'une de ces données, il doit alors appeler Skip() pour ignorer les octets consommés. Cela peut être utile pour implémenter des routines d'analyse rapide externes pour des types de données non couverts par l'interface CodedInputStream.


bool CodedInputStream::ReadVarint32(
        uint32 * value)

Lire un entier non signé avec encodage Varint et tronquant à 32 bits

Lire une valeur 32 bits équivaut à lire une valeur 64 bits et à la convertir en uint32, mais peut s'avérer plus efficace.


bool CodedInputStream::ReadVarintSizeAsInt(
        int * value)

Lit une variable du fil en "int".

Utilisez cette option pour lire les tailles hors connexion (tailles de chaînes, de sous-messages, d'octets, etc.).

La valeur du fil est interprétée comme non signée. Si sa valeur dépasse la valeur représentative d'un entier sur cette plate-forme, nous renvoyons "false" au lieu de la tronquer. Le troncage (tel qu'effectué par ReadVarint32() ci-dessus) est une approche acceptable pour les champs représentant un entier. Toutefois, lorsque nous analysons une taille à partir du réseau, le fait de tronquer la valeur peut entraîner une erreur d'analyse de la charge utile.


uint32 CodedInputStream::ReadTag()

Lire un tag

La méthode ReadVarint32() est appelée et renvoie le résultat, ou la valeur zéro (qui n'est pas un tag valide) en cas d'échec de ReadVarint32(). ReadTag (mais pas ReadTagNoLastTag) met à jour la dernière valeur de balise, qui peut être vérifiée avec LastTagWas().

Toujours intégré, car il n'est appelé qu'à un seul endroit par boucle d'analyse, mais il est appelé pour chaque itération de cette boucle. Il doit donc être rapide. GCC ne souhaite pas intégrer ce paramètre par défaut.


std::pair< uint32, bool >
    CodedInputStream::ReadTagWithCutoff(
        uint32 cutoff)

Cette solution est généralement plus rapide que la méthode ReadTag() lorsque la coupure est une constante du fichier manifeste.

Elle est particulièrement efficace pour un intervalle supérieur ou égal à 127. La première partie de la valeur renvoyée est la balise qui a été lue, même si elle peut également être nulle dans les cas où ReadTag() renverrait 0. Si la deuxième partie est vraie, alors le tag est connu dans [[]0, coupure]. Si ce n'est pas le cas, la balise est au-dessus de la date limite ou est égale à 0. Il existe une marge de manœuvre intentionnelle lorsque le tag est 0, car cela peut se produire de plusieurs manières. Pour optimiser les performances, nous souhaitons éviter d'ajouter "is tag == 0?" ici.


bool CodedInputStream::ExpectTag(
        uint32 expected)

Cette fonction renvoie généralement "true" si l'appel de ReadVarint32() génère la valeur donnée.

Renvoie toujours "false" si la méthode ReadVarint32() ne renvoie pas la valeur donnée. Si la méthode ExpectTag() renvoie la valeur "true", elle avance également au-delà de la variable. Pour de meilleures performances, utilisez une constante connue à la compilation comme paramètre. Toujours intégré, car cela se réduit à un petit nombre d'instructions lorsqu'un paramètre constant est fourni, mais GCC ne souhaite pas être intégré par défaut.


bool CodedInputStream::ExpectAtEnd()

Cette fonction renvoie généralement la valeur "true" si aucun autre octet ne peut être lu.

Renvoie toujours "false" si davantage d'octets peuvent être lus. Si ExpectAtEnd() renvoie la valeur "true", un appel ultérieur à LastTagWas() agira comme si ReadTag() avait été appelé et renvoyé zéro, et ConsumedIntegerMessage() renvoyait "true".


bool CodedInputStream::LastTagWas(
        uint32 expected)

Si le dernier appel à ReadTag() ou ReadTagWithCutoff() a renvoyé la valeur donnée, la valeur "true" est renvoyée.

Sinon, renvoie la valeur "false". ReadTagNoLastTag/ReadTagWithCutoffNoLastTag ne conserve pas la dernière valeur renvoyée.

Cela est nécessaire, car les analyseurs de certains types de messages intégrés (avec le type de champ TYPE_GROUP) ne savent pas qu'ils ont atteint la fin d'un message tant que le tag ENDGROUP n'est pas inclus dans le message englobant. Le message englobant veut vérifier ce tag pour s'assurer qu'il a le bon numéro, il appelle donc LastTagWas() à partir de l'analyseur intégré pour le vérifier.


bool CodedInputStream::ConsumedEntireMessage()

Lors de l'analyse d'un message (mais PAS d'un groupe), cette méthode doit être appelée immédiatement après le retour de la méthode MergeFromCodedStream() (si elle renvoie la valeur "true"), afin de vérifier que le message s'est terminé de façon légitime.

Cela permet par exemple de vérifier que l'analyse ne s'est pas terminée sur une balise de groupe de fin. Il vérifie également dans certains cas, où, en raison d'optimisations, MergeFromCodedStream() peut renvoyer la valeur "true".


static const uint8 * CodedInputStream::ReadLittleEndian32FromArray(
        const uint8 * buffer,
        uint32 * value)

Ces méthodes lisent des données à partir d'un tampon fourni en externe.

static

L'appelant doit s'assurer que la mémoire tampon dispose d'un espace suffisant. Lire un entier endend de 32 bits.


static const uint8 * CodedInputStream::ReadLittleEndian64FromArray(
        const uint8 * buffer,
        uint64 * value)

Lire un entier endend de 64 bits.

static


static const uint8 * CodedInputStream::ExpectTagFromArray(
        const uint8 * buffer,
        uint32 expected)

Comme ci-dessus, sauf les lectures à partir du tampon spécifié.

L'appelant doit s'assurer que la mémoire tampon est assez grande pour lire une variable de la taille attendue. Pour des performances optimales, utilisez une constante connue à la compilation comme paramètre de tag attendu.

Renvoie un pointeur au-delà du tag attendu s'il a été trouvé ou NULL dans le cas contraire.


typedef CodedInputStream::Limit

Type d'opaque utilisé avec PushLimit() et PopLimit().

Ne modifiez pas les valeurs de ce type vous-même. La seule raison pour laquelle il ne s'agit pas d'une structure avec des éléments internes privés est l'efficacité.


Limit CodedInputStream::PushLimit(
        int byte_limit)

Place une limite sur le nombre d'octets pouvant être lus par le flux, à partir de la position actuelle.

Lorsque le flux atteint cette limite, il agit comme si la fin de l'entrée était atteinte jusqu'à ce que PopLimit() soit appelé.

Comme leurs noms l'indiquent, le concept de flux comporte une pile de limites. La limite la plus courte de la pile est toujours appliquée, même s'il ne s'agit pas de la limite supérieure.

La valeur renvoyée par PushLimit() est opaque pour l'appelant et doit être transmise telle quelle à l'appel correspondant de PopLimit().


void CodedInputStream::PopLimit(
        Limit limit)

Affiche la dernière limite appliquée par PushLimit().

L'entrée doit être la valeur renvoyée par cet appel à PushLimit().


void CodedInputStream::SetTotalBytesLimit(
        int total_bytes_limit)

Définit le nombre maximal d'octets lus par cet objet CodedInputStream avant de continuer.

Pour éviter que les serveurs allouent de grandes quantités de mémoire pour stocker les messages analysés, la longueur maximale des messages doit être limitée à la plus courte d'entre eux sans nuire à leur facilité d'utilisation. La limite par défaut est de INT_MAX (environ 2 Go), et les applications doivent définir des limites plus courtes si possible. Une erreur est toujours envoyée à stderr si la limite est atteinte.

Remarque: Si vous définissez une limite inférieure à la position de lecture actuelle, vous serez considéré comme une limite par rapport à la position actuelle.

Cela n'a aucun lien avec PushLimit()/PopLimit().


bool CodedInputStream::IncrementRecursionDepth()

Augmente la profondeur de récursion actuelle.

Renvoie la valeur "true" si la profondeur est inférieure à la limite, et la valeur "false" si elle a été dépassée.


void CodedInputStream::UnsafeDecrementRecursionDepth()

Décrémente la profondeur de récursion de manière aveugle.

Cette méthode est plus rapide que la règle DecrementRecursionDepth(). Ne doit être utilisée que si toutes les incréments précédents de la profondeur de récursion ont réussi.


std::pair< CodedInputStream::Limit, int >
    CodedInputStream::IncrementRecursionDepthAndPushLimit(
        int byte_limit)

Raccourci de make_pair(PushLimit(byte_limit), –recursion_budget_).

Cela peut réduire la taille et la complexité du code dans certains cas. L'appelant doit vérifier que la deuxième partie du résultat n'est pas négative (afin de s'éloigner si la profondeur de récursion est trop élevée) et, si tout se passe comme prévu, transmettre la première partie du résultat à PopLimit() ou une valeur similaire.


bool CodedInputStream::DecrementRecursionDepthAndPopLimit(
        Limit limit)

Outil d'aide équivalent à: { bool result = ConsumedFullscreenMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); return result; } Cela peut réduire la taille du code et sa complexité dans certains cas.

Ne l'utilisez que si la profondeur de récursion actuelle est supérieure à zéro.


void CodedInputStream::SetExtensionRegistry(
        const DescriptorPool * pool,
        MessageFactory * factory)

Définissez le pool utilisé pour rechercher les extensions.

La plupart des utilisateurs n'ont pas besoin d'appeler cette méthode, car le pool approprié sera choisi automatiquement.

AVERTISSEMENT: Il est très facile d'en faire un usage abusif. Lisez attentivement les exigences ci-dessous. Ne l'utilisez que si vous êtes sûr d'en avoir besoin. Presque personne.

Imaginons que vous analysez un message dans l'objet message m et que vous souhaitez tirer parti de SetExtensionRegistry(). Vous devez respecter les conditions suivantes:

La classe DescriptorPool doit contenir m->GetDescriptor(). Il ne suffit pas de contenir un descripteur ayant le même nom et le même contenu. Il doit s'agir de l'objet exact. Autrement dit :

assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) ==
       m->GetDescriptor());

Il existe deux façons de répondre à cette exigence: 1) Utiliser le pool m->GetDescriptor()->pool(). C'est généralement inutile

because this is the pool that would be used anyway if you didn't call
SetExtensionRegistry() at all.

2) Utilisez un pool DescriptorPool comportant m->GetDescriptor()->pool() comme

"underlay".  Read the documentation for DescriptorPool for more
information about underlays.

Vous devez également fournir un MessageFactory. Cette fabrique sera utilisée pour construire des objets Message représentant des extensions. La méthode GetPrototype() de l'usine DOIT renvoyer des valeurs non nulles pour tout descripteur accessible via le pool fourni.

Si la fabrique fournie peut renvoyer des instances de types générés par le compilateur de protocole (par exemple, compilées) ou si l'objet de message externe "m" est un type généré, alors l'usine donnée DOIT avoir cette propriété: si "GetPrototype()" reçoit un descripteur qui réside dans DescriptorPool::generated_pool(), la fabrique DOIT renvoyer le même prototype que MessageFactory::generated_factory(). Autrement dit, en fonction d'un descripteur pour un type généré, la fabrique doit renvoyer une instance de la classe générée (PAS DynamicMessage). Toutefois, si vous lui fournissez un descripteur pour un type qui ne se trouve PAS dans le pool généré, l'usine est libre de renvoyer toute mise en œuvre.

Cette exigence s'explique par le fait que les sous-objets générés sont accessibles via les méthodes d'accesseur d'extension standards (non-réflexion). Ces méthodes convertiront ensuite l'objet en type de classe généré. Si l'objet ne correspond pas à ce type, les résultats ne seront pas définis. En revanche, si une extension n'est pas compilée, le code ne pourra pas y accéder via les accesseurs standards. Le seul moyen d'y accéder est la réflexion. Lorsque vous utilisez la fonction de réflexion, DynamicMessage et les messages générés ne peuvent pas être distingués. Vous pouvez donc les représenter à l'aide de DynamicMessage.

L'utilisation de DynamicMessageFactory sur laquelle vous avez appelé SetDelegateToGeneratedFactory(true) devrait suffire pour satisfaire à l'exigence ci-dessus.

Si le pool ou la fabrique est défini sur NULL, les deux doivent être NULL.

Notez que cette fonctionnalité est ignorée lors de l'analyse des messages "allégés", car ils ne possèdent pas de descripteurs.

Classe EpsCopyOutputStream

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

EpsCopyOutputStream enveloppe un objet ZeroCopyOutputStream et expose un nouveau flux. La propriété vous permet d'écrire des kSlopBytes (16 octets) à partir de la position actuelle sans limites.

Le curseur dans le flux est géré par l'utilisateur de la classe et constitue un paramètre explicite dans les méthodes. En utilisant cette classe avec précaution, c'est-à-dire en conservant ptr une variable locale, il n'est pas nécessaire que le compilateur synchronise la valeur ptr entre le registre et la mémoire.

Membres

enum
@33
EpsCopyOutputStream(ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Initialiser un flux
EpsCopyOutputStream(void * data, int size, bool deterministic)
Uniquement pour la sérialisation des tableaux. plus...
EpsCopyOutputStream(void * data, int size, ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Initialisation à partir du flux, mais avec le premier tampon déjà fourni (exagéré)
uint8 *
Trim(uint8 * ptr)
Videz tout ce qui est écrit dans ZeroCopyOutputStream et coupez le flux sous-jacent à l'emplacement de ptr.
PROTOBUF_MUST_USE_RESULT uint8 *
EnsureSpace(uint8 * ptr)
Vous pouvez ensuite écrire en toute sécurité vos kSlopBytes sur ptr. plus...
uint8 *
WriteRaw(const void * data, int size, uint8 * ptr)
uint8 *
WriteRawMaybeAliased(const void * data, int size, uint8 * ptr)
Permet d'écrire le tampon spécifié par les données et sa taille dans le flux. plus...
uint8 *
WriteStringMaybeAliased(uint32 num, const std::string & s, uint8 * ptr)
uint8 *
WriteBytesMaybeAliased(uint32 num, const std::string & s, uint8 * ptr)
template uint8 *
WriteString(uint32 num, const T & s, uint8 * ptr)
template uint8 *
WriteBytes(uint32 num, const T & s, uint8 * ptr)
template uint8 *
WriteInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteUInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteSInt32Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteUInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteSInt64Packed(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteEnumPacked(int num, const T & r, int size, uint8 * ptr)
template uint8 *
WriteFixedPacked(int num, const T & r, uint8 * ptr)
bool
HadError() const
Renvoie la valeur "true" en cas d'erreur d'E/S sous-jacente depuis la création de l'objet.
void
EnableAliasing(bool enabled)
Ordonne à EpsCopyOutputStream de permettre à la classe ZeroCopyOutputStream sous-jacente de conserver les pointeurs vers la structure d'origine plutôt que de la copier, si elle est compatible avec (plus
void
SetSerializationDeterministic(bool value)
Consultez la documentation sur CodedOutputStream::SetSerializationDeterministic.
bool
IsSerializationDeterministic() const
Consultez la documentation sur CodedOutputStream::IsSerializationDeterministic.
int64
ByteCount(uint8 * ptr) const
Nombre d'octets écrits dans le flux à la position ptr, par rapport à la position globale du flux.
uint8 *
SetInitialBuffer(void * data, int size)
Ces méthodes sont destinées à CodedOutputStream. plus...

enum EpsCopyOutputStream::@33 {
  kSlopBytes = = 16
}

kSlopBytes

EpsCopyOutputStream::EpsCopyOutputStream(
        void * data,
        int size,
        bool deterministic)

Uniquement pour la sérialisation des tableaux.

Aucune protection contre les débordements n'est définie, end____ sera la pointe vers la fin du tableau. Lorsque vous utilisez cette valeur, la taille totale est déjà connue. Il n'est donc pas nécessaire de maintenir la région en pente.


PROTOBUF_MUST_USE_RESULT uint8 *
    EpsCopyOutputStream::EnsureSpace(
        uint8 * ptr)

Vous pouvez ensuite écrire en toute sécurité vos kSlopBytes sur ptr.

Cela ne échouera jamais ! Le flux sous-jacent peut générer une erreur. Utilisez HadError pour rechercher les erreurs.


uint8 * EpsCopyOutputStream::WriteRawMaybeAliased(
        const void * data,
        int size,
        uint8 * ptr)

Permet d'écrire le tampon spécifié par les données et sa taille dans le flux.

Il peut s'agir d'un alias du tampon (c'est-à-dire de ne pas copier les données). L'appelant doit s'assurer que la mémoire tampon est active pendant toute la durée de ZeroCopyOutputStream.


void EpsCopyOutputStream::EnableAliasing(
        bool enabled)

Ordonne à EpsCopyOutputStream de permettre à la classe ZeroCopyOutputStream sous-jacente de conserver les pointeurs vers la structure d'origine plutôt que de la copier, si elle est compatible avec

output->AllowsAliasing() défini sur "true"). Si le flux sous-jacent n'est pas compatible avec les alias, l'activation de ce flux n'a aucune incidence. Pour l'instant, cela ne concerne que le comportement de WriteRawPeutAliased().

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.


uint8 * EpsCopyOutputStream::SetInitialBuffer(
        void * data,
        int size)

Ces méthodes sont destinées à CodedOutputStream.

Idéalement, ils devraient être privés, mais pour correspondre au comportement actuel de CodedOutputStream le plus près possible, nous lui autorisons certaines fonctionnalités.

Classe CodedOutputStream

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

Classe qui encode et écrit des données binaires composées d'entiers encodés en variance et d'éléments à largeur fixe.

Encapsule un objet ZeroCopyOutputStream. La plupart des utilisateurs n'ont pas besoin de gérer CodedOutputStream.

La plupart des méthodes de CodedOutputStream qui renvoient un bool renvoient false si une erreur d'E/S sous-jacente se produit. Lorsqu'un tel échec se produit, le CodedOutputStream est interrompu et n'est plus utile. Les méthodes d'écriture ne renvoient pas l'état du flux, mais invalident le flux en cas d'erreur. Le client peut vérifier HadError() pour déterminer l'état.

Notez que chaque méthode de CodedOutputStream qui écrit certaines données possède une version "ToArray" statique correspondante. Ces versions écrivent directement dans le tampon fourni et renvoient un pointeur après le dernier octet écrit. Elles nécessitent que le tampon dispose d'une capacité suffisante pour les données encodées. Cela permet d'effectuer une optimisation : nous vérifions si un flux de sortie dispose de suffisamment d'espace pour un message entier avant de commencer à écrire. Le cas échéant, nous n'appelons que les méthodes ToArray pour éviter d'effectuer des contrôles liés pour chaque valeur individuelle, comme dans l'exemple ci-dessus :

CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
int magic_number = 1234;
char text[[]] = "Hello world!";

int coded_size = sizeof(magic_number) +
                 CodedOutputStream::VarintSize32(strlen(text)) +
                 strlen(text);

uint8* buffer =
    coded_output->GetDirectBufferForNBytesAndAdvance(coded_size);
if (buffer != nullptr) {
  // The output stream has enough space in the buffer: write directly to
  // the array.
  buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number,
                                                         buffer);
  buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer);
  buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer);
} else {
  // Make bound-checked writes, which will ask the underlying stream for
  // more space as needed.
  coded_output->WriteLittleEndian32(magic_number);
  coded_output->WriteVarint32(strlen(text));
  coded_output->WriteRaw(text, strlen(text));
}

delete coded_output;

Membres

explicit
CodedOutputStream(ZeroCopyOutputStream * stream)
Crée un CodedOutputStream qui écrit dans le ZeroCopyOutputStream donné.
CodedOutputStream(ZeroCopyOutputStream * stream, bool do_eager_refresh)
~CodedOutputStream()
Détruisez CodedOutputStream et positionnez ZeroCopyOutputStream sous-jacent immédiatement après le dernier octet écrit.
bool
HadError()
Renvoie la valeur "true" en cas d'erreur d'E/S sous-jacente depuis la création de l'objet. plus...
void
Trim()
Supprime les espaces inutilisés du tampon afin que sa taille corresponde au nombre d'octets écrits par ce flux. plus...
bool
Skip(int count)
Ignore un certain nombre d'octets, sans les modifier dans la mémoire tampon sous-jacente. plus...
bool
GetDirectBufferPointer(void ** data, int * size)
Définit les *données pour qu'elles pointent directement vers la partie non écrite du tampon sous-jacent de CodedOutputStream, et *fient la taille de ce tampon, sans pour autant avancer la position actuelle du flux. plus...
uint8 *
GetDirectBufferForNBytesAndAdvance(int size)
Si au moins la taille est indiquée dans le tampon actuel, renvoie un pointeur directement dans le tampon et avance sur ces octets. plus...
void
WriteRaw(const void * buffer, int size)
Écrire des octets bruts en les copiant à partir du tampon donné
void
WriteRawMaybeAliased(const void * data, int size)
Semblable à WriteRaw(), il essaie d'écrire des données avec un alias si l'alias est activé.
void
WriteString(const std::string & str)
Équivaut à WriteRaw(str.data(), str.size()).
void
WriteLittleEndian32(uint32 value)
Écrivez un entier de 32 bits en petit-endian.
void
WriteLittleEndian64(uint64 value)
Écrivez un entier end-endian de 64 bits.
void
WriteVarint32(uint32 value)
Écrivez un entier non signé avec un encodage Varint. plus...
void
WriteVarint64(uint64 value)
Écrivez un entier non signé avec un encodage Varint.
void
WriteVarint32SignExtended(int32 value)
Équivaut à WriteVarint32(), sauf lorsque la valeur est négative. Dans ce cas, elle doit être étendue à 10 octets complets.
void
WriteTag(uint32 value)
Identique à WriteVarint32(), mais optimisé pour l'écriture de tags. plus...
int
ByteCount() const
Renvoie le nombre total d'octets écrits depuis la création de cet objet.
void
EnableAliasing(bool enabled)
Ordonne à CodedOutputStream de permettre à ZeroCopyOutputStream sous-jacent de conserver les pointeurs vers la structure d'origine au lieu de copier s'il est compatible (c'est-à-dire plus
void
SetSerializationDeterministic(bool value)
Indique au sérialiseur si l'utilisateur veut une sérialisation derministe. plus...
bool
IsSerializationDeterministic() const
Indique si l'utilisateur souhaite la sérialisation déterministe. Voir ci-dessus
template void
Serialize(const Func & func)
uint8 *
Cur() const
void
SetCur(uint8 * ptr)
EpsCopyOutputStream *
EpsCopy()
static uint8 *
WriteRawToArray(const void * buffer, int size, uint8 * target)
Semblable à WriteRaw(), mais écrivant directement dans le tableau cible. plus...
static uint8 *
WriteStringToArray(const std::string & str, uint8 * target)
Semblable à WriteString(), mais écriture directe dans le tableau cible.
static uint8 *
WriteStringWithSizeToArray(const std::string & str, uint8 * target)
Écrivez la taille de str encodée par variable, suivie de str.
static uint8 *
WriteLittleEndian32ToArray(uint32 value, uint8 * target)
Semblable à WriteLittleEndian32(), mais écrivant directement dans le tableau cible.
static uint8 *
WriteLittleEndian64ToArray(uint64 value, uint8 * target)
Semblable à WriteLittleEndian64(), mais écrivant directement dans le tableau cible.
static uint8 *
WriteVarint32ToArray(uint32 value, uint8 * target)
Semblable à WriteVarint32(), mais l'écriture directe dans le tableau cible.
static uint8 *
WriteVarint32ToArrayOutOfLine(uint32 value, uint8 * target)
Semblable à WriteVarint32(), mais écrivant directement dans le tableau cible, avec les cas moins courants en dehors de la ligne et non intégrés.
static uint8 *
WriteVarint64ToArray(uint64 value, uint8 * target)
Semblable à WriteVarint64(), mais l'écriture directe dans le tableau cible.
static uint8 *
WriteVarint32SignExtendedToArray(int32 value, uint8 * target)
Semblable à WriteVarint32SignExtended(), mais l'écriture directe dans le tableau cible.
static uint8 *
WriteTagToArray(uint32 value, uint8 * target)
Semblable à WriteTag(), mais écriture directe dans le tableau cible.
static size_t
VarintSize32(uint32 value)
Renvoie le nombre d'octets nécessaires pour encoder la valeur donnée en tant que variable.
static size_t
VarintSize64(uint64 value)
Renvoie le nombre d'octets nécessaires pour encoder la valeur donnée en tant que variable.
static size_t
VarintSize32SignExtended(int32 value)
Si négatif, 10 octets. Sinon, identique à VarintSize32().
static bool
IsDefaultSerializationDeterministic()

bool CodedOutputStream::HadError()

Renvoie la valeur "true" en cas d'erreur d'E/S sous-jacente depuis la création de l'objet.

Activée doit appeler Trim avant cette fonction afin de détecter toutes les erreurs.


void CodedOutputStream::Trim()

Supprime les espaces inutilisés du tampon afin que sa taille corresponde au nombre d'octets écrits par ce flux.

Le tampon sous-jacent est automatiquement coupé lorsque le flux est détruit. Cet appel n'est nécessaire que si le tampon sous-jacent est consulté avant la destruction du flux.


bool CodedOutputStream::Skip(
        int count)

Ignore un certain nombre d'octets, sans les modifier dans la mémoire tampon sous-jacente.

Affiche la valeur "false" si une erreur d'écriture sous-jacente se produit. Cela est principalement utile avec GetDirectBufferPointer(). Attention, les octets ignorés peuvent contenir des données non initialisées. L'appelant doit s'assurer que les octets ignorés sont correctement initialisés. Dans le cas contraire, vous risquez de perdre des octets de votre segment de mémoire.


bool CodedOutputStream::GetDirectBufferPointer(
        void ** data,
        int * size)

Définit les *données pour qu'elles pointent directement vers la partie non écrite du tampon sous-jacent de CodedOutputStream, et *fient la taille de ce tampon, sans pour autant avancer la position actuelle du flux.

Cela génère toujours un tampon non vide ou renvoie la valeur "false". Si l'appelant écrit des données dans ce tampon, il doit ensuite appeler Skip() pour ignorer les octets consommés. Cela peut être utile pour implémenter des routines de sérialisation rapide externes pour des types de données non couverts par l'interface CodedOutputStream.


uint8 * CodedOutputStream::GetDirectBufferForNBytesAndAdvance(
        int size)

Si au moins la taille est indiquée dans le tampon actuel, renvoie un pointeur directement dans le tampon et avance sur ces octets.

L'appelant peut ensuite écrire directement dans ce tampon (par exemple, à l'aide des méthodes statiques *ToArray) au lieu de passer par CodedOutputStream. Si le nombre d'octets disponibles est insuffisant, la valeur renvoyée est NULL. Le pointeur de retour n'est plus valide dès qu'une autre méthode non-const de CodedOutputStream est appelée.


void CodedOutputStream::WriteVarint32(
        uint32 value)

Écrivez un entier non signé avec un encodage Varint.

Écrire une valeur 32 bits équivaut à la convertir en uint64 et en 64 bits, mais peut s'avérer plus efficace.


void CodedOutputStream::WriteTag(
        uint32 value)

Identique à WriteVarint32(), mais optimisé pour l'écriture de tags.

En particulier, si l'entrée est une constante connue à la compilation, cette méthode se compile en quelques instructions. Toujours intégrée, car l'optimisation susmentionnée ne peut pas fonctionner, mais GCC ne souhaite pas l'intégrer par défaut.


void CodedOutputStream::EnableAliasing(
        bool enabled)

Ordonne à CodedOutputStream de permettre à ZeroCopyOutputStream sous-jacent de conserver les pointeurs vers la structure d'origine au lieu de copier s'il l'est (par exemple,

output->AllowsAliasing() défini sur "true"). Si le flux sous-jacent n'est pas compatible avec les alias, l'activation de ce flux n'a aucune incidence. Pour l'instant, cela ne concerne que le comportement de WriteRawPeutAliased().

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.


void CodedOutputStream::SetSerializationDeterministic(
        bool value)

Indique au sérialiseur si l'utilisateur veut une sérialisation derministe.

La valeur par défaut lorsque cette valeur n'est pas appelée provient de la valeur globale par défaut, contrôlée par la règle SetDefaultSerializationDeterministic.

Ce que signifie la sérialisation déterministe dépend entièrement du pilote du processus de sérialisation (c'est-à-dire de l'appelant de méthodes telles que WriteVarint32). Dans le cas de la sérialisation d'un message proto tampon à l'aide de l'une des méthodes de MessageLite, cela signifie que pour un binaire donné, les messages égaux seront toujours sérialisés avec les mêmes octets. Entre autres :

Repeated serialization of a message will return the same bytes.

Different processes running the same binary (including on different
machines) will serialize equal messages to the same bytes.

Notez qu'il ne s'agit pas d'une URL canonique. Elle est également instable entre différentes versions avec des modifications apportées à la définition des messages, en raison de champs inconnus. Les utilisateurs ayant besoin d'une sérialisation canonique (par exemple, stockage persistant sous forme canonique ou empreinte digitale) doivent définir leurs propres spécifications de mise en forme canonique et implémenter le sérialiseur à l'aide d'API de réflexion plutôt que d'utiliser cette API.


static uint8 * CodedOutputStream::WriteRawToArray(
        const void * buffer,
        int size,
        uint8 * target)

Semblable à WriteRaw(), mais écrivant directement dans le tableau cible.

Cela n'est pas intégré, car le compilateur optimise souvent le protocole MEMCH dans les boucles de copie intégrées. Étant donné que cette fonction est appelée par chaque champ de type chaîne ou octets, l'intégration peut entraîner une surcharge importante du code, avec seulement un léger gain de performances.

modèle de structure CodedOutputStream::StaticVarintSize32

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

template <typename Value>

Équivalent de compilation de VarintSize32().

Membres

const size_t
value = = (Value < (1 << 7)) ? 1 : (Value < (1 << 14)) ? 2 : (Value < (1 << 21)) ? 3 : (Value < (1 << 28)) ? 4 : 5