Je cherche =E0 =E9crire une fonction qui lirait des donn=E9es sur le r=E9se=
au
via la fonction InternetReadFile (dont le prototype est proche de la
fonction write) et =E9crirait les donn=E9es lu dans un osteam.
Si l'ostream est un fichier (c'est =E0 dire si il n'a pas de taille
d=E9finie) alors la fonction =E9crirait dans le dedans jusqu'=E0 ce que
InternetReadFile indique qu'il n'y a plus de donn=E9es =E0 lire
Si l'ostream est de type buffer (cf. mon message d'hier ;-)) la
fonction remplirait le buffer et devrait =EAtre re-appel=E9e pour avoir la
suite des donn=E9es.
Je cherche =E0 =E9crire cette fonction de la mani=E8re la plus propre
possible (pas du bricolage) mais comme je ne m'y connais pas trop sur
les stream std, je m'en remet =E0 vous
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Fabien LE LEZ
On Thu, 31 Dec 2009 02:57:14 -0800 (PST), Philippe MESMEUR :
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.
On Thu, 31 Dec 2009 02:57:14 -0800 (PST), Philippe MESMEUR
<philippe.mesmeur@gmail.com>:
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.
On Thu, 31 Dec 2009 02:57:14 -0800 (PST), Philippe MESMEUR :
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.
Philippe MESMEUR
On 31 déc, 12:18, Fabien LE LEZ wrote:
On Thu, 31 Dec 2009 02:57:14 -0800 (PST), Philippe MESMEUR :
>et écrirait les données lu dans un osteam. >[...] Si l'ostreamest de type buffer [...]
Pourquoi ?
Si tu as un buffer de taille définie, tu peux le passer directement à InternetReadFile, sans encapsuler tout ça dans duostream.
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.
On 31 déc, 12:18, Fabien LE LEZ <grams...@gramster.com> wrote:
On Thu, 31 Dec 2009 02:57:14 -0800 (PST), Philippe MESMEUR
<philippe.mesm...@gmail.com>:
>et écrirait les données lu dans un osteam.
>[...] Si l'ostreamest de type buffer [...]
Pourquoi ?
Si tu as un buffer de taille définie, tu peux le passer directement à
InternetReadFile, sans encapsuler tout ça dans duostream.
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.
On Thu, 31 Dec 2009 02:57:14 -0800 (PST), Philippe MESMEUR :
>et écrirait les données lu dans un osteam. >[...] Si l'ostreamest de type buffer [...]
Pourquoi ?
Si tu as un buffer de taille définie, tu peux le passer directement à InternetReadFile, sans encapsuler tout ça dans duostream.
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.
James Kanze
On Dec 31 2009, 10:57 am, Philippe MESMEUR wrote:
Je cherche à écrire une fonction qui lirait des données sur le réseau via la fonction InternetReadFile (dont le prototype est proche de la fonction write) et écrirait les données lu dans un osteam.
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 ? ' ' : 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 ? ' ' : 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
On Dec 31 2009, 10:57 am, Philippe MESMEUR
<philippe.mesm...@gmail.com> wrote:
Je cherche à écrire une fonction qui lirait des données sur le
réseau via la fonction InternetReadFile (dont le prototype est
proche de la fonction write) et écrirait les données lu dans
un osteam.
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 ? ' ' : 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 ? ' ' : 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]);
}
};
Je cherche à écrire une fonction qui lirait des données sur le réseau via la fonction InternetReadFile (dont le prototype est proche de la fonction write) et écrirait les données lu dans un osteam.
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 ? ' ' : 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 ? ' ' : 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]); } };