+#include "wx/object.h"
+#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;
+
+typedef wxInputStream& (*__wxInputManip)(wxInputStream&);
+typedef wxOutputStream& (*__wxOutputManip)(wxOutputStream&);
+
+WXDLLIMPEXP_BASE wxOutputStream& wxEndL(wxOutputStream& o_stream);
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+enum wxStreamError
+{
+ wxSTREAM_NO_ERROR = 0, // stream is in good state
+ wxSTREAM_EOF, // EOF reached in Read() or similar
+ wxSTREAM_WRITE_ERROR, // generic write error
+ wxSTREAM_READ_ERROR // generic read error
+};
+
+const int wxEOF = -1;
+
+// ============================================================================
+// base stream classes: wxInputStream and wxOutputStream
+// ============================================================================
+
+// ---------------------------------------------------------------------------
+// wxStreamBase: common (but non virtual!) base for all stream classes
+// ---------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxStreamBase
+{
+public:
+ wxStreamBase();
+ virtual ~wxStreamBase();
+
+ // error testing
+ wxStreamError GetLastError() const { return m_lasterror; }
+ 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; }
+
+ // this doesn't make sense for all streams, always test its return value
+ virtual size_t GetSize() const;
+ virtual wxFileOffset GetLength() const { return wxInvalidOffset; }
+
+ // returns true if the streams supports seeking to arbitrary offsets
+ virtual bool IsSeekable() const { return false; }
+
+protected:
+ virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
+ virtual wxFileOffset OnSysTell() const;
+
+ size_t m_lastcount;
+ wxStreamError m_lasterror;
+
+ friend class wxStreamBuffer;
+
+ DECLARE_NO_COPY_CLASS(wxStreamBase)
+};
+
+// ----------------------------------------------------------------------------
+// wxInputStream: base class for the input streams
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxInputStream : public wxStreamBase
+{
+public:
+ // ctor and dtor, nothing exciting
+ wxInputStream();
+ virtual ~wxInputStream();
+
+
+ // IO functions
+ // ------------
+
+ // return a character from the stream without removing it, i.e. it will
+ // still be returned by the next call to GetC()
+ //
+ // blocks until something appears in the stream if necessary, if nothing
+ // ever does (i.e. EOF) LastRead() will return 0 (and the return value is
+ // undefined), otherwise 1
+ virtual char Peek();
+
+ // return one byte from the stream, blocking until it appears if
+ // necessary
+ //
+ // 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
+ //
+ // there are 2 possible situations here: either there is nothing at all in
+ // the stream right now in which case Read() blocks until something appears
+ // (use CanRead() to avoid this) or there is already some data available in
+ // the stream and then Read() doesn't block but returns just the data it
+ // can read without waiting for more
+ //
+ // in any case, if there are not enough bytes in the stream right now,
+ // LastRead() value will be less than size but greater than 0. If it is 0,
+ // it means that EOF has been reached.
+ virtual wxInputStream& Read(void *buffer, size_t size);
+
+ // copy the entire contents of this stream into streamOut, stopping only
+ // when EOF is reached or an error occurs
+ wxInputStream& Read(wxOutputStream& streamOut);
+
+
+ // status functions
+ // ----------------
+
+ // returns the number of bytes read by the last call to Read(), GetC() or
+ // Peek()
+ //
+ // this should be used to discover whether that call succeeded in reading
+ // all the requested data or not
+ virtual size_t LastRead() const { return wxStreamBase::m_lastcount; }
+
+ // returns true if some data is available in the stream right now, so that
+ // calling Read() wouldn't block
+ virtual bool CanRead() const;
+
+ // is the stream at EOF?
+ //
+ // note that this cannot be really implemented for all streams and
+ // CanRead() is more reliable than Eof()
+ virtual bool Eof() const;
+
+
+ // write back buffer
+ // -----------------
+
+ // put back the specified number of bytes into the stream, they will be
+ // fetched by the next call to the read functions
+ //
+ // returns the number of bytes really stuffed back
+ size_t Ungetch(const void *buffer, size_t size);
+
+ // put back the specified character in the stream
+ //
+ // returns true if ok, false on error
+ bool Ungetch(char c);
+
+
+ // position functions
+ // ------------------
+
+ // move the stream pointer to the given position (if the stream supports
+ // it)
+ //
+ // returns wxInvalidOffset on error
+ virtual wxFileOffset SeekI(wxFileOffset pos, wxSeekMode mode = wxFromStart);
+
+ // return the current position of the stream pointer or wxInvalidOffset
+ virtual wxFileOffset TellI() const;
+
+
+ // stream-like operators
+ // ---------------------
+
+ wxInputStream& operator>>(wxOutputStream& out) { return Read(out); }
+ wxInputStream& operator>>(__wxInputManip func) { return func(*this); }
+
+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 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;
+
+ // write-back buffer support
+ // -------------------------
+
+ // return the pointer to a buffer big enough to hold sizeNeeded bytes
+ char *AllocSpaceWBack(size_t sizeNeeded);
+
+ // read up to size data from the write back buffer, return the number of
+ // bytes read
+ size_t GetWBack(void *buf, size_t size);
+
+ // write back buffer or NULL if none
+ char *m_wback;
+
+ // the size of the buffer
+ size_t m_wbacksize;
+
+ // the current position in the buffer
+ size_t m_wbackcur;
+
+ friend class wxStreamBuffer;
+
+ DECLARE_NO_COPY_CLASS(wxInputStream)
+};
+
+// ----------------------------------------------------------------------------
+// wxOutputStream: base for the output streams
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxOutputStream : public wxStreamBase
+{
+public:
+ wxOutputStream();
+ virtual ~wxOutputStream();
+
+ void PutC(char c);
+ virtual wxOutputStream& Write(const void *buffer, size_t size);
+ wxOutputStream& Write(wxInputStream& stream_in);
+
+ virtual wxFileOffset SeekO(wxFileOffset pos, wxSeekMode mode = wxFromStart);
+ virtual wxFileOffset TellO() const;
+
+ virtual size_t LastWrite() const { return wxStreamBase::m_lastcount; }
+
+ virtual void Sync();
+ virtual bool Close() { return true; }
+
+ wxOutputStream& operator<<(wxInputStream& out) { return Write(out); }
+ 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;
+
+ DECLARE_NO_COPY_CLASS(wxOutputStream)
+};
+
+// ============================================================================
+// helper stream classes
+// ============================================================================
+
+// ---------------------------------------------------------------------------
+// A stream for measuring streamed output
+// ---------------------------------------------------------------------------