]> git.saurik.com Git - wxWidgets.git/blob - include/wx/stream.h
wxPerl notes for DocView.
[wxWidgets.git] / include / wx / stream.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/stream.h
3 // Purpose: stream classes
4 // Author: Guilhem Lavaux, Guillermo Rodriguez Garcia, Vadim Zeitlin
5 // Modified by:
6 // Created: 11/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_WXSTREAM_H__
13 #define _WX_WXSTREAM_H__
14
15 #if defined(__GNUG__) && !defined(__APPLE__)
16 #pragma interface "stream.h"
17 #endif
18
19 #include "wx/defs.h"
20
21 #if wxUSE_STREAMS
22
23 #include <stdio.h>
24 #include "wx/object.h"
25 #include "wx/string.h"
26 #include "wx/filefn.h" // for off_t, wxInvalidOffset and wxSeekMode
27
28 class WXDLLEXPORT wxStreamBase;
29 class WXDLLEXPORT wxInputStream;
30 class WXDLLEXPORT wxOutputStream;
31
32 typedef wxInputStream& (*__wxInputManip)(wxInputStream&);
33 typedef wxOutputStream& (*__wxOutputManip)(wxOutputStream&);
34
35 WXDLLEXPORT wxOutputStream& wxEndL(wxOutputStream& o_stream);
36
37 // ----------------------------------------------------------------------------
38 // constants
39 // ----------------------------------------------------------------------------
40
41 enum wxStreamError
42 {
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
47 };
48
49 // compatibility
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
55
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
61
62 // ============================================================================
63 // base stream classes: wxInputStream and wxOutputStream
64 // ============================================================================
65
66 // ---------------------------------------------------------------------------
67 // wxStreamBase: common (but non virtual!) base for all stream classes
68 // ---------------------------------------------------------------------------
69
70 class WXDLLEXPORT wxStreamBase
71 {
72 public:
73 wxStreamBase();
74 virtual ~wxStreamBase();
75
76 // error testing
77 wxStreamError GetLastError() const { return m_lasterror; }
78 bool IsOk() const { return GetLastError() == wxSTREAM_NO_ERROR; }
79 bool operator!() const { return !IsOk(); }
80
81 // reset the stream state
82 void Reset() { m_lasterror = wxSTREAM_NO_ERROR; }
83
84 // deprecated (doesn't make sense!), don't use
85 virtual size_t GetSize() const { return 0; }
86
87 #if WXWIN_COMPATIBILITY_2_2
88 // deprecated, for compatibility only
89 wxStreamError LastError() const { return m_lasterror; }
90 size_t StreamSize() const { return GetSize(); }
91 #endif // WXWIN_COMPATIBILITY_2_2
92
93 protected:
94 virtual off_t OnSysSeek(off_t seek, wxSeekMode mode);
95 virtual off_t OnSysTell() const;
96
97 size_t m_lastcount;
98 wxStreamError m_lasterror;
99
100 friend class wxStreamBuffer;
101 };
102
103 // ----------------------------------------------------------------------------
104 // wxInputStream: base class for the input streams
105 // ----------------------------------------------------------------------------
106
107 class WXDLLEXPORT wxInputStream : public wxStreamBase
108 {
109 public:
110 // ctor and dtor, nothing exciting
111 wxInputStream();
112 virtual ~wxInputStream();
113
114
115 // IO functions
116 // ------------
117
118 // return a character from the stream without removing it, i.e. it will
119 // still be returned by the next call to GetC()
120 //
121 // blocks until something appears in the stream if necessary, if nothing
122 // ever does (i.e. EOF) LastRead() will return 0 (and the return value is
123 // undefined), otherwise 1
124 virtual char Peek();
125
126 // return one character from the stream, blocking until it appears if
127 // necessary
128 //
129 // if EOF, return value is undefined and LastRead() will return 0 and not 1
130 char GetC();
131
132 // read at most the given number of bytes from the stream
133 //
134 // there are 2 possible situations here: either there is nothing at all in
135 // the stream right now in which case Read() blocks until something appears
136 // (use CanRead() to avoid this) or there is already some data available in
137 // the stream and then Read() doesn't block but returns just the data it
138 // can read without waiting for more
139 //
140 // in any case, if there are not enough bytes in the stream right now,
141 // LastRead() value will be less than size but greater than 0. If it is 0,
142 // it means that EOF has been reached.
143 virtual wxInputStream& Read(void *buffer, size_t size);
144
145 // copy the entire contents of this stream into streamOut, stopping only
146 // when EOF is reached or an error occurs
147 wxInputStream& Read(wxOutputStream& streamOut);
148
149
150 // status functions
151 // ----------------
152
153 // returns the number of bytes read by the last call to Read(), GetC() or
154 // Peek()
155 //
156 // this should be used to discover whether that call succeeded in reading
157 // all the requested data or not
158 virtual size_t LastRead() const { return wxStreamBase::m_lastcount; }
159
160 // returns TRUE if some data is available in the stream right now, so that
161 // calling Read() wouldn't block
162 virtual bool CanRead() const;
163
164 // is the stream at EOF?
165 //
166 // note that this cannot be really implemented for all streams and
167 // CanRead() is more reliable than Eof()
168 virtual bool Eof() const;
169
170
171 // write back buffer
172 // -----------------
173
174 // put back the specified number of bytes into the stream, they will be
175 // fetched by the next call to the read functions
176 //
177 // returns the number of bytes really stuffed back
178 size_t Ungetch(const void *buffer, size_t size);
179
180 // put back the specified character in the stream
181 //
182 // returns TRUE if ok, FALSE on error
183 bool Ungetch(char c);
184
185
186 // position functions
187 // ------------------
188
189 // move the stream pointer to the given position (if the stream supports
190 // it)
191 //
192 // returns wxInvalidOffset on error
193 virtual off_t SeekI(off_t pos, wxSeekMode mode = wxFromStart);
194
195 // return the current position of the stream pointer or wxInvalidOffset
196 virtual off_t TellI() const;
197
198
199 // stream-like operators
200 // ---------------------
201
202 wxInputStream& operator>>(wxOutputStream& out) { return Read(out); }
203 wxInputStream& operator>>(__wxInputManip func) { return func(*this); }
204
205 protected:
206 // do read up to size bytes of data into the provided buffer
207 //
208 // this method should return 0 if EOF has been reached or an error occured
209 // (m_lasterror should be set accordingly as well) or the number of bytes
210 // read
211 virtual size_t OnSysRead(void *buffer, size_t size) = 0;
212
213 // write-back buffer support
214 // -------------------------
215
216 // return the pointer to a buffer big enough to hold sizeNeeded bytes
217 char *AllocSpaceWBack(size_t sizeNeeded);
218
219 // read up to size data from the write back buffer, return the number of
220 // bytes read
221 size_t GetWBack(void *buf, size_t size);
222
223 // write back buffer or NULL if none
224 char *m_wback;
225
226 // the size of the buffer
227 size_t m_wbacksize;
228
229 // the current position in the buffer
230 size_t m_wbackcur;
231
232 friend class wxStreamBuffer;
233 };
234
235 // ----------------------------------------------------------------------------
236 // wxOutputStream: base for the output streams
237 // ----------------------------------------------------------------------------
238
239 class WXDLLEXPORT wxOutputStream : public wxStreamBase
240 {
241 public:
242 wxOutputStream();
243 virtual ~wxOutputStream();
244
245 void PutC(char c);
246 virtual wxOutputStream& Write(const void *buffer, size_t size);
247 wxOutputStream& Write(wxInputStream& stream_in);
248
249 virtual off_t SeekO(off_t pos, wxSeekMode mode = wxFromStart);
250 virtual off_t TellO() const;
251
252 virtual size_t LastWrite() const { return wxStreamBase::m_lastcount; }
253
254 virtual void Sync();
255
256 wxOutputStream& operator<<(wxInputStream& out) { return Write(out); }
257 wxOutputStream& operator<<( __wxOutputManip func) { return func(*this); }
258
259 protected:
260 // to be implemented in the derived classes (it should have been pure
261 // virtual)
262 virtual size_t OnSysWrite(const void *buffer, size_t bufsize);
263
264 friend class wxStreamBuffer;
265 };
266
267 // ============================================================================
268 // helper stream classes
269 // ============================================================================
270
271 // ---------------------------------------------------------------------------
272 // A stream for measuring streamed output
273 // ---------------------------------------------------------------------------
274
275 class WXDLLEXPORT wxCountingOutputStream : public wxOutputStream
276 {
277 public:
278 wxCountingOutputStream();
279
280 size_t GetSize() const;
281 bool Ok() const { return TRUE; }
282
283 protected:
284 virtual size_t OnSysWrite(const void *buffer, size_t size);
285 virtual off_t OnSysSeek(off_t pos, wxSeekMode mode);
286 virtual off_t OnSysTell() const;
287
288 size_t m_currentPos;
289 };
290
291 // ---------------------------------------------------------------------------
292 // "Filter" streams
293 // ---------------------------------------------------------------------------
294
295 class WXDLLEXPORT wxFilterInputStream : public wxInputStream
296 {
297 public:
298 wxFilterInputStream();
299 wxFilterInputStream(wxInputStream& stream);
300 virtual ~wxFilterInputStream();
301
302 char Peek() { return m_parent_i_stream->Peek(); }
303
304 size_t GetSize() const { return m_parent_i_stream->GetSize(); }
305
306 wxInputStream *GetFilterInputStream() const { return m_parent_i_stream; }
307
308 protected:
309 wxInputStream *m_parent_i_stream;
310 };
311
312 class WXDLLEXPORT wxFilterOutputStream : public wxOutputStream
313 {
314 public:
315 wxFilterOutputStream();
316 wxFilterOutputStream(wxOutputStream& stream);
317 virtual ~wxFilterOutputStream();
318
319 size_t GetSize() const { return m_parent_o_stream->GetSize(); }
320
321 wxOutputStream *GetFilterOutputStream() const { return m_parent_o_stream; }
322
323 protected:
324 wxOutputStream *m_parent_o_stream;
325 };
326
327 // ============================================================================
328 // buffered streams
329 // ============================================================================
330
331 // ---------------------------------------------------------------------------
332 // Stream buffer: this class can be derived from and passed to
333 // wxBufferedStreams to implement custom buffering
334 // ---------------------------------------------------------------------------
335
336 class WXDLLEXPORT wxStreamBuffer
337 {
338 public:
339 enum BufMode
340 {
341 read,
342 write,
343 read_write
344 };
345
346 wxStreamBuffer(wxStreamBase& stream, BufMode mode);
347 wxStreamBuffer(const wxStreamBuffer& buf);
348 virtual ~wxStreamBuffer();
349
350 // Filtered IO
351 virtual size_t Read(void *buffer, size_t size);
352 size_t Read(wxStreamBuffer *buf);
353 virtual size_t Write(const void *buffer, size_t size);
354 size_t Write(wxStreamBuffer *buf);
355
356 virtual char Peek();
357 virtual char GetChar();
358 virtual void PutChar(char c);
359 virtual off_t Tell() const;
360 virtual off_t Seek(off_t pos, wxSeekMode mode);
361
362 // Buffer control
363 void ResetBuffer();
364
365 // NB: the buffer must always be allocated with malloc() if takeOwn is
366 // TRUE as it will be deallocated by free()
367 void SetBufferIO(void *start, void *end, bool takeOwnership = FALSE);
368 void SetBufferIO(void *start, size_t len, bool takeOwnership = FALSE);
369 void SetBufferIO(size_t bufsize);
370 void *GetBufferStart() const { return m_buffer_start; }
371 void *GetBufferEnd() const { return m_buffer_end; }
372 void *GetBufferPos() const { return m_buffer_pos; }
373 size_t GetBufferSize() const { return m_buffer_size; }
374 size_t GetIntPosition() const { return m_buffer_pos - m_buffer_start; }
375 void SetIntPosition(size_t pos) { m_buffer_pos = m_buffer_start + pos; }
376 size_t GetLastAccess() const { return m_buffer_end - m_buffer_start; }
377 size_t GetBytesLeft() const { return m_buffer_end - m_buffer_pos; }
378
379 void Fixed(bool fixed) { m_fixed = fixed; }
380 void Flushable(bool f) { m_flushable = f; }
381
382 bool FlushBuffer();
383 bool FillBuffer();
384 size_t GetDataLeft();
385
386 // misc accessors
387 wxStreamBase *GetStream() const { return m_stream; }
388 bool HasBuffer() const { return m_buffer_size != 0; }
389
390 bool IsFixed() const { return m_fixed; }
391 bool IsFlushable() const { return m_flushable; }
392
393 // only for input/output buffers respectively, returns NULL otherwise
394 wxInputStream *GetInputStream() const;
395 wxOutputStream *GetOutputStream() const;
396
397 // deprecated, for compatibility only
398 wxStreamBase *Stream() { return m_stream; }
399
400 // this constructs a dummy wxStreamBuffer, used by (and exists for)
401 // wxMemoryStreams only, don't use!
402 wxStreamBuffer(BufMode mode);
403
404 protected:
405 void GetFromBuffer(void *buffer, size_t size);
406 void PutToBuffer(const void *buffer, size_t size);
407
408 // set the last error to the specified value if we didn't have it before
409 void SetError(wxStreamError err);
410
411 // common part of several ctors
412 void Init();
413
414 // init buffer variables to be empty
415 void InitBuffer();
416
417 // free the buffer (always safe to call)
418 void FreeBuffer();
419
420 // the buffer itself: the pointers to its start and end and the current
421 // position in the buffer
422 char *m_buffer_start,
423 *m_buffer_end,
424 *m_buffer_pos;
425
426 // the buffer size
427 // FIXME: isn't it the same as m_buffer_end - m_buffer_start? (VZ)
428 size_t m_buffer_size;
429
430 // the stream we're associated with
431 wxStreamBase *m_stream;
432
433 // its mode
434 BufMode m_mode;
435
436 // flags
437 bool m_destroybuf, // deallocate buffer?
438 m_fixed,
439 m_flushable;
440 };
441
442 // ---------------------------------------------------------------------------
443 // wxBufferedInputStream
444 // ---------------------------------------------------------------------------
445
446 class WXDLLEXPORT wxBufferedInputStream : public wxFilterInputStream
447 {
448 public:
449 // if a non NULL buffer is given to the stream, it will be deleted by it
450 wxBufferedInputStream(wxInputStream& stream,
451 wxStreamBuffer *buffer = NULL);
452 virtual ~wxBufferedInputStream();
453
454 char Peek();
455 wxInputStream& Read(void *buffer, size_t size);
456
457 // Position functions
458 off_t SeekI(off_t pos, wxSeekMode mode = wxFromStart);
459 off_t TellI() const;
460
461 // the buffer given to the stream will be deleted by it
462 void SetInputStreamBuffer(wxStreamBuffer *buffer);
463 wxStreamBuffer *GetInputStreamBuffer() const { return m_i_streambuf; }
464
465 // deprecated, for compatibility only
466 wxStreamBuffer *InputStreamBuffer() const { return m_i_streambuf; }
467
468 protected:
469 virtual size_t OnSysRead(void *buffer, size_t bufsize);
470 virtual off_t OnSysSeek(off_t seek, wxSeekMode mode);
471 virtual off_t OnSysTell() const;
472
473 wxStreamBuffer *m_i_streambuf;
474 };
475
476 // ----------------------------------------------------------------------------
477 // wxBufferedOutputStream
478 // ----------------------------------------------------------------------------
479
480 class WXDLLEXPORT wxBufferedOutputStream : public wxFilterOutputStream
481 {
482 public:
483 // if a non NULL buffer is given to the stream, it will be deleted by it
484 wxBufferedOutputStream(wxOutputStream& stream,
485 wxStreamBuffer *buffer = NULL);
486 virtual ~wxBufferedOutputStream();
487
488 wxOutputStream& Write(const void *buffer, size_t size);
489
490 // Position functions
491 off_t SeekO(off_t pos, wxSeekMode mode = wxFromStart);
492 off_t TellO() const;
493
494 void Sync();
495
496 size_t GetSize() const;
497
498 // the buffer given to the stream will be deleted by it
499 void SetOutputStreamBuffer(wxStreamBuffer *buffer);
500 wxStreamBuffer *GetOutputStreamBuffer() const { return m_o_streambuf; }
501
502 // deprecated, for compatibility only
503 wxStreamBuffer *OutputStreamBuffer() const { return m_o_streambuf; }
504
505 protected:
506 virtual size_t OnSysWrite(const void *buffer, size_t bufsize);
507 virtual off_t OnSysSeek(off_t seek, wxSeekMode mode);
508 virtual off_t OnSysTell() const;
509
510 wxStreamBuffer *m_o_streambuf;
511 };
512
513 #endif // wxUSE_STREAMS
514
515 #endif // _WX_WXSTREAM_H__
516