Newsgroup: it.comp.lang.c++
Titolo: Proxy di iostream

Ho il seguente problema, proposto in maniera semplificata: data una 
classe di iostream X, vorrei avere una classe Y tale per cui ogni 
input/output sulla classe Y venga modificato (da una certa funzione) e 
poi passato sulla classe X. Ad es:
Y y(std::ofstream("tmp.txt"));
y << "Ciao!" << std::endl;
y << "Come va?" << std::endl;
Stampa su file:
CCiiaaoo!!
CCoommee  vvaa??
(in questo caso la funzione di modifica e' banale, raddoppia 
semplicemente ogni carattere - nel mio caso si tratta di effettuare una 
crittazione AES).
Qualcuno ha idee su quale sia il metodo migliore? Un semplice 
overloading - ma di quali metodi? Forse ci sarebbe piuttosto da lavorare 
sul sottostante streambuf?
-- 
Mat/tia Belletti - Undergraduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://mbellett.web.cs.unibo.it/
Linux registered user 299762 @ Linux registered machine 213003

 sul sottostante streambuf?
Direi proprio di sě. Non sono molto esperto di iostream, ma penso che 
la tecnica piů rapida sia quella di derivare da std::streambuf e riderinire 
'overloflow', 'sync' e 'xsputn'. Ti suggerisco di cercare qualche 
tutorial che approfondisca la questione.
Max

 CCoommee  vvaa??
Dovresti crearti una classe derivandola da ostream creandoti l'operatore che
restituisca un oggetto di tipo Y.
Nel semplice esempio che hai mostrato in realtà non hai bisogno di uno
streambuf specializzato, ma ti basta utilizzare quello standard.
//Esempio
...
using namespace std;
class Y: public ostream
{
public:
 Y(filebuf* fb) : std::ostream(fb), fbuf(fb) {} //inizializza lo stream
 ~Y() {}
//serve per serializzare Y verso ostream
 friend ostream& operator<<(ostream & s, Y& c) {
  s<<c.strStream.c_str();
  return s;
 }
//serve per serializzare i manipolatori (ad es. endl)
 _Myt& operator<<(_Myt&(__cdecl *_Pfn )(_Myt&))
  { // call basic_ostream manipulator
   strStream +="\n"; //supponendo che accetti solo il manipolatore endl
   return ((*_Pfn)(*this));
  }
//serve per serializzare una stringa verso Y
   Y& operator<<(const char * s)
    {
      string buffer;
      for (unsigned int i=0;i< strlen(s);++i){
       char c = s[i];
       buffer += s[i];
       buffer += s[i];
      }
      fbuf->sputn(buffer.c_str(),buffer.length());
      strStream += buffer;
            return *this;
    }
private:
  string strStream; //stringa che contiene lo stream di caratteri totale
  filebuf* fbuf; //puntatore al file buffer
};
int main ()
{
 filebuf fb;
 fb.open ("test.txt",ios::out);
 Y y (&fb);
 y << "Ciao"<<endl;
 y << "Come va?" <<endl;
 cout << y <<endl;
 return 0;
}
Per una più dettagliata descrizione sulle tecniche di derivazione da
iostream vedi
http://www.langer.camelot.de/Articles/C++Report/IOStreamsDerivation/IOStreamsDerivation.html
Ciao
Andrea

 lavorare sul sottostante streambuf?
Infatti. La soluzione e un streambuf filtrante, cioè un streambuf chi
utiliza un altro streambuf come destinazione. Vedo a la mia site
(
www.gabi-soft.fr
), c'e un'esplicazione nei articoli, è codice nella
partita di codice.
--
James Kanze           GABI Software         
http://www.gabi-soft.fr
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, 
+33 (0)1 30 23 00 34