]> git.saurik.com Git - wxWidgets.git/blobdiff - interface/wx/stream.h
Don't look for catalogs in AddCatalogLookupPathPrefix() path directly.
[wxWidgets.git] / interface / wx / stream.h
index 6de6fa871c4d65d5f23cb4848416562a438998eb..51b983dd8ad9a1edab64fa7289a74252df3ff566 100644 (file)
 // Purpose:     interface of wxStreamBase and its derived classes
 // Author:      wxWidgets team
 // RCS-ID:      $Id$
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
+
 /**
-    @class wxCountingOutputStream
+    These enumeration values are returned by various functions in the context
+    of wxStream classes.
+*/
+enum wxStreamError
+{
+    wxSTREAM_NO_ERROR = 0,      //!< No error occurred.
+    wxSTREAM_EOF,               //!< EOF reached in Read() or similar.
+    wxSTREAM_WRITE_ERROR,       //!< generic write error on the last write call.
+    wxSTREAM_READ_ERROR         //!< generic read error on the last read call.
+};
 
-    wxCountingOutputStream is a specialized output stream which does not write any
-    data anywhere, instead it counts how many bytes would get written if this were a
-    normal stream. This can sometimes be useful or required if some data gets
-    serialized to a stream or compressed by using stream compression and thus the
-    final size of the stream cannot be known other than pretending to write the stream.
-    One case where the resulting size would have to be known is if the data has
-    to be written to a piece of memory and the memory has to be allocated before
-    writing to it (which is probably always the case when writing to a memory stream).
+/**
+    @class wxStreamBase
+
+    This class is the base class of most stream related classes in wxWidgets.
+    It must not be used directly.
 
     @library{wxbase}
     @category{streams}
+
+    @see wxStreamBuffer
 */
-class wxCountingOutputStream : public wxOutputStream
+class wxStreamBase
 {
 public:
     /**
-        Creates a wxCountingOutputStream object.
+        Creates a dummy stream object. It doesn't do anything.
     */
-    wxCountingOutputStream();
+    wxStreamBase();
 
     /**
         Destructor.
     */
-    virtual ~wxCountingOutputStream();
+    virtual ~wxStreamBase();
 
     /**
-        Returns the current size of the stream.
+        This function returns the last error.
     */
-    size_t GetSize() const;
-};
-
+    wxStreamError GetLastError() const;
 
+    /**
+        Returns the length of the stream in bytes. If the length cannot be
+        determined (this is always the case for socket streams for example),
+        returns ::wxInvalidOffset.
 
-/**
-    @class wxBufferedInputStream
+        @since 2.5.4
+    */
+    virtual wxFileOffset GetLength() const;
 
-    This stream acts as a cache. It caches the bytes read from the specified
-    input stream (see wxFilterInputStream).
-    It uses wxStreamBuffer and sets the default in-buffer size to 1024 bytes.
-    This class may not be used without some other stream to read the data
-    from (such as a file stream or a memory stream).
+    /**
+        This function returns the size of the stream.
+        For example, for a file it is the size of the file.
 
-    @library{wxbase}
-    @category{streams}
+        @warning
+        There are streams which do not have size by definition, such as socket
+        streams. In that cases, GetSize() returns 0 so you should always test its
+        return value.
+    */
+    virtual size_t GetSize() const;
 
