]> git.saurik.com Git - wxWidgets.git/blame - src/common/datstrm.cpp
fixed memory leak in RestoreState
[wxWidgets.git] / src / common / datstrm.cpp
CommitLineData
cf447356 1/////////////////////////////////////////////////////////////////////////////
40319aa0 2// Name: src/common/datstrm.cpp
cf447356
GL
3// Purpose: Data stream classes
4// Author: Guilhem Lavaux
53663be8 5// Modified by: Mickael Gilabert
cf447356
GL
6// Created: 28/06/98
7// RCS-ID: $Id$
13111b2a 8// Copyright: (c) Guilhem Lavaux
68379eaf 9// Licence: wxWindows licence
cf447356
GL
10/////////////////////////////////////////////////////////////////////////////
11
cf447356
GL
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
ce4169a4 16 #pragma hdrstop
cf447356
GL
17#endif
18
ce4169a4
RR
19#if wxUSE_STREAMS
20
cf447356 21#include "wx/datstrm.h"
18680f86
WS
22
23#ifndef WX_PRECOMP
24 #include "wx/math.h"
25#endif //WX_PRECOMP
3cacae09 26
f4ada568
GL
27// ---------------------------------------------------------------------------
28// wxDataInputStream
29// ---------------------------------------------------------------------------
30
a99acbb0 31#if wxUSE_UNICODE
830f8f11 32wxDataInputStream::wxDataInputStream(wxInputStream& s, const wxMBConv& conv)
d36c9347 33 : m_input(&s), m_be_order(false), m_conv(conv.Clone())
a99acbb0 34#else
3d4c6a21 35wxDataInputStream::wxDataInputStream(wxInputStream& s)
68379eaf 36 : m_input(&s), m_be_order(false)
a99acbb0 37#endif
cf447356 38{
cf447356
GL
39}
40
d36c9347
VZ
41wxDataInputStream::~wxDataInputStream()
42{
43#if wxUSE_UNICODE
44 delete m_conv;
45#endif // wxUSE_UNICODE
46}
47
216a72f3 48#if wxHAS_INT64
41b0a113
RL
49wxUint64 wxDataInputStream::Read64()
50{
216a72f3
VZ
51 wxUint64 tmp;
52 Read64(&tmp, 1);
53 return tmp;
41b0a113 54}
216a72f3 55#endif // wxHAS_INT64
41b0a113 56
7b8bd818 57wxUint32 wxDataInputStream::Read32()
cf447356 58{
5a96d2f4 59 wxUint32 i32;
cf447356 60
5a96d2f4 61 m_input->Read(&i32, 4);
cf447356 62
5a96d2f4
GL
63 if (m_be_order)
64 return wxUINT32_SWAP_ON_LE(i32);
65 else
66 return wxUINT32_SWAP_ON_BE(i32);
cf447356
GL
67}
68
7b8bd818 69wxUint16 wxDataInputStream::Read16()
cf447356 70{
5a96d2f4 71 wxUint16 i16;
cf447356 72
5a96d2f4 73 m_input->Read(&i16, 2);
cf447356 74
5a96d2f4
GL
75 if (m_be_order)
76 return wxUINT16_SWAP_ON_LE(i16);
77 else
78 return wxUINT16_SWAP_ON_BE(i16);
cf447356
GL
79}
80
7b8bd818 81wxUint8 wxDataInputStream::Read8()
cf447356 82{
7b8bd818 83 wxUint8 buf;
cf447356 84
5a96d2f4 85 m_input->Read(&buf, 1);
7b8bd818 86 return (wxUint8)buf;
cf447356
GL
87}
88
3d4c6a21 89double wxDataInputStream::ReadDouble()
cf447356 90{
47d67540 91#if wxUSE_APPLE_IEEE
cf447356
GL
92 char buf[10];
93
fae05df5 94 m_input->Read(buf, 10);
225dfbc5 95 return wxConvertFromIeeeExtended((const wxInt8 *)buf);
cf447356
GL
96#else
97 return 0.0;
98#endif
99}
100
3d4c6a21 101wxString wxDataInputStream::ReadString()
eafc087e 102{
13111b2a 103 size_t len;
eafc087e 104
eafc087e 105 len = Read32();
eafc087e 106
39a16cb4
VS
107 if (len > 0)
108 {
2ae47e3f 109#if wxUSE_UNICODE
de564874
MB
110 wxCharBuffer tmp(len + 1);
111 m_input->Read(tmp.data(), len);
112 tmp.data()[len] = '\0';
d36c9347 113 wxString ret(m_conv->cMB2WX(tmp.data()));
2ae47e3f 114#else
2b5f62a0 115 wxString ret;
de564874 116 m_input->Read( wxStringBuffer(ret, len), len);
2ae47e3f 117#endif
2b5f62a0 118 return ret;
39a16cb4 119 }
38caaa61 120 else
39a16cb4 121 return wxEmptyString;
eafc087e 122}
13111b2a 123
216a72f3
VZ
124#if wxUSE_LONGLONG
125
126template <class T>
127static
128void DoReadLL(T *buffer, size_t size, wxInputStream *input, bool be_order)
53663be8 129{
216a72f3
VZ
130 typedef T DataType;
131 unsigned char *pchBuffer = new unsigned char[size * 8];
132 // TODO: Check for overflow when size is of type uint and is > than 512m
133 input->Read(pchBuffer, size * 8);
134 size_t idx_base = 0;
135 if ( be_order )
136 {
137 for ( size_t uiIndex = 0; uiIndex != size; ++uiIndex )
138 {
139 buffer[uiIndex] = 0l;
140 for ( unsigned ui = 0; ui != 8; ++ui )
141 {
142 buffer[uiIndex] = buffer[uiIndex] * 256l +
143 DataType((unsigned long) pchBuffer[idx_base + ui]);
144 }
145
146 idx_base += 8;
147 }
148 }
149 else // little endian
150 {
151 for ( size_t uiIndex=0; uiIndex!=size; ++uiIndex )
152 {
153 buffer[uiIndex] = 0l;
154 for ( unsigned ui=0; ui!=8; ++ui )
155 buffer[uiIndex] = buffer[uiIndex] * 256l +
156 DataType((unsigned long) pchBuffer[idx_base + 7 - ui]);
157 idx_base += 8;
158 }
159 }
160 delete[] pchBuffer;
161}
53663be8 162
216a72f3
VZ
163template <class T>
164static void DoWriteLL(const T *buffer, size_t size, wxOutputStream *output, bool be_order)
165{
166 typedef T DataType;
167 unsigned char *pchBuffer = new unsigned char[size * 8];
168 size_t idx_base = 0;
169 if ( be_order )
170 {
171 for ( size_t uiIndex = 0; uiIndex != size; ++uiIndex )
172 {
173 DataType i64 = buffer[uiIndex];
174 for ( unsigned ui = 0; ui != 8; ++ui )
175 {
176 pchBuffer[idx_base + 7 - ui] =
177 (unsigned char) (i64.GetLo() & 255l);
178 i64 >>= 8l;
179 }
180
181 idx_base += 8;
182 }
183 }
184 else // little endian
185 {
186 for ( size_t uiIndex=0; uiIndex != size; ++uiIndex )
187 {
188 DataType i64 = buffer[uiIndex];
189 for (unsigned ui=0; ui!=8; ++ui)
190 {
191 pchBuffer[idx_base + ui] =
192 (unsigned char) (i64.GetLo() & 255l);
193 i64 >>= 8l;
194 }
195
196 idx_base += 8;
197 }
198 }
199
200 // TODO: Check for overflow when size is of type uint and is > than 512m
201 output->Write(pchBuffer, size * 8);
202 delete[] pchBuffer;
203}
204
205#endif // wxUSE_LONGLONG
206
207#ifdef wxLongLong_t
208
209template <class T>
210static
211void DoReadI64(T *buffer, size_t size, wxInputStream *input, bool be_order)
212{
213 typedef T DataType;
214 unsigned char *pchBuffer = (unsigned char*) buffer;
215 // TODO: Check for overflow when size is of type uint and is > than 512m
216 input->Read(pchBuffer, size * 8);
217 if ( be_order )
218 {
219 for ( wxUint32 i = 0; i < size; i++ )
220 {
221 DataType v = wxUINT64_SWAP_ON_LE(*buffer);
222 *(buffer++) = v;
223 }
224 }
225 else // little endian
226 {
227 for ( wxUint32 i=0; i<size; i++ )
228 {
229 DataType v = wxUINT64_SWAP_ON_BE(*buffer);
230 *(buffer++) = v;
231 }
232 }
233}
234
235template <class T>
236static
237void DoWriteI64(const T *buffer, size_t size, wxOutputStream *output, bool be_order)
238{
239 typedef T DataType;
240 if ( be_order )
53663be8 241 {
216a72f3 242 for ( size_t i = 0; i < size; i++ )
53663be8 243 {
216a72f3
VZ
244 DataType i64 = wxUINT64_SWAP_ON_LE(*buffer);
245 buffer++;
246 output->Write(&i64, 8);
53663be8
VZ
247 }
248 }
216a72f3 249 else // little endian
53663be8 250 {
216a72f3 251 for ( size_t i=0; i < size; i++ )
53663be8 252 {
216a72f3
VZ
253 DataType i64 = wxUINT64_SWAP_ON_BE(*buffer);
254 buffer++;
255 output->Write(&i64, 8);
53663be8
VZ
256 }
257 }
258}
259
216a72f3
VZ
260#endif // wxLongLong_t
261
262
263#if wxHAS_INT64
264void wxDataInputStream::Read64(wxUint64 *buffer, size_t size)
265{
266#ifndef wxLongLong_t
267 DoReadLL(buffer, size, m_input, m_be_order);
268#else
269 DoReadI64(buffer, size, m_input, m_be_order);
270#endif
271}
272
273void wxDataInputStream::Read64(wxInt64 *buffer, size_t size)
274{
275#ifndef wxLongLong_t
276 DoReadLL(buffer, size, m_input, m_be_order);
277#else
278 DoReadI64(buffer, size, m_input, m_be_order);
279#endif
280}
281#endif // wxHAS_INT64
282
283#if defined(wxLongLong_t) && wxUSE_LONGLONG
284void wxDataInputStream::Read64(wxULongLong *buffer, size_t size)
285{
286 DoReadLL(buffer, size, m_input, m_be_order);
287}
288
289void wxDataInputStream::Read64(wxLongLong *buffer, size_t size)
290{
291 DoReadLL(buffer, size, m_input, m_be_order);
292}
293#endif // wxLongLong_t
294
295#if wxUSE_LONGLONG
296void wxDataInputStream::ReadLL(wxULongLong *buffer, size_t size)
297{
298 DoReadLL(buffer, size, m_input, m_be_order);
299}
300
301void wxDataInputStream::ReadLL(wxLongLong *buffer, size_t size)
302{
303 DoReadLL(buffer, size, m_input, m_be_order);
304}
305
306wxLongLong wxDataInputStream::ReadLL(void)
307{
308 wxLongLong ll;
40319aa0 309 DoReadLL(&ll, (size_t)1, m_input, m_be_order);
216a72f3
VZ
310 return ll;
311}
312#endif // wxUSE_LONGLONG
313
53663be8
VZ
314void wxDataInputStream::Read32(wxUint32 *buffer, size_t size)
315{
7448de8d 316 m_input->Read(buffer, size * 4);
53663be8 317
7448de8d 318 if (m_be_order)
53663be8 319 {
7448de8d
WS
320 for (wxUint32 i=0; i<size; i++)
321 {
322 wxUint32 v = wxUINT32_SWAP_ON_LE(*buffer);
323 *(buffer++) = v;
324 }
53663be8 325 }
7448de8d 326 else
53663be8 327 {
7448de8d
WS
328 for (wxUint32 i=0; i<size; i++)
329 {
330 wxUint32 v = wxUINT32_SWAP_ON_BE(*buffer);
331 *(buffer++) = v;
332 }
53663be8 333 }
53663be8
VZ
334}
335
336void wxDataInputStream::Read16(wxUint16 *buffer, size_t size)
337{
338 m_input->Read(buffer, size * 2);
339
340 if (m_be_order)
341 {
342 for (wxUint32 i=0; i<size; i++)
343 {
344 wxUint16 v = wxUINT16_SWAP_ON_LE(*buffer);
345 *(buffer++) = v;
346 }
347 }
348 else
349 {
350 for (wxUint32 i=0; i<size; i++)
351 {
352 wxUint16 v = wxUINT16_SWAP_ON_BE(*buffer);
353 *(buffer++) = v;
354 }
355 }
356}
357
358void wxDataInputStream::Read8(wxUint8 *buffer, size_t size)
359{
360 m_input->Read(buffer, size);
361}
362
363void wxDataInputStream::ReadDouble(double *buffer, size_t size)
364{
365 for (wxUint32 i=0; i<size; i++)
366 {
367 *(buffer++) = ReadDouble();
368 }
369}
370
fae05df5
GL
371wxDataInputStream& wxDataInputStream::operator>>(wxString& s)
372{
373 s = ReadString();
374 return *this;
375}
376
377wxDataInputStream& wxDataInputStream::operator>>(wxInt8& c)
378{
379 c = (wxInt8)Read8();
380 return *this;
381}
382
383wxDataInputStream& wxDataInputStream::operator>>(wxInt16& i)
384{
385 i = (wxInt16)Read16();
386 return *this;
387}
388
389wxDataInputStream& wxDataInputStream::operator>>(wxInt32& i)
390{
391 i = (wxInt32)Read32();
392 return *this;
393}
394
395wxDataInputStream& wxDataInputStream::operator>>(wxUint8& c)
396{
397 c = Read8();
398 return *this;
399}
400
401wxDataInputStream& wxDataInputStream::operator>>(wxUint16& i)
402{
403 i = Read16();
404 return *this;
405}
406
407wxDataInputStream& wxDataInputStream::operator>>(wxUint32& i)
408{
409 i = Read32();
410 return *this;
411}
412
216a72f3 413#if wxHAS_INT64
41b0a113
RL
414wxDataInputStream& wxDataInputStream::operator>>(wxUint64& i)
415{
416 i = Read64();
417 return *this;
418}
419
216a72f3
VZ
420wxDataInputStream& wxDataInputStream::operator>>(wxInt64& i)
421{
422 i = Read64();
423 return *this;
424}
425#endif // wxHAS_INT64
426
427#if defined(wxLongLong_t) && wxUSE_LONGLONG
428wxDataInputStream& wxDataInputStream::operator>>(wxULongLong& i)
429{
430 i = ReadLL();
431 return *this;
432}
433
434wxDataInputStream& wxDataInputStream::operator>>(wxLongLong& i)
435{
436 i = ReadLL();
437 return *this;
438}
439#endif // wxLongLong_t
440
fae05df5
GL
441wxDataInputStream& wxDataInputStream::operator>>(double& i)
442{
443 i = ReadDouble();
444 return *this;
445}
446
447wxDataInputStream& wxDataInputStream::operator>>(float& f)
448{
449 f = (float)ReadDouble();
450 return *this;
451}
eafc087e 452
f4ada568
GL
453// ---------------------------------------------------------------------------
454// wxDataOutputStream
455// ---------------------------------------------------------------------------
456
a99acbb0 457#if wxUSE_UNICODE
830f8f11 458wxDataOutputStream::wxDataOutputStream(wxOutputStream& s, const wxMBConv& conv)
d36c9347 459 : m_output(&s), m_be_order(false), m_conv(conv.Clone())
a99acbb0 460#else
3d4c6a21 461wxDataOutputStream::wxDataOutputStream(wxOutputStream& s)
68379eaf 462 : m_output(&s), m_be_order(false)
a99acbb0 463#endif
3d4c6a21
GL
464{
465}
466
d36c9347
VZ
467wxDataOutputStream::~wxDataOutputStream()
468{
469#if wxUSE_UNICODE
470 delete m_conv;
471#endif // wxUSE_UNICODE
472}
473
216a72f3 474#if wxHAS_INT64
41b0a113
RL
475void wxDataOutputStream::Write64(wxUint64 i)
476{
216a72f3
VZ
477 Write64(&i, 1);
478}
41b0a113 479
216a72f3
VZ
480void wxDataOutputStream::Write64(wxInt64 i)
481{
482 Write64(&i, 1);
41b0a113 483}
216a72f3 484#endif // wxHAS_INT64
41b0a113 485
7b8bd818 486void wxDataOutputStream::Write32(wxUint32 i)
cf447356 487{
5a96d2f4 488 wxUint32 i32;
cf447356 489
5a96d2f4
GL
490 if (m_be_order)
491 i32 = wxUINT32_SWAP_ON_LE(i);
492 else
493 i32 = wxUINT32_SWAP_ON_BE(i);
494 m_output->Write(&i32, 4);
cf447356
GL
495}
496
7b8bd818 497void wxDataOutputStream::Write16(wxUint16 i)
cf447356 498{
5a96d2f4 499 wxUint16 i16;
cf447356 500
5a96d2f4
GL
501 if (m_be_order)
502 i16 = wxUINT16_SWAP_ON_LE(i);
503 else
504 i16 = wxUINT16_SWAP_ON_BE(i);
505
506 m_output->Write(&i16, 2);
cf447356
GL
507}
508
7b8bd818 509void wxDataOutputStream::Write8(wxUint8 i)
cf447356 510{
fae05df5 511 m_output->Write(&i, 1);
cf447356
GL
512}
513
3d4c6a21 514void wxDataOutputStream::WriteString(const wxString& string)
eafc087e 515{
a99acbb0 516#if wxUSE_UNICODE
d36c9347 517 const wxWX2MBbuf buf = string.mb_str(*m_conv);
a99acbb0 518#else
c980c992 519 const wxWX2MBbuf buf = string.mb_str();
a99acbb0
VS
520#endif
521 size_t len = strlen(buf);
522 Write32(len);
523 if (len > 0)
524 m_output->Write(buf, len);
cf447356
GL
525}
526
3d4c6a21 527void wxDataOutputStream::WriteDouble(double d)
cf447356 528{
cf447356
GL
529 char buf[10];
530
47d67540 531#if wxUSE_APPLE_IEEE
225dfbc5 532 wxConvertToIeeeExtended(d, (wxInt8 *)buf);
0e338ff9 533#else
c5ceb215 534#if !defined(__VMS__) && !defined(__GNUG__)
338dd992
JJ
535# pragma warning "wxDataOutputStream::WriteDouble() not using IeeeExtended - will not work!"
536#endif
537 buf[0] = '\0';
0e338ff9 538#endif
fae05df5
GL
539 m_output->Write(buf, 10);
540}
541
216a72f3 542#if wxHAS_INT64
53663be8
VZ
543void wxDataOutputStream::Write64(const wxUint64 *buffer, size_t size)
544{
216a72f3
VZ
545#ifndef wxLongLong_t
546 DoWriteLL(buffer, size, m_output, m_be_order);
547#else
548 DoWriteI64(buffer, size, m_output, m_be_order);
549#endif
550}
551
552void wxDataOutputStream::Write64(const wxInt64 *buffer, size_t size)
553{
554#ifndef wxLongLong_t
555 DoWriteLL(buffer, size, m_output, m_be_order);
556#else
557 DoWriteI64(buffer, size, m_output, m_be_order);
558#endif
53663be8 559}
216a72f3
VZ
560#endif // wxHAS_INT64
561
562#if defined(wxLongLong_t) && wxUSE_LONGLONG
563void wxDataOutputStream::Write64(const wxULongLong *buffer, size_t size)
564{
565 DoWriteLL(buffer, size, m_output, m_be_order);
566}
567
568void wxDataOutputStream::Write64(const wxLongLong *buffer, size_t size)
569{
570 DoWriteLL(buffer, size, m_output, m_be_order);
571}
572#endif // wxLongLong_t
573
574#if wxUSE_LONGLONG
575void wxDataOutputStream::WriteLL(const wxULongLong *buffer, size_t size)
576{
577 DoWriteLL(buffer, size, m_output, m_be_order);
578}
579
580void wxDataOutputStream::WriteLL(const wxLongLong *buffer, size_t size)
581{
582 DoWriteLL(buffer, size, m_output, m_be_order);
583}
584
585void wxDataOutputStream::WriteLL(const wxLongLong &ll)
586{
587 WriteLL(&ll, 1);
588}
589
590void wxDataOutputStream::WriteLL(const wxULongLong &ll)
591{
592 WriteLL(&ll, 1);
593}
594#endif // wxUSE_LONGLONG
53663be8
VZ
595
596void wxDataOutputStream::Write32(const wxUint32 *buffer, size_t size)
597{
598 if (m_be_order)
599 {
600 for (wxUint32 i=0; i<size ;i++)
601 {
602 wxUint32 i32 = wxUINT32_SWAP_ON_LE(*buffer);
603 buffer++;
604 m_output->Write(&i32, 4);
605 }
606 }
607 else
608 {
609 for (wxUint32 i=0; i<size ;i++)
610 {
611 wxUint32 i32 = wxUINT32_SWAP_ON_BE(*buffer);
612 buffer++;
613 m_output->Write(&i32, 4);
614 }
615 }
616}
617
618void wxDataOutputStream::Write16(const wxUint16 *buffer, size_t size)
619{
620 if (m_be_order)
621 {
622 for (wxUint32 i=0; i<size ;i++)
623 {
624 wxUint16 i16 = wxUINT16_SWAP_ON_LE(*buffer);
625 buffer++;
626 m_output->Write(&i16, 2);
627 }
628 }
629 else
630 {
631 for (wxUint32 i=0; i<size ;i++)
632 {
633 wxUint16 i16 = wxUINT16_SWAP_ON_BE(*buffer);
634 buffer++;
635 m_output->Write(&i16, 2);
636 }
637 }
638}
639
640void wxDataOutputStream::Write8(const wxUint8 *buffer, size_t size)
641{
642 m_output->Write(buffer, size);
643}
644
645void wxDataOutputStream::WriteDouble(const double *buffer, size_t size)
646{
647 for (wxUint32 i=0; i<size; i++)
648 {
649 WriteDouble(*(buffer++));
650 }
651}
652
38caaa61 653wxDataOutputStream& wxDataOutputStream::operator<<(const wxString& string)
fae05df5
GL
654{
655 WriteString(string);
656 return *this;
657}
658
659wxDataOutputStream& wxDataOutputStream::operator<<(wxInt8 c)
660{
661 Write8((wxUint8)c);
662 return *this;
663}
664
665wxDataOutputStream& wxDataOutputStream::operator<<(wxInt16 i)
666{
667 Write16((wxUint16)i);
668 return *this;
669}
670
671wxDataOutputStream& wxDataOutputStream::operator<<(wxInt32 i)
672{
673 Write32((wxUint32)i);
674 return *this;
675}
676
677wxDataOutputStream& wxDataOutputStream::operator<<(wxUint8 c)
678{
679 Write8(c);
680 return *this;
681}
682
683wxDataOutputStream& wxDataOutputStream::operator<<(wxUint16 i)
684{
685 Write16(i);
686 return *this;
687}
688
689wxDataOutputStream& wxDataOutputStream::operator<<(wxUint32 i)
690{
691 Write32(i);
692 return *this;
693}
694
216a72f3 695#if wxHAS_INT64
41b0a113
RL
696wxDataOutputStream& wxDataOutputStream::operator<<(wxUint64 i)
697{
698 Write64(i);
699 return *this;
700}
701
216a72f3
VZ
702wxDataOutputStream& wxDataOutputStream::operator<<(wxInt64 i)
703{
704 Write64(i);
705 return *this;
706}
707#endif // wxHAS_INT64
708
709#if defined(wxLongLong_t) && wxUSE_LONGLONG
710wxDataOutputStream& wxDataOutputStream::operator<<(const wxULongLong &i)
711{
712 WriteLL(i);
713 return *this;
714}
715
716wxDataOutputStream& wxDataOutputStream::operator<<(const wxLongLong &i)
717{
718 WriteLL(i);
719 return *this;
720}
721#endif // wxLongLong_t
722
fae05df5
GL
723wxDataOutputStream& wxDataOutputStream::operator<<(double f)
724{
725 WriteDouble(f);
726 return *this;
727}
728
729wxDataOutputStream& wxDataOutputStream::operator<<(float f)
730{
731 WriteDouble((double)f);
732 return *this;
cf447356 733}
ce4169a4
RR
734
735#endif
736 // wxUSE_STREAMS