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/textfile.h"
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 // the temporary buffer size used when copying from stream to stream
48 #define BUF_TEMP_SIZE 10000
50 // ============================================================================
52 // ============================================================================
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 void wxStreamBuffer::SetError(wxStreamError err
)
60 if ( m_stream
->m_lasterror
== wxStream_NOERROR
)
61 m_stream
->m_lasterror
= err
;
64 void wxStreamBuffer::InitBuffer()
71 // if we are going to allocate the buffer, we should free it later as well
75 void wxStreamBuffer::Init()
82 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
90 m_destroystream
= FALSE
;
93 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
97 wxASSERT_MSG(mode
!= read_write
, wxT("you have to use the other ctor for read_write mode") );
99 m_stream
= new wxInputStream
;
100 else if ( mode
== write
)
101 m_stream
= new wxOutputStream
;
108 m_destroystream
= TRUE
;
111 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
113 // doing this has big chances to lead to a crashwhen the source buffer is
114 // destroyed (otherwise assume the caller knows what he does)
115 wxASSERT_MSG( !buffer
.m_destroybuf
&& !buffer
.m_destroystream
,
116 _T("it's a bad idea to copy this buffer") );
118 m_buffer_start
= buffer
.m_buffer_start
;
119 m_buffer_end
= buffer
.m_buffer_end
;
120 m_buffer_pos
= buffer
.m_buffer_pos
;
121 m_buffer_size
= buffer
.m_buffer_size
;
122 m_fixed
= buffer
.m_fixed
;
123 m_flushable
= buffer
.m_flushable
;
124 m_stream
= buffer
.m_stream
;
125 m_mode
= buffer
.m_mode
;
126 m_destroybuf
= FALSE
;
127 m_destroystream
= FALSE
;
130 void wxStreamBuffer::FreeBuffer()
133 free(m_buffer_start
);
136 wxStreamBuffer::~wxStreamBuffer()
140 if ( m_destroystream
)
144 wxInputStream
*wxStreamBuffer::GetInputStream() const
146 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
149 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
151 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
154 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
158 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
162 void wxStreamBuffer::SetBufferIO(void *start
,
166 // start by freeing the old buffer
169 m_buffer_start
= (char *)start
;
170 m_buffer_end
= m_buffer_start
+ len
;
174 // if we own it, we free it
175 m_destroybuf
= takeOwnership
;
180 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
182 // start by freeing the old buffer
187 SetBufferIO(malloc(bufsize
), bufsize
, TRUE
/* take ownership */);
189 else // no buffer size => no buffer
195 void wxStreamBuffer::ResetBuffer()
197 wxCHECK_RET( m_stream
, _T("should have a stream in wxStreamBuffer") );
199 m_stream
->m_lasterror
= wxStream_NOERROR
;
200 m_stream
->m_lastcount
= 0;
201 if (m_mode
== read
&& m_flushable
)
202 m_buffer_pos
= m_buffer_end
;
204 m_buffer_pos
= m_buffer_start
;
207 // fill the buffer with as much data as possible (only for read buffers)
208 bool wxStreamBuffer::FillBuffer()
210 wxInputStream
*inStream
= GetInputStream();
212 wxCHECK_MSG( inStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
214 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
218 m_buffer_end
= m_buffer_start
+ count
;
219 m_buffer_pos
= m_buffer_start
;
224 // write the buffer contents to the stream (only for write buffers)
225 bool wxStreamBuffer::FlushBuffer()
227 wxCHECK_MSG( m_flushable
, FALSE
, _T("can't flush this buffer") );
229 // FIXME: what is this check for? (VZ)
230 if ( m_buffer_pos
== m_buffer_start
)
233 wxOutputStream
*outStream
= GetOutputStream();
235 wxCHECK_MSG( outStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
237 size_t current
= m_buffer_pos
- m_buffer_start
;
238 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
239 if ( count
!= current
)
242 m_buffer_pos
= m_buffer_start
;
247 size_t wxStreamBuffer::GetDataLeft()
249 /* Why is this done? RR. */
250 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
253 return GetBytesLeft();
256 // copy up to size bytes from our buffer into the provided one
257 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
259 // don't get more bytes than left in the buffer
260 size_t left
= GetBytesLeft();
265 memcpy(buffer
, m_buffer_pos
, size
);
266 m_buffer_pos
+= size
;
269 // copy the contents of the provided buffer into this one
270 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
272 size_t left
= GetBytesLeft();
277 // we can't realloc the buffer, so just copy what we can
282 // realloc the buffer to have enough space for the data
283 size_t delta
= m_buffer_pos
- m_buffer_start
;
285 char *startOld
= m_buffer_start
;
286 m_buffer_size
+= size
;
287 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
288 if ( !m_buffer_start
)
290 // don't leak memory if realloc() failed
291 m_buffer_start
= startOld
;
292 m_buffer_size
-= size
;
294 // what else can we do?
298 // adjust the pointers invalidated by realloc()
299 m_buffer_pos
= m_buffer_start
+ delta
;
300 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
304 memcpy(m_buffer_pos
, buffer
, size
);
305 m_buffer_pos
+= size
;
308 void wxStreamBuffer::PutChar(char c
)
310 wxOutputStream
*outStream
= GetOutputStream();
312 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
314 // if we don't have buffer at all, just forward this call to the stream,
317 outStream
->OnSysWrite(&c
, 1);
321 // otherwise check we have enough space left
322 if ( !GetDataLeft() && !FlushBuffer() )
325 SetError(wxStream_WRITE_ERR
);
330 m_stream
->m_lastcount
= 1;
335 char wxStreamBuffer::Peek()
337 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
338 _T("should have the stream and the buffer in wxStreamBuffer") );
340 if ( !GetDataLeft() )
342 SetError(wxStream_READ_ERR
);
347 GetFromBuffer(&c
, 1);
353 char wxStreamBuffer::GetChar()
355 wxInputStream
*inStream
= GetInputStream();
357 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
362 inStream
->OnSysRead(&c
, 1);
366 if ( !GetDataLeft() )
368 SetError(wxStream_READ_ERR
);
373 GetFromBuffer(&c
, 1);
374 m_stream
->m_lastcount
= 1;
381 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
383 wxInputStream
*inStream
= GetInputStream();
385 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
387 // lasterror is reset before all new IO calls
388 m_stream
->m_lasterror
= wxStream_NOERROR
;
392 m_stream
->m_lastcount
= inStream
->OnSysRead(buffer
, size
);
394 else // we have a buffer, use it
396 size_t orig_size
= size
;
400 size_t left
= GetDataLeft();
402 // if the requested number of bytes if greater than the buffer
403 // size, read data in chunks
406 GetFromBuffer(buffer
, left
);
408 buffer
= (char *)buffer
+ left
;
412 SetError(wxStream_EOF
);
416 else // otherwise just do it in one gulp
418 GetFromBuffer(buffer
, size
);
423 m_stream
->m_lastcount
= orig_size
- size
;
426 return m_stream
->m_lastcount
;
429 // this should really be called "Copy()"
430 size_t wxStreamBuffer::Read(wxStreamBuffer
*dbuf
)
432 wxCHECK_MSG( m_mode
!= write
, 0, _T("can't read from this buffer") );
434 char buf
[BUF_TEMP_SIZE
];
440 nRead
= Read(dbuf
, WXSIZEOF(buf
));
443 nRead
= dbuf
->Write(buf
, nRead
);
452 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
454 wxOutputStream
*outStream
= GetOutputStream();
456 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
458 // lasterror is reset before all new IO calls
459 m_stream
->m_lasterror
= wxStream_NOERROR
;
461 if ( !HasBuffer() && m_fixed
)
463 // no buffer, just forward the call to the stream
464 m_stream
->m_lastcount
= outStream
->OnSysWrite(buffer
, size
);
466 else // we [may] have a buffer, use it
468 size_t orig_size
= size
;
472 size_t left
= GetBytesLeft();
474 // if the buffer is too large to fit in the stream buffer, split
475 // it in smaller parts
477 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
478 // we always go to the second case.
480 // FIXME: fine, but if it fails we should (re)try writing it by
481 // chunks as this will (hopefully) always work (VZ)
482 if ( size
> left
&& m_fixed
)
484 PutToBuffer(buffer
, left
);
486 buffer
= (char *)buffer
+ left
;
488 if ( !FlushBuffer() )
490 SetError(wxStream_WRITE_ERR
);
495 m_buffer_pos
= m_buffer_start
;
497 else // we can do it in one gulp
499 PutToBuffer(buffer
, size
);
504 m_stream
->m_lastcount
= orig_size
- size
;
507 return m_stream
->m_lastcount
;
510 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
512 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
513 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
515 char buf
[BUF_TEMP_SIZE
];
521 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
524 nWrite
= Write(buf
, nRead
);
525 if ( nWrite
< nRead
)
527 // put back data we couldn't copy
528 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
530 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
540 while ( nWrite
== WXSIZEOF(buf
) );
545 off_t
wxStreamBuffer::Seek(off_t pos
, wxSeekMode mode
)
549 off_t last_access
= GetLastAccess();
560 diff
= pos
+ GetIntPosition();
564 diff
= pos
+ last_access
;
568 wxFAIL_MSG( _T("invalid seek mode") );
570 return wxInvalidOffset
;
572 if (diff
< 0 || diff
> last_access
)
573 return wxInvalidOffset
;
574 SetIntPosition(diff
);
581 // We'll try to compute an internal position later ...
582 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
587 diff
= pos
+ GetIntPosition();
589 if ( (diff
> last_access
) || (diff
< 0) )
591 // We must take into account the fact that we have read
592 // something previously.
593 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
599 SetIntPosition(diff
);
604 // Hard to compute: always seek to the requested position.
605 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
610 return wxInvalidOffset
;
613 off_t
wxStreamBuffer::Tell() const
615 off_t pos
= m_stream
->OnSysTell();
616 if ( pos
== wxInvalidOffset
)
617 return wxInvalidOffset
;
619 pos
+= GetIntPosition();
621 if ( m_mode
== read
&& m_flushable
)
622 pos
-= GetLastAccess();
627 // ----------------------------------------------------------------------------
629 // ----------------------------------------------------------------------------
631 wxStreamBase::wxStreamBase()
633 m_lasterror
= wxStream_NOERROR
;
637 wxStreamBase::~wxStreamBase()
641 off_t
wxStreamBase::OnSysSeek(off_t
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
643 return wxInvalidOffset
;
646 off_t
wxStreamBase::OnSysTell() const
648 return wxInvalidOffset
;
651 // ----------------------------------------------------------------------------
653 // ----------------------------------------------------------------------------
655 wxInputStream::wxInputStream()
662 wxInputStream::~wxInputStream()
667 size_t wxInputStream::OnSysRead(void * WXUNUSED(buffer
),
668 size_t WXUNUSED(bufsize
))
673 bool wxInputStream::Eof() const
675 wxInputStream
*self
= wxConstCast(this, wxInputStream
);
680 // some streams can know that they're at EOF before actually trying to
681 // read beyond the end of stream (e.g. files) while others have no way of
682 // knowing it, so to provide the same behaviour in all cases we only
683 // return TRUE from here if the character really couldn't be read
684 if ( !self
->LastRead() && GetLastError() == wxSTREAM_EOF
)
694 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
696 // get number of bytes left from previous wback buffer
697 size_t toget
= m_wbacksize
- m_wbackcur
;
699 // allocate a buffer large enough to hold prev + new data
700 char *temp_b
= (char *)malloc(needed_size
+ toget
);
705 /* copy previous data (and free old buffer) if needed */
708 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
715 m_wbacksize
= needed_size
+ toget
;
720 size_t wxInputStream::GetWBack(void *buf
, size_t bsize
)
725 // how many bytes do we have in the buffer?
726 size_t toget
= m_wbacksize
- m_wbackcur
;
730 // we won't read everything
734 // copy the data from the cache
735 memcpy(buf
, m_wback
+ m_wbackcur
, toget
);
738 if ( m_wbackcur
== m_wbacksize
)
740 // TODO: should we really free it here all the time? maybe keep it?
747 // return the number of bytes copied
751 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
753 char *ptrback
= AllocSpaceWBack(bufsize
);
757 memcpy(ptrback
, buf
, bufsize
);
761 bool wxInputStream::Ungetch(char c
)
763 void *ptrback
= AllocSpaceWBack(1);
767 *(char *)ptrback
= c
;
771 char wxInputStream::GetC()
778 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
780 size_t retsize
= GetWBack(buf
, size
);
784 m_lasterror
= wxStream_NOERROR
;
788 buf
= (char *)buf
+ retsize
;
790 m_lastcount
= OnSysRead(buf
, size
) + retsize
;
794 char wxInputStream::Peek()
798 if (m_lasterror
== wxStream_NOERROR
)
807 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
809 char buf
[BUF_TEMP_SIZE
];
810 size_t bytes_read
= BUF_TEMP_SIZE
;
812 while (bytes_read
== BUF_TEMP_SIZE
)
814 bytes_read
= Read(buf
, bytes_read
).LastRead();
815 bytes_read
= stream_out
.Write(buf
, bytes_read
).LastWrite();
820 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
822 /* Should be check and improve, just to remove a slight bug !
823 I don't know whether it should be put as well in wxFileInputStream::OnSysSeek ? */
824 if (m_lasterror
==wxSTREAM_EOF
)
825 m_lasterror
=wxSTREAM_NOERROR
;
827 /* A call to SeekI() will automatically invalidate any previous call
828 to Ungetch(), otherwise it would be possible to SeekI() to one
829 one position, unread some bytes there, SeekI() to another position
830 and the data would be corrupted.
832 GRG: Could add code here to try to navigate within the wback
833 buffer if possible, but is it really needed? It would only work
834 when seeking in wxFromCurrent mode, else it would invalidate
845 return OnSysSeek(pos
, mode
);
848 off_t
wxInputStream::TellI() const
850 /* GRG: Changed to make it compatible with the wback buffer */
851 off_t pos
= OnSysTell();
853 if (pos
!= wxInvalidOffset
)
854 pos
-= (m_wbacksize
- m_wbackcur
);
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 // ----------------------------------------------------------------------------
911 // wxCountingOutputStream
912 // ----------------------------------------------------------------------------
914 wxCountingOutputStream::wxCountingOutputStream ()
919 size_t wxCountingOutputStream::GetSize() const
924 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
927 m_currentPos
+= size
;
928 if (m_currentPos
> m_lastcount
)
929 m_lastcount
= m_currentPos
;
934 off_t
wxCountingOutputStream::OnSysSeek(off_t pos
, wxSeekMode mode
)
943 m_currentPos
= m_lastcount
+ pos
;
951 wxFAIL_MSG( _T("invalid seek mode") );
952 return wxInvalidOffset
;
955 if (m_currentPos
> m_lastcount
)
956 m_lastcount
= m_currentPos
;
961 off_t
wxCountingOutputStream::OnSysTell() const
966 // ----------------------------------------------------------------------------
967 // wxFilterInputStream
968 // ----------------------------------------------------------------------------
970 wxFilterInputStream::wxFilterInputStream()
972 m_parent_i_stream
= NULL
;
975 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
977 m_parent_i_stream
= &stream
;
980 wxFilterInputStream::~wxFilterInputStream()
984 // ----------------------------------------------------------------------------
985 // wxFilterOutputStream
986 // ----------------------------------------------------------------------------
988 wxFilterOutputStream::wxFilterOutputStream()
990 m_parent_o_stream
= NULL
;
993 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
995 m_parent_o_stream
= &stream
;
998 wxFilterOutputStream::~wxFilterOutputStream()
1002 // ----------------------------------------------------------------------------
1003 // wxBufferedInputStream
1004 // ----------------------------------------------------------------------------
1006 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1007 wxStreamBuffer
*buffer
)
1008 : wxFilterInputStream(s
)
1012 // use the buffer provided by the user
1013 m_i_streambuf
= buffer
;
1015 else // create a default buffer
1017 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1019 m_i_streambuf
->SetBufferIO(1024);
1023 wxBufferedInputStream::~wxBufferedInputStream()
1025 m_parent_i_stream
->SeekI(-(off_t
)m_i_streambuf
->GetBytesLeft(),
1028 delete m_i_streambuf
;
1031 char wxBufferedInputStream::Peek()
1033 return m_i_streambuf
->Peek();
1036 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1038 // reset the error flag
1039 m_lasterror
= wxStream_NOERROR
;
1041 // first read from the already cached data
1042 m_lastcount
= GetWBack(buf
, size
);
1044 // do we have to read anything more?
1045 if ( m_lastcount
< size
)
1047 size
-= m_lastcount
;
1048 buf
= (char *)buf
+ m_lastcount
;
1050 // the call to wxStreamBuffer::Read() below will reset our m_lastcount,
1052 size_t countOld
= m_lastcount
;
1054 m_i_streambuf
->Read(buf
, size
);
1056 m_lastcount
+= countOld
;
1062 off_t
wxBufferedInputStream::SeekI(off_t pos
, wxSeekMode mode
)
1064 return m_i_streambuf
->Seek(pos
, mode
);
1067 off_t
wxBufferedInputStream::TellI() const
1069 return m_i_streambuf
->Tell();
1072 size_t wxBufferedInputStream::OnSysRead(void *buffer
, size_t bufsize
)
1074 return m_parent_i_stream
->Read(buffer
, bufsize
).LastRead();
1077 off_t
wxBufferedInputStream::OnSysSeek(off_t seek
, wxSeekMode mode
)
1079 return m_parent_i_stream
->SeekI(seek
, mode
);
1082 off_t
wxBufferedInputStream::OnSysTell() const
1084 return m_parent_i_stream
->TellI();
1087 void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer
*buffer
)
1089 wxCHECK_RET( buffer
, _T("wxBufferedInputStream needs buffer") );
1091 delete m_i_streambuf
;
1092 m_i_streambuf
= buffer
;
1095 // ----------------------------------------------------------------------------
1096 // wxBufferedOutputStream
1097 // ----------------------------------------------------------------------------
1099 wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream
& s
,
1100 wxStreamBuffer
*buffer
)
1101 : wxFilterOutputStream(s
)
1105 m_o_streambuf
= buffer
;
1107 else // create a default one
1109 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
1111 m_o_streambuf
->SetBufferIO(1024);
1115 wxBufferedOutputStream::~wxBufferedOutputStream()
1118 delete m_o_streambuf
;
1121 wxOutputStream
& wxBufferedOutputStream::Write(const void *buffer
, size_t size
)
1124 m_o_streambuf
->Write(buffer
, size
);
1128 off_t
wxBufferedOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
1131 return m_o_streambuf
->Seek(pos
, mode
);
1134 off_t
wxBufferedOutputStream::TellO() const
1136 return m_o_streambuf
->Tell();
1139 void wxBufferedOutputStream::Sync()
1141 m_o_streambuf
->FlushBuffer();
1142 m_parent_o_stream
->Sync();
1145 size_t wxBufferedOutputStream::OnSysWrite(const void *buffer
, size_t bufsize
)
1147 return m_parent_o_stream
->Write(buffer
, bufsize
).LastWrite();
1150 off_t
wxBufferedOutputStream::OnSysSeek(off_t seek
, wxSeekMode mode
)
1152 return m_parent_o_stream
->SeekO(seek
, mode
);
1155 off_t
wxBufferedOutputStream::OnSysTell() const
1157 return m_parent_o_stream
->TellO();
1160 size_t wxBufferedOutputStream::GetSize() const
1162 return m_parent_o_stream
->GetSize() + m_o_streambuf
->GetIntPosition();
1165 void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer
*buffer
)
1167 wxCHECK_RET( buffer
, _T("wxBufferedOutputStream needs buffer") );
1169 delete m_o_streambuf
;
1170 m_o_streambuf
= buffer
;
1173 // ----------------------------------------------------------------------------
1174 // Some IOManip function
1175 // ----------------------------------------------------------------------------
1177 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
1179 static const wxChar
*eol
= wxTextFile::GetEOL();
1181 return stream
.Write(eol
, wxStrlen(eol
));