OBSERVAÇÃO:este site foi descontinuado. O site será desativado após 31 de janeiro de 2023, e o tráfego será redirecionado para o novo site em https://protobuf.dev. Enquanto isso, as atualizações serão feitas apenas para protobuf.dev.

stream_codificado.h

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

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

Esse arquivo contém as classes CodedInputStream e CodedOutputStream, que envolvem um ZeroCopyInputStream ou ZeroCopyOutputStream, respectivamente, e permitem a leitura ou gravação de dados individuais em vários formatos.

Em especial, eles implementam a codificação varint para números inteiros, uma codificação simples de comprimento variável em que números menores precisam de menos bytes.

Normalmente, essas classes são usadas internamente pela biblioteca do buffer de protocolo para codificar e decodificar buffers de protocolo. Os clientes da biblioteca só precisam saber sobre essa classe se quiserem escrever procedimentos personalizados de análise ou serialização de mensagens.

Exemplo de 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);

Exemplo de 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;

Para quem tiver interesse, a codificação varint é definida da seguinte maneira:

A codificação opera em números inteiros não assinados de até 64 bits de comprimento. Cada byte do valor codificado tem o formato:

  • bits 0-6: sete bits do número que está sendo codificado.
  • bit 7: zero se este for o último byte na codificação (nesse caso, todos os bits restantes do número serão zero) ou 1 se mais bytes seguirem. O primeiro byte contém os sete bits menos significativos, o segundo (se estiver presente) contém os sete menos significativos, e assim por diante. Portanto, o número binário 1011000101011 seria codificado em dois bytes como "10101011 00101100".

Teoricamente, varint pode ser usado para codificar números inteiros de qualquer tamanho. No entanto, para praticar, definimos um limite de 64 bits. Portanto, o comprimento máximo codificado de um número é de 10 bytes.

Turmas neste arquivo

Classe que lê e decodifica dados binários compostos por números inteiros codificados por varint e partes de largura fixa.
EpsCopyOutputStream envolve um ZeroCopyOutputStream e expõe um novo fluxo, que tem a propriedade que permite gravar kSlopBytes (16 bytes) da posição atual sem verificações de limites.
Classe que codifica e grava dados binários compostos por números inteiros codificados por varint e partes de largura fixa.
Equivalente a tempo de compilação de VarintSize32().

classe CodedInputStream

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

Classe que lê e decodifica dados binários compostos por números inteiros codificados por varint e partes de largura fixa.

Encapsula um ZeroCopyInputStream. A maioria dos usuários não precisará lidar com o CodedInputStream.

A maioria dos métodos de CodedInputStream que retornam um booleano retornam "false" se ocorrer um erro de E/S ou se os dados estiverem malformados. Após essa falha, o CodedInputStream fica corrompido e não é mais útil. Após uma falha, os autores da chamada também devem presumir que podem ocorrer gravações em "out" argumentos, embora nada útil possa ser determinado com base nessas gravações.

Participantes

