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__
20 #include "wx/object.h"
21 #include "wx/string.h"
22 #include "wx/filefn.h" // for wxFileOffset, wxInvalidOffset and wxSeekMode
24 class WXDLLIMPEXP_BASE wxStreamBase
;
25 class WXDLLIMPEXP_BASE wxInputStream
;
26 class WXDLLIMPEXP_BASE wxOutputStream
;
28 typedef wxInputStream
& (*__wxInputManip
)(wxInputStream
&);
29 typedef wxOutputStream
& (*__wxOutputManip
)(wxOutputStream
&);
31 WXDLLIMPEXP_BASE wxOutputStream
& wxEndL(wxOutputStream
& o_stream
);
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
39 wxSTREAM_NO_ERROR
= 0, // stream is in good state
40 wxSTREAM_EOF
, // EOF reached in Read() or similar
41 wxSTREAM_WRITE_ERROR
, // generic write error
42 wxSTREAM_READ_ERROR
// generic read error
45 // ============================================================================
46 // base stream classes: wxInputStream and wxOutputStream
47 // ============================================================================
49 // ---------------------------------------------------------------------------
50 // wxStreamBase: common (but non virtual!) base for all stream classes
51 // ---------------------------------------------------------------------------
53 class WXDLLIMPEXP_BASE wxStreamBase
57 virtual ~wxStreamBase();
60 wxStreamError
GetLastError() const { return m_lasterror
; }
61 bool IsOk() const { return GetLastError() == wxSTREAM_NO_ERROR
; }
62 bool operator!() const { return !IsOk(); }
64 // reset the stream state
65 void Reset() { m_lasterror
= wxSTREAM_NO_ERROR
; }
67 // this doesn't make sense for all streams, always test its return value
68 virtual size_t GetSize() const;
69 virtual wxFileOffset
GetLength() const { return wxInvalidOffset
; }
71 // returns true if the streams supports seeking to arbitrary offsets
72 virtual bool IsSeekable() const { return false; }
74 // Reserved for future use
75 virtual void ReservedStreamFunc1() {}
76 virtual void ReservedStreamFunc2() {}
77 virtual void ReservedStreamFunc3() {}
78 virtual void ReservedStreamFunc4() {}
79 virtual void ReservedStreamFunc5() {}
80 virtual void ReservedStreamFunc6() {}
81 virtual void ReservedStreamFunc7() {}
82 virtual void ReservedStreamFunc8() {}
83 virtual void ReservedStreamFunc9() {}
86 virtual wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
87 virtual wxFileOffset
OnSysTell() const;
90 wxStreamError m_lasterror
;
92 friend class wxStreamBuffer
;
94 DECLARE_NO_COPY_CLASS(wxStreamBase
)
97 // ----------------------------------------------------------------------------
98 // wxInputStream: base class for the input streams
99 // ----------------------------------------------------------------------------
101 class WXDLLIMPEXP_BASE wxInputStream
: public wxStreamBase
104 // ctor and dtor, nothing exciting
106 virtual ~wxInputStream();
112 // return a character from the stream without removing it, i.e. it will
113 // still be returned by the next call to GetC()
115 // blocks until something appears in the stream if necessary, if nothing
116 // ever does (i.e. EOF) LastRead() will return 0 (and the return value is
117 // undefined), otherwise 1
120 // return one character from the stream, blocking until it appears if
123 // if EOF, return value is undefined and LastRead() will return 0 and not 1
126 // read at most the given number of bytes from the stream
128 // there are 2 possible situations here: either there is nothing at all in
129 // the stream right now in which case Read() blocks until something appears
130 // (use CanRead() to avoid this) or there is already some data available in
131 // the stream and then Read() doesn't block but returns just the data it
132 // can read without waiting for more
134 // in any case, if there are not enough bytes in the stream right now,
135 // LastRead() value will be less than size but greater than 0. If it is 0,
136 // it means that EOF has been reached.
137 virtual wxInputStream
& Read(void *buffer
, size_t size
);
139 // copy the entire contents of this stream into streamOut, stopping only
140 // when EOF is reached or an error occurs
141 wxInputStream
& Read(wxOutputStream
& streamOut
);
147 // returns the number of bytes read by the last call to Read(), GetC() or
150 // this should be used to discover whether that call succeeded in reading
151 // all the requested data or not
152 virtual size_t LastRead() const { return wxStreamBase::m_lastcount
; }
154 // returns true if some data is available in the stream right now, so that
155 // calling Read() wouldn't block
156 virtual bool CanRead() const;
158 // is the stream at EOF?
160 // note that this cannot be really implemented for all streams and
161 // CanRead() is more reliable than Eof()
162 virtual bool Eof() const;
168 // put back the specified number of bytes into the stream, they will be
169 // fetched by the next call to the read functions
171 // returns the number of bytes really stuffed back
172 size_t Ungetch(const void *buffer
, size_t size
);
174 // put back the specified character in the stream
176 // returns true if ok, false on error
177 bool Ungetch(char c
);
180 // position functions
181 // ------------------
183 // move the stream pointer to the given position (if the stream supports
186 // returns wxInvalidOffset on error
187 virtual wxFileOffset
SeekI(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
189 // return the current position of the stream pointer or wxInvalidOffset
190 virtual wxFileOffset
TellI() const;
193 // stream-like operators
194 // ---------------------
196 wxInputStream
& operator>>(wxOutputStream
& out
) { return Read(out
); }
197 wxInputStream
& operator>>(__wxInputManip func
) { return func(*this); }
200 // do read up to size bytes of data into the provided buffer
202 // this method should return 0 if EOF has been reached or an error occurred
203 // (m_lasterror should be set accordingly as well) or the number of bytes
205 virtual size_t OnSysRead(void *buffer
, size_t size
) = 0;
207 // write-back buffer support
208 // -------------------------
210 // return the pointer to a buffer big enough to hold sizeNeeded bytes
211 char *AllocSpaceWBack(size_t sizeNeeded
);
213 // read up to size data from the write back buffer, return the number of
215 size_t GetWBack(void *buf
, size_t size
);
217 // write back buffer or NULL if none
220 // the size of the buffer
223 // the current position in the buffer
226 friend class wxStreamBuffer
;
228 DECLARE_NO_COPY_CLASS(wxInputStream
)
231 // ----------------------------------------------------------------------------
232 // wxOutputStream: base for the output streams
233 // ----------------------------------------------------------------------------
235 class WXDLLIMPEXP_BASE wxOutputStream
: public wxStreamBase
239 virtual ~wxOutputStream();
242 virtual wxOutputStream
& Write(const void *buffer
, size_t size
);
243 wxOutputStream
& Write(wxInputStream
& stream_in
);
245 virtual wxFileOffset
SeekO(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
246 virtual wxFileOffset
TellO() const;
248 virtual size_t LastWrite() const { return wxStreamBase::m_lastcount
; }
251 virtual bool Close() { return true; }
253 wxOutputStream
& operator<<(wxInputStream
& out
) { return Write(out
); }
254 wxOutputStream
& operator<<( __wxOutputManip func
) { return func(*this); }
257 // to be implemented in the derived classes (it should have been pure
259 virtual size_t OnSysWrite(const void *buffer
, size_t bufsize
);
261 friend class wxStreamBuffer
;
263 DECLARE_NO_COPY_CLASS(wxOutputStream
)
266 // ============================================================================
267 // helper stream classes
268 // ============================================================================
270 // ---------------------------------------------------------------------------
271 // A stream for measuring streamed output
272 // ---------------------------------------------------------------------------
274 class WXDLLIMPEXP_BASE wxCountingOutputStream
: public wxOutputStream
277 wxCountingOutputStream();
279 wxFileOffset
GetLength() const;
280 bool Ok() const { return true; }
283 virtual size_t OnSysWrite(const void *buffer
, size_t size
);
284 virtual wxFileOffset
OnSysSeek(wxFileOffset pos
, wxSeekMode mode
);
285 virtual wxFileOffset
OnSysTell() const;
289 DECLARE_NO_COPY_CLASS(wxCountingOutputStream
)
292 // ---------------------------------------------------------------------------
294 // ---------------------------------------------------------------------------
296 class WXDLLIMPEXP_BASE wxFilterInputStream
: public wxInputStream
299 wxFilterInputStream();
300 wxFilterInputStream(wxInputStream
& stream
);
301 virtual ~wxFilterInputStream();
303 char Peek() { return m_parent_i_stream
->Peek(); }
305 wxFileOffset
GetLength() const { return m_parent_i_stream
->GetLength(); }
307 wxInputStream
*GetFilterInputStream() const { return m_parent_i_stream
; }
310 wxInputStream
*m_parent_i_stream
;
312 DECLARE_NO_COPY_CLASS(wxFilterInputStream
)
315 class WXDLLIMPEXP_BASE wxFilterOutputStream
: public wxOutputStream
318 wxFilterOutputStream();
319 wxFilterOutputStream(wxOutputStream
& stream
);
320 virtual ~wxFilterOutputStream();
322 wxFileOffset
GetLength() const { return m_parent_o_stream
->GetLength(); }
324 wxOutputStream
*GetFilterOutputStream() const { return m_parent_o_stream
; }
327 wxOutputStream
*m_parent_o_stream
;
329 DECLARE_NO_COPY_CLASS(wxFilterOutputStream
)
332 // ============================================================================
334 // ============================================================================
336 // ---------------------------------------------------------------------------
337 // Stream buffer: this class can be derived from and passed to
338 // wxBufferedStreams to implement custom buffering
339 // ---------------------------------------------------------------------------
341 class WXDLLIMPEXP_BASE wxStreamBuffer
351 wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
);
352 wxStreamBuffer(const wxStreamBuffer
& buf
);
353 virtual ~wxStreamBuffer();
356 virtual size_t Read(void *buffer
, size_t size
);
357 size_t Read(wxStreamBuffer
*buf
);
358 virtual size_t Write(const void *buffer
, size_t size
);
359 size_t Write(wxStreamBuffer
*buf
);
362 virtual char GetChar();
363 virtual void PutChar(char c
);
364 virtual wxFileOffset
Tell() const;
365 virtual wxFileOffset
Seek(wxFileOffset pos
, wxSeekMode mode
);
370 // NB: the buffer must always be allocated with malloc() if takeOwn is
371 // true as it will be deallocated by free()
372 void SetBufferIO(void *start
, void *end
, bool takeOwnership
= false);
373 void SetBufferIO(void *start
, size_t len
, bool takeOwnership
= false);
374 void SetBufferIO(size_t bufsize
);
375 void *GetBufferStart() const { return m_buffer_start
; }
376 void *GetBufferEnd() const { return m_buffer_end
; }
377 void *GetBufferPos() const { return m_buffer_pos
; }
378 size_t GetBufferSize() const { return m_buffer_size
; }
379 size_t GetIntPosition() const { return m_buffer_pos
- m_buffer_start
; }
380 void SetIntPosition(size_t pos
) { m_buffer_pos
= m_buffer_start
+ pos
; }
381 size_t GetLastAccess() const { return m_buffer_end
- m_buffer_start
; }
382 size_t GetBytesLeft() const { return m_buffer_end
- m_buffer_pos
; }
384 void Fixed(bool fixed
) { m_fixed
= fixed
; }
385 void Flushable(bool f
) { m_flushable
= f
; }
389 size_t GetDataLeft();
392 wxStreamBase
*GetStream() const { return m_stream
; }
393 bool HasBuffer() const { return m_buffer_size
!= 0; }
395 bool IsFixed() const { return m_fixed
; }
396 bool IsFlushable() const { return m_flushable
; }
398 // only for input/output buffers respectively, returns NULL otherwise
399 wxInputStream
*GetInputStream() const;
400 wxOutputStream
*GetOutputStream() const;
402 // deprecated, for compatibility only
403 wxStreamBase
*Stream() { return m_stream
; }
405 // this constructs a dummy wxStreamBuffer, used by (and exists for)
406 // wxMemoryStreams only, don't use!
407 wxStreamBuffer(BufMode mode
);
410 void GetFromBuffer(void *buffer
, size_t size
);
411 void PutToBuffer(const void *buffer
, size_t size
);
413 // set the last error to the specified value if we didn't have it before
414 void SetError(wxStreamError err
);
416 // common part of several ctors
419 // init buffer variables to be empty
422 // free the buffer (always safe to call)
425 // the buffer itself: the pointers to its start and end and the current
426 // position in the buffer
427 char *m_buffer_start
,
432 // FIXME: isn't it the same as m_buffer_end - m_buffer_start? (VZ)
433 size_t m_buffer_size
;
435 // the stream we're associated with
436 wxStreamBase
*m_stream
;
442 bool m_destroybuf
, // deallocate buffer?
448 // DECLARE_NO_COPY_CLASS(wxStreamBuffer)
449 // because copy constructor is explicitly declared above;
450 // but no copy assignment operator is defined, so declare
451 // it private to prevent the compiler from defining it:
452 wxStreamBuffer
& operator=(const wxStreamBuffer
&);
455 // ---------------------------------------------------------------------------
456 // wxBufferedInputStream
457 // ---------------------------------------------------------------------------
459 class WXDLLIMPEXP_BASE wxBufferedInputStream
: public wxFilterInputStream
462 // if a non NULL buffer is given to the stream, it will be deleted by it
463 wxBufferedInputStream(wxInputStream
& stream
,
464 wxStreamBuffer
*buffer
= NULL
);
465 virtual ~wxBufferedInputStream();
468 wxInputStream
& Read(void *buffer
, size_t size
);
470 // Position functions
471 wxFileOffset
SeekI(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
472 wxFileOffset
TellI() const;
473 bool IsSeekable() const { return m_parent_i_stream
->IsSeekable(); }
475 // the buffer given to the stream will be deleted by it
476 void SetInputStreamBuffer(wxStreamBuffer
*buffer
);
477 wxStreamBuffer
*GetInputStreamBuffer() const { return m_i_streambuf
; }
479 // deprecated, for compatibility only
480 wxStreamBuffer
*InputStreamBuffer() const { return m_i_streambuf
; }
483 virtual size_t OnSysRead(void *buffer
, size_t bufsize
);
484 virtual wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
485 virtual wxFileOffset
OnSysTell() const;
487 wxStreamBuffer
*m_i_streambuf
;
489 DECLARE_NO_COPY_CLASS(wxBufferedInputStream
)
492 // ----------------------------------------------------------------------------
493 // wxBufferedOutputStream
494 // ----------------------------------------------------------------------------
496 class WXDLLIMPEXP_BASE wxBufferedOutputStream
: public wxFilterOutputStream
499 // if a non NULL buffer is given to the stream, it will be deleted by it
500 wxBufferedOutputStream(wxOutputStream
& stream
,
501 wxStreamBuffer
*buffer
= NULL
);
502 virtual ~wxBufferedOutputStream();
504 wxOutputStream
& Write(const void *buffer
, size_t size
);
506 // Position functions
507 wxFileOffset
SeekO(wxFileOffset pos
, wxSeekMode mode
= wxFromStart
);
508 wxFileOffset
TellO() const;
509 bool IsSeekable() const { return m_parent_o_stream
->IsSeekable(); }
514 wxFileOffset
GetLength() const;
516 // the buffer given to the stream will be deleted by it
517 void SetOutputStreamBuffer(wxStreamBuffer
*buffer
);
518 wxStreamBuffer
*GetOutputStreamBuffer() const { return m_o_streambuf
; }
520 // deprecated, for compatibility only
521 wxStreamBuffer
*OutputStreamBuffer() const { return m_o_streambuf
; }
524 virtual size_t OnSysWrite(const void *buffer
, size_t bufsize
);
525 virtual wxFileOffset
OnSysSeek(wxFileOffset seek
, wxSeekMode mode
);
526 virtual wxFileOffset
OnSysTell() const;
528 wxStreamBuffer
*m_o_streambuf
;
530 DECLARE_NO_COPY_CLASS(wxBufferedOutputStream
)
533 #endif // wxUSE_STREAMS
535 #endif // _WX_WXSTREAM_H__