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