Newsgroup: it.comp.lang.c++
Titolo: Estensione di IOStream

Allora, presupponendo che il tutto deve usare solo e unicamente le classi
iostream per I/O su file, vi chiedo una mano: mettiamo che io voglia
applicare un determinato "filtro" a tutti i dati in entrata e in uscita da
un file, per esempio:
Inutile filtro per il "raddoppiamento dei caratteri":
Il programma scrive "CIAO" -> sul file viene memorizzato "CCIIAAOO"
Il programma chiede la lettura di 4 bytes -> dal disco viene letto
"CCIIAAOO" -> al programma viene restituito "CIAO".
Sebbene questo possa sembrare inutile, mi piacerebbe applicare un MIO
algoritmo a tutti i read() e write() della classe fstream, in modo che senza
che il programma di accorga di nulla (immagino istanziando una classe
derivata da fstream) in realtà su disco vengano scritti dati "elaborati", e
poi quando il programma li richieda vengano trasparentemente "de-elaborati"
:-)
Ora, immagino debba derivare da fstream una nuova classe, chiamiamola
newfstream, ma poi ??? Se io scrivo le funzioni read() e write() queste si
eseguono il mio codice, ma poi si vanno a sovrapporre alle read() e write()
precedenti! Potrei aggiungere funzioni come code() e decode(), che
codificano e automaticamente chiamano read() e write(), ma a questo punto
l'interfaccia per usare la classe newfstream non sarebbe più uguale a quella
per fstream().
Conoscendo l'estensibilità del C++ immagino sia un problema di facile
soluzione, solo che non mi viene in mente :-)
Ciao by Stefano from Italy
On the net: 
s.pe...@usa.net

 per fstream().
Puoi derivare una classe da fstream con i metodi read e write,
all'interno dei metodi poi usi le funzioni della classe padre con la
sistassi fstream::read() e fstream::write().
Spero basti altrimenti fatti rirentire.
Ciao. 
-- 
     (ZZZ)       Filippo Salotti, Bagni di Lucca, Lucca, Italy.
    //   \\  _                 E-mail : 
fil...@humnet.unipi.it
   /Y\    ZD<_o===============================================o
 .oZZZZZo.     | Studente Ingegneria Informatica Automatica  |
<OXXXXXXXO>    | Dip. Sistemi Elettrici Universita' di Pisa. |

un file, per esempio:
C'e` un ottimo articolo di James Kanze, proprio su questo 
argomento, e proprio nel numero corrente (vol 10 n 8) di "C++ 
Report", la migliore rivista di C++.  Purtroppo non e` la cosa
piu` semplice procurarsela, comunque i sorgenti relativi
sono su 
http://www.oma.com/C++Report/Sep98/Kanze
 e
quindi puoi almeno darci un'occhiata.  Il punto fondamentale
e` che il "perno" dell'architettura degli iostream NON e`
l'oggetto "stream", BENSI` l'oggetto "streambuf"; il lavoro
di uno "stream" e` sostanzialmente quello di costruire e
tenere un opportuno streambuf e coordinare il flusso di
caratteri a/da esso, lo "streambuf" e` anzitutto quello che
devi ereditare per fare personalizzazioni (da cui il titolo
dell'articolo di Kanze, "Filtering streambufs").  Le funzioni
virtuali overflow per l'output, e underflow per l'input, sono
il punto-chiave.
Ecco un esempio-giocattolo in C++ standard; non sara`
molto difficile, se ti serve, adattarlo a compilatori C++
antichi/venerabili/obsoleti -- dovrebbe bastarti cambiare
l'include da iostream a iostream.h e togliere gli std::,
visto che usiamo solo funzionalita` elementari...:
#include <iostream>
class filterbuf: public std::streambuf
{
    std::ostream& ost;       // lo stream di output su cui lavoriamo
    std::streambuf* dest;    // il suo streambuf originale
public:
    filterbuf(std::ostream& ost): ost(ost) {
        dest = ost.rdbuf(); // preleviamo lo streambuf "vero"...
        ost.rdbuf(this);      // ...e ci istalliamo noi al suo posto
    }
    virtual ~filterbuf() {
        ost.rdbuf(dest);     // ripristiniamo lo streambuf "vero"
    }
    virtual int overflow(int ch) {
        // esempio-giocattolo: duplice inserzione
        dest->sputc(ch);
        return dest->sputc(ch);
    }
};
int main()
{
    filterbuf myfilter(std::cout);    // istalliamo il ns filtro su stdout
    std::cout << "Ciao!\n";
    return 0;
}
Alex

Spero basti altrimenti fatti rirentire.
Mmm... questo trucchetto non lo sapevo :-)


};
Immagino che applicare il filtro sulla stream é meglio di quello che avevo
pensato io, e probabilmente molto più efficace se il mio algoritmo dovesse
essere un algoritmo di compressione, ma penso che userò il trucco detto
suggerito da Filippo Salotti, sai, sono un pò alle prima armi...


suggerito da Filippo Salotti, sai, sono un pò alle prima armi...
Auguri, soprattutto di non dover scoprire sulla tua pelle cosa
significa tentare un override di metodi che virtuali non sono
(non passare oggetti della tua classe ereditata da stream a
metodi o funzioni che si aspettano un reference a stream, per
esempio).
Alex