]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stream.cpp
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"
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 // there is nothing to destroy anyhow
75 void wxStreamBuffer::Init()
82 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
90 m_destroystream
= FALSE
;
93 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
97 m_stream
= new wxStreamBase
;
101 m_destroystream
= TRUE
;
104 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
106 // doing this has big chances to lead to a crashwhen the source buffer is
107 // destroyed (otherwise assume the caller knows what he does)
108 wxASSERT_MSG( !buffer
.m_destroybuf
&& !buffer
.m_destroystream
,
109 _T("it's a bad idea to copy this buffer") );
111 m_buffer_start
= buffer
.m_buffer_start
;
112 m_buffer_end
= buffer
.m_buffer_end
;
113 m_buffer_pos
= buffer
.m_buffer_pos
;
114 m_buffer_size
= buffer
.m_buffer_size
;
115 m_fixed
= buffer
.m_fixed
;
116 m_flushable
= buffer
.m_flushable
;
117 m_stream
= buffer
.m_stream
;
118 m_mode
= buffer
.m_mode
;
119 m_destroybuf
= FALSE
;
120 m_destroystream
= FALSE
;
123 void wxStreamBuffer::FreeBuffer()
126 free(m_buffer_start
);
129 wxStreamBuffer::~wxStreamBuffer()
133 if ( m_destroystream
)
137 wxInputStream
*wxStreamBuffer::GetInputStream() const
139 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
142 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
144 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
147 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
151 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
155 void wxStreamBuffer::SetBufferIO(void *start
,
159 // start by freeing the old buffer
162 m_buffer_start
= (char *)start
;
163 m_buffer_end
= m_buffer_start
+ len
;
167 // if we own it, we free it
168 m_destroybuf
= takeOwnership
;
173 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
175 // start by freeing the old buffer
180 SetBufferIO(malloc(bufsize
), bufsize
, TRUE
/* take ownership */);
182 else // no buffer size => no buffer
188 void wxStreamBuffer::ResetBuffer()
190 wxCHECK_RET( m_stream
, _T("should have a stream in wxStreamBuffer") );
192 m_stream
->m_lasterror
= wxStream_NOERROR
;
193 m_stream
->m_lastcount
= 0;
194 if (m_mode
== read
&& m_flushable
)
195 m_buffer_pos
= m_buffer_end
;
197 m_buffer_pos
= m_buffer_start
;
200 // fill the buffer with as much data as possible (only for read buffers)
201 bool wxStreamBuffer::FillBuffer()
203 wxInputStream
*inStream
= GetInputStream();
205 wxCHECK_MSG( inStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
207 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
211 m_buffer_end
= m_buffer_start
+ count
;
212 m_buffer_pos
= m_buffer_start
;
217 // write the buffer contents to the stream (only for write buffers)
218 bool wxStreamBuffer::FlushBuffer()
220 wxCHECK_MSG( m_flushable
, FALSE
, _T("can't flush this buffer") );
222 // FIXME: what is this check for? (VZ)
223 if ( m_buffer_pos
== m_buffer_start
)
226 wxOutputStream
*outStream
= GetOutputStream();
228 wxCHECK_MSG( outStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
230 size_t current
= m_buffer_pos
- m_buffer_start
;
231 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
232 if ( count
!= current
)
235 m_buffer_pos
= m_buffer_start
;
240 size_t wxStreamBuffer::GetDataLeft()
242 /* Why is this done? RR. */
243 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
246 return GetBytesLeft();
249 // copy up to size bytes from our buffer into the provided one
250 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
252 // don't get more bytes than left in the buffer
253 size_t left
= GetBytesLeft();
258 memcpy(buffer
, m_buffer_pos
, size
);
259 m_buffer_pos
+= size
;
262 // copy the contents of the provided buffer into this one
263 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
265 size_t left
= GetBytesLeft();
270 // we can't realloc the buffer, so just copy what we can
275 // realloc the buffer to have enough space for the data
276 size_t delta
= m_buffer_pos
- m_buffer_start
;
278 char *startOld
= m_buffer_start
;
279 m_buffer_size
+= size
;
280 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
281 if ( !m_buffer_start
)
283 // don't leak memory if realloc() failed
284 m_buffer_start
= startOld
;
285 m_buffer_size
-= size
;
287 // what else can we do?
291 // adjust the pointers invalidated by realloc()
292 m_buffer_pos
= m_buffer_start
+ delta
;
293 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
297 memcpy(m_buffer_pos
, buffer
, size
);
298 m_buffer_pos
+= size
;
301 void wxStreamBuffer::PutChar(char c
)
303 wxOutputStream
*outStream
= GetOutputStream();
305 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
307 // if we don't have buffer at all, just forward this call to the stream,
310 outStream
->OnSysWrite(&c
, 1);
314 // otherwise check we have enough space left
315 if ( !GetDataLeft() && !FlushBuffer() )
318 SetError(wxStream_WRITE_ERR
);
323 m_stream
->m_lastcount
= 1;
328 char wxStreamBuffer::Peek()
330 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
331 _T("should have the stream and the buffer in wxStreamBuffer") );
333 if ( !GetDataLeft() )
335 SetError(wxStream_READ_ERR
);
340 GetFromBuffer(&c
, 1);
346 char wxStreamBuffer::GetChar()
348 wxInputStream
*inStream
= GetInputStream();
350 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
355 inStream
->OnSysRead(&c
, 1);
359 if ( !GetDataLeft() )
361 SetError(wxStream_READ_ERR
);
366 GetFromBuffer(&c
, 1);
367 m_stream
->m_lastcount
= 1;
374 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
376 wxInputStream
*inStream
= GetInputStream();
378 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
380 // lasterror is reset before all new IO calls
381 m_stream
->m_lasterror
= wxStream_NOERROR
;
385 m_stream
->m_lastcount
= inStream
->OnSysRead(buffer
, size
);
387 else // we have a buffer, use it
389 size_t orig_size
= size
;
393 size_t left
= GetDataLeft();
395 // if the requested number of bytes if greater than the buffer
396 // size, read data in chunks
399 GetFromBuffer(buffer
, left
);
401 buffer
= (char *)buffer
+ left
;
405 SetError(wxStream_EOF
);
409 else // otherwise just do it in one gulp
411 GetFromBuffer(buffer
, size
);
416 m_stream
->m_lastcount
= orig_size
- size
;
419 return m_stream
->m_lastcount
;
422 // this should really be called "Copy()"
423 size_t wxStreamBuffer::Read(wxStreamBuffer
*dbuf
)
425 wxCHECK_MSG( m_mode
!= write
, 0, _T("can't read from this buffer") );
427 char buf
[BUF_TEMP_SIZE
];
433 nRead
= Read(dbuf
, WXSIZEOF(buf
));
436 nRead
= dbuf
->Write(buf
, nRead
);
445 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
447 wxOutputStream
*outStream
= GetOutputStream();
449 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
451 // lasterror is reset before all new IO calls
452 m_stream
->m_lasterror
= wxStream_NOERROR
;
454 if ( !HasBuffer() && m_fixed
)
456 // no buffer, just forward the call to the stream
457 m_stream
->m_lastcount
= outStream
->OnSysWrite(buffer
, size
);
459 else // we [may] have a buffer, use it
461 size_t orig_size
= size
;
465 size_t left
= GetBytesLeft();
467 // if the buffer is too large to fit in the stream buffer, split
468 // it in smaller parts
470 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
471 // we always go to the second case.
473 // FIXME: fine, but if it fails we should (re)try writing it by
474 // chunks as this will (hopefully) always work (VZ)
475 if ( size
> left
&& m_fixed
)
477 PutToBuffer(buffer
, left
);
479 buffer
= (char *)buffer
+ left
;
481 if ( !FlushBuffer() )
483 SetError(wxStream_WRITE_ERR
);
488 m_buffer_pos
= m_buffer_start
;
490 else // we can do it in one gulp
492 PutToBuffer(buffer
, size
);
497 m_stream
->m_lastcount
= orig_size
- size
;
500 return m_stream
->m_lastcount
;
503 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
505 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
506 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
508 char buf
[BUF_TEMP_SIZE
];
514 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
517 nWrite
= Write(buf
, nRead
);
518 if ( nWrite
< nRead
)
520 // put back data we couldn't copy
521 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
523 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
533 while ( nWrite
== WXSIZEOF(buf
) );
538 off_t
wxStreamBuffer::Seek(off_t pos
, wxSeekMode mode
)
542 off_t last_access
= GetLastAccess();
553 diff
= pos
+ GetIntPosition();
557 diff
= pos
+ last_access
;
561 wxFAIL_MSG( _T("invalid seek mode") );
563 return wxInvalidOffset
;
565 if (diff
< 0 || diff
> last_access
)
566 return wxInvalidOffset
;
567 SetIntPosition(diff
);
574 // We'll try to compute an internal position later ...
575 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
580 diff
= pos
+ GetIntPosition();
582 if ( (diff
> last_access
) || (diff
< 0) )
584 // We must take into account the fact that we have read
585 // something previously.
586 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
592 SetIntPosition(diff
);
597 // Hard to compute: always seek to the requested position.
598 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
603 return wxInvalidOffset
;
606 off_t
wxStreamBuffer::Tell() const
608 off_t pos
= m_stream
->OnSysTell();
609 if ( pos
== wxInvalidOffset
)
610 return wxInvalidOffset
;
612 pos
+= GetIntPosition();
614 if ( m_mode
== read
&& m_flushable
)
615 pos
-= GetLastAccess();
620 // ----------------------------------------------------------------------------
622 // ----------------------------------------------------------------------------
624 wxStreamBase::wxStreamBase()
626 m_lasterror
= wxStream_NOERROR
;
630 wxStreamBase::~wxStreamBase()
634 off_t
wxStreamBase::OnSysSeek(off_t
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
636 return wxInvalidOffset
;
639 off_t
wxStreamBase::OnSysTell() const
641 return wxInvalidOffset
;
644 // ----------------------------------------------------------------------------
646 // ----------------------------------------------------------------------------
648 wxInputStream::wxInputStream()
655 wxInputStream::~wxInputStream()
660 size_t wxInputStream::OnSysRead(void * WXUNUSED(buffer
),
661 size_t WXUNUSED(bufsize
))
666 bool wxInputStream::Eof() const
668 wxInputStream
*self
= wxConstCast(this, wxInputStream
);
673 // some streams can know that they're at EOF before actually trying to
674 // read beyond the end of stream (e.g. files) while others have no way of
675 // knowing it, so to provide the same behaviour in all cases we only
676 // return TRUE from here if the character really couldn't be read
677 if ( !self
->LastRead() && GetLastError() == wxSTREAM_EOF
)
687 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
689 // get number of bytes left from previous wback buffer
690 size_t toget
= m_wbacksize
- m_wbackcur
;
692 // allocate a buffer large enough to hold prev + new data
693 char *temp_b
= (char *)malloc(needed_size
+ toget
);
698 /* copy previous data (and free old buffer) if needed */
701 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
708 m_wbacksize
= needed_size
+ toget
;
713 size_t wxInputStream::GetWBack(void *buf
, size_t bsize
)
715 size_t toget
= m_wbacksize
-m_wbackcur
;
723 memcpy(buf
, (m_wback
+m_wbackcur
), toget
);
726 if (m_wbackcur
== m_wbacksize
)
737 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
739 char *ptrback
= AllocSpaceWBack(bufsize
);
743 memcpy(ptrback
, buf
, bufsize
);
747 bool wxInputStream::Ungetch(char c
)
749 void *ptrback
= AllocSpaceWBack(1);
753 *(char *)ptrback
= c
;
757 char wxInputStream::GetC()
764 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
766 size_t retsize
= GetWBack(buf
, size
);
770 m_lasterror
= wxStream_NOERROR
;
774 buf
= (char *)buf
+ retsize
;
776 m_lastcount
= OnSysRead(buf
, size
) + retsize
;
780 char wxInputStream::Peek()
784 if (m_lasterror
== wxStream_NOERROR
)
793 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
795 char buf
[BUF_TEMP_SIZE
];
796 size_t bytes_read
= BUF_TEMP_SIZE
;
798 while (bytes_read
== BUF_TEMP_SIZE
)
800 bytes_read
= Read(buf
, bytes_read
).LastRead();
801 bytes_read
= stream_out
.Write(buf
, bytes_read
).LastWrite();
806 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
808 /* Should be check and improve, just to remove a slight bug !
809 I don't know whether it should be put as well in wxFileInputStream::OnSysSeek ? */
810 if (m_lasterror
==wxSTREAM_EOF
)
811 m_lasterror
=wxSTREAM_NOERROR
;
813 /* A call to SeekI() will automatically invalidate any previous call
814 to Ungetch(), otherwise it would be possible to SeekI() to one
815 one position, unread some bytes there, SeekI() to another position
816 and the data would be corrupted.
818 GRG: Could add code here to try to navigate within the wback
819 buffer if possible, but is it really needed? It would only work
820 when seeking in wxFromCurrent mode, else it would invalidate
831 return OnSysSeek(pos
, mode
);
834 off_t
wxInputStream::TellI() const
836 /* GRG: Changed to make it compatible with the wback buffer */
837 off_t pos
= OnSysTell();
839 if (pos
!= wxInvalidOffset
)
840 pos
-= (m_wbacksize
- m_wbackcur
);
845 // --------------------
846 // Overloaded operators
847 // --------------------
850 wxInputStream
& wxInputStream::operator>>(wxObject
*& obj
)
852 wxObjectInputStream
obj_s(*this);
853 obj
= obj_s
.LoadObject();
856 #endif // wxUSE_SERIAL
859 // ----------------------------------------------------------------------------
861 // ----------------------------------------------------------------------------
863 wxOutputStream::wxOutputStream()
867 wxOutputStream::~wxOutputStream()
871 size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer
),
872 size_t WXUNUSED(bufsize
))
877 void wxOutputStream::PutC(char c
)
882 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
884 m_lastcount
= OnSysWrite(buffer
, size
);
888 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
890 stream_in
.Read(*this);
894 off_t
wxOutputStream::TellO() const
899 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
901 return OnSysSeek(pos
, mode
);
904 void wxOutputStream::Sync()
909 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
)
911 wxObjectOutputStream
obj_s(*this);
912 obj_s
.SaveObject(obj
);
915 #endif // wxUSE_SERIAL
917 // ----------------------------------------------------------------------------
918 // wxCountingOutputStream
919 // ----------------------------------------------------------------------------
921 wxCountingOutputStream::wxCountingOutputStream ()
926 size_t wxCountingOutputStream::GetSize() const
931 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
934 m_currentPos
+= size
;
935 if (m_currentPos
> m_lastcount
)
936 m_lastcount
= m_currentPos
;
941 off_t
wxCountingOutputStream::OnSysSeek(off_t pos
, wxSeekMode mode
)
950 m_currentPos
= m_lastcount
+ pos
;
958 wxFAIL_MSG( _T("invalid seek mode") );
959 return wxInvalidOffset
;
962 if (m_currentPos
> m_lastcount
)
963 m_lastcount
= m_currentPos
;
968 off_t
wxCountingOutputStream::OnSysTell() const
973 // ----------------------------------------------------------------------------
974 // wxFilterInputStream
975 // ----------------------------------------------------------------------------
977 wxFilterInputStream::wxFilterInputStream()
979 m_parent_i_stream
= NULL
;
982 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
984 m_parent_i_stream
= &stream
;
987 wxFilterInputStream::~wxFilterInputStream()
991 // ----------------------------------------------------------------------------
992 // wxFilterOutputStream
993 // ----------------------------------------------------------------------------
995 wxFilterOutputStream::wxFilterOutputStream()
997 m_parent_o_stream
= NULL
;
1000 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
1002 m_parent_o_stream
= &stream
;
1005 wxFilterOutputStream::~wxFilterOutputStream()
1009 // ----------------------------------------------------------------------------
1010 // wxBufferedInputStream
1011 // ----------------------------------------------------------------------------
1013 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1014 wxStreamBuffer
*buffer
)
1015 : wxFilterInputStream(s
)
1019 // use the buffer provided by the user
1020 m_i_streambuf
= buffer
;
1022 else // create a default buffer
1024 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1026 m_i_streambuf
->SetBufferIO(1024);
1030 wxBufferedInputStream::~wxBufferedInputStream()
1032 m_parent_i_stream
->SeekI(-(off_t
)m_i_streambuf
->GetBytesLeft(),
1035 delete m_i_streambuf
;
1038 char wxBufferedInputStream::Peek()
1040 return m_i_streambuf
->Peek();
1043 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1047 retsize
= GetWBack(buf
, size
);
1048 m_lastcount
= retsize
;
1049 if ( retsize
== size
)
1051 m_lasterror
= wxStream_NOERROR
;
1055 buf
= (char *)buf
+ retsize
;
1057 m_i_streambuf
->Read(buf
, size
);
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
)
1180 return stream
.Write("\r\n", 2);
1183 return stream
.Write("\r", 1);
1185 return stream
.Write("\n", 1);