]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/datstrm.cpp
Fixed a rare wxAuiFloatingFrame dtor crash on MSW using a registration mechanism...
[wxWidgets.git] / src / common / datstrm.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/datstrm.cpp
3// Purpose: Data stream classes
4// Author: Guilhem Lavaux
5// Modified by: Mickael Gilabert
6// Created: 28/06/98
7// RCS-ID: $Id$
8// Copyright: (c) Guilhem Lavaux
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#if wxUSE_STREAMS
20
21#include "wx/datstrm.h"
22
23#ifndef WX_PRECOMP
24 #include "wx/math.h"
25#endif //WX_PRECOMP
26
27// ---------------------------------------------------------------------------
28// wxDataInputStream
29// ---------------------------------------------------------------------------
30
31#if wxUSE_UNICODE
32wxDataInputStream::wxDataInputStream(wxInputStream& s, const wxMBConv& conv)
33 : m_input(&s), m_be_order(false), m_conv(conv.Clone())
34#else
35wxDataInputStream::wxDataInputStream(wxInputStream& s)
36 : m_input(&s), m_be_order(false)
37#endif
38{
39}
40
41wxDataInputStream::~wxDataInputStream()
42{
43#if wxUSE_UNICODE
44 delete m_conv;
45#endif // wxUSE_UNICODE
46}
47
48#if wxHAS_INT64
49wxUint64 wxDataInputStream::Read64()
50{
51 wxUint64 tmp;
52 Read64(&tmp, 1);
53 return tmp;
54}
55#endif // wxHAS_INT64
56
57wxUint32 wxDataInputStream::Read32()
58{
59 wxUint32 i32;
60
61 m_input->Read(&i32, 4);
62
63 if (m_be_order)
64 return wxUINT32_SWAP_ON_LE(i32);
65 else
66 return wxUINT32_SWAP_ON_BE(i32);
67}
68
69wxUint16 wxDataInputStream::Read16()
70{
71 wxUint16 i16;
72
73 m_input->Read(&i16, 2);
74
75 if (m_be_order)
76 return wxUINT16_SWAP_ON_LE(i16);
77 else
78 return wxUINT16_SWAP_ON_BE(i16);
79}
80
81wxUint8 wxDataInputStream::Read8()
82{
83 wxUint8 buf;
84
85 m_input->Read(&buf, 1);
86 return (wxUint8)buf;
87}
88
89double wxDataInputStream::ReadDouble()
90{
91#if wxUSE_APPLE_IEEE
92 char buf[10];
93
94 m_input->Read(buf, 10);
95 return wxConvertFromIeeeExtended((const wxInt8 *)buf);
96#else
97 return 0.0;
98#endif
99}
100
101wxString wxDataInputStream::ReadString()
102{
103 size_t len;
104
105 len = Read32();
106
107 if (len > 0)
108 {
109#if wxUSE_UNICODE
110 wxCharBuffer tmp(len + 1);
111 m_input->Read(tmp.data(), len);
112 tmp.data()[len] = '\0';
113 wxString ret(m_conv->cMB2WX(tmp.data()));
114#else
115 wxString ret;
116 m_input->Read( wxStringBuffer(ret, len), len);
117#endif
118 return ret;
119 }
120 else
121 return wxEmptyString;
122}
123
124#if wxUSE_LONGLONG
125
126template <class T>
127static
128void DoReadLL(T *buffer, size_t size, wxInputStream *input, bool be_order)
129{
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}
162
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 )
241 {
242 for ( size_t i = 0; i < size; i++ )
243 {
244 DataType i64 = wxUINT64_SWAP_ON_LE(*buffer);
245 buffer++;
246 output->Write(&i64, 8);
247 }
248 }
249 else // little endian
250 {
251 for ( size_t i=0; i < size; i++ )
252 {
253 DataType i64 = wxUINT64_SWAP_ON_BE(*buffer);
254 buffer++;
255 output->Write(&i64, 8);
256 }
257 }
258}
259
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;
309 DoReadLL(&ll, (size_t)1, m_input, m_be_order);
310 return ll;
311}
312#endif // wxUSE_LONGLONG
313
314void wxDataInputStream::Read32(wxUint32 *buffer, size_t size)
315{
316 m_input->Read(buffer, size * 4);
317
318 if (m_be_order)
319 {
320 for (wxUint32 i=0; i<size; i++)
321 {
322 wxUint32 v = wxUINT32_SWAP_ON_LE(*buffer);
323 *(buffer++) = v;
324 }
325 }
326 else
327 {
328 for (wxUint32 i=0; i<size; i++)
329 {
330 wxUint32 v = wxUINT32_SWAP_ON_BE(*buffer);
331 *(buffer++) = v;
332 }
333 }
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
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
413#if wxHAS_INT64
414wxDataInputStream& wxDataInputStream::operator>>(wxUint64& i)
415{
416 i = Read64();
417 return *this;
418}
419
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
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}
452
453// ---------------------------------------------------------------------------
454// wxDataOutputStream
455// ---------------------------------------------------------------------------
456
457#if wxUSE_UNICODE
458wxDataOutputStream::wxDataOutputStream(wxOutputStream& s, const wxMBConv& conv)
459 : m_output(&s), m_be_order(false), m_conv(conv.Clone())
460#else
461wxDataOutputStream::wxDataOutputStream(wxOutputStream& s)
462 : m_output(&s), m_be_order(false)
463#endif
464{
465}
466
467wxDataOutputStream::~wxDataOutputStream()
468{
469#if wxUSE_UNICODE
470 delete m_conv;
471#endif // wxUSE_UNICODE
472}
473
474#if wxHAS_INT64
475void wxDataOutputStream::Write64(wxUint64 i)
476{
477 Write64(&i, 1);
478}
479
480void wxDataOutputStream::Write64(wxInt64 i)
481{
482 Write64(&i, 1);
483}
484#endif // wxHAS_INT64
485
486void wxDataOutputStream::Write32(wxUint32 i)
487{
488 wxUint32 i32;
489
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);
495}
496
497void wxDataOutputStream::Write16(wxUint16 i)
498{
499 wxUint16 i16;
500
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);
507}
508
509void wxDataOutputStream::Write8(wxUint8 i)
510{
511 m_output->Write(&i, 1);
512}
513
514void wxDataOutputStream::WriteString(const wxString& string)
515{
516#if wxUSE_UNICODE
517 const wxWX2MBbuf buf = string.mb_str(*m_conv);
518#else
519 const wxWX2MBbuf buf = string.mb_str();
520#endif
521 size_t len = strlen(buf);
522 Write32(len);
523 if (len > 0)
524 m_output->Write(buf, len);
525}
526
527void wxDataOutputStream::WriteDouble(double d)
528{
529 char buf[10];
530
531#if wxUSE_APPLE_IEEE
532 wxConvertToIeeeExtended(d, (wxInt8 *)buf);
533#else
534#if !defined(__VMS__) && !defined(__GNUG__)
535# pragma warning "wxDataOutputStream::WriteDouble() not using IeeeExtended - will not work!"
536#endif
537 buf[0] = '\0';
538#endif
539 m_output->Write(buf, 10);
540}
541
542#if wxHAS_INT64
543void wxDataOutputStream::Write64(const wxUint64 *buffer, size_t size)
544{
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
559}
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
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
653wxDataOutputStream& wxDataOutputStream::operator<<(const wxString& string)
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
695#if wxHAS_INT64
696wxDataOutputStream& wxDataOutputStream::operator<<(wxUint64 i)
697{
698 Write64(i);
699 return *this;
700}
701
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
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;
733}
734
735#endif
736 // wxUSE_STREAMS