]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/stream.cpp
O_BINARY added to wxFile::Create
[wxWidgets.git] / src / common / stream.cpp
... / ...
CommitLineData
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
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20 #pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24 #include "wx/defs.h"
25#endif
26
27#if wxUSE_STREAMS
28
29#include <ctype.h>
30#include "wx/stream.h"
31#include "wx/datstrm.h"
32#include "wx/objstrm.h"
33
34#define BUF_TEMP_SIZE 10000
35
36// ----------------------------------------------------------------------------
37// wxStreamBuffer
38// ----------------------------------------------------------------------------
39
40#define CHECK_ERROR(err) \
41 if (m_stream->m_lasterror == wxStream_NOERROR) \
42 m_stream->m_lasterror = err
43
44wxStreamBuffer::wxStreamBuffer(wxStreamBase& stream, BufMode mode)
45 : m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
46 m_buffer_size(0), m_fixed(TRUE), m_flushable(TRUE), m_stream(&stream),
47 m_mode(mode), m_destroybuf(FALSE), m_destroystream(FALSE)
48{
49}
50
51wxStreamBuffer::wxStreamBuffer(BufMode mode)
52 : m_buffer_start(NULL), m_buffer_end(NULL), m_buffer_pos(NULL),
53 m_buffer_size(0), m_fixed(TRUE), m_flushable(FALSE), m_stream(NULL),
54 m_mode(mode), m_destroybuf(FALSE), m_destroystream(TRUE)
55{
56 m_stream = new wxStreamBase();
57}
58
59wxStreamBuffer::wxStreamBuffer(const wxStreamBuffer& buffer)
60{
61 m_buffer_start = buffer.m_buffer_start;
62 m_buffer_end = buffer.m_buffer_end;
63 m_buffer_pos = buffer.m_buffer_pos;
64 m_buffer_size = buffer.m_buffer_size;
65 m_fixed = buffer.m_fixed;
66 m_flushable = buffer.m_flushable;
67 m_stream = buffer.m_stream;
68 m_mode = buffer.m_mode;
69 m_destroybuf = FALSE;
70 m_destroystream = FALSE;
71}
72
73wxStreamBuffer::~wxStreamBuffer()
74{
75 if (m_destroybuf)
76 wxDELETEA(m_buffer_start);
77 if (m_destroystream)
78 delete m_stream;
79}
80
81void wxStreamBuffer::SetBufferIO(char *buffer_start, char *buffer_end)
82{
83 if (m_destroybuf)
84 wxDELETEA(m_buffer_start);
85 m_buffer_start = buffer_start;
86 m_buffer_end = buffer_end;
87
88 m_buffer_size = m_buffer_end-m_buffer_start;
89 m_destroybuf = FALSE;
90 ResetBuffer();
91}
92
93void wxStreamBuffer::SetBufferIO(size_t bufsize)
94{
95 char *b_start;
96
97 if (m_destroybuf)
98 wxDELETEA(m_buffer_start);
99
100 if (!bufsize) {
101 m_buffer_start = (char*)NULL;
102 m_buffer_end = (char*)NULL;
103 m_buffer_pos = (char*)NULL;
104 m_buffer_size = 0;
105 return;
106 }
107
108 b_start = new char[bufsize];
109 SetBufferIO(b_start, b_start + bufsize);
110 m_destroybuf = TRUE;
111}
112
113void wxStreamBuffer::ResetBuffer()
114{
115 m_stream->m_lasterror = wxStream_NOERROR;
116 m_stream->m_lastcount = 0;
117 if (m_mode == read && m_flushable)
118 m_buffer_pos = m_buffer_end;
119 else
120 m_buffer_pos = m_buffer_start;
121}
122
123bool wxStreamBuffer::FillBuffer()
124{
125 size_t count;
126
127 count = m_stream->OnSysRead(m_buffer_start, m_buffer_size);
128 m_buffer_end = m_buffer_start+count;
129 m_buffer_pos = m_buffer_start;
130
131 if (count == 0)
132 return FALSE;
133 return TRUE;
134}
135
136bool wxStreamBuffer::FlushBuffer()
137{
138 size_t count, current;
139
140 if (m_buffer_pos == m_buffer_start || !m_flushable)
141 return FALSE;
142
143 current = m_buffer_pos-m_buffer_start;
144 count = m_stream->OnSysWrite(m_buffer_start, current);
145 if (count != current)
146 return FALSE;
147 m_buffer_pos = m_buffer_start;
148
149 return TRUE;
150}
151
152void wxStreamBuffer::GetFromBuffer(void *buffer, size_t size)
153{
154 size_t s_toget = m_buffer_end-m_buffer_pos;
155
156 if (size < s_toget)
157 s_toget = size;
158
159 memcpy(buffer, m_buffer_pos, s_toget);
160 m_buffer_pos += s_toget;
161}
162
163void wxStreamBuffer::PutToBuffer(const void *buffer, size_t size)
164{
165 size_t s_toput = m_buffer_end-m_buffer_pos;
166
167 if (s_toput < size && !m_fixed) {
168 if (!m_buffer_start)
169 SetBufferIO(size);
170 else {
171 size_t delta = m_buffer_pos-m_buffer_start;
172
173 m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size);
174 m_buffer_pos = m_buffer_start + delta;
175 // I round a bit
176 m_buffer_size += size;
177 m_buffer_end = m_buffer_start+m_buffer_size;
178 }
179 s_toput = size;
180 }
181 if (s_toput > size)
182 s_toput = size;
183 memcpy(m_buffer_pos, buffer, s_toput);
184 m_buffer_pos += s_toput;
185}
186
187void wxStreamBuffer::PutChar(char c)
188{
189 wxASSERT(m_stream != NULL);
190
191 if (!m_buffer_size) {
192 m_stream->OnSysWrite(&c, 1);
193 return;
194 }
195
196 if (GetDataLeft() == 0 && !FlushBuffer()) {
197 CHECK_ERROR(wxStream_WRITE_ERR);
198 return;
199 }
200
201 PutToBuffer(&c, 1);
202 m_stream->m_lastcount = 1;
203}
204
205char wxStreamBuffer::Peek()
206{
207 char c;
208
209 wxASSERT(m_stream != NULL && m_buffer_size != 0);
210
211 if (!GetDataLeft()) {
212 CHECK_ERROR(wxStream_READ_ERR);
213 return 0;
214 }
215
216 GetFromBuffer(&c, 1);
217 m_buffer_pos--;
218
219 return c;
220}
221
222char wxStreamBuffer::GetChar()
223{
224 char c;
225
226 wxASSERT(m_stream != NULL);
227
228 if (!m_buffer_size) {
229 m_stream->OnSysRead(&c, 1);
230 return c;
231 }
232
233 if (!GetDataLeft()) {
234 CHECK_ERROR(wxStream_READ_ERR);
235 return 0;
236 }
237
238 GetFromBuffer(&c, 1);
239
240 m_stream->m_lastcount = 1;
241 return c;
242}
243
244size_t wxStreamBuffer::Read(void *buffer, size_t size)
245{
246 wxASSERT(m_stream != NULL);
247
248 if (m_mode == write)
249 return 0;
250
251 // ------------------
252 // Buffering disabled
253 // ------------------
254
255 m_stream->m_lasterror = wxStream_NOERROR;
256 if (!m_buffer_size)
257 return (m_stream->m_lastcount += m_stream->OnSysRead(buffer, size));
258
259 // -----------------
260 // Buffering enabled
261 // -----------------
262 size_t buf_left, orig_size = size;
263
264 while (size > 0) {
265 buf_left = GetDataLeft();
266
267 // First case: the requested buffer is larger than the stream buffer,
268 // we split it.
269 if (size > buf_left) {
270 GetFromBuffer(buffer, buf_left);
271 size -= buf_left;
272 buffer = (char *)buffer + buf_left; // ANSI C++ violation.
273
274 if (!FillBuffer()) {
275 CHECK_ERROR(wxStream_EOF);
276 return (m_stream->m_lastcount = orig_size-size);
277 }
278 } else {
279
280 // Second case: we just copy from the stream buffer.
281 GetFromBuffer(buffer, size);
282 break;
283 }
284 }
285 return (m_stream->m_lastcount += orig_size);
286}
287
288size_t wxStreamBuffer::Read(wxStreamBuffer *s_buf)
289{
290 char buf[BUF_TEMP_SIZE];
291 size_t s = 0, bytes_read = BUF_TEMP_SIZE;
292
293 if (m_mode == write)
294 return 0;
295
296 while (bytes_read != 0) {
297 bytes_read = Read(buf, bytes_read);
298 bytes_read = s_buf->Write(buf, bytes_read);
299 s += bytes_read;
300 }
301 return s;
302}
303
304size_t wxStreamBuffer::Write(const void *buffer, size_t size)
305{
306 wxASSERT(m_stream != NULL);
307
308 if (m_mode == read)
309 return 0;
310
311 // ------------------
312 // Buffering disabled
313 // ------------------
314
315 m_stream->m_lasterror = wxStream_NOERROR;
316 if (!m_buffer_size && m_fixed)
317 return (m_stream->m_lastcount = m_stream->OnSysWrite(buffer, size));
318
319 // ------------------
320 // Buffering enabled
321 // ------------------
322
323 size_t buf_left, orig_size = size;
324
325 while (size > 0) {
326 buf_left = m_buffer_end - m_buffer_pos;
327
328 // First case: the buffer to write is larger than the stream buffer,
329 // we split it
330 // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream),
331 // we always go to the second case.
332 if (size > buf_left && m_fixed) {
333 PutToBuffer(buffer, buf_left);
334 size -= buf_left;
335 buffer = (char *)buffer + buf_left; // ANSI C++ violation.
336
337 if (!FlushBuffer()) {
338 CHECK_ERROR(wxStream_WRITE_ERR);
339 return (m_stream->m_lastcount = orig_size-size);
340 }
341
342 m_buffer_pos = m_buffer_start;
343
344 } else {
345
346 // Second case: just copy it in the stream buffer.
347 PutToBuffer(buffer, size);
348 break;
349 }
350 }
351 return (m_stream->m_lastcount = orig_size);
352}
353
354size_t wxStreamBuffer::Write(wxStreamBuffer *sbuf)
355{
356 char buf[BUF_TEMP_SIZE];
357 size_t s = 0, bytes_count = BUF_TEMP_SIZE, b_count2;
358 wxInputStream *in_stream;
359
360 if (m_mode == read)
361 return 0;
362
363 in_stream = (wxInputStream *)sbuf->Stream();
364
365 while (bytes_count == BUF_TEMP_SIZE) {
366 b_count2 = sbuf->Read(buf, bytes_count);
367 bytes_count = Write(buf, b_count2);
368 if (b_count2 > bytes_count)
369 in_stream->Ungetch(buf+bytes_count, b_count2-bytes_count);
370 s += bytes_count;
371 }
372 return s;
373}
374
375off_t wxStreamBuffer::Seek(off_t pos, wxSeekMode mode)
376{
377 off_t ret_off, diff, last_access;
378
379 last_access = GetLastAccess();
380
381 if (!m_flushable) {
382 switch (mode) {
383 case wxFromStart: diff = pos; break;
384 case wxFromCurrent: diff = pos + GetIntPosition(); break;
385 case wxFromEnd: diff = pos + last_access; break;
386 default: return wxInvalidOffset;
387 }
388 if (diff < 0 || diff > last_access)
389 return wxInvalidOffset;
390 SetIntPosition(diff);
391 return diff;
392 }
393
394 switch (mode) {
395 case wxFromStart: {
396 // We'll try to compute an internal position later ...
397 ret_off = m_stream->OnSysSeek(pos, wxFromStart);
398 ResetBuffer();
399 return ret_off;
400 }
401 case wxFromCurrent: {
402 diff = pos + GetIntPosition();
403
404 if ( (diff > last_access) || (diff < 0) ) {
405 // We must take into account the fact that we have read something
406 // previously.
407 ret_off = m_stream->OnSysSeek(diff-last_access, wxFromCurrent);
408 ResetBuffer();
409 return ret_off;
410 } else {
411 SetIntPosition(diff);
412 return pos;
413 }
414 }
415 case wxFromEnd:
416 // Hard to compute: always seek to the requested position.
417 ret_off = m_stream->OnSysSeek(pos, wxFromEnd);
418 ResetBuffer();
419 return ret_off;
420 }
421 return wxInvalidOffset;
422}
423
424off_t wxStreamBuffer::Tell() const
425{
426 off_t pos = m_stream->OnSysTell();
427 if (pos == wxInvalidOffset)
428 return wxInvalidOffset;
429
430 pos += GetIntPosition();
431
432 if (m_mode == read && m_flushable)
433 pos -= GetLastAccess();
434
435 return pos;
436}
437
438size_t wxStreamBuffer::GetDataLeft()
439{
440 /* Why is this done? RR. */
441 if (m_buffer_end == m_buffer_pos && m_flushable)
442 FillBuffer();
443
444 return m_buffer_end-m_buffer_pos;
445}
446
447// ----------------------------------------------------------------------------
448// wxStreamBase
449// ----------------------------------------------------------------------------
450
451wxStreamBase::wxStreamBase()
452{
453 m_lasterror = wxStream_NOERROR;
454 m_lastcount = 0;
455}
456
457wxStreamBase::~wxStreamBase()
458{
459}
460
461size_t wxStreamBase::OnSysRead(void *WXUNUSED(buffer), size_t WXUNUSED(size))
462{
463 return 0;
464}
465
466size_t wxStreamBase::OnSysWrite(const void *WXUNUSED(buffer), size_t WXUNUSED(bufsize))
467{
468 return 0;
469}
470
471off_t wxStreamBase::OnSysSeek(off_t WXUNUSED(seek), wxSeekMode WXUNUSED(mode))
472{
473 return wxInvalidOffset;
474}
475
476off_t wxStreamBase::OnSysTell() const
477{
478 return wxInvalidOffset;
479}
480
481// ----------------------------------------------------------------------------
482// wxInputStream
483// ----------------------------------------------------------------------------
484
485wxInputStream::wxInputStream()
486 : wxStreamBase(),
487 m_wback(NULL), m_wbacksize(0), m_wbackcur(0)
488{
489}
490
491wxInputStream::~wxInputStream()
492{
493 if (m_wback)
494 free(m_wback);
495}
496
497char *wxInputStream::AllocSpaceWBack(size_t needed_size)
498{
499 /* get number of bytes left from previous wback buffer */
500 size_t toget = m_wbacksize - m_wbackcur;
501
502 /* allocate a buffer large enough to hold prev + new data */
503 char *temp_b = (char *) malloc(needed_size + toget);
504
505 if (!temp_b)
506 return NULL;
507
508 /* copy previous data (and free old buffer) if needed */
509 if (m_wback)
510 {
511 memmove(temp_b + needed_size, m_wback + m_wbackcur, toget);
512 free(m_wback);
513 }
514
515 /* done */
516 m_wback = temp_b;
517 m_wbackcur = 0;
518 m_wbacksize = needed_size + toget;
519
520 return (char *) m_wback;
521}
522
523size_t wxInputStream::GetWBack(char *buf, size_t bsize)
524{
525 size_t s_toget = m_wbacksize-m_wbackcur;
526
527 if (!m_wback)
528 return 0;
529
530 if (bsize < s_toget)
531 s_toget = bsize;
532
533 memcpy(buf, (m_wback+m_wbackcur), s_toget);
534
535 m_wbackcur += s_toget;
536 if (m_wbackcur == m_wbacksize)
537 {
538 free(m_wback);
539 m_wback = (char *)NULL;
540 m_wbacksize = 0;
541 m_wbackcur = 0;
542 }
543
544 return s_toget;
545}
546
547size_t wxInputStream::Ungetch(const void *buf, size_t bufsize)
548{
549 char *ptrback = AllocSpaceWBack(bufsize);
550 if (!ptrback)
551 return 0;
552
553 memcpy(ptrback, buf, bufsize);
554 return bufsize;
555}
556
557bool wxInputStream::Ungetch(char c)
558{
559 char * ptrback = AllocSpaceWBack(1);
560 if (!ptrback)
561 return FALSE;
562
563 *ptrback = c;
564 return TRUE;
565}
566
567char wxInputStream::GetC()
568{
569 char c;
570 Read(&c, 1);
571 return c;
572}
573
574wxInputStream& wxInputStream::Read(void *buffer, size_t size)
575{
576 char *buf = (char *)buffer;
577
578 size_t retsize = GetWBack(buf, size);
579 if (retsize == size)
580 {
581 m_lastcount = size;
582 m_lasterror = wxStream_NOERROR;
583 return *this;
584 }
585 size -= retsize;
586 buf += retsize;
587
588 m_lastcount = OnSysRead(buf, size) + retsize;
589 return *this;
590}
591
592char wxInputStream::Peek()
593{
594 char c;
595 Read(&c, 1);
596 if (m_lasterror == wxStream_NOERROR)
597 {
598 Ungetch(c);
599 return c;
600 }
601
602 return 0;
603}
604
605wxInputStream& wxInputStream::Read(wxOutputStream& stream_out)
606{
607 char buf[BUF_TEMP_SIZE];
608 size_t bytes_read = BUF_TEMP_SIZE;
609
610 while (bytes_read == BUF_TEMP_SIZE)
611 {
612 bytes_read = Read(buf, bytes_read).LastRead();
613 bytes_read = stream_out.Write(buf, bytes_read).LastWrite();
614 }
615 return *this;
616}
617
618off_t wxInputStream::SeekI(off_t pos, wxSeekMode mode)
619{
620 /* Should be check and improve, just to remove a slight bug !
621 I don't know whether it should be put as well in wxFileInputStream::OnSysSeek ? */
622 if (m_lasterror==wxSTREAM_EOF)
623 m_lasterror=wxSTREAM_NOERROR;
624
625 /* A call to SeekI() will automatically invalidate any previous call
626 to Ungetch(), otherwise it would be possible to SeekI() to one
627 one position, unread some bytes there, SeekI() to another position
628 and the data would be corrupted. */
629 if (m_wback)
630 {
631 free(m_wback);
632 m_wback = (char*) NULL;
633 m_wbacksize = 0;
634 m_wbackcur = 0;
635 }
636
637 return OnSysSeek(pos, mode);
638}
639
640off_t wxInputStream::TellI() const
641{
642 return OnSysTell();
643}
644
645// --------------------
646// Overloaded operators
647// --------------------
648
649#if wxUSE_SERIAL
650wxInputStream& wxInputStream::operator>>(wxObject *& obj)
651{
652 wxObjectInputStream obj_s(*this);
653 obj = obj_s.LoadObject();
654 return *this;
655}
656#endif
657
658
659// ----------------------------------------------------------------------------
660// wxOutputStream
661// ----------------------------------------------------------------------------
662wxOutputStream::wxOutputStream()
663 : wxStreamBase()
664{
665}
666
667wxOutputStream::~wxOutputStream()
668{
669}
670
671void wxOutputStream::PutC(char c)
672{
673 Write((void *) &c, 1);
674}
675
676wxOutputStream& wxOutputStream::Write(const void *buffer, size_t size)
677{
678 m_lastcount = OnSysWrite(buffer, size);
679 return *this;
680}
681
682wxOutputStream& wxOutputStream::Write(wxInputStream& stream_in)
683{
684 stream_in.Read(*this);
685 return *this;
686}
687
688off_t wxOutputStream::TellO() const
689{
690 return OnSysTell();
691}
692
693off_t wxOutputStream::SeekO(off_t pos, wxSeekMode mode)
694{
695 return OnSysSeek(pos, mode);
696}
697
698void wxOutputStream::Sync()
699{
700}
701
702#if wxUSE_SERIAL
703wxOutputStream& wxOutputStream::operator<<(wxObject& obj)
704{
705 wxObjectOutputStream obj_s(*this);
706 obj_s.SaveObject(obj);
707 return *this;
708}
709#endif
710
711// ----------------------------------------------------------------------------
712// wxCountingOutputStream
713// ----------------------------------------------------------------------------
714
715wxCountingOutputStream::wxCountingOutputStream ()
716 : wxOutputStream()
717{
718 m_currentPos = 0;
719}
720
721size_t wxCountingOutputStream::GetSize() const
722{
723 return m_lastcount;
724}
725
726size_t wxCountingOutputStream::OnSysWrite(const void *WXUNUSED(buffer), size_t size)
727{
728 m_currentPos += size;
729 if (m_currentPos > m_lastcount) m_lastcount = m_currentPos;
730 return m_currentPos;
731}
732
733off_t wxCountingOutputStream::OnSysSeek(off_t pos, wxSeekMode mode)
734{
735 if (mode == wxFromStart)
736 m_currentPos = pos;
737 if (mode == wxFromEnd)
738 m_currentPos = m_lastcount + pos;
739 else
740 m_currentPos += pos;
741
742 if (m_currentPos > m_lastcount) m_lastcount = m_currentPos;
743
744 return m_currentPos;
745}
746
747off_t wxCountingOutputStream::OnSysTell() const
748{
749 return m_currentPos;
750}
751
752// ----------------------------------------------------------------------------
753// wxFilterInputStream
754// ----------------------------------------------------------------------------
755
756wxFilterInputStream::wxFilterInputStream()
757 : wxInputStream()
758{
759}
760
761wxFilterInputStream::wxFilterInputStream(wxInputStream& stream)
762 : wxInputStream()
763{
764 m_parent_i_stream = &stream;
765}
766
767wxFilterInputStream::~wxFilterInputStream()
768{
769}
770
771// ----------------------------------------------------------------------------
772// wxFilterOutputStream
773// ----------------------------------------------------------------------------
774wxFilterOutputStream::wxFilterOutputStream()
775 : wxOutputStream()
776{
777}
778
779wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream)
780 : wxOutputStream()
781{
782 m_parent_o_stream = &stream;
783}
784
785wxFilterOutputStream::~wxFilterOutputStream()
786{
787}
788
789// ----------------------------------------------------------------------------
790// wxBufferedInputStream
791// ----------------------------------------------------------------------------
792wxBufferedInputStream::wxBufferedInputStream(wxInputStream& s)
793 : wxFilterInputStream(s)
794{
795 m_i_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::read);
796 m_i_streambuf->SetBufferIO(1024);
797}
798
799wxBufferedInputStream::~wxBufferedInputStream()
800{
801 off_t unused_bytes=m_i_streambuf->GetBufferPos()-m_i_streambuf->GetBufferEnd();
802 m_parent_i_stream->SeekI(unused_bytes,wxFromCurrent);
803
804 delete m_i_streambuf;
805}
806
807char wxBufferedInputStream::Peek()
808{
809 return m_i_streambuf->Peek();
810}
811
812wxInputStream& wxBufferedInputStream::Read(void *buffer, size_t size)
813{
814 size_t retsize;
815 char *buf = (char *)buffer;
816
817 retsize = GetWBack(buf, size);
818 m_lastcount = retsize;
819 if (retsize == size)
820 {
821 m_lasterror = wxStream_NOERROR;
822 return *this;
823 }
824 size -= retsize;
825 buf += retsize;
826
827 m_i_streambuf->Read(buf, size);
828
829 return *this;
830}
831
832off_t wxBufferedInputStream::SeekI(off_t pos, wxSeekMode mode)
833{
834 return m_i_streambuf->Seek(pos, mode);
835}
836
837off_t wxBufferedInputStream::TellI() const
838{
839 return m_i_streambuf->Tell();
840}
841
842size_t wxBufferedInputStream::OnSysRead(void *buffer, size_t bufsize)
843{
844 return m_parent_i_stream->Read(buffer, bufsize).LastRead();
845}
846
847off_t wxBufferedInputStream::OnSysSeek(off_t seek, wxSeekMode mode)
848{
849 return m_parent_i_stream->SeekI(seek, mode);
850}
851
852off_t wxBufferedInputStream::OnSysTell() const
853{
854 return m_parent_i_stream->TellI();
855}
856
857
858// ----------------------------------------------------------------------------
859// wxBufferedOutputStream
860// ----------------------------------------------------------------------------
861
862wxBufferedOutputStream::wxBufferedOutputStream(wxOutputStream& s)
863 : wxFilterOutputStream(s)
864{
865 m_o_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::write);
866 m_o_streambuf->SetBufferIO(1024);
867}
868
869wxBufferedOutputStream::~wxBufferedOutputStream()
870{
871 Sync();
872 delete m_o_streambuf;
873}
874
875wxOutputStream& wxBufferedOutputStream::Write(const void *buffer, size_t size)
876{
877 m_lastcount = 0;
878 m_o_streambuf->Write(buffer, size);
879 return *this;
880}
881
882off_t wxBufferedOutputStream::SeekO(off_t pos, wxSeekMode mode)
883{
884 Sync();
885 return m_o_streambuf->Seek(pos, mode);
886}
887
888off_t wxBufferedOutputStream::TellO() const
889{
890 return m_o_streambuf->Tell();
891}
892
893void wxBufferedOutputStream::Sync()
894{
895 m_o_streambuf->FlushBuffer();
896 m_parent_o_stream->Sync();
897}
898
899size_t wxBufferedOutputStream::OnSysWrite(const void *buffer, size_t bufsize)
900{
901 return m_parent_o_stream->Write(buffer, bufsize).LastWrite();
902}
903
904off_t wxBufferedOutputStream::OnSysSeek(off_t seek, wxSeekMode mode)
905{
906 return m_parent_o_stream->SeekO(seek, mode);
907}
908
909off_t wxBufferedOutputStream::OnSysTell() const
910{
911 return m_parent_o_stream->TellO();
912}
913
914size_t wxBufferedOutputStream::GetSize() const
915{
916 return m_parent_o_stream->GetSize() + m_o_streambuf->GetIntPosition();
917}
918
919// ----------------------------------------------------------------------------
920// Some IOManip function
921// ----------------------------------------------------------------------------
922
923wxOutputStream& wxEndL(wxOutputStream& stream)
924{
925#ifdef __MSW__
926 return stream.Write("\r\n", 2);
927#else
928#ifdef __WXMAC__
929 return stream.Write("\r", 1);
930#else
931 return stream.Write("\n", 1);
932#endif
933#endif
934}
935
936#endif
937 // wxUSE_STREAMS