Newsgroup: it.comp.programmare.win32
Titolo: TFileStream <-> fstream

Ho un ofstream F ma in esso dovrei salvare un oggetto (BCB) che ha il metodo
SaveToStream(Classes::TStream* Stream), come posso "trasformare" un ofstream
in un TStream ?
grazie

"Drag" ha scritto
: Ho un ofstream F ma in esso dovrei salvare un oggetto (BCB) che ha il

:
Puoi derivare da TStream un tuo oggettino Wrapper che implementa le
Write, Read e Seek in termini di quelle dell'ostream, qualcosa tipo:
  struct TWrapOStream : Classes::TStream {
    TWrapOStream( std::ostream& s ) : stream_(&s) {}
    int __fastcall Write(const void *Buffer, int Count){
      stream_->write(reinterpret_cast<const char*>(Buffer), Count);
      return 1;
    }
  private: std::ostream* stream_;
    int __fastcall Read(void *, int) { throw "NotImplemented"; }
    int __fastcall Seek(int, Word)   { throw "NotImplemented"; }
  } ;
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    std::ofstream stream("prova.jpg", std::ios_base::binary);
    TWrapOStream* Stream = new TWrapOStream(stream);
    TJPEGImage *jp = new TJPEGImage();
    try
    {
      jp->Assign(Image1->Picture->Bitmap);
      jp->SaveToStream( Stream );
    }
    __finally
    {
      delete jp;
      delete Stream;
    }
  }
ciao
Massimo

 Massimo
Miticò!!!
Ottima soluzione, grazie 1000.
Un ultima cosa, per input stream ho così modificato la classe
 struct TWrapIStream : Classes::TStream {
    TWrapIStream( std::istream& s ) : stream_(&s) {}
    int __fastcall Read(void *Buffer, int Count){
      stream_->read(reinterpret_cast<char*>(Buffer), Count);
      return 1;
    }
  private: std::istream* stream_;
    int __fastcall Write(void *, int) { throw "NotImplemented"; }
    int __fastcall Seek(int, Word)   { throw "NotImplemented"; }
  } ;
Che dovrebbe servire per bmp->LoadFromStream(stream).
Mi sai dire se è giusta ?, non mi convince molto quel *Buffer ... si
dovrebbe allocare dentro il metodo ?
Grazie ancora.
Ciao
DrAg

"Drag" ha scritto
:
: Un ultima cosa, per input stream ho così modificato la classe
:
:  struct TWrapIStream : Classes::TStream {
:     TWrapIStream( std::istream& s ) : stream_(&s) {}
:
:     int __fastcall Read(void *Buffer, int Count){
:       stream_->read(reinterpret_cast<char*>(Buffer), Count);
:       return 1;
:     }
:   private: std::istream* stream_;
:     int __fastcall Write(void *, int) { throw "NotImplemented"; }
:     int __fastcall Seek(int, Word)   { throw "NotImplemented"; }
:   } ;
:
: Che dovrebbe servire per bmp->LoadFromStream(stream).
: Mi sai dire se è giusta ?, non mi convince molto quel *Buffer ... si
: dovrebbe allocare dentro il metodo ?
Il Buffer e` giusto, perche` e` il componente che ti chiede di leggere
Count bytes e ti dice dove metterli. Mentre per la lettura penso che
da Read dovresti restituire stream_->gcount(), e forse implementare
anche la Seek.
ciao
Massimo
P.S. Anche la Write deve restituire il numero di bytes effettivamente
scritti.

 :
Ho modificato così la classe per input stream.
Ma quando la istanzione mi da l'errore:
<<Cannot create instance of abstract class 'class' >>
Quale metodo manca da implementare ?  (ho provato col seek, ma da lo stesso
errore)
Grazie
ciao

"Drag" ha scritto nel messaggio
:
: > :  struct TWrapIStream : Classes::TStream {

:
Il BCB ti dice qual e` il metodo che manca. Per esempio se io dichiaro
il metodo Seek con la s minuscola il compilatore mi dice anche:
[C++ Error] WrapStream.cpp(46): E2353 Class 'TWrapIOStream' is abstract
because of '_fastcall TStream::Seek(int,unsigned short) = 0'
comunque i 3 metodi virtuali puri di TStream sono: Write, Read e Seek.
Prova a seguire questo schema:
  struct TWrapIOStream : Classes::TStream {
    TWrapIOStream( std::iostream& s ) : stream_(&s) {}
    int __fastcall Write(const void *Buffer, int Count){
      if ( stream_->write(reinterpret_cast<const char*>(Buffer), Count) )
        return Count;
      return 0;
    }
    int __fastcall Read(void *Buffer, int Count) {
      if (stream_->read(reinterpret_cast<char*>(Buffer), Count))
        return stream_->gcount();
      return 0;
    }
    int __fastcall Seek(int Offset, Word dir) {
      stream_->seekg(
        Offset,
        soFromBeginning == dir ? std::ios_base::beg :
        soFromCurrent == dir ? std::ios_base::cur :
            std::ios_base::end
      );
      return stream_->tellg();
    }
  private: std::iostream* stream_;
  } ;
a te verificare che sia 'corretto'.
ciao
Massimo