From 47fc03d21ab5b2d88959b6650a0151fb2c241c30 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 23 Nov 2000 19:45:46 +0000 Subject: [PATCH] more fixes to stream code: allow deriving from wxStreamBuffer and using custom buffers with wxBufferedInput/OutputStream git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8777 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/stream.h | 133 ++++++++++++++++++++++++++++-------------- src/common/stream.cpp | 132 ++++++++++++++++++++++++++++------------- 2 files changed, 178 insertions(+), 87 deletions(-) diff --git a/include/wx/stream.h b/include/wx/stream.h index c2574995f4..00bf592d09 100644 --- a/include/wx/stream.h +++ b/include/wx/stream.h @@ -40,17 +40,17 @@ WXDLLEXPORT wxOutputStream& wxEndL(wxOutputStream& o_stream); enum wxStreamError { - wxSTREAM_NO_ERROR = 0, - wxSTREAM_NO_ERR = wxSTREAM_NO_ERROR, - wxSTREAM_NOERROR = wxSTREAM_NO_ERROR, + wxSTREAM_NO_ERROR = 0, + wxSTREAM_NO_ERR = wxSTREAM_NO_ERROR, + wxSTREAM_NOERROR = wxSTREAM_NO_ERROR, - wxSTREAM_EOF, + wxSTREAM_EOF, - wxSTREAM_WRITE_ERROR, - wxSTREAM_WRITE_ERR = wxSTREAM_WRITE_ERROR, + wxSTREAM_WRITE_ERROR, + wxSTREAM_WRITE_ERR = wxSTREAM_WRITE_ERROR, - wxSTREAM_READ_ERROR, - wxSTREAM_READ_ERR = wxSTREAM_READ_ERROR + wxSTREAM_READ_ERROR, + wxSTREAM_READ_ERR = wxSTREAM_READ_ERROR }; // compatibility @@ -66,17 +66,25 @@ public: virtual ~wxStreamBase(); // error testing - wxStreamError LastError() const { return m_lasterror; } wxStreamError GetLastError() const { return m_lasterror; } bool IsOk() const { return LastError() == wxSTREAM_NOERROR; } bool operator!() const { return LastError() != wxSTREAM_NOERROR; } - virtual size_t GetSize() const { return ~((size_t)0); } + virtual size_t GetSize() const { return 0; } + + // deprecated, for compatibility only + wxStreamError LastError() const { return m_lasterror; } size_t StreamSize() const { return GetSize(); } protected: + // VZ: these functions are really pure virtual and shouldn't be declared + // in the base class because it creates ambiguties in stream classes + // deriving from both wxInputStream and wxOutputStream +#if 0 virtual size_t OnSysRead(void *buffer, size_t bufsize); virtual size_t OnSysWrite(const void *buffer, size_t bufsize); +#endif + virtual off_t OnSysSeek(off_t seek, wxSeekMode mode); virtual off_t OnSysTell() const; @@ -86,7 +94,7 @@ protected: wxStreamError m_lasterror; }; -class WXDLLEXPORT wxInputStream: public wxStreamBase +class WXDLLEXPORT wxInputStream : /* virtual */ public wxStreamBase { public: wxInputStream(); @@ -120,6 +128,10 @@ public: wxInputStream& operator>>( __wxInputManip func) { return func(*this); } protected: + // to be implemented in the derived classes (it should have been pure + // virtual) + virtual size_t OnSysRead(void *buffer, size_t bufsize); + // Ungetch managers char *m_wback; size_t m_wbacksize; @@ -127,9 +139,11 @@ protected: char *AllocSpaceWBack(size_t needed_size); size_t GetWBack(void *buf, size_t bsize); + + friend class wxStreamBuffer; }; -class WXDLLEXPORT wxOutputStream: public wxStreamBase +class WXDLLEXPORT wxOutputStream : /* virtual */ public wxStreamBase { public: wxOutputStream(); @@ -151,13 +165,20 @@ public: wxOutputStream& operator<<(wxObject& obj); #endif wxOutputStream& operator<<( __wxOutputManip func) { return func(*this); } + +protected: + // to be implemented in the derived classes (it should have been pure + // virtual) + virtual size_t OnSysWrite(const void *buffer, size_t bufsize); + + friend class wxStreamBuffer; }; // --------------------------------------------------------------------------- // A stream for measuring streamed output // --------------------------------------------------------------------------- -class WXDLLEXPORT wxCountingOutputStream: public wxOutputStream +class WXDLLEXPORT wxCountingOutputStream : public wxOutputStream { public: wxCountingOutputStream(); @@ -166,9 +187,9 @@ public: bool Ok() const { return TRUE; } protected: - size_t OnSysWrite(const void *buffer, size_t size); - off_t OnSysSeek(off_t pos, wxSeekMode mode); - off_t OnSysTell() const; + virtual size_t OnSysWrite(const void *buffer, size_t size); + virtual off_t OnSysSeek(off_t pos, wxSeekMode mode); + virtual off_t OnSysTell() const; size_t m_currentPos; }; @@ -177,36 +198,41 @@ protected: // "Filter" streams // --------------------------------------------------------------------------- -class WXDLLEXPORT wxFilterInputStream: public wxInputStream +class WXDLLEXPORT wxFilterInputStream : public wxInputStream { public: wxFilterInputStream(); wxFilterInputStream(wxInputStream& stream); - ~wxFilterInputStream(); + virtual ~wxFilterInputStream(); char Peek() { return m_parent_i_stream->Peek(); } size_t GetSize() const { return m_parent_i_stream->GetSize(); } + wxInputStream *GetFilterInputStream() const { return m_parent_i_stream; } + protected: wxInputStream *m_parent_i_stream; }; -class WXDLLEXPORT wxFilterOutputStream: public wxOutputStream +class WXDLLEXPORT wxFilterOutputStream : public wxOutputStream { public: wxFilterOutputStream(); wxFilterOutputStream(wxOutputStream& stream); - ~wxFilterOutputStream(); + virtual ~wxFilterOutputStream(); size_t GetSize() const { return m_parent_o_stream->GetSize(); } + wxOutputStream *GetFilterOutputStream() const { return m_parent_o_stream; } + protected: wxOutputStream *m_parent_o_stream; }; // --------------------------------------------------------------------------- -// Stream buffer +// Stream buffer: this class can be derived from and passed to +// wxBufferedStreams to implement custom buffering // --------------------------------------------------------------------------- class WXDLLEXPORT wxStreamBuffer @@ -222,19 +248,19 @@ public: wxStreamBuffer(wxStreamBase& stream, BufMode mode); wxStreamBuffer(BufMode mode); wxStreamBuffer(const wxStreamBuffer& buf); - ~wxStreamBuffer(); + virtual ~wxStreamBuffer(); // Filtered IO - size_t Read(void *buffer, size_t size); + virtual size_t Read(void *buffer, size_t size); size_t Read(wxStreamBuffer *buf); - size_t Write(const void *buffer, size_t size); + virtual size_t Write(const void *buffer, size_t size); size_t Write(wxStreamBuffer *buf); - char Peek(); - char GetChar(); - void PutChar(char c); - off_t Tell() const; - off_t Seek(off_t pos, wxSeekMode mode); + virtual char Peek(); + virtual char GetChar(); + virtual void PutChar(char c); + virtual off_t Tell() const; + virtual off_t Seek(off_t pos, wxSeekMode mode); // Buffer control void ResetBuffer(); @@ -267,6 +293,10 @@ public: bool IsFixed() const { return m_fixed; } bool IsFlushable() const { return m_flushable; } + // only for input/output buffers respectively, returns NULL otherwise + wxInputStream *GetInputStream() const; + wxOutputStream *GetOutputStream() const; + // deprecated, for compatibility only wxStreamBase *Stream() { return m_stream; } @@ -313,11 +343,13 @@ protected: // wxBufferedStreams // --------------------------------------------------------------------------- -class WXDLLEXPORT wxBufferedInputStream: public wxFilterInputStream +class WXDLLEXPORT wxBufferedInputStream : public wxFilterInputStream { public: - wxBufferedInputStream(wxInputStream& stream); - ~wxBufferedInputStream(); + // if a non NULL buffer is given to the stream, it will be deleted by it + wxBufferedInputStream(wxInputStream& stream, + wxStreamBuffer *buffer = NULL); + virtual ~wxBufferedInputStream(); char Peek(); wxInputStream& Read(void *buffer, size_t size); @@ -326,21 +358,28 @@ public: off_t SeekI(off_t pos, wxSeekMode mode = wxFromStart); off_t TellI() const; + // the buffer given to the stream will be deleted by it + void SetInputStreamBuffer(wxStreamBuffer *buffer); + wxStreamBuffer *GetInputStreamBuffer() const { return m_i_streambuf; } + + // deprecated, for compatibility only wxStreamBuffer *InputStreamBuffer() const { return m_i_streambuf; } protected: - size_t OnSysRead(void *buffer, size_t bufsize); - off_t OnSysSeek(off_t seek, wxSeekMode mode); - off_t OnSysTell() const; + virtual size_t OnSysRead(void *buffer, size_t bufsize); + virtual off_t OnSysSeek(off_t seek, wxSeekMode mode); + virtual off_t OnSysTell() const; wxStreamBuffer *m_i_streambuf; }; -class WXDLLEXPORT wxBufferedOutputStream: public wxFilterOutputStream +class WXDLLEXPORT wxBufferedOutputStream : public wxFilterOutputStream { public: - wxBufferedOutputStream(wxOutputStream& stream); - ~wxBufferedOutputStream(); + // if a non NULL buffer is given to the stream, it will be deleted by it + wxBufferedOutputStream(wxOutputStream& stream, + wxStreamBuffer *buffer = NULL); + virtual ~wxBufferedOutputStream(); wxOutputStream& Write(const void *buffer, size_t size); @@ -352,18 +391,22 @@ public: size_t GetSize() const; + // the buffer given to the stream will be deleted by it + void SetOutputStreamBuffer(wxStreamBuffer *buffer); + wxStreamBuffer *GetOutputStreamBuffer() const { return m_o_streambuf; } + + // deprecated, for compatibility only wxStreamBuffer *OutputStreamBuffer() const { return m_o_streambuf; } protected: - size_t OnSysWrite(const void *buffer, size_t bufsize); - off_t OnSysSeek(off_t seek, wxSeekMode mode); - off_t OnSysTell() const; + virtual size_t OnSysWrite(const void *buffer, size_t bufsize); + virtual off_t OnSysSeek(off_t seek, wxSeekMode mode); + virtual off_t OnSysTell() const; wxStreamBuffer *m_o_streambuf; }; -#endif - // wxUSE_STREAMS +#endif // wxUSE_STREAMS + +#endif // _WX_WXSTREAM_H__ -#endif - // _WX_WXSTREAM_H__ diff --git a/src/common/stream.cpp b/src/common/stream.cpp index 38499f5793..99baaa5634 100644 --- a/src/common/stream.cpp +++ b/src/common/stream.cpp @@ -17,8 +17,9 @@ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "stream.h" + #pragma implementation "stream.h" #endif // For compilers that support precompilation, includes "wx.h". @@ -129,6 +130,16 @@ wxStreamBuffer::~wxStreamBuffer() delete m_stream; } +wxInputStream *wxStreamBuffer::GetInputStream() const +{ + return m_mode == write ? NULL : (wxInputStream *)m_stream; +} + +wxOutputStream *wxStreamBuffer::GetOutputStream() const +{ + return m_mode == read ? NULL : (wxOutputStream *)m_stream; +} + void wxStreamBuffer::SetBufferIO(void *buffer_start, void *buffer_end, bool takeOwnership) @@ -185,9 +196,11 @@ void wxStreamBuffer::ResetBuffer() // fill the buffer with as much data as possible (only for read buffers) bool wxStreamBuffer::FillBuffer() { - wxCHECK_MSG( m_stream, FALSE, _T("should have a stream in wxStreamBuffer") ); + wxInputStream *inStream = GetInputStream(); + + wxCHECK_MSG( inStream, FALSE, _T("should have a stream in wxStreamBuffer") ); - size_t count = m_stream->OnSysRead(m_buffer_start, m_buffer_size); + size_t count = inStream->OnSysRead(m_buffer_start, m_buffer_size); if ( !count ) return FALSE; @@ -206,10 +219,12 @@ bool wxStreamBuffer::FlushBuffer() if ( m_buffer_pos == m_buffer_start ) return FALSE; - wxCHECK_MSG( m_stream, FALSE, _T("should have a stream in wxStreamBuffer") ); + wxOutputStream *outStream = GetOutputStream(); + + wxCHECK_MSG( outStream, FALSE, _T("should have a stream in wxStreamBuffer") ); size_t current = m_buffer_pos - m_buffer_start; - size_t count = m_stream->OnSysWrite(m_buffer_start, current); + size_t count = outStream->OnSysWrite(m_buffer_start, current); if ( count != current ) return FALSE; @@ -281,12 +296,14 @@ void wxStreamBuffer::PutToBuffer(const void *buffer, size_t size) void wxStreamBuffer::PutChar(char c) { - wxCHECK_RET( m_stream, _T("should have a stream in wxStreamBuffer") ); + wxOutputStream *outStream = GetOutputStream(); + + wxCHECK_RET( outStream, _T("should have a stream in wxStreamBuffer") ); // if we don't have buffer at all, just forward this call to the stream, if ( !HasBuffer() ) { - m_stream->OnSysWrite(&c, 1); + outStream->OnSysWrite(&c, 1); } else { @@ -324,12 +341,14 @@ char wxStreamBuffer::Peek() char wxStreamBuffer::GetChar() { - wxCHECK_MSG( m_stream, 0, _T("should have a stream in wxStreamBuffer") ); + wxInputStream *inStream = GetInputStream(); + + wxCHECK_MSG( inStream, 0, _T("should have a stream in wxStreamBuffer") ); char c; if ( !HasBuffer() ) { - m_stream->OnSysRead(&c, 1); + inStream->OnSysRead(&c, 1); } else { @@ -350,16 +369,16 @@ char wxStreamBuffer::GetChar() size_t wxStreamBuffer::Read(void *buffer, size_t size) { - wxCHECK_MSG( m_stream, 0, _T("should have a stream in wxStreamBuffer") ); + wxInputStream *inStream = GetInputStream(); - wxCHECK_MSG( m_mode != write, 0, _T("can't read from this buffer") ); + wxCHECK_MSG( inStream, 0, _T("should have a stream in wxStreamBuffer") ); // lasterror is reset before all new IO calls m_stream->m_lasterror = wxStream_NOERROR; if ( !HasBuffer() ) { - m_stream->m_lastcount = m_stream->OnSysRead(buffer, size); + m_stream->m_lastcount = inStream->OnSysRead(buffer, size); } else // we have a buffer, use it { @@ -421,8 +440,9 @@ size_t wxStreamBuffer::Read(wxStreamBuffer *dbuf) size_t wxStreamBuffer::Write(const void *buffer, size_t size) { - wxCHECK_MSG( m_stream, 0, _T("should have a stream in wxStreamBuffer") ); - wxCHECK_MSG( m_mode != read, 0, _T("can't write to this buffer") ); + wxOutputStream *outStream = GetOutputStream(); + + wxCHECK_MSG( outStream, 0, _T("should have a stream in wxStreamBuffer") ); // lasterror is reset before all new IO calls m_stream->m_lasterror = wxStream_NOERROR; @@ -430,7 +450,7 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t size) if ( !HasBuffer() && m_fixed ) { // no buffer, just forward the call to the stream - m_stream->m_lastcount = m_stream->OnSysWrite(buffer, size); + m_stream->m_lastcount = outStream->OnSysWrite(buffer, size); } else // we [may] have a buffer, use it { @@ -607,26 +627,6 @@ wxStreamBase::~wxStreamBase() { } -size_t wxStreamBase::OnSysRead(void *WXUNUSED(buffer), size_t WXUNUSED(size)) -{ - return 0; -} - -size_t wxStreamBase::OnSysWrite(const void *WXUNUSED(buffer), size_t WXUNUSED(bufsize)) -{ - return 0; -} - -off_t wxStreamBase::OnSysSeek(off_t WXUNUSED(seek), wxSeekMode WXUNUSED(mode)) -{ - return wxInvalidOffset; -} - -off_t wxStreamBase::OnSysTell() const -{ - return wxInvalidOffset; -} - // ---------------------------------------------------------------------------- // wxInputStream // ---------------------------------------------------------------------------- @@ -643,6 +643,12 @@ wxInputStream::~wxInputStream() free(m_wback); } +size_t wxInputStream::OnSysRead(void * WXUNUSED(buffer), + size_t WXUNUSED(bufsize)) +{ + return 0; +} + bool wxInputStream::Eof() const { wxInputStream *self = wxConstCast(this, wxInputStream); @@ -843,6 +849,12 @@ wxOutputStream::~wxOutputStream() { } +size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer), + size_t WXUNUSED(bufsize)) +{ + return 0; +} + void wxOutputStream::PutC(char c) { Write(&c, 1); @@ -945,6 +957,7 @@ off_t wxCountingOutputStream::OnSysTell() const wxFilterInputStream::wxFilterInputStream() { + m_parent_i_stream = NULL; } wxFilterInputStream::wxFilterInputStream(wxInputStream& stream) @@ -962,6 +975,7 @@ wxFilterInputStream::~wxFilterInputStream() wxFilterOutputStream::wxFilterOutputStream() { + m_parent_o_stream = NULL; } wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream) @@ -977,12 +991,21 @@ wxFilterOutputStream::~wxFilterOutputStream() // wxBufferedInputStream // ---------------------------------------------------------------------------- -wxBufferedInputStream::wxBufferedInputStream(wxInputStream& s) +wxBufferedInputStream::wxBufferedInputStream(wxInputStream& s, + wxStreamBuffer *buffer) : wxFilterInputStream(s) { - m_i_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::read); + if ( buffer ) + { + // use the buffer provided by the user + m_i_streambuf = buffer; + } + else // create a default buffer + { + m_i_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::read); - m_i_streambuf->SetBufferIO(1024); + m_i_streambuf->SetBufferIO(1024); + } } wxBufferedInputStream::~wxBufferedInputStream() @@ -1003,7 +1026,7 @@ wxInputStream& wxBufferedInputStream::Read(void *buf, size_t size) retsize = GetWBack(buf, size); m_lastcount = retsize; - if (retsize == size) + if ( retsize == size ) { m_lasterror = wxStream_NOERROR; return *this; @@ -1041,15 +1064,32 @@ off_t wxBufferedInputStream::OnSysTell() const return m_parent_i_stream->TellI(); } +void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer *buffer) +{ + wxCHECK_RET( buffer, _T("wxBufferedInputStream needs buffer") ); + + delete m_i_streambuf; + m_i_streambuf = buffer; +} + // ---------------------------------------------------------------------------- // wxBufferedOutputStream // ---------------------------------------------------------------------------- -wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream& s) +wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream& s, + wxStreamBuffer *buffer) : wxFilterOutputStream(s) { - m_o_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::write); - m_o_streambuf->SetBufferIO(1024); + if ( buffer ) + { + m_o_streambuf = buffer; + } + else // create a default one + { + m_o_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::write); + + m_o_streambuf->SetBufferIO(1024); + } } wxBufferedOutputStream::~wxBufferedOutputStream() @@ -1102,6 +1142,14 @@ size_t wxBufferedOutputStream::GetSize() const return m_parent_o_stream->GetSize() + m_o_streambuf->GetIntPosition(); } +void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer *buffer) +{ + wxCHECK_RET( buffer, _T("wxBufferedOutputStream needs buffer") ); + + delete m_o_streambuf; + m_o_streambuf = buffer; +} + // ---------------------------------------------------------------------------- // Some IOManip function // ---------------------------------------------------------------------------- -- 2.45.2