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 // Copyright:   (c) Guilhem Lavaux
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef _WX_WXSTREAM_H__
12 #define _WX_WXSTREAM_H__
13 
14 #include "wx/defs.h"
15 
16 #if wxUSE_STREAMS
17 
18 #include <stdio.h>
19 #include "wx/object.h"
20 #include "wx/string.h"
21 #include "wx/filefn.h"  // for wxFileOffset, wxInvalidOffset and wxSeekMode
22 
23 class WXDLLIMPEXP_FWD_BASE wxStreamBase;
24 class WXDLLIMPEXP_FWD_BASE wxInputStream;
25 class WXDLLIMPEXP_FWD_BASE wxOutputStream;
26 
27 typedef wxInputStream& (*__wxInputManip)(wxInputStream&);
28 typedef wxOutputStream& (*__wxOutputManip)(wxOutputStream&);
29 
30 WXDLLIMPEXP_BASE wxOutputStream& wxEndL(wxOutputStream& o_stream);
31 
32 // ----------------------------------------------------------------------------
33 // constants
34 // ----------------------------------------------------------------------------
35 
36 enum wxStreamError
37 {
38     wxSTREAM_NO_ERROR = 0,      // stream is in good state
39     wxSTREAM_EOF,               // EOF reached in Read() or similar
40     wxSTREAM_WRITE_ERROR,       // generic write error
41     wxSTREAM_READ_ERROR         // generic read error
42 };
43 
44 const int wxEOF = -1;
45 
46 // ============================================================================
47 // base stream classes: wxInputStream and wxOutputStream
48 // ============================================================================
49 
50 // ---------------------------------------------------------------------------
51 // wxStreamBase: common (but non virtual!) base for all stream classes
52 // ---------------------------------------------------------------------------
53 
54 class WXDLLIMPEXP_BASE wxStreamBase : public wxObject
55 {
56 public:
57     wxStreamBase();
58     virtual ~wxStreamBase();
59 
60     // error testing
GetLastError()61     wxStreamError GetLastError() const { return m_lasterror; }
IsOk()62     virtual bool IsOk() const { return GetLastError() == wxSTREAM_NO_ERROR; }
63     bool operator!() const { return !IsOk(); }
64 
65     // reset the stream state
66     void Reset(wxStreamError error = wxSTREAM_NO_ERROR) { m_lasterror = error; }
67 
68     // this doesn't make sense for all streams, always test its return value
69     virtual size_t GetSize() const;
GetLength()70     virtual wxFileOffset GetLength() const { return wxInvalidOffset; }
71 
72     // returns true if the streams supports seeking to arbitrary offsets
IsSeekable()73     virtual bool IsSeekable() const { return false; }
74 
75 protected:
76     virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
77     virtual wxFileOffset OnSysTell() const;
78 
79     size_t m_lastcount;
80     wxStreamError m_lasterror;
81 
82     friend class wxStreamBuffer;
83 
84     DECLARE_ABSTRACT_CLASS(wxStreamBase)
85     wxDECLARE_NO_COPY_CLASS(wxStreamBase);
86 };
87 
88 // ----------------------------------------------------------------------------
89 // wxInputStream: base class for the input streams
90 // ----------------------------------------------------------------------------
91 
92 class WXDLLIMPEXP_BASE wxInputStream : public wxStreamBase
93 {
94 public:
95     // ctor and dtor, nothing exciting
96     wxInputStream();
97     virtual ~wxInputStream();
98 
99 
100     // IO functions
101     // ------------
102 
103     // return a character from the stream without removing it, i.e. it will
104     // still be returned by the next call to GetC()
105     //
106     // blocks until something appears in the stream if necessary, if nothing
107     // ever does (i.e. EOF) LastRead() will return 0 (and the return value is
108     // undefined), otherwise 1
109     virtual char Peek();
110 
111     // return one byte from the stream, blocking until it appears if
112     // necessary
113     //
114     // on success returns a value between 0 - 255, or wxEOF on EOF or error.
115     int GetC();
116 
117     // read at most the given number of bytes from the stream
118     //
119     // there are 2 possible situations here: either there is nothing at all in
120     // the stream right now in which case Read() blocks until something appears
121     // (use CanRead() to avoid this) or there is already some data available in
122     // the stream and then Read() doesn't block but returns just the data it
123     // can read without waiting for more
124     //
125     // in any case, if there are not enough bytes in the stream right now,
126     // LastRead() value will be less than size but greater than 0. If it is 0,
127     // it means that EOF has been reached.
128     virtual wxInputStream& Read(void *buffer, size_t size);
129 
130     // Read exactly the given number of bytes, unlike Read(), which may read
131     // less than the requested amount of data without returning an error, this
132     // method either reads all the data or returns false.
133     bool ReadAll(void *buffer, size_t size);
134 
135     // copy the entire contents of this stream into streamOut, stopping only
136     // when EOF is reached or an error occurs
137     wxInputStream& Read(wxOutputStream& streamOut);
138 
139 
140     // status functions
141     // ----------------
142 
143     // returns the number of bytes read by the last call to Read(), GetC() or
144     // Peek()
145     //
146     // this should be used to discover whether that call succeeded in reading
147     // all the requested data or not
LastRead()148     virtual size_t LastRead() const { return wxStreamBase::m_lastcount; }
149 
150     // returns true if some data is available in the stream right now, so that
151     // calling Read() wouldn't block
152     virtual bool CanRead() const;
153 
154     // is the stream at EOF?
155     //
156     // note that this cannot be really implemented for all streams and
157     // CanRead() is more reliable than Eof()
158     virtual bool Eof() const;
159 
160 
161     // write back buffer
162     // -----------------
163 
164     // put back the specified number of bytes into the stream, they will be
165     // fetched by the next call to the read functions
166     //
167     // returns the number of bytes really stuffed back
168     size_t Ungetch(const void *buffer, size_t size);
169 
170     // put back the specified character in the stream
171     //
172     // returns true if ok, false on error
173     bool Ungetch(char c);
174 
175 
176     // position functions
177     // ------------------
178 
179     // move the stream pointer to the given position (if the stream supports
180     // it)
181     //
182     // returns wxInvalidOffset on error
183     virtual wxFileOffset SeekI(wxFileOffset pos, wxSeekMode mode = wxFromStart);
184 
185     // return the current position of the stream pointer or wxInvalidOffset
186     virtual wxFileOffset TellI() const;
187 
188 
189     // stream-like operators
190     // ---------------------
191 
192     wxInputStream& operator>>(wxOutputStream& out) { return Read(out); }
193     wxInputStream& operator>>(__wxInputManip func) { return func(*this); }
194 
195 protected:
196     // do read up to size bytes of data into the provided buffer
197     //
198     // this method should return 0 if EOF has been reached or an error occurred
199     // (m_lasterror should be set accordingly as well) or the number of bytes
200     // read
201     virtual size_t OnSysRead(void *buffer, size_t size) = 0;
202 
203     // write-back buffer support
204     // -------------------------
205 
206     // return the pointer to a buffer big enough to hold sizeNeeded bytes
207     char *AllocSpaceWBack(size_t sizeNeeded);
208 
209     // read up to size data from the write back buffer, return the number of
210     // bytes read
211     size_t GetWBack(void *buf, size_t size);
212 
213     // write back buffer or NULL if none
214     char *m_wback;
215 
216     // the size of the buffer
217     size_t m_wbacksize;
218 
219     // the current position in the buffer
220     size_t m_wbackcur;
221 
222     friend class wxStreamBuffer;
223 
224     DECLARE_ABSTRACT_CLASS(wxInputStream)
225     wxDECLARE_NO_COPY_CLASS(wxInputStream);
226 };
227 
228 // ----------------------------------------------------------------------------
229 // wxOutputStream: base for the output streams
230 // ----------------------------------------------------------------------------
231 
232 class WXDLLIMPEXP_BASE wxOutputStream : public wxStreamBase
233 {
234 public:
235     wxOutputStream();
236     virtual ~wxOutputStream();
237 
238     void PutC(char c);
239     virtual wxOutputStream& Write(const void *buffer, size_t size);
240 
241     // This is ReadAll() equivalent for Write(): it either writes exactly the
242     // given number of bytes or returns false, unlike Write() which can write
243     // less data than requested but still return without error.
244     bool WriteAll(const void *buffer, size_t size);
245 
246     wxOutputStream& Write(wxInputStream& stream_in);
247 
248     virtual wxFileOffset SeekO(wxFileOffset pos, wxSeekMode mode = wxFromStart);
249     virtual wxFileOffset TellO() const;
250 
LastWrite()251     virtual size_t LastWrite() const { return wxStreamBase::m_lastcount; }
252 
253     virtual void Sync();
Close()254     virtual bool Close() { return true; }
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     DECLARE_ABSTRACT_CLASS(wxOutputStream)
267     wxDECLARE_NO_COPY_CLASS(wxOutputStream);
268 };
269 
270 // ============================================================================
271 // helper stream classes
272 // ============================================================================
273 
274 // ---------------------------------------------------------------------------
275 // A stream for measuring streamed output
276 // ---------------------------------------------------------------------------
277 
278 class WXDLLIMPEXP_BASE wxCountingOutputStream : public wxOutputStream
279 {
280 public:
281     wxCountingOutputStream();
282 
283     virtual wxFileOffset GetLength() const;
Ok()284     bool Ok() const { return IsOk(); }
IsOk()285     virtual bool IsOk() const { return true; }
286 
287 protected:
288     virtual size_t OnSysWrite(const void *buffer, size_t size);
289     virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
290     virtual wxFileOffset OnSysTell() const;
291 
292     size_t m_currentPos,
293            m_lastPos;
294 
295     DECLARE_DYNAMIC_CLASS(wxCountingOutputStream)
296     wxDECLARE_NO_COPY_CLASS(wxCountingOutputStream);
297 };
298 
299 // ---------------------------------------------------------------------------
300 // "Filter" streams
301 // ---------------------------------------------------------------------------
302 
303 class WXDLLIMPEXP_BASE wxFilterInputStream : public wxInputStream
304 {
305 public:
306     wxFilterInputStream();
307     wxFilterInputStream(wxInputStream& stream);
308     wxFilterInputStream(wxInputStream *stream);
309     virtual ~wxFilterInputStream();
310 
Peek()311     char Peek() { return m_parent_i_stream->Peek(); }
312 
GetLength()313     wxFileOffset GetLength() const { return m_parent_i_stream->GetLength(); }
314 
GetFilterInputStream()315     wxInputStream *GetFilterInputStream() const { return m_parent_i_stream; }
316 
317 protected:
318     wxInputStream *m_parent_i_stream;
319     bool m_owns;
320 
321     DECLARE_ABSTRACT_CLASS(wxFilterInputStream)
322     wxDECLARE_NO_COPY_CLASS(wxFilterInputStream);
323 };
324 
325 class WXDLLIMPEXP_BASE wxFilterOutputStream : public wxOutputStream
326 {
327 public:
328     wxFilterOutputStream();
329     wxFilterOutputStream(wxOutputStream& stream);
330     wxFilterOutputStream(wxOutputStream *stream);
331     virtual ~wxFilterOutputStream();
332 
GetLength()333     wxFileOffset GetLength() const { return m_parent_o_stream->GetLength(); }
334 
GetFilterOutputStream()335     wxOutputStream *GetFilterOutputStream() const { return m_parent_o_stream; }
336 
337     bool Close();
338 
339 protected:
340     wxOutputStream *m_parent_o_stream;
341     bool m_owns;
342 
343     DECLARE_ABSTRACT_CLASS(wxFilterOutputStream)
344     wxDECLARE_NO_COPY_CLASS(wxFilterOutputStream);
345 };
346 
347 enum wxStreamProtocolType
348 {
349     wxSTREAM_PROTOCOL,  // wxFileSystem protocol (should be only one)
350     wxSTREAM_MIMETYPE,  // MIME types the stream handles
351     wxSTREAM_ENCODING,  // The HTTP Content-Encodings the stream handles
352     wxSTREAM_FILEEXT    // File extensions the stream handles
353 };
354 
355 void WXDLLIMPEXP_BASE wxUseFilterClasses();
356 
357 class WXDLLIMPEXP_BASE wxFilterClassFactoryBase : public wxObject
358 {
359 public:
~wxFilterClassFactoryBase()360     virtual ~wxFilterClassFactoryBase() { }
361 
GetProtocol()362     wxString GetProtocol() const { return wxString(*GetProtocols()); }
363     wxString PopExtension(const wxString& location) const;
364 
365     virtual const wxChar * const *GetProtocols(wxStreamProtocolType type
366                                                = wxSTREAM_PROTOCOL) const = 0;
367 
368     bool CanHandle(const wxString& protocol,
369                    wxStreamProtocolType type
370                    = wxSTREAM_PROTOCOL) const;
371 
372 protected:
373     wxString::size_type FindExtension(const wxString& location) const;
374 
375     DECLARE_ABSTRACT_CLASS(wxFilterClassFactoryBase)
376 };
377 
378 class WXDLLIMPEXP_BASE wxFilterClassFactory : public wxFilterClassFactoryBase
379 {
380 public:
~wxFilterClassFactory()381     virtual ~wxFilterClassFactory() { }
382 
383     virtual wxFilterInputStream  *NewStream(wxInputStream& stream)  const = 0;
384     virtual wxFilterOutputStream *NewStream(wxOutputStream& stream) const = 0;
385     virtual wxFilterInputStream  *NewStream(wxInputStream *stream)  const = 0;
386     virtual wxFilterOutputStream *NewStream(wxOutputStream *stream) const = 0;
387 
388     static const wxFilterClassFactory *Find(const wxString& protocol,
389                                             wxStreamProtocolType type
390                                             = wxSTREAM_PROTOCOL);
391 
392     static const wxFilterClassFactory *GetFirst();
GetNext()393     const wxFilterClassFactory *GetNext() const { return m_next; }
394 
PushFront()395     void PushFront() { Remove(); m_next = sm_first; sm_first = this; }
396     void Remove();
397 
398 protected:
wxFilterClassFactory()399     wxFilterClassFactory() : m_next(this) { }
400 
401     wxFilterClassFactory& operator=(const wxFilterClassFactory&)
402         { return *this; }
403 
404 private:
405     static wxFilterClassFactory *sm_first;
406     wxFilterClassFactory *m_next;
407 
408     DECLARE_ABSTRACT_CLASS(wxFilterClassFactory)
409 };
410 
411 // ============================================================================
412 // buffered streams
413 // ============================================================================
414 
415 // ---------------------------------------------------------------------------
416 // Stream buffer: this class can be derived from and passed to
417 // wxBufferedStreams to implement custom buffering
418 // ---------------------------------------------------------------------------
419 
420 class WXDLLIMPEXP_BASE wxStreamBuffer
421 {
422 public:
423     enum BufMode
424     {
425         read,
426         write,
427         read_write
428     };
429 
wxStreamBuffer(wxStreamBase & stream,BufMode mode)430     wxStreamBuffer(wxStreamBase& stream, BufMode mode)
431     {
432         InitWithStream(stream, mode);
433     }
434 
wxStreamBuffer(size_t bufsize,wxInputStream & stream)435     wxStreamBuffer(size_t bufsize, wxInputStream& stream)
436     {
437         InitWithStream(stream, read);
438         SetBufferIO(bufsize);
439     }
440 
wxStreamBuffer(size_t bufsize,wxOutputStream & stream)441     wxStreamBuffer(size_t bufsize, wxOutputStream& stream)
442     {
443         InitWithStream(stream, write);
444         SetBufferIO(bufsize);
445     }
446 
447     wxStreamBuffer(const wxStreamBuffer& buf);
448     virtual ~wxStreamBuffer();
449 
450     // Filtered IO
451     virtual size_t Read(void *buffer, size_t size);
452     size_t Read(wxStreamBuffer *buf);
453     virtual size_t Write(const void *buffer, size_t size);
454     size_t Write(wxStreamBuffer *buf);
455 
456     virtual char Peek();
457     virtual char GetChar();
458     virtual void PutChar(char c);
459     virtual wxFileOffset Tell() const;
460     virtual wxFileOffset Seek(wxFileOffset pos, wxSeekMode mode);
461 
462     // Buffer control
463     void ResetBuffer();
464     void Truncate();
465 
466     // NB: the buffer must always be allocated with malloc() if takeOwn is
467     //     true as it will be deallocated by free()
468     void SetBufferIO(void *start, void *end, bool takeOwnership = false);
469     void SetBufferIO(void *start, size_t len, bool takeOwnership = false);
470     void SetBufferIO(size_t bufsize);
GetBufferStart()471     void *GetBufferStart() const { return m_buffer_start; }
GetBufferEnd()472     void *GetBufferEnd() const { return m_buffer_end; }
GetBufferPos()473     void *GetBufferPos() const { return m_buffer_pos; }
GetBufferSize()474     size_t GetBufferSize() const { return m_buffer_end - m_buffer_start; }
GetIntPosition()475     size_t GetIntPosition() const { return m_buffer_pos - m_buffer_start; }
SetIntPosition(size_t pos)476     void SetIntPosition(size_t pos) { m_buffer_pos = m_buffer_start + pos; }
GetLastAccess()477     size_t GetLastAccess() const { return m_buffer_end - m_buffer_start; }
GetBytesLeft()478     size_t GetBytesLeft() const { return m_buffer_end - m_buffer_pos; }
479 
Fixed(bool fixed)480     void Fixed(bool fixed) { m_fixed = fixed; }
Flushable(bool f)481     void Flushable(bool f) { m_flushable = f; }
482 
483     bool FlushBuffer();
484     bool FillBuffer();
485     size_t GetDataLeft();
486 
487     // misc accessors
GetStream()488     wxStreamBase *GetStream() const { return m_stream; }
HasBuffer()489     bool HasBuffer() const { return m_buffer_start != m_buffer_end; }
490 
IsFixed()491     bool IsFixed() const { return m_fixed; }
IsFlushable()492     bool IsFlushable() const { return m_flushable; }
493 
494     // only for input/output buffers respectively, returns NULL otherwise
495     wxInputStream *GetInputStream() const;
496     wxOutputStream *GetOutputStream() const;
497 
498 #if WXWIN_COMPATIBILITY_2_6
499     // deprecated, for compatibility only
500     wxDEPRECATED( wxStreamBase *Stream() );
501 #endif // WXWIN_COMPATIBILITY_2_6
502 
503     // this constructs a dummy wxStreamBuffer, used by (and exists for)
504     // wxMemoryStreams only, don't use!
505     wxStreamBuffer(BufMode mode);
506 
507 protected:
508     void GetFromBuffer(void *buffer, size_t size);
509     void PutToBuffer(const void *buffer, size_t size);
510 
511     // set the last error to the specified value if we didn't have it before
512     void SetError(wxStreamError err);
513 
514     // common part of several ctors
515     void Init();
516 
517     // common part of ctors taking wxStreamBase parameter
518     void InitWithStream(wxStreamBase& stream, BufMode mode);
519 
520     // init buffer variables to be empty
521     void InitBuffer();
522 
523     // free the buffer (always safe to call)
524     void FreeBuffer();
525 
526     // the buffer itself: the pointers to its start and end and the current
527     // position in the buffer
528     char *m_buffer_start,
529          *m_buffer_end,
530          *m_buffer_pos;
531 
532     // the stream we're associated with
533     wxStreamBase *m_stream;
534 
535     // its mode
536     BufMode m_mode;
537 
538     // flags
539     bool m_destroybuf,      // deallocate buffer?
540          m_fixed,
541          m_flushable;
542 
543 
544     wxDECLARE_NO_ASSIGN_CLASS(wxStreamBuffer);
545 };
546 
547 // ---------------------------------------------------------------------------
548 // wxBufferedInputStream
549 // ---------------------------------------------------------------------------
550 
551 class WXDLLIMPEXP_BASE wxBufferedInputStream : public wxFilterInputStream
552 {
553 public:
554     // create a buffered stream on top of the specified low-level stream
555     //
556     // if a non NULL buffer is given to the stream, it will be deleted by it,
557     // otherwise a default 1KB buffer will be used
558     wxBufferedInputStream(wxInputStream& stream,
559                           wxStreamBuffer *buffer = NULL);
560 
561     // ctor allowing to specify the buffer size, it's just a more convenient
562     // alternative to creating wxStreamBuffer, calling its SetBufferIO(bufsize)
563     // and using the ctor above
564     wxBufferedInputStream(wxInputStream& stream, size_t bufsize);
565 
566 
567     virtual ~wxBufferedInputStream();
568 
569     char Peek();
570     wxInputStream& Read(void *buffer, size_t size);
571 
572     // Position functions
573     wxFileOffset SeekI(wxFileOffset pos, wxSeekMode mode = wxFromStart);
574     wxFileOffset TellI() const;
IsSeekable()575     bool IsSeekable() const { return m_parent_i_stream->IsSeekable(); }
576 
577     // the buffer given to the stream will be deleted by it
578     void SetInputStreamBuffer(wxStreamBuffer *buffer);
GetInputStreamBuffer()579     wxStreamBuffer *GetInputStreamBuffer() const { return m_i_streambuf; }
580 
581 #if WXWIN_COMPATIBILITY_2_6
582     // deprecated, for compatibility only
583     wxDEPRECATED( wxStreamBuffer *InputStreamBuffer() const );
584 #endif // WXWIN_COMPATIBILITY_2_6
585 
586 protected:
587     virtual size_t OnSysRead(void *buffer, size_t bufsize);
588     virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
589     virtual wxFileOffset OnSysTell() const;
590 
591     wxStreamBuffer *m_i_streambuf;
592 
593     wxDECLARE_NO_COPY_CLASS(wxBufferedInputStream);
594 };
595 
596 // ----------------------------------------------------------------------------
597 // wxBufferedOutputStream
598 // ----------------------------------------------------------------------------
599 
600 class WXDLLIMPEXP_BASE wxBufferedOutputStream : public wxFilterOutputStream
601 {
602 public:
603     // create a buffered stream on top of the specified low-level stream
604     //
605     // if a non NULL buffer is given to the stream, it will be deleted by it,
606     // otherwise a default 1KB buffer will be used
607     wxBufferedOutputStream(wxOutputStream& stream,
608                            wxStreamBuffer *buffer = NULL);
609 
610     // ctor allowing to specify the buffer size, it's just a more convenient
611     // alternative to creating wxStreamBuffer, calling its SetBufferIO(bufsize)
612     // and using the ctor above
613     wxBufferedOutputStream(wxOutputStream& stream, size_t bufsize);
614 
615     virtual ~wxBufferedOutputStream();
616 
617     wxOutputStream& Write(const void *buffer, size_t size);
618 
619     // Position functions
620     wxFileOffset SeekO(wxFileOffset pos, wxSeekMode mode = wxFromStart);
621     wxFileOffset TellO() const;
IsSeekable()622     bool IsSeekable() const { return m_parent_o_stream->IsSeekable(); }
623 
624     void Sync();
625     bool Close();
626 
627     wxFileOffset GetLength() const;
628 
629     // the buffer given to the stream will be deleted by it
630     void SetOutputStreamBuffer(wxStreamBuffer *buffer);
GetOutputStreamBuffer()631     wxStreamBuffer *GetOutputStreamBuffer() const { return m_o_streambuf; }
632 
633 #if WXWIN_COMPATIBILITY_2_6
634     // deprecated, for compatibility only
635     wxDEPRECATED( wxStreamBuffer *OutputStreamBuffer() const );
636 #endif // WXWIN_COMPATIBILITY_2_6
637 
638 protected:
639     virtual size_t OnSysWrite(const void *buffer, size_t bufsize);
640     virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
641     virtual wxFileOffset OnSysTell() const;
642 
643     wxStreamBuffer *m_o_streambuf;
644 
645     wxDECLARE_NO_COPY_CLASS(wxBufferedOutputStream);
646 };
647 
648 #if WXWIN_COMPATIBILITY_2_6
Stream()649     inline wxStreamBase *wxStreamBuffer::Stream() { return m_stream; }
InputStreamBuffer()650     inline wxStreamBuffer *wxBufferedInputStream::InputStreamBuffer() const { return m_i_streambuf; }
OutputStreamBuffer()651     inline wxStreamBuffer *wxBufferedOutputStream::OutputStreamBuffer() const { return m_o_streambuf; }
652 #endif // WXWIN_COMPATIBILITY_2_6
653 
654 // ---------------------------------------------------------------------------
655 // wxWrapperInputStream: forwards all IO to another stream.
656 // ---------------------------------------------------------------------------
657 
658 class WXDLLIMPEXP_BASE wxWrapperInputStream : public wxFilterInputStream
659 {
660 public:
661     // Constructor fully initializing the stream. The overload taking pointer
662     // takes ownership of the parent stream, the one taking reference does not.
663     //
664     // Notice that this class also has a default ctor but it's protected as the
665     // derived class is supposed to take care of calling InitParentStream() if
666     // it's used.
667     wxWrapperInputStream(wxInputStream& stream);
668     wxWrapperInputStream(wxInputStream* stream);
669 
670     // Override the base class methods to forward to the wrapped stream.
671     virtual wxFileOffset GetLength() const;
672     virtual bool IsSeekable() const;
673 
674 protected:
675     virtual size_t OnSysRead(void *buffer, size_t size);
676     virtual wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
677     virtual wxFileOffset OnSysTell() const;
678 
679     // Ensure that our own last error is the same as that of the real stream.
680     //
681     // This method is const because the error must be updated even from const
682     // methods (in other words, it really should have been mutable in the first
683     // place).
SynchronizeLastError()684     void SynchronizeLastError() const
685     {
686         const_cast<wxWrapperInputStream*>(this)->
687             Reset(m_parent_i_stream->GetLastError());
688     }
689 
690     // Default constructor, use InitParentStream() later.
691     wxWrapperInputStream();
692 
693     // Set up the wrapped stream for an object initialized using the default
694     // constructor. The ownership logic is the same as above.
695     void InitParentStream(wxInputStream& stream);
696     void InitParentStream(wxInputStream* stream);
697 
698     wxDECLARE_NO_COPY_CLASS(wxWrapperInputStream);
699 };
700 
701 
702 #endif // wxUSE_STREAMS
703 
704 #endif // _WX_WXSTREAM_H__
705