1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/stream.cpp
3 // Purpose: wxStream base classes
4 // Author: Guilhem Lavaux
5 // Modified by: VZ (23.11.00) to fix realloc()ing new[]ed memory,
9 // Copyright: (c) Guilhem Lavaux
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
13 // ============================================================================
15 // ============================================================================
17 // ----------------------------------------------------------------------------
19 // ----------------------------------------------------------------------------
22 #pragma implementation "stream.h"
25 // For compilers that support precompilation, includes "wx.h".
26 #include "wx/wxprec.h"
39 #include "wx/stream.h"
40 #include "wx/datstrm.h"
41 #include "wx/objstrm.h"
42 #include "wx/textfile.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 // the temporary buffer size used when copying from stream to stream
49 #define BUF_TEMP_SIZE 10000
51 // ============================================================================
53 // ============================================================================
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 void wxStreamBuffer::SetError(wxStreamError err
)
61 if ( m_stream
->m_lasterror
== wxStream_NOERROR
)
62 m_stream
->m_lasterror
= err
;
65 void wxStreamBuffer::InitBuffer()
72 // there is nothing to destroy anyhow
76 void wxStreamBuffer::Init()
83 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
91 m_destroystream
= FALSE
;
94 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
98 m_stream
= new wxStreamBase
;
102 m_destroystream
= TRUE
;
105 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
107 // doing this has big chances to lead to a crashwhen the source buffer is
108 // destroyed (otherwise assume the caller knows what he does)
109 wxASSERT_MSG( !buffer
.m_destroybuf
&& !buffer
.m_destroystream
,
110 _T("it's a bad idea to copy this buffer") );
112 m_buffer_start
= buffer
.m_buffer_start
;
113 m_buffer_end
= buffer
.m_buffer_end
;
114 m_buffer_pos
= buffer
.m_buffer_pos
;
115 m_buffer_size
= buffer
.m_buffer_size
;
116 m_fixed
= buffer
.m_fixed
;
117 m_flushable
= buffer
.m_flushable
;
118 m_stream
= buffer
.m_stream
;
119 m_mode
= buffer
.m_mode
;
120 m_destroybuf
= FALSE
;
121 m_destroystream
= FALSE
;
124 void wxStreamBuffer::FreeBuffer()
127 free(m_buffer_start
);
130 wxStreamBuffer::~wxStreamBuffer()
134 if ( m_destroystream
)
138 wxInputStream
*wxStreamBuffer::GetInputStream() const
140 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
143 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
145 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
148 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
152 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
156 void wxStreamBuffer::SetBufferIO(void *start
,
160 // start by freeing the old buffer
163 m_buffer_start
= (char *)start
;
164 m_buffer_end
= m_buffer_start
+ len
;
168 // if we own it, we free it
169 m_destroybuf
= takeOwnership
;
174 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
176 // start by freeing the old buffer
181 SetBufferIO(malloc(bufsize
), bufsize
, TRUE
/* take ownership */);
183 else // no buffer size => no buffer
189 void wxStreamBuffer::ResetBuffer()
191 wxCHECK_RET( m_stream
, _T("should have a stream in wxStreamBuffer") );
193 m_stream
->m_lasterror
= wxStream_NOERROR
;
194 m_stream
->m_lastcount
= 0;
195 if (m_mode
== read
&& m_flushable
)
196 m_buffer_pos
= m_buffer_end
;
198 m_buffer_pos
= m_buffer_start
;
201 // fill the buffer with as much data as possible (only for read buffers)
202 bool wxStreamBuffer::FillBuffer()
204 wxInputStream
*inStream
= GetInputStream();
206 wxCHECK_MSG( inStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
208 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
212 m_buffer_end
= m_buffer_start
+ count
;
213 m_buffer_pos
= m_buffer_start
;
218 // write the buffer contents to the stream (only for write buffers)
219 bool wxStreamBuffer::FlushBuffer()
221 wxCHECK_MSG( m_flushable
, FALSE
, _T("can't flush this buffer") );
223 // FIXME: what is this check for? (VZ)
224 if ( m_buffer_pos
== m_buffer_start
)
227 wxOutputStream
*outStream
= GetOutputStream();
229 wxCHECK_MSG( outStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
231 size_t current
= m_buffer_pos
- m_buffer_start
;
232 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
233 if ( count
!= current
)
236 m_buffer_pos
= m_buffer_start
;
241 size_t wxStreamBuffer::GetDataLeft()
243 /* Why is this done? RR. */
244 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
247 return GetBytesLeft();
250 // copy up to size bytes from our buffer into the provided one
251 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
253 // don't get more bytes than left in the buffer
254 size_t left
= GetBytesLeft();
259 memcpy(buffer
, m_buffer_pos
, size
);
260 m_buffer_pos
+= size
;
263 // copy the contents of the provided buffer into this one
264 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
266 size_t left
= GetBytesLeft();
271 // we can't realloc the buffer, so just copy what we can
276 // realloc the buffer to have enough space for the data
277 size_t delta
= m_buffer_pos
- m_buffer_start
;
279 char *startOld
= m_buffer_start
;
280 m_buffer_size
+= size
;
281 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
282 if ( !m_buffer_start
)
284 // don't leak memory if realloc() failed
285 m_buffer_start
= startOld
;
286 m_buffer_size
-= size
;
288 // what else can we do?
292 // adjust the pointers invalidated by realloc()
293 m_buffer_pos
= m_buffer_start
+ delta
;
294 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
298 memcpy(m_buffer_pos
, buffer
, size
);
299 m_buffer_pos
+= size
;
302 void wxStreamBuffer::PutChar(char c
)
304 wxOutputStream
*outStream
= GetOutputStream();
306 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
308 // if we don't have buffer at all, just forward this call to the stream,
311 outStream
->OnSysWrite(&c
, 1);
315 // otherwise check we have enough space left
316 if ( !GetDataLeft() && !FlushBuffer() )
319 SetError(wxStream_WRITE_ERR
);
324 m_stream
->m_lastcount
= 1;
329 char wxStreamBuffer::Peek()
331 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
332 _T("should have the stream and the buffer in wxStreamBuffer") );
334 if ( !GetDataLeft() )
336 SetError(wxStream_READ_ERR
);
341 GetFromBuffer(&c
, 1);
347 char wxStreamBuffer::GetChar()
349 wxInputStream
*inStream
= GetInputStream();
351 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
356 inStream
->OnSysRead(&c
, 1);
360 if ( !GetDataLeft() )
362 SetError(wxStream_READ_ERR
);
367 GetFromBuffer(&c
, 1);
368 m_stream
->m_lastcount
= 1;
375 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
377 wxInputStream
*inStream
= GetInputStream();
379 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
381 // lasterror is reset before all new IO calls
382 m_stream
->m_lasterror
= wxStream_NOERROR
;
386 m_stream
->m_lastcount
= inStream
->OnSysRead(buffer
, size
);
388 else // we have a buffer, use it
390 size_t orig_size
= size
;
394 size_t left
= GetDataLeft();
396 // if the requested number of bytes if greater than the buffer
397 // size, read data in chunks
400 GetFromBuffer(buffer
, left
);
402 buffer
= (char *)buffer
+ left
;
406 SetError(wxStream_EOF
);
410 else // otherwise just do it in one gulp
412 GetFromBuffer(buffer
, size
);
417 m_stream
->m_lastcount
= orig_size
- size
;
420 return m_stream
->m_lastcount
;
423 // this should really be called "Copy()"
424 size_t wxStreamBuffer::Read(wxStreamBuffer
*dbuf
)
426 wxCHECK_MSG( m_mode
!= write
, 0, _T("can't read from this buffer") );
428 char buf
[BUF_TEMP_SIZE
];
434 nRead
= Read(dbuf
, WXSIZEOF(buf
));
437 nRead
= dbuf
->Write(buf
, nRead
);
446 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
448 wxOutputStream
*outStream
= GetOutputStream();
450 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
452 // lasterror is reset before all new IO calls
453 m_stream
->m_lasterror
= wxStream_NOERROR
;
455 if ( !HasBuffer() && m_fixed
)
457 // no buffer, just forward the call to the stream
458 m_stream
->m_lastcount
= outStream
->OnSysWrite(buffer
, size
);
460 else // we [may] have a buffer, use it
462 size_t orig_size
= size
;
466 size_t left
= GetBytesLeft();
468 // if the buffer is too large to fit in the stream buffer, split
469 // it in smaller parts
471 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
472 // we always go to the second case.
474 // FIXME: fine, but if it fails we should (re)try writing it by
475 // chunks as this will (hopefully) always work (VZ)
476 if ( size
> left
&& m_fixed
)
478 PutToBuffer(buffer
, left
);
480 buffer
= (char *)buffer
+ left
;
482 if ( !FlushBuffer() )
484 SetError(wxStream_WRITE_ERR
);
489 m_buffer_pos
= m_buffer_start
;
491 else // we can do it in one gulp
493 PutToBuffer(buffer
, size
);
498 m_stream
->m_lastcount
= orig_size
- size
;
501 return m_stream
->m_lastcount
;
504 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
506 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
507 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
509 char buf
[BUF_TEMP_SIZE
];
515 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
518 nWrite
= Write(buf
, nRead
);
519 if ( nWrite
< nRead
)
521 // put back data we couldn't copy
522 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
524 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
534 while ( nWrite
== WXSIZEOF(buf
) );
539 off_t
wxStreamBuffer::Seek(off_t pos
, wxSeekMode mode
)
543 off_t last_access
= GetLastAccess();
554 diff
= pos
+ GetIntPosition();
558 diff
= pos
+ last_access
;
562 wxFAIL_MSG( _T("invalid seek mode") );
564 return wxInvalidOffset
;
566 if (diff
< 0 || diff
> last_access
)
567 return wxInvalidOffset
;
568 SetIntPosition(diff
);
575 // We'll try to compute an internal position later ...
576 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
581 diff
= pos
+ GetIntPosition();
583 if ( (diff
> last_access
) || (diff
< 0) )
585 // We must take into account the fact that we have read
586 // something previously.
587 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
593 SetIntPosition(diff
);
598 // Hard to compute: always seek to the requested position.
599 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
604 return wxInvalidOffset
;
607 off_t
wxStreamBuffer::Tell() const
609 off_t pos
= m_stream
->OnSysTell();
610 if ( pos
== wxInvalidOffset
)
611 return wxInvalidOffset
;
613 pos
+= GetIntPosition();
615 if ( m_mode
== read
&& m_flushable
)
616 pos
-= GetLastAccess();
621 // ----------------------------------------------------------------------------
623 // ----------------------------------------------------------------------------
625 wxStreamBase::wxStreamBase()
627 m_lasterror
= wxStream_NOERROR
;
631 wxStreamBase::~wxStreamBase()
635 off_t
wxStreamBase::OnSysSeek(off_t
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
637 return wxInvalidOffset
;
640 off_t
wxStreamBase::OnSysTell() const
642 return wxInvalidOffset
;
645 // ----------------------------------------------------------------------------
647 // ----------------------------------------------------------------------------
649 wxInputStream::wxInputStream()
656 wxInputStream::~wxInputStream()
661 size_t wxInputStream::OnSysRead(void * WXUNUSED(buffer
),
662 size_t WXUNUSED(bufsize
))
667 bool wxInputStream::Eof() const
669 wxInputStream
*self
= wxConstCast(this, wxInputStream
);
674 // some streams can know that they're at EOF before actually trying to
675 // read beyond the end of stream (e.g. files) while others have no way of
676 // knowing it, so to provide the same behaviour in all cases we only
677 // return TRUE from here if the character really couldn't be read
678 if ( !self
->LastRead() && GetLastError() == wxSTREAM_EOF
)
688 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
690 // get number of bytes left from previous wback buffer
691 size_t toget
= m_wbacksize
- m_wbackcur
;
693 // allocate a buffer large enough to hold prev + new data
694 char *temp_b
= (char *)malloc(needed_size
+ toget
);
699 /* copy previous data (and free old buffer) if needed */
702 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
709 m_wbacksize
= needed_size
+ toget
;
714 size_t wxInputStream::GetWBack(void *buf
, size_t bsize
)
716 size_t toget
= m_wbacksize
-m_wbackcur
;
724 memcpy(buf
, (m_wback
+m_wbackcur
), toget
);
727 if (m_wbackcur
== m_wbacksize
)
738 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
740 char *ptrback
= AllocSpaceWBack(bufsize
);
744 memcpy(ptrback
, buf
, bufsize
);
748 bool wxInputStream::Ungetch(char c
)
750 void *ptrback
= AllocSpaceWBack(1);
754 *(char *)ptrback
= c
;
758 char wxInputStream::GetC()
765 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
767 size_t retsize
= GetWBack(buf
, size
);
771 m_lasterror
= wxStream_NOERROR
;
775 buf
= (char *)buf
+ retsize
;
777 m_lastcount
= OnSysRead(buf
, size
) + retsize
;
781 char wxInputStream::Peek()
785 if (m_lasterror
== wxStream_NOERROR
)
794 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
796 char buf
[BUF_TEMP_SIZE
];
797 size_t bytes_read
= BUF_TEMP_SIZE
;
799 while (bytes_read
== BUF_TEMP_SIZE
)
801 bytes_read
= Read(buf
, bytes_read
).LastRead();
802 bytes_read
= stream_out
.Write(buf
, bytes_read
).LastWrite();
807 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
809 /* Should be check and improve, just to remove a slight bug !
810 I don't know whether it should be put as well in wxFileInputStream::OnSysSeek ? */
811 if (m_lasterror
==wxSTREAM_EOF
)
812 m_lasterror
=wxSTREAM_NOERROR
;
814 /* A call to SeekI() will automatically invalidate any previous call
815 to Ungetch(), otherwise it would be possible to SeekI() to one
816 one position, unread some bytes there, SeekI() to another position
817 and the data would be corrupted.
819 GRG: Could add code here to try to navigate within the wback
820 buffer if possible, but is it really needed? It would only work
821 when seeking in wxFromCurrent mode, else it would invalidate
832 return OnSysSeek(pos
, mode
);
835 off_t
wxInputStream::TellI() const
837 /* GRG: Changed to make it compatible with the wback buffer */
838 off_t pos
= OnSysTell();
840 if (pos
!= wxInvalidOffset
)
841 pos
-= (m_wbacksize
- m_wbackcur
);
846 // --------------------
847 // Overloaded operators
848 // --------------------
851 wxInputStream
& wxInputStream::operator>>(wxObject
*& obj
)
853 wxObjectInputStream
obj_s(*this);
854 obj
= obj_s
.LoadObject();
857 #endif // wxUSE_SERIAL
860 // ----------------------------------------------------------------------------
862 // ----------------------------------------------------------------------------
864 wxOutputStream::wxOutputStream()
868 wxOutputStream::~wxOutputStream()
872 size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer
),
873 size_t WXUNUSED(bufsize
))
878 void wxOutputStream::PutC(char c
)
883 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
885 m_lastcount
= OnSysWrite(buffer
, size
);
889 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
891 stream_in
.Read(*this);
895 off_t
wxOutputStream::TellO() const
900 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
902 return OnSysSeek(pos
, mode
);
905 void wxOutputStream::Sync()
910 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
)
912 wxObjectOutputStream
obj_s(*this);
913 obj_s
.SaveObject(obj
);
916 #endif // wxUSE_SERIAL
918 // ----------------------------------------------------------------------------
919 // wxCountingOutputStream
920 // ----------------------------------------------------------------------------
922 wxCountingOutputStream::wxCountingOutputStream ()
927 size_t wxCountingOutputStream::GetSize() const
932 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
935 m_currentPos
+= size
;
936 if (m_currentPos
> m_lastcount
)
937 m_lastcount
= m_currentPos
;
942 off_t
wxCountingOutputStream::OnSysSeek(off_t pos
, wxSeekMode mode
)
951 m_currentPos
= m_lastcount
+ pos
;
959 wxFAIL_MSG( _T("invalid seek mode") );
960 return wxInvalidOffset
;
963 if (m_currentPos
> m_lastcount
)
964 m_lastcount
= m_currentPos
;
969 off_t
wxCountingOutputStream::OnSysTell() const
974 // ----------------------------------------------------------------------------
975 // wxFilterInputStream
976 // ----------------------------------------------------------------------------
978 wxFilterInputStream::wxFilterInputStream()
980 m_parent_i_stream
= NULL
;
983 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
985 m_parent_i_stream
= &stream
;
988 wxFilterInputStream::~wxFilterInputStream()
992 // ----------------------------------------------------------------------------
993 // wxFilterOutputStream
994 // ----------------------------------------------------------------------------
996 wxFilterOutputStream::wxFilterOutputStream()
998 m_parent_o_stream
= NULL
;
1001 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
1003 m_parent_o_stream
= &stream
;
1006 wxFilterOutputStream::~wxFilterOutputStream()
1010 // ----------------------------------------------------------------------------
1011 // wxBufferedInputStream
1012 // ----------------------------------------------------------------------------
1014 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1015 wxStreamBuffer
*buffer
)
1016 : wxFilterInputStream(s
)
1020 // use the buffer provided by the user
1021 m_i_streambuf
= buffer
;
1023 else // create a default buffer
1025 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1027 m_i_streambuf
->SetBufferIO(1024);
1031 wxBufferedInputStream::~wxBufferedInputStream()
1033 m_parent_i_stream
->SeekI(-(off_t
)m_i_streambuf
->GetBytesLeft(),
1036 delete m_i_streambuf
;
1039 char wxBufferedInputStream::Peek()
1041 return m_i_streambuf
->Peek();
1044 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1048 retsize
= GetWBack(buf
, size
);
1049 m_lastcount
= retsize
;
1050 if ( retsize
== size
)
1052 m_lasterror
= wxStream_NOERROR
;
1056 buf
= (char *)buf
+ retsize
;
1058 m_i_streambuf
->Read(buf
, size
);
1063 off_t
wxBufferedInputStream::SeekI(off_t pos
, wxSeekMode mode
)
1065 return m_i_streambuf
->Seek(pos
, mode
);
1068 off_t
wxBufferedInputStream::TellI() const
1070 return m_i_streambuf
->Tell();
1073 size_t wxBufferedInputStream::OnSysRead(void *buffer
, size_t bufsize
)
1075 return m_parent_i_stream
->Read(buffer
, bufsize
).LastRead();
1078 off_t
wxBufferedInputStream::OnSysSeek(off_t seek
, wxSeekMode mode
)
1080 return m_parent_i_stream
->SeekI(seek
, mode
);
1083 off_t
wxBufferedInputStream::OnSysTell() const
1085 return m_parent_i_stream
->TellI();
1088 void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer
*buffer
)
1090 wxCHECK_RET( buffer
, _T("wxBufferedInputStream needs buffer") );
1092 delete m_i_streambuf
;
1093 m_i_streambuf
= buffer
;
1096 // ----------------------------------------------------------------------------
1097 // wxBufferedOutputStream
1098 // ----------------------------------------------------------------------------
1100 wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream
& s
,
1101 wxStreamBuffer
*buffer
)
1102 : wxFilterOutputStream(s
)
1106 m_o_streambuf
= buffer
;
1108 else // create a default one
1110 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
1112 m_o_streambuf
->SetBufferIO(1024);
1116 wxBufferedOutputStream::~wxBufferedOutputStream()
1119 delete m_o_streambuf
;
1122 wxOutputStream
& wxBufferedOutputStream::Write(const void *buffer
, size_t size
)
1125 m_o_streambuf
->Write(buffer
, size
);
1129 off_t
wxBufferedOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
1132 return m_o_streambuf
->Seek(pos
, mode
);
1135 off_t
wxBufferedOutputStream::TellO() const
1137 return m_o_streambuf
->Tell();
1140 void wxBufferedOutputStream::Sync()
1142 m_o_streambuf
->FlushBuffer();
1143 m_parent_o_stream
->Sync();
1146 size_t wxBufferedOutputStream::OnSysWrite(const void *buffer
, size_t bufsize
)
1148 return m_parent_o_stream
->Write(buffer
, bufsize
).LastWrite();
1151 off_t
wxBufferedOutputStream::OnSysSeek(off_t seek
, wxSeekMode mode
)
1153 return m_parent_o_stream
->SeekO(seek
, mode
);
1156 off_t
wxBufferedOutputStream::OnSysTell() const
1158 return m_parent_o_stream
->TellO();
1161 size_t wxBufferedOutputStream::GetSize() const
1163 return m_parent_o_stream
->GetSize() + m_o_streambuf
->GetIntPosition();
1166 void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer
*buffer
)
1168 wxCHECK_RET( buffer
, _T("wxBufferedOutputStream needs buffer") );
1170 delete m_o_streambuf
;
1171 m_o_streambuf
= buffer
;
1174 // ----------------------------------------------------------------------------
1175 // Some IOManip function
1176 // ----------------------------------------------------------------------------
1178 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
1180 static const wxChar
*eol
= wxTextFile::GetEOL();
1182 return stream
.Write(eol
, wxStrlen(eol
));