X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8f0ff178513f59471bfce85cf6d7a78f4f4818ab..6968a3b87cee46f5c5af9b46e1ef97f17133cef7:/include/wx/stream.h diff --git a/include/wx/stream.h b/include/wx/stream.h index 5799895fe0..80c81bcbdc 100644 --- a/include/wx/stream.h +++ b/include/wx/stream.h @@ -12,10 +12,6 @@ #ifndef _WX_WXSTREAM_H__ #define _WX_WXSTREAM_H__ -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma interface "stream.h" -#endif - #include "wx/defs.h" #if wxUSE_STREAMS @@ -25,9 +21,9 @@ #include "wx/string.h" #include "wx/filefn.h" // for wxFileOffset, wxInvalidOffset and wxSeekMode -class WXDLLIMPEXP_BASE wxStreamBase; -class WXDLLIMPEXP_BASE wxInputStream; -class WXDLLIMPEXP_BASE wxOutputStream; +class WXDLLIMPEXP_FWD_BASE wxStreamBase; +class WXDLLIMPEXP_FWD_BASE wxInputStream; +class WXDLLIMPEXP_FWD_BASE wxOutputStream; typedef wxInputStream& (*__wxInputManip)(wxInputStream&); typedef wxOutputStream& (*__wxOutputManip)(wxOutputStream&); @@ -46,18 +42,7 @@ enum wxStreamError wxSTREAM_READ_ERROR // generic read error }; -// compatibility -#if WXWIN_COMPATIBILITY_2_2 - #define wxStream_NOERROR wxSTREAM_NOERROR - #define wxStream_EOF wxSTREAM_EOF - #define wxStream_WRITE_ERR wxSTREAM_WRITE_ERROR - #define wxStream_READ_ERR wxSTREAM_READ_ERROR - - #define wxSTREAM_NO_ERR wxSTREAM_NO_ERROR - #define wxSTREAM_NOERROR wxSTREAM_NO_ERROR - #define wxSTREAM_WRITE_ERR wxSTREAM_WRITE_ERROR - #define wxSTREAM_READ_ERR wxSTREAM_READ_ERROR -#endif // WXWIN_COMPATIBILITY_2_2 +const int wxEOF = -1; // ============================================================================ // base stream classes: wxInputStream and wxOutputStream @@ -67,7 +52,7 @@ enum wxStreamError // wxStreamBase: common (but non virtual!) base for all stream classes // --------------------------------------------------------------------------- -class WXDLLIMPEXP_BASE wxStreamBase +class WXDLLIMPEXP_BASE wxStreamBase : public wxObject { public: wxStreamBase(); @@ -75,21 +60,18 @@ public: // error testing wxStreamError GetLastError() const { return m_lasterror; } - bool IsOk() const { return GetLastError() == wxSTREAM_NO_ERROR; } + virtual bool IsOk() const { return GetLastError() == wxSTREAM_NO_ERROR; } bool operator!() const { return !IsOk(); } // reset the stream state - void Reset() { m_lasterror = wxSTREAM_NO_ERROR; } + void Reset(wxStreamError error = wxSTREAM_NO_ERROR) { m_lasterror = error; } // this doesn't make sense for all streams, always test its return value virtual size_t GetSize() const; virtual wxFileOffset GetLength() const { return wxInvalidOffset; } -#if WXWIN_COMPATIBILITY_2_2 - // deprecated, for compatibility only - wxStreamError LastError() const { return m_lasterror; } - size_t StreamSize() const { return GetSize(); } -#endif // WXWIN_COMPATIBILITY_2_2 + // returns true if the streams supports seeking to arbitrary offsets + virtual bool IsSeekable() const { return false; } protected: virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode); @@ -100,7 +82,8 @@ protected: friend class wxStreamBuffer; - DECLARE_NO_COPY_CLASS(wxStreamBase) + DECLARE_ABSTRACT_CLASS(wxStreamBase) + wxDECLARE_NO_COPY_CLASS(wxStreamBase); }; // ---------------------------------------------------------------------------- @@ -126,11 +109,11 @@ public: // undefined), otherwise 1 virtual char Peek(); - // return one character from the stream, blocking until it appears if + // return one byte from the stream, blocking until it appears if // necessary // - // if EOF, return value is undefined and LastRead() will return 0 and not 1 - char GetC(); + // on success returns a value between 0 - 255, or wxEOF on EOF or error. + int GetC(); // read at most the given number of bytes from the stream // @@ -208,7 +191,7 @@ public: protected: // do read up to size bytes of data into the provided buffer // - // this method should return 0 if EOF has been reached or an error occured + // this method should return 0 if EOF has been reached or an error occurred // (m_lasterror should be set accordingly as well) or the number of bytes // read virtual size_t OnSysRead(void *buffer, size_t size) = 0; @@ -234,7 +217,8 @@ protected: friend class wxStreamBuffer; - DECLARE_NO_COPY_CLASS(wxInputStream) + DECLARE_ABSTRACT_CLASS(wxInputStream) + wxDECLARE_NO_COPY_CLASS(wxInputStream); }; // ---------------------------------------------------------------------------- @@ -269,7 +253,8 @@ protected: friend class wxStreamBuffer; - DECLARE_NO_COPY_CLASS(wxOutputStream) + DECLARE_ABSTRACT_CLASS(wxOutputStream) + wxDECLARE_NO_COPY_CLASS(wxOutputStream); }; // ============================================================================ @@ -286,7 +271,8 @@ public: wxCountingOutputStream(); wxFileOffset GetLength() const; - bool Ok() const { return true; } + bool Ok() const { return IsOk(); } + bool IsOk() const { return true; } protected: virtual size_t OnSysWrite(const void *buffer, size_t size); @@ -295,7 +281,8 @@ protected: size_t m_currentPos; - DECLARE_NO_COPY_CLASS(wxCountingOutputStream) + DECLARE_DYNAMIC_CLASS(wxCountingOutputStream) + wxDECLARE_NO_COPY_CLASS(wxCountingOutputStream); }; // --------------------------------------------------------------------------- @@ -307,6 +294,7 @@ class WXDLLIMPEXP_BASE wxFilterInputStream : public wxInputStream public: wxFilterInputStream(); wxFilterInputStream(wxInputStream& stream); + wxFilterInputStream(wxInputStream *stream); virtual ~wxFilterInputStream(); char Peek() { return m_parent_i_stream->Peek(); } @@ -317,8 +305,10 @@ public: protected: wxInputStream *m_parent_i_stream; + bool m_owns; - DECLARE_NO_COPY_CLASS(wxFilterInputStream) + DECLARE_ABSTRACT_CLASS(wxFilterInputStream) + wxDECLARE_NO_COPY_CLASS(wxFilterInputStream); }; class WXDLLIMPEXP_BASE wxFilterOutputStream : public wxOutputStream @@ -326,16 +316,85 @@ class WXDLLIMPEXP_BASE wxFilterOutputStream : public wxOutputStream public: wxFilterOutputStream(); wxFilterOutputStream(wxOutputStream& stream); + wxFilterOutputStream(wxOutputStream *stream); virtual ~wxFilterOutputStream(); wxFileOffset GetLength() const { return m_parent_o_stream->GetLength(); } wxOutputStream *GetFilterOutputStream() const { return m_parent_o_stream; } + bool Close(); + protected: wxOutputStream *m_parent_o_stream; + bool m_owns; + + DECLARE_ABSTRACT_CLASS(wxFilterOutputStream) + wxDECLARE_NO_COPY_CLASS(wxFilterOutputStream); +}; + +enum wxStreamProtocolType +{ + wxSTREAM_PROTOCOL, // wxFileSystem protocol (should be only one) + wxSTREAM_MIMETYPE, // MIME types the stream handles + wxSTREAM_ENCODING, // The HTTP Content-Encodings the stream handles + wxSTREAM_FILEEXT // File extensions the stream handles +}; + +void WXDLLIMPEXP_BASE wxUseFilterClasses(); + +class WXDLLIMPEXP_BASE wxFilterClassFactoryBase : public wxObject +{ +public: + virtual ~wxFilterClassFactoryBase() { } + + wxString GetProtocol() const { return wxString(*GetProtocols()); } + wxString PopExtension(const wxString& location) const; + + virtual const wxChar * const *GetProtocols(wxStreamProtocolType type + = wxSTREAM_PROTOCOL) const = 0; + + bool CanHandle(const wxString& protocol, + wxStreamProtocolType type + = wxSTREAM_PROTOCOL) const; + +protected: + wxString::size_type FindExtension(const wxString& location) const; + + DECLARE_ABSTRACT_CLASS(wxFilterClassFactoryBase) +}; + +class WXDLLIMPEXP_BASE wxFilterClassFactory : public wxFilterClassFactoryBase +{ +public: + virtual ~wxFilterClassFactory() { } + + virtual wxFilterInputStream *NewStream(wxInputStream& stream) const = 0; + virtual wxFilterOutputStream *NewStream(wxOutputStream& stream) const = 0; + virtual wxFilterInputStream *NewStream(wxInputStream *stream) const = 0; + virtual wxFilterOutputStream *NewStream(wxOutputStream *stream) const = 0; + + static const wxFilterClassFactory *Find(const wxString& protocol, + wxStreamProtocolType type + = wxSTREAM_PROTOCOL); + + static const wxFilterClassFactory *GetFirst(); + const wxFilterClassFactory *GetNext() const { return m_next; } - DECLARE_NO_COPY_CLASS(wxFilterOutputStream) + void PushFront() { Remove(); m_next = sm_first; sm_first = this; } + void Remove(); + +protected: + wxFilterClassFactory() : m_next(this) { } + + wxFilterClassFactory& operator=(const wxFilterClassFactory&) + { return *this; } + +private: + static wxFilterClassFactory *sm_first; + wxFilterClassFactory *m_next; + + DECLARE_ABSTRACT_CLASS(wxFilterClassFactory) }; // ============================================================================ @@ -357,7 +416,23 @@ public: read_write }; - wxStreamBuffer(wxStreamBase& stream, BufMode mode); + wxStreamBuffer(wxStreamBase& stream, BufMode mode) + { + InitWithStream(stream, mode); + } + + wxStreamBuffer(size_t bufsize, wxInputStream& stream) + { + InitWithStream(stream, read); + SetBufferIO(bufsize); + } + + wxStreamBuffer(size_t bufsize, wxOutputStream& stream) + { + InitWithStream(stream, write); + SetBufferIO(bufsize); + } + wxStreamBuffer(const wxStreamBuffer& buf); virtual ~wxStreamBuffer(); @@ -375,6 +450,7 @@ public: // Buffer control void ResetBuffer(); + void Truncate(); // NB: the buffer must always be allocated with malloc() if takeOwn is // true as it will be deallocated by free() @@ -384,7 +460,7 @@ public: void *GetBufferStart() const { return m_buffer_start; } void *GetBufferEnd() const { return m_buffer_end; } void *GetBufferPos() const { return m_buffer_pos; } - size_t GetBufferSize() const { return m_buffer_size; } + size_t GetBufferSize() const { return m_buffer_end - m_buffer_start; } size_t GetIntPosition() const { return m_buffer_pos - m_buffer_start; } void SetIntPosition(size_t pos) { m_buffer_pos = m_buffer_start + pos; } size_t GetLastAccess() const { return m_buffer_end - m_buffer_start; } @@ -399,7 +475,7 @@ public: // misc accessors wxStreamBase *GetStream() const { return m_stream; } - bool HasBuffer() const { return m_buffer_size != 0; } + bool HasBuffer() const { return m_buffer_start != m_buffer_end; } bool IsFixed() const { return m_fixed; } bool IsFlushable() const { return m_flushable; } @@ -408,8 +484,10 @@ public: wxInputStream *GetInputStream() const; wxOutputStream *GetOutputStream() const; +#if WXWIN_COMPATIBILITY_2_6 // deprecated, for compatibility only - wxStreamBase *Stream() { return m_stream; } + wxDEPRECATED( wxStreamBase *Stream() ); +#endif // WXWIN_COMPATIBILITY_2_6 // this constructs a dummy wxStreamBuffer, used by (and exists for) // wxMemoryStreams only, don't use! @@ -425,6 +503,9 @@ protected: // common part of several ctors void Init(); + // common part of ctors taking wxStreamBase parameter + void InitWithStream(wxStreamBase& stream, BufMode mode); + // init buffer variables to be empty void InitBuffer(); @@ -437,10 +518,6 @@ protected: *m_buffer_end, *m_buffer_pos; - // the buffer size - // FIXME: isn't it the same as m_buffer_end - m_buffer_start? (VZ) - size_t m_buffer_size; - // the stream we're associated with wxStreamBase *m_stream; @@ -452,13 +529,8 @@ protected: m_fixed, m_flushable; -private: -// Cannot use -// DECLARE_NO_COPY_CLASS(wxStreamBuffer) -// because copy constructor is explicitly declared above; -// but no copy assignment operator is defined, so declare -// it private to prevent the compiler from defining it: - wxStreamBuffer& operator=(const wxStreamBuffer&); + + wxDECLARE_NO_ASSIGN_CLASS(wxStreamBuffer); }; // --------------------------------------------------------------------------- @@ -468,9 +540,19 @@ private: class WXDLLIMPEXP_BASE wxBufferedInputStream : public wxFilterInputStream { public: - // if a non NULL buffer is given to the stream, it will be deleted by it + // create a buffered stream on top of the specified low-level stream + // + // if a non NULL buffer is given to the stream, it will be deleted by it, + // otherwise a default 1KB buffer will be used wxBufferedInputStream(wxInputStream& stream, wxStreamBuffer *buffer = NULL); + + // ctor allowing to specify the buffer size, it's just a more convenient + // alternative to creating wxStreamBuffer, calling its SetBufferIO(bufsize) + // and using the ctor above + wxBufferedInputStream(wxInputStream& stream, size_t bufsize); + + virtual ~wxBufferedInputStream(); char Peek(); @@ -479,13 +561,16 @@ public: // Position functions wxFileOffset SeekI(wxFileOffset pos, wxSeekMode mode = wxFromStart); wxFileOffset TellI() const; + bool IsSeekable() const { return m_parent_i_stream->IsSeekable(); } // the buffer given to the stream will be deleted by it void SetInputStreamBuffer(wxStreamBuffer *buffer); wxStreamBuffer *GetInputStreamBuffer() const { return m_i_streambuf; } +#if WXWIN_COMPATIBILITY_2_6 // deprecated, for compatibility only - wxStreamBuffer *InputStreamBuffer() const { return m_i_streambuf; } + wxDEPRECATED( wxStreamBuffer *InputStreamBuffer() const ); +#endif // WXWIN_COMPATIBILITY_2_6 protected: virtual size_t OnSysRead(void *buffer, size_t bufsize); @@ -494,7 +579,7 @@ protected: wxStreamBuffer *m_i_streambuf; - DECLARE_NO_COPY_CLASS(wxBufferedInputStream) + wxDECLARE_NO_COPY_CLASS(wxBufferedInputStream); }; // ---------------------------------------------------------------------------- @@ -504,9 +589,18 @@ protected: class WXDLLIMPEXP_BASE wxBufferedOutputStream : public wxFilterOutputStream { public: - // if a non NULL buffer is given to the stream, it will be deleted by it + // create a buffered stream on top of the specified low-level stream + // + // if a non NULL buffer is given to the stream, it will be deleted by it, + // otherwise a default 1KB buffer will be used wxBufferedOutputStream(wxOutputStream& stream, wxStreamBuffer *buffer = NULL); + + // ctor allowing to specify the buffer size, it's just a more convenient + // alternative to creating wxStreamBuffer, calling its SetBufferIO(bufsize) + // and using the ctor above + wxBufferedOutputStream(wxOutputStream& stream, size_t bufsize); + virtual ~wxBufferedOutputStream(); wxOutputStream& Write(const void *buffer, size_t size); @@ -514,6 +608,7 @@ public: // Position functions wxFileOffset SeekO(wxFileOffset pos, wxSeekMode mode = wxFromStart); wxFileOffset TellO() const; + bool IsSeekable() const { return m_parent_o_stream->IsSeekable(); } void Sync(); bool Close(); @@ -524,8 +619,10 @@ public: void SetOutputStreamBuffer(wxStreamBuffer *buffer); wxStreamBuffer *GetOutputStreamBuffer() const { return m_o_streambuf; } +#if WXWIN_COMPATIBILITY_2_6 // deprecated, for compatibility only - wxStreamBuffer *OutputStreamBuffer() const { return m_o_streambuf; } + wxDEPRECATED( wxStreamBuffer *OutputStreamBuffer() const ); +#endif // WXWIN_COMPATIBILITY_2_6 protected: virtual size_t OnSysWrite(const void *buffer, size_t bufsize); @@ -534,10 +631,63 @@ protected: wxStreamBuffer *m_o_streambuf; - DECLARE_NO_COPY_CLASS(wxBufferedOutputStream) + wxDECLARE_NO_COPY_CLASS(wxBufferedOutputStream); +}; + +#if WXWIN_COMPATIBILITY_2_6 + inline wxStreamBase *wxStreamBuffer::Stream() { return m_stream; } + inline wxStreamBuffer *wxBufferedInputStream::InputStreamBuffer() const { return m_i_streambuf; } + inline wxStreamBuffer *wxBufferedOutputStream::OutputStreamBuffer() const { return m_o_streambuf; } +#endif // WXWIN_COMPATIBILITY_2_6 + +// --------------------------------------------------------------------------- +// wxWrapperInputStream: forwards all IO to another stream. +// --------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxWrapperInputStream : public wxFilterInputStream +{ +public: + // Constructor fully initializing the stream. The overload taking pointer + // takes ownership of the parent stream, the one taking reference does not. + // + // Notice that this class also has a default ctor but it's protected as the + // derived class is supposed to take care of calling InitParentStream() if + // it's used. + wxWrapperInputStream(wxInputStream& stream); + wxWrapperInputStream(wxInputStream* stream); + + // Override the base class methods to forward to the wrapped stream. + virtual wxFileOffset GetLength() const; + virtual bool IsSeekable() const; + +protected: + virtual size_t OnSysRead(void *buffer, size_t size); + virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode); + virtual wxFileOffset OnSysTell() const; + + // Ensure that our own last error is the same as that of the real stream. + // + // This method is const because the error must be updated even from const + // methods (in other words, it really should have been mutable in the first + // place). + void SynchronizeLastError() const + { + const_cast(this)-> + Reset(m_parent_i_stream->GetLastError()); + } + + // Default constructor, use InitParentStream() later. + wxWrapperInputStream(); + + // Set up the wrapped stream for an object initialized using the default + // constructor. The ownership logic is the same as above. + void InitParentStream(wxInputStream& stream); + void InitParentStream(wxInputStream* stream); + + wxDECLARE_NO_COPY_CLASS(wxWrapperInputStream); }; + #endif // wxUSE_STREAMS #endif // _WX_WXSTREAM_H__ -