Pergunta

Eu tenho um bloco de memória (opaco), que eu quero para armazenar em um Blob no MySQL através do seu adaptador de C ++. O adaptador espera um istream:

virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0;

Então, minha pergunta é: como posso criar um std :: istream deste bloco de memória (digitado como char *). Não é uma cadeia, pois não é terminada em nulo (mas eu sei que seu comprimento é claro).

Eu não poderia encontrar uma maneira de fazê-lo sem copiar o meu bloco de memória, por exemplo, em um std :: string. Eu acho que isso é um pouco desperdício. Algo como isso não funciona:

    std::streambuf istringbuf(blockPtr, blockLength);
    std::istringstream tmp_blob(&istringbuf);

porque std :: streambuf esquentar têm como um construtor. Eu vi a seguinte sugestão.

    std:: istringstream       tmp_blob;
    tmp_blob.rdbuf()->pubsetbuf(blockPtr, blockLength);

É essa a maneira correta?

Foi útil?

Solução

Olhe para std :: istrstream tem um construtor

 istrstream( char* pch, int nLength );

Esta classe é uma espécie de depreciado ou pelo menos você normalmente são instruídos a usar outras classes.
O problema com strstream é que ele é mais complexo para gerenciar a memória do char * buffer de modo em geral você preferir stringstream como faz o gerenciamento de memória para você. No entanto, neste caso, você já está gerenciando a memória do char * assim o benefício normal é neste caso um custo. Na verdade, neste caso strstream faz exatamente o que você quer com sobrecarga mínima no código ou velocidade. Isto é semelhante à discussão de ostrsteram por Herb Sutter

Outras dicas

É realmente muito trivial para escrever um std::streambuf one-shot que usa o tampão no lugar como o comportamento padrão de todas as funções virtuais de std::streambuf faz 'a coisa certa'. Você pode apenas setg a área de leitura na construção e underflow e uflow pode seguramente ser deixado para traits_type::eof() retorno como o fim da área get inicial é o fim do fluxo.

por exemplo:.

#include <streambuf>
#include <iostream>
#include <istream>
#include <ostream>

struct OneShotReadBuf : public std::streambuf
{
    OneShotReadBuf(char* s, std::size_t n)
    {
        setg(s, s, s + n);
    }
};

char hw[] = "Hello, World!\n";

int main()
{
    // In this case disregard the null terminator
    OneShotReadBuf osrb(hw, sizeof hw - 1);
    std::istream istr(&osrb);

    istr >> std::cout.rdbuf();
}

Boost.IOStreams tem um fluxo que funciona como um stringstream, mas envolve uma matriz nativa, de modo a evitar ter que copiar os dados.

std :: stringstream sempre cria seu próprio buffer interno

teste de um Untested mas talvez valha a pena ...

std::stringstream ss;
ss.write( blockPtr, blockLength );
ss.seekg(0);

Em seguida, chamar essa função setBlob com ss. Sua ainda tem que buffer interno em std :: stringstream como jalf já mencionado embora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top