explicit
CodedInputStream(ZeroCopyInputStream * input)
Cria um CodedInputStream que lê o ZeroCopyInputStream fornecido.
explicit
CodedInputStream(const uint8 * buffer, int size)
Crie um CodedInputStream que faça leituras na matriz plana especificada. mais...
~CodedInputStream()
Destrua o CodedInputStream e posicione o ZeroCopyInputStream subjacente no primeiro byte não lido. mais...
bool
IsFlat() const
Retornará verdadeiro se esse CodedInputStream ler de uma matriz plana em vez de um ZeroCopyInputStream.
bool
Skip(int count)
Ignora vários bytes. mais…
bool
GetDirectBufferPointer(const void ** data, int * size)
Define *dados a apontar diretamente para a parte não lida do buffer subjacente do CodedInputStream e *dimensiona para o tamanho desse buffer, mas não avança a posição atual do stream. mais...
void
GetDirectBufferPointerInline(const void ** data, int * size)
Semelhante a GetDirectBufferPointer, mas esse método é in-line e não tentará Refresh() se o buffer estiver vazio no momento.
bool
ReadRaw(void * buffer, int size)
Lê bytes brutos, copiando-os para o buffer especificado.
bool
ReadString(std::string * buffer, int size)
Como ReadRead, mas lê em uma string.
bool
ReadLittleEndian32(uint32 * value)
Leia um número inteiro bit-endian de 32 bits.
bool
ReadLittleEndian64(uint64 * value)
Ler um número inteiro de end-end de 64 bits.
bool
ReadVarint32(uint32 * value)
Leia um número inteiro não assinado com a codificação Varint, truncando para 32 bits. mais…
bool
ReadVarint64(uint64 * value)
Ler um número inteiro não assinado com a codificação Varint.
bool
ReadVarintSizeAsInt(int * value)
Lê uma variedade do fio em uma "int". mais…
uint32
ReadTag()
Ler uma tag. mais…
uint32
ReadTagNoLastTag()
std::pair< uint32, bool >
ReadTagWithCutoff(uint32 cutoff)
Essa geralmente é uma alternativa mais rápida a ReadTag() quando o corte é uma constante de manifesto. mais...
std::pair< uint32, bool >
ReadTagWithCutoffNoLastTag(uint32 cutoff)
bool
ExpectTag(uint32 expected)
Geralmente, é verdadeiro se a chamada de ReadVarint32() gerar o valor informado. mais...
bool
ExpectAtEnd()
Geralmente retorna verdadeiro se não for possível ler mais bytes. mais…
bool
LastTagWas(uint32 expected)
Se a última chamada para ReadTag() ou ReadTagWithCutoff() retornar o valor informado, retornará "true". mais...
void
SetLastTag(uint32 tag)
bool
ConsumedEntireMessage()
Ao analisar uma mensagem (mas NÃO um grupo), esse método precisa ser chamado imediatamente depois que MergeFromCodedStream() retornar (se retornar verdadeiro) para verificar melhor se a mensagem terminou de maneira legítima. mais…
void
SetConsumed()
static const uint8 *
ReadLittleEndian32FromArray(const uint8 * buffer, uint32 * value)
Esses métodos leem um buffer fornecido externamente. mais…
static const uint8 *
ReadLittleEndian64FromArray(const uint8 * buffer, uint64 * value)
Ler um número inteiro de end-end de 64 bits. mais…
static const uint8 *
ExpectTagFromArray(const uint8 * buffer, uint32 expected)
Como acima, exceto pelo leitura do buffer especificado. mais…

Limites

Os limites são usados ao analisar mensagens incorporadas delimitadas por comprimento. Depois que a mensagem for lida, PushLimit() será usado para evitar que o CodedInputStream leia além desse tamanho. Depois que a mensagem incorporada for analisada, PopLimit() será chamado para desfazer o limite.
typedef
int Limit
Tipo opaco usado com PushLimit() e PopLimit(). Mais...
Limit
PushLimit(int byte_limit)
Aplica um limite ao número de bytes que o stream pode ler, começando pela posição atual. mais…
void
PopLimit(Limit limit)
Mostra o último limite enviado por PushLimit(). mais...
int
BytesUntilLimit() const
Retornará o número de bytes restantes até o limite mais próximo na pilha ser atingido, ou -1 se não houver nenhum limite.
int
CurrentPosition() const
Retorna a posição atual em relação ao início do stream de entrada.

Limite total de bytes

Para evitar que usuários mal-intencionados enviem mensagens muito grandes e causem esgotamento de memória, o CodedInputStream impõe um limite rígido para o número total de bytes lidos.
int = { SetTotalBytesLimit(total_bytes_limit)
void
SetTotalBytesLimit(int total_bytes_limit)
Define o número máximo de bytes que esse CodedInputStream lerá antes de se recusar a continuar. mais...
PROTOBUF_DEPRECATED_MSG("Please use the single parameter version of SetTotalBytesLimit(). The " "second parameter is ignored." )
int
BytesUntilTotalBytesLimit() const
O limite total de bytes menos a posição atual, ou -1 se o limite total de bytes for INT_MAX.

Limite de recursão

Para evitar que mensagens corrompidas ou maliciosas causem estouro de pilha, precisamos acompanhar a profundidade da recursão ao analisar mensagens e grupos incorporados.

CodedInputStream acompanha isso porque é o único objeto transmitido para a pilha durante a análise.

void
SetRecursionLimit(int limit)
Define a profundidade máxima de recursão. O padrão é 100.
int
RecursionBudget()
bool
IncrementRecursionDepth()
Incrementa a profundidade de recursão atual. mais…
void
DecrementRecursionDepth()
Diminui a profundidade da recursão, se possível.
void
UnsafeDecrementRecursionDepth()
Diminui a profundidade da recursão cegamente. mais…
std::pair< CodedInputStream::Limit, int >
IncrementRecursionDepthAndPushLimit(int byte_limit)
Abreviação de make_pair(PushLimit(byte_limit), –recursion_budget_). mais…
Limit
ReadLengthAndPushLimit()
Abreviação de PushLimit(ReadVarint32(&length) ? comprimento : 0).
bool
DecrementRecursionDepthAndPopLimit(Limit limit)
Assistente que é equivalente a: { bool result = ConsumedFullMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); result result; } Isso pode reduzir o tamanho e a complexidade do código em alguns casos. mais...
bool
CheckEntireMessageConsumedAndPopLimit(Limit limit)
Assistente que é equivalente a: { bool result = ConsumedFullMessage(); PopLimit(limit); return result; } Isso pode reduzir o tamanho e a complexidade do código em alguns casos.
static int
GetDefaultRecursionLimit()

