2009-09-19 9 views
12

Ho un blocco di memoria (opaco), che voglio memorizzare in un Blob in mySQL attraverso il loro adattatore C++. L'adattatore si aspetta un istream:inizializzazione di un C++ std :: istringstream da un buffer di memoria?

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

Quindi la mia domanda è: come posso creare uno std :: istream da questo blocco di memoria (digitato come char *). Non è una stringa in quanto non è terminata con null (ma ne conosco ovviamente la lunghezza).

Non riesco a trovare un modo per farlo senza copiare il mio blocco di memoria, ad esempio in una stringa std ::. Penso che questo sia un po 'dispendioso. Qualcosa del genere non funziona:

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

perché std :: streambuf non ha tale costruttore. Ho visto il seguente suggerimento.

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

È quello il modo corretto?

+0

Possibile duplicato [Impostazione del buffer interno utilizzato da un flusso standard (pubsetbuf)] (http://stackoverflow.com/questions/1494182/setting-the-internal-buffer- used-by-a-standard-stream-pubsetbuf) –

risposta

7

Guarda std :: istrstream ha un costruttore

istrstream(char* pch, int nLength); 

Questa classe è una sorta di deprezzato o almeno si sono normalmente ha detto di usare altre classi.
Il problema con strstream è che è più complesso gestire la memoria del buffer char *, quindi in generale si preferisce lo stringstream come per la gestione della memoria. Comunque in questo caso stai già gestendo la memoria del char * quindi il normale vantaggio è in questo caso un costo. In questo caso, infatti, strstream fa esattamente quello che vuoi con un sovraccarico minimo di codice o velocità. Questo è simile alla discussione di ostrsteram by Herb Sutter

+5

Sì, ma Josuttis dice "Le classi di flusso char * vengono mantenute solo per compatibilità con le versioni precedenti, la loro interfaccia è soggetta a errori e vengono utilizzate raramente correttamente." Questo è il motivo per cui ero un po 'riluttante a usarli. E "mantenuto solo per compatibilità con le versioni precedenti" sembra implicare che esiste un modo migliore di utilizzare classi "migliori". –

+0

Ho letto quell'articolo, è direttamente rilevante. Grazie. Credo che alla mia domanda sia stata data una risposta, anche se nessun commento sul "tmp_blob".rdbuf() -> pubsetbuf (blockPtr, blockLength); "Approccio –

6

Boost.IOStreams ha uno stream che funziona come un stringstream, ma avvolge un array nativo, quindi evita di dover copiare i dati.

std :: stringstream crea sempre un proprio buffer interno

0

testato, ma forse vale la pena di un test ...

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

quindi chiamare quella funzione setBlob con ss. Hai ancora quel buffer interno in std :: stringstream come jalf già menzionato.

37

In realtà è piuttosto semplice scrivere uno std::streambuf one-shot che utilizza il buffer in posizione poiché il comportamento predefinito di tutte le funzioni virtuali di std::streambuf fa "la cosa giusta". È possibile solo setg l'area di lettura in costruzione e underflow e uflow può essere lasciato in modo sicuro per restituire traits_type::eof() come la fine dell'area di acquisizione iniziale è la fine del flusso.

esempio:

#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(); 
} 
+0

Haha, la tua soluzione non è comparsa nei risultati di ricerca quando ho postato la mia domanda.Abbiamo praticamente la stessa cosa;) http: // StackOverflow .com/domande/2079912/più semplice-way-to-create-ac-MemoryStream-da-char-sizet-senza-copia-esimo –

Problemi correlati