]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stream.cpp
66538c9ddd1892d1ab7d2a24d5fb81777a6aee5f
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>
26 // ----------------------------------------------------------------------------
28 // ----------------------------------------------------------------------------
30 wxStreamBuffer::wxStreamBuffer(wxInputStream
& i_stream
)
31 : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
),
32 m_buffer_size(0), m_istream(&i_stream
), m_ostream(NULL
)
36 wxStreamBuffer::wxStreamBuffer(wxOutputStream
& o_stream
)
37 : m_buffer_start(NULL
), m_buffer_end(NULL
), m_buffer_pos(NULL
),
38 m_buffer_size(0), m_istream(NULL
), m_ostream(&o_stream
)
42 wxStreamBuffer::~wxStreamBuffer()
46 void wxStreamBuffer::WriteBack(char c
)
51 // Assume that if we write "back" we have read a few bytes: so we have some
58 void wxStreamBuffer::SetBufferIO(char *buffer_start
, char *buffer_end
)
60 m_buffer_pos
= m_buffer_start
= buffer_start
;
61 m_buffer_end
= buffer_end
;
63 m_buffer_size
= m_buffer_end
-m_buffer_start
;
66 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
69 delete[] m_buffer_start
;
72 m_buffer_start
= NULL
;
78 m_buffer_start
= new char[bufsize
];
79 m_buffer_end
= m_buffer_start
+ bufsize
;
81 m_buffer_pos
= m_buffer_end
;
83 m_buffer_pos
= m_buffer_start
;
84 m_buffer_size
= bufsize
;
87 void wxStreamBuffer::ResetBuffer()
90 m_buffer_pos
= m_buffer_end
;
92 m_buffer_pos
= m_buffer_start
;
95 void wxStreamBuffer::Read(void *buffer
, size_t size
)
97 wxASSERT(m_istream
!= NULL
);
100 // Buffering disabled
101 // ------------------
103 if (!m_buffer_size
) {
104 m_istream
->m_lastread
= m_istream
->DoRead(buffer
, size
);
111 size_t buf_left
, orig_size
= size
;
115 buf_left
= m_buffer_end
- m_buffer_pos
;
117 // First case: the requested buffer is larger than the stream buffer,
119 if (size
> buf_left
) {
120 memcpy(buffer
, m_buffer_pos
, buf_left
);
122 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
124 read_ret
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
);
128 m_istream
->m_lastread
= orig_size
-size
;
129 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
132 m_buffer_end
= m_buffer_start
+read_ret
;
133 m_buffer_pos
= m_buffer_start
;
137 // Second case: we just copy from the stream buffer.
138 memcpy(buffer
, m_buffer_pos
, size
);
139 m_buffer_pos
+= size
;
143 m_istream
->m_lastread
= orig_size
;
146 void wxStreamBuffer::Write(const void *buffer
, size_t size
)
148 wxASSERT(m_ostream
!= NULL
);
150 // ------------------
151 // Buffering disabled
152 // ------------------
154 if (!m_buffer_size
) {
155 m_ostream
->m_lastwrite
= m_ostream
->DoWrite(buffer
, size
);
159 // ------------------
161 // ------------------
163 size_t buf_left
, orig_size
= size
;
167 buf_left
= m_buffer_end
- m_buffer_pos
;
169 // First case: the buffer to write is larger than the stream buffer,
171 if (size
> buf_left
) {
172 memcpy(m_buffer_pos
, buffer
, buf_left
);
174 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
176 write_ret
= m_ostream
->DoWrite(m_buffer_start
, m_buffer_size
);
177 if (write_ret
!= m_buffer_size
) {
178 m_ostream
->m_bad
= TRUE
;
179 m_ostream
->m_lastwrite
= orig_size
-size
;
180 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
183 m_buffer_pos
= m_buffer_start
;
187 // Second case: just copy it in the stream buffer.
189 memcpy(m_buffer_pos
, buffer
, size
);
190 m_buffer_pos
+= size
;
194 m_ostream
->m_lastwrite
= orig_size
;
197 // ----------------------------------------------------------------------------
199 // ----------------------------------------------------------------------------
201 wxInputStream::wxInputStream()
203 m_i_destroybuf
= TRUE
;
204 m_i_streambuf
= new wxStreamBuffer(*this);
208 wxInputStream::wxInputStream(wxStreamBuffer
*buffer
)
210 m_i_destroybuf
= FALSE
;
211 m_i_streambuf
= buffer
;
215 wxInputStream::~wxInputStream()
218 delete m_i_streambuf
;
221 char wxInputStream::GetC()
224 m_i_streambuf
->Read(&c
, 1);
228 wxInputStream
& wxInputStream::Read(void *buffer
, size_t size
)
230 m_i_streambuf
->Read(buffer
, size
);
231 // wxStreamBuffer sets all variables for us
235 #define BUF_TEMP_SIZE 10000
237 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
239 char buf
[BUF_TEMP_SIZE
];
240 size_t bytes_read
= BUF_TEMP_SIZE
;
242 while (bytes_read
== BUF_TEMP_SIZE
&& !stream_out
.Bad()) {
243 bytes_read
= Read(buf
, bytes_read
).LastRead();
245 stream_out
.Write(buf
, bytes_read
);
250 wxInputStream
& wxInputStream::operator>>(wxString
& line
)
252 wxDataInputStream
s(*this);
258 wxInputStream
& wxInputStream::operator>>(char& c
)
264 wxInputStream
& wxInputStream::operator>>(short& i
)
273 wxInputStream
& wxInputStream::operator>>(long& i
)
275 /* I only implemented a simple integer parser */
278 while (isspace( c
= GetC() ) )
282 if (! (c
== '-' || isdigit(c
)) ) {
283 InputStreamBuffer()->WriteBack(c
);
303 wxInputStream
& wxInputStream::operator>>(float& f
)
305 /* I only implemented a simple float parser */
308 while (isspace( c
= GetC() ) )
312 if (! (c
== '-' || isdigit(c
)) ) {
313 InputStreamBuffer()->WriteBack(c
);
329 float f_multiplicator
= 0.1;
333 f
+= c
*f_multiplicator
;
334 f_multiplicator
/= 10;
344 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
350 if ( (unsigned)abs (DoTellInput()-pos
) > m_i_streambuf
->GetLastAccess() ) {
351 ret_off
= DoSeekInput(pos
, wxFromStart
);
352 m_i_streambuf
->ResetBuffer();
355 m_i_streambuf
->SetIntPosition(DoTellInput() - pos
);
359 if ( ((unsigned)pos
> m_i_streambuf
->GetLastAccess()) || (pos
< 0) ) {
360 ret_off
= DoSeekInput(pos
, wxFromCurrent
);
361 m_i_streambuf
->ResetBuffer();
364 m_i_streambuf
->SetIntPosition(pos
);
368 // Hard to compute: always seek to the requested position.
369 ret_off
= DoSeekInput(pos
, wxFromEnd
);
370 m_i_streambuf
->ResetBuffer();
373 return wxInvalidOffset
;
376 off_t
wxInputStream::TellI() const
378 return DoTellInput() - m_i_streambuf
->GetLastAccess() +
379 m_i_streambuf
->GetIntPosition();
382 // ----------------------------------------------------------------------------
384 // ----------------------------------------------------------------------------
385 wxOutputStream::wxOutputStream()
387 m_o_destroybuf
= TRUE
;
388 m_o_streambuf
= new wxStreamBuffer(*this);
391 wxOutputStream::wxOutputStream(wxStreamBuffer
*buffer
)
393 m_o_destroybuf
= FALSE
;
394 m_o_streambuf
= buffer
;
397 wxOutputStream::~wxOutputStream()
400 delete m_o_streambuf
;
403 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
405 m_o_streambuf
->Write(buffer
, size
);
409 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
411 stream_in
.Read(*this);
415 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
421 if ( (unsigned)abs (DoTellOutput()-pos
) > m_o_streambuf
->GetLastAccess() ) {
422 ret_off
= DoSeekOutput(pos
, wxFromStart
);
423 m_o_streambuf
->ResetBuffer();
426 m_o_streambuf
->SetIntPosition( DoTellOutput() - pos
);
430 if ( ((unsigned)pos
> m_o_streambuf
->GetLastAccess()) || (pos
< 0) ) {
431 ret_off
= DoSeekOutput(pos
, wxFromCurrent
);
432 m_o_streambuf
->ResetBuffer();
435 m_o_streambuf
->SetIntPosition(pos
);
439 // Hard to compute: always seek to the requested position.
440 ret_off
= DoSeekOutput(pos
, wxFromEnd
);
441 m_o_streambuf
->ResetBuffer();
444 return wxInvalidOffset
;
447 off_t
wxOutputStream::TellO() const
449 return DoTellOutput() - m_o_streambuf
->GetLastAccess()
450 + m_o_streambuf
->GetIntPosition();
453 void wxOutputStream::Sync()
455 DoWrite(m_o_streambuf
->GetBufferStart(), m_o_streambuf
->GetIntPosition());
457 m_o_streambuf
->ResetBuffer();
460 wxOutputStream
& wxOutputStream::operator<<(const char *string
)
462 return Write(string
, strlen(string
));
465 wxOutputStream
& wxOutputStream::operator<<(wxString
& string
)
467 return Write(string
, string
.Len());
470 wxOutputStream
& wxOutputStream::operator<<(char c
)
475 wxOutputStream
& wxOutputStream::operator<<(short i
)
479 strint
.Printf("%i", i
);
480 return Write(strint
, strint
.Len());
483 wxOutputStream
& wxOutputStream::operator<<(int i
)
487 strint
.Printf("%i", i
);
488 return Write(strint
, strint
.Len());
491 wxOutputStream
& wxOutputStream::operator<<(long i
)
495 strlong
.Printf("%i", i
);
496 return Write((const char *)strlong
, strlong
.Len());
499 wxOutputStream
& wxOutputStream::operator<<(double f
)
503 strfloat
.Printf("%f", f
);
504 return Write(strfloat
, strfloat
.Len());
507 // ----------------------------------------------------------------------------
508 // wxFilterInputStream
509 // ----------------------------------------------------------------------------
510 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
511 : wxInputStream(NULL
)
513 m_parent_i_stream
= &stream
;
514 m_i_streambuf
= stream
.InputStreamBuffer();
517 wxFilterInputStream::~wxFilterInputStream()
521 size_t wxFilterInputStream::DoRead(void *buffer
, size_t size
)
523 return m_parent_i_stream
->Read(buffer
, size
).LastRead();
526 off_t
wxFilterInputStream::DoSeekInput(off_t pos
, wxSeekMode mode
)
528 return m_parent_i_stream
->SeekI(pos
, mode
);
531 off_t
wxFilterInputStream::DoTellInput() const
533 return m_parent_i_stream
->TellI();
537 // ----------------------------------------------------------------------------
538 // wxFilterOutputStream
539 // ----------------------------------------------------------------------------
540 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
541 : wxOutputStream(NULL
)
543 m_parent_o_stream
= &stream
;
544 m_o_streambuf
= stream
.OutputStreamBuffer();
547 wxFilterOutputStream::~wxFilterOutputStream()
551 size_t wxFilterOutputStream::DoWrite(const void *buffer
, size_t size
)
553 return m_parent_o_stream
->Write(buffer
, size
).LastWrite();
556 off_t
wxFilterOutputStream::DoSeekOutput(off_t pos
, wxSeekMode mode
)
558 return m_parent_o_stream
->SeekO(pos
, mode
);
561 off_t
wxFilterOutputStream::DoTellOutput() const
563 return m_parent_o_stream
->TellO();
566 // ----------------------------------------------------------------------------
567 // Some IOManip function
568 // ----------------------------------------------------------------------------
570 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
573 return stream
.Write("\r\n", 2);
575 return stream
.Write("\n", 1);