]>
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(wxInputStream
& i_stream
)
32 : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
),
33 m_buffer_size(0), m_istream(&i_stream
), m_ostream(NULL
)
37 wxStreamBuffer::wxStreamBuffer(wxOutputStream
& o_stream
)
38 : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
),
39 m_buffer_size(0), m_istream(NULL
), m_ostream(&o_stream
)
43 wxStreamBuffer::~wxStreamBuffer()
45 wxDELETEA(m_buffer_start
);
48 void wxStreamBuffer::WriteBack(char c
)
53 // Assume that if we write "back" we have read a few bytes: so we have some
55 if (m_buffer_pos
== m_buffer_start
)
62 void wxStreamBuffer::SetBufferIO(char *buffer_start
, char *buffer_end
)
66 m_buffer_start
= buffer_start
;
67 m_buffer_end
= buffer_end
;
69 m_buffer_size
= m_buffer_end
-m_buffer_start
;
72 ret
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
);
73 m_buffer_end
= m_buffer_start
+ ret
;
75 m_buffer_pos
= m_buffer_start
;
78 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
82 wxDELETE(m_buffer_start
);
85 m_buffer_start
= NULL
;
92 b_start
= new char[bufsize
];
94 SetBufferIO(b_start
, b_start
+ bufsize
);
97 void wxStreamBuffer::ResetBuffer()
100 m_buffer_pos
= m_buffer_end
;
102 m_buffer_pos
= m_buffer_start
;
105 void wxStreamBuffer::Read(void *buffer
, size_t size
)
107 wxASSERT(m_istream
!= NULL
);
109 // ------------------
110 // Buffering disabled
111 // ------------------
113 if (!m_buffer_size
) {
114 m_istream
->m_lastread
= m_istream
->DoRead(buffer
, size
);
121 size_t buf_left
, orig_size
= size
;
125 buf_left
= m_buffer_end
- m_buffer_pos
;
127 // First case: the requested buffer is larger than the stream buffer,
129 if (size
> buf_left
) {
130 memcpy(buffer
, m_buffer_pos
, buf_left
);
132 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
134 read_ret
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
);
138 m_istream
->m_lastread
= orig_size
-size
;
139 m_istream
->m_eof
= TRUE
;
140 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
143 m_buffer_end
= m_buffer_start
+read_ret
;
144 m_buffer_pos
= m_buffer_start
;
148 // Second case: we just copy from the stream buffer.
149 memcpy(buffer
, m_buffer_pos
, size
);
150 m_buffer_pos
+= size
;
154 m_istream
->m_lastread
= orig_size
;
157 void wxStreamBuffer::Write(const void *buffer
, size_t size
)
159 wxASSERT(m_ostream
!= NULL
);
161 // ------------------
162 // Buffering disabled
163 // ------------------
165 if (!m_buffer_size
) {
166 m_ostream
->m_lastwrite
= m_ostream
->DoWrite(buffer
, size
);
170 // ------------------
172 // ------------------
174 size_t buf_left
, orig_size
= size
;
178 buf_left
= m_buffer_end
- m_buffer_pos
;
180 // First case: the buffer to write is larger than the stream buffer,
182 if (size
> buf_left
) {
183 memcpy(m_buffer_pos
, buffer
, buf_left
);
185 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
187 write_ret
= m_ostream
->DoWrite(m_buffer_start
, m_buffer_size
);
188 if (write_ret
!= m_buffer_size
) {
189 m_ostream
->m_bad
= TRUE
;
190 m_ostream
->m_lastwrite
= orig_size
-size
;
191 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
194 m_buffer_pos
= m_buffer_start
;
198 // Second case: just copy it in the stream buffer.
200 memcpy(m_buffer_pos
, buffer
, size
);
201 m_buffer_pos
+= size
;
205 m_ostream
->m_lastwrite
= orig_size
;
208 // ----------------------------------------------------------------------------
210 // ----------------------------------------------------------------------------
212 wxInputStream::wxInputStream()
214 m_i_destroybuf
= TRUE
;
215 m_i_streambuf
= new wxStreamBuffer(*this);
220 wxInputStream::wxInputStream(wxStreamBuffer
*buffer
)
222 m_i_destroybuf
= FALSE
;
223 m_i_streambuf
= buffer
;
228 wxInputStream::~wxInputStream()
231 delete m_i_streambuf
;
234 char wxInputStream::GetC()
237 m_i_streambuf
->Read(&c
, 1);
241 wxInputStream
& wxInputStream::Read(void *buffer
, size_t size
)
243 m_i_streambuf
->Read(buffer
, size
);
244 // wxStreamBuffer sets all variables for us
248 #define BUF_TEMP_SIZE 10000
250 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
252 char buf
[BUF_TEMP_SIZE
];
253 size_t bytes_read
= BUF_TEMP_SIZE
;
255 while (bytes_read
== BUF_TEMP_SIZE
&& !stream_out
.Bad()) {
256 bytes_read
= Read(buf
, bytes_read
).LastRead();
258 stream_out
.Write(buf
, bytes_read
);
263 wxInputStream
& wxInputStream::operator>>(wxString
& line
)
265 wxDataInputStream
s(*this);
271 wxInputStream
& wxInputStream::operator>>(char& c
)
277 wxInputStream
& wxInputStream::operator>>(short& i
)
286 wxInputStream
& wxInputStream::operator>>(int& i
)
295 wxInputStream
& wxInputStream::operator>>(long& i
)
297 /* I only implemented a simple integer parser */
300 while (isspace( c
= GetC() ) )
304 if (! (c
== '-' || isdigit(c
)) ) {
305 InputStreamBuffer()->WriteBack(c
);
325 wxInputStream
& wxInputStream::operator>>(float& f
)
327 /* I only implemented a simple float parser */
330 while (isspace( c
= GetC() ) )
334 if (! (c
== '-' || isdigit(c
)) ) {
335 InputStreamBuffer()->WriteBack(c
);
351 float f_multiplicator
= (float) 0.1;
355 f
+= c
*f_multiplicator
;
356 f_multiplicator
/= 10;
367 wxInputStream
& wxInputStream::operator>>(wxObject
*& obj
)
369 wxObjectInputStream
obj_s(*this);
370 obj
= obj_s
.LoadObject();
375 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
377 off_t ret_off
, diff
, last_access
;
379 last_access
= m_i_streambuf
->GetLastAccess();
383 diff
= DoTellInput() - pos
;
384 if ( diff
< 0 || diff
> last_access
) {
385 ret_off
= DoSeekInput(pos
, wxFromStart
);
386 m_i_streambuf
->ResetBuffer();
389 m_i_streambuf
->SetIntPosition(last_access
- diff
);
393 diff
= pos
+ m_i_streambuf
->GetIntPosition();
395 if ( (diff
> last_access
) || (diff
< 0) ) {
396 ret_off
= DoSeekInput(pos
, wxFromCurrent
);
397 m_i_streambuf
->ResetBuffer();
400 m_i_streambuf
->SetIntPosition(diff
);
404 // Hard to compute: always seek to the requested position.
405 ret_off
= DoSeekInput(pos
, wxFromEnd
);
406 m_i_streambuf
->ResetBuffer();
409 return wxInvalidOffset
;
412 off_t
wxInputStream::TellI() const
414 return DoTellInput() - m_i_streambuf
->GetLastAccess() +
415 m_i_streambuf
->GetIntPosition();
418 // ----------------------------------------------------------------------------
420 // ----------------------------------------------------------------------------
421 wxOutputStream::wxOutputStream()
423 m_o_destroybuf
= TRUE
;
424 m_o_streambuf
= new wxStreamBuffer(*this);
429 wxOutputStream::wxOutputStream(wxStreamBuffer
*buffer
)
431 m_o_destroybuf
= FALSE
;
432 m_o_streambuf
= buffer
;
437 wxOutputStream::~wxOutputStream()
440 delete m_o_streambuf
;
443 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
445 m_o_streambuf
->Write(buffer
, size
);
449 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
451 stream_in
.Read(*this);
455 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
461 if ( (unsigned)abs (DoTellOutput()-pos
) > m_o_streambuf
->GetLastAccess() ) {
462 ret_off
= DoSeekOutput(pos
, wxFromStart
);
463 m_o_streambuf
->ResetBuffer();
466 m_o_streambuf
->SetIntPosition( DoTellOutput() - pos
);
470 if ( ((unsigned)pos
> m_o_streambuf
->GetLastAccess()) || (pos
< 0) ) {
471 ret_off
= DoSeekOutput(pos
, wxFromCurrent
);
472 m_o_streambuf
->ResetBuffer();
475 m_o_streambuf
->SetIntPosition(pos
);
479 // Hard to compute: always seek to the requested position.
480 ret_off
= DoSeekOutput(pos
, wxFromEnd
);
481 m_o_streambuf
->ResetBuffer();
484 return wxInvalidOffset
;
487 off_t
wxOutputStream::TellO() const
489 return DoTellOutput() - m_o_streambuf
->GetLastAccess()
490 + m_o_streambuf
->GetIntPosition();
493 void wxOutputStream::Sync()
495 DoWrite(m_o_streambuf
->GetBufferStart(), m_o_streambuf
->GetIntPosition());
497 m_o_streambuf
->ResetBuffer();
500 wxOutputStream
& wxOutputStream::operator<<(const char *string
)
502 return Write(string
, strlen(string
));
505 wxOutputStream
& wxOutputStream::operator<<(wxString
& string
)
507 return Write(string
, string
.Len());
510 wxOutputStream
& wxOutputStream::operator<<(char c
)
515 wxOutputStream
& wxOutputStream::operator<<(short i
)
519 strint
.Printf("%i", i
);
520 return Write(strint
, strint
.Len());
523 wxOutputStream
& wxOutputStream::operator<<(int i
)
527 strint
.Printf("%i", i
);
528 return Write(strint
, strint
.Len());
531 wxOutputStream
& wxOutputStream::operator<<(long i
)
535 strlong
.Printf("%i", i
);
536 return Write((const char *)strlong
, strlong
.Len());
539 wxOutputStream
& wxOutputStream::operator<<(double f
)
543 strfloat
.Printf("%f", f
);
544 return Write(strfloat
, strfloat
.Len());
548 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
)
550 wxObjectOutputStream
obj_s(*this);
551 obj_s
.SaveObject(obj
);
556 // ----------------------------------------------------------------------------
558 // ----------------------------------------------------------------------------
561 : wxInputStream(), wxOutputStream()
565 // ----------------------------------------------------------------------------
566 // wxFilterInputStream
567 // ----------------------------------------------------------------------------
568 wxFilterInputStream::wxFilterInputStream()
569 : wxInputStream(NULL
)
573 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
574 : wxInputStream(NULL
)
576 m_parent_i_stream
= &stream
;
577 wxDELETE(m_i_streambuf
); // In case m_i_streambuf has been initialized.
578 m_i_destroybuf
= FALSE
;
579 m_i_streambuf
= stream
.InputStreamBuffer();
582 wxFilterInputStream::~wxFilterInputStream()
586 size_t wxFilterInputStream::DoRead(void *buffer
, size_t size
)
588 return m_parent_i_stream
->Read(buffer
, size
).LastRead();
591 off_t
wxFilterInputStream::DoSeekInput(off_t pos
, wxSeekMode mode
)
593 return m_parent_i_stream
->SeekI(pos
, mode
);
596 off_t
wxFilterInputStream::DoTellInput() const
598 return m_parent_i_stream
->TellI();
601 // ----------------------------------------------------------------------------
602 // wxFilterOutputStream
603 // ----------------------------------------------------------------------------
604 wxFilterOutputStream::wxFilterOutputStream()
605 : wxOutputStream(NULL
)
609 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
610 : wxOutputStream(NULL
)
612 m_parent_o_stream
= &stream
;
613 wxDELETE(m_o_streambuf
); // In case m_o_streambuf has been initialized.
614 m_o_destroybuf
= FALSE
;
615 m_o_streambuf
= stream
.OutputStreamBuffer();
618 wxFilterOutputStream::~wxFilterOutputStream()
622 size_t wxFilterOutputStream::DoWrite(const void *buffer
, size_t size
)
624 return m_parent_o_stream
->Write(buffer
, size
).LastWrite();
627 off_t
wxFilterOutputStream::DoSeekOutput(off_t pos
, wxSeekMode mode
)
629 return m_parent_o_stream
->SeekO(pos
, mode
);
632 off_t
wxFilterOutputStream::DoTellOutput() const
634 return m_parent_o_stream
->TellO();
637 // ----------------------------------------------------------------------------
639 // ----------------------------------------------------------------------------
641 wxFilterStream::wxFilterStream()
645 wxFilterStream::wxFilterStream(wxStream
& stream
)
646 : wxFilterInputStream(stream
), wxFilterOutputStream(stream
)
650 // ----------------------------------------------------------------------------
651 // Some IOManip function
652 // ----------------------------------------------------------------------------
654 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
657 return stream
.Write("\r\n", 2);
659 return stream
.Write("\n", 1);