]> git.saurik.com Git - wxWidgets.git/blame - src/common/stream.cpp
SetFont() the second
[wxWidgets.git] / src / common / stream.cpp
CommitLineData
3d4c6a21
GL
1/////////////////////////////////////////////////////////////////////////////
2// Name: stream.cpp
3// Purpose: wxStream base classes
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 11/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Guilhem Lavaux
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "stream.h"
14#endif
15
db138a4c
JS
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
6d44bf31 18#include <ctype.h>
79c3e0e1 19#include <wx/stream.h>
6d44bf31 20#include <wx/datstrm.h>
123a7fdd 21#include <wx/objstrm.h>
db138a4c
JS
22
23#ifdef __BORLANDC__
24#pragma hdrstop
25#endif
26
6d44bf31
GL
27// ----------------------------------------------------------------------------
28// wxStreamBuffer
29// ----------------------------------------------------------------------------
30
31wxStreamBuffer::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)
34{
35}
36
37wxStreamBuffer::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)
40{
41}
42
43wxStreamBuffer::~wxStreamBuffer()
44{
6f34921d 45 wxDELETEA(m_buffer_start);
6d44bf31
GL
46}
47
48void wxStreamBuffer::WriteBack(char c)
49{
50 if (m_ostream)
51 return;
52
53 // Assume that if we write "back" we have read a few bytes: so we have some
54 // space.
f4a8c29f
GL
55 if (m_buffer_pos == m_buffer_start)
56 return;
6d44bf31
GL
57
58 m_buffer_pos--;
59 *m_buffer_pos = c;
60}
61
62void wxStreamBuffer::SetBufferIO(char *buffer_start, char *buffer_end)
63{
885ee235
GL
64 size_t ret;
65
66 m_buffer_start = buffer_start;
67 m_buffer_end = buffer_end;
6d44bf31
GL
68
69 m_buffer_size = m_buffer_end-m_buffer_start;
885ee235
GL
70
71 if (m_istream) {
72 ret = m_istream->DoRead(m_buffer_start, m_buffer_size);
73 m_buffer_end = m_buffer_start + ret;
74 }
75 m_buffer_pos = m_buffer_start;
6d44bf31
GL
76}
77
78void wxStreamBuffer::SetBufferIO(size_t bufsize)
79{
885ee235
GL
80 char *b_start;
81
82 wxDELETE(m_buffer_start);
6d44bf31
GL
83
84 if (!bufsize) {
85 m_buffer_start = NULL;
86 m_buffer_end = NULL;
87 m_buffer_pos = NULL;
88 m_buffer_size = 0;
885ee235 89 return;
6d44bf31
GL
90 }
91
885ee235
GL
92 b_start = new char[bufsize];
93
94 SetBufferIO(b_start, b_start + bufsize);
6d44bf31
GL
95}
96
97void wxStreamBuffer::ResetBuffer()
98{
99 if (m_istream)
100 m_buffer_pos = m_buffer_end;
101 else
102 m_buffer_pos = m_buffer_start;
103}
104
105void wxStreamBuffer::Read(void *buffer, size_t size)
106{
107 wxASSERT(m_istream != NULL);
108
109 // ------------------
110 // Buffering disabled
111 // ------------------
112
113 if (!m_buffer_size) {
114 m_istream->m_lastread = m_istream->DoRead(buffer, size);
115 return;
116 }
117
118 // -----------------
119 // Buffering enabled
120 // -----------------
121 size_t buf_left, orig_size = size;
122 size_t read_ret;
123
124 while (size > 0) {
125 buf_left = m_buffer_end - m_buffer_pos;
126
127 // First case: the requested buffer is larger than the stream buffer,
128 // we split
129 if (size > buf_left) {
130 memcpy(buffer, m_buffer_pos, buf_left);
131 size -= buf_left;
132 buffer = (char *)buffer + buf_left; // ANSI C++ violation.
133
134 read_ret = m_istream->DoRead(m_buffer_start, m_buffer_size);
135
885ee235 136 // Read failed: EOF
6d44bf31
GL
137 if (read_ret == 0) {
138 m_istream->m_lastread = orig_size-size;
885ee235 139 m_istream->m_eof = TRUE;
6d44bf31
GL
140 m_buffer_pos = m_buffer_end = m_buffer_start;
141 return;
142 } else {
143 m_buffer_end = m_buffer_start+read_ret;
144 m_buffer_pos = m_buffer_start;
145 }
146 } else {
147
148 // Second case: we just copy from the stream buffer.
149 memcpy(buffer, m_buffer_pos, size);
150 m_buffer_pos += size;
151 break;
152 }
153 }
154 m_istream->m_lastread = orig_size;
155}
156
157void wxStreamBuffer::Write(const void *buffer, size_t size)
158{
159 wxASSERT(m_ostream != NULL);
160
161 // ------------------
162 // Buffering disabled
163 // ------------------
164
165 if (!m_buffer_size) {
166 m_ostream->m_lastwrite = m_ostream->DoWrite(buffer, size);
167 return;
168 }
169
170 // ------------------
171 // Buffering enabled
172 // ------------------
173
174 size_t buf_left, orig_size = size;
175 size_t write_ret;
176
177 while (size > 0) {
178 buf_left = m_buffer_end - m_buffer_pos;
179
180 // First case: the buffer to write is larger than the stream buffer,
181 // we split it
182 if (size > buf_left) {
183 memcpy(m_buffer_pos, buffer, buf_left);
184 size -= buf_left;
185 buffer = (char *)buffer + buf_left; // ANSI C++ violation.
186
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;
192 return;
193 }
194 m_buffer_pos = m_buffer_start;
195
196 } else {
197
198 // Second case: just copy it in the stream buffer.
199
200 memcpy(m_buffer_pos, buffer, size);
201 m_buffer_pos += size;
202 break;
203 }
204 }
205 m_ostream->m_lastwrite = orig_size;
206}
207
1678ad78
GL
208// ----------------------------------------------------------------------------
209// wxInputStream
210// ----------------------------------------------------------------------------
211
3d4c6a21 212wxInputStream::wxInputStream()
3d4c6a21 213{
6d44bf31
GL
214 m_i_destroybuf = TRUE;
215 m_i_streambuf = new wxStreamBuffer(*this);
7a4b9130 216 m_eof = FALSE;
f4a8c29f 217 m_lastread = 0;
6d44bf31
GL
218}
219
220wxInputStream::wxInputStream(wxStreamBuffer *buffer)
221{
222 m_i_destroybuf = FALSE;
223 m_i_streambuf = buffer;
7a4b9130 224 m_eof = FALSE;
f4a8c29f 225 m_lastread = 0;
3d4c6a21
GL
226}
227
228wxInputStream::~wxInputStream()
229{
6d44bf31
GL
230 if (m_i_destroybuf)
231 delete m_i_streambuf;
232}
233
234char wxInputStream::GetC()
235{
236 char c;
237 m_i_streambuf->Read(&c, 1);
238 return c;
239}
240
241wxInputStream& wxInputStream::Read(void *buffer, size_t size)
242{
243 m_i_streambuf->Read(buffer, size);
244 // wxStreamBuffer sets all variables for us
245 return *this;
3d4c6a21
GL
246}
247
248#define BUF_TEMP_SIZE 10000
249
250wxInputStream& wxInputStream::Read(wxOutputStream& stream_out)
251{
252 char buf[BUF_TEMP_SIZE];
253 size_t bytes_read = BUF_TEMP_SIZE;
254
255 while (bytes_read == BUF_TEMP_SIZE && !stream_out.Bad()) {
256 bytes_read = Read(buf, bytes_read).LastRead();
257
258 stream_out.Write(buf, bytes_read);
259 }
260 return *this;
261}
262
1678ad78
GL
263wxInputStream& wxInputStream::operator>>(wxString& line)
264{
265 wxDataInputStream s(*this);
266
267 line = s.ReadLine();
268 return *this;
269}
270
271wxInputStream& wxInputStream::operator>>(char& c)
272{
273 c = GetC();
6d44bf31 274 return *this;
1678ad78
GL
275}
276
277wxInputStream& wxInputStream::operator>>(short& i)
278{
6d44bf31
GL
279 long l;
280
281 *this >> l;
282 i = (short)l;
1678ad78
GL
283 return *this;
284}
285
123a7fdd
GL
286wxInputStream& wxInputStream::operator>>(int& i)
287{
288 long l;
289
290 *this >> l;
291 i = (short)l;
292 return *this;
293}
294
1678ad78
GL
295wxInputStream& wxInputStream::operator>>(long& i)
296{
6d44bf31
GL
297 /* I only implemented a simple integer parser */
298 int c, sign;
299
300 while (isspace( c = GetC() ) )
301 /* Do nothing */ ;
302
303 i = 0;
304 if (! (c == '-' || isdigit(c)) ) {
305 InputStreamBuffer()->WriteBack(c);
306 return *this;
307 }
308
309 if (c == '-') {
310 sign = -1;
311 c = GetC();
312 } else
313 sign = 1;
314
315 while (isdigit(c)) {
316 i = i*10 + c;
317 c = GetC();
318 }
319
320 i *= sign;
321
1678ad78
GL
322 return *this;
323}
324
325wxInputStream& wxInputStream::operator>>(float& f)
326{
6d44bf31
GL
327 /* I only implemented a simple float parser */
328 int c, sign;
329
330 while (isspace( c = GetC() ) )
331 /* Do nothing */ ;
332
333 f = 0.0;
334 if (! (c == '-' || isdigit(c)) ) {
335 InputStreamBuffer()->WriteBack(c);
336 return *this;
337 }
338
339 if (c == '-') {
340 sign = -1;
341 c = GetC();
342 } else
343 sign = 1;
344
345 while (isdigit(c)) {
346 f = f*10 + c;
347 c = GetC();
348 }
349
350 if (c == '.') {
351 float f_multiplicator = 0.1;
352 c = GetC();
353
354 while (isdigit(c)) {
355 f += c*f_multiplicator;
356 f_multiplicator /= 10;
357 c = GetC();
358 }
359 }
360
361 f *= sign;
362
1678ad78
GL
363 return *this;
364}
365
123a7fdd
GL
366wxInputStream& wxInputStream::operator>>(wxObject *& obj)
367{
368 wxObjectInputStream obj_s(*this);
369 obj = obj_s.LoadObject();
370 return *this;
371}
372
6d44bf31
GL
373off_t wxInputStream::SeekI(off_t pos, wxSeekMode mode)
374{
885ee235
GL
375 off_t ret_off, diff, last_access;
376
377 last_access = m_i_streambuf->GetLastAccess();
6d44bf31
GL
378
379 switch (mode) {
380 case wxFromStart:
885ee235
GL
381 diff = DoTellInput() - pos;
382 if ( diff < 0 || diff > last_access ) {
6d44bf31
GL
383 ret_off = DoSeekInput(pos, wxFromStart);
384 m_i_streambuf->ResetBuffer();
385 return ret_off;
386 } else {
885ee235 387 m_i_streambuf->SetIntPosition(last_access - diff);
6d44bf31
GL
388 return pos;
389 }
390 case wxFromCurrent:
885ee235
GL
391 diff = pos + m_i_streambuf->GetIntPosition();
392
393 if ( (diff > last_access) || (diff < 0) ) {
6d44bf31
GL
394 ret_off = DoSeekInput(pos, wxFromCurrent);
395 m_i_streambuf->ResetBuffer();
396 return ret_off;
397 } else {
885ee235 398 m_i_streambuf->SetIntPosition(diff);
6d44bf31
GL
399 return pos;
400 }
401 case wxFromEnd:
402 // Hard to compute: always seek to the requested position.
403 ret_off = DoSeekInput(pos, wxFromEnd);
404 m_i_streambuf->ResetBuffer();
405 return ret_off;
406 }
407 return wxInvalidOffset;
408}
409
410off_t wxInputStream::TellI() const
411{
412 return DoTellInput() - m_i_streambuf->GetLastAccess() +
413 m_i_streambuf->GetIntPosition();
414}
415
1678ad78
GL
416// ----------------------------------------------------------------------------
417// wxOutputStream
418// ----------------------------------------------------------------------------
3d4c6a21 419wxOutputStream::wxOutputStream()
3d4c6a21 420{
6d44bf31
GL
421 m_o_destroybuf = TRUE;
422 m_o_streambuf = new wxStreamBuffer(*this);
f4a8c29f
GL
423 m_bad = FALSE;
424 m_lastwrite = 0;
6d44bf31
GL
425}
426
427wxOutputStream::wxOutputStream(wxStreamBuffer *buffer)
428{
429 m_o_destroybuf = FALSE;
430 m_o_streambuf = buffer;
f4a8c29f
GL
431 m_bad = FALSE;
432 m_lastwrite = 0;
3d4c6a21
GL
433}
434
435wxOutputStream::~wxOutputStream()
436{
6d44bf31
GL
437 if (m_o_destroybuf)
438 delete m_o_streambuf;
439}
440
441wxOutputStream& wxOutputStream::Write(const void *buffer, size_t size)
442{
443 m_o_streambuf->Write(buffer, size);
444 return *this;
3d4c6a21
GL
445}
446
447wxOutputStream& wxOutputStream::Write(wxInputStream& stream_in)
448{
6d44bf31
GL
449 stream_in.Read(*this);
450 return *this;
451}
452
453off_t wxOutputStream::SeekO(off_t pos, wxSeekMode mode)
454{
455 off_t ret_off;
456
457 switch (mode) {
458 case wxFromStart:
459 if ( (unsigned)abs (DoTellOutput()-pos) > m_o_streambuf->GetLastAccess() ) {
460 ret_off = DoSeekOutput(pos, wxFromStart);
461 m_o_streambuf->ResetBuffer();
462 return ret_off;
463 } else {
464 m_o_streambuf->SetIntPosition( DoTellOutput() - pos);
465 return pos;
466 }
467 case wxFromCurrent:
468 if ( ((unsigned)pos > m_o_streambuf->GetLastAccess()) || (pos < 0) ) {
469 ret_off = DoSeekOutput(pos, wxFromCurrent);
470 m_o_streambuf->ResetBuffer();
471 return ret_off;
472 } else {
473 m_o_streambuf->SetIntPosition(pos);
474 return pos;
475 }
476 case wxFromEnd:
477 // Hard to compute: always seek to the requested position.
478 ret_off = DoSeekOutput(pos, wxFromEnd);
479 m_o_streambuf->ResetBuffer();
480 return ret_off;
481 }
482 return wxInvalidOffset;
483}
484
485off_t wxOutputStream::TellO() const
486{
487 return DoTellOutput() - m_o_streambuf->GetLastAccess()
488 + m_o_streambuf->GetIntPosition();
489}
490
491void wxOutputStream::Sync()
492{
493 DoWrite(m_o_streambuf->GetBufferStart(), m_o_streambuf->GetIntPosition());
494
495 m_o_streambuf->ResetBuffer();
496}
497
498wxOutputStream& wxOutputStream::operator<<(const char *string)
499{
500 return Write(string, strlen(string));
501}
502
503wxOutputStream& wxOutputStream::operator<<(wxString& string)
504{
505 return Write(string, string.Len());
506}
507
508wxOutputStream& wxOutputStream::operator<<(char c)
509{
510 return Write(&c, 1);
511}
512
513wxOutputStream& wxOutputStream::operator<<(short i)
514{
515 wxString strint;
516
517 strint.Printf("%i", i);
518 return Write(strint, strint.Len());
519}
520
521wxOutputStream& wxOutputStream::operator<<(int i)
522{
523 wxString strint;
524
525 strint.Printf("%i", i);
526 return Write(strint, strint.Len());
527}
528
529wxOutputStream& wxOutputStream::operator<<(long i)
530{
531 wxString strlong;
532
533 strlong.Printf("%i", i);
534 return Write((const char *)strlong, strlong.Len());
535}
536
537wxOutputStream& wxOutputStream::operator<<(double f)
538{
539 wxString strfloat;
540
541 strfloat.Printf("%f", f);
542 return Write(strfloat, strfloat.Len());
3d4c6a21
GL
543}
544
123a7fdd
GL
545wxOutputStream& wxOutputStream::operator<<(wxObject& obj)
546{
547 wxObjectOutputStream obj_s(*this);
548 obj_s.SaveObject(obj);
549 return *this;
550}
551
f4ada568
GL
552// ----------------------------------------------------------------------------
553// wxStream
554// ----------------------------------------------------------------------------
555
556wxStream::wxStream()
557 : wxInputStream(), wxOutputStream()
558{
559}
560
1678ad78
GL
561// ----------------------------------------------------------------------------
562// wxFilterInputStream
563// ----------------------------------------------------------------------------
f4ada568
GL
564wxFilterInputStream::wxFilterInputStream()
565 : wxInputStream(NULL)
566{
567}
568
3d4c6a21 569wxFilterInputStream::wxFilterInputStream(wxInputStream& stream)
6d44bf31 570 : wxInputStream(NULL)
3d4c6a21 571{
219f895a 572 m_parent_i_stream = &stream;
6d44bf31 573 m_i_streambuf = stream.InputStreamBuffer();
3d4c6a21
GL
574}
575
576wxFilterInputStream::~wxFilterInputStream()
577{
578}
219f895a 579
6d44bf31
GL
580size_t wxFilterInputStream::DoRead(void *buffer, size_t size)
581{
582 return m_parent_i_stream->Read(buffer, size).LastRead();
583}
584
585off_t wxFilterInputStream::DoSeekInput(off_t pos, wxSeekMode mode)
586{
587 return m_parent_i_stream->SeekI(pos, mode);
588}
589
590off_t wxFilterInputStream::DoTellInput() const
591{
592 return m_parent_i_stream->TellI();
593}
594
1678ad78
GL
595// ----------------------------------------------------------------------------
596// wxFilterOutputStream
597// ----------------------------------------------------------------------------
f4ada568
GL
598wxFilterOutputStream::wxFilterOutputStream()
599 : wxOutputStream(NULL)
600{
601}
602
219f895a 603wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream)
6d44bf31 604 : wxOutputStream(NULL)
219f895a
RR
605{
606 m_parent_o_stream = &stream;
6d44bf31 607 m_o_streambuf = stream.OutputStreamBuffer();
219f895a
RR
608}
609
610wxFilterOutputStream::~wxFilterOutputStream()
611{
612}
6d44bf31
GL
613
614size_t wxFilterOutputStream::DoWrite(const void *buffer, size_t size)
615{
616 return m_parent_o_stream->Write(buffer, size).LastWrite();
617}
618
619off_t wxFilterOutputStream::DoSeekOutput(off_t pos, wxSeekMode mode)
620{
621 return m_parent_o_stream->SeekO(pos, mode);
622}
623
624off_t wxFilterOutputStream::DoTellOutput() const
625{
626 return m_parent_o_stream->TellO();
627}
628
f4ada568
GL
629// ----------------------------------------------------------------------------
630// wxFilterStream
631// ----------------------------------------------------------------------------
632
633wxFilterStream::wxFilterStream()
634{
635}
636
637wxFilterStream::wxFilterStream(wxStream& stream)
638 : wxFilterInputStream(stream), wxFilterOutputStream(stream)
639{
640}
641
6d44bf31
GL
642// ----------------------------------------------------------------------------
643// Some IOManip function
644// ----------------------------------------------------------------------------
645
646wxOutputStream& wxEndL(wxOutputStream& stream)
647{
648#ifdef __MSW__
649 return stream.Write("\r\n", 2);
650#else
651 return stream.Write("\n", 1);
652#endif
653}