Registro de extensões

USO AVANÇADO: 99,9% das pessoas podem ignorar esta seção.

Por padrão, ao analisar extensões, o analisador procura definições de extensão no pool que é proprietário do Descriptor da mensagem externa. No entanto, é possível chamar SetExtensionRegistry() para fornecer um pool alternativo. Isso permite, por exemplo, analisar uma mensagem usando uma classe gerada, mas representar algumas extensões usando o DynamicMessage.

void
SetExtensionRegistry(const DescriptorPool * pool, MessageFactory * factory)
Defina o pool usado para procurar extensões. mais…
const DescriptorPool *
GetExtensionPool()
Defina o DescriptorPool definido por SetExtensionRegistry() ou NULL se nenhum pool tiver sido fornecido.
MessageFactory *
GetExtensionFactory()
Acessa o MessageFactory definido por SetExtensionRegistry() ou NULL se nenhuma fábrica tiver sido fornecida.

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

Crie um CodedInputStream que faça leituras na matriz plana especificada.

Isso é mais rápido do que usar um ArrayInputStream. PushLimit(size) está implícito neste construtor.


CodedInputStream::~CodedInputStream()

Destrua o CodedInputStream e posicione o ZeroCopyInputStream subjacente no primeiro byte não lido.

Se ocorrer um erro durante a leitura (causa um método para retornar falso), a posição exata do stream de entrada poderá estar em qualquer lugar entre o último valor que foi lido e o limite de bytes do stream.


bool CodedInputStream::Skip(
        int count)

Ignora vários bytes.

Retorna "false" se ocorrer um erro de leitura.


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

Define *dados a apontar diretamente para a parte não lida do buffer subjacente do CodedInputStream e *dimensiona para o tamanho desse buffer, mas não avança a posição atual do stream.

Isso sempre produzirá um buffer não vazio ou retornará "false". Se o autor da chamada consumir qualquer um desses dados, ele precisará chamar Skip() para pular os bytes consumidos. Isso pode ser útil para implementar rotinas de análise rápida externa para tipos de dados não cobertos pela interface CodedInputStream.


bool CodedInputStream::ReadVarint32(
        uint32 * value)

Leia um número inteiro não assinado com a codificação Varint, truncando para 32 bits.

Ler um valor de 32 bits é equivalente a ler um valor de 64 bits e convertê-lo em uint32, mas pode ser mais eficiente.


bool CodedInputStream::ReadVarintSizeAsInt(
        int * value)

Lê uma variedade do fio em uma "int".

Ele deve ser usado para ler tamanhos fora da transmissão (tamanhos de strings, submensagens, campos de bytes etc.).

O valor do fio é interpretado como não assinado. Se o valor dela exceder o valor representável de um número inteiro nessa plataforma, em vez de truncar, retornaremos falso. O truncamento (como feito por ReadVarint32() acima) é uma abordagem aceitável para campos que representam um número inteiro, mas quando analisamos um tamanho do fio, truncar o valor resultaria na separação do payload.


uint32 CodedInputStream::ReadTag()

Ler uma tag.

Isso chama ReadVarint32() e retorna o resultado ou retorna zero (que não é uma tag válida) se ReadVarint32() falhar. Além disso, ReadTag, mas não ReadTagNoLastTag, atualiza o último valor da tag, que pode ser verificado com LastTagWas().

Sempre inline, porque isso é chamado apenas em um lugar por loop de análise, mas é chamado para cada iteração desse loop, portanto, deve ser rápido. O GCC não quer fazer a inserção in-line por padrão.


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

Essa geralmente é uma alternativa mais rápida a ReadTag() quando o corte é uma constante de manifesto.

Ele funciona muito bem para cortes maiores que 127. A primeira parte do valor de retorno é a tag que foi lida, embora também possa ser 0 nos casos em que ReadTag() retorna 0. Se a segunda parte for verdadeira, a tag estará em [[]0, cutoff]. Caso contrário, a tag estará acima do limite ou será 0. Há espaço intencional quando a tag é 0, porque isso pode surgir de várias maneiras. Para um melhor desempenho, queremos evitar a marcação "tag == 0?" extra aqui.


bool CodedInputStream::ExpectTag(
        uint32 expected)

Geralmente, é verdadeiro se a chamada de ReadVarint32() gerar o valor informado.

