]>
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 licence
11 /////////////////////////////////////////////////////////////////////////////
13 // ============================================================================
15 // ============================================================================
17 // ----------------------------------------------------------------------------
19 // ----------------------------------------------------------------------------
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
35 #include "wx/stream.h"
36 #include "wx/datstrm.h"
37 #include "wx/textfile.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 // the temporary buffer size used when copying from stream to stream
44 #define BUF_TEMP_SIZE 4096
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 void wxStreamBuffer::SetError(wxStreamError err
)
56 if ( m_stream
&& m_stream
->m_lasterror
== wxSTREAM_NO_ERROR
)
57 m_stream
->m_lasterror
= err
;
60 void wxStreamBuffer::InitBuffer()
67 // if we are going to allocate the buffer, we should free it later as well
71 void wxStreamBuffer::Init()
78 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
88 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
98 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
100 // doing this has big chances to lead to a crash when the source buffer is
101 // destroyed (otherwise assume the caller knows what he does)
102 wxASSERT_MSG( !buffer
.m_destroybuf
,
103 _T("it's a bad idea to copy this buffer") );
105 m_buffer_start
= buffer
.m_buffer_start
;
106 m_buffer_end
= buffer
.m_buffer_end
;
107 m_buffer_pos
= buffer
.m_buffer_pos
;
108 m_buffer_size
= buffer
.m_buffer_size
;
109 m_fixed
= buffer
.m_fixed
;
110 m_flushable
= buffer
.m_flushable
;
111 m_stream
= buffer
.m_stream
;
112 m_mode
= buffer
.m_mode
;
113 m_destroybuf
= false;
116 void wxStreamBuffer::FreeBuffer()
120 free(m_buffer_start
);
121 m_buffer_start
= NULL
;
125 wxStreamBuffer::~wxStreamBuffer()
130 wxInputStream
*wxStreamBuffer::GetInputStream() const
132 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
135 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
137 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
140 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
144 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
148 void wxStreamBuffer::SetBufferIO(void *start
,
152 // start by freeing the old buffer
155 m_buffer_start
= (char *)start
;
156 m_buffer_end
= m_buffer_start
+ len
;
160 // if we own it, we free it
161 m_destroybuf
= takeOwnership
;
166 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
170 // this will free the old buffer and allocate the new one
171 SetBufferIO(malloc(bufsize
), bufsize
, true /* take ownership */);
173 else // no buffer size => no buffer
175 // still free the old one
181 void wxStreamBuffer::ResetBuffer()
186 m_stream
->m_lastcount
= 0;
189 m_buffer_pos
= m_mode
== read
&& m_flushable
194 // fill the buffer with as much data as possible (only for read buffers)
195 bool wxStreamBuffer::FillBuffer()
197 wxInputStream
*inStream
= GetInputStream();
199 // It's legal to have no stream, so we don't complain about it just return false
203 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
207 m_buffer_end
= m_buffer_start
+ count
;
208 m_buffer_pos
= m_buffer_start
;
213 // write the buffer contents to the stream (only for write buffers)
214 bool wxStreamBuffer::FlushBuffer()
216 wxCHECK_MSG( m_flushable
, false, _T("can't flush this buffer") );
218 // FIXME: what is this check for? (VZ)
219 if ( m_buffer_pos
== m_buffer_start
)
222 wxOutputStream
*outStream
= GetOutputStream();
224 wxCHECK_MSG( outStream
, false, _T("should have a stream in wxStreamBuffer") );
226 size_t current
= m_buffer_pos
- m_buffer_start
;
227 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
228 if ( count
!= current
)
231 m_buffer_pos
= m_buffer_start
;
236 size_t wxStreamBuffer::GetDataLeft()
238 /* Why is this done? RR. */
239 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
242 return GetBytesLeft();
245 // copy up to size bytes from our buffer into the provided one
246 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
248 // don't get more bytes than left in the buffer
249 size_t left
= GetBytesLeft();
254 memcpy(buffer
, m_buffer_pos
, size
);
255 m_buffer_pos
+= size
;
258 // copy the contents of the provided buffer into this one
259 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
261 size_t left
= GetBytesLeft();
267 // we can't realloc the buffer, so just copy what we can
272 // realloc the buffer to have enough space for the data
273 size_t delta
= m_buffer_pos
- m_buffer_start
;
275 char *startOld
= m_buffer_start
;
276 m_buffer_size
+= size
;
277 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
278 if ( !m_buffer_start
)
280 // don't leak memory if realloc() failed
281 m_buffer_start
= startOld
;
282 m_buffer_size
-= size
;
284 // what else can we do?
288 // adjust the pointers invalidated by realloc()
289 m_buffer_pos
= m_buffer_start
+ delta
;
290 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
294 memcpy(m_buffer_pos
, buffer
, size
);
295 m_buffer_pos
+= size
;
298 void wxStreamBuffer::PutChar(char c
)
300 wxOutputStream
*outStream
= GetOutputStream();
302 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
304 // if we don't have buffer at all, just forward this call to the stream,
307 outStream
->OnSysWrite(&c
, sizeof(c
));
311 // otherwise check we have enough space left
312 if ( !GetDataLeft() && !FlushBuffer() )
315 SetError(wxSTREAM_WRITE_ERROR
);
319 PutToBuffer(&c
, sizeof(c
));
320 m_stream
->m_lastcount
= 1;
325 char wxStreamBuffer::Peek()
327 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
328 _T("should have the stream and the buffer in wxStreamBuffer") );
330 if ( !GetDataLeft() )
332 SetError(wxSTREAM_READ_ERROR
);
337 GetFromBuffer(&c
, sizeof(c
));
343 char wxStreamBuffer::GetChar()
345 wxInputStream
*inStream
= GetInputStream();
347 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
352 inStream
->OnSysRead(&c
, sizeof(c
));
356 if ( !GetDataLeft() )
358 SetError(wxSTREAM_READ_ERROR
);
363 GetFromBuffer(&c
, sizeof(c
));
364 m_stream
->m_lastcount
= 1;
371 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
373 // lasterror is reset before all new IO calls
380 wxInputStream
*inStream
= GetInputStream();
382 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
384 readBytes
= inStream
->OnSysRead(buffer
, size
);
386 else // we have a buffer, use it
388 size_t orig_size
= size
;
392 size_t left
= GetDataLeft();
394 // if the requested number of bytes if greater than the buffer
395 // size, read data in chunks
398 GetFromBuffer(buffer
, left
);
400 buffer
= (char *)buffer
+ left
;
404 SetError(wxSTREAM_EOF
);
408 else // otherwise just do it in one gulp
410 GetFromBuffer(buffer
, size
);
415 readBytes
= orig_size
- size
;
419 m_stream
->m_lastcount
= readBytes
;
424 // this should really be called "Copy()"
425 size_t wxStreamBuffer::Read(wxStreamBuffer
*dbuf
)
427 wxCHECK_MSG( m_mode
!= write
, 0, _T("can't read from this buffer") );
429 char buf
[BUF_TEMP_SIZE
];
435 nRead
= Read(buf
, WXSIZEOF(buf
));
438 nRead
= dbuf
->Write(buf
, nRead
);
447 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
451 // lasterror is reset before all new IO calls
457 if ( !HasBuffer() && m_fixed
)
459 wxOutputStream
*outStream
= GetOutputStream();
461 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
463 // no buffer, just forward the call to the stream
464 ret
= 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)
483 if ( size
> left
&& m_fixed
)
485 PutToBuffer(buffer
, left
);
487 buffer
= (char *)buffer
+ left
;
489 if ( !FlushBuffer() )
491 SetError(wxSTREAM_WRITE_ERROR
);
496 m_buffer_pos
= m_buffer_start
;
498 else // we can do it in one gulp
500 PutToBuffer(buffer
, size
);
505 ret
= orig_size
- size
;
510 // i am not entirely sure what we do this for
511 m_stream
->m_lastcount
= ret
;
517 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
519 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
520 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
522 char buf
[BUF_TEMP_SIZE
];
528 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
531 nWrite
= Write(buf
, nRead
);
532 if ( nWrite
< nRead
)
534 // put back data we couldn't copy
535 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
537 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
547 while ( nWrite
== WXSIZEOF(buf
) );
552 wxFileOffset
wxStreamBuffer::Seek(wxFileOffset pos
, wxSeekMode mode
)
554 wxFileOffset ret_off
, diff
;
556 wxFileOffset last_access
= GetLastAccess();
567 diff
= pos
+ GetIntPosition();
571 diff
= pos
+ last_access
;
575 wxFAIL_MSG( _T("invalid seek mode") );
577 return wxInvalidOffset
;
579 if (diff
< 0 || diff
> last_access
)
580 return wxInvalidOffset
;
581 size_t int_diff
= wx_truncate_cast(size_t, diff
);
582 wxCHECK_MSG( (wxFileOffset
)int_diff
== diff
, wxInvalidOffset
, wxT("huge file not supported") );
583 SetIntPosition(int_diff
);
590 // We'll try to compute an internal position later ...
591 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
596 diff
= pos
+ GetIntPosition();
598 if ( (diff
> last_access
) || (diff
< 0) )
600 // We must take into account the fact that we have read
601 // something previously.
602 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
608 size_t int_diff
= wx_truncate_cast(size_t, diff
);
609 wxCHECK_MSG( (wxFileOffset
)int_diff
== diff
, wxInvalidOffset
, wxT("huge file not supported") );
610 SetIntPosition(int_diff
);
615 // Hard to compute: always seek to the requested position.
616 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
621 return wxInvalidOffset
;
624 wxFileOffset
wxStreamBuffer::Tell() const
628 // ask the stream for position if we have a real one
631 pos
= m_stream
->OnSysTell();
632 if ( pos
== wxInvalidOffset
)
633 return wxInvalidOffset
;
635 else // no associated stream
640 pos
+= GetIntPosition();
642 if ( m_mode
== read
&& m_flushable
)
643 pos
-= GetLastAccess();
648 // ----------------------------------------------------------------------------
650 // ----------------------------------------------------------------------------
652 wxStreamBase::wxStreamBase()
654 m_lasterror
= wxSTREAM_NO_ERROR
;
658 wxStreamBase::~wxStreamBase()
662 size_t wxStreamBase::GetSize() const
664 wxFileOffset length
= GetLength();
665 if ( length
== wxInvalidOffset
)
668 const size_t len
= wx_truncate_cast(size_t, length
);
669 wxASSERT_MSG( len
== length
+ size_t(0), _T("large files not supported") );
674 wxFileOffset
wxStreamBase::OnSysSeek(wxFileOffset
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
676 return wxInvalidOffset
;
679 wxFileOffset
wxStreamBase::OnSysTell() const
681 return wxInvalidOffset
;
684 // ----------------------------------------------------------------------------
686 // ----------------------------------------------------------------------------
688 wxInputStream::wxInputStream()
695 wxInputStream::~wxInputStream()
700 bool wxInputStream::CanRead() const
702 // we don't know if there is anything to read or not and by default we
703 // prefer to be optimistic and try to read data unless we know for sure
704 // there is no more of it
705 return m_lasterror
!= wxSTREAM_EOF
;
708 bool wxInputStream::Eof() const
710 // the only way the base class can know we're at EOF is when we'd already
711 // tried to read beyond it in which case last error is set accordingly
712 return GetLastError() == wxSTREAM_EOF
;
715 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
717 // get number of bytes left from previous wback buffer
718 size_t toget
= m_wbacksize
- m_wbackcur
;
720 // allocate a buffer large enough to hold prev + new data
721 char *temp_b
= (char *)malloc(needed_size
+ toget
);
726 // copy previous data (and free old buffer) if needed
729 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
736 m_wbacksize
= needed_size
+ toget
;
741 size_t wxInputStream::GetWBack(void *buf
, size_t size
)
746 // how many bytes do we have in the buffer?
747 size_t toget
= m_wbacksize
- m_wbackcur
;
751 // we won't read everything
755 // copy the data from the cache
756 memcpy(buf
, m_wback
+ m_wbackcur
, toget
);
759 if ( m_wbackcur
== m_wbacksize
)
761 // TODO: should we really free it here all the time? maybe keep it?
768 // return the number of bytes copied
772 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
774 if ( m_lasterror
!= wxSTREAM_NO_ERROR
&& m_lasterror
!= wxSTREAM_EOF
)
776 // can't operate on this stream until the error is cleared
780 char *ptrback
= AllocSpaceWBack(bufsize
);
784 // Eof() shouldn't return true any longer
785 if ( m_lasterror
== wxSTREAM_EOF
)
786 m_lasterror
= wxSTREAM_NO_ERROR
;
788 memcpy(ptrback
, buf
, bufsize
);
792 bool wxInputStream::Ungetch(char c
)
794 return Ungetch(&c
, sizeof(c
)) != 0;
797 char wxInputStream::GetC()
804 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
806 char *p
= (char *)buf
;
809 size_t read
= GetWBack(buf
, size
);
818 // we read the requested amount of data
822 if ( p
!= buf
&& !CanRead() )
824 // we have already read something and we would block in OnSysRead()
825 // now: don't do it but return immediately
829 read
= OnSysRead(p
, size
);
832 // no more data available
840 char wxInputStream::Peek()
844 if (m_lasterror
== wxSTREAM_NO_ERROR
)
853 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
855 char buf
[BUF_TEMP_SIZE
];
859 size_t bytes_read
= Read(buf
, WXSIZEOF(buf
)).LastRead();
863 if ( stream_out
.Write(buf
, bytes_read
).LastWrite() != bytes_read
)
870 wxFileOffset
wxInputStream::SeekI(wxFileOffset pos
, wxSeekMode mode
)
872 // RR: This code is duplicated in wxBufferedInputStream. This is
873 // not really a good design, but buffered stream are different
874 // from all other in that they handle two stream-related objects,
875 // the stream buffer and parent stream.
877 // I don't know whether it should be put as well in wxFileInputStream::OnSysSeek
878 if (m_lasterror
==wxSTREAM_EOF
)
879 m_lasterror
=wxSTREAM_NO_ERROR
;
881 /* RR: A call to SeekI() will automatically invalidate any previous
882 call to Ungetch(), otherwise it would be possible to SeekI() to
883 one position, unread some bytes there, SeekI() to another position
884 and the data would be corrupted.
886 GRG: Could add code here to try to navigate within the wback
887 buffer if possible, but is it really needed? It would only work
888 when seeking in wxFromCurrent mode, else it would invalidate
893 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
901 return OnSysSeek(pos
, mode
);
904 wxFileOffset
wxInputStream::TellI() const
906 wxFileOffset pos
= OnSysTell();
908 if (pos
!= wxInvalidOffset
)
909 pos
-= (m_wbacksize
- m_wbackcur
);
915 // ----------------------------------------------------------------------------
917 // ----------------------------------------------------------------------------
919 wxOutputStream::wxOutputStream()
923 wxOutputStream::~wxOutputStream()
927 size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer
),
928 size_t WXUNUSED(bufsize
))
933 void wxOutputStream::PutC(char c
)
935 Write(&c
, sizeof(c
));
938 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
940 m_lastcount
= OnSysWrite(buffer
, size
);
944 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
946 stream_in
.Read(*this);
950 wxFileOffset
wxOutputStream::TellO() const
955 wxFileOffset
wxOutputStream::SeekO(wxFileOffset pos
, wxSeekMode mode
)
957 return OnSysSeek(pos
, mode
);
960 void wxOutputStream::Sync()
965 // ----------------------------------------------------------------------------
966 // wxCountingOutputStream
967 // ----------------------------------------------------------------------------
969 wxCountingOutputStream::wxCountingOutputStream ()
974 wxFileOffset
wxCountingOutputStream::GetLength() const
979 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
982 m_currentPos
+= size
;
983 if (m_currentPos
> m_lastcount
)
984 m_lastcount
= m_currentPos
;
989 wxFileOffset
wxCountingOutputStream::OnSysSeek(wxFileOffset pos
, wxSeekMode mode
)
991 ssize_t new_pos
= wx_truncate_cast(ssize_t
, pos
);
996 wxCHECK_MSG( (wxFileOffset
)new_pos
== pos
, wxInvalidOffset
, wxT("huge position not supported") );
1000 new_pos
= m_lastcount
+ new_pos
;
1001 wxCHECK_MSG( (wxFileOffset
)new_pos
== (wxFileOffset
)(m_lastcount
+ pos
), wxInvalidOffset
, wxT("huge position not supported") );
1005 new_pos
= m_currentPos
+ new_pos
;
1006 wxCHECK_MSG( (wxFileOffset
)new_pos
== (wxFileOffset
)(m_currentPos
+ pos
), wxInvalidOffset
, wxT("huge position not supported") );
1010 wxFAIL_MSG( _T("invalid seek mode") );
1011 return wxInvalidOffset
;
1014 m_currentPos
= new_pos
;
1016 if (m_currentPos
> m_lastcount
)
1017 m_lastcount
= m_currentPos
;
1019 return m_currentPos
;
1022 wxFileOffset
wxCountingOutputStream::OnSysTell() const
1024 return m_currentPos
;
1027 // ----------------------------------------------------------------------------
1028 // wxFilterInputStream
1029 // ----------------------------------------------------------------------------
1031 wxFilterInputStream::wxFilterInputStream()
1033 m_parent_i_stream
= NULL
;
1036 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
1038 m_parent_i_stream
= &stream
;
1041 wxFilterInputStream::~wxFilterInputStream()
1045 // ----------------------------------------------------------------------------
1046 // wxFilterOutputStream
1047 // ----------------------------------------------------------------------------
1049 wxFilterOutputStream::wxFilterOutputStream()
1051 m_parent_o_stream
= NULL
;
1054 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
1056 m_parent_o_stream
= &stream
;
1059 wxFilterOutputStream::~wxFilterOutputStream()
1063 // ----------------------------------------------------------------------------
1064 // wxBufferedInputStream
1065 // ----------------------------------------------------------------------------
1067 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1068 wxStreamBuffer
*buffer
)
1069 : wxFilterInputStream(s
)
1073 // use the buffer provided by the user
1074 m_i_streambuf
= buffer
;
1076 else // create a default buffer
1078 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1080 m_i_streambuf
->SetBufferIO(1024);
1084 wxBufferedInputStream::~wxBufferedInputStream()
1086 m_parent_i_stream
->SeekI(-(wxFileOffset
)m_i_streambuf
->GetBytesLeft(),
1089 delete m_i_streambuf
;
1092 char wxBufferedInputStream::Peek()
1094 return m_i_streambuf
->Peek();
1097 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1099 // reset the error flag
1102 // first read from the already cached data
1103 m_lastcount
= GetWBack(buf
, size
);
1105 // do we have to read anything more?
1106 if ( m_lastcount
< size
)
1108 size
-= m_lastcount
;
1109 buf
= (char *)buf
+ m_lastcount
;
1111 // the call to wxStreamBuffer::Read() below will reset our m_lastcount,
1113 size_t countOld
= m_lastcount
;
1115 m_i_streambuf
->Read(buf
, size
);
1117 m_lastcount
+= countOld
;
1123 wxFileOffset
wxBufferedInputStream::SeekI(wxFileOffset pos
, wxSeekMode mode
)
1125 // RR: Look at wxInputStream for comments.
1127 if (m_lasterror
==wxSTREAM_EOF
)
1132 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
1140 return m_i_streambuf
->Seek(pos
, mode
);
1143 wxFileOffset
wxBufferedInputStream::TellI() const
1145 wxFileOffset pos
= m_i_streambuf
->Tell();
1147 if (pos
!= wxInvalidOffset
)
1148 pos
-= (m_wbacksize
- m_wbackcur
);
1153 size_t wxBufferedInputStream::OnSysRead(void *buffer
, size_t bufsize
)
1155 return m_parent_i_stream
->Read(buffer
, bufsize
).LastRead();
1158 wxFileOffset
wxBufferedInputStream::OnSysSeek(wxFileOffset seek
, wxSeekMode mode
)
1160 return m_parent_i_stream
->SeekI(seek
, mode
);
1163 wxFileOffset
wxBufferedInputStream::OnSysTell() const
1165 return m_parent_i_stream
->TellI();
1168 void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer
*buffer
)
1170 wxCHECK_RET( buffer
, _T("wxBufferedInputStream needs buffer") );
1172 delete m_i_streambuf
;
1173 m_i_streambuf
= buffer
;
1176 // ----------------------------------------------------------------------------
1177 // wxBufferedOutputStream
1178 // ----------------------------------------------------------------------------
1180 wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream
& s
,
1181 wxStreamBuffer
*buffer
)
1182 : wxFilterOutputStream(s
)
1186 m_o_streambuf
= buffer
;
1188 else // create a default one
1190 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
1192 m_o_streambuf
->SetBufferIO(1024);
1196 wxBufferedOutputStream::~wxBufferedOutputStream()
1199 delete m_o_streambuf
;
1202 bool wxBufferedOutputStream::Close()
1209 wxOutputStream
& wxBufferedOutputStream::Write(const void *buffer
, size_t size
)
1212 m_o_streambuf
->Write(buffer
, size
);
1216 wxFileOffset
wxBufferedOutputStream::SeekO(wxFileOffset pos
, wxSeekMode mode
)
1219 return m_o_streambuf
->Seek(pos
, mode
);
1222 wxFileOffset
wxBufferedOutputStream::TellO() const
1224 return m_o_streambuf
->Tell();
1227 void wxBufferedOutputStream::Sync()
1229 m_o_streambuf
->FlushBuffer();
1230 m_parent_o_stream
->Sync();
1233 size_t wxBufferedOutputStream::OnSysWrite(const void *buffer
, size_t bufsize
)
1235 return m_parent_o_stream
->Write(buffer
, bufsize
).LastWrite();
1238 wxFileOffset
wxBufferedOutputStream::OnSysSeek(wxFileOffset seek
, wxSeekMode mode
)
1240 return m_parent_o_stream
->SeekO(seek
, mode
);
1243 wxFileOffset
wxBufferedOutputStream::OnSysTell() const
1245 return m_parent_o_stream
->TellO();
1248 wxFileOffset
wxBufferedOutputStream::GetLength() const
1250 return m_parent_o_stream
->GetLength() + m_o_streambuf
->GetIntPosition();
1253 void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer
*buffer
)
1255 wxCHECK_RET( buffer
, _T("wxBufferedOutputStream needs buffer") );
1257 delete m_o_streambuf
;
1258 m_o_streambuf
= buffer
;
1261 // ----------------------------------------------------------------------------
1262 // Some IOManip function
1263 // ----------------------------------------------------------------------------
1265 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
1267 static const wxChar
*eol
= wxTextFile::GetEOL();
1269 return stream
.Write(eol
, wxStrlen(eol
));
1272 #endif // wxUSE_STREAMS