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