]>
git.saurik.com Git - wxWidgets.git/blob - src/common/stream.cpp
34b9f1be7d2d3176164effca20d1e5e8da35a079
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
60 void wxStreamBuffer::SetBufferIO(char *buffer_start
, char *buffer_end
)
62 m_buffer_pos
= m_buffer_start
= buffer_start
;
63 m_buffer_end
= buffer_end
;
65 m_buffer_size
= m_buffer_end
-m_buffer_start
;
68 void wxStreamBuffer::SetBufferIO(size_t bufsize
)
71 delete[] m_buffer_start
;
74 m_buffer_start
= NULL
;
80 m_buffer_start
= new char[bufsize
];
81 m_buffer_end
= m_buffer_start
+ bufsize
;
83 m_buffer_pos
= m_buffer_end
;
85 m_buffer_pos
= m_buffer_start
;
86 m_buffer_size
= bufsize
;
89 void wxStreamBuffer::ResetBuffer()
92 m_buffer_pos
= m_buffer_end
;
94 m_buffer_pos
= m_buffer_start
;
97 void wxStreamBuffer::Read(void *buffer
, size_t size
)
99 wxASSERT(m_istream
!= NULL
);
101 // ------------------
102 // Buffering disabled
103 // ------------------
105 if (!m_buffer_size
) {
106 m_istream
->m_lastread
= m_istream
->DoRead(buffer
, size
);
113 size_t buf_left
, orig_size
= size
;
117 buf_left
= m_buffer_end
- m_buffer_pos
;
119 // First case: the requested buffer is larger than the stream buffer,
121 if (size
> buf_left
) {
122 memcpy(buffer
, m_buffer_pos
, buf_left
);
124 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
126 read_ret
= m_istream
->DoRead(m_buffer_start
, m_buffer_size
);
130 m_istream
->m_lastread
= orig_size
-size
;
131 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
134 m_buffer_end
= m_buffer_start
+read_ret
;
135 m_buffer_pos
= m_buffer_start
;
139 // Second case: we just copy from the stream buffer.
140 memcpy(buffer
, m_buffer_pos
, size
);
141 m_buffer_pos
+= size
;
145 m_istream
->m_lastread
= orig_size
;
148 void wxStreamBuffer::Write(const void *buffer
, size_t size
)
150 wxASSERT(m_ostream
!= NULL
);
152 // ------------------
153 // Buffering disabled
154 // ------------------
156 if (!m_buffer_size
) {
157 m_ostream
->m_lastwrite
= m_ostream
->DoWrite(buffer
, size
);
161 // ------------------
163 // ------------------
165 size_t buf_left
, orig_size
= size
;
169 buf_left
= m_buffer_end
- m_buffer_pos
;
171 // First case: the buffer to write is larger than the stream buffer,
173 if (size
> buf_left
) {
174 memcpy(m_buffer_pos
, buffer
, buf_left
);
176 buffer
= (char *)buffer
+ buf_left
; // ANSI C++ violation.
178 write_ret
= m_ostream
->DoWrite(m_buffer_start
, m_buffer_size
);
179 if (write_ret
!= m_buffer_size
) {
180 m_ostream
->m_bad
= TRUE
;
181 m_ostream
->m_lastwrite
= orig_size
-size
;
182 m_buffer_pos
= m_buffer_end
= m_buffer_start
;
185 m_buffer_pos
= m_buffer_start
;
189 // Second case: just copy it in the stream buffer.
191 memcpy(m_buffer_pos
, buffer
, size
);
192 m_buffer_pos
+= size
;
196 m_ostream
->m_lastwrite
= orig_size
;
199 // ----------------------------------------------------------------------------
201 // ----------------------------------------------------------------------------
203 wxInputStream::wxInputStream()
205 m_i_destroybuf
= TRUE
;
206 m_i_streambuf
= new wxStreamBuffer(*this);
210 wxInputStream::wxInputStream(wxStreamBuffer
*buffer
)
212 m_i_destroybuf
= FALSE
;
213 m_i_streambuf
= buffer
;
217 wxInputStream::~wxInputStream()
220 delete m_i_streambuf
;
223 char wxInputStream::GetC()
226 m_i_streambuf
->Read(&c
, 1);
230 wxInputStream
& wxInputStream::Read(void *buffer
, size_t size
)
232 m_i_streambuf
->Read(buffer
, size
);
233 // wxStreamBuffer sets all variables for us
237 #define BUF_TEMP_SIZE 10000
239 wxInputStream
& wxInputStream::Read(wxOutputStream
& stream_out
)
241 char buf
[BUF_TEMP_SIZE
];
242 size_t bytes_read
= BUF_TEMP_SIZE
;
244 while (bytes_read
== BUF_TEMP_SIZE
&& !stream_out
.Bad()) {
245 bytes_read
= Read(buf
, bytes_read
).LastRead();
247 stream_out
.Write(buf
, bytes_read
);
252 wxInputStream
& wxInputStream::operator>>(wxString
& line
)
254 wxDataInputStream
s(*this);
260 wxInputStream
& wxInputStream::operator>>(char& c
)
266 wxInputStream
& wxInputStream::operator>>(short& i
)
275 wxInputStream
& wxInputStream::operator>>(int& i
)
284 wxInputStream
& wxInputStream::operator>>(long& i
)
286 /* I only implemented a simple integer parser */
289 while (isspace( c
= GetC() ) )
293 if (! (c
== '-' || isdigit(c
)) ) {
294 InputStreamBuffer()->WriteBack(c
);
314 wxInputStream
& wxInputStream::operator>>(float& f
)
316 /* I only implemented a simple float parser */
319 while (isspace( c
= GetC() ) )
323 if (! (c
== '-' || isdigit(c
)) ) {
324 InputStreamBuffer()->WriteBack(c
);
340 float f_multiplicator
= 0.1;
344 f
+= c
*f_multiplicator
;
345 f_multiplicator
/= 10;
355 wxInputStream
& wxInputStream::operator>>(wxObject
*& obj
)
357 wxObjectInputStream
obj_s(*this);
358 obj
= obj_s
.LoadObject();
362 off_t
wxInputStream::SeekI(off_t pos
, wxSeekMode mode
)
368 if ( (unsigned)abs (DoTellInput()-pos
) > m_i_streambuf
->GetLastAccess() ) {
369 ret_off
= DoSeekInput(pos
, wxFromStart
);
370 m_i_streambuf
->ResetBuffer();
373 m_i_streambuf
->SetIntPosition(DoTellInput() - pos
);
377 if ( ((unsigned)pos
> m_i_streambuf
->GetLastAccess()) || (pos
< 0) ) {
378 ret_off
= DoSeekInput(pos
, wxFromCurrent
);
379 m_i_streambuf
->ResetBuffer();
382 m_i_streambuf
->SetIntPosition(pos
);
386 // Hard to compute: always seek to the requested position.
387 ret_off
= DoSeekInput(pos
, wxFromEnd
);
388 m_i_streambuf
->ResetBuffer();
391 return wxInvalidOffset
;
394 off_t
wxInputStream::TellI() const
396 return DoTellInput() - m_i_streambuf
->GetLastAccess() +
397 m_i_streambuf
->GetIntPosition();
400 // ----------------------------------------------------------------------------
402 // ----------------------------------------------------------------------------
403 wxOutputStream::wxOutputStream()
405 m_o_destroybuf
= TRUE
;
406 m_o_streambuf
= new wxStreamBuffer(*this);
409 wxOutputStream::wxOutputStream(wxStreamBuffer
*buffer
)
411 m_o_destroybuf
= FALSE
;
412 m_o_streambuf
= buffer
;
415 wxOutputStream::~wxOutputStream()
418 delete m_o_streambuf
;
421 wxOutputStream
& wxOutputStream::Write(const void *buffer
, size_t size
)
423 m_o_streambuf
->Write(buffer
, size
);
427 wxOutputStream
& wxOutputStream::Write(wxInputStream
& stream_in
)
429 stream_in
.Read(*this);
433 off_t
wxOutputStream::SeekO(off_t pos
, wxSeekMode mode
)
439 if ( (unsigned)abs (DoTellOutput()-pos
) > m_o_streambuf
->GetLastAccess() ) {
440 ret_off
= DoSeekOutput(pos
, wxFromStart
);
441 m_o_streambuf
->ResetBuffer();
444 m_o_streambuf
->SetIntPosition( DoTellOutput() - pos
);
448 if ( ((unsigned)pos
> m_o_streambuf
->GetLastAccess()) || (pos
< 0) ) {
449 ret_off
= DoSeekOutput(pos
, wxFromCurrent
);
450 m_o_streambuf
->ResetBuffer();
453 m_o_streambuf
->SetIntPosition(pos
);
457 // Hard to compute: always seek to the requested position.
458 ret_off
= DoSeekOutput(pos
, wxFromEnd
);
459 m_o_streambuf
->ResetBuffer();
462 return wxInvalidOffset
;
465 off_t
wxOutputStream::TellO() const
467 return DoTellOutput() - m_o_streambuf
->GetLastAccess()
468 + m_o_streambuf
->GetIntPosition();
471 void wxOutputStream::Sync()
473 DoWrite(m_o_streambuf
->GetBufferStart(), m_o_streambuf
->GetIntPosition());
475 m_o_streambuf
->ResetBuffer();
478 wxOutputStream
& wxOutputStream::operator<<(const char *string
)
480 return Write(string
, strlen(string
));
483 wxOutputStream
& wxOutputStream::operator<<(wxString
& string
)
485 return Write(string
, string
.Len());
488 wxOutputStream
& wxOutputStream::operator<<(char c
)
493 wxOutputStream
& wxOutputStream::operator<<(short i
)
497 strint
.Printf("%i", i
);
498 return Write(strint
, strint
.Len());
501 wxOutputStream
& wxOutputStream::operator<<(int i
)
505 strint
.Printf("%i", i
);
506 return Write(strint
, strint
.Len());
509 wxOutputStream
& wxOutputStream::operator<<(long i
)
513 strlong
.Printf("%i", i
);
514 return Write((const char *)strlong
, strlong
.Len());
517 wxOutputStream
& wxOutputStream::operator<<(double f
)
521 strfloat
.Printf("%f", f
);
522 return Write(strfloat
, strfloat
.Len());
525 wxOutputStream
& wxOutputStream::operator<<(wxObject
& obj
)
527 wxObjectOutputStream
obj_s(*this);
528 obj_s
.SaveObject(obj
);
532 // ----------------------------------------------------------------------------
533 // wxFilterInputStream
534 // ----------------------------------------------------------------------------
535 wxFilterInputStream::wxFilterInputStream(wxInputStream
& stream
)
536 : wxInputStream(NULL
)
538 m_parent_i_stream
= &stream
;
539 m_i_streambuf
= stream
.InputStreamBuffer();
542 wxFilterInputStream::~wxFilterInputStream()
546 size_t wxFilterInputStream::DoRead(void *buffer
, size_t size
)
548 return m_parent_i_stream
->Read(buffer
, size
).LastRead();
551 off_t
wxFilterInputStream::DoSeekInput(off_t pos
, wxSeekMode mode
)
553 return m_parent_i_stream
->SeekI(pos
, mode
);
556 off_t
wxFilterInputStream::DoTellInput() const
558 return m_parent_i_stream
->TellI();
562 // ----------------------------------------------------------------------------
563 // wxFilterOutputStream
564 // ----------------------------------------------------------------------------
565 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream
& stream
)
566 : wxOutputStream(NULL
)
568 m_parent_o_stream
= &stream
;
569 m_o_streambuf
= stream
.OutputStreamBuffer();
572 wxFilterOutputStream::~wxFilterOutputStream()
576 size_t wxFilterOutputStream::DoWrite(const void *buffer
, size_t size
)
578 return m_parent_o_stream
->Write(buffer
, size
).LastWrite();
581 off_t
wxFilterOutputStream::DoSeekOutput(off_t pos
, wxSeekMode mode
)
583 return m_parent_o_stream
->SeekO(pos
, mode
);
586 off_t
wxFilterOutputStream::DoTellOutput() const
588 return m_parent_o_stream
->TellO();
591 // ----------------------------------------------------------------------------
592 // Some IOManip function
593 // ----------------------------------------------------------------------------
595 wxOutputStream
& wxEndL(wxOutputStream
& stream
)
598 return stream
.Write("\r\n", 2);
600 return stream
.Write("\n", 1);