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