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