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