eine C ++ std :: istringstream von einem in Speicherpuffer zu initialisieren?

StackOverflow https://stackoverflow.com/questions/1448467

  •  11-09-2019
  •  | 
  •  

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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top