eine C ++ std :: istringstream von einem in Speicherpuffer zu initialisieren?
Frage
Ich habe einen Speicherblock (opak), dass ich in einem Blob in mySQL durch ihre C ++ Adapter gespeichert werden soll. Der Adapter erwartet eine istream:
virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0;
Also meine Frage ist: Wie kann ich einen std :: istream aus diesem Speicherblock (typisiert als char *) erstellen. Es ist nicht eine Zeichenfolge, da es nicht nullterminierte ist (aber ich weiß, seine Länge natürlich).
Ich kann nicht einen Weg finden, es zu tun, ohne das Kopieren von meinem Speicherblock zum Beispiel in einem std :: string. Ich denke, das ist ein bisschen verschwenderisch ist. So etwas wie dies funktioniert nicht:
std::streambuf istringbuf(blockPtr, blockLength);
std::istringstream tmp_blob(&istringbuf);
da std :: streambuf tut solch einen Konstruktor haben. Ich sah den folgenden Vorschlag.
std:: istringstream tmp_blob;
tmp_blob.rdbuf()->pubsetbuf(blockPtr, blockLength);
Ist das der richtige Weg?
Lösung
Blick auf std :: Istrstream es einen Konstruktor hat
istrstream( char* pch, int nLength );
Diese Klasse ist eine Art abgeschrieben oder zumindest erzählt man normalerweise andere Klassen zu verwenden.
Das Problem mit Strstream ist, dass es komplizierter ist die Erinnerung an die char * buffer zu verwalten, so im Allgemeinen würden Sie bevorzugen string, wie es die Speicherverwaltung für Sie. Allerdings sind in diesem Fall die Verwaltung bereits die Erinnerung an die char *, so dass die normale Leistung in diesem Fall eine Kosten. In der Tat in diesem Fall Strstream tut genau das, was Sie mit minimalem Aufwand in Code oder Geschwindigkeit wollen. Dies ist vergleichbar mit der Diskussion über ostrsteram von Herb Sutter
Andere Tipps
Es ist eigentlich ziemlich trivial, ein One-Shot-std::streambuf
zu schreiben, die den Puffer anstelle als Standardverhalten aller virtuellen Funktionen von std::streambuf
verwendet bedeuten ‚das Richtige‘. Sie können nur den Lesebereich in Bau setg
und underflow
und uflow
kann sicher verlassen werden traits_type::eof()
als das Ende des ursprünglichen get Bereich zurückzukehren ist das Ende des Stroms.
z.
#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 hat einen Strom, der wie ein string funktioniert, aber hüllt eine native Array, so müssen Sie vermeiden, die Daten kopieren.
std :: string immer schafft seine eigenen internen Puffer
Nicht getestet, aber vielleicht einen Test wert ...
std::stringstream ss;
ss.write( blockPtr, blockLength );
ss.seekg(0);
Dann rufen Sie diese Funktion setBlob mit ss. hat Ihr nach wie vor, dass interne Puffer in std :: string als JALF bereits obwohl erwähnt.