-    @see wxStreamBuffer, wxInputStream, wxBufferedOutputStream
-*/
-class wxBufferedInputStream : public wxFilterInputStream
-{
-public:
     /**
-        Constructor using the provided buffer or default.
+        Returns @true if no error occurred on the stream.
 
-        @param stream
-            The associated low-level stream.
-        @param buffer
-            The buffer to use if non-@NULL. Notice that the ownership of this
-            buffer is taken by the stream, i.e. it will delete it. If this
-            parameter is @NULL a default 1KB buffer is used.
+        @see GetLastError()
     */
-    wxBufferedInputStream(wxInputStream& stream,
-                          wxStreamBuffer *buffer = NULL);
+    virtual bool IsOk() const;
 
     /**
-        Constructor allowing to specify the size of the buffer.
+        Returns @true if the stream supports seeking to arbitrary offsets.
+    */
+    virtual bool IsSeekable() const;
 
-        This is just a more convenient alternative to creating a wxStreamBuffer
-        of the given size and using the other overloaded constructor of this
-        class.
+    /**
+        Resets the stream state.
 
-        @param stream
-            The associated low-level stream.
-        @param bufsize
-            The size of the buffer, in bytes.
+        By default, resets the stream to good state, i.e. clears any errors.
+        Since wxWidgets 2.9.3 can be also used to explicitly set the state to
+        the specified error (the @a error argument didn't exist in the previous
+        versions).
 
-        @since 2.9.0
+        @see GetLastError()
      */
-    wxBufferedInputStream(wxInputStream& stream, size_t bufsize);
+    void Reset(wxStreamError error = wxSTREAM_NO_ERROR);
 
     /**
-        Destructor.
+        Returns the opposite of IsOk().
+        You can use this function to test the validity of the stream as if
+        it was a pointer:
+
+        @code
+            bool DoSomething(wxInputStream& stream)
+            {
+                wxInt32 data;
+                if (!stream.Read(&data, 4))
+                    return false;
+                ...
+            }
+        @endcode
     */
-    virtual ~wxBufferedInputStream();
-};
+    bool operator!() const;
+
+protected:
+
+    /**
+        Internal function.
+        It is called when the stream needs to change the current position.
+
+        @param pos
+            Offset to seek to.
+        @param mode
+            One of the ::wxSeekMode enumeration values.
+
+        @return The new stream position or ::wxInvalidOffset on error.
+    */
+    virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
 
+    /**
+        Internal function.
+        It is called when the stream needs to know the real position.
 
+        @return The current stream position.
+    */
+    virtual wxFileOffset OnSysTell() const;
+};
 
 /**
     @class wxStreamBuffer
 
-    @todo WRITE A DESCRIPTION
+    wxStreamBuffer is a cache manager for wxStreamBase: it manages a stream buffer
+    linked to a stream.
+
+    Each stream always has one autoinitialized stream buffer, but you may
+    attach more of them to the same stream.
 
     @library{wxbase}
     @category{streams}
 
-    @see wxStreamBase
+    @see wxStreamBase, @ref overview_stream
 */
 class wxStreamBuffer
 {
 public:
+    /** BufMode flags */
+    enum BufMode
+    {
+        read,
+        write,
+        read_write
+    };
 
     /**
         Constructor, creates a new stream buffer using @a stream as a parent stream
@@ -127,7 +175,9 @@ public:
 
         @code
         streambuffer.Read(...);
-        streambuffer2.Read(...); // This call erases previous error messages set by 'streambuffer'
+        streambuffer2.Read(...);
+            // This call erases previous error messages set by 'streambuffer'
+            // assuming that both instances are stream buffers for the same stream
         @endcode
 
         @see SetBufferIO()
@@ -141,8 +191,13 @@ public:
         and calling SetBufferIO() but is more convenient.
 
         @since 2.9.0
+
+        @param bufsize
+            The size of buffer in bytes.
+        @param stream
+            The associated input stream, the buffer will be used in read mode.
      */
-    wxStreamBuffer(wxInputStream& stream, size_t bufsize);
+    wxStreamBuffer(size_t bufsize, wxInputStream& stream);
 
     /**
         Constructor for an output buffer of the specified size.
@@ -151,8 +206,13 @@ public:
         and calling SetBufferIO() but is more convenient.
 
         @since 2.9.0
+
+        @param bufsize
+            The size of buffer in bytes.
+        @param stream
+            The associated output stream, the buffer will be used in write mode.
      */
-    wxStreamBuffer(wxOutputStream& stream, size_t bufsize);
+    wxStreamBuffer(size_t bufsize, wxOutputStream& stream);
 
     /**
         Constructor; creates a new empty stream buffer which won't flush any data
@@ -188,7 +248,7 @@ public:
         Destructor.
         It finalizes all IO calls and frees all internal buffers if necessary.
     */
-    wxStreamBuffer();
+    ~wxStreamBuffer();
 
     /**
         Fill the IO buffer.
@@ -290,7 +350,7 @@ public:
 
         @see Write()
     */
-    Return value size_t Read(wxStreamBuffer* buffer);
+    size_t Read(wxStreamBuffer* buffer);
 
     /**
         Resets to the initial state variables concerning the buffer.
@@ -307,7 +367,7 @@ public:
 
         @return Upon successful completion, it returns the new offset as
                 measured in bytes from the beginning of the stream.
-                Otherwise, it returns wxInvalidOffset.
+                Otherwise, it returns ::wxInvalidOffset.
     */
     virtual wxFileOffset Seek(wxFileOffset pos, wxSeekMode mode);
 
@@ -326,7 +386,7 @@ public:
 
         @see wxStreamBuffer(), Fixed(), Flushable()
     */
-    void SetBufferIO(char* buffer_start, char* buffer_end);
+    void SetBufferIO(void* start, void* end, bool takeOwnership = false);
 
     /**
         Destroys or invalidates the previous IO buffer and allocates a new one of the
@@ -364,7 +424,7 @@ public:
         the stream.
 
         @return Returns the current position in the stream if possible,
-                wxInvalidOffset in the other case.
+                ::wxInvalidOffset in the other case.
     */
     virtual wxFileOffset Tell() const;
 
@@ -394,6 +454,11 @@ public:
     @class wxOutputStream
 
     wxOutputStream is an abstract base class which may not be used directly.
+    It is the base class of all streams which provide a Write() function,
+    i.e. which can be used to output data (e.g. to a file, to a socket, etc).
+
+    If you want to create your own output stream, you'll need to derive from this
+    class and implement the protected OnSysWrite() function only.
 
     @library{wxbase}
     @category{streams}
@@ -443,7 +508,7 @@ public:
         @param mode
             One of wxFromStart, wxFromEnd, wxFromCurrent.
 
-        @return The new stream position or wxInvalidOffset on error.
+        @return The new stream position or ::wxInvalidOffset on error.
     */
     virtual wxFileOffset SeekO(wxFileOffset pos, wxSeekMode mode = wxFromStart);
 
@@ -463,7 +528,7 @@ public:
         This function returns a reference on the current object, so the user can
         test any states of the stream right away.
     */
-    wxOutputStream& Write(const void* buffer, size_t size);
+    virtual wxOutputStream& Write(const void* buffer, size_t size);
 
     /**
         Reads data from the specified input stream and stores them
@@ -471,138 +536,414 @@ public:
         by one of the two streams.
     */
     wxOutputStream& Write(wxInputStream& stream_in);
-};
 
