File/dir dialog styles and other changes (patch 1488371):
[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, const wxMBConv& conv)
30 : m_input(&s), m_be_order(false), m_conv(conv.Clone())
31 #else
32 wxDataInputStream::wxDataInputStream(wxInputStream& s)
33 : m_input(&s), m_be_order(false)
34 #endif
35 {
36 }
37
38 wxDataInputStream::~wxDataInputStream()
39 {
40 #if wxUSE_UNICODE
41 delete m_conv;
42 #endif // wxUSE_UNICODE
43 }
44
45 #if wxHAS_INT64
46 wxUint64 wxDataInputStream::Read64()
47 {
48 wxUint64 tmp;
49 Read64(&tmp, 1);
50 return tmp;
51 }
52 #endif // wxHAS_INT64
53
54 wxUint32 wxDataInputStream::Read32()
55 {
56 wxUint32 i32;
57
58 m_input->Read(&i32, 4);
59
60 if (m_be_order)
61 return wxUINT32_SWAP_ON_LE(i32);
62 else
63 return wxUINT32_SWAP_ON_BE(i32);
64 }
65
66 wxUint16 wxDataInputStream::Read16()
67 {
68 wxUint16 i16;
69
70 m_input->Read(&i16, 2);
71
72 if (m_be_order)
73 return wxUINT16_SWAP_ON_LE(i16);
74 else
75 return wxUINT16_SWAP_ON_BE(i16);
76 }
77
78 wxUint8 wxDataInputStream::Read8()
79 {
80 wxUint8 buf;
81
82 m_input->Read(&buf, 1);
83 return (wxUint8)buf;
84 }
85
86 double wxDataInputStream::ReadDouble()
87 {
88 #if wxUSE_APPLE_IEEE
89 char buf[10];
90
91 m_input->Read(buf, 10);
92 return ConvertFromIeeeExtended((const wxInt8 *)buf);
93 #else
94 return 0.0;
95 #endif
96 }
97
98 wxString wxDataInputStream::ReadString()
99 {
100 size_t len;
101
102 len = Read32();
103
104 if (len > 0)
105 {
106 #if wxUSE_UNICODE
107 wxCharBuffer tmp(len + 1);
108 m_input->Read(tmp.data(), len);
109 tmp.data()[len] = '\0';
110 wxString ret(m_conv->cMB2WX(tmp.data()));
111 #else
112 wxString ret;
113 m_input->Read( wxStringBuffer(ret, len), len);
114 #endif
115 return ret;
116 }
117 else
118 return wxEmptyString;
119 }
120
121 #if wxUSE_LONGLONG
122
123 template <class T>
124 static
125 void DoReadLL(T *buffer, size_t size, wxInputStream *input, bool be_order)
126 {
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 }
159
160 template <class T>
161 static 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
206 template <class T>
207 static
208 void 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
232 template <class T>
233 static
234 void DoWriteI64(const T *buffer, size_t size, wxOutputStream *output, bool be_order)
235 {
236 typedef T DataType;
237 if ( be_order )
238 {
239 for ( size_t i = 0; i < size; i++ )
240 {
241 DataType i64 = wxUINT64_SWAP_ON_LE(*buffer);
242 buffer++;
243 output->Write(&i64, 8);
244 }
245 }
246 else // little endian
247 {
248 for ( size_t i=0; i < size; i++ )
249 {
250 DataType i64 = wxUINT64_SWAP_ON_BE(*buffer);
251 buffer++;
252 output->Write(&i64, 8);
253 }
254 }
255 }
256
257 #endif // wxLongLong_t
258
259
260 #if wxHAS_INT64
261 void 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
270 void 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
281 void wxDataInputStream::Read64(wxULongLong *buffer, size_t size)
282 {
283 DoReadLL(buffer, size, m_input, m_be_order);
284 }
285
286 void 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
293 void wxDataInputStream::ReadLL(wxULongLong *buffer, size_t size)
294 {
295 DoReadLL(buffer, size, m_input, m_be_order);
296 }
297
298 void wxDataInputStream::ReadLL(wxLongLong *buffer, size_t size)
299 {
300 DoReadLL(buffer, size, m_input, m_be_order);
301 }
302
303 wxLongLong wxDataInputStream::ReadLL(void)
304 {
305 wxLongLong ll;
306 DoReadLL(&ll, (size_t)1, m_input, m_be_order);
307 return ll;
308 }
309 #endif // wxUSE_LONGLONG
310
311 void wxDataInputStream::Read32(wxUint32 *buffer, size_t size)
312 {
313 m_input->Read(buffer, size * 4);
314
315 if (m_be_order)
316 {
317 for (wxUint32 i=0; i<size; i++)
318 {
319 wxUint32 v = wxUINT32_SWAP_ON_LE(*buffer);
320 *(buffer++) = v;
321 }
322 }
323 else
324 {
325 for (wxUint32 i=0; i<size; i++)
326 {
327 wxUint32 v = wxUINT32_SWAP_ON_BE(*buffer);
328 *(buffer++) = v;
329 }
330 }
331 }
332
333 void 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
355 void wxDataInputStream::Read8(wxUint8 *buffer, size_t size)
356 {
357 m_input->Read(buffer, size);
358 }
359
360 void wxDataInputStream::ReadDouble(double *buffer, size_t size)
361 {
362 for (wxUint32 i=0; i<size; i++)
363 {
364 *(buffer++) = ReadDouble();
365 }
366 }
367
368 wxDataInputStream& wxDataInputStream::operator>>(wxString& s)
369 {
370 s = ReadString();
371 return *this;
372 }
373
374 wxDataInputStream& wxDataInputStream::operator>>(wxInt8& c)
375 {
376 c = (wxInt8)Read8();
377 return *this;
378 }
379
380 wxDataInputStream& wxDataInputStream::operator>>(wxInt16& i)
381 {
382 i = (wxInt16)Read16();
383 return *this;
384 }
385
386 wxDataInputStream& wxDataInputStream::operator>>(wxInt32& i)
387 {
388 i = (wxInt32)Read32();
389 return *this;
390 }
391
392 wxDataInputStream& wxDataInputStream::operator>>(wxUint8& c)
393 {
394 c = Read8();
395 return *this;
396 }
397
398 wxDataInputStream& wxDataInputStream::operator>>(wxUint16& i)
399 {
400 i = Read16();
401 return *this;
402 }
403
404 wxDataInputStream& wxDataInputStream::operator>>(wxUint32& i)
405 {
406 i = Read32();
407 return *this;
408 }
409
410 #if wxHAS_INT64
411 wxDataInputStream& wxDataInputStream::operator>>(wxUint64& i)
412 {
413 i = Read64();
414 return *this;
415 }
416
417 wxDataInputStream& wxDataInputStream::operator>>(wxInt64& i)
418 {
419 i = Read64();
420 return *this;
421 }
422 #endif // wxHAS_INT64
423
424 #if defined(wxLongLong_t) && wxUSE_LONGLONG
425 wxDataInputStream& wxDataInputStream::operator>>(wxULongLong& i)
426 {
427 i = ReadLL();
428 return *this;
429 }
430
431 wxDataInputStream& wxDataInputStream::operator>>(wxLongLong& i)
432 {
433 i = ReadLL();
434 return *this;
435 }
436 #endif // wxLongLong_t
437
438 wxDataInputStream& wxDataInputStream::operator>>(double& i)
439 {
440 i = ReadDouble();
441 return *this;
442 }
443
444 wxDataInputStream& wxDataInputStream::operator>>(float& f)
445 {
446 f = (float)ReadDouble();
447 return *this;
448 }
449
450 // ---------------------------------------------------------------------------
451 // wxDataOutputStream
452 // ---------------------------------------------------------------------------
453
454 #if wxUSE_UNICODE
455 wxDataOutputStream::wxDataOutputStream(wxOutputStream& s, const wxMBConv& conv)
456 : m_output(&s), m_be_order(false), m_conv(conv.Clone())
457 #else
458 wxDataOutputStream::wxDataOutputStream(wxOutputStream& s)
459 : m_output(&s), m_be_order(false)
460 #endif
461 {
462 }
463
464 wxDataOutputStream::~wxDataOutputStream()
465 {
466 #if wxUSE_UNICODE
467 delete m_conv;
468 #endif // wxUSE_UNICODE
469 }
470
471 #if wxHAS_INT64
472 void wxDataOutputStream::Write64(wxUint64 i)
473 {
474 Write64(&i, 1);
475 }
476
477 void wxDataOutputStream::Write64(wxInt64 i)
478 {
479 Write64(&i, 1);
480 }
481 #endif // wxHAS_INT64
482
483 void wxDataOutputStream::Write32(wxUint32 i)
484 {
485 wxUint32 i32;
486
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);
492 }
493
494 void wxDataOutputStream::Write16(wxUint16 i)
495 {
496 wxUint16 i16;
497
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);
504 }
505
506 void wxDataOutputStream::Write8(wxUint8 i)
507 {
508 m_output->Write(&i, 1);
509 }
510
511 void wxDataOutputStream::WriteString(const wxString& string)
512 {
513 #if wxUSE_UNICODE
514 const wxWX2MBbuf buf = string.mb_str(*m_conv);
515 #else
516 const wxWX2MBbuf buf = string.mb_str();
517 #endif
518 size_t len = strlen(buf);
519 Write32(len);
520 if (len > 0)
521 m_output->Write(buf, len);
522 }
523
524 void wxDataOutputStream::WriteDouble(double d)
525 {
526 char buf[10];
527
528 #if wxUSE_APPLE_IEEE
529 ConvertToIeeeExtended(d, (wxInt8 *)buf);
530 #else
531 #if !defined(__VMS__) && !defined(__GNUG__)
532 # pragma warning "wxDataOutputStream::WriteDouble() not using IeeeExtended - will not work!"
533 #endif
534 buf[0] = '\0';
535 #endif
536 m_output->Write(buf, 10);
537 }
538
539 #if wxHAS_INT64
540 void wxDataOutputStream::Write64(const wxUint64 *buffer, size_t size)
541 {
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
549 void 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
556 }
557 #endif // wxHAS_INT64
558
559 #if defined(wxLongLong_t) && wxUSE_LONGLONG
560 void wxDataOutputStream::Write64(const wxULongLong *buffer, size_t size)
561 {
562 DoWriteLL(buffer, size, m_output, m_be_order);
563 }
564
565 void 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
572 void wxDataOutputStream::WriteLL(const wxULongLong *buffer, size_t size)
573 {
574 DoWriteLL(buffer, size, m_output, m_be_order);
575 }
576
577 void wxDataOutputStream::WriteLL(const wxLongLong *buffer, size_t size)
578 {
579 DoWriteLL(buffer, size, m_output, m_be_order);
580 }
581
582 void wxDataOutputStream::WriteLL(const wxLongLong &ll)
583 {
584 WriteLL(&ll, 1);
585 }
586
587 void wxDataOutputStream::WriteLL(const wxULongLong &ll)
588 {
589 WriteLL(&ll, 1);
590 }
591 #endif // wxUSE_LONGLONG
592
593 void 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
615 void 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
637 void wxDataOutputStream::Write8(const wxUint8 *buffer, size_t size)
638 {
639 m_output->Write(buffer, size);
640 }
641
642 void wxDataOutputStream::WriteDouble(const double *buffer, size_t size)
643 {
644 for (wxUint32 i=0; i<size; i++)
645 {
646 WriteDouble(*(buffer++));
647 }
648 }
649
650 wxDataOutputStream& 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
657 wxDataOutputStream& wxDataOutputStream::operator<<(const wxString& string)
658 {
659 WriteString(string);
660 return *this;
661 }
662
663 wxDataOutputStream& wxDataOutputStream::operator<<(wxInt8 c)
664 {
665 Write8((wxUint8)c);
666 return *this;
667 }
668
669 wxDataOutputStream& wxDataOutputStream::operator<<(wxInt16 i)
670 {
671 Write16((wxUint16)i);
672 return *this;
673 }
674
675 wxDataOutputStream& wxDataOutputStream::operator<<(wxInt32 i)
676 {
677 Write32((wxUint32)i);
678 return *this;
679 }
680
681 wxDataOutputStream& wxDataOutputStream::operator<<(wxUint8 c)
682 {
683 Write8(c);
684 return *this;
685 }
686
687 wxDataOutputStream& wxDataOutputStream::operator<<(wxUint16 i)
688 {
689 Write16(i);
690 return *this;
691 }
692
693 wxDataOutputStream& wxDataOutputStream::operator<<(wxUint32 i)
694 {
695 Write32(i);
696 return *this;
697 }
698
699 #if wxHAS_INT64
700 wxDataOutputStream& wxDataOutputStream::operator<<(wxUint64 i)
701 {
702 Write64(i);
703 return *this;
704 }
705
706 wxDataOutputStream& wxDataOutputStream::operator<<(wxInt64 i)
707 {
708 Write64(i);
709 return *this;
710 }
711 #endif // wxHAS_INT64
712
713 #if defined(wxLongLong_t) && wxUSE_LONGLONG
714 wxDataOutputStream& wxDataOutputStream::operator<<(const wxULongLong &i)
715 {
716 WriteLL(i);
717 return *this;
718 }
719
720 wxDataOutputStream& wxDataOutputStream::operator<<(const wxLongLong &i)
721 {
722 WriteLL(i);
723 return *this;
724 }
725 #endif // wxLongLong_t
726
727 wxDataOutputStream& wxDataOutputStream::operator<<(double f)
728 {
729 WriteDouble(f);
730 return *this;
731 }
732
733 wxDataOutputStream& wxDataOutputStream::operator<<(float f)
734 {
735 WriteDouble((double)f);
736 return *this;
737 }
738
739 #endif
740 // wxUSE_STREAMS