Pregunta

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

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

Así que mi pregunta es: ¿Cómo puedo crear un std :: istream de este bloque de memoria (a máquina como char *). No es una cadena, ya que no es terminada en cero (pero sé de su longitud, por supuesto).

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

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

debido a std :: duerma streambuf tienen un constructor tales. Vi la siguiente sugerencia.

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

Es esa la forma correcta?

¿Fue útil?

Solución

Mira std :: istrstream que tiene un constructor

 istrstream( char* pch, int nLength );

Esta clase es una especie de depreciación o por lo menos que normalmente se les dice a utilizar otras clases.
El problema con strstream es que es más difícil de gestionar la memoria del búfer char * lo que en general se prefiere stringstream como lo hace la gestión de memoria para usted. Sin embargo, en este caso ya está gestionando la memoria de la char * por lo que el beneficio normal es en este caso un costo. De hecho, en este caso strstream hace exactamente lo que desea con una sobrecarga mínima en el código o la velocidad. Esto es similar a la discusión de ostrsteram por Herb Sutter

Otros consejos

En realidad es bastante trivial para escribir una std::streambuf de un solo disparo que utiliza el búfer en el lugar como el comportamiento por defecto de todas las funciones virtuales de std::streambuf hace 'lo correcto'. Puede simplemente setg el área de lectura en la construcción y underflow y uflow con seguridad se puede dejar de volver traits_type::eof() como el final de la zona inicial get es el final de la secuencia.

por ejemplo:.

#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 tiene una corriente que funciona como un stringstream, pero envuelve una matriz nativa, por lo que se evita tener que copiar los datos.

std :: stringstream crea siempre su propio buffer interno

No comprobado pero quizás vale la pena una prueba ...

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

A continuación, llamar a esa función con setBlob ss. Su todavía tienen que buffer interno en std :: stringstream como ya se ha mencionado, aunque JALF.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top