+    /**
+        Writes exactly the specified number of bytes from the buffer.
+
+        Returns @true if exactly @a size bytes were written. Otherwise, returns
+        @false and LastWrite() should be used to retrieve the exact amount of
+        the data written if necessary.
 
-/**
-    Enumeration values used by wxFilterClassFactory.
-*/
-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.
-};
+        This method uses repeated calls to Write() (which may return writing
+        only part of the data) if necessary.
 
+        @since 2.9.5
+    */
+    bool WriteAll(const void* buffer, size_t size);
 
-/**
-    @class wxFilterClassFactory
+protected:
+    /**
+        Internal function. It is called when the stream wants to write data of the
+        specified size @a bufsize into the given @a buffer.
 
-    Allows the creation of filter streams to handle compression formats such
-    as gzip and bzip2.
+        It should return the size that was actually wrote (which maybe zero if
+        @a bufsize is zero or if an error occurred; in this last case the internal
+        variable @c m_lasterror should be appropriately set).
+    */
+    size_t OnSysWrite(const void* buffer, size_t bufsize);
+};
 
-    For example, given a filename you can search for a factory that will
-    handle it and create a stream to decompress it:
 
-    @code
-        factory = wxFilterClassFactory::Find(filename, wxSTREAM_FILEEXT);
-        if (factory)
-            stream = factory-NewStream(new wxFFileInputStream(filename));
-    @endcode
+/**
+    @class wxInputStream
 
-    wxFilterClassFactory::Find can also search for a factory by MIME type,
-    HTTP encoding or by wxFileSystem protocol.
-    The available factories can be enumerated using wxFilterClassFactory::GetFirst()
-    and wxFilterClassFactory::GetNext().
+    wxInputStream is an abstract base class which may not be used directly.
+    It is the base class of all streams which provide a Read() function,
+    i.e. which can be used to read data from a source (e.g. a file, a socket, etc).
+
+    If you want to create your own input stream, you'll need to derive from this
+    class and implement the protected OnSysRead() function only.
 
     @library{wxbase}
     @category{streams}
-
-    @see wxFilterInputStream, wxFilterOutputStream, wxArchiveClassFactory,
-        @ref overview_archive
 */
