inicializando un C ++ std :: istringstream desde un buffer en la memoria?

Tengo un bloque de memoria (opaco), que quiero almacenar en una Blob en mySQL a través de su adaptador C ++. El adaptador espera un istream:

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

Entonces mi pregunta es: ¿cómo puedo crear un std :: istream desde este bloque de memoria (escrito como char *). No es una cadena ya que no tiene terminación nula (pero sé su duración, por supuesto).

No pude encontrar una manera de hacerlo sin copiar mi bloque de memoria, por ejemplo, en std :: string. Creo que esto es un poco derrochador Algo como esto no funciona:

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

porque std :: streambuf no tiene dicho constructor. Vi la siguiente sugerencia.

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

¿Es esa la forma correcta?

Mira std :: istrstream tiene un constructor

  istrstream( char* pch, int nLength ); 

Esta clase está un poco depreciada o, al menos, normalmente le dicen que use otras clases.
El problema con strstream es que es más complejo administrar la memoria del búfer char *, por lo que en general preferiría stringstream como lo hace con la administración de memoria. Sin embargo, en este caso ya está administrando la memoria del char *, por lo que el beneficio normal es, en este caso, un costo. De hecho, en este caso, strstream hace exactamente lo que usted desea con una sobrecarga mínima en código o velocidad. Esto es similar a la discusión de ostrsteram por Herb Sutter

De hecho, es bastante trivial escribir un std::streambuf un solo std::streambuf que utilice el búfer en su lugar ya que el comportamiento predeterminado de todas las funciones virtuales de std::streambuf es “lo correcto”. Solo puede setg el área de lectura en construcción y underflow y uflow puede uflow seguridad para devolverle a traits_type::eof() ya que el final del área de obtención inicial es el final de la secuencia.

p.ej:

 #include  #include  #include  #include  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 tiene una secuencia que funciona como una cadena de caracteres, pero envuelve una matriz nativa, por lo que evita tener que copiar los datos.

std :: stringstream siempre crea su propio buffer interno

No probado, pero tal vez vale la pena una prueba …

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

Luego llama a esa función setBlob con ss. Todavía tienes ese búfer interno en std :: stringstream como jalf ya mencionado.