]>
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()
47 void wxStreamBuffer::WriteBack(char c
)
52 // Assume that if we write "back" we have read a few bytes: so we have some
59 void wxStreamBuffer::SetBufferIO(char *buffer_start
, char *buffer_end
)
61 m_buffer_pos
= m_buffer_start
= buffer_start
;
62 m_buffer_end
= buffer_end
;
64 m_buffer_size
= m_buffer_end
-m_buffer_start
;
67 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
70 delete[] m_buffer_start
;
73 m_buffer_start
= NULL
;
79 m_buffer_start
= new char[bufsize
];
80 m_buffer_end
= m_buffer_start
+ bufsize
;
82 m_buffer_pos
= m_buffer_end
;
84 m_buffer_pos
= m_buffer_start
;
85 m_buffer_size
= bufsize
;
88 void wxStreamBuffer::ResetBuffer()
91 m_buffer_pos
= m_buffer_end
;
93 m_buffer_pos
= m_buffer_start
;
96 void wxStreamBuffer::Read(void *buffer
, size_t size
)
98 wxASSERT(m_istream
!= NULL
);
100 // ------------------
101 // Buffering disabled
102 // ------------------
104 if (!m_buffer_size
) {
105 m_istream
->m_lastread
= m_istream
->DoRead(buffer
, size
);
112 size_t buf_left
, orig_size
= size
;
116 buf_left
= m_buffer_end
- m_buffer_pos
;
118 // First case: the requested buffer is larger than the stream buffer,
120 if (size
> buf_left
) {
121 memcpy(buffer
, m_buffer_pos
, buf_left
);
123 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
125 read_ret
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
);
129 m_istream
->m_lastread
= orig_size
-size
;
130 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
133 m_buffer_end
= m_buffer_start
+read_ret
;
134 m_buffer_pos
= m_buffer_start
;
138 // Second case: we just copy from the stream buffer.
139 memcpy(buffer
, m_buffer_pos
, size
);
140 m_buffer_pos
+= size
;
144 m_istream
->m_lastread
= orig_size
;
147 void wxStreamBuffer::Write(const void *buffer
, size_t size
)
149 wxASSERT(m_ostream
!= NULL
);
151 // ------------------
152 // Buffering disabled
153 // ------------------
155 if (!m_buffer_size
) {
156 m_ostream
->m_lastwrite
= m_ostream
->DoWrite(buffer
, size
);
160 // ------------------
162 // ------------------
164 size_t buf_left
, orig_size
= size
;
168 buf_left
= m_buffer_end
- m_buffer_pos
;
170 // First case: the buffer to write is larger than the stream buffer,
172 if (size
> buf_left
) {
173 memcpy(m_buffer_pos
, buffer
, buf_left
);
175 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
177 write_ret
= m_ostream
->DoWrite(m_buffer_start
, m_buffer_size
);
178 if (write_ret
!= m_buffer_size
) {
179 m_ostream
->m_bad
= TRUE
;
180 m_ostream
->m_lastwrite
= orig_size
-size
;
181 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
184 m_buffer_pos
= m_buffer_start
;
188 // Second case: just copy it in the stream buffer.
190 memcpy(m_buffer_pos
, buffer
, size
);
191 m_buffer_pos
+= size
;
195 m_ostream
->m_lastwrite
= orig_size
;
198 // ----------------------------------------------------------------------------
200 // ----------------------------------------------------------------------------
202 wxInputStream::wxInputStream()
204 m_i_destroybuf
= TRUE
;
205 m_i_streambuf
= new wxStreamBuffer(*this);
209 wxInputStream::wxInputStream(wxStreamBuffer
*buffer
)
211 m_i_destroybuf
= FALSE
;
212 m_i_streambuf
= buffer
;
216 wxInputStream::~wxInputStream()
219 delete m_i_streambuf
;
222 char wxInputStream::GetC()
225 m_i_streambuf
->Read(&c
, 1);
229 wxInputStream
& wxInputStream::Read(void *buffer
, size_t size
)
231 m_i_streambuf
->Read(buffer
, size
);
232 // wxStreamBuffer sets all variables for us
236 #define BUF_TEMP_SIZE 10000
238 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
240 char buf
[BUF_TEMP_SIZE
];
241 size_t bytes_read
= BUF_TEMP_SIZE
;
243 while (bytes_read
== BUF_TEMP_SIZE
&& !stream_out
.Bad()) {
244 bytes_read
= Read(buf
, bytes_read
).LastRead();
246 stream_out
.Write(buf
, bytes_read
);
251 wxInputStream
& wxInputStream::operator>>(wxString
& line
)
253 wxDataInputStream
s(*this);
259 wxInputStream
& wxInputStream::operator>>(char& c
)
265 wxInputStream
& wxInputStream::operator>>(short& i
)
274 wxInputStream
& wxInputStream::operator>>(int& i
)
283 wxInputStream
& wxInputStream::operator>>(long& i
)
285 /* I only implemented a simple integer parser */
288 while (isspace( c
= GetC() ) )
292 if (! (c
== '-' || isdigit(c
)) ) {
293 InputStreamBuffer()->WriteBack(c
);
313 wxInputStream
& wxInputStream::operator>>(float& f
)
315 /* I only implemented a simple float parser */
318 while (isspace( c
= GetC() ) )
322 if (! (c
== '-' || isdigit(c
)) ) {
323 InputStreamBuffer()->WriteBack(c
);
339 float f_multiplicator
= 0.1;
343 f
+= c
*f_multiplicator
;
344 f_multiplicator
/= 10;
354 wxInputStream
& wxInputStream::operator>>(wxObject
*& obj
)
356 wxObjectInputStream
obj_s(*this);
357 obj
= obj_s
.LoadObject();
361 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
367 if ( (unsigned)abs (DoTellInput()-pos
) > m_i_streambuf
->GetLastAccess() ) {
368 ret_off
= DoSeekInput(pos
, wxFromStart
);
369 m_i_streambuf
->ResetBuffer();
372 m_i_streambuf
->SetIntPosition(DoTellInput() - pos
);
376 if ( ((unsigned)pos
> m_i_streambuf
->GetLastAccess()) || (pos
< 0) ) {
377 ret_off
= DoSeekInput(pos
, wxFromCurrent
);
378 m_i_streambuf
->ResetBuffer();
381 m_i_streambuf
->SetIntPosition(pos
);
385 // Hard to compute: always seek to the requested position.
386 ret_off
= DoSeekInput(pos
, wxFromEnd
);
387 m_i_streambuf
->ResetBuffer();
390 return wxInvalidOffset
;
393 off_t
wxInputStream::TellI() const
395 return DoTellInput() - m_i_streambuf
->GetLastAccess() +
396 m_i_streambuf
->GetIntPosition();
399 // ----------------------------------------------------------------------------
401 // ----------------------------------------------------------------------------
402 wxOutputStream::wxOutputStream()
404 m_o_destroybuf
= TRUE
;
405 m_o_streambuf
= new wxStreamBuffer(*this);
408 wxOutputStream::wxOutputStream(wxStreamBuffer
*buffer
)
410 m_o_destroybuf
= FALSE
;
411 m_o_streambuf
= buffer
;
414 wxOutputStream::~wxOutputStream()
417 delete m_o_streambuf
;
420 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
422 m_o_streambuf
->Write(buffer
, size
);
426 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
428 stream_in
.Read(*this);
432 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
438 if ( (unsigned)abs (DoTellOutput()-pos
) > m_o_streambuf
->GetLastAccess() ) {
439 ret_off
= DoSeekOutput(pos
, wxFromStart
);
440 m_o_streambuf
->ResetBuffer();
443 m_o_streambuf
->SetIntPosition( DoTellOutput() - pos
);
447 if ( ((unsigned)pos
> m_o_streambuf
->GetLastAccess()) || (pos
< 0) ) {
448 ret_off
= DoSeekOutput(pos
, wxFromCurrent
);
449 m_o_streambuf
->ResetBuffer();
452 m_o_streambuf
->SetIntPosition(pos
);
456 // Hard to compute: always seek to the requested position.
457 ret_off
= DoSeekOutput(pos
, wxFromEnd
);
458 m_o_streambuf
->ResetBuffer();
461 return wxInvalidOffset
;
464 off_t
wxOutputStream::TellO() const
466 return DoTellOutput() - m_o_streambuf
->GetLastAccess()
467 + m_o_streambuf
->GetIntPosition();
470 void wxOutputStream::Sync()
472 DoWrite(m_o_streambuf
->GetBufferStart(), m_o_streambuf
->GetIntPosition());
474 m_o_streambuf
->ResetBuffer();
477 wxOutputStream
& wxOutputStream::operator<<(const char *string
)
479 return Write(string
, strlen(string
));
482 wxOutputStream
& wxOutputStream::operator<<(wxString
& string
)
484 return Write(string
, string
.Len());
487 wxOutputStream
& wxOutputStream::operator<<(char c
)
492 wxOutputStream
& wxOutputStream::operator<<(short i
)
496 strint
.Printf("%i", i
);
497 return Write(strint
, strint
.Len());
500 wxOutputStream
& wxOutputStream::operator<<(int i
)
504 strint
.Printf("%i", i
);
505 return Write(strint
, strint
.Len());
508 wxOutputStream
& wxOutputStream::operator<<(long i
)
512 strlong
.Printf("%i", i
);
513 return Write((const char *)strlong
, strlong
.Len());
516 wxOutputStream
& wxOutputStream::operator<<(double f
)
520 strfloat
.Printf("%f", f
);
521 return Write(strfloat
, strfloat
.Len());
524 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
)
526 wxObjectOutputStream
obj_s(*this);
527 obj_s
.SaveObject(obj
);
531 // ----------------------------------------------------------------------------
532 // wxFilterInputStream
533 // ----------------------------------------------------------------------------
534 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
535 : wxInputStream(NULL
)
537 m_parent_i_stream
= &stream
;
538 m_i_streambuf
= stream
.InputStreamBuffer();
541 wxFilterInputStream::~wxFilterInputStream()
545 size_t wxFilterInputStream::DoRead(void *buffer
, size_t size
)
547 return m_parent_i_stream
->Read(buffer
, size
).LastRead();
550 off_t
wxFilterInputStream::DoSeekInput(off_t pos
, wxSeekMode mode
)
552 return m_parent_i_stream
->SeekI(pos
, mode
);
555 off_t
wxFilterInputStream::DoTellInput() const
557 return m_parent_i_stream
->TellI();
561 // ----------------------------------------------------------------------------
562 // wxFilterOutputStream
563 // ----------------------------------------------------------------------------
564 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
565 : wxOutputStream(NULL
)
567 m_parent_o_stream
= &stream
;
568 m_o_streambuf
= stream
.OutputStreamBuffer();
571 wxFilterOutputStream::~wxFilterOutputStream()
575 size_t wxFilterOutputStream::DoWrite(const void *buffer
, size_t size
)
577 return m_parent_o_stream
->Write(buffer
, size
).LastWrite();
580 off_t
wxFilterOutputStream::DoSeekOutput(off_t pos
, wxSeekMode mode
)
582 return m_parent_o_stream
->SeekO(pos
, mode
);
585 off_t
wxFilterOutputStream::DoTellOutput() const
587 return m_parent_o_stream
->TellO();
590 // ----------------------------------------------------------------------------
591 // Some IOManip function
592 // ----------------------------------------------------------------------------
594 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
597 return stream
.Write("\r\n", 2);
599 return stream
.Write("\n", 1);