]>
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/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 // if we are going to allocate the buffer, we should free it later as well
76 void wxStreamBuffer::Init()
83 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
91 m_destroystream
= FALSE
;
94 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
98 wxASSERT_MSG(mode
!= read_write
, wxT("you have to use the other ctor for read_write mode") );
100 m_stream
= new wxInputStream
;
101 else if ( mode
== write
)
102 m_stream
= new wxOutputStream
;
109 m_destroystream
= TRUE
;
112 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
114 // doing this has big chances to lead to a crashwhen the source buffer is
115 // destroyed (otherwise assume the caller knows what he does)
116 wxASSERT_MSG( !buffer
.m_destroybuf
&& !buffer
.m_destroystream
,
117 _T("it's a bad idea to copy this buffer") );
119 m_buffer_start
= buffer
.m_buffer_start
;
120 m_buffer_end
= buffer
.m_buffer_end
;
121 m_buffer_pos
= buffer
.m_buffer_pos
;
122 m_buffer_size
= buffer
.m_buffer_size
;
123 m_fixed
= buffer
.m_fixed
;
124 m_flushable
= buffer
.m_flushable
;
125 m_stream
= buffer
.m_stream
;
126 m_mode
= buffer
.m_mode
;
127 m_destroybuf
= FALSE
;
128 m_destroystream
= FALSE
;
131 void wxStreamBuffer::FreeBuffer()
134 free(m_buffer_start
);
137 wxStreamBuffer::~wxStreamBuffer()
141 if ( m_destroystream
)
145 wxInputStream
*wxStreamBuffer::GetInputStream() const
147 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
150 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
152 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
155 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
159 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
163 void wxStreamBuffer::SetBufferIO(void *start
,
167 // start by freeing the old buffer
170 m_buffer_start
= (char *)start
;
171 m_buffer_end
= m_buffer_start
+ len
;
175 // if we own it, we free it
176 m_destroybuf
= takeOwnership
;
181 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
183 // start by freeing the old buffer
188 SetBufferIO(malloc(bufsize
), bufsize
, TRUE
/* take ownership */);
190 else // no buffer size => no buffer
196 void wxStreamBuffer::ResetBuffer()
198 wxCHECK_RET( m_stream
, _T("should have a stream in wxStreamBuffer") );
200 m_stream
->m_lasterror
= wxStream_NOERROR
;
201 m_stream
->m_lastcount
= 0;
202 if (m_mode
== read
&& m_flushable
)
203 m_buffer_pos
= m_buffer_end
;
205 m_buffer_pos
= m_buffer_start
;
208 // fill the buffer with as much data as possible (only for read buffers)
209 bool wxStreamBuffer::FillBuffer()
211 wxInputStream
*inStream
= GetInputStream();
213 wxCHECK_MSG( inStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
215 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
219 m_buffer_end
= m_buffer_start
+ count
;
220 m_buffer_pos
= m_buffer_start
;
225 // write the buffer contents to the stream (only for write buffers)
226 bool wxStreamBuffer::FlushBuffer()
228 wxCHECK_MSG( m_flushable
, FALSE
, _T("can't flush this buffer") );
230 // FIXME: what is this check for? (VZ)
231 if ( m_buffer_pos
== m_buffer_start
)
234 wxOutputStream
*outStream
= GetOutputStream();
236 wxCHECK_MSG( outStream
, FALSE
, _T("should have a stream in wxStreamBuffer") );
238 size_t current
= m_buffer_pos
- m_buffer_start
;
239 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
240 if ( count
!= current
)
243 m_buffer_pos
= m_buffer_start
;
248 size_t wxStreamBuffer::GetDataLeft()
250 /* Why is this done? RR. */
251 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
254 return GetBytesLeft();
257 // copy up to size bytes from our buffer into the provided one
258 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
260 // don't get more bytes than left in the buffer
261 size_t left
= GetBytesLeft();
266 memcpy(buffer
, m_buffer_pos
, size
);
267 m_buffer_pos
+= size
;
270 // copy the contents of the provided buffer into this one
271 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
273 size_t left
= GetBytesLeft();
278 // we can't realloc the buffer, so just copy what we can
283 // realloc the buffer to have enough space for the data
284 size_t delta
= m_buffer_pos
- m_buffer_start
;
286 char *startOld
= m_buffer_start
;
287 m_buffer_size
+= size
;
288 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
289 if ( !m_buffer_start
)
291 // don't leak memory if realloc() failed
292 m_buffer_start
= startOld
;
293 m_buffer_size
-= size
;
295 // what else can we do?
299 // adjust the pointers invalidated by realloc()
300 m_buffer_pos
= m_buffer_start
+ delta
;
301 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
305 memcpy(m_buffer_pos
, buffer
, size
);
306 m_buffer_pos
+= size
;
309 void wxStreamBuffer::PutChar(char c
)
311 wxOutputStream
*outStream
= GetOutputStream();
313 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
315 // if we don't have buffer at all, just forward this call to the stream,
318 outStream
->OnSysWrite(&c
, 1);
322 // otherwise check we have enough space left
323 if ( !GetDataLeft() && !FlushBuffer() )
326 SetError(wxStream_WRITE_ERR
);
331 m_stream
->m_lastcount
= 1;
336 char wxStreamBuffer::Peek()
338 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
339 _T("should have the stream and the buffer in wxStreamBuffer") );
341 if ( !GetDataLeft() )
343 SetError(wxStream_READ_ERR
);
348 GetFromBuffer(&c
, 1);
354 char wxStreamBuffer::GetChar()
356 wxInputStream
*inStream
= GetInputStream();
358 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
363 inStream
->OnSysRead(&c
, 1);
367 if ( !GetDataLeft() )
369 SetError(wxStream_READ_ERR
);
374 GetFromBuffer(&c
, 1);
375 m_stream
->m_lastcount
= 1;
382 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
384 wxInputStream
*inStream
= GetInputStream();
386 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
388 // lasterror is reset before all new IO calls
389 m_stream
->m_lasterror
= wxStream_NOERROR
;
393 m_stream
->m_lastcount
= inStream
->OnSysRead(buffer
, size
);
395 else // we have a buffer, use it
397 size_t orig_size
= size
;
401 size_t left
= GetDataLeft();
403 // if the requested number of bytes if greater than the buffer
404 // size, read data in chunks
407 GetFromBuffer(buffer
, left
);
409 buffer
= (char *)buffer
+ left
;
413 SetError(wxStream_EOF
);
417 else // otherwise just do it in one gulp
419 GetFromBuffer(buffer
, size
);
424 m_stream
->m_lastcount
= orig_size
- size
;
427 return m_stream
->m_lastcount
;
430 // this should really be called "Copy()"
431 size_t wxStreamBuffer::Read(wxStreamBuffer
*dbuf
)
433 wxCHECK_MSG( m_mode
!= write
, 0, _T("can't read from this buffer") );
435 char buf
[BUF_TEMP_SIZE
];
441 nRead
= Read(dbuf
, WXSIZEOF(buf
));
444 nRead
= dbuf
->Write(buf
, nRead
);
453 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
455 wxOutputStream
*outStream
= GetOutputStream();
457 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
459 // lasterror is reset before all new IO calls
460 m_stream
->m_lasterror
= wxStream_NOERROR
;
462 if ( !HasBuffer() && m_fixed
)
464 // no buffer, just forward the call to the stream
465 m_stream
->m_lastcount
= outStream
->OnSysWrite(buffer
, size
);
467 else // we [may] have a buffer, use it
469 size_t orig_size
= size
;
473 size_t left
= GetBytesLeft();
475 // if the buffer is too large to fit in the stream buffer, split
476 // it in smaller parts
478 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
479 // we always go to the second case.
481 // FIXME: fine, but if it fails we should (re)try writing it by
482 // chunks as this will (hopefully) always work (VZ)
483 if ( size
> left
&& m_fixed
)
485 PutToBuffer(buffer
, left
);
487 buffer
= (char *)buffer
+ left
;
489 if ( !FlushBuffer() )
491 SetError(wxStream_WRITE_ERR
);
496 m_buffer_pos
= m_buffer_start
;
498 else // we can do it in one gulp
500 PutToBuffer(buffer
, size
);
505 m_stream
->m_lastcount
= orig_size
- size
;
508 return m_stream
->m_lastcount
;
511 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
513 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
514 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
516 char buf
[BUF_TEMP_SIZE
];
522 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
525 nWrite
= Write(buf
, nRead
);
526 if ( nWrite
< nRead
)
528 // put back data we couldn't copy
529 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
531 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
541 while ( nWrite
== WXSIZEOF(buf
) );
546 off_t
wxStreamBuffer::Seek(off_t pos
, wxSeekMode mode
)
550 off_t last_access
= GetLastAccess();
561 diff
= pos
+ GetIntPosition();
565 diff
= pos
+ last_access
;
569 wxFAIL_MSG( _T("invalid seek mode") );
571 return wxInvalidOffset
;
573 if (diff
< 0 || diff
> last_access
)
574 return wxInvalidOffset
;
575 SetIntPosition(diff
);
582 // We'll try to compute an internal position later ...
583 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
588 diff
= pos
+ GetIntPosition();
590 if ( (diff
> last_access
) || (diff
< 0) )
592 // We must take into account the fact that we have read
593 // something previously.
594 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
600 SetIntPosition(diff
);
605 // Hard to compute: always seek to the requested position.
606 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
611 return wxInvalidOffset
;
614 off_t
wxStreamBuffer::Tell() const
618 // only ask the stream for position if we have a real stream and not a
619 // dummy one which we created ourselves, otherwise we'd call
620 // wxStream::OnSysTell() which would always return wxInvalidOffset
621 if ( !m_destroystream
)
623 pos
= m_stream
->OnSysTell();
624 if ( pos
== wxInvalidOffset
)
625 return wxInvalidOffset
;
627 else // no associated stream
632 pos
+= GetIntPosition();
634 if ( m_mode
== read
&& m_flushable
)
635 pos
-= GetLastAccess();
640 // ----------------------------------------------------------------------------
642 // ----------------------------------------------------------------------------
644 wxStreamBase::wxStreamBase()
646 m_lasterror
= wxStream_NOERROR
;
650 wxStreamBase::~wxStreamBase()
654 off_t
wxStreamBase::OnSysSeek(off_t
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
656 return wxInvalidOffset
;
659 off_t
wxStreamBase::OnSysTell() const
661 return wxInvalidOffset
;
664 // ----------------------------------------------------------------------------
666 // ----------------------------------------------------------------------------
668 wxInputStream::wxInputStream()
675 wxInputStream::~wxInputStream()
680 size_t wxInputStream::OnSysRead(void * WXUNUSED(buffer
),
681 size_t WXUNUSED(bufsize
))
686 bool wxInputStream::Eof() const
688 wxInputStream
*self
= wxConstCast(this, wxInputStream
);
693 // some streams can know that they're at EOF before actually trying to
694 // read beyond the end of stream (e.g. files) while others have no way of
695 // knowing it, so to provide the same behaviour in all cases we only
696 // return TRUE from here if the character really couldn't be read
697 if ( !self
->LastRead() && GetLastError() == wxSTREAM_EOF
)
707 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
709 // get number of bytes left from previous wback buffer
710 size_t toget
= m_wbacksize
- m_wbackcur
;
712 // allocate a buffer large enough to hold prev + new data
713 char *temp_b
= (char *)malloc(needed_size
+ toget
);
718 // copy previous data (and free old buffer) if needed
721 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
728 m_wbacksize
= needed_size
+ toget
;
733 size_t wxInputStream::GetWBack(void *buf
, size_t bsize
)
738 // how many bytes do we have in the buffer?
739 size_t toget
= m_wbacksize
- m_wbackcur
;
743 // we won't read everything
747 // copy the data from the cache
748 memcpy(buf
, m_wback
+ m_wbackcur
, toget
);
751 if ( m_wbackcur
== m_wbacksize
)
753 // TODO: should we really free it here all the time? maybe keep it?
760 // return the number of bytes copied
764 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
766 if ( m_lasterror
!= wxSTREAM_NO_ERROR
&& m_lasterror
!= wxSTREAM_EOF
)
768 // can't operate on this stream until the error is cleared
772 char *ptrback
= AllocSpaceWBack(bufsize
);
776 // Eof() shouldn't return TRUE any longer
777 if ( m_lasterror
== wxSTREAM_EOF
)
778 m_lasterror
= wxSTREAM_NO_ERROR
;
780 memcpy(ptrback
, buf
, bufsize
);
784 bool wxInputStream::Ungetch(char c
)
786 return Ungetch(&c
, sizeof(char)) != 0;
789 char wxInputStream::GetC()
796 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
798 size_t retsize
= GetWBack(buf
, size
);
802 m_lasterror
= wxStream_NOERROR
;
806 buf
= (char *)buf
+ retsize
;
808 m_lastcount
= OnSysRead(buf
, size
) + retsize
;
812 char wxInputStream::Peek()
816 if (m_lasterror
== wxStream_NOERROR
)
825 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
827 char buf
[BUF_TEMP_SIZE
];
828 size_t bytes_read
= BUF_TEMP_SIZE
;
830 while (bytes_read
== BUF_TEMP_SIZE
)
832 bytes_read
= Read(buf
, bytes_read
).LastRead();
833 bytes_read
= stream_out
.Write(buf
, bytes_read
).LastWrite();
838 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
840 // RR: This code is duplicated in wxBufferedInputStream. This is
841 // not really a good design, but buffered stream are different
842 // from all other in that they handle two stream-related objects,
843 // the stream buffer and parent stream.
845 // I don't know whether it should be put as well in wxFileInputStream::OnSysSeek
846 if (m_lasterror
==wxSTREAM_EOF
)
847 m_lasterror
=wxSTREAM_NOERROR
;
849 /* RR: A call to SeekI() will automatically invalidate any previous
850 call to Ungetch(), otherwise it would be possible to SeekI() to
851 one position, unread some bytes there, SeekI() to another position
852 and the data would be corrupted.
854 GRG: Could add code here to try to navigate within the wback
855 buffer if possible, but is it really needed? It would only work
856 when seeking in wxFromCurrent mode, else it would invalidate
861 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
869 return OnSysSeek(pos
, mode
);
872 off_t
wxInputStream::TellI() const
874 off_t pos
= OnSysTell();
876 if (pos
!= wxInvalidOffset
)
877 pos
-= (m_wbacksize
- m_wbackcur
);
883 // ----------------------------------------------------------------------------
885 // ----------------------------------------------------------------------------
887 wxOutputStream::wxOutputStream()
891 wxOutputStream::~wxOutputStream()
895 size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer
),
896 size_t WXUNUSED(bufsize
))
901 void wxOutputStream::PutC(char c
)
906 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
908 m_lastcount
= OnSysWrite(buffer
, size
);
912 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
914 stream_in
.Read(*this);
918 off_t
wxOutputStream::TellO() const
923 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
925 return OnSysSeek(pos
, mode
);
928 void wxOutputStream::Sync()
933 // ----------------------------------------------------------------------------
934 // wxCountingOutputStream
935 // ----------------------------------------------------------------------------
937 wxCountingOutputStream::wxCountingOutputStream ()
942 size_t wxCountingOutputStream::GetSize() const
947 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
950 m_currentPos
+= size
;
951 if (m_currentPos
> m_lastcount
)
952 m_lastcount
= m_currentPos
;
957 off_t
wxCountingOutputStream::OnSysSeek(off_t pos
, wxSeekMode mode
)
966 m_currentPos
= m_lastcount
+ pos
;
974 wxFAIL_MSG( _T("invalid seek mode") );
975 return wxInvalidOffset
;
978 if (m_currentPos
> m_lastcount
)
979 m_lastcount
= m_currentPos
;
984 off_t
wxCountingOutputStream::OnSysTell() const
989 // ----------------------------------------------------------------------------
990 // wxFilterInputStream
991 // ----------------------------------------------------------------------------
993 wxFilterInputStream::wxFilterInputStream()
995 m_parent_i_stream
= NULL
;
998 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
1000 m_parent_i_stream
= &stream
;
1003 wxFilterInputStream::~wxFilterInputStream()
1007 // ----------------------------------------------------------------------------
1008 // wxFilterOutputStream
1009 // ----------------------------------------------------------------------------
1011 wxFilterOutputStream::wxFilterOutputStream()
1013 m_parent_o_stream
= NULL
;
1016 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
1018 m_parent_o_stream
= &stream
;
1021 wxFilterOutputStream::~wxFilterOutputStream()
1025 // ----------------------------------------------------------------------------
1026 // wxBufferedInputStream
1027 // ----------------------------------------------------------------------------
1029 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1030 wxStreamBuffer
*buffer
)
1031 : wxFilterInputStream(s
)
1035 // use the buffer provided by the user
1036 m_i_streambuf
= buffer
;
1038 else // create a default buffer
1040 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1042 m_i_streambuf
->SetBufferIO(1024);
1046 wxBufferedInputStream::~wxBufferedInputStream()
1048 m_parent_i_stream
->SeekI(-(off_t
)m_i_streambuf
->GetBytesLeft(),
1051 delete m_i_streambuf
;
1054 char wxBufferedInputStream::Peek()
1056 return m_i_streambuf
->Peek();
1059 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1061 // reset the error flag
1062 m_lasterror
= wxStream_NOERROR
;
1064 // first read from the already cached data
1065 m_lastcount
= GetWBack(buf
, size
);
1067 // do we have to read anything more?
1068 if ( m_lastcount
< size
)
1070 size
-= m_lastcount
;
1071 buf
= (char *)buf
+ m_lastcount
;
1073 // the call to wxStreamBuffer::Read() below will reset our m_lastcount,
1075 size_t countOld
= m_lastcount
;
1077 m_i_streambuf
->Read(buf
, size
);
1079 m_lastcount
+= countOld
;
1085 off_t
wxBufferedInputStream::SeekI(off_t pos
, wxSeekMode mode
)
1087 // RR: Look at wxInputStream for comments.
1089 if (m_lasterror
==wxSTREAM_EOF
)
1090 m_lasterror
=wxSTREAM_NOERROR
;
1094 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
1102 return m_i_streambuf
->Seek(pos
, mode
);
1105 off_t
wxBufferedInputStream::TellI() const
1107 off_t pos
= m_i_streambuf
->Tell();
1109 if (pos
!= wxInvalidOffset
)
1110 pos
-= (m_wbacksize
- m_wbackcur
);
1115 size_t wxBufferedInputStream::OnSysRead(void *buffer
, size_t bufsize
)
1117 return m_parent_i_stream
->Read(buffer
, bufsize
).LastRead();
1120 off_t
wxBufferedInputStream::OnSysSeek(off_t seek
, wxSeekMode mode
)
1122 return m_parent_i_stream
->SeekI(seek
, mode
);
1125 off_t
wxBufferedInputStream::OnSysTell() const
1127 return m_parent_i_stream
->TellI();
1130 void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer
*buffer
)
1132 wxCHECK_RET( buffer
, _T("wxBufferedInputStream needs buffer") );
1134 delete m_i_streambuf
;
1135 m_i_streambuf
= buffer
;
1138 // ----------------------------------------------------------------------------
1139 // wxBufferedOutputStream
1140 // ----------------------------------------------------------------------------
1142 wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream
& s
,
1143 wxStreamBuffer
*buffer
)
1144 : wxFilterOutputStream(s
)
1148 m_o_streambuf
= buffer
;
1150 else // create a default one
1152 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
1154 m_o_streambuf
->SetBufferIO(1024);
1158 wxBufferedOutputStream::~wxBufferedOutputStream()
1161 delete m_o_streambuf
;
1164 wxOutputStream
& wxBufferedOutputStream::Write(const void *buffer
, size_t size
)
1167 m_o_streambuf
->Write(buffer
, size
);
1171 off_t
wxBufferedOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
1174 return m_o_streambuf
->Seek(pos
, mode
);
1177 off_t
wxBufferedOutputStream::TellO() const
1179 return m_o_streambuf
->Tell();
1182 void wxBufferedOutputStream::Sync()
1184 m_o_streambuf
->FlushBuffer();
1185 m_parent_o_stream
->Sync();
1188 size_t wxBufferedOutputStream::OnSysWrite(const void *buffer
, size_t bufsize
)
1190 return m_parent_o_stream
->Write(buffer
, bufsize
).LastWrite();
1193 off_t
wxBufferedOutputStream::OnSysSeek(off_t seek
, wxSeekMode mode
)
1195 return m_parent_o_stream
->SeekO(seek
, mode
);
1198 off_t
wxBufferedOutputStream::OnSysTell() const
1200 return m_parent_o_stream
->TellO();
1203 size_t wxBufferedOutputStream::GetSize() const
1205 return m_parent_o_stream
->GetSize() + m_o_streambuf
->GetIntPosition();
1208 void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer
*buffer
)
1210 wxCHECK_RET( buffer
, _T("wxBufferedOutputStream needs buffer") );
1212 delete m_o_streambuf
;
1213 m_o_streambuf
= buffer
;
1216 // ----------------------------------------------------------------------------
1217 // Some IOManip function
1218 // ----------------------------------------------------------------------------
1220 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
1222 static const wxChar
*eol
= wxTextFile::GetEOL();
1224 return stream
.Write(eol
, wxStrlen(eol
));