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_sem_cópia.h

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

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

Esse arquivo contém as interfaces ZeroCopyInputStream e ZeroCopyOutputStream, que representam streams de E/S abstratos de e para os quais os buffers de protocolo podem ser lidos e gravados.

Para ver implementações simples dessas interfaces, consulte zero_copy_stream_impl.h.

Essas interfaces são diferentes dos fluxos clássicos de E/S porque tentam minimizar a quantidade de cópias de dados que precisam ser feitas. Para fazer isso, a responsabilidade de alocar buffers é movida para o objeto de stream, em vez de ser a responsabilidade do autor da chamada. Assim, o stream pode retornar um buffer que realmente aponta diretamente para a estrutura de dados final, onde os bytes serão armazenados, e o autor da chamada pode interagir diretamente com esse buffer, eliminando uma operação de cópia intermediária.

Por exemplo, considere o caso comum em que você está lendo bytes de uma matriz que já está na memória (ou talvez em um arquivo mmap()ed). Com as transmissões clássicas de E/S, você faria algo como:

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

O stream basicamente chama memcpy() para copiar os dados da matriz para o buffer. Com um ZeroCopyInputStream, você faria isso:

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

Aqui, nenhuma cópia é realizada. O stream de entrada retorna um ponteiro diretamente para a matriz de apoio, e o autor da chamada acaba lendo diretamente dela.

Se você quiser ler de uma forma antiga, crie um CodedInputStream ou CodedOutputStream encapsulando esses objetos e usando os métodos ReadRaw()/WriteRaw(). Obviamente, elas vão adicionar uma etapa de cópia, mas o Coded*Stream processará o buffer para que pelo menos seja razoavelmente eficiente.

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

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

Turmas neste arquivo

Interface abstrata semelhante a um fluxo de entrada, mas projetada para minimizar a cópia.
Interface abstrata semelhante a um stream de saída, mas projetada para minimizar a cópia.

classe ZeroCopyInputStream

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

Interface abstrata semelhante a um fluxo de entrada, mas projetada para minimizar a cópia.

Subclasses conhecidas:

Participantes

ZeroCopyInputStream()
virtual
~ZeroCopyInputStream()
virtual bool
Next(const void ** data, int * size) = 0
Recebe um bloco de dados do stream. mais…
virtual void
BackUp(int count) = 0
Faz backup de vários bytes, de modo que a próxima chamada para Next() retorna dados que já foram retornados pela última chamada para Next(). Mais...
virtual bool
Skip(int count) = 0
Ignora vários bytes. mais…
virtual int64_t
ByteCount() const = 0
Retorna o número total de bytes lidos desde que o objeto foi criado.

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

Recebe um bloco de dados do stream.

Condições prévias:

  • "size" e "data" não são NULL.

Pós-condições:

  • Se o valor retornado for falso, não haverá mais dados para retornar ou ocorreu um erro. Todos os erros são permanentes.
  • Caso contrário, "size" aponta para o número real de bytes lidos e "data" aponta para um ponteiro para um buffer que contém esses bytes.
  • A propriedade desse buffer permanece com o stream e ele permanece válido somente até que algum outro método do stream seja chamado ou que o stream seja destruído.
  • É permitido que o buffer retornado tenha tamanho zero, desde que chamar Next() várias vezes produz um buffer com tamanho diferente de zero.

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

Faz backup de vários bytes, de modo que a próxima chamada para Next() retorna dados que já foram retornados pela última chamada para Next().

Isso é útil ao escrever procedimentos que apenas devem ler um certo ponto da entrada e retornar. Se Next() retornar um buffer que vai além do que você quer ler, use BackUp() para voltar ao ponto em que quer concluir.

Condições prévias:

  • O último método chamado precisa ter sido Next().
  • a contagem deve ser menor ou igual ao tamanho do último buffer retornado por Next().

Pós-condições:

  • Os últimos bytes de "count" do último buffer retornados por Next() serão reenviados para o stream. As chamadas subsequentes para Next() retornarão os mesmos dados novamente antes de produzir novos dados.

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

Ignora vários bytes.

Retorna falso se o final do stream for alcançado ou se ocorrer algum erro de entrada. No caso de fim do stream, ele é avançado para o final (de modo que ByteCount() retorna o tamanho total do stream).

classe ZeroCopyOutputStream

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

Interface abstrata semelhante a um stream de saída, mas projetada para minimizar a cópia.

Subclasses conhecidas:

Participantes

ZeroCopyOutputStream()
virtual
~ZeroCopyOutputStream()
virtual bool
Next(void ** data, int * size) = 0
Recebe um buffer em que os dados podem ser gravados. mais…
virtual void
BackUp(int count) = 0
Faz backup de vários bytes, de modo que o fim do último buffer retornado por Next() não seja gravado. mais...
virtual int64_t
ByteCount() const = 0
Retorna o número total de bytes gravados desde que o objeto foi criado.
virtual bool
WriteAliasedRaw(const void * data, int size)
Gravar um determinado bloco de dados na saída. mais…
virtual bool
AllowsAliasing() const

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

Recebe um buffer em que os dados podem ser gravados.

Todos os dados gravados nesse buffer serão gravados na saída (talvez instantaneamente, talvez mais tarde).

Condições prévias:

  • "size" e "data" não são NULL.

Pós-condições:

  • Se o valor retornado for “false”, significa que ocorreu um erro. Todos os erros são permanentes.
  • Caso contrário, "tamanho" apontará para o número real de bytes no buffer e "dados" aponta para o buffer.
  • A propriedade desse buffer permanece com o stream e ele permanece válido somente até que algum outro método do stream seja chamado ou que o stream seja destruído.
  • Todos os dados armazenados pelo autor da chamada nesse buffer serão gravados na saída (a menos que BackUp() seja chamado).
  • É permitido que o buffer retornado tenha tamanho zero, desde que chamar Next() várias vezes produz um buffer com tamanho diferente de zero.

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

Faz backup de vários bytes, de modo que o fim do último buffer retornado por Next() não seja gravado.

Isso é necessário quando você termina de gravar todos os dados que quer gravar, mas o último buffer foi maior do que o necessário. Não é recomendável escrever vários lixo após o término dos dados, então use BackUp() para fazer backup.

Condições prévias:

  • O último método chamado precisa ter sido Next().
  • a contagem deve ser menor ou igual ao tamanho do último buffer retornado por Next().
  • O autor da chamada não pode ter escrito nada para os últimos bytes de "contagem" desse buffer.

Pós-condições:

  • Os últimos bytes de "count" do último buffer retornados por Next() serão ignorados.

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

Gravar um determinado bloco de dados na saída.

Alguns streams de saída podem implementar isso de modo a evitar a cópia. Verifique AllowAliasing() antes de chamar WriteAliasedRaw(). Ocorrerá uma falha na GOOGLE_CHECK se o WriteAliasedRaw() for chamado em um stream que não permita o alias.

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.