]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stream.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxStream base classes
4 // Author: Guilhem Lavaux
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "stream.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
19 #include <wx/stream.h>
20 #include <wx/datstrm.h>
21 #include <wx/objstrm.h>
27 // ----------------------------------------------------------------------------
29 // ----------------------------------------------------------------------------
31 wxStreamBuffer::wxStreamBuffer(wxStreamBase
& stream
, BufMode mode
)
32 : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
),
33 m_buffer_size(0), m_fixed(TRUE
), m_flushable(TRUE
), m_stream(&stream
),
34 m_mode(mode
), m_destroybuf(FALSE
)
38 wxStreamBuffer::wxStreamBuffer(BufMode mode
)
39 : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
),
40 m_buffer_size(0), m_fixed(TRUE
), m_flushable(FALSE
), m_stream(NULL
),
41 m_mode(mode
), m_destroybuf(FALSE
)
45 wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer
& buffer
)
47 m_buffer_start
= buffer
.m_buffer_start
;
48 m_buffer_end
= buffer
.m_buffer_end
;
49 m_buffer_pos
= buffer
.m_buffer_pos
;
50 m_buffer_size
= buffer
.m_buffer_size
;
51 m_fixed
= buffer
.m_fixed
;
52 m_flushable
= buffer
.m_flushable
;
53 m_stream
= buffer
.m_stream
;
54 m_mode
= buffer
.m_mode
;
58 wxStreamBuffer::~wxStreamBuffer()
61 wxDELETEA(m_buffer_start
);
64 bool wxStreamBuffer::WriteBack(const char *buf
, size_t bufsize
)
68 ptrback
= AllocSpaceWBack(bufsize
);
72 memcpy(ptrback
, buf
, bufsize
);
76 bool wxStreamBuffer::WriteBack(char c
)
80 ptrback
= AllocSpaceWBack(1);
88 void wxStreamBuffer::SetBufferIO(char *buffer_start
, char *buffer_end
)
91 wxDELETEA(m_buffer_start
);
92 m_buffer_start
= buffer_start
;
93 m_buffer_end
= buffer_end
;
95 m_buffer_size
= m_buffer_end
-m_buffer_start
;
100 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
104 wxDELETE(m_buffer_start
);
107 m_buffer_start
= NULL
;
114 b_start
= new char[bufsize
];
115 SetBufferIO(b_start
, b_start
+ bufsize
);
119 void wxStreamBuffer::ResetBuffer()
122 m_buffer_pos
= m_buffer_end
;
124 m_buffer_pos
= m_buffer_start
;
127 char *wxStreamBuffer::AllocSpaceWBack(size_t needed_size
)
131 m_wbacksize
+= needed_size
;
134 temp_b
= (char *)malloc(m_wbacksize
);
136 temp_b
= (char *)realloc(m_wback
, m_wbacksize
);
140 return (char *)((size_t)m_wback
+(m_wbacksize
-needed_size
));
143 size_t wxStreamBuffer::GetWBack(char *buf
, size_t bsize
)
145 size_t s_toget
= m_wbacksize
-m_wbackcur
;
150 memcpy(buf
, (m_wback
+m_wbackcur
), s_toget
);
152 m_wbackcur
+= s_toget
;
153 if (m_wbackcur
== m_wbacksize
) {
155 m_wback
= (char *)NULL
;
163 bool wxStreamBuffer::FillBuffer()
167 count
= m_stream
->OnSysRead(m_buffer_start
, m_buffer_size
);
168 m_buffer_end
= m_buffer_start
+count
;
169 m_buffer_pos
= m_buffer_start
;
176 bool wxStreamBuffer::FlushBuffer()
178 size_t count
, current
;
180 if (m_buffer_pos
== m_buffer_start
|| !m_flushable
)
183 current
= m_buffer_pos
-m_buffer_start
;
184 count
= m_stream
->OnSysWrite(m_buffer_start
, current
);
185 if (count
!= current
)
187 m_buffer_pos
= m_buffer_start
;
192 void wxStreamBuffer::GetFromBuffer(void *buffer
, size_t size
)
194 size_t s_toget
= m_buffer_end
-m_buffer_pos
;
199 memcpy(buffer
, m_buffer_pos
, s_toget
);
200 m_buffer_pos
+= s_toget
;
203 void wxStreamBuffer::PutToBuffer(const void *buffer
, size_t size
)
205 size_t s_toput
= m_buffer_end
-m_buffer_pos
;
207 if (s_toput
< size
&& !m_fixed
) {
208 m_buffer_start
= (char *)realloc(m_buffer_start
, m_buffer_size
+size
);
210 m_buffer_size
+= size
;
211 m_buffer_end
= m_buffer_start
+m_buffer_size
;
216 memcpy(m_buffer_pos
, buffer
, s_toput
);
217 m_buffer_pos
+= s_toput
;
220 void wxStreamBuffer::PutChar(char c
)
222 wxASSERT(m_stream
!= NULL
);
224 if (!m_buffer_size
) {
225 m_stream
->OnSysWrite(&c
, 1);
229 if (!GetDataLeft() && !FlushBuffer())
233 m_stream
->m_lastcount
= 1;
236 char wxStreamBuffer::GetChar()
240 wxASSERT(m_stream
!= NULL
);
242 if (!m_buffer_size
) {
243 m_stream
->OnSysRead(&c
, 1);
247 if (!GetDataLeft() && !FillBuffer())
250 GetFromBuffer(&c
, 1);
251 m_stream
->m_lastcount
= 1;
255 void wxStreamBuffer::Read(void *buffer
, size_t size
)
257 wxASSERT(m_stream
!= NULL
);
259 // ------------------
260 // Buffering disabled
261 // ------------------
263 m_stream
->m_lastcount
= GetWBack((char *)buffer
, size
);
264 size
-= m_stream
->m_lastcount
;
268 buffer
= (void *)((char *)buffer
+m_stream
->m_lastcount
);
270 if (!m_buffer_size
) {
271 m_stream
->m_lastcount
+= m_stream
->OnSysRead(buffer
, size
);
278 size_t buf_left
, orig_size
= size
;
281 buf_left
= GetDataLeft();
283 // First case: the requested buffer is larger than the stream buffer,
285 if (size
> buf_left
) {
286 GetFromBuffer(buffer
, buf_left
);
288 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
291 m_stream
->m_lastcount
= orig_size
-size
;
296 // Second case: we just copy from the stream buffer.
297 GetFromBuffer(buffer
, size
);
301 m_stream
->m_lastcount
+= orig_size
;
304 void wxStreamBuffer::Write(const void *buffer
, size_t size
)
306 wxASSERT(m_stream
!= NULL
);
308 // ------------------
309 // Buffering disabled
310 // ------------------
312 if (!m_buffer_size
) {
313 m_stream
->m_lastcount
= m_stream
->OnSysWrite(buffer
, size
);
317 // ------------------
319 // ------------------
321 size_t buf_left
, orig_size
= size
;
324 buf_left
= m_buffer_end
- m_buffer_pos
;
326 // First case: the buffer to write is larger than the stream buffer,
328 if (size
> buf_left
) {
329 PutToBuffer(buffer
, buf_left
);
331 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
333 if (!FlushBuffer()) {
334 m_stream
->m_lastcount
= orig_size
-size
;
337 m_buffer_pos
= m_buffer_start
;
341 // Second case: just copy it in the stream buffer.
342 PutToBuffer(buffer
, size
);
346 m_stream
->m_lastcount
= orig_size
;
349 off_t
wxStreamBuffer::Seek(off_t pos
, wxSeekMode mode
)
351 off_t ret_off
, diff
, last_access
;
353 last_access
= GetLastAccess();
356 diff
= pos
+ GetIntPosition();
357 if (diff
< 0 || diff
> last_access
)
358 return wxInvalidOffset
;
359 SetIntPosition(diff
);
365 // We'll try to compute an internal position later ...
366 ret_off
= m_stream
->OnSysSeek(pos
, wxFromStart
);
370 case wxFromCurrent
: {
371 diff
= pos
+ GetIntPosition();
373 if ( (diff
> last_access
) || (diff
< 0) ) {
374 ret_off
= m_stream
->OnSysSeek(pos
, wxFromCurrent
);
378 SetIntPosition(diff
);
383 // Hard to compute: always seek to the requested position.
384 ret_off
= m_stream
->OnSysSeek(pos
, wxFromEnd
);
388 return wxInvalidOffset
;
391 off_t
wxStreamBuffer::Tell() const
396 pos
= m_stream
->OnSysTell();
397 if (pos
== wxInvalidOffset
)
398 return wxInvalidOffset
;
399 return pos
- GetLastAccess() + GetIntPosition();
401 return GetIntPosition();
404 size_t wxStreamBuffer::GetDataLeft() const
406 return m_buffer_end
-m_buffer_pos
;
409 // ----------------------------------------------------------------------------
411 // ----------------------------------------------------------------------------
413 wxStreamBase::wxStreamBase()
415 m_lasterror
= wxStream_NOERROR
;
419 wxStreamBase::~wxStreamBase()
423 size_t wxStreamBase::OnSysRead(void *buffer
, size_t size
)
428 size_t wxStreamBase::OnSysWrite(const void *buffer
, size_t bufsize
)
433 off_t
wxStreamBase::OnSysSeek(off_t seek
, wxSeekMode mode
)
435 return wxInvalidOffset
;
438 off_t
wxStreamBase::OnSysTell() const
440 return wxInvalidOffset
;
443 // ----------------------------------------------------------------------------
445 // ----------------------------------------------------------------------------
447 wxInputStream::wxInputStream()
450 m_i_destroybuf
= TRUE
;
451 m_i_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::read
);
454 wxInputStream::wxInputStream(wxStreamBuffer
*buffer
)
457 m_i_destroybuf
= FALSE
;
458 m_i_streambuf
= buffer
;
461 wxInputStream::~wxInputStream()
464 delete m_i_streambuf
;
467 char wxInputStream::GetC()
470 m_i_streambuf
->Read(&c
, 1);
474 wxInputStream
& wxInputStream::Read(void *buffer
, size_t size
)
476 m_i_streambuf
->Read(buffer
, size
);
477 // wxStreamBuffer sets all variables for us
481 char wxInputStream::Peek()
483 if (!m_i_streambuf
->GetDataLeft())
484 m_i_streambuf
->FillBuffer();
486 return *(m_i_streambuf
->GetBufferPos());
489 #define BUF_TEMP_SIZE 10000
491 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
493 char buf
[BUF_TEMP_SIZE
];
494 size_t bytes_read
= BUF_TEMP_SIZE
;
496 while (bytes_read
== BUF_TEMP_SIZE
&& stream_out
.LastError() != wxStream_NOERROR
) {
497 bytes_read
= Read(buf
, bytes_read
).LastRead();
499 stream_out
.Write(buf
, bytes_read
);
504 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
506 return m_i_streambuf
->Seek(pos
, mode
);
509 off_t
wxInputStream::TellI() const
511 return m_i_streambuf
->Tell();
514 // --------------------
515 // Overloaded operators
516 // --------------------
518 wxInputStream
& wxInputStream::operator>>(wxString
& line
)
520 wxDataInputStream
s(*this);
526 wxInputStream
& wxInputStream::operator>>(char& c
)
532 wxInputStream
& wxInputStream::operator>>(short& i
)
541 wxInputStream
& wxInputStream::operator>>(int& i
)
550 wxInputStream
& wxInputStream::operator>>(long& i
)
552 /* I only implemented a simple integer parser */
555 while (isspace( c
= GetC() ) )
559 if (! (c
== '-' || isdigit(c
)) ) {
560 InputStreamBuffer()->WriteBack(c
);
580 wxInputStream
& wxInputStream::operator>>(double& f
)
582 /* I only implemented a simple float parser */
585 while (isspace( c
= GetC() ) )
589 if (! (c
== '-' || isdigit(c
)) ) {
590 InputStreamBuffer()->WriteBack(c
);
601 f
= f
*10 + (c
- '0');
606 double f_multiplicator
= (double) 0.1;
610 f
+= (c
-'0')*f_multiplicator
;
611 f_multiplicator
/= 10;
622 wxInputStream
& wxInputStream::operator>>(wxObject
*& obj
)
624 wxObjectInputStream
obj_s(*this);
625 obj
= obj_s
.LoadObject();
631 // ----------------------------------------------------------------------------
633 // ----------------------------------------------------------------------------
634 wxOutputStream::wxOutputStream()
637 m_o_destroybuf
= TRUE
;
638 m_o_streambuf
= new wxStreamBuffer(*this, wxStreamBuffer::write
);
641 wxOutputStream::wxOutputStream(wxStreamBuffer
*buffer
)
644 m_o_destroybuf
= FALSE
;
645 m_o_streambuf
= buffer
;
648 wxOutputStream::~wxOutputStream()
651 delete m_o_streambuf
;
654 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
656 m_o_streambuf
->Write(buffer
, size
);
660 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
662 stream_in
.Read(*this);
666 off_t
wxOutputStream::TellO() const
668 return m_o_streambuf
->Tell();
671 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
673 return m_o_streambuf
->Seek(pos
, mode
);
676 void wxOutputStream::Sync()
678 m_o_streambuf
->FlushBuffer();
681 wxOutputStream
& wxOutputStream::operator<<(const char *string
)
683 return Write(string
, strlen(string
));
686 wxOutputStream
& wxOutputStream::operator<<(wxString
& string
)
688 return Write(string
, string
.Len());
691 wxOutputStream
& wxOutputStream::operator<<(char c
)
696 wxOutputStream
& wxOutputStream::operator<<(short i
)
700 strint
.Printf("%i", i
);
701 return Write(strint
, strint
.Len());
704 wxOutputStream
& wxOutputStream::operator<<(int i
)
708 strint
.Printf("%i", i
);
709 return Write(strint
, strint
.Len());
712 wxOutputStream
& wxOutputStream::operator<<(long i
)
716 strlong
.Printf("%i", i
);
717 return Write((const char *)strlong
, strlong
.Len());
720 wxOutputStream
& wxOutputStream::operator<<(double f
)
724 strfloat
.Printf("%f", f
);
725 return Write(strfloat
, strfloat
.Len());
729 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
)
731 wxObjectOutputStream
obj_s(*this);
732 obj_s
.SaveObject(obj
);
737 // ----------------------------------------------------------------------------
738 // wxFilterInputStream
739 // ----------------------------------------------------------------------------
740 wxFilterInputStream::wxFilterInputStream()
741 : wxInputStream(NULL
)
743 // WARNING streambuf set to NULL !
746 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
747 : wxInputStream(stream
.InputStreamBuffer())
749 m_parent_i_stream
= &stream
;
752 wxFilterInputStream::~wxFilterInputStream()
756 // ----------------------------------------------------------------------------
757 // wxFilterOutputStream
758 // ----------------------------------------------------------------------------
759 wxFilterOutputStream::wxFilterOutputStream()
760 : wxOutputStream(NULL
)
764 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
765 : wxOutputStream(stream
.OutputStreamBuffer())
767 m_parent_o_stream
= &stream
;
770 wxFilterOutputStream::~wxFilterOutputStream()
774 // ----------------------------------------------------------------------------
775 // Some IOManip function
776 // ----------------------------------------------------------------------------
778 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
781 return stream
.Write("\r\n", 2);
783 return stream
.Write("\n", 1);