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