wxWidgets/include/wx/stream.h
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

705 lines
23 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: wx/stream.h
// Purpose: stream classes
// Author: Guilhem Lavaux, Guillermo Rodriguez Garcia, Vadim Zeitlin
// Modified by:
// Created: 11/07/98
// Copyright: (c) Guilhem Lavaux
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_WXSTREAM_H__
#define _WX_WXSTREAM_H__
#include "wx/defs.h"
#if wxUSE_STREAMS
#include <stdio.h>
#include "wx/object.h"
#include "wx/string.h"
#include "wx/filefn.h" // for wxFileOffset, wxInvalidOffset and wxSeekMode
class WXDLLIMPEXP_FWD_BASE wxStreamBase;
class WXDLLIMPEXP_FWD_BASE wxInputStream;
class WXDLLIMPEXP_FWD_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 wxObject
{
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(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; }
// 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_ABSTRACT_CLASS(wxStreamBase)
wxDECLARE_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);
// Read exactly the given number of bytes, unlike Read(), which may read
// less than the requested amount of data without returning an error, this
// method either reads all the data or returns false.
bool ReadAll(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_ABSTRACT_CLASS(wxInputStream)
wxDECLARE_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);
// This is ReadAll() equivalent for Write(): it either writes exactly the
// given number of bytes or returns false, unlike Write() which can write
// less data than requested but still return without error.
bool WriteAll(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_ABSTRACT_CLASS(wxOutputStream)
wxDECLARE_NO_COPY_CLASS(wxOutputStream);
};
// ============================================================================
// helper stream classes
// ============================================================================
// ---------------------------------------------------------------------------
// A stream for measuring streamed output
// ---------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxCountingOutputStream : public wxOutputStream
{
public:
wxCountingOutputStream();
virtual wxFileOffset GetLength() const;
bool Ok() const { return IsOk(); }
virtual bool IsOk() const { return true; }
protected:
virtual size_t OnSysWrite(const void *buffer, size_t size);
virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
virtual wxFileOffset OnSysTell() const;
size_t m_currentPos,
m_lastPos;
DECLARE_DYNAMIC_CLASS(wxCountingOutputStream)
wxDECLARE_NO_COPY_CLASS(wxCountingOutputStream);
};
// ---------------------------------------------------------------------------
// "Filter" streams
// ---------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxFilterInputStream : public wxInputStream
{
public:
wxFilterInputStream();
wxFilterInputStream(wxInputStream& stream);
wxFilterInputStream(wxInputStream *stream);
virtual ~wxFilterInputStream();
char Peek() { return m_parent_i_stream->Peek(); }
wxFileOffset GetLength() const { return m_parent_i_stream->GetLength(); }
wxInputStream *GetFilterInputStream() const { return m_parent_i_stream; }
protected:
wxInputStream *m_parent_i_stream;
bool m_owns;
DECLARE_ABSTRACT_CLASS(wxFilterInputStream)
wxDECLARE_NO_COPY_CLASS(wxFilterInputStream);
};
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; }
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)
};
// ============================================================================
// buffered streams
// ============================================================================
// ---------------------------------------------------------------------------
// Stream buffer: this class can be derived from and passed to
// wxBufferedStreams to implement custom buffering
// ---------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxStreamBuffer
{
public:
enum BufMode
{
read,
write,
read_write
};
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();
// Filtered IO
virtual size_t Read(void *buffer, size_t size);
size_t Read(wxStreamBuffer *buf);
virtual size_t Write(const void *buffer, size_t size);
size_t Write(wxStreamBuffer *buf);
virtual char Peek();
virtual char GetChar();
virtual void PutChar(char c);
virtual wxFileOffset Tell() const;
virtual wxFileOffset Seek(wxFileOffset pos, wxSeekMode mode);
// 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()
void SetBufferIO(void *start, void *end, bool takeOwnership = false);
void SetBufferIO(void *start, size_t len, bool takeOwnership = false);
void SetBufferIO(size_t bufsize);
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_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; }
size_t GetBytesLeft() const { return m_buffer_end - m_buffer_pos; }
void Fixed(bool fixed) { m_fixed = fixed; }
void Flushable(bool f) { m_flushable = f; }
bool FlushBuffer();
bool FillBuffer();
size_t GetDataLeft();
// misc accessors
wxStreamBase *GetStream() const { return m_stream; }
bool HasBuffer() const { return m_buffer_start != m_buffer_end; }
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;
#if WXWIN_COMPATIBILITY_2_6
// deprecated, for compatibility only
wxDEPRECATED( wxStreamBase *Stream() );
#endif // WXWIN_COMPATIBILITY_2_6
// this constructs a dummy wxStreamBuffer, used by (and exists for)
// wxMemoryStreams only, don't use!
wxStreamBuffer(BufMode mode);
protected:
void GetFromBuffer(void *buffer, size_t size);
void PutToBuffer(const void *buffer, size_t size);
// set the last error to the specified value if we didn't have it before
void SetError(wxStreamError err);
// 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();
// free the buffer (always safe to call)
void FreeBuffer();
// the buffer itself: the pointers to its start and end and the current
// position in the buffer
char *m_buffer_start,
*m_buffer_end,
*m_buffer_pos;
// the stream we're associated with
wxStreamBase *m_stream;
// its mode
BufMode m_mode;
// flags
bool m_destroybuf, // deallocate buffer?
m_fixed,
m_flushable;
wxDECLARE_NO_ASSIGN_CLASS(wxStreamBuffer);
};
// ---------------------------------------------------------------------------
// wxBufferedInputStream
// ---------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxBufferedInputStream : public wxFilterInputStream
{
public:
// 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();
wxInputStream& Read(void *buffer, size_t size);
// 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
wxDEPRECATED( wxStreamBuffer *InputStreamBuffer() const );
#endif // WXWIN_COMPATIBILITY_2_6
protected:
virtual size_t OnSysRead(void *buffer, size_t bufsize);
virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
virtual wxFileOffset OnSysTell() const;
wxStreamBuffer *m_i_streambuf;
wxDECLARE_NO_COPY_CLASS(wxBufferedInputStream);
};
// ----------------------------------------------------------------------------
// wxBufferedOutputStream
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxBufferedOutputStream : public wxFilterOutputStream
{
public:
// 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);
// 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();
wxFileOffset GetLength() const;
// the buffer given to the stream will be deleted by it
void SetOutputStreamBuffer(wxStreamBuffer *buffer);
wxStreamBuffer *GetOutputStreamBuffer() const { return m_o_streambuf; }
#if WXWIN_COMPATIBILITY_2_6
// deprecated, for compatibility only
wxDEPRECATED( wxStreamBuffer *OutputStreamBuffer() const );
#endif // WXWIN_COMPATIBILITY_2_6
protected:
virtual size_t OnSysWrite(const void *buffer, size_t bufsize);
virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
virtual wxFileOffset OnSysTell() const;
wxStreamBuffer *m_o_streambuf;
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<wxWrapperInputStream*>(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__