-class wxFilterClassFactory : public wxObject
+class wxInputStream : public wxStreamBase
 {
 public:
     /**
-        Returns @true if this factory can handle the given protocol, MIME type, HTTP
-        encoding or file extension.
-
-        When using @c wxSTREAM_FILEEXT for the second parameter, the first parameter
-        can be a complete filename rather than just an extension.
+        Creates a dummy input stream.
     */
-    bool CanHandle(const wxString& protocol,
-                   wxStreamProtocolType type = wxSTREAM_PROTOCOL) const;
+    wxInputStream();
 
     /**
-        A static member that finds a factory that can handle a given protocol, MIME
-        type, HTTP encoding or file extension. Returns a pointer to the class
-        factory if found, or @NULL otherwise.
-        It does not give away ownership of the factory.
-
-        When using @c wxSTREAM_FILEEXT for the second parameter, the first parameter
-        can be a complete filename rather than just an extension.
+        Destructor.
     */
-    static const wxFilterClassFactory* Find(const wxString& protocol,
-                                            wxStreamProtocolType type = wxSTREAM_PROTOCOL);
+    virtual ~wxInputStream();
 
-    //@{
     /**
-        GetFirst and GetNext can be used to enumerate the available factories.
-        For example, to list them:
+        Returns @true if some data is available in the stream right now, so that
+        calling Read() wouldn't block.
+    */
+    virtual bool CanRead() const;
 
-        @code
-        wxString list;
-        const wxFilterClassFactory *factory = wxFilterClassFactory::GetFirst();
+    /**
+        Returns @true after an attempt has been made to read past the end of the
+        stream.
+    */
+    virtual bool Eof() const;
 
-        while (factory) {
-            list << factory->GetProtocol() << _T("\n");
-            factory = factory->GetNext();
-        }
-        @endcode
+    /**
+        Returns the first character in the input queue and removes it,
+        blocking until it appears if necessary.
 
-        GetFirst()/GetNext() return a pointer to a factory or @NULL if no more
-        are available. They do not give away ownership of the factory.
+        On success returns a value between 0 - 255; on end of file returns @c wxEOF.
     */
-    static const wxFilterClassFactory* GetFirst() const;
-    const wxFilterClassFactory* GetNext() const;
-    //@}
+    int GetC();
 
     /**
-        Returns the wxFileSystem protocol supported by this factory.
-        Equivalent to @code wxString(*GetProtocols()) @endcode.
+        Returns the last number of bytes read.
     */
-    wxString GetProtocol() const;
+    virtual size_t LastRead() const;
 
     /**
-        Returns the protocols, MIME types, HTTP encodings or file extensions
-        supported by this factory, as an array of null terminated strings.
-        It does not give away ownership of the array or strings.
+        Returns the first character in the input queue without removing it.
+    */
+    virtual char Peek();
 
-        For example, to list the file extensions a factory supports:
+    /**
+        Reads the specified amount of bytes and stores the data in buffer.
+        To check if the call was successful you must use LastRead() to check
+        if this call did actually read @a size bytes (if it didn't, GetLastError()
+        should return a meaningful value).
 
-        @code
-        wxString list;
-        const wxChar *const *p;
+        @warning
+        The buffer absolutely needs to have at least the specified size.
 
-        for (p = factory->GetProtocols(wxSTREAM_FILEEXT); *p; p++)
-            list << *p << _T("\n");
-        @endcode
+        @return This function returns a reference on the current object, so the
+                user can test any states of the stream right away.
     */
-    virtual const wxChar * const* GetProtocols(wxStreamProtocolType type = wxSTREAM_PROTOCOL) const = 0;
+    virtual wxInputStream& Read(void* buffer, size_t size);
 
-    //@{
     /**
-        Create a new input or output stream to decompress or compress a given stream.
+        Reads data from the input queue and stores it in the specified output stream.
+        The data is read until an error is raised by one of the two streams.
 
-        If the parent stream is passed as a pointer then the new filter stream
-        takes ownership of it. If it is passed by reference then it does not.
+        @return This function returns a reference on the current object, so the
+                user can test any states of the stream right away.
     */
-    wxFilterInputStream*  NewStream(wxInputStream& stream) const;
-    wxFilterOutputStream* NewStream(wxOutputStream& stream) const;
-    wxFilterInputStream*  NewStream(wxInputStream* stream) const;
-    wxFilterOutputStream* NewStream(wxOutputStream* stream) const;
-    //@}
+    wxInputStream& Read(wxOutputStream& stream_out);
 
     /**
-        Remove the file extension of @a location if it is one of the file
-        extensions handled by this factory.
-    */
-    wxString PopExtension(const wxString& location) const;
+        Reads exactly the specified number of bytes into the buffer.
 
-    /**
-        Adds this class factory to the list returned  by GetFirst()/GetNext().
+        Returns @true only if the entire amount of data was read, otherwise
+        @false is returned and the number of bytes really read can be retrieved
+        using LastRead(), as with Read().
+
+        This method uses repeated calls to Read() (which may return after
+        reading less than the requested number of bytes) if necessary.
+
+        @warning
+        The buffer absolutely needs to have at least the specified size.
+
+        @since 2.9.5
+    */
+    bool ReadAll(void* buffer, size_t size);
+
+    /**
+        Changes the stream current position.
+
+        This operation in general is possible only for seekable streams 
+        (see wxStreamBase::IsSeekable()); non-seekable streams support only
+        seeking positive amounts in mode @c wxFromCurrent (this is implemented
+        by reading data and simply discarding it).
+
+        @param pos
+            Offset to seek to.
+        @param mode
+            One of wxFromStart, wxFromEnd, wxFromCurrent.
+
+        @return The new stream position or ::wxInvalidOffset on error.
+    */
+    virtual wxFileOffset SeekI(wxFileOffset pos, wxSeekMode mode = wxFromStart);
+
+    /**
+        Returns the current stream position or ::wxInvalidOffset if it's not
+        available (e.g. socket streams do not have a size nor a current stream
+        position).
+    */
+    virtual wxFileOffset TellI() const;
+
+    /**
+        This function is only useful in read mode.
+        It is the manager of the "Write-Back" buffer. This buffer acts like a
+        temporary buffer where data which has to be read during the next read IO
+        call are put. This is useful when you get a big block of data which you
+        didn't want to read: you can replace them at the top of the input queue
+        by this way.
+
+        Be very careful about this call in connection with calling SeekI() on
+        the same stream. Any call to SeekI() will invalidate any previous call
+        to this method (otherwise you could SeekI() to one position, "unread" a
+        few bytes there, SeekI() to another position and data would be either
+        lost or corrupted).
+
+        @return Returns the amount of bytes saved in the Write-Back buffer.
+    */
+    size_t Ungetch(const void* buffer, size_t size);
+
+    /**
+        This function acts like the previous one except that it takes only one
+        character: it is sometimes shorter to use than the generic function.
+    */
+    bool Ungetch(char c);
+
+protected:
+
+    /**
+        Internal function. It is called when the stream wants to read data of the
+        specified size @a bufsize and wants it to be placed inside @a buffer.
+
+        It should return the size that was actually read or zero if EOF has been
+        reached or an error occurred (in this last case the internal @c m_lasterror
+        variable should be set accordingly as well).
+    */
+    size_t OnSysRead(void* buffer, size_t bufsize) = 0;
+};
+
+
+
+
+/**
+    @class wxCountingOutputStream
+
+    wxCountingOutputStream is a specialized output stream which does not write any
+    data anywhere, instead it counts how many bytes would get written if this were a
+    normal stream. This can sometimes be useful or required if some data gets
+    serialized to a stream or compressed by using stream compression and thus the
+    final size of the stream cannot be known other than pretending to write the stream.
+    One case where the resulting size would have to be known is if the data has
+    to be written to a piece of memory and the memory has to be allocated before
+    writing to it (which is probably always the case when writing to a memory stream).
+
+    @library{wxbase}
+    @category{streams}
+*/
+class wxCountingOutputStream : public wxOutputStream
+{
+public:
+    /**
+        Creates a wxCountingOutputStream object.
+    */
+    wxCountingOutputStream();
+
+    /**
+        Destructor.
+    */
+    virtual ~wxCountingOutputStream();
+
+    /**
+        Returns the current length of the stream.
+
+        This is the amount of data written to the stream so far, in bytes.
+    */
+    virtual wxFileOffset GetLength() const;
+};
+
+
+/**
+    @class wxBufferedInputStream
+
+    This stream acts as a cache. It caches the bytes read from the specified
+    input stream (see wxFilterInputStream).
+    It uses wxStreamBuffer and sets the default in-buffer size to 1024 bytes.
+    This class may not be used without some other stream to read the data
+    from (such as a file stream or a memory stream).
+
+    @library{wxbase}
+    @category{streams}
+
+    @see wxStreamBuffer, wxInputStream, wxBufferedOutputStream
+*/
+class wxBufferedInputStream : public wxFilterInputStream
+{
+public:
+    /**
+        Constructor using the provided buffer or default.
+
+        @param stream
+            The associated low-level stream.
+        @param buffer
+            The buffer to use if non-@NULL. Notice that the ownership of this
+            buffer is taken by the stream, i.e. it will delete it. If this
+            parameter is @NULL a default 1KB buffer is used.
+    */
+    wxBufferedInputStream(wxInputStream& stream,
+                          wxStreamBuffer *buffer = NULL);
+
+    /**
+        Constructor allowing to specify the size of the buffer.
+
+        This is just a more convenient alternative to creating a wxStreamBuffer
+        of the given size and using the other overloaded constructor of this
+        class.
+
+        @param stream
+            The associated low-level stream.
+        @param bufsize
+            The size of the buffer, in bytes.
+
+        @since 2.9.0
+     */
+    wxBufferedInputStream(wxInputStream& stream, size_t bufsize);
+
+    /**
+        Destructor.
+    */
+    virtual ~wxBufferedInputStream();
+};
+
+
+
+
+/**
+    Enumeration values used by wxFilterClassFactory.
+*/
+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.
+};
+
+/**
+    @class wxFilterClassFactory
+
+    Allows the creation of filter streams to handle compression formats such
+    as gzip and bzip2.
+
+    For example, given a filename you can search for a factory that will
+    handle it and create a stream to decompress it:
+
+    @code
+        factory = wxFilterClassFactory::Find(filename, wxSTREAM_FILEEXT);
+        if (factory)
+            stream = factory->NewStream(new wxFFileInputStream(filename));
+    @endcode
+
+    wxFilterClassFactory::Find can also search for a factory by MIME type,
+    HTTP encoding or by wxFileSystem protocol.
+    The available factories can be enumerated using wxFilterClassFactory::GetFirst()
+    and wxFilterClassFactory::GetNext().
+
+    @library{wxbase}
+    @category{streams}
+
+    @see wxFilterInputStream, wxFilterOutputStream, wxArchiveClassFactory,
+        @ref overview_archive
+*/
+class wxFilterClassFactory : public wxObject
+{
+public:
+    /**
+        Returns @true if this factory can handle the given protocol, MIME type, HTTP
+        encoding or file extension.
+
+        When using @c wxSTREAM_FILEEXT for the second parameter, the first parameter
+        can be a complete filename rather than just an extension.
+    */
+    bool CanHandle(const wxString& protocol,
+                   wxStreamProtocolType type = wxSTREAM_PROTOCOL) const;
+
+    /**
+        A static member that finds a factory that can handle a given protocol, MIME
+        type, HTTP encoding or file extension. Returns a pointer to the class
+        factory if found, or @NULL otherwise.
+        It does not give away ownership of the factory.
+
+        When using @c wxSTREAM_FILEEXT for the second parameter, the first parameter
+        can be a complete filename rather than just an extension.
+    */
+    static const wxFilterClassFactory* Find(const wxString& protocol,
+                                            wxStreamProtocolType type = wxSTREAM_PROTOCOL);
+
+    //@{
+    /**
+        GetFirst and GetNext can be used to enumerate the available factories.
+        For example, to list them:
+
+        @code
+        wxString list;
+        const wxFilterClassFactory *factory = wxFilterClassFactory::GetFirst();
+
+        while (factory) {
+            list << factory->GetProtocol() << wxT("\n");
+            factory = factory->GetNext();
+        }
+        @endcode
+
+        GetFirst()/GetNext() return a pointer to a factory or @NULL if no more
+        are available. They do not give away ownership of the factory.
+    */
+    static const wxFilterClassFactory* GetFirst();
+    const wxFilterClassFactory* GetNext() const;
+    //@}
+
+    /**
+        Returns the wxFileSystem protocol supported by this factory.
+        Equivalent to @code wxString(*GetProtocols()) @endcode.
+    */
+    wxString GetProtocol() const;
+
+    /**
+        Returns the protocols, MIME types, HTTP encodings or file extensions
+        supported by this factory, as an array of null terminated strings.
+        It does not give away ownership of the array or strings.
+
+        For example, to list the file extensions a factory supports:
+
+        @code
+        wxString list;
+        const wxChar *const *p;
+
+        for (p = factory->GetProtocols(wxSTREAM_FILEEXT); *p; p++)
+            list << *p << wxT("\n");
+        @endcode
+    */
+    virtual const wxChar * const* GetProtocols(wxStreamProtocolType type = wxSTREAM_PROTOCOL) const = 0;
+
+    //@{
+    /**
+        Create a new input or output stream to decompress or compress a given stream.
+
+        If the parent stream is passed as a pointer then the new filter stream
+        takes ownership of it. If it is passed by reference then it does not.
+    */
+    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;
+    //@}
+
+    /**
+        Remove the file extension of @a location if it is one of the file
+        extensions handled by this factory.
+    */
+    wxString PopExtension(const wxString& location) const;
+
+    /**
+        Adds this class factory to the list returned  by GetFirst()/GetNext().
 
         It is not necessary to do this to use the filter streams. It is usually
         used when implementing streams, typically the implementation will
@@ -758,216 +1099,57 @@ public:
 };
 
 
-
-/**
-    @class wxInputStream
-
-    wxInputStream is an abstract base class which may not be used directly.
-
-    @library{wxbase}
-    @category{streams}
-*/
-class wxInputStream : public wxStreamBase
-{
-public:
-    /**
-        Creates a dummy input stream.
-    */
-    wxInputStream();
-
-    /**
-        Destructor.
-    */
-    virtual ~wxInputStream();
-
-    /**
-        Returns @true if some data is available in the stream right now, so that
-        calling Read() wouldn't block.
-    */
-    virtual bool CanRead() const;
-
-    /**
-        Returns @true after an attempt has been made to read past the end of the
-        stream.
-    */
-    virtual bool Eof() const;
-
-    /**
-        Returns the first character in the input queue and removes it,
-        blocking until it appears if necessary.
-    */
-    int GetC();
-
-    /**
-        Returns the last number of bytes read.
-    */
-    virtual size_t LastRead() const;
-
-    /**
-        Returns the first character in the input queue without removing it.
-    */
-    virtual char Peek();
-
-    /**
-        Reads the specified amount of bytes and stores the data in buffer.
-
-        @warning
-        The buffer absolutely needs to have at least the specified size.
-
-        @return This function returns a reference on the current object, so the
-                user can test any states of the stream right away.
-    */
-    virtual wxInputStream& Read(void* buffer, size_t size);
-
-    /**
-        Reads data from the input queue and stores it in the specified output stream.
-        The data is read until an error is raised by one of the two streams.
-
-        @return This function returns a reference on the current object, so the
-                user can test any states of the stream right away.
-    */
-    wxInputStream& Read(wxOutputStream& stream_out);
-
-    /**
-        Changes the stream current position.
-
-        @param pos
-            Offset to seek to.
-        @param mode
-            One of wxFromStart, wxFromEnd, wxFromCurrent.
-
-        @return The new stream position or wxInvalidOffset on error.
-    */
-    virtual wxFileOffset SeekI(wxFileOffset pos, wxSeekMode mode = wxFromStart);
-
-    /**
-        Returns the current stream position.
-    */
-    virtual wxFileOffset TellI() const;
-
-    /**
-        This function is only useful in read mode.
-        It is the manager of the "Write-Back" buffer. This buffer acts like a
-        temporary buffer where data which has to be read during the next read IO
-        call are put. This is useful when you get a big block of data which you
-        didn't want to read: you can replace them at the top of the input queue
-        by this way.
-
-        Be very careful about this call in connection with calling SeekI() on
-        the same stream. Any call to SeekI() will invalidate any previous call
-        to this method (otherwise you could SeekI() to one position, "unread" a
-        few bytes there, SeekI() to another position and data would be either
-        lost or corrupted).
-
-        @return Returns the amount of bytes saved in the Write-Back buffer.
-    */
-    size_t Ungetch(const void* buffer, size_t size);
-
-    /**
-        This function acts like the previous one except that it takes only one
-        character: it is sometimes shorter to use than the generic function.
-    */
-    bool Ungetch(char c);
-};
-
-
 /**
-    These enumeration values are returned by various functions in the context
-    of wxStream classes.
-*/
-enum wxStreamError
-{
-    wxSTREAM_NO_ERROR = 0,      //!< No error occurred.
-    wxSTREAM_EOF,               //!< EOF reached in Read() or similar.
-    wxSTREAM_WRITE_ERROR,       //!< generic write error on the last write call.
-    wxSTREAM_READ_ERROR         //!< generic read error on the last read call.
-};
+    @class wxWrapperInputStream
 
-/**
-    @class wxStreamBase
+    A wrapper input stream is a kind of filter stream which forwards all the
+    operations to its base stream. This is useful to build utility classes such
+    as wxFSInputStream.
 
-    This class is the base class of most stream related classes in wxWidgets.
-    It must not be used directly.
+    @note
+    The interface of this class is the same as that of wxInputStream.
+    Only a constructor differs and it is documented below.
 
     @library{wxbase}
     @category{streams}
 
-    @see wxStreamBuffer
+    @see wxFSInputStream, wxFilterInputStream
+    @since 2.9.4
 */
-class wxStreamBase
+class wxWrapperInputStream : public wxFilterInputStream
 {
 public:
+    //@{
     /**
-        Creates a dummy stream object. It doesn't do anything.
-    */
-    wxStreamBase();
-
-    /**
-        Destructor.
-    */
-    virtual ~wxStreamBase();
-
-    /**
-        This function returns the last error.
-    */
-    wxStreamError GetLastError() const;
-
-    /**
-        Returns the length of the stream in bytes. If the length cannot be
-        determined (this is always the case for socket streams for example),
-        returns @c wxInvalidOffset.
-
-        @since 2.5.4
-    */
-    virtual wxFileOffset GetLength() const;
-
-    /**
-        This function returns the size of the stream.
-        For example, for a file it is the size of the file.
-
-        @warning
-        There are streams which do not have size by definition, such as socket
-        streams. In that cases, GetSize returns 0 so you should always test its
-        return value.
-    */
-    virtual size_t GetSize() const;
-
-    /**
-        Returns @true if no error occurred on the stream.
-
-        @see GetLastError()
-    */
-    virtual bool IsOk() const;
-
-    /**
-        Returns @true if the streams supports seeking to arbitrary offsets.
-    */
-    virtual bool IsSeekable() const;
+        Initializes a wrapper stream.
 
-    /**
-        Internal function. It is called when the stream wants to read data of the
-        specified size. It should return the size that was actually read.
+        If the parent stream is passed as a pointer then the new wrapper stream
+        takes ownership of it. If it is passed by reference then it does not.
     */
-    size_t OnSysRead(void* buffer, size_t bufsize);
+    wxWrapperInputStream(wxInputStream& stream);
+    wxWrapperInputStream(wxInputStream* stream);
+    //@}
 
+protected:
     /**
-        See OnSysRead().
-    */
-    size_t OnSysWrite(const void* buffer, size_t bufsize);
-
+        Default constructor, use InitParentStream() to finish initialization.
 
-protected:
+        This constructor can be used by the derived classes from their own
+        constructors when the parent stream can't be specified immediately.
+        The derived class must call InitParentStream() later to do it.
+     */
+    wxWrapperInputStream();
 
+    //@{
     /**
-        Internal function.
-        It is called when the stream needs to change the current position.
-    */
-    virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
+        Set up the wrapped stream for an object initialized using the default
+        constructor.
 
-    /**
-        Internal function.
-        It is called when the stream needs to know the real position.
-    */
-    virtual wxFileOffset OnSysTell() const;
+        The ownership logic is the same as for the non-default constructor,
+        i.e. this object takes ownership of the stream if it's passed by
+        pointer but not if it's passed by reference.
+     */
+    void InitParentStream(wxInputStream& stream);
+    void InitParentStream(wxInputStream* stream);
+    //@}
 };
-