source: vendor/trolltech/current/src/tools/qdatastream.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 30.7 KB
Line 
1/****************************************************************************
2** $Id: qdatastream.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QDataStream class
5**
6** Created : 930831
7**
8** Copyright (C) 1992-2004 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qdatastream.h"
39
40#ifndef QT_NO_DATASTREAM
41#include "qbuffer.h"
42#include <stdio.h>
43#include <ctype.h>
44#include <stdlib.h>
45#ifndef Q_OS_TEMP
46#include <locale.h>
47#else
48#include "qt_windows.h"
49#endif
50
51/*!
52 \class QDataStream qdatastream.h
53 \reentrant
54 \brief The QDataStream class provides serialization of binary data
55 to a QIODevice.
56
57 \ingroup io
58
59 A data stream is a binary stream of encoded information which is
60 100% independent of the host computer's operating system, CPU or
61 byte order. For example, a data stream that is written by a PC
62 under Windows can be read by a Sun SPARC running Solaris.
63
64 You can also use a data stream to read/write \link #raw raw
65 unencoded binary data\endlink. If you want a "parsing" input
66 stream, see QTextStream.
67
68 The QDataStream class implements the serialization of C++'s basic
69 data types, like \c char, \c short, \c int, \c char*, etc.
70 Serialization of more complex data is accomplished by breaking up
71 the data into primitive units.
72
73 A data stream cooperates closely with a QIODevice. A QIODevice
74 represents an input/output medium one can read data from and write
75 data to. The QFile class is an example of an IO device.
76
77 Example (write binary data to a stream):
78 \code
79 QFile file( "file.dat" );
80 file.open( IO_WriteOnly );
81 QDataStream stream( &file ); // we will serialize the data into the file
82 stream << "the answer is"; // serialize a string
83 stream << (Q_INT32)42; // serialize an integer
84 \endcode
85
86 Example (read binary data from a stream):
87 \code
88 QFile file( "file.dat" );
89 file.open( IO_ReadOnly );
90 QDataStream stream( &file ); // read the data serialized from the file
91 QString str;
92 Q_INT32 a;
93 stream >> str >> a; // extract "the answer is" and 42
94 \endcode
95
96 Each item written to the stream is written in a predefined binary
97 format that varies depending on the item's type. Supported Qt
98 types include QBrush, QColor, QDateTime, QFont, QPixmap, QString,
99 QVariant and many others. For the complete list of all Qt types
100 supporting data streaming see the \link datastreamformat.html
101 Format of the QDataStream operators \endlink.
102
103 For integers it is best to always cast to a Qt integer type for
104 writing, and to read back into the same Qt integer type. This
105 ensures that you get integers of the size you want and insulates
106 you from compiler and platform differences.
107
108 To take one example, a \c char* string is written as a 32-bit
109 integer equal to the length of the string including the NUL byte
110 ('\0'), followed by all the characters of the string including the
111 NUL byte. When reading a \c char* string, 4 bytes are read to
112 create the 32-bit length value, then that many characters for the
113 \c char* string including the NUL are read.
114
115 The initial IODevice is usually set in the constructor, but can be
116 changed with setDevice(). If you've reached the end of the data
117 (or if there is no IODevice set) atEnd() will return TRUE.
118
119 If you want the data to be compatible with an earlier version of
120 Qt use setVersion().
121
122 If you want the data to be human-readable, e.g. for debugging, you
123 can set the data stream into printable data mode with
124 setPrintableData(). The data is then written slower, in a bloated
125 but human readable format.
126
127 If you are producing a new binary data format, such as a file
128 format for documents created by your application, you could use a
129 QDataStream to write the data in a portable format. Typically, you
130 would write a brief header containing a magic string and a version
131 number to give yourself room for future expansion. For example:
132
133 \code
134 QFile file( "file.xxx" );
135 file.open( IO_WriteOnly );
136 QDataStream stream( &file );
137
138 // Write a header with a "magic number" and a version
139 stream << (Q_UINT32)0xA0B0C0D0;
140 stream << (Q_INT32)123;
141
142 // Write the data
143 stream << [lots of interesting data]
144 \endcode
145
146 Then read it in with:
147
148 \code
149 QFile file( "file.xxx" );
150 file.open( IO_ReadOnly );
151 QDataStream stream( &file );
152
153 // Read and check the header
154 Q_UINT32 magic;
155 stream >> magic;
156 if ( magic != 0xA0B0C0D0 )
157 return XXX_BAD_FILE_FORMAT;
158
159 // Read the version
160 Q_INT32 version;
161 stream >> version;
162 if ( version < 100 )
163 return XXX_BAD_FILE_TOO_OLD;
164 if ( version > 123 )
165 return XXX_BAD_FILE_TOO_NEW;
166 if ( version <= 110 )
167 stream.setVersion(1);
168
169 // Read the data
170 stream >> [lots of interesting data];
171 if ( version > 120 )
172 stream >> [data new in XXX version 1.2];
173 stream >> [other interesting data];
174 \endcode
175
176 You can select which byte order to use when serializing data. The
177 default setting is big endian (MSB first). Changing it to little
178 endian breaks the portability (unless the reader also changes to
179 little endian). We recommend keeping this setting unless you have
180 special requirements.
181
182 \target raw
183 \section1 Reading and writing raw binary data
184
185 You may wish to read/write your own raw binary data to/from the
186 data stream directly. Data may be read from the stream into a
187 preallocated char* using readRawBytes(). Similarly data can be
188 written to the stream using writeRawBytes(). Notice that any
189 encoding/decoding of the data must be done by you.
190
191 A similar pair of functions is readBytes() and writeBytes(). These
192 differ from their \e raw counterparts as follows: readBytes()
193 reads a Q_UINT32 which is taken to be the length of the data to be
194 read, then that number of bytes is read into the preallocated
195 char*; writeBytes() writes a Q_UINT32 containing the length of the
196 data, followed by the data. Notice that any encoding/decoding of
197 the data (apart from the length Q_UINT32) must be done by you.
198
199 \sa QTextStream QVariant
200*/
201
202/*!
203 \enum QDataStream::ByteOrder
204
205 The byte order used for reading/writing the data.
206
207 \value BigEndian the default
208 \value LittleEndian
209*/
210
211
212/*****************************************************************************
213 QDataStream member functions
214 *****************************************************************************/
215
216#if defined(QT_CHECK_STATE)
217#undef CHECK_STREAM_PRECOND
218#define CHECK_STREAM_PRECOND if ( !dev ) { \
219 qWarning( "QDataStream: No device" ); \
220 return *this; }
221#else
222#define CHECK_STREAM_PRECOND
223#endif
224
225static int systemWordSize = 0;
226static bool systemBigEndian;
227
228static const int DefaultStreamVersion = 6;
229// ### On next version bump, QPen::width() should not be restricted to 8-bit values.
230// ### On next version bump, when streaming invalid QVariants, just the type should
231// be written, no "data" after it
232// 6 is default in Qt 3.3
233// 5 is default in Qt 3.1
234// 4 is default in Qt 3.0
235// 3 is default in Qt 2.1
236// 2 is the Qt 2.0.x format
237// 1 is the Qt 1.x format
238
239/*!
240 Constructs a data stream that has no IO device.
241
242 \sa setDevice()
243*/
244
245QDataStream::QDataStream()
246{
247 if ( systemWordSize == 0 ) // get system features
248 qSysInfo( &systemWordSize, &systemBigEndian );
249 dev = 0; // no device set
250 owndev = FALSE;
251 byteorder = BigEndian; // default byte order
252 printable = FALSE;
253 ver = DefaultStreamVersion;
254 noswap = systemBigEndian;
255}
256
257/*!
258 Constructs a data stream that uses the IO device \a d.
259
260 \warning If you use QSocket or QSocketDevice as the IO device \a d
261 for reading data, you must make sure that enough data is available
262 on the socket for the operation to successfully proceed;
263 QDataStream does not have any means to handle or recover from
264 short-reads.
265
266 \sa setDevice(), device()
267*/
268
269QDataStream::QDataStream( QIODevice *d )
270{
271 if ( systemWordSize == 0 ) // get system features
272 qSysInfo( &systemWordSize, &systemBigEndian );
273 dev = d; // set device
274 owndev = FALSE;
275 byteorder = BigEndian; // default byte order
276 printable = FALSE;
277 ver = DefaultStreamVersion;
278 noswap = systemBigEndian;
279}
280
281/*!
282 Constructs a data stream that operates on a byte array, \a a,
283 through an internal QBuffer device. The \a mode is a
284 QIODevice::mode(), usually either \c IO_ReadOnly or \c
285 IO_WriteOnly.
286
287 Example:
288 \code
289 static char bindata[] = { 231, 1, 44, ... };
290 QByteArray a;
291 a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
292 QDataStream stream( a, IO_ReadOnly ); // open on a's data
293 stream >> [something]; // read raw bindata
294 a.resetRawData( bindata, sizeof(bindata) ); // finished
295 \endcode
296
297 The QByteArray::setRawData() function is not for the inexperienced.
298*/
299
300QDataStream::QDataStream( QByteArray a, int mode )
301{
302 if ( systemWordSize == 0 ) // get system features
303 qSysInfo( &systemWordSize, &systemBigEndian );
304 dev = new QBuffer( a ); // create device
305 ((QBuffer *)dev)->open( mode ); // open device
306 owndev = TRUE;
307 byteorder = BigEndian; // default byte order
308 printable = FALSE;
309 ver = DefaultStreamVersion;
310 noswap = systemBigEndian;
311}
312
313/*!
314 Destroys the data stream.
315
316 The destructor will not affect the current IO device, unless it is
317 an internal IO device processing a QByteArray passed in the \e
318 constructor, in which case the internal IO device is destroyed.
319*/
320
321QDataStream::~QDataStream()
322{
323 if ( owndev )
324 delete dev;
325}
326
327
328/*!
329 \fn QIODevice *QDataStream::device() const
330
331 Returns the IO device currently set.
332
333 \sa setDevice(), unsetDevice()
334*/
335
336/*!
337 void QDataStream::setDevice(QIODevice *d )
338
339 Sets the IO device to \a d.
340
341 \sa device(), unsetDevice()
342*/
343
344void QDataStream::setDevice(QIODevice *d )
345{
346 if ( owndev ) {
347 delete dev;
348 owndev = FALSE;
349 }
350 dev = d;
351}
352
353/*!
354 Unsets the IO device. This is the same as calling setDevice( 0 ).
355
356 \sa device(), setDevice()
357*/
358
359void QDataStream::unsetDevice()
360{
361 setDevice( 0 );
362}
363
364
365/*!
366 \fn bool QDataStream::atEnd() const
367
368 Returns TRUE if the IO device has reached the end position (end of
369 the stream or file) or if there is no IO device set; otherwise
370 returns FALSE, i.e. if the current position of the IO device is
371 before the end position.
372
373 \sa QIODevice::atEnd()
374*/
375
376/*!\fn bool QDataStream::eof() const
377
378 \obsolete
379
380 Returns TRUE if the IO device has reached the end position (end of
381 stream or file) or if there is no IO device set.
382
383 Returns FALSE if the current position of the read/write head of the IO
384 device is somewhere before the end position.
385
386 \sa QIODevice::atEnd()
387*/
388
389/*!
390 \fn int QDataStream::byteOrder() const
391
392 Returns the current byte order setting -- either \c BigEndian or
393 \c LittleEndian.
394
395 \sa setByteOrder()
396*/
397
398/*!
399 Sets the serialization byte order to \a bo.
400
401 The \a bo parameter can be \c QDataStream::BigEndian or \c
402 QDataStream::LittleEndian.
403
404 The default setting is big endian. We recommend leaving this
405 setting unless you have special requirements.
406
407 \sa byteOrder()
408*/
409
410void QDataStream::setByteOrder( int bo )
411{
412 byteorder = bo;
413 if ( systemBigEndian )
414 noswap = byteorder == BigEndian;
415 else
416 noswap = byteorder == LittleEndian;
417}
418
419
420/*!
421 \fn bool QDataStream::isPrintableData() const
422
423 Returns TRUE if the printable data flag has been set; otherwise
424 returns FALSE.
425
426 \sa setPrintableData()
427*/
428
429/*!
430 \fn void QDataStream::setPrintableData( bool enable )
431
432 If \a enable is TRUE, data will be output in a human readable
433 format. If \a enable is FALSE, data will be output in a binary
434 format.
435
436 If \a enable is TRUE, the write functions will generate output
437 that consists of printable characters (7 bit ASCII). This output
438 will typically be a lot larger than the default binary output, and
439 consequently slower to write.
440
441 We recommend only enabling printable data for debugging purposes.
442*/
443
444
445/*!
446 \fn int QDataStream::version() const
447
448 Returns the version number of the data serialization format. In Qt
449 3.1, this number is 5.
450
451 \sa setVersion()
452*/
453
454/*!
455 \fn void QDataStream::setVersion( int v )
456
457 Sets the version number of the data serialization format to \a v.
458
459 You don't need to set a version if you are using the current
460 version of Qt.
461
462 In order to accommodate new functionality, the datastream
463 serialization format of some Qt classes has changed in some
464 versions of Qt. If you want to read data that was created by an
465 earlier version of Qt, or write data that can be read by a program
466 that was compiled with an earlier version of Qt, use this function
467 to modify the serialization format of QDataStream.
468
469 \table
470 \header \i Qt Version \i QDataStream Version
471 \row \i Qt 3.1 \i11 5
472 \row \i Qt 3.0 \i11 4
473 \row \i Qt 2.1.x and Qt 2.2.x \i11 3
474 \row \i Qt 2.0.x \i11 2
475 \row \i Qt 1.x \i11 1
476 \endtable
477
478 \sa version()
479*/
480
481/*****************************************************************************
482 QDataStream read functions
483 *****************************************************************************/
484
485#if defined(Q_OS_HPUX) && !defined(__LP64__)
486extern "C" long long __strtoll( const char *, char**, int );
487#endif
488
489static Q_INT64 read_int_ascii( QDataStream *s )
490{
491 register int n = 0;
492 char buf[40];
493 for ( ;; ) {
494 buf[n] = s->device()->getch();
495 if ( buf[n] == '\n' || n > 38 ) // $-terminator
496 break;
497 n++;
498 }
499 buf[n] = '\0';
500
501#if defined(__LP64__) || defined(Q_OS_OSF)
502 // sizeof(long) == 8
503 return strtol(buf, (char **)0, 10);
504#else
505# if defined(Q_OS_TEMP)
506 return strtol( buf, (char**)0, 10 );
507# elif defined(Q_OS_WIN)
508 return _atoi64( buf );
509# elif defined(Q_OS_HPUX)
510 return __strtoll( buf, (char**)0, 10 );
511# elif defined(Q_OS_MACX) && defined(QT_MACOSX_VERSION) && QT_MACOSX_VERSION < 0x1020
512 return strtoq( buf, (char**)0, 10 );
513# else
514 return strtoll( buf, (char**)0, 10 ); // C99 function
515# endif
516#endif
517}
518
519/*!
520 \overload QDataStream &QDataStream::operator>>( Q_UINT8 &i )
521
522 Reads an unsigned byte from the stream into \a i, and returns a
523 reference to the stream.
524*/
525
526/*!
527 Reads a signed byte from the stream into \a i, and returns a
528 reference to the stream.
529*/
530
531QDataStream &QDataStream::operator>>( Q_INT8 &i )
532{
533 CHECK_STREAM_PRECOND
534 if ( printable ) { // printable data
535 i = (Q_INT8)dev->getch();
536 if ( i == '\\' ) { // read octal code
537 char buf[4];
538 dev->readBlock( buf, 3 );
539 i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
540 }
541 } else { // data or text
542 i = (Q_INT8)dev->getch();
543 }
544 return *this;
545}
546
547
548/*!
549 \overload QDataStream &QDataStream::operator>>( Q_UINT16 &i )
550
551 Reads an unsigned 16-bit integer from the stream into \a i, and
552 returns a reference to the stream.
553*/
554
555/*!
556 \overload
557
558 Reads a signed 16-bit integer from the stream into \a i, and
559 returns a reference to the stream.
560*/
561
562QDataStream &QDataStream::operator>>( Q_INT16 &i )
563{
564 CHECK_STREAM_PRECOND
565 if ( printable ) { // printable data
566 i = (Q_INT16)read_int_ascii( this );
567 } else if ( noswap ) { // no conversion needed
568 dev->readBlock( (char *)&i, sizeof(Q_INT16) );
569 } else { // swap bytes
570 register uchar *p = (uchar *)(&i);
571 char b[2];
572 dev->readBlock( b, 2 );
573 *p++ = b[1];
574 *p = b[0];
575 }
576 return *this;
577}
578
579
580/*!
581 \overload QDataStream &QDataStream::operator>>( Q_UINT32 &i )
582
583 Reads an unsigned 32-bit integer from the stream into \a i, and
584 returns a reference to the stream.
585*/
586
587/*!
588 \overload
589
590 Reads a signed 32-bit integer from the stream into \a i, and
591 returns a reference to the stream.
592*/
593
594QDataStream &QDataStream::operator>>( Q_INT32 &i )
595{
596 CHECK_STREAM_PRECOND
597 if ( printable ) { // printable data
598 i = (Q_INT32)read_int_ascii( this );
599 } else if ( noswap ) { // no conversion needed
600 dev->readBlock( (char *)&i, sizeof(Q_INT32) );
601 } else { // swap bytes
602 uchar *p = (uchar *)(&i);
603 char b[4];
604 dev->readBlock( b, 4 );
605 *p++ = b[3];
606 *p++ = b[2];
607 *p++ = b[1];
608 *p = b[0];
609 }
610 return *this;
611}
612
613/*!
614 \overload QDataStream &QDataStream::operator>>( Q_UINT64 &i )
615
616 Reads an unsigned 64-bit integer from the stream, into \a i, and
617 returns a reference to the stream.
618*/
619
620/*!
621 \overload
622
623 Reads a signed 64-bit integer from the stream into \a i, and
624 returns a reference to the stream.
625*/
626
627QDataStream &QDataStream::operator>>( Q_INT64 &i )
628{
629 CHECK_STREAM_PRECOND
630 if ( printable ) { // printable data
631 i = read_int_ascii( this );
632 } else if ( version() < 6 ) {
633 Q_UINT32 i1, i2;
634 *this >> i2 >> i1;
635 i = ((Q_UINT64)i1 << 32) + i2;
636 } else if ( noswap ) { // no conversion needed
637 dev->readBlock( (char *)&i, sizeof(Q_INT64) );
638 } else { // swap bytes
639 uchar *p = (uchar *)(&i);
640 char b[8];
641 dev->readBlock( b, 8 );
642 *p++ = b[7];
643 *p++ = b[6];
644 *p++ = b[5];
645 *p++ = b[4];
646 *p++ = b[3];
647 *p++ = b[2];
648 *p++ = b[1];
649 *p = b[0];
650 }
651 return *this;
652}
653
654
655/*!
656 \overload QDataStream &QDataStream::operator>>( Q_ULONG &i )
657
658 Reads an unsigned integer of the system's word length from the
659 stream, into \a i, and returns a reference to the stream.
660*/
661
662#if !defined(Q_OS_WIN64)
663/*!
664 \overload
665
666 Reads a signed integer of the system's word length from the stream
667 into \a i, and returns a reference to the stream.
668
669*/
670
671QDataStream &QDataStream::operator>>( Q_LONG &i )
672{
673 CHECK_STREAM_PRECOND
674 if ( printable ) { // printable data
675 i = (Q_LONG)read_int_ascii( this );
676 } else if ( noswap ) { // no conversion needed
677 dev->readBlock( (char *)&i, sizeof(Q_LONG) );
678 } else { // swap bytes
679 register uchar *p = (uchar *)(&i);
680 char b[sizeof(Q_LONG)];
681 dev->readBlock( b, sizeof(Q_LONG) );
682 for ( int j = sizeof(Q_LONG); j; )
683 *p++ = b[--j];
684 }
685 return *this;
686}
687#endif
688
689static double read_double_ascii( QDataStream *s )
690{
691 register int n = 0;
692 char buf[80];
693 for ( ;; ) {
694 buf[n] = s->device()->getch();
695 if ( buf[n] == '\n' || n > 78 ) // $-terminator
696 break;
697 n++;
698 }
699 buf[n] = '\0';
700 return atof( buf );
701}
702
703
704/*!
705 \overload
706
707 Reads a 32-bit floating point number from the stream into \a f,
708 using the standard IEEE754 format. Returns a reference to the
709 stream.
710*/
711
712QDataStream &QDataStream::operator>>( float &f )
713{
714 CHECK_STREAM_PRECOND
715 if ( printable ) { // printable data
716 f = (float)read_double_ascii( this );
717 } else if ( noswap ) { // no conversion needed
718 dev->readBlock( (char *)&f, sizeof(float) );
719 } else { // swap bytes
720 uchar *p = (uchar *)(&f);
721 char b[4];
722 dev->readBlock( b, 4 );
723 *p++ = b[3];
724 *p++ = b[2];
725 *p++ = b[1];
726 *p = b[0];
727 }
728 return *this;
729}
730
731
732/*!
733 \overload
734
735 Reads a 64-bit floating point number from the stream into \a f,
736 using the standard IEEE754 format. Returns a reference to the
737 stream.
738*/
739
740QDataStream &QDataStream::operator>>( double &f )
741{
742 CHECK_STREAM_PRECOND
743 if ( printable ) { // printable data
744 f = read_double_ascii( this );
745 } else if ( noswap ) { // no conversion needed
746 dev->readBlock( (char *)&f, sizeof(double) );
747 } else { // swap bytes
748 register uchar *p = (uchar *)(&f);
749 char b[8];
750 dev->readBlock( b, 8 );
751 *p++ = b[7];
752 *p++ = b[6];
753 *p++ = b[5];
754 *p++ = b[4];
755 *p++ = b[3];
756 *p++ = b[2];
757 *p++ = b[1];
758 *p = b[0];
759 }
760 return *this;
761}
762
763
764/*!
765 \overload
766
767 Reads the '\0'-terminated string \a s from the stream and returns
768 a reference to the stream.
769
770 Space for the string is allocated using \c new -- the caller must
771 destroy it with delete[].
772*/
773
774QDataStream &QDataStream::operator>>( char *&s )
775{
776 uint len = 0;
777 return readBytes( s, len );
778}
779
780
781/*!
782 Reads the buffer \a s from the stream and returns a reference to
783 the stream.
784
785 The buffer \a s is allocated using \c new. Destroy it with the \c
786 delete[] operator. If the length is zero or \a s cannot be
787 allocated, \a s is set to 0.
788
789 The \a l parameter will be set to the length of the buffer.
790
791 The serialization format is a Q_UINT32 length specifier first,
792 then \a l bytes of data. Note that the data is \e not encoded.
793
794 \sa readRawBytes(), writeBytes()
795*/
796
797QDataStream &QDataStream::readBytes( char *&s, uint &l )
798{
799 CHECK_STREAM_PRECOND
800 Q_UINT32 len;
801 *this >> len; // first read length spec
802 l = (uint)len;
803 if ( len == 0 || eof() ) {
804 s = 0;
805 return *this;
806 } else {
807 s = new char[len]; // create char array
808 Q_CHECK_PTR( s );
809 if ( !s ) // no memory
810 return *this;
811 return readRawBytes( s, (uint)len );
812 }
813}
814
815
816/*!
817 Reads \a len bytes from the stream into \a s and returns a
818 reference to the stream.
819
820 The buffer \a s must be preallocated. The data is \e not encoded.
821
822 \sa readBytes(), QIODevice::readBlock(), writeRawBytes()
823*/
824
825QDataStream &QDataStream::readRawBytes( char *s, uint len )
826{
827 CHECK_STREAM_PRECOND
828 if ( printable ) { // printable data
829 register Q_INT8 *p = (Q_INT8*)s;
830 if ( version() < 4 ) {
831 while ( len-- ) {
832 Q_INT32 tmp;
833 *this >> tmp;
834 *p++ = tmp;
835 }
836 } else {
837 while ( len-- )
838 *this >> *p++;
839 }
840 } else { // read data char array
841 dev->readBlock( s, len );
842 }
843 return *this;
844}
845
846
847/*****************************************************************************
848 QDataStream write functions
849 *****************************************************************************/
850
851
852/*!
853 \overload QDataStream &QDataStream::operator<<( Q_UINT8 i )
854
855 Writes an unsigned byte, \a i, to the stream and returns a
856 reference to the stream.
857*/
858
859/*!
860 Writes a signed byte, \a i, to the stream and returns a reference
861 to the stream.
862*/
863
864QDataStream &QDataStream::operator<<( Q_INT8 i )
865{
866 CHECK_STREAM_PRECOND
867 if ( printable && (i == '\\' || !isprint((uchar) i)) ) {
868 char buf[6]; // write octal code
869 buf[0] = '\\';
870 buf[1] = '0' + ((i >> 6) & 0x07);
871 buf[2] = '0' + ((i >> 3) & 0x07);
872 buf[3] = '0' + (i & 0x07);
873 buf[4] = '\0';
874 dev->writeBlock( buf, 4 );
875 } else {
876 dev->putch( i );
877 }
878 return *this;
879}
880
881
882/*!
883 \overload QDataStream &QDataStream::operator<<( Q_UINT16 i )
884
885 Writes an unsigned 16-bit integer, \a i, to the stream and returns
886 a reference to the stream.
887*/
888
889/*!
890 \overload
891
892 Writes a signed 16-bit integer, \a i, to the stream and returns a
893 reference to the stream.
894*/
895
896QDataStream &QDataStream::operator<<( Q_INT16 i )
897{
898 CHECK_STREAM_PRECOND
899 if ( printable ) { // printable data
900 char buf[16];
901 sprintf( buf, "%d\n", i );
902 dev->writeBlock( buf, strlen(buf) );
903 } else if ( noswap ) { // no conversion needed
904 dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
905 } else { // swap bytes
906 register uchar *p = (uchar *)(&i);
907 char b[2];
908 b[1] = *p++;
909 b[0] = *p;
910 dev->writeBlock( b, 2 );
911 }
912 return *this;
913}
914
915/*!
916 \overload
917
918 Writes a signed 32-bit integer, \a i, to the stream and returns a
919 reference to the stream.
920*/
921
922QDataStream &QDataStream::operator<<( Q_INT32 i )
923{
924 CHECK_STREAM_PRECOND
925 if ( printable ) { // printable data
926 char buf[16];
927 sprintf( buf, "%d\n", i );
928 dev->writeBlock( buf, strlen(buf) );
929 } else if ( noswap ) { // no conversion needed
930 dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
931 } else { // swap bytes
932 register uchar *p = (uchar *)(&i);
933 char b[4];
934 b[3] = *p++;
935 b[2] = *p++;
936 b[1] = *p++;
937 b[0] = *p;
938 dev->writeBlock( b, 4 );
939 }
940 return *this;
941}
942
943/*!
944 \overload QDataStream &QDataStream::operator<<( Q_UINT64 i )
945
946 Writes an unsigned 64-bit integer, \a i, to the stream and returns a
947 reference to the stream.
948*/
949
950/*!
951 \overload
952
953 Writes a signed 64-bit integer, \a i, to the stream and returns a
954 reference to the stream.
955*/
956
957QDataStream &QDataStream::operator<<( Q_INT64 i )
958{
959 CHECK_STREAM_PRECOND
960 if ( printable ) { // printable data
961 char buf[16];
962#ifdef Q_OS_WIN
963 sprintf( buf, "%I64d\n", i );
964#else
965 sprintf( buf, "%lld\n", i );
966#endif
967 dev->writeBlock( buf, strlen(buf) );
968 } else if ( version() < 6 ) {
969 Q_UINT32 i1, i2;
970 *this >> i2 >> i1;
971 i = ((Q_UINT64)i1 << 32) + i2;
972 } else if ( noswap ) { // no conversion needed
973 dev->writeBlock( (char *)&i, sizeof(Q_INT64) );
974 } else { // swap bytes
975 register uchar *p = (uchar *)(&i);
976 char b[8];
977 b[7] = *p++;
978 b[6] = *p++;
979 b[5] = *p++;
980 b[4] = *p++;
981 b[3] = *p++;
982 b[2] = *p++;
983 b[1] = *p++;
984 b[0] = *p;
985 dev->writeBlock( b, 8 );
986 }
987 return *this;
988}
989
990/*!
991 \overload QDataStream &QDataStream::operator<<( Q_ULONG i )
992
993 Writes an unsigned integer \a i, of the system's word length, to
994 the stream and returns a reference to the stream.
995*/
996
997#if !defined(Q_OS_WIN64)
998/*!
999 \overload
1000
1001 Writes a signed integer \a i, of the system's word length, to the
1002 stream and returns a reference to the stream.
1003*/
1004
1005QDataStream &QDataStream::operator<<( Q_LONG i )
1006{
1007 CHECK_STREAM_PRECOND
1008 if ( printable ) { // printable data
1009 char buf[20];
1010 sprintf( buf, "%ld\n", i );
1011 dev->writeBlock( buf, strlen(buf) );
1012 } else if ( noswap ) { // no conversion needed
1013 dev->writeBlock( (char *)&i, sizeof(Q_LONG) );
1014 } else { // swap bytes
1015 register uchar *p = (uchar *)(&i);
1016 char b[sizeof(Q_LONG)];
1017 for ( int j = sizeof(Q_LONG); j; )
1018 b[--j] = *p++;
1019 dev->writeBlock( b, sizeof(Q_LONG) );
1020 }
1021 return *this;
1022}
1023#endif
1024
1025
1026/*!
1027 \overload QDataStream &QDataStream::operator<<( Q_UINT32 i )
1028
1029 Writes an unsigned integer, \a i, to the stream as a 32-bit
1030 unsigned integer (Q_UINT32). Returns a reference to the stream.
1031*/
1032
1033/*!
1034 \overload
1035
1036 Writes a 32-bit floating point number, \a f, to the stream using
1037 the standard IEEE754 format. Returns a reference to the stream.
1038*/
1039
1040QDataStream &QDataStream::operator<<( float f )
1041{
1042 CHECK_STREAM_PRECOND
1043 if ( printable ) { // printable data
1044 QString num = QString::number((double)f);
1045 dev->writeBlock(num.latin1(), num.length());
1046 } else {
1047 float g = f; // fixes float-on-stack problem
1048 if ( noswap ) { // no conversion needed
1049 dev->writeBlock( (char *)&g, sizeof(float) );
1050 } else { // swap bytes
1051 register uchar *p = (uchar *)(&g);
1052 char b[4];
1053 b[3] = *p++;
1054 b[2] = *p++;
1055 b[1] = *p++;
1056 b[0] = *p;
1057 dev->writeBlock( b, 4 );
1058 }
1059 }
1060 return *this;
1061}
1062
1063
1064/*!
1065 \overload
1066
1067 Writes a 64-bit floating point number, \a f, to the stream using
1068 the standard IEEE754 format. Returns a reference to the stream.
1069*/
1070
1071QDataStream &QDataStream::operator<<( double f )
1072{
1073 CHECK_STREAM_PRECOND
1074 if ( printable ) { // printable data
1075 QString num = QString::number((double)f);
1076 dev->writeBlock(num.latin1(), num.length());
1077 } else if ( noswap ) { // no conversion needed
1078 dev->writeBlock( (char *)&f, sizeof(double) );
1079 } else { // swap bytes
1080 register uchar *p = (uchar *)(&f);
1081 char b[8];
1082 b[7] = *p++;
1083 b[6] = *p++;
1084 b[5] = *p++;
1085 b[4] = *p++;
1086 b[3] = *p++;
1087 b[2] = *p++;
1088 b[1] = *p++;
1089 b[0] = *p;
1090 dev->writeBlock( b, 8 );
1091 }
1092 return *this;
1093}
1094
1095
1096/*!
1097 \overload
1098
1099 Writes the '\0'-terminated string \a s to the stream and returns a
1100 reference to the stream.
1101
1102 The string is serialized using writeBytes().
1103*/
1104
1105QDataStream &QDataStream::operator<<( const char *s )
1106{
1107 if ( !s ) {
1108 *this << (Q_UINT32)0;
1109 return *this;
1110 }
1111 uint len = qstrlen( s ) + 1; // also write null terminator
1112 *this << (Q_UINT32)len; // write length specifier
1113 return writeRawBytes( s, len );
1114}
1115
1116
1117/*!
1118 Writes the length specifier \a len and the buffer \a s to the
1119 stream and returns a reference to the stream.
1120
1121 The \a len is serialized as a Q_UINT32, followed by \a len bytes
1122 from \a s. Note that the data is \e not encoded.
1123
1124 \sa writeRawBytes(), readBytes()
1125*/
1126
1127QDataStream &QDataStream::writeBytes(const char *s, uint len)
1128{
1129 CHECK_STREAM_PRECOND
1130 *this << (Q_UINT32)len; // write length specifier
1131 if ( len )
1132 writeRawBytes( s, len );
1133 return *this;
1134}
1135
1136
1137/*!
1138 Writes \a len bytes from \a s to the stream and returns a
1139 reference to the stream. The data is \e not encoded.
1140
1141 \sa writeBytes(), QIODevice::writeBlock(), readRawBytes()
1142*/
1143
1144QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
1145{
1146 CHECK_STREAM_PRECOND
1147 if ( printable ) { // write printable
1148 if ( version() < 4 ) {
1149 register char *p = (char *)s;
1150 while ( len-- )
1151 *this << *p++;
1152 } else {
1153 register Q_INT8 *p = (Q_INT8*)s;
1154 while ( len-- )
1155 *this << *p++;
1156 }
1157 } else { // write data char array
1158 dev->writeBlock( s, len );
1159 }
1160 return *this;
1161}
1162
1163#endif // QT_NO_DATASTREAM
Note: See TracBrowser for help on using the repository browser.