Si l'ostream est un fichier (c'est à dire si il n'a pas de taille
définie) alors la fonction écrirait dans le dedans jusqu'à ce que
InternetReadFile indique qu'il n'y a plus de données à lire
Si l'ostream est de type buffer (cf. mon message d'hier ;-)) la
fonction remplirait le buffer et devrait être re-appelée pour avoir la
suite des données.
Je cherche à écrire cette fonction de la manière la plus propre
possible (pas du bricolage) mais comme je ne m'y connais pas trop sur
les stream std, je m'en remet à vous
Merci d'avance
Philippe
>et �crirait les donn�es lu dans un osteam.
>[...] Si l'ostream est de type buffer [...]
Pourquoi ?
Si tu as un buffer de taille d�finie, tu peux le passer directement �
InternetReadFile, sans encapsuler tout �a dans du ostream.
Mais si on creuse un peu plus : pourquoi diable veux-tu utiliser un
buffer ? Utilise donc std::string et std::stringstream, et ton
programme n'en sera que plus fiable (et facile � programmer, ce qui va
souvent ensemble).
D'autant que si ton buffer est trop petit, InternetReadFile va se
plaindre, tu vas devoir remonter l'erreur, etc.
Pr�vois du parac�tamol.
Ou mais je souhaite que ma fonction puisse lire des données via
InternetReadFile et les écrire dans un ostream, indépendamment que
c'est ostream encapule un fichier, un buffer ou autre chose.
> Mais si on creuse un peu plus : pourquoi diable veux-tu utiliser un
> buffer ? Utilise donc std::string et std::stringstream, et ton
> programme n'en sera que plus fiable (et facile à programmer, ce qui va
> souvent ensemble).
>
> D'autant que si ton buffer est trop petit, InternetReadFile va se
> plaindre, tu vas devoir remonter l'erreur, etc.
> Prévois du paracétamol.
> Si l'ostream est un fichier (c'est à dire si il n'a pas de
> taille définie) alors la fonction écrirait dans le dedans
> jusqu'à ce que InternetReadFile indique qu'il n'y a plus de
> données à lire
> Si l'ostream est de type buffer (cf. mon message d'hier ;-))
> la fonction remplirait le buffer et devrait être re-appelée
> pour avoir la suite des données.
Ça dépend de ton implémentation du buffer_streambuf (ou comment
tu l'appèles). L'implémentation la plus naturelle, à mon avis,
se servira de std::vector< char > (c'est le type naturel d'un
buffer), et il n'y aura jamais besoin de le reinitialiser. Mais
à la fin, c'est toi que définit le streambuf, et c'est toi qui
établis les règles.
> Je cherche à écrire cette fonction de la manière la plus
> propre possible (pas du bricolage) mais comme je ne m'y
> connais pas trop sur les stream std, je m'en remet à vous
Alors, la première chose, c'est d'apprendre sur les stream
standard. Parce qu'utiliser un outil qu'on ne connaît pas ne
mène jamais à quelque chose de bien. Mais dans ce cas-ci, ce
qu'il te faut savoir n'est pas énorme : tous les put, write, et
>> de ostream renvoie à la fin au streambuf pour les sorties
physiques des caractères. En se servant uniquement de deux
fonctions : sputc et sputn. Fonctions publiques qui elles se
servent des fonctions virtuelles de xsputn et de overflow. Et il
existe une version par défaut de la première, qui l'implémente
en fonction de la seconde. (En fait, en fonction de sputc, mais
sputc, qui elle n'appelle que overflow.) Alors, l'impémentation
la plus simple serait simplement :
class buffering_streambuf : public std::streambuf
{
std::vector< char > buffer;
protected:
virtual int overflow( int ch )
{
if ( ch != EOF )
buffer.push_back( ch );
return ch == EOF ? '\0' : ch;
}
public:
// accès au buffer, etc.
};
Pour éviter quelques appels virtuels, il pourrait être
préferrable de rendre la bufferisation visible à sputc et
sputn :
class buffering_streambuf : public std::streambuf
{
std::vector< char > buffer;
protected:
virtual int overflow( int ch )
{
if ( ch != EOF )
buffer.push_back( ch );
size_t current = buffer.size();
buffer.resize( buffer.capacity() );
setp( &buffer[0] + current,
&buffer[0] + buffer.size());
return ch == EOF ? '\0' : ch;
}
public:
// accès au buffer, etc.
// Les fonctions d'accès doivent prendre en compte
// la position courante, c-à-d pptr. Par exemple:
typedef std::vector< char >::const_iterator iterator;
iterator begin() const
{
return buffer.begin();
}
iterator end() const
{
return buffer.begin() + (pptr() - &buffer[0]);
}
};
--
James Kanze