Sempre retornará "false" se ReadVarint32() não retornar o valor informado. Se ExpectTag() retornar "true", ela também vai além do varint. Para ter o melhor desempenho, use uma constante de tempo de compilação como parâmetro. Sempre in-line porque essa opção se fecha para um pequeno número de instruções quando recebe um parâmetro constante, mas o GCC não quer in-line por padrão


bool CodedInputStream::ExpectAtEnd()

Geralmente retorna verdadeiro se não for possível ler mais bytes.

Sempre retornará "false" se for possível ler mais bytes. Se ExpectAtEnd() retornar "true", uma chamada subsequente para LastTagWas() atuará como se ReadTag() tivesse sido chamada e retornado zero, e ConsumedFullMessage() retornará "true".


bool CodedInputStream::LastTagWas(
        uint32 expected)

Se a última chamada para ReadTag() ou ReadTagWithCutoff() retornar o valor informado, retornará "true".

Caso contrário, retorna "false". ReadTagNoLastTag/ReadTagWithCutoffNoLastTag não preservam o último valor retornado.

Isso é necessário porque os analisadores de alguns tipos de mensagens incorporadas (com o tipo de campo TYPE_GROUP) não sabem que chegaram ao final de uma mensagem até que vejam uma tag ENDGROUP, que, na verdade, fazia parte da mensagem de inclusão. A mensagem presente quer verificar se essa tag tem o número correto. Portanto, ela chama LastTagWas() no retorno do analisador incorporado para verificar.


bool CodedInputStream::ConsumedEntireMessage()

Ao analisar uma mensagem (mas NÃO um grupo), esse método precisa ser chamado imediatamente depois que MergeFromCodedStream() retornar (se retornar verdadeiro) para verificar melhor se a mensagem terminou de maneira legítima.

Por exemplo, isso verifica se a análise não terminou em uma tag de grupo final. Ela também verifica alguns casos em que, devido a otimizações, MergeFromCodedStream() pode retornar "true" incorretamente.


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

Esses métodos leem um buffer fornecido externamente.

static

O autor da chamada é responsável por garantir que o buffer tenha espaço suficiente. Leia um número inteiro bit-endian de 32 bits.


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

Ler um número inteiro de end-end de 64 bits.

static


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

Como acima, exceto pelo leitura do buffer especificado.

O autor da chamada é responsável por garantir que o buffer seja grande o suficiente para ler uma variedade do tamanho esperado. Para ter o melhor desempenho, use uma constante de tempo de compilação como parâmetro de tag esperado.

Retorna um ponteiro além da tag esperada, se ela tiver sido encontrada, ou NULL, caso não tenha sido.


typedef CodedInputStream::Limit

Tipo opaco usado com PushLimit() e PopLimit().

Não modifique valores desse tipo por conta própria. A única razão para isso não ser uma estrutura com componentes internos particulares é a eficiência.


Limit CodedInputStream::PushLimit(
        int byte_limit)

Aplica um limite ao número de bytes que o stream pode ler, começando pela posição atual.

Quando o stream atinge esse limite, ele funciona como o fim da entrada até que PopLimit() seja chamado.

Como os nomes indicam, o stream tem uma pilha conceitualmente de limites. O limite mais curto na pilha é sempre aplicado, mesmo que não seja o limite superior.

O valor retornado por PushLimit() é opaco para o autor da chamada e precisa ser transmitido para a chamada correspondente para PopLimit().


void CodedInputStream::PopLimit(
        Limit limit)

Exibe o último limite enviado por PushLimit().

A entrada precisa ser o valor retornado por essa chamada para PushLimit().


void CodedInputStream::SetTotalBytesLimit(
        int total_bytes_limit)

Define o número máximo de bytes que esse CodedInputStream lerá antes de se recusar a continuar.

Para evitar que os servidores aloquem quantidades enormes de memória para reter mensagens analisadas, o comprimento máximo da mensagem deve ser limitado ao tamanho mais curto possível, sem prejudicar a usabilidade. O limite padrão é INT_MAX (cerca de 2 GB), e os apps devem definir limites mais curtos, se possível. Um erro sempre será exibido no stderr se o limite for atingido.

Observação: definir um limite inferior à posição atual de leitura é interpretado como um limite na posição atual.

Isso não está relacionado a PushLimit()/PopLimit().


bool CodedInputStream::IncrementRecursionDepth()

Incrementa a profundidade de recursão atual.

Retorna "true" se a profundidade estiver abaixo do limite e "false" se a profundidade foi ultrapassada.


void CodedInputStream::UnsafeDecrementRecursionDepth()

Diminui a profundidade da recursão cegamente.

Isso é mais rápido que DecrementRecursionDepth(). Só deve ser usado se todos os acréscimos anteriores à profundidade de recursão tiveram êxito.


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

Abreviação de make_pair(PushLimit(byte_limit), –recursion_budget_).

Isso pode reduzir o tamanho e a complexidade do código em alguns casos. É esperado que o autor da chamada verifique se a segunda parte do resultado não é negativa, para abandonar se a profundidade de recursão é muito alta, e, se tudo estiver certo, para transmitir a primeira parte do resultado para PopLimit() ou semelhante.


bool CodedInputStream::DecrementRecursionDepthAndPopLimit(
        Limit limit)

Assistente que é equivalente a: { bool result = ConsumedFullMessage(); PopLimit(limit); UnsafeDecrementRecursionDepth(); result result; } Isso pode reduzir o tamanho e a complexidade do código em alguns casos.

Não use a menos que a profundidade de recursão atual seja maior que zero.


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

Defina o pool usado para procurar extensões.

A maioria dos usuários não precisa chamar esse método, porque o pool correto será escolhido automaticamente.

AVISO: é muito fácil fazer uso indevido desse recurso. Leia com atenção os requisitos abaixo. Não use a menos que você tenha certeza de que precisa dele. Quase ninguém faz isso.

Digamos que você esteja analisando uma mensagem no objeto de mensagem m e queira aproveitar o SetExtensionRegistry(). Você precisa atender a estes requisitos:

O DescriptorPool fornecido precisa conter m->GetDescriptor(). Não basta ter um descritor com o mesmo nome e conteúdo, ele precisa ser o objeto exato. Resumindo:

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

Há duas maneiras de atender a esse requisito: 1) Usar m->GetDescriptor()->pool() como o pool. Em geral, isso é inútil

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

2) Use um DescriptorPool que tenha m->GetDescriptor()->pool() como

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

Também é necessário informar um MessageFactory. Essa fábrica será usada para construir objetos Message que representam extensões. O GetPrototype() da fábrica PRECISA retornar não NULL para qualquer Descriptor que possa ser encontrado por meio do pool fornecido.

Se a fábrica fornecida puder retornar instâncias de tipos gerados pelo compilador de protocolo (ou seja, compilados) ou se o objeto de mensagem externo m for um tipo gerado, a fábrica fornecida PRECISA ter essa propriedade: se GetPrototype() receber um Descriptor que reside em DescriptorPool::Generated_pool(), a fábrica PRECISA retornar o mesmo protótipo que MessageFactory::Generated_factory() retornaria. Ou seja, com um descritor para um tipo gerado, a fábrica precisa retornar uma instância da classe gerada (NOT DynamicMessage). No entanto, quando recebe um descritor para um tipo que NÃO está em generate_pool, a fábrica é livre para retornar qualquer implementação.

O motivo para esse requisito é que os subobjetos gerados podem ser acessados usando os métodos do acessador de extensão padrão (não reflexão), e esses métodos transmitirão o objeto para o tipo de classe gerado. Se o objeto não for desse tipo, os resultados serão indefinidos. Por outro lado, se uma extensão não for compilada, não há como o código possa acessá-la pelos acessadores padrão. A única maneira de acessar a extensão é por reflexão. Ao usar a reflexão, o DynamicMessage e as mensagens geradas são indistinguíveis. Portanto, não há problema se esses objetos forem representados usando DynamicMessage.

Usar DynamicMessageFactory no qual você chamou SetDelegateToGeneratedFactory(true) deve ser suficiente para atender ao requisito acima.

Se o pool ou a fábrica for NULL, ambos precisarão ser NULL.

Observe que esse recurso é ignorado ao analisar mensagens "lite", já que elas não têm descritores.

classe EpsCopyOutputStream

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

EpsCopyOutputStream envolve um ZeroCopyOutputStream e expõe um novo fluxo, que tem a propriedade que permite gravar kSlopBytes (16 bytes) da posição atual sem verificações de limites.

O cursor no stream é gerenciado pelo usuário da classe e é um parâmetro explícito nos métodos. O uso cuidadoso dessa classe, ou seja, mantém o ptr uma variável local, elimina a necessidade de o compilador sincronizar o valor do ptr entre registro e memória.

Participantes

enum
@33
EpsCopyOutputStream(ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Inicializar a partir de um stream.
EpsCopyOutputStream(void * data, int size, bool deterministic)
Apenas para serialização de matrizes. mais…
EpsCopyOutputStream(void * data, int size, ZeroCopyOutputStream * stream, bool deterministic, uint8 ** pp)
Inicialize a partir do stream, mas com o primeiro buffer já fornecido (com antecedência).
uint8 *
Trim(uint8 * ptr)
Limpe tudo que está escrito em ZeroCopyOutputStream subjacente e recorte o stream subjacente para a localização do ptr.
PROTOBUF_MUST_USE_RESULT uint8 *
EnsureSpace(uint8 * ptr)
Depois disso, é possível gravar com segurança kSlopBytes em ptr. mais…
uint8 *
WriteRaw(const void * data, int size, uint8 * ptr)
uint8 *
WriteRawMaybeAliased(const void * data, int size, uint8 * ptr)
Grava o buffer especificado por dados, tamanho no stream. mais…
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
Retornará "true" se houver um erro de E/S subjacente desde que o objeto foi criado.
void
EnableAliasing(bool enabled)
Instrui o EpsCopyOutputStream a permitir que o ZeroCopyOutputStream subjacente contenha ponteiros para a estrutura original em vez de copiar, se houver suporte (ou seja, mais...
void
SetSerializationDeterministic(bool value)
Consulte a documentação sobre CodedOutputStream::SetSerializationDeterministic.
bool
IsSerializationDeterministic() const
Consulte a documentação sobre CodedOutputStream::IsSerializationDeterministic.
int64
ByteCount(uint8 * ptr) const
O número de bytes gravados no stream na posição ptr, em relação à posição geral do stream.
uint8 *
SetInitialBuffer(void * data, int size)
Esses métodos são para CodedOutputStream. mais...

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

kSlopBytes

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

Apenas para serialização de matrizes.

Sem proteção de estouro, end_ será o apontado para o fim da matriz. Ao usar esse atributo, o tamanho total já é conhecido. Portanto, não é necessário manter a região inclinada.


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

Depois disso, é possível gravar com segurança kSlopBytes em ptr.

Isso nunca vai falhar. O stream subjacente pode gerar erros. Use o HadError para verificar se há erros.


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

Grava o buffer especificado por dados, tamanho no stream.

Possibilidade de criar um alias do buffer (ou seja, não copiar os dados). O autor da chamada é responsável por garantir que o buffer esteja ativo durante o ZeroCopyOutputStream.


void EpsCopyOutputStream::EnableAliasing(
        bool enabled)

Instrui o EpsCopyOutputStream a permitir que o ZeroCopyOutputStream subjacente contenha ponteiros para a estrutura original em vez de copiar, se houver suporte (ou seja,

output->AllowsAliasing() for verdadeiro). Se a transmissão não for compatível com alias, a ativação não terá efeito. Por enquanto, isso afeta apenas o comportamento de WriteRawTalvezAliased().

OBSERVAÇÃO: é responsabilidade do autor da chamada garantir que o bloco de memória permaneça ativo até que todos os dados tenham sido consumidos pelo stream.


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

Esses métodos são para CodedOutputStream.

O ideal é que sejam privados, mas, para corresponder ao comportamento atual do CodedOutputStream o mais próximo possível, permitimos algumas funcionalidades.

classe CodedOutputStream

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

Classe que codifica e grava dados binários compostos por números inteiros codificados por varint e partes de largura fixa.

Encapsula um ZeroCopyOutputStream. A maioria dos usuários não precisará lidar com o CodedOutputStream.

A maioria dos métodos de CodedOutputStream, que retornam um booleano, retornam "false" se ocorrer um erro de E/S. Após essa falha, o CodedOutputStream fica corrompido e não é mais útil. Os métodos Write* não retornam o status de stream, mas invalidam o stream se ocorrer um erro. O cliente pode sondar HadError() para determinar o status.

Observe que cada método de CodedOutputStream, que grava alguns dados, tem uma versão "ToArray" estática correspondente. Essas versões gravam diretamente no buffer fornecido, retornando um ponteiro após o último byte escrito. Eles exigem que o buffer tenha capacidade suficiente para os dados codificados. Isso permite uma otimização em que conferimos se um stream de saída tem espaço suficiente para uma mensagem inteira antes de começarmos a escrever. Se houver, chamaremos somente os métodos ToArray para evitar fazer verificações vinculadas a cada valor individual, ou seja, no exemplo acima:

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;

Participantes

explicit
CodedOutputStream(ZeroCopyOutputStream * stream)
Cria um CodedOutputStream que grava no ZeroCopyOutputStream especificado.
CodedOutputStream(ZeroCopyOutputStream * stream, bool do_eager_refresh)
~CodedOutputStream()
Destrua o CodedOutputStream e posicione o ZeroCopyOutputStream subjacente imediatamente após o último byte escrito.
bool
HadError()
Retornará "true" se houver um erro de E/S subjacente desde que o objeto foi criado. mais…
void
Trim()
Corta qualquer espaço não utilizado no buffer subjacente para que o tamanho corresponda ao número de bytes gravados por esse stream. mais…
bool
Skip(int count)
Ignora vários bytes, deixando os bytes inalterados no buffer subjacente. mais…
bool
GetDirectBufferPointer(void ** data, int * size)
Define *dados a apontar diretamente para a parte não escrita do buffer subjacente de CodedOutputStream e *dimensiona para o tamanho desse buffer, mas não avança a posição atual do stream. mais...
uint8 *
GetDirectBufferForNBytesAndAdvance(int size)
Se houver pelo menos bytes de "tamanho" disponíveis no buffer atual, retorna um ponteiro diretamente para o buffer e avança sobre esses bytes. mais…
void
WriteRaw(const void * buffer, int size)
Grave bytes brutos, copiando-os do buffer especificado.
void
WriteRawMaybeAliased(const void * data, int size)
Semelhante a WriteRaw(), mas tentará gravar dados com alias se o alias estiver ativado.
void
WriteString(const std::string & str)
Equivalente a WriteRaw(str.data(), str.size()).
void
WriteLittleEndian32(uint32 value)
Escreva um número inteiro bit-endian de 32 bits.
void
WriteLittleEndian64(uint64 value)
Escreva um número inteiro bit-endian de 64 bits.
void
WriteVarint32(uint32 value)
Escreva um número inteiro não assinado com a codificação Varint. mais…
void
WriteVarint64(uint64 value)
Escreva um número inteiro não assinado com a codificação Varint.
void
WriteVarint32SignExtended(int32 value)
Equivalente a WriteVarint32(), exceto quando o valor é negativo. Nesse caso, precisa ser estendido por sinal para 10 bytes completos.
void
WriteTag(uint32 value)
Isso é idêntico a WriteVarint32(), mas otimizado para escrever tags. mais...
int
ByteCount() const
Retorna o número total de bytes gravados desde que o objeto foi criado.
void
EnableAliasing(bool enabled)
Instrui o CodedOutputStream a permitir que o ZeroCopyOutputStream subjacente contenha ponteiros para a estrutura original em vez de copiar, se houver suporte (ou seja, mais...
void
SetSerializationDeterministic(bool value)
Indique ao serializador se o usuário quer a serialização derminística. mais…
bool
IsSerializationDeterministic() const
Retorne se o usuário quer a serialização determinística. Veja como fazer isso acima.
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)
Como WriteRaw(), mas gravando diretamente na matriz de destino. mais...
static uint8 *
WriteStringToArray(const std::string & str, uint8 * target)
Como WriteString(), mas gravando diretamente na matriz de destino.
static uint8 *
WriteStringWithSizeToArray(const std::string & str, uint8 * target)
Grave o tamanho de str codificado por varint seguido por str.
static uint8 *
WriteLittleEndian32ToArray(uint32 value, uint8 * target)
Como WriteLittleEndian32(), mas gravando diretamente na matriz de destino.
static uint8 *
WriteLittleEndian64ToArray(uint64 value, uint8 * target)
Como WriteLittleEndian64(), mas gravando diretamente na matriz de destino.
static uint8 *
WriteVarint32ToArray(uint32 value, uint8 * target)
Como WriteVarint32(), mas gravando diretamente na matriz de destino.
static uint8 *
WriteVarint32ToArrayOutOfLine(uint32 value, uint8 * target)
Como WriteVarint32(), mas gravando diretamente na matriz de destino e com os caminhos de caso menos comuns fora de linha, em vez de inline.
static uint8 *
WriteVarint64ToArray(uint64 value, uint8 * target)
Como WriteVarint64(), mas gravando diretamente na matriz de destino.
static uint8 *
WriteVarint32SignExtendedToArray(int32 value, uint8 * target)
Como WriteVarint32SignExtended(), mas gravando diretamente na matriz de destino.
static uint8 *
WriteTagToArray(uint32 value, uint8 * target)
Como WriteTag(), mas gravando diretamente na matriz de destino.
static size_t
VarintSize32(uint32 value)
Retorna o número de bytes necessários para codificar o valor fornecido como um varint.
static size_t
VarintSize64(uint64 value)
Retorna o número de bytes necessários para codificar o valor fornecido como um varint.
static size_t
VarintSize32SignExtended(int32 value)
Se negativo, 10 bytes. Caso contrário, é igual a VarintSize32().
static bool
IsDefaultSerializationDeterministic()

bool CodedOutputStream::HadError()

Retornará "true" se houver um erro de E/S subjacente desde que o objeto foi criado.

Ativado deve chamar Trim antes dessa função para capturar todos os erros.


void CodedOutputStream::Trim()

Corta qualquer espaço não utilizado no buffer subjacente para que o tamanho corresponda ao número de bytes gravados por esse stream.

O buffer subjacente será cortado automaticamente quando o stream for destruído. Essa chamada só será necessária se o buffer subjacente for acessado antes de o stream ser destruído.


bool CodedOutputStream::Skip(
        int count)

Ignora vários bytes, deixando os bytes inalterados no buffer subjacente.

Retorna "false" se ocorrer um erro de gravação. Isso é útil principalmente com GetDirectBufferPointer(). Cuidado, os bytes ignorados podem conter dados não inicializados. O autor da chamada precisa garantir que os bytes ignorados sejam inicializados corretamente. Caso contrário, você poderá vazar bytes do seu heap.


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

Define *dados a apontar diretamente para a parte não escrita do buffer subjacente de CodedOutputStream e *dimensiona para o tamanho desse buffer, mas não avança a posição atual do stream.

Isso sempre produzirá um buffer não vazio ou retornará "false". Se o autor da chamada gravar os dados nesse buffer, ele precisará chamar Skip() para pular os bytes consumidos. Isso pode ser útil para implementar rotinas externas de serialização rápida para tipos de dados não cobertos pela interface CodedOutputStream.


uint8 * CodedOutputStream::GetDirectBufferForNBytesAndAdvance(
        int size)

Se houver pelo menos bytes de "tamanho" disponíveis no buffer atual, retorna um ponteiro diretamente para o buffer e avança sobre esses bytes.

Em seguida, o autor da chamada pode gravar diretamente nesse buffer (por exemplo, usando os métodos estáticos *ToArray) em vez de usar CodedOutputStream. Se não houver bytes suficientes disponíveis, retornará NULL. O ponteiro de retorno é invalidado assim que outro método não indicado de CodedOutputStream é chamado.


void CodedOutputStream::WriteVarint32(
        uint32 value)

Escreva um número inteiro não assinado com a codificação Varint.

Gravar um valor de 32 bits é equivalente a convertê-lo em um uint64 e um valor de 64 bits, mas pode ser mais eficiente.


void CodedOutputStream::WriteTag(
        uint32 value)

Isso é idêntico a WriteVarint32(), mas otimizado para escrever tags.

Especificamente, se a entrada for uma constante de tempo de compilação, esse método compilará com algumas instruções. Sempre inline porque, caso contrário, a otimização mencionada acima não pode funcionar, mas o GCC, por padrão, não quer in-line


void CodedOutputStream::EnableAliasing(
        bool enabled)

Instrui o CodedOutputStream a permitir que o ZeroCopyOutputStream subjacente contenha ponteiros para a estrutura original em vez de copiar, se houver suporte (ou seja,

output->AllowsAliasing() for verdadeiro). Se a transmissão não for compatível com alias, a ativação não terá efeito. Por enquanto, isso afeta apenas o comportamento de WriteRawTalvezAliased().

OBSERVAÇÃO: é responsabilidade do autor da chamada garantir que o bloco de memória permaneça ativo até que todos os dados tenham sido consumidos pelo stream.


void CodedOutputStream::SetSerializationDeterministic(
        bool value)

Indique ao serializador se o usuário quer a serialização derminística.

Quando esse elemento não é chamado, o padrão é global, controlado por SetDefaultSerializationDeterministic.

O que significa serialização determinística depende inteiramente do processo do processo de serialização (ou seja, o autor da chamada de métodos como WriteVarint32). No caso de serializar uma mensagem de buffer de proto usando um dos métodos de MessageLite, isso significa que, para um determinado binário, mensagens iguais sempre serão serializadas nos mesmos bytes. Isso implica:

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.

Isso não é canônico em outros idiomas. Ela também é instável em diferentes builds com alterações intermediárias de definição de mensagem, devido a campos desconhecidos. Os usuários que precisam de serialização canônica (por exemplo, armazenamento persistente em um formato canônico, técnicas de impressão digital) devem definir a própria especificação de canonização e implementar o serializador usando APIs de reflexão em vez de depender dessa API.


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

Como WriteRaw(), mas gravando diretamente na matriz de destino.

Isso não é in-line, já que o compilador geralmente otimiza o memcpy em loops de cópia in-line Como isso é chamado por todos os campos com tipo de string ou bytes, a inserção in-line pode levar a uma quantidade significativa de sobrecarga de código, com apenas um pequeno ganho de desempenho.

model struct CodedOutputStream::StaticVarintSize32

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

template <typename Value>

Equivalente a tempo de compilação de VarintSize32().

Participantes

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