1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: stream classes
4 // Author: Guilhem Lavaux, Guillermo Rodriguez Garcia, Vadim Zeitlin
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_WXSTREAM_H__
13 #define _WX_WXSTREAM_H__
15 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
16 #pragma interface "stream.h"
24 #include "wx/object.h"
25 #include "wx/string.h"
26 #include "wx/filefn.h" // for wxFileOffset, wxInvalidOffset and wxSeekMode
28 class WXDLLIMPEXP_BASE wxStreamBase
;
29 class WXDLLIMPEXP_BASE wxInputStream
;
30 class WXDLLIMPEXP_BASE wxOutputStream
;
32 typedef wxInputStream
& (*__wxInputManip
)(wxInputStream
&);
33 typedef wxOutputStream
& (*__wxOutputManip
)(wxOutputStream
&);
35 WXDLLIMPEXP_BASE wxOutputStream
& wxEndL(wxOutputStream
& o_stream
);
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
43 wxSTREAM_NO_ERROR
= 0, // stream is in good state
44 wxSTREAM_EOF
, // EOF reached in Read() or similar
45 wxSTREAM_WRITE_ERROR
, // generic write error
46 wxSTREAM_READ_ERROR
// generic read error
50 #if WXWIN_COMPATIBILITY_2_2
51 #define wxStream_NOERROR wxSTREAM_NOERROR
52 #define wxStream_EOF wxSTREAM_EOF
53 #define wxStream_WRITE_ERR wxSTREAM_WRITE_ERROR
54 #define wxStream_READ_ERR wxSTREAM_READ_ERROR
56 #define wxSTREAM_NO_ERR wxSTREAM_NO_ERROR
57 #define wxSTREAM_NOERROR wxSTREAM_NO_ERROR
58 #define wxSTREAM_WRITE_ERR wxSTREAM_WRITE_ERROR
59 #define wxSTREAM_READ_ERR wxSTREAM_READ_ERROR
60 #endif // WXWIN_COMPATIBILITY_2_2
62 // ============================================================================
63 // base stream classes: wxInputStream and wxOutputStream
64 // ============================================================================
66 // ---------------------------------------------------------------------------
67 // wxStreamBase: common (but non virtual!) base for all stream classes
68 // ---------------------------------------------------------------------------
70 class WXDLLIMPEXP_BASE wxStreamBase
74 virtual ~wxStreamBase();
77 wxStreamError
GetLastError() const { return m_lasterror
; }
78 bool IsOk() const { return GetLastError() == wxSTREAM_NO_ERROR
; }
79 bool operator!() const { return !IsOk(); }
81 // reset the stream state
82 void Reset() { m_lasterror
= wxSTREAM_NO_ERROR
; }
84 // this doesn't make sense for all streams, always test its return value
85 virtual size_t GetSize() const;
86 virtual wxFileOffset
GetLength() const { return wxInvalidOffset
; }
88 // returns true if the streams supports seeking to arbitrary offsets
89 virtual bool IsSeekable() const { return false; }
91 #if WXWIN_COMPATIBILITY_2_2
92 // deprecated, for compatibility only
93 wxDEPRECATED( wxStreamError
LastError() const );
94 wxDEPRECATED( size_t StreamSize() const );
95 #endif // WXWIN_COMPATIBILITY_2_2
98 // Reserved for future use
99 virtual void ReservedStreamFunc1() {}
100 virtual void ReservedStreamFunc2() {}
101 virtual void ReservedStreamFunc3() {}
102 virtual void ReservedStreamFunc4() {}
103 virtual void ReservedStreamFunc5() {}
104 virtual void ReservedStreamFunc6() {}
105 virtual void ReservedStreamFunc7() {}
106 virtual void ReservedStreamFunc8() {}
107 virtual void ReservedStreamFunc9() {}
110 virtual wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
111 virtual wxFileOffset
OnSysTell() const;
114 wxStreamError m_lasterror
;
116 friend class wxStreamBuffer
;
118 DECLARE_NO_COPY_CLASS(wxStreamBase
)
121 // ----------------------------------------------------------------------------
122 // wxInputStream: base class for the input streams
123 // ----------------------------------------------------------------------------
125 class WXDLLIMPEXP_BASE wxInputStream
: public wxStreamBase
128 // ctor and dtor, nothing exciting
130 virtual ~wxInputStream();
136 // return a character from the stream without removing it, i.e. it will
137 // still be returned by the next call to GetC()
139 // blocks until something appears in the stream if necessary, if nothing
140 // ever does (i.e. EOF) LastRead() will return 0 (and the return value is
141 // undefined), otherwise 1
144 // return one character from the stream, blocking until it appears if
147 // if EOF, return value is undefined and LastRead() will return 0 and not 1
150 // read at most the given number of bytes from the stream
152 // there are 2 possible situations here: either there is nothing at all in
153 // the stream right now in which case Read() blocks until something appears
154 // (use CanRead() to avoid this) or there is already some data available in
155 // the stream and then Read() doesn't block but returns just the data it
156 // can read without waiting for more
158 // in any case, if there are not enough bytes in the stream right now,
159 // LastRead() value will be less than size but greater than 0. If it is 0,
160 // it means that EOF has been reached.
161 virtual wxInputStream
& Read(void *buffer
, size_t size
);
163 // copy the entire contents of this stream into streamOut, stopping only
164 // when EOF is reached or an error occurs
165 wxInputStream
& Read(wxOutputStream
& streamOut
);
171 // returns the number of bytes read by the last call to Read(), GetC() or
174 // this should be used to discover whether that call succeeded in reading
175 // all the requested data or not
176 virtual size_t LastRead() const { return wxStreamBase::m_lastcount
; }
178 // returns true if some data is available in the stream right now, so that
179 // calling Read() wouldn't block
180 virtual bool CanRead() const;
182 // is the stream at EOF?
184 // note that this cannot be really implemented for all streams and
185 // CanRead() is more reliable than Eof()
186 virtual bool Eof() const;
192 // put back the specified number of bytes into the stream, they will be
193 // fetched by the next call to the read functions
195 // returns the number of bytes really stuffed back
196 size_t Ungetch(const void *buffer
, size_t size
);
198 // put back the specified character in the stream
200 // returns true if ok, false on error
201 bool Ungetch(char c
);
204 // position functions
205 // ------------------
207 // move the stream pointer to the given position (if the stream supports
210 // returns wxInvalidOffset on error
211 virtual wxFileOffset
SeekI(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
213 // return the current position of the stream pointer or wxInvalidOffset
214 virtual wxFileOffset
TellI() const;
217 // stream-like operators
218 // ---------------------
220 wxInputStream
& operator>>(wxOutputStream
& out
) { return Read(out
); }
221 wxInputStream
& operator>>(__wxInputManip func
) { return func(*this); }
224 // do read up to size bytes of data into the provided buffer
226 // this method should return 0 if EOF has been reached or an error occured
227 // (m_lasterror should be set accordingly as well) or the number of bytes
229 virtual size_t OnSysRead(void *buffer
, size_t size
) = 0;
231 // write-back buffer support
232 // -------------------------
234 // return the pointer to a buffer big enough to hold sizeNeeded bytes
235 char *AllocSpaceWBack(size_t sizeNeeded
);
237 // read up to size data from the write back buffer, return the number of
239 size_t GetWBack(void *buf
, size_t size
);
241 // write back buffer or NULL if none
244 // the size of the buffer
247 // the current position in the buffer
250 friend class wxStreamBuffer
;
252 DECLARE_NO_COPY_CLASS(wxInputStream
)
255 // ----------------------------------------------------------------------------
256 // wxOutputStream: base for the output streams
257 // ----------------------------------------------------------------------------
259 class WXDLLIMPEXP_BASE wxOutputStream
: public wxStreamBase
263 virtual ~wxOutputStream();
266 virtual wxOutputStream
& Write(const void *buffer
, size_t size
);
267 wxOutputStream
& Write(wxInputStream
& stream_in
);
269 virtual wxFileOffset
SeekO(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
270 virtual wxFileOffset
TellO() const;
272 virtual size_t LastWrite() const { return wxStreamBase::m_lastcount
; }
275 virtual bool Close() { return true; }
277 wxOutputStream
& operator<<(wxInputStream
& out
) { return Write(out
); }
278 wxOutputStream
& operator<<( __wxOutputManip func
) { return func(*this); }
281 // to be implemented in the derived classes (it should have been pure
283 virtual size_t OnSysWrite(const void *buffer
, size_t bufsize
);
285 friend class wxStreamBuffer
;
287 DECLARE_NO_COPY_CLASS(wxOutputStream
)
290 // ============================================================================
291 // helper stream classes
292 // ============================================================================
294 // ---------------------------------------------------------------------------
295 // A stream for measuring streamed output
296 // ---------------------------------------------------------------------------
298 class WXDLLIMPEXP_BASE wxCountingOutputStream
: public wxOutputStream
301 wxCountingOutputStream();
303 wxFileOffset
GetLength() const;
304 bool Ok() const { return true; }
307 virtual size_t OnSysWrite(const void *buffer
, size_t size
);
308 virtual wxFileOffset
OnSysSeek(wxFileOffset pos
, wxSeekMode mode
);
309 virtual wxFileOffset
OnSysTell() const;
313 DECLARE_NO_COPY_CLASS(wxCountingOutputStream
)
316 // ---------------------------------------------------------------------------
318 // ---------------------------------------------------------------------------
320 class WXDLLIMPEXP_BASE wxFilterInputStream
: public wxInputStream
323 wxFilterInputStream();
324 wxFilterInputStream(wxInputStream
& stream
);
325 virtual ~wxFilterInputStream();
327 char Peek() { return m_parent_i_stream
->Peek(); }
329 wxFileOffset
GetLength() const { return m_parent_i_stream
->GetLength(); }
331 wxInputStream
*GetFilterInputStream() const { return m_parent_i_stream
; }
334 wxInputStream
*m_parent_i_stream
;
336 DECLARE_NO_COPY_CLASS(wxFilterInputStream
)
339 class WXDLLIMPEXP_BASE wxFilterOutputStream
: public wxOutputStream
342 wxFilterOutputStream();
343 wxFilterOutputStream(wxOutputStream
& stream
);
344 virtual ~wxFilterOutputStream();
346 wxFileOffset
GetLength() const { return m_parent_o_stream
->GetLength(); }
348 wxOutputStream
*GetFilterOutputStream() const { return m_parent_o_stream
; }
351 wxOutputStream
*m_parent_o_stream
;
353 DECLARE_NO_COPY_CLASS(wxFilterOutputStream
)
356 // ============================================================================
358 // ============================================================================
360 // ---------------------------------------------------------------------------
361 // Stream buffer: this class can be derived from and passed to
362 // wxBufferedStreams to implement custom buffering
363 // ---------------------------------------------------------------------------
365 class WXDLLIMPEXP_BASE wxStreamBuffer
375 wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
);
376 wxStreamBuffer(const wxStreamBuffer
& buf
);
377 virtual ~wxStreamBuffer();
380 virtual size_t Read(void *buffer
, size_t size
);
381 size_t Read(wxStreamBuffer
*buf
);
382 virtual size_t Write(const void *buffer
, size_t size
);
383 size_t Write(wxStreamBuffer
*buf
);
386 virtual char GetChar();
387 virtual void PutChar(char c
);
388 virtual wxFileOffset
Tell() const;
389 virtual wxFileOffset
Seek(wxFileOffset pos
, wxSeekMode mode
);
394 // NB: the buffer must always be allocated with malloc() if takeOwn is
395 // true as it will be deallocated by free()
396 void SetBufferIO(void *start
, void *end
, bool takeOwnership
= false);
397 void SetBufferIO(void *start
, size_t len
, bool takeOwnership
= false);
398 void SetBufferIO(size_t bufsize
);
399 void *GetBufferStart() const { return m_buffer_start
; }
400 void *GetBufferEnd() const { return m_buffer_end
; }
401 void *GetBufferPos() const { return m_buffer_pos
; }
402 size_t GetBufferSize() const { return m_buffer_size
; }
403 size_t GetIntPosition() const { return m_buffer_pos
- m_buffer_start
; }
404 void SetIntPosition(size_t pos
) { m_buffer_pos
= m_buffer_start
+ pos
; }
405 size_t GetLastAccess() const { return m_buffer_end
- m_buffer_start
; }
406 size_t GetBytesLeft() const { return m_buffer_end
- m_buffer_pos
; }
408 void Fixed(bool fixed
) { m_fixed
= fixed
; }
409 void Flushable(bool f
) { m_flushable
= f
; }
413 size_t GetDataLeft();
416 wxStreamBase
*GetStream() const { return m_stream
; }
417 bool HasBuffer() const { return m_buffer_size
!= 0; }
419 bool IsFixed() const { return m_fixed
; }
420 bool IsFlushable() const { return m_flushable
; }
422 // only for input/output buffers respectively, returns NULL otherwise
423 wxInputStream
*GetInputStream() const;
424 wxOutputStream
*GetOutputStream() const;
426 // deprecated, for compatibility only
427 wxStreamBase
*Stream() { return m_stream
; }
429 // this constructs a dummy wxStreamBuffer, used by (and exists for)
430 // wxMemoryStreams only, don't use!
431 wxStreamBuffer(BufMode mode
);
434 void GetFromBuffer(void *buffer
, size_t size
);
435 void PutToBuffer(const void *buffer
, size_t size
);
437 // set the last error to the specified value if we didn't have it before
438 void SetError(wxStreamError err
);
440 // common part of several ctors
443 // init buffer variables to be empty
446 // free the buffer (always safe to call)
449 // the buffer itself: the pointers to its start and end and the current
450 // position in the buffer
451 char *m_buffer_start
,
456 // FIXME: isn't it the same as m_buffer_end - m_buffer_start? (VZ)
457 size_t m_buffer_size
;
459 // the stream we're associated with
460 wxStreamBase
*m_stream
;
466 bool m_destroybuf
, // deallocate buffer?
472 // DECLARE_NO_COPY_CLASS(wxStreamBuffer)
473 // because copy constructor is explicitly declared above;
474 // but no copy assignment operator is defined, so declare
475 // it private to prevent the compiler from defining it:
476 wxStreamBuffer
& operator=(const wxStreamBuffer
&);
479 // ---------------------------------------------------------------------------
480 // wxBufferedInputStream
481 // ---------------------------------------------------------------------------
483 class WXDLLIMPEXP_BASE wxBufferedInputStream
: public wxFilterInputStream
486 // if a non NULL buffer is given to the stream, it will be deleted by it
487 wxBufferedInputStream(wxInputStream
& stream
,
488 wxStreamBuffer
*buffer
= NULL
);
489 virtual ~wxBufferedInputStream();
492 wxInputStream
& Read(void *buffer
, size_t size
);
494 // Position functions
495 wxFileOffset
SeekI(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
496 wxFileOffset
TellI() const;
497 bool IsSeekable() const { return m_parent_i_stream
->IsSeekable(); }
499 // the buffer given to the stream will be deleted by it
500 void SetInputStreamBuffer(wxStreamBuffer
*buffer
);
501 wxStreamBuffer
*GetInputStreamBuffer() const { return m_i_streambuf
; }
503 // deprecated, for compatibility only
504 wxStreamBuffer
*InputStreamBuffer() const { return m_i_streambuf
; }
507 virtual size_t OnSysRead(void *buffer
, size_t bufsize
);
508 virtual wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
509 virtual wxFileOffset
OnSysTell() const;
511 wxStreamBuffer
*m_i_streambuf
;
513 DECLARE_NO_COPY_CLASS(wxBufferedInputStream
)
516 // ----------------------------------------------------------------------------
517 // wxBufferedOutputStream
518 // ----------------------------------------------------------------------------
520 class WXDLLIMPEXP_BASE wxBufferedOutputStream
: public wxFilterOutputStream
523 // if a non NULL buffer is given to the stream, it will be deleted by it
524 wxBufferedOutputStream(wxOutputStream
& stream
,
525 wxStreamBuffer
*buffer
= NULL
);
526 virtual ~wxBufferedOutputStream();
528 wxOutputStream
& Write(const void *buffer
, size_t size
);
530 // Position functions
531 wxFileOffset
SeekO(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
532 wxFileOffset
TellO() const;
533 bool IsSeekable() const { return m_parent_o_stream
->IsSeekable(); }
538 wxFileOffset
GetLength() const;
540 // the buffer given to the stream will be deleted by it
541 void SetOutputStreamBuffer(wxStreamBuffer
*buffer
);
542 wxStreamBuffer
*GetOutputStreamBuffer() const { return m_o_streambuf
; }
544 // deprecated, for compatibility only
545 wxStreamBuffer
*OutputStreamBuffer() const { return m_o_streambuf
; }
548 virtual size_t OnSysWrite(const void *buffer
, size_t bufsize
);
549 virtual wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
550 virtual wxFileOffset
OnSysTell() const;
552 wxStreamBuffer
*m_o_streambuf
;
554 DECLARE_NO_COPY_CLASS(wxBufferedOutputStream
)
557 #endif // wxUSE_STREAMS
559 #endif // _WX_WXSTREAM_H__