l'initialisation d'un C ++ std :: istringstream à partir d'un tampon dans la mémoire?

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

  •  11-09-2019
  •  | 
  •  

Question

J'ai un bloc de mémoire (opaque), que je veux stocker dans un Blob dans mySQL par leur adaptateur C ++. L'adaptateur attend un istream:

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

Alors ma question est: 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 comme il est non nul terminé (mais je sais que 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 un std :: string. Je pense que c'est un peu inutile. Quelque chose comme cela ne fonctionne pas:

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

parce que std :: ne marche pas streambuf ont 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?

Était-ce utile?

La solution

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 à gérer la mémoire du tampon char * si en général vous préférez stringstream comme il le fait de la gestion de la mémoire pour vous. Toutefois, dans ce cas, vous gérez déjà la mémoire du char * si le bénéfice est normale dans ce cas un coût. En fait, dans ce cas strstream fait exactement ce que vous voulez avec un minimum de frais généraux dans le code ou la vitesse. Ceci est similaire à la discussion sur ostrsteram par Herb Sutter

Autres conseils

Il est en fait assez trivial d'écrire un std::streambuf one-shot qui utilise la mémoire tampon en place 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 en toute sécurité uflow peut être laissé revenir traits_type::eof() comme la fin de la zone get 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();
}

Boost.IOStreams a un flux qui fonctionne comme un stringstream, mais encapsule un tableau natif, ce qui vous évite d'avoir à copier les données.

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

Non testé, mais peut-être vaut un test ...

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

Ensuite, appelez cette fonction de setBLOB avec art. Avez-vous encore que la mémoire tampon interne dans std :: stringstream comme jalf déjà mentionné cependant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top