2009-09-19 6 views
12

J'ai un bloc de mémoire (opaque), que je veux stocker dans un blob dans mySQL via leur adaptateur C++. L'adaptateur attend un istream:initialiser un C++ std :: istringstream à partir d'un tampon dans la mémoire?

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

Donc, ma question est la suivante: comment puis-je créer un std :: istream de ce bloc de mémoire (typée comme char *). Ce n'est pas une chaîne car elle n'est pas terminée par un caractère nul (mais je connais sa longueur bien sûr).

Je ne pouvais pas trouver un moyen de le faire sans copier mon bloc de mémoire par exemple dans une chaîne std :: string. Je pense que c'est un peu inutile. Quelque chose comme ceci ne fonctionne pas:

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

parce que std :: streambuf n'a pas un tel constructeur. J'ai vu la suggestion suivante.

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

Est-ce la bonne façon?

+0

double possible de [Réglage de la mémoire tampon interne utilisé par un courant standard (pubsetbuf)] (http://stackoverflow.com/questions/1494182/setting-the-internal-buffer- -ou-standard-stream-pubsetbuf) –

Répondre

7

Regardez std :: istrstream il a un constructeur

istrstream(char* pch, int nLength); 

Cette classe est un peu dépréciée ou au moins vous êtes normalement dit d'utiliser d'autres classes.
Le problème avec strstream est qu'il est plus complexe de gérer la mémoire du tampon char * donc en général, vous préféreriez stringstream comme pour la gestion de la mémoire. Cependant, dans ce cas, vous êtes déjà en train de gérer la mémoire de l'ombrelle *, donc le bénéfice normal est dans ce cas un coût. En fait, dans ce cas, Strstream fait exactement ce que vous voulez avec un minimum de surcharge en code ou en vitesse. Ceci est similaire à la discussion de

+5

Ouais, mais Josuttis dit: "Les classes de flux char * sont conservées uniquement pour des raisons de compatibilité ascendante, leur interface est sujette aux erreurs et elles sont rarement utilisées correctement." C'est pourquoi j'étais un peu réticent à les utiliser. Et "retenu seulement pour la rétrocompatibilité" semble impliquer qu'il existe une meilleure façon d'utiliser les "meilleures" classes. –

+0

J'ai lu cet article, c'est directement pertinent. Merci. Je suppose que ma question est répondue, mais pas de commentaire sur le "tmp_blob.rdbuf() -> pubsetbuf (blockPtr, blockLength); "approche. –

6

Boost.IOStreams a un flux qui fonctionne comme une chaîne de caractères, mais qui enveloppe un tableau natif, évitant ainsi d'avoir à copier les données.

std :: stringstream crée toujours son propre tampon interne

0

un Untested mais peut-être vaut essai ...

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

ensuite appeler cette fonction de setBLOB avec art. Vous avez toujours ce tampon interne dans std :: stringstream comme jalf déjà mentionné.

37

Il est en fait assez trivial d'écrire un std::streambuf one-shot qui utilise le tampon en place comme le comportement par défaut de toutes les fonctions virtuelles de std::streambuf fait 'la bonne chose'. Vous pouvez juste setg la zone de lecture dans la construction et underflow et uflow peut être laissé en toute sécurité pour retourner traits_type::eof() comme la fin de la zone d'obtention initiale est la fin du flux.

par exemple:

#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, votre solution n'est pas apparue dans les résultats de recherche quand j'ai posté ma question. Nous avons à peu près la même chose;) http: // stackoverflow .com/questions/2079912/plus simple-de-créer-ac-memorystream-de-char-sizet-sans-copier-th –

Questions connexes