]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stream.cpp
271f7490ae38c0a2c6538d5505eecb131eb41f40
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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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 4096
51 // ============================================================================
53 // ============================================================================
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 void wxStreamBuffer::SetError(wxStreamError err
)
61 if ( m_stream
&& m_stream
->m_lasterror
== wxSTREAM_NO_ERROR
)
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(BufMode mode
)
93 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
103 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
105 // doing this has big chances to lead to a crash when the source buffer is
106 // destroyed (otherwise assume the caller knows what he does)
107 wxASSERT_MSG( !buffer
.m_destroybuf
,
108 _T("it's a bad idea to copy this buffer") );
110 m_buffer_start
= buffer
.m_buffer_start
;
111 m_buffer_end
= buffer
.m_buffer_end
;
112 m_buffer_pos
= buffer
.m_buffer_pos
;
113 m_buffer_size
= buffer
.m_buffer_size
;
114 m_fixed
= buffer
.m_fixed
;
115 m_flushable
= buffer
.m_flushable
;
116 m_stream
= buffer
.m_stream
;
117 m_mode
= buffer
.m_mode
;
118 m_destroybuf
= false;
121 void wxStreamBuffer::FreeBuffer()
124 free(m_buffer_start
);
127 wxStreamBuffer::~wxStreamBuffer()
132 wxInputStream
*wxStreamBuffer::GetInputStream() const
134 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
137 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
139 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
142 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
146 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
150 void wxStreamBuffer::SetBufferIO(void *start
,
154 // start by freeing the old buffer
157 m_buffer_start
= (char *)start
;
158 m_buffer_end
= m_buffer_start
+ len
;
162 // if we own it, we free it
163 m_destroybuf
= takeOwnership
;
168 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
170 // start by freeing the old buffer
175 SetBufferIO(malloc(bufsize
), bufsize
, true /* take ownership */);
177 else // no buffer size => no buffer
183 void wxStreamBuffer::ResetBuffer()
188 m_stream
->m_lastcount
= 0;
191 m_buffer_pos
= m_mode
== read
&& m_flushable
196 // fill the buffer with as much data as possible (only for read buffers)
197 bool wxStreamBuffer::FillBuffer()
199 wxInputStream
*inStream
= GetInputStream();
201 // It's legal to have no stream, so we don't complain about it just return false
205 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
209 m_buffer_end
= m_buffer_start
+ count
;
210 m_buffer_pos
= m_buffer_start
;
215 // write the buffer contents to the stream (only for write buffers)
216 bool wxStreamBuffer::FlushBuffer()
218 wxCHECK_MSG( m_flushable
, false, _T("can't flush this buffer") );
220 // FIXME: what is this check for? (VZ)
221 if ( m_buffer_pos
== m_buffer_start
)
224 wxOutputStream
*outStream
= GetOutputStream();
226 wxCHECK_MSG( outStream
, false, _T("should have a stream in wxStreamBuffer") );
228 size_t current
= m_buffer_pos
- m_buffer_start
;
229 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
230 if ( count
!= current
)
233 m_buffer_pos
= m_buffer_start
;
238 size_t wxStreamBuffer::GetDataLeft()
240 /* Why is this done? RR. */
241 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
244 return GetBytesLeft();
247 // copy up to size bytes from our buffer into the provided one
248 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
250 // don't get more bytes than left in the buffer
251 size_t left
= GetBytesLeft();
256 memcpy(buffer
, m_buffer_pos
, size
);
257 m_buffer_pos
+= size
;
260 // copy the contents of the provided buffer into this one
261 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
263 size_t left
= GetBytesLeft();
269 // we can't realloc the buffer, so just copy what we can
274 // realloc the buffer to have enough space for the data
275 size_t delta
= m_buffer_pos
- m_buffer_start
;
277 char *startOld
= m_buffer_start
;
278 m_buffer_size
+= size
;
279 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
280 if ( !m_buffer_start
)
282 // don't leak memory if realloc() failed
283 m_buffer_start
= startOld
;
284 m_buffer_size
-= size
;
286 // what else can we do?
290 // adjust the pointers invalidated by realloc()
291 m_buffer_pos
= m_buffer_start
+ delta
;
292 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
296 memcpy(m_buffer_pos
, buffer
, size
);
297 m_buffer_pos
+= size
;
300 void wxStreamBuffer::PutChar(char c
)
302 wxOutputStream
*outStream
= GetOutputStream();
304 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
306 // if we don't have buffer at all, just forward this call to the stream,
309 outStream
->OnSysWrite(&c
, sizeof(c
));
313 // otherwise check we have enough space left
314 if ( !GetDataLeft() && !FlushBuffer() )
317 SetError(wxSTREAM_WRITE_ERROR
);
321 PutToBuffer(&c
, sizeof(c
));
322 m_stream
->m_lastcount
= 1;
327 char wxStreamBuffer::Peek()
329 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
330 _T("should have the stream and the buffer in wxStreamBuffer") );
332 if ( !GetDataLeft() )
334 SetError(wxSTREAM_READ_ERROR
);
339 GetFromBuffer(&c
, sizeof(c
));
345 char wxStreamBuffer::GetChar()
347 wxInputStream
*inStream
= GetInputStream();
349 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
354 inStream
->OnSysRead(&c
, sizeof(c
));
358 if ( !GetDataLeft() )
360 SetError(wxSTREAM_READ_ERROR
);
365 GetFromBuffer(&c
, sizeof(c
));
366 m_stream
->m_lastcount
= 1;
373 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
375 // lasterror is reset before all new IO calls
382 wxInputStream
*inStream
= GetInputStream();
384 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
386 read
= 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 read
= orig_size
- size
;
421 m_stream
->m_lastcount
= read
;
426 // this should really be called "Copy()"
427 size_t wxStreamBuffer::Read(wxStreamBuffer
*dbuf
)
429 wxCHECK_MSG( m_mode
!= write
, 0, _T("can't read from this buffer") );
431 char buf
[BUF_TEMP_SIZE
];
437 nRead
= Read(dbuf
, WXSIZEOF(buf
));
440 nRead
= dbuf
->Write(buf
, nRead
);
449 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
453 // lasterror is reset before all new IO calls
459 if ( !HasBuffer() && m_fixed
)
461 wxOutputStream
*outStream
= GetOutputStream();
463 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
465 // no buffer, just forward the call to the stream
466 ret
= outStream
->OnSysWrite(buffer
, size
);
468 else // we [may] have a buffer, use it
470 size_t orig_size
= size
;
474 size_t left
= GetBytesLeft();
476 // if the buffer is too large to fit in the stream buffer, split
477 // it in smaller parts
479 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
480 // we always go to the second case.
482 // FIXME: fine, but if it fails we should (re)try writing it by
483 // chunks as this will (hopefully) always work (VZ)
485 if ( size
> left
&& m_fixed
)
487 PutToBuffer(buffer
, left
);
489 buffer
= (char *)buffer
+ left
;
491 if ( !FlushBuffer() )
493 SetError(wxSTREAM_WRITE_ERROR
);
498 m_buffer_pos
= m_buffer_start
;
500 else // we can do it in one gulp
502 PutToBuffer(buffer
, size
);
507 ret
= orig_size
- size
;
512 // i am not entirely sure what we do this for
513 m_stream
->m_lastcount
= ret
;
519 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
521 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
522 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
524 char buf
[BUF_TEMP_SIZE
];
530 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
533 nWrite
= Write(buf
, nRead
);
534 if ( nWrite
< nRead
)
536 // put back data we couldn't copy
537 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
539 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
549 while ( nWrite
== WXSIZEOF(buf
) );
554 wxFileOffset
wxStreamBuffer::Seek(wxFileOffset pos
, wxSeekMode mode
)
556 wxFileOffset ret_off
, diff
;
558 wxFileOffset last_access
= GetLastAccess();
569 diff
= pos
+ GetIntPosition();
573 diff
= pos
+ last_access
;
577 wxFAIL_MSG( _T("invalid seek mode") );
579 return wxInvalidOffset
;
581 if (diff
< 0 || diff
> last_access
)
582 return wxInvalidOffset
;
583 size_t int_diff
= (size_t)diff
;
584 wxCHECK_MSG( (wxFileOffset
)int_diff
== diff
, wxInvalidOffset
, wxT("huge file not supported") );
585 SetIntPosition(int_diff
);
592 // We'll try to compute an internal position later ...
593 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
598 diff
= pos
+ GetIntPosition();
600 if ( (diff
> last_access
) || (diff
< 0) )
602 // We must take into account the fact that we have read
603 // something previously.
604 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
610 size_t int_diff
= (size_t)diff
;
611 wxCHECK_MSG( (wxFileOffset
)int_diff
== diff
, wxInvalidOffset
, wxT("huge file not supported") );
612 SetIntPosition(int_diff
);
617 // Hard to compute: always seek to the requested position.
618 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
623 return wxInvalidOffset
;
626 wxFileOffset
wxStreamBuffer::Tell() const
630 // ask the stream for position if we have a real one
633 pos
= m_stream
->OnSysTell();
634 if ( pos
== wxInvalidOffset
)
635 return wxInvalidOffset
;
637 else // no associated stream
642 pos
+= GetIntPosition();
644 if ( m_mode
== read
&& m_flushable
)
645 pos
-= GetLastAccess();
650 // ----------------------------------------------------------------------------
652 // ----------------------------------------------------------------------------
654 wxStreamBase::wxStreamBase()
656 m_lasterror
= wxSTREAM_NO_ERROR
;
660 wxStreamBase::~wxStreamBase()
664 size_t wxStreamBase::GetSize() const
666 wxFileOffset length
= GetLength();
667 return length
== wxInvalidOffset
? 0 : (size_t)length
;
670 wxFileOffset
wxStreamBase::OnSysSeek(wxFileOffset
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
672 return wxInvalidOffset
;
675 wxFileOffset
wxStreamBase::OnSysTell() const
677 return wxInvalidOffset
;
680 #if WXWIN_COMPATIBILITY_2_2
682 wxStreamError
wxStreamBase::LastError() const
687 size_t wxStreamBase::StreamSize() const
692 #endif // WXWIN_COMPATIBILITY_2_2
694 // ----------------------------------------------------------------------------
696 // ----------------------------------------------------------------------------
698 wxInputStream::wxInputStream()
705 wxInputStream::~wxInputStream()
710 bool wxInputStream::CanRead() const
712 // we don't know if there is anything to read or not and by default we
713 // prefer to be optimistic and try to read data unless we know for sure
714 // there is no more of it
715 return m_lasterror
!= wxSTREAM_EOF
;
718 bool wxInputStream::Eof() const
720 // the only way the base class can know we're at EOF is when we'd already
721 // tried to read beyond it in which case last error is set accordingly
722 return GetLastError() == wxSTREAM_EOF
;
725 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
727 // get number of bytes left from previous wback buffer
728 size_t toget
= m_wbacksize
- m_wbackcur
;
730 // allocate a buffer large enough to hold prev + new data
731 char *temp_b
= (char *)malloc(needed_size
+ toget
);
736 // copy previous data (and free old buffer) if needed
739 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
746 m_wbacksize
= needed_size
+ toget
;
751 size_t wxInputStream::GetWBack(void *buf
, size_t size
)
756 // how many bytes do we have in the buffer?
757 size_t toget
= m_wbacksize
- m_wbackcur
;
761 // we won't read everything
765 // copy the data from the cache
766 memcpy(buf
, m_wback
+ m_wbackcur
, toget
);
769 if ( m_wbackcur
== m_wbacksize
)
771 // TODO: should we really free it here all the time? maybe keep it?
778 // return the number of bytes copied
782 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
784 if ( m_lasterror
!= wxSTREAM_NO_ERROR
&& m_lasterror
!= wxSTREAM_EOF
)
786 // can't operate on this stream until the error is cleared
790 char *ptrback
= AllocSpaceWBack(bufsize
);
794 // Eof() shouldn't return true any longer
795 if ( m_lasterror
== wxSTREAM_EOF
)
796 m_lasterror
= wxSTREAM_NO_ERROR
;
798 memcpy(ptrback
, buf
, bufsize
);
802 bool wxInputStream::Ungetch(char c
)
804 return Ungetch(&c
, sizeof(c
)) != 0;
807 char wxInputStream::GetC()
814 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
816 char *p
= (char *)buf
;
819 size_t read
= GetWBack(buf
, size
);
828 // we read the requested amount of data
832 if ( p
!= buf
&& !CanRead() )
834 // we have already read something and we would block in OnSysRead()
835 // now: don't do it but return immediately
839 read
= OnSysRead(p
, size
);
842 // no more data available
850 char wxInputStream::Peek()
854 if (m_lasterror
== wxSTREAM_NO_ERROR
)
863 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
865 char buf
[BUF_TEMP_SIZE
];
869 size_t bytes_read
= Read(buf
, WXSIZEOF(buf
)).LastRead();
873 if ( stream_out
.Write(buf
, bytes_read
).LastWrite() != bytes_read
)
880 wxFileOffset
wxInputStream::SeekI(wxFileOffset pos
, wxSeekMode mode
)
882 // RR: This code is duplicated in wxBufferedInputStream. This is
883 // not really a good design, but buffered stream are different
884 // from all other in that they handle two stream-related objects,
885 // the stream buffer and parent stream.
887 // I don't know whether it should be put as well in wxFileInputStream::OnSysSeek
888 if (m_lasterror
==wxSTREAM_EOF
)
889 m_lasterror
=wxSTREAM_NO_ERROR
;
891 /* RR: A call to SeekI() will automatically invalidate any previous
892 call to Ungetch(), otherwise it would be possible to SeekI() to
893 one position, unread some bytes there, SeekI() to another position
894 and the data would be corrupted.
896 GRG: Could add code here to try to navigate within the wback
897 buffer if possible, but is it really needed? It would only work
898 when seeking in wxFromCurrent mode, else it would invalidate
903 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
911 return OnSysSeek(pos
, mode
);
914 wxFileOffset
wxInputStream::TellI() const
916 wxFileOffset pos
= OnSysTell();
918 if (pos
!= wxInvalidOffset
)
919 pos
-= (m_wbacksize
- m_wbackcur
);
925 // ----------------------------------------------------------------------------
927 // ----------------------------------------------------------------------------
929 wxOutputStream::wxOutputStream()
933 wxOutputStream::~wxOutputStream()
937 size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer
),
938 size_t WXUNUSED(bufsize
))
943 void wxOutputStream::PutC(char c
)
945 Write(&c
, sizeof(c
));
948 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
950 m_lastcount
= OnSysWrite(buffer
, size
);
954 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
956 stream_in
.Read(*this);
960 wxFileOffset
wxOutputStream::TellO() const
965 wxFileOffset
wxOutputStream::SeekO(wxFileOffset pos
, wxSeekMode mode
)
967 return OnSysSeek(pos
, mode
);
970 void wxOutputStream::Sync()
975 // ----------------------------------------------------------------------------
976 // wxCountingOutputStream
977 // ----------------------------------------------------------------------------
979 wxCountingOutputStream::wxCountingOutputStream ()
984 wxFileOffset
wxCountingOutputStream::GetLength() const
989 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
992 m_currentPos
+= size
;
993 if (m_currentPos
> m_lastcount
)
994 m_lastcount
= m_currentPos
;
999 wxFileOffset
wxCountingOutputStream::OnSysSeek(wxFileOffset pos
, wxSeekMode mode
)
1001 ssize_t new_pos
= (ssize_t
)pos
;
1006 wxCHECK_MSG( (wxFileOffset
)new_pos
== pos
, wxInvalidOffset
, wxT("huge position not supported") );
1010 new_pos
= m_lastcount
+ new_pos
;
1011 wxCHECK_MSG( (wxFileOffset
)new_pos
== (wxFileOffset
)(m_lastcount
+ pos
), wxInvalidOffset
, wxT("huge position not supported") );
1015 new_pos
= m_currentPos
+ new_pos
;
1016 wxCHECK_MSG( (wxFileOffset
)new_pos
== (wxFileOffset
)(m_currentPos
+ pos
), wxInvalidOffset
, wxT("huge position not supported") );
1020 wxFAIL_MSG( _T("invalid seek mode") );
1021 return wxInvalidOffset
;
1024 m_currentPos
= new_pos
;
1026 if (m_currentPos
> m_lastcount
)
1027 m_lastcount
= m_currentPos
;
1029 return m_currentPos
;
1032 wxFileOffset
wxCountingOutputStream::OnSysTell() const
1034 return m_currentPos
;
1037 // ----------------------------------------------------------------------------
1038 // wxFilterInputStream
1039 // ----------------------------------------------------------------------------
1041 wxFilterInputStream::wxFilterInputStream()
1043 m_parent_i_stream
= NULL
;
1046 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
1048 m_parent_i_stream
= &stream
;
1051 wxFilterInputStream::~wxFilterInputStream()
1055 // ----------------------------------------------------------------------------
1056 // wxFilterOutputStream
1057 // ----------------------------------------------------------------------------
1059 wxFilterOutputStream::wxFilterOutputStream()
1061 m_parent_o_stream
= NULL
;
1064 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
1066 m_parent_o_stream
= &stream
;
1069 wxFilterOutputStream::~wxFilterOutputStream()
1073 // ----------------------------------------------------------------------------
1074 // wxBufferedInputStream
1075 // ----------------------------------------------------------------------------
1077 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1078 wxStreamBuffer
*buffer
)
1079 : wxFilterInputStream(s
)
1083 // use the buffer provided by the user
1084 m_i_streambuf
= buffer
;
1086 else // create a default buffer
1088 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1090 m_i_streambuf
->SetBufferIO(1024);
1094 wxBufferedInputStream::~wxBufferedInputStream()
1096 m_parent_i_stream
->SeekI(-(wxFileOffset
)m_i_streambuf
->GetBytesLeft(),
1099 delete m_i_streambuf
;
1102 char wxBufferedInputStream::Peek()
1104 return m_i_streambuf
->Peek();
1107 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1109 // reset the error flag
1112 // first read from the already cached data
1113 m_lastcount
= GetWBack(buf
, size
);
1115 // do we have to read anything more?
1116 if ( m_lastcount
< size
)
1118 size
-= m_lastcount
;
1119 buf
= (char *)buf
+ m_lastcount
;
1121 // the call to wxStreamBuffer::Read() below will reset our m_lastcount,
1123 size_t countOld
= m_lastcount
;
1125 m_i_streambuf
->Read(buf
, size
);
1127 m_lastcount
+= countOld
;
1133 wxFileOffset
wxBufferedInputStream::SeekI(wxFileOffset pos
, wxSeekMode mode
)
1135 // RR: Look at wxInputStream for comments.
1137 if (m_lasterror
==wxSTREAM_EOF
)
1142 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
1150 return m_i_streambuf
->Seek(pos
, mode
);
1153 wxFileOffset
wxBufferedInputStream::TellI() const
1155 wxFileOffset pos
= m_i_streambuf
->Tell();
1157 if (pos
!= wxInvalidOffset
)
1158 pos
-= (m_wbacksize
- m_wbackcur
);
1163 size_t wxBufferedInputStream::OnSysRead(void *buffer
, size_t bufsize
)
1165 return m_parent_i_stream
->Read(buffer
, bufsize
).LastRead();
1168 wxFileOffset
wxBufferedInputStream::OnSysSeek(wxFileOffset seek
, wxSeekMode mode
)
1170 return m_parent_i_stream
->SeekI(seek
, mode
);
1173 wxFileOffset
wxBufferedInputStream::OnSysTell() const
1175 return m_parent_i_stream
->TellI();
1178 void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer
*buffer
)
1180 wxCHECK_RET( buffer
, _T("wxBufferedInputStream needs buffer") );
1182 delete m_i_streambuf
;
1183 m_i_streambuf
= buffer
;
1186 // ----------------------------------------------------------------------------
1187 // wxBufferedOutputStream
1188 // ----------------------------------------------------------------------------
1190 wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream
& s
,
1191 wxStreamBuffer
*buffer
)
1192 : wxFilterOutputStream(s
)
1196 m_o_streambuf
= buffer
;
1198 else // create a default one
1200 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
1202 m_o_streambuf
->SetBufferIO(1024);
1206 wxBufferedOutputStream::~wxBufferedOutputStream()
1209 delete m_o_streambuf
;
1212 bool wxBufferedOutputStream::Close()
1219 wxOutputStream
& wxBufferedOutputStream::Write(const void *buffer
, size_t size
)
1222 m_o_streambuf
->Write(buffer
, size
);
1226 wxFileOffset
wxBufferedOutputStream::SeekO(wxFileOffset pos
, wxSeekMode mode
)
1229 return m_o_streambuf
->Seek(pos
, mode
);
1232 wxFileOffset
wxBufferedOutputStream::TellO() const
1234 return m_o_streambuf
->Tell();
1237 void wxBufferedOutputStream::Sync()
1239 m_o_streambuf
->FlushBuffer();
1240 m_parent_o_stream
->Sync();
1243 size_t wxBufferedOutputStream::OnSysWrite(const void *buffer
, size_t bufsize
)
1245 return m_parent_o_stream
->Write(buffer
, bufsize
).LastWrite();
1248 wxFileOffset
wxBufferedOutputStream::OnSysSeek(wxFileOffset seek
, wxSeekMode mode
)
1250 return m_parent_o_stream
->SeekO(seek
, mode
);
1253 wxFileOffset
wxBufferedOutputStream::OnSysTell() const
1255 return m_parent_o_stream
->TellO();
1258 wxFileOffset
wxBufferedOutputStream::GetLength() const
1260 return m_parent_o_stream
->GetLength() + m_o_streambuf
->GetIntPosition();
1263 void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer
*buffer
)
1265 wxCHECK_RET( buffer
, _T("wxBufferedOutputStream needs buffer") );
1267 delete m_o_streambuf
;
1268 m_o_streambuf
= buffer
;
1271 // ----------------------------------------------------------------------------
1272 // Some IOManip function
1273 // ----------------------------------------------------------------------------
1275 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
1277 static const wxChar
*eol
= wxTextFile::GetEOL();
1279 return stream
.Write(eol
, wxStrlen(eol
));