]>
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"
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 // the temporary buffer size used when copying from stream to stream
45 #define BUF_TEMP_SIZE 4096
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 void wxStreamBuffer::SetError(wxStreamError err
)
57 if ( m_stream
&& m_stream
->m_lasterror
== wxSTREAM_NO_ERROR
)
58 m_stream
->m_lasterror
= err
;
61 void wxStreamBuffer::InitBuffer()
68 // if we are going to allocate the buffer, we should free it later as well
72 void wxStreamBuffer::Init()
79 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
89 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
99 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
101 // doing this has big chances to lead to a crash when the source buffer is
102 // destroyed (otherwise assume the caller knows what he does)
103 wxASSERT_MSG( !buffer
.m_destroybuf
,
104 _T("it's a bad idea to copy this buffer") );
106 m_buffer_start
= buffer
.m_buffer_start
;
107 m_buffer_end
= buffer
.m_buffer_end
;
108 m_buffer_pos
= buffer
.m_buffer_pos
;
109 m_buffer_size
= buffer
.m_buffer_size
;
110 m_fixed
= buffer
.m_fixed
;
111 m_flushable
= buffer
.m_flushable
;
112 m_stream
= buffer
.m_stream
;
113 m_mode
= buffer
.m_mode
;
114 m_destroybuf
= false;
117 void wxStreamBuffer::FreeBuffer()
120 free(m_buffer_start
);
123 wxStreamBuffer::~wxStreamBuffer()
128 wxInputStream
*wxStreamBuffer::GetInputStream() const
130 return m_mode
== write
? NULL
: (wxInputStream
*)m_stream
;
133 wxOutputStream
*wxStreamBuffer::GetOutputStream() const
135 return m_mode
== read
? NULL
: (wxOutputStream
*)m_stream
;
138 void wxStreamBuffer::SetBufferIO(void *buffer_start
,
142 SetBufferIO(buffer_start
, (char *)buffer_end
- (char *)buffer_start
,
146 void wxStreamBuffer::SetBufferIO(void *start
,
150 // start by freeing the old buffer
153 m_buffer_start
= (char *)start
;
154 m_buffer_end
= m_buffer_start
+ len
;
158 // if we own it, we free it
159 m_destroybuf
= takeOwnership
;
164 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
166 // start by freeing the old buffer
171 SetBufferIO(malloc(bufsize
), bufsize
, true /* take ownership */);
173 else // no buffer size => no buffer
179 void wxStreamBuffer::ResetBuffer()
184 m_stream
->m_lastcount
= 0;
187 m_buffer_pos
= m_mode
== read
&& m_flushable
192 // fill the buffer with as much data as possible (only for read buffers)
193 bool wxStreamBuffer::FillBuffer()
195 wxInputStream
*inStream
= GetInputStream();
197 // It's legal to have no stream, so we don't complain about it just return false
201 size_t count
= inStream
->OnSysRead(m_buffer_start
, m_buffer_size
);
205 m_buffer_end
= m_buffer_start
+ count
;
206 m_buffer_pos
= m_buffer_start
;
211 // write the buffer contents to the stream (only for write buffers)
212 bool wxStreamBuffer::FlushBuffer()
214 wxCHECK_MSG( m_flushable
, false, _T("can't flush this buffer") );
216 // FIXME: what is this check for? (VZ)
217 if ( m_buffer_pos
== m_buffer_start
)
220 wxOutputStream
*outStream
= GetOutputStream();
222 wxCHECK_MSG( outStream
, false, _T("should have a stream in wxStreamBuffer") );
224 size_t current
= m_buffer_pos
- m_buffer_start
;
225 size_t count
= outStream
->OnSysWrite(m_buffer_start
, current
);
226 if ( count
!= current
)
229 m_buffer_pos
= m_buffer_start
;
234 size_t wxStreamBuffer::GetDataLeft()
236 /* Why is this done? RR. */
237 if ( m_buffer_pos
== m_buffer_end
&& m_flushable
)
240 return GetBytesLeft();
243 // copy up to size bytes from our buffer into the provided one
244 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
246 // don't get more bytes than left in the buffer
247 size_t left
= GetBytesLeft();
252 memcpy(buffer
, m_buffer_pos
, size
);
253 m_buffer_pos
+= size
;
256 // copy the contents of the provided buffer into this one
257 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
259 size_t left
= GetBytesLeft();
265 // we can't realloc the buffer, so just copy what we can
270 // realloc the buffer to have enough space for the data
271 size_t delta
= m_buffer_pos
- m_buffer_start
;
273 char *startOld
= m_buffer_start
;
274 m_buffer_size
+= size
;
275 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
);
276 if ( !m_buffer_start
)
278 // don't leak memory if realloc() failed
279 m_buffer_start
= startOld
;
280 m_buffer_size
-= size
;
282 // what else can we do?
286 // adjust the pointers invalidated by realloc()
287 m_buffer_pos
= m_buffer_start
+ delta
;
288 m_buffer_end
= m_buffer_start
+ m_buffer_size
;
292 memcpy(m_buffer_pos
, buffer
, size
);
293 m_buffer_pos
+= size
;
296 void wxStreamBuffer::PutChar(char c
)
298 wxOutputStream
*outStream
= GetOutputStream();
300 wxCHECK_RET( outStream
, _T("should have a stream in wxStreamBuffer") );
302 // if we don't have buffer at all, just forward this call to the stream,
305 outStream
->OnSysWrite(&c
, sizeof(c
));
309 // otherwise check we have enough space left
310 if ( !GetDataLeft() && !FlushBuffer() )
313 SetError(wxSTREAM_WRITE_ERROR
);
317 PutToBuffer(&c
, sizeof(c
));
318 m_stream
->m_lastcount
= 1;
323 char wxStreamBuffer::Peek()
325 wxCHECK_MSG( m_stream
&& HasBuffer(), 0,
326 _T("should have the stream and the buffer in wxStreamBuffer") );
328 if ( !GetDataLeft() )
330 SetError(wxSTREAM_READ_ERROR
);
335 GetFromBuffer(&c
, sizeof(c
));
341 char wxStreamBuffer::GetChar()
343 wxInputStream
*inStream
= GetInputStream();
345 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
350 inStream
->OnSysRead(&c
, sizeof(c
));
354 if ( !GetDataLeft() )
356 SetError(wxSTREAM_READ_ERROR
);
361 GetFromBuffer(&c
, sizeof(c
));
362 m_stream
->m_lastcount
= 1;
369 size_t wxStreamBuffer::Read(void *buffer
, size_t size
)
371 // lasterror is reset before all new IO calls
378 wxInputStream
*inStream
= GetInputStream();
380 wxCHECK_MSG( inStream
, 0, _T("should have a stream in wxStreamBuffer") );
382 readBytes
= inStream
->OnSysRead(buffer
, size
);
384 else // we have a buffer, use it
386 size_t orig_size
= size
;
390 size_t left
= GetDataLeft();
392 // if the requested number of bytes if greater than the buffer
393 // size, read data in chunks
396 GetFromBuffer(buffer
, left
);
398 buffer
= (char *)buffer
+ left
;
402 SetError(wxSTREAM_EOF
);
406 else // otherwise just do it in one gulp
408 GetFromBuffer(buffer
, size
);
413 readBytes
= orig_size
- size
;
417 m_stream
->m_lastcount
= readBytes
;
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(buf
, WXSIZEOF(buf
));
436 nRead
= dbuf
->Write(buf
, nRead
);
445 size_t wxStreamBuffer::Write(const void *buffer
, size_t size
)
449 // lasterror is reset before all new IO calls
455 if ( !HasBuffer() && m_fixed
)
457 wxOutputStream
*outStream
= GetOutputStream();
459 wxCHECK_MSG( outStream
, 0, _T("should have a stream in wxStreamBuffer") );
461 // no buffer, just forward the call to the stream
462 ret
= outStream
->OnSysWrite(buffer
, size
);
464 else // we [may] have a buffer, use it
466 size_t orig_size
= size
;
470 size_t left
= GetBytesLeft();
472 // if the buffer is too large to fit in the stream buffer, split
473 // it in smaller parts
475 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
476 // we always go to the second case.
478 // FIXME: fine, but if it fails we should (re)try writing it by
479 // chunks as this will (hopefully) always work (VZ)
481 if ( size
> left
&& m_fixed
)
483 PutToBuffer(buffer
, left
);
485 buffer
= (char *)buffer
+ left
;
487 if ( !FlushBuffer() )
489 SetError(wxSTREAM_WRITE_ERROR
);
494 m_buffer_pos
= m_buffer_start
;
496 else // we can do it in one gulp
498 PutToBuffer(buffer
, size
);
503 ret
= orig_size
- size
;
508 // i am not entirely sure what we do this for
509 m_stream
->m_lastcount
= ret
;
515 size_t wxStreamBuffer::Write(wxStreamBuffer
*sbuf
)
517 wxCHECK_MSG( m_mode
!= read
, 0, _T("can't write to this buffer") );
518 wxCHECK_MSG( sbuf
->m_mode
!= write
, 0, _T("can't read from that buffer") );
520 char buf
[BUF_TEMP_SIZE
];
526 size_t nRead
= sbuf
->Read(buf
, WXSIZEOF(buf
));
529 nWrite
= Write(buf
, nRead
);
530 if ( nWrite
< nRead
)
532 // put back data we couldn't copy
533 wxInputStream
*in_stream
= (wxInputStream
*)sbuf
->GetStream();
535 in_stream
->Ungetch(buf
+ nWrite
, nRead
- nWrite
);
545 while ( nWrite
== WXSIZEOF(buf
) );
550 wxFileOffset
wxStreamBuffer::Seek(wxFileOffset pos
, wxSeekMode mode
)
552 wxFileOffset ret_off
, diff
;
554 wxFileOffset last_access
= GetLastAccess();
565 diff
= pos
+ GetIntPosition();
569 diff
= pos
+ last_access
;
573 wxFAIL_MSG( _T("invalid seek mode") );
575 return wxInvalidOffset
;
577 if (diff
< 0 || diff
> last_access
)
578 return wxInvalidOffset
;
579 size_t int_diff
= wx_truncate_cast(size_t, diff
);
580 wxCHECK_MSG( (wxFileOffset
)int_diff
== diff
, wxInvalidOffset
, wxT("huge file not supported") );
581 SetIntPosition(int_diff
);
588 // We'll try to compute an internal position later ...
589 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
594 diff
= pos
+ GetIntPosition();
596 if ( (diff
> last_access
) || (diff
< 0) )
598 // We must take into account the fact that we have read
599 // something previously.
600 ret_off
= m_stream
->OnSysSeek(diff
-last_access
, wxFromCurrent
);
606 size_t int_diff
= wx_truncate_cast(size_t, diff
);
607 wxCHECK_MSG( (wxFileOffset
)int_diff
== diff
, wxInvalidOffset
, wxT("huge file not supported") );
608 SetIntPosition(int_diff
);
613 // Hard to compute: always seek to the requested position.
614 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
619 return wxInvalidOffset
;
622 wxFileOffset
wxStreamBuffer::Tell() const
626 // ask the stream for position if we have a real one
629 pos
= m_stream
->OnSysTell();
630 if ( pos
== wxInvalidOffset
)
631 return wxInvalidOffset
;
633 else // no associated stream
638 pos
+= GetIntPosition();
640 if ( m_mode
== read
&& m_flushable
)
641 pos
-= GetLastAccess();
646 // ----------------------------------------------------------------------------
648 // ----------------------------------------------------------------------------
650 wxStreamBase::wxStreamBase()
652 m_lasterror
= wxSTREAM_NO_ERROR
;
656 wxStreamBase::~wxStreamBase()
660 size_t wxStreamBase::GetSize() const
662 wxFileOffset length
= GetLength();
663 if ( length
== wxInvalidOffset
)
666 const size_t len
= wx_truncate_cast(size_t, length
);
667 wxASSERT_MSG( len
== length
, _T("large files not supported") );
672 wxFileOffset
wxStreamBase::OnSysSeek(wxFileOffset
WXUNUSED(seek
), wxSeekMode
WXUNUSED(mode
))
674 return wxInvalidOffset
;
677 wxFileOffset
wxStreamBase::OnSysTell() const
679 return wxInvalidOffset
;
682 #if WXWIN_COMPATIBILITY_2_2
684 wxStreamError
wxStreamBase::LastError() const
689 size_t wxStreamBase::StreamSize() const
694 #endif // WXWIN_COMPATIBILITY_2_2
696 // ----------------------------------------------------------------------------
698 // ----------------------------------------------------------------------------
700 wxInputStream::wxInputStream()
707 wxInputStream::~wxInputStream()
712 bool wxInputStream::CanRead() const
714 // we don't know if there is anything to read or not and by default we
715 // prefer to be optimistic and try to read data unless we know for sure
716 // there is no more of it
717 return m_lasterror
!= wxSTREAM_EOF
;
720 bool wxInputStream::Eof() const
722 // the only way the base class can know we're at EOF is when we'd already
723 // tried to read beyond it in which case last error is set accordingly
724 return GetLastError() == wxSTREAM_EOF
;
727 char *wxInputStream::AllocSpaceWBack(size_t needed_size
)
729 // get number of bytes left from previous wback buffer
730 size_t toget
= m_wbacksize
- m_wbackcur
;
732 // allocate a buffer large enough to hold prev + new data
733 char *temp_b
= (char *)malloc(needed_size
+ toget
);
738 // copy previous data (and free old buffer) if needed
741 memmove(temp_b
+ needed_size
, m_wback
+ m_wbackcur
, toget
);
748 m_wbacksize
= needed_size
+ toget
;
753 size_t wxInputStream::GetWBack(void *buf
, size_t size
)
758 // how many bytes do we have in the buffer?
759 size_t toget
= m_wbacksize
- m_wbackcur
;
763 // we won't read everything
767 // copy the data from the cache
768 memcpy(buf
, m_wback
+ m_wbackcur
, toget
);
771 if ( m_wbackcur
== m_wbacksize
)
773 // TODO: should we really free it here all the time? maybe keep it?
780 // return the number of bytes copied
784 size_t wxInputStream::Ungetch(const void *buf
, size_t bufsize
)
786 if ( m_lasterror
!= wxSTREAM_NO_ERROR
&& m_lasterror
!= wxSTREAM_EOF
)
788 // can't operate on this stream until the error is cleared
792 char *ptrback
= AllocSpaceWBack(bufsize
);
796 // Eof() shouldn't return true any longer
797 if ( m_lasterror
== wxSTREAM_EOF
)
798 m_lasterror
= wxSTREAM_NO_ERROR
;
800 memcpy(ptrback
, buf
, bufsize
);
804 bool wxInputStream::Ungetch(char c
)
806 return Ungetch(&c
, sizeof(c
)) != 0;
809 char wxInputStream::GetC()
816 wxInputStream
& wxInputStream::Read(void *buf
, size_t size
)
818 char *p
= (char *)buf
;
821 size_t read
= GetWBack(buf
, size
);
830 // we read the requested amount of data
834 if ( p
!= buf
&& !CanRead() )
836 // we have already read something and we would block in OnSysRead()
837 // now: don't do it but return immediately
841 read
= OnSysRead(p
, size
);
844 // no more data available
852 char wxInputStream::Peek()
856 if (m_lasterror
== wxSTREAM_NO_ERROR
)
865 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
867 char buf
[BUF_TEMP_SIZE
];
871 size_t bytes_read
= Read(buf
, WXSIZEOF(buf
)).LastRead();
875 if ( stream_out
.Write(buf
, bytes_read
).LastWrite() != bytes_read
)
882 wxFileOffset
wxInputStream::SeekI(wxFileOffset pos
, wxSeekMode mode
)
884 // RR: This code is duplicated in wxBufferedInputStream. This is
885 // not really a good design, but buffered stream are different
886 // from all other in that they handle two stream-related objects,
887 // the stream buffer and parent stream.
889 // I don't know whether it should be put as well in wxFileInputStream::OnSysSeek
890 if (m_lasterror
==wxSTREAM_EOF
)
891 m_lasterror
=wxSTREAM_NO_ERROR
;
893 /* RR: A call to SeekI() will automatically invalidate any previous
894 call to Ungetch(), otherwise it would be possible to SeekI() to
895 one position, unread some bytes there, SeekI() to another position
896 and the data would be corrupted.
898 GRG: Could add code here to try to navigate within the wback
899 buffer if possible, but is it really needed? It would only work
900 when seeking in wxFromCurrent mode, else it would invalidate
905 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
913 return OnSysSeek(pos
, mode
);
916 wxFileOffset
wxInputStream::TellI() const
918 wxFileOffset pos
= OnSysTell();
920 if (pos
!= wxInvalidOffset
)
921 pos
-= (m_wbacksize
- m_wbackcur
);
927 // ----------------------------------------------------------------------------
929 // ----------------------------------------------------------------------------
931 wxOutputStream::wxOutputStream()
935 wxOutputStream::~wxOutputStream()
939 size_t wxOutputStream::OnSysWrite(const void * WXUNUSED(buffer
),
940 size_t WXUNUSED(bufsize
))
945 void wxOutputStream::PutC(char c
)
947 Write(&c
, sizeof(c
));
950 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
952 m_lastcount
= OnSysWrite(buffer
, size
);
956 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
958 stream_in
.Read(*this);
962 wxFileOffset
wxOutputStream::TellO() const
967 wxFileOffset
wxOutputStream::SeekO(wxFileOffset pos
, wxSeekMode mode
)
969 return OnSysSeek(pos
, mode
);
972 void wxOutputStream::Sync()
977 // ----------------------------------------------------------------------------
978 // wxCountingOutputStream
979 // ----------------------------------------------------------------------------
981 wxCountingOutputStream::wxCountingOutputStream ()
986 wxFileOffset
wxCountingOutputStream::GetLength() const
991 size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer
),
994 m_currentPos
+= size
;
995 if (m_currentPos
> m_lastcount
)
996 m_lastcount
= m_currentPos
;
1001 wxFileOffset
wxCountingOutputStream::OnSysSeek(wxFileOffset pos
, wxSeekMode mode
)
1003 ssize_t new_pos
= wx_truncate_cast(ssize_t
, pos
);
1008 wxCHECK_MSG( (wxFileOffset
)new_pos
== pos
, wxInvalidOffset
, wxT("huge position not supported") );
1012 new_pos
= m_lastcount
+ new_pos
;
1013 wxCHECK_MSG( (wxFileOffset
)new_pos
== (wxFileOffset
)(m_lastcount
+ pos
), wxInvalidOffset
, wxT("huge position not supported") );
1017 new_pos
= m_currentPos
+ new_pos
;
1018 wxCHECK_MSG( (wxFileOffset
)new_pos
== (wxFileOffset
)(m_currentPos
+ pos
), wxInvalidOffset
, wxT("huge position not supported") );
1022 wxFAIL_MSG( _T("invalid seek mode") );
1023 return wxInvalidOffset
;
1026 m_currentPos
= new_pos
;
1028 if (m_currentPos
> m_lastcount
)
1029 m_lastcount
= m_currentPos
;
1031 return m_currentPos
;
1034 wxFileOffset
wxCountingOutputStream::OnSysTell() const
1036 return m_currentPos
;
1039 // ----------------------------------------------------------------------------
1040 // wxFilterInputStream
1041 // ----------------------------------------------------------------------------
1043 wxFilterInputStream::wxFilterInputStream()
1045 m_parent_i_stream
= NULL
;
1048 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
1050 m_parent_i_stream
= &stream
;
1053 wxFilterInputStream::~wxFilterInputStream()
1057 // ----------------------------------------------------------------------------
1058 // wxFilterOutputStream
1059 // ----------------------------------------------------------------------------
1061 wxFilterOutputStream::wxFilterOutputStream()
1063 m_parent_o_stream
= NULL
;
1066 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
1068 m_parent_o_stream
= &stream
;
1071 wxFilterOutputStream::~wxFilterOutputStream()
1075 // ----------------------------------------------------------------------------
1076 // wxBufferedInputStream
1077 // ----------------------------------------------------------------------------
1079 wxBufferedInputStream::wxBufferedInputStream(wxInputStream
& s
,
1080 wxStreamBuffer
*buffer
)
1081 : wxFilterInputStream(s
)
1085 // use the buffer provided by the user
1086 m_i_streambuf
= buffer
;
1088 else // create a default buffer
1090 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
1092 m_i_streambuf
->SetBufferIO(1024);
1096 wxBufferedInputStream::~wxBufferedInputStream()
1098 m_parent_i_stream
->SeekI(-(wxFileOffset
)m_i_streambuf
->GetBytesLeft(),
1101 delete m_i_streambuf
;
1104 char wxBufferedInputStream::Peek()
1106 return m_i_streambuf
->Peek();
1109 wxInputStream
& wxBufferedInputStream::Read(void *buf
, size_t size
)
1111 // reset the error flag
1114 // first read from the already cached data
1115 m_lastcount
= GetWBack(buf
, size
);
1117 // do we have to read anything more?
1118 if ( m_lastcount
< size
)
1120 size
-= m_lastcount
;
1121 buf
= (char *)buf
+ m_lastcount
;
1123 // the call to wxStreamBuffer::Read() below will reset our m_lastcount,
1125 size_t countOld
= m_lastcount
;
1127 m_i_streambuf
->Read(buf
, size
);
1129 m_lastcount
+= countOld
;
1135 wxFileOffset
wxBufferedInputStream::SeekI(wxFileOffset pos
, wxSeekMode mode
)
1137 // RR: Look at wxInputStream for comments.
1139 if (m_lasterror
==wxSTREAM_EOF
)
1144 wxLogDebug( wxT("Seeking in stream which has data written back to it.") );
1152 return m_i_streambuf
->Seek(pos
, mode
);
1155 wxFileOffset
wxBufferedInputStream::TellI() const
1157 wxFileOffset pos
= m_i_streambuf
->Tell();
1159 if (pos
!= wxInvalidOffset
)
1160 pos
-= (m_wbacksize
- m_wbackcur
);
1165 size_t wxBufferedInputStream::OnSysRead(void *buffer
, size_t bufsize
)
1167 return m_parent_i_stream
->Read(buffer
, bufsize
).LastRead();
1170 wxFileOffset
wxBufferedInputStream::OnSysSeek(wxFileOffset seek
, wxSeekMode mode
)
1172 return m_parent_i_stream
->SeekI(seek
, mode
);
1175 wxFileOffset
wxBufferedInputStream::OnSysTell() const
1177 return m_parent_i_stream
->TellI();
1180 void wxBufferedInputStream::SetInputStreamBuffer(wxStreamBuffer
*buffer
)
1182 wxCHECK_RET( buffer
, _T("wxBufferedInputStream needs buffer") );
1184 delete m_i_streambuf
;
1185 m_i_streambuf
= buffer
;
1188 // ----------------------------------------------------------------------------
1189 // wxBufferedOutputStream
1190 // ----------------------------------------------------------------------------
1192 wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream
& s
,
1193 wxStreamBuffer
*buffer
)
1194 : wxFilterOutputStream(s
)
1198 m_o_streambuf
= buffer
;
1200 else // create a default one
1202 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
1204 m_o_streambuf
->SetBufferIO(1024);
1208 wxBufferedOutputStream::~wxBufferedOutputStream()
1211 delete m_o_streambuf
;
1214 bool wxBufferedOutputStream::Close()
1221 wxOutputStream
& wxBufferedOutputStream::Write(const void *buffer
, size_t size
)
1224 m_o_streambuf
->Write(buffer
, size
);
1228 wxFileOffset
wxBufferedOutputStream::SeekO(wxFileOffset pos
, wxSeekMode mode
)
1231 return m_o_streambuf
->Seek(pos
, mode
);
1234 wxFileOffset
wxBufferedOutputStream::TellO() const
1236 return m_o_streambuf
->Tell();
1239 void wxBufferedOutputStream::Sync()
1241 m_o_streambuf
->FlushBuffer();
1242 m_parent_o_stream
->Sync();
1245 size_t wxBufferedOutputStream::OnSysWrite(const void *buffer
, size_t bufsize
)
1247 return m_parent_o_stream
->Write(buffer
, bufsize
).LastWrite();
1250 wxFileOffset
wxBufferedOutputStream::OnSysSeek(wxFileOffset seek
, wxSeekMode mode
)
1252 return m_parent_o_stream
->SeekO(seek
, mode
);
1255 wxFileOffset
wxBufferedOutputStream::OnSysTell() const
1257 return m_parent_o_stream
->TellO();
1260 wxFileOffset
wxBufferedOutputStream::GetLength() const
1262 return m_parent_o_stream
->GetLength() + m_o_streambuf
->GetIntPosition();
1265 void wxBufferedOutputStream::SetOutputStreamBuffer(wxStreamBuffer
*buffer
)
1267 wxCHECK_RET( buffer
, _T("wxBufferedOutputStream needs buffer") );
1269 delete m_o_streambuf
;
1270 m_o_streambuf
= buffer
;
1273 // ----------------------------------------------------------------------------
1274 // Some IOManip function
1275 // ----------------------------------------------------------------------------
1277 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
1279 static const wxChar
*eol
= wxTextFile::GetEOL();
1281 return stream
.Write(eol
, wxStrlen(eol
));
1284 #endif // wxUSE_STREAMS