source: trunk/src/corelib/io/qdatastream.cpp@ 168

Last change on this file since 168 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 32.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qdatastream.h"
43
44#ifndef QT_NO_DATASTREAM
45#include "qbuffer.h"
46#include "qstring.h"
47#include <stdio.h>
48#include <ctype.h>
49#include <stdlib.h>
50
51QT_BEGIN_NAMESPACE
52
53/*!
54 \class QDataStream
55 \reentrant
56 \brief The QDataStream class provides serialization of binary data
57 to a QIODevice.
58
59 \ingroup io
60 \mainclass
61
62 A data stream is a binary stream of encoded information which is
63 100% independent of the host computer's operating system, CPU or
64 byte order. For example, a data stream that is written by a PC
65 under Windows can be read by a Sun SPARC running Solaris.
66
67 You can also use a data stream to read/write \l{raw}{raw
68 unencoded binary data}. If you want a "parsing" input stream, see
69 QTextStream.
70
71 The QDataStream class implements the serialization of C++'s basic
72 data types, like \c char, \c short, \c int, \c{char *}, etc.
73 Serialization of more complex data is accomplished by breaking up
74 the data into primitive units.
75
76 A data stream cooperates closely with a QIODevice. A QIODevice
77 represents an input/output medium one can read data from and write
78 data to. The QFile class is an example of an I/O device.
79
80 Example (write binary data to a stream):
81
82 \snippet doc/src/snippets/code/src_corelib_io_qdatastream.cpp 0
83
84 Example (read binary data from a stream):
85
86 \snippet doc/src/snippets/code/src_corelib_io_qdatastream.cpp 1
87
88 Each item written to the stream is written in a predefined binary
89 format that varies depending on the item's type. Supported Qt
90 types include QBrush, QColor, QDateTime, QFont, QPixmap, QString,
91 QVariant and many others. For the complete list of all Qt types
92 supporting data streaming see the \l{Format of the QDataStream
93 operators}.
94
95 For integers it is best to always cast to a Qt integer type for
96 writing, and to read back into the same Qt integer type. This
97 ensures that you get integers of the size you want and insulates
98 you from compiler and platform differences.
99
100 To take one example, a \c{char *} string is written as a 32-bit
101 integer equal to the length of the string including the '\\0' byte,
102 followed by all the characters of the string including the
103 '\\0' byte. When reading a \c{char *} string, 4 bytes are read to
104 create the 32-bit length value, then that many characters for the
105 \c {char *} string including the '\\0' terminator are read.
106
107 The initial I/O device is usually set in the constructor, but can be
108 changed with setDevice(). If you've reached the end of the data
109 (or if there is no I/O device set) atEnd() will return true.
110
111 \section1 Versioning
112
113 QDataStream's binary format has evolved since Qt 1.0, and is
114 likely to continue evolving to reflect changes done in Qt. When
115 inputting or outputting complex types, it's very important to
116 make sure that the same version of the stream (version()) is used
117 for reading and writing. If you need both forward and backward
118 compatibility, you can hardcode the version number in the
119 application:
120
121 \snippet doc/src/snippets/code/src_corelib_io_qdatastream.cpp 2
122
123 If you are producing a new binary data format, such as a file
124 format for documents created by your application, you could use a
125 QDataStream to write the data in a portable format. Typically, you
126 would write a brief header containing a magic string and a version
127 number to give yourself room for future expansion. For example:
128
129 \snippet doc/src/snippets/code/src_corelib_io_qdatastream.cpp 3
130
131 Then read it in with:
132
133 \snippet doc/src/snippets/code/src_corelib_io_qdatastream.cpp 4
134
135 You can select which byte order to use when serializing data. The
136 default setting is big endian (MSB first). Changing it to little
137 endian breaks the portability (unless the reader also changes to
138 little endian). We recommend keeping this setting unless you have
139 special requirements.
140
141 \target raw
142 \section1 Reading and writing raw binary data
143
144 You may wish to read/write your own raw binary data to/from the
145 data stream directly. Data may be read from the stream into a
146 preallocated \c{char *} using readRawData(). Similarly data can be
147 written to the stream using writeRawData(). Note that any
148 encoding/decoding of the data must be done by you.
149
150 A similar pair of functions is readBytes() and writeBytes(). These
151 differ from their \e raw counterparts as follows: readBytes()
152 reads a quint32 which is taken to be the length of the data to be
153 read, then that number of bytes is read into the preallocated
154 \c{char *}; writeBytes() writes a quint32 containing the length of the
155 data, followed by the data. Note that any encoding/decoding of
156 the data (apart from the length quint32) must be done by you.
157
158 \target Serializing Qt Classes
159 \section1 Reading and writing other Qt classes.
160
161 In addition to the overloaded stream operators documented here,
162 any Qt classes that you might want to serialize to a QDataStream
163 will have appropriate stream operators declared as non-member of
164 the class:
165
166 \code
167 QDataStream &operator<<(QDataStream &, const QXxx &);
168 QDataStream &operator>>(QDataStream &, QXxx &);
169 \endcode
170
171 For example, here are the stream operators declared as non-members
172 of the QImage class:
173
174 \code
175 QDataStream & operator<< (QDataStream& stream, const QImage& image);
176 QDataStream & operator>> (QDataStream& stream, QImage& image);
177 \endcode
178
179 To see if your favorite Qt class has similar stream operators
180 defined, check the \bold {Related Non-Members} section of the
181 class's documentation page.
182
183 \sa QTextStream QVariant
184*/
185
186/*!
187 \enum QDataStream::ByteOrder
188
189 The byte order used for reading/writing the data.
190
191 \value BigEndian Most significant byte first (the default)
192 \value LittleEndian Least significant byte first
193*/
194
195/*!
196 \enum QDataStream::Status
197
198 This enum describes the current status of the data stream.
199
200 \value Ok The data stream is operating normally.
201 \value ReadPastEnd The data stream has read past the end of the
202 data in the underlying device.
203 \value ReadCorruptData The data stream has read corrupt data.
204*/
205
206/*****************************************************************************
207 QDataStream member functions
208 *****************************************************************************/
209
210#undef CHECK_STREAM_PRECOND
211#ifndef QT_NO_DEBUG
212#define CHECK_STREAM_PRECOND(retVal) \
213 if (!dev) { \
214 qWarning("QDataStream: No device"); \
215 return retVal; \
216 }
217#else
218#define CHECK_STREAM_PRECOND(retVal) \
219 if (!dev) { \
220 return retVal; \
221 }
222#endif
223
224enum {
225 DefaultStreamVersion = QDataStream::Qt_4_5
226};
227
228// ### 5.0: when streaming invalid QVariants, just the type should
229// be written, no "data" after it
230
231/*!
232 Constructs a data stream that has no I/O device.
233
234 \sa setDevice()
235*/
236
237QDataStream::QDataStream()
238{
239 dev = 0;
240 owndev = false;
241 byteorder = BigEndian;
242 ver = DefaultStreamVersion;
243 noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
244 q_status = Ok;
245}
246
247/*!
248 Constructs a data stream that uses the I/O device \a d.
249
250 \warning If you use QSocket or QSocketDevice as the I/O device \a d
251 for reading data, you must make sure that enough data is available
252 on the socket for the operation to successfully proceed;
253 QDataStream does not have any means to handle or recover from
254 short-reads.
255
256 \sa setDevice(), device()
257*/
258
259QDataStream::QDataStream(QIODevice *d)
260{
261 dev = d; // set device
262 owndev = false;
263 byteorder = BigEndian; // default byte order
264 ver = DefaultStreamVersion;
265 noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
266 q_status = Ok;
267}
268
269#ifdef QT3_SUPPORT
270/*!
271 \fn QDataStream::QDataStream(QByteArray *array, int mode)
272 \compat
273
274 Constructs a data stream that operates on the given \a array. The
275 \a mode specifies how the byte array is to be used, and is
276 usually either QIODevice::ReadOnly or QIODevice::WriteOnly.
277*/
278QDataStream::QDataStream(QByteArray *a, int mode)
279{
280 QBuffer *buf = new QBuffer(a);
281#ifndef QT_NO_QOBJECT
282 buf->blockSignals(true);
283#endif
284 buf->open(QIODevice::OpenMode(mode));
285 dev = buf;
286 owndev = true;
287 byteorder = BigEndian;
288 ver = DefaultStreamVersion;
289 noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
290 q_status = Ok;
291}
292#endif
293
294/*!
295 \fn QDataStream::QDataStream(QByteArray *a, QIODevice::OpenMode mode)
296
297 Constructs a data stream that operates on a byte array, \a a. The
298 \a mode describes how the device is to be used.
299
300 Alternatively, you can use QDataStream(const QByteArray &) if you
301 just want to read from a byte array.
302
303 Since QByteArray is not a QIODevice subclass, internally a QBuffer
304 is created to wrap the byte array.
305*/
306
307QDataStream::QDataStream(QByteArray *a, QIODevice::OpenMode flags)
308{
309 QBuffer *buf = new QBuffer(a);
310#ifndef QT_NO_QOBJECT
311 buf->blockSignals(true);
312#endif
313 buf->open(flags);
314 dev = buf;
315 owndev = true;
316 byteorder = BigEndian;
317 ver = DefaultStreamVersion;
318 noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
319 q_status = Ok;
320}
321
322/*!
323 Constructs a read-only data stream that operates on byte array \a a.
324 Use QDataStream(QByteArray*, int) if you want to write to a byte
325 array.
326
327 Since QByteArray is not a QIODevice subclass, internally a QBuffer
328 is created to wrap the byte array.
329*/
330QDataStream::QDataStream(const QByteArray &a)
331{
332 QBuffer *buf = new QBuffer;
333#ifndef QT_NO_QOBJECT
334 buf->blockSignals(true);
335#endif
336 buf->setData(a);
337 buf->open(QIODevice::ReadOnly);
338 dev = buf;
339 owndev = true;
340 byteorder = BigEndian;
341 ver = DefaultStreamVersion;
342 noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
343 q_status = Ok;
344}
345
346/*!
347 Destroys the data stream.
348
349 The destructor will not affect the current I/O device, unless it is
350 an internal I/O device (e.g. a QBuffer) processing a QByteArray
351 passed in the \e constructor, in which case the internal I/O device
352 is destroyed.
353*/
354
355QDataStream::~QDataStream()
356{
357 if (owndev)
358 delete dev;
359}
360
361
362/*!
363 \fn QIODevice *QDataStream::device() const
364
365 Returns the I/O device currently set.
366
367 \sa setDevice(), unsetDevice()
368*/
369
370/*!
371 void QDataStream::setDevice(QIODevice *d)
372
373 Sets the I/O device to \a d.
374
375 \sa device(), unsetDevice()
376*/
377
378void QDataStream::setDevice(QIODevice *d)
379{
380 if (owndev) {
381 delete dev;
382 owndev = false;
383 }
384 dev = d;
385}
386
387/*!
388 \obsolete
389 Unsets the I/O device.
390 Use setDevice(0) instead.
391*/
392
393void QDataStream::unsetDevice()
394{
395 setDevice(0);
396}
397
398
399/*!
400 \fn bool QDataStream::atEnd() const
401
402 Returns true if the I/O device has reached the end position (end of
403 the stream or file) or if there is no I/O device set; otherwise
404 returns false.
405
406 \sa QIODevice::atEnd()
407*/
408
409bool QDataStream::atEnd() const
410{
411 return dev ? dev->atEnd() : true;
412}
413
414/*!
415 Returns the status of the data stream.
416
417 \sa Status setStatus() resetStatus()
418*/
419
420QDataStream::Status QDataStream::status() const
421{
422 return q_status;
423}
424
425/*!
426 Resets the status of the data stream.
427
428 \sa Status status() setStatus()
429*/
430void QDataStream::resetStatus()
431{
432 q_status = Ok;
433}
434
435/*!
436 Sets the status of the data stream to the \a status given.
437
438 \sa Status status() resetStatus()
439*/
440void QDataStream::setStatus(Status status)
441{
442 if (q_status == Ok)
443 q_status = status;
444}
445
446/*!\fn bool QDataStream::eof() const
447
448 Use atEnd() instead.
449*/
450
451/*!
452 \fn int QDataStream::byteOrder() const
453
454 Returns the current byte order setting -- either BigEndian or
455 LittleEndian.
456
457 \sa setByteOrder()
458*/
459
460/*!
461 Sets the serialization byte order to \a bo.
462
463 The \a bo parameter can be QDataStream::BigEndian or
464 QDataStream::LittleEndian.
465
466 The default setting is big endian. We recommend leaving this
467 setting unless you have special requirements.
468
469 \sa byteOrder()
470*/
471
472void QDataStream::setByteOrder(ByteOrder bo)
473{
474 byteorder = bo;
475 if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
476 noswap = (byteorder == BigEndian);
477 else
478 noswap = (byteorder == LittleEndian);
479}
480
481
482/*!
483 \fn bool QDataStream::isPrintableData() const
484
485 In Qt 4, this function always returns false.
486
487 \sa setPrintableData()
488*/
489
490/*!
491 \fn void QDataStream::setPrintableData(bool enable)
492
493 In Qt 3, this function enabled output in a human-readable
494 format if \a enable was false.
495
496 In Qt 4, QDataStream no longer provides a human-readable output.
497 This function does nothing.
498*/
499
500/*!
501 \enum QDataStream::Version
502
503 This enum provides symbolic synonyms for the data serialization
504 format version numbers.
505
506 \value Qt_1_0 Version 1 (Qt 1.x)
507 \value Qt_2_0 Version 2 (Qt 2.0)
508 \value Qt_2_1 Version 3 (Qt 2.1, 2.2, 2.3)
509 \value Qt_3_0 Version 4 (Qt 3.0)
510 \value Qt_3_1 Version 5 (Qt 3.1, 3.2)
511 \value Qt_3_3 Version 6 (Qt 3.3)
512 \value Qt_4_0 Version 7 (Qt 4.0, Qt 4.1)
513 \value Qt_4_1 Version 7 (Qt 4.0, Qt 4.1)
514 \value Qt_4_2 Version 8 (Qt 4.2)
515 \value Qt_4_3 Version 9 (Qt 4.3)
516 \value Qt_4_4 Version 10 (Qt 4.4)
517 \value Qt_4_5 Version 10 (Qt 4.5)
518 \omitvalue Qt_4_6
519
520 \sa setVersion(), version()
521*/
522
523/*!
524 \fn int QDataStream::version() const
525
526 Returns the version number of the data serialization format.
527
528 \sa setVersion(), Version
529*/
530
531/*!
532 \fn void QDataStream::setVersion(int v)
533
534 Sets the version number of the data serialization format to \a v.
535
536 You don't \e have to set a version if you are using the current
537 version of Qt, but for your own custom binary formats we
538 recommend that you do; see \l{Versioning} in the Detailed
539 Description.
540
541 In order to accommodate new functionality, the datastream
542 serialization format of some Qt classes has changed in some
543 versions of Qt. If you want to read data that was created by an
544 earlier version of Qt, or write data that can be read by a
545 program that was compiled with an earlier version of Qt, use this
546 function to modify the serialization format used by QDataStream.
547
548 \table
549 \header \i Qt Version \i QDataStream Version
550 \row \i Qt 4.4 \i 10
551 \row \i Qt 4.3 \i 9
552 \row \i Qt 4.2 \i 8
553 \row \i Qt 4.0, 4.1 \i 7
554 \row \i Qt 3.3 \i 6
555 \row \i Qt 3.1, 3.2 \i 5
556 \row \i Qt 3.0 \i 4
557 \row \i Qt 2.1, 2.2, 2.3 \i 3
558 \row \i Qt 2.0 \i 2
559 \row \i Qt 1.x \i 1
560 \endtable
561
562 The \l Version enum provides symbolic constants for the different
563 versions of Qt. For example:
564
565 \snippet doc/src/snippets/code/src_corelib_io_qdatastream.cpp 5
566
567 \sa version(), Version
568*/
569
570/*****************************************************************************
571 QDataStream read functions
572 *****************************************************************************/
573
574/*!
575 \fn QDataStream &QDataStream::operator>>(quint8 &i)
576 \overload
577
578 Reads an unsigned byte from the stream into \a i, and returns a
579 reference to the stream.
580*/
581
582/*!
583 Reads a signed byte from the stream into \a i, and returns a
584 reference to the stream.
585*/
586
587QDataStream &QDataStream::operator>>(qint8 &i)
588{
589 i = 0;
590 CHECK_STREAM_PRECOND(*this)
591 char c;
592 if (!dev->getChar(&c))
593 setStatus(ReadPastEnd);
594 else
595 i = qint8(c);
596 return *this;
597}
598
599
600/*!
601 \fn QDataStream &QDataStream::operator>>(quint16 &i)
602 \overload
603
604 Reads an unsigned 16-bit integer from the stream into \a i, and
605 returns a reference to the stream.
606*/
607
608/*!
609 \overload
610
611 Reads a signed 16-bit integer from the stream into \a i, and
612 returns a reference to the stream.
613*/
614
615QDataStream &QDataStream::operator>>(qint16 &i)
616{
617 i = 0;
618 CHECK_STREAM_PRECOND(*this)
619 if (noswap) {
620 if (dev->read((char *)&i, 2) != 2) {
621 i = 0;
622 setStatus(ReadPastEnd);
623 }
624 } else {
625 register uchar *p = (uchar *)(&i);
626 char b[2];
627 if (dev->read(b, 2) == 2) {
628 *p++ = b[1];
629 *p = b[0];
630 } else {
631 setStatus(ReadPastEnd);
632 }
633 }
634 return *this;
635}
636
637
638/*!
639 \fn QDataStream &QDataStream::operator>>(quint32 &i)
640 \overload
641
642 Reads an unsigned 32-bit integer from the stream into \a i, and
643 returns a reference to the stream.
644*/
645
646/*!
647 \overload
648
649 Reads a signed 32-bit integer from the stream into \a i, and
650 returns a reference to the stream.
651*/
652
653QDataStream &QDataStream::operator>>(qint32 &i)
654{
655 i = 0;
656 CHECK_STREAM_PRECOND(*this)
657 if (noswap) {
658 if (dev->read((char *)&i, 4) != 4) {
659 i = 0;
660 setStatus(ReadPastEnd);
661 }
662 } else { // swap bytes
663 uchar *p = (uchar *)(&i);
664 char b[4];
665 if (dev->read(b, 4) == 4) {
666 *p++ = b[3];
667 *p++ = b[2];
668 *p++ = b[1];
669 *p = b[0];
670 } else {
671 setStatus(ReadPastEnd);
672 }
673 }
674 return *this;
675}
676
677/*!
678 \fn QDataStream &QDataStream::operator>>(quint64 &i)
679 \overload
680
681 Reads an unsigned 64-bit integer from the stream, into \a i, and
682 returns a reference to the stream.
683*/
684
685/*!
686 \overload
687
688 Reads a signed 64-bit integer from the stream into \a i, and
689 returns a reference to the stream.
690*/
691
692QDataStream &QDataStream::operator>>(qint64 &i)
693{
694 i = qint64(0);
695 CHECK_STREAM_PRECOND(*this)
696 if (version() < 6) {
697 quint32 i1, i2;
698 *this >> i2 >> i1;
699 i = ((quint64)i1 << 32) + i2;
700 } else if (noswap) { // no conversion needed
701 if (dev->read((char *)&i, 8) != 8) {
702 i = qint64(0);
703 setStatus(ReadPastEnd);
704 }
705 } else { // swap bytes
706 uchar *p = (uchar *)(&i);
707 char b[8];
708 if (dev->read(b, 8) == 8) {
709 *p++ = b[7];
710 *p++ = b[6];
711 *p++ = b[5];
712 *p++ = b[4];
713 *p++ = b[3];
714 *p++ = b[2];
715 *p++ = b[1];
716 *p = b[0];
717 } else {
718 setStatus(ReadPastEnd);
719 }
720 }
721 return *this;
722}
723
724/*!
725 Reads a boolean value from the stream into \a i. Returns a
726 reference to the stream.
727*/
728QDataStream &QDataStream::operator>>(bool &i)
729{
730 qint8 v;
731 *this >> v;
732 i = !!v;
733 return *this;
734}
735
736/*!
737 \overload
738
739 Reads a 32-bit floating point number from the stream into \a f,
740 using the standard IEEE 754 format. Returns a reference to the
741 stream.
742*/
743
744QDataStream &QDataStream::operator>>(float &f)
745{
746 f = 0.0f;
747 CHECK_STREAM_PRECOND(*this)
748 if (noswap) {
749 if (dev->read((char *)&f, 4) != 4) {
750 f = 0.0f;
751 setStatus(ReadPastEnd);
752 }
753 } else { // swap bytes
754 uchar *p = (uchar *)(&f);
755 char b[4];
756 if (dev->read(b, 4) == 4) {
757 *p++ = b[3];
758 *p++ = b[2];
759 *p++ = b[1];
760 *p = b[0];
761 } else {
762 setStatus(ReadPastEnd);
763 }
764 }
765 return *this;
766}
767
768#if defined(Q_DOUBLE_FORMAT)
769#define Q_DF(x) Q_DOUBLE_FORMAT[(x)] - '0'
770#endif
771
772/*!
773 \overload
774
775 Reads a 64-bit floating point number from the stream into \a f,
776 using the standard IEEE 754 format. Returns a reference to the
777 stream.
778*/
779
780QDataStream &QDataStream::operator>>(double &f)
781{
782 f = 0.0;
783 CHECK_STREAM_PRECOND(*this)
784#ifndef Q_DOUBLE_FORMAT
785 if (noswap) {
786 if (dev->read((char *)&f, 8) != 8) {
787 f = 0.0;
788 setStatus(ReadPastEnd);
789 }
790 } else { // swap bytes
791 register uchar *p = (uchar *)(&f);
792 char b[8];
793 if (dev->read(b, 8) == 8) {
794 *p++ = b[7];
795 *p++ = b[6];
796 *p++ = b[5];
797 *p++ = b[4];
798 *p++ = b[3];
799 *p++ = b[2];
800 *p++ = b[1];
801 *p = b[0];
802 } else {
803 setStatus(ReadPastEnd);
804 }
805 }
806#else
807 //non-standard floating point format
808 register uchar *p = (uchar *)(&f);
809 char b[8];
810 if (dev->read(b, 8) == 8) {
811 if (noswap) {
812 *p++ = b[Q_DF(0)];
813 *p++ = b[Q_DF(1)];
814 *p++ = b[Q_DF(2)];
815 *p++ = b[Q_DF(3)];
816 *p++ = b[Q_DF(4)];
817 *p++ = b[Q_DF(5)];
818 *p++ = b[Q_DF(6)];
819 *p = b[Q_DF(7)];
820 } else {
821 *p++ = b[Q_DF(7)];
822 *p++ = b[Q_DF(6)];
823 *p++ = b[Q_DF(5)];
824 *p++ = b[Q_DF(4)];
825 *p++ = b[Q_DF(3)];
826 *p++ = b[Q_DF(2)];
827 *p++ = b[Q_DF(1)];
828 *p = b[Q_DF(0)];
829 }
830 } else {
831 setStatus(ReadPastEnd);
832 }
833#endif
834 return *this;
835}
836
837
838/*!
839 \overload
840
841 Reads the '\0'-terminated string \a s from the stream and returns
842 a reference to the stream.
843
844 Space for the string is allocated using \c new -- the caller must
845 destroy it with \c{delete[]}.
846*/
847
848QDataStream &QDataStream::operator>>(char *&s)
849{
850 uint len = 0;
851 return readBytes(s, len);
852}
853
854
855/*!
856 Reads the buffer \a s from the stream and returns a reference to
857 the stream.
858
859 The buffer \a s is allocated using \c new. Destroy it with the \c
860 delete[] operator.
861
862 The \a l parameter is set to the length of the buffer. If the
863 string read is empty, \a l is set to 0 and \a s is set to
864 a null pointer.
865
866 The serialization format is a quint32 length specifier first,
867 then \a l bytes of data.
868
869 \sa readRawData(), writeBytes()
870*/
871
872QDataStream &QDataStream::readBytes(char *&s, uint &l)
873{
874 s = 0;
875 l = 0;
876 CHECK_STREAM_PRECOND(*this)
877
878 quint32 len;
879 *this >> len;
880 if (len == 0)
881 return *this;
882
883 const quint32 Step = 1024 * 1024;
884 quint32 allocated = 0;
885 char *prevBuf = 0;
886 char *curBuf = 0;
887
888 do {
889 int blockSize = qMin(Step, len - allocated);
890 prevBuf = curBuf;
891 curBuf = new char[allocated + blockSize + 1];
892 if (prevBuf) {
893 memcpy(curBuf, prevBuf, allocated);
894 delete [] prevBuf;
895 }
896 if (dev->read(curBuf + allocated, blockSize) != blockSize) {
897 delete [] curBuf;
898 setStatus(ReadPastEnd);
899 return *this;
900 }
901 allocated += blockSize;
902 } while (allocated < len);
903
904 s = curBuf;
905 s[len] = '\0';
906 l = (uint)len;
907 return *this;
908}
909
910/*!
911 Reads at most \a len bytes from the stream into \a s and returns the number of
912 bytes read. If an error occurs, this function returns -1.
913
914 The buffer \a s must be preallocated. The data is \e not encoded.
915
916 \sa readBytes(), QIODevice::read(), writeRawData()
917*/
918
919int QDataStream::readRawData(char *s, int len)
920{
921 CHECK_STREAM_PRECOND(-1)
922 return dev->read(s, len);
923}
924
925
926/*****************************************************************************
927 QDataStream write functions
928 *****************************************************************************/
929
930
931/*!
932 \fn QDataStream &QDataStream::operator<<(quint8 i)
933 \overload
934
935 Writes an unsigned byte, \a i, to the stream and returns a
936 reference to the stream.
937*/
938
939/*!
940 Writes a signed byte, \a i, to the stream and returns a reference
941 to the stream.
942*/
943
944QDataStream &QDataStream::operator<<(qint8 i)
945{
946 CHECK_STREAM_PRECOND(*this)
947 dev->putChar(i);
948 return *this;
949}
950
951
952/*!
953 \fn QDataStream &QDataStream::operator<<(quint16 i)
954 \overload
955
956 Writes an unsigned 16-bit integer, \a i, to the stream and returns
957 a reference to the stream.
958*/
959
960/*!
961 \overload
962
963 Writes a signed 16-bit integer, \a i, to the stream and returns a
964 reference to the stream.
965*/
966
967QDataStream &QDataStream::operator<<(qint16 i)
968{
969 CHECK_STREAM_PRECOND(*this)
970 if (noswap) {
971 dev->write((char *)&i, sizeof(qint16));
972 } else { // swap bytes
973 register uchar *p = (uchar *)(&i);
974 char b[2];
975 b[1] = *p++;
976 b[0] = *p;
977 dev->write(b, 2);
978 }
979 return *this;
980}
981
982/*!
983 \overload
984
985 Writes a signed 32-bit integer, \a i, to the stream and returns a
986 reference to the stream.
987*/
988
989QDataStream &QDataStream::operator<<(qint32 i)
990{
991 CHECK_STREAM_PRECOND(*this)
992 if (noswap) {
993 dev->write((char *)&i, sizeof(qint32));
994 } else { // swap bytes
995 register uchar *p = (uchar *)(&i);
996 char b[4];
997 b[3] = *p++;
998 b[2] = *p++;
999 b[1] = *p++;
1000 b[0] = *p;
1001 dev->write(b, 4);
1002 }
1003 return *this;
1004}
1005
1006/*!
1007 \fn QDataStream &QDataStream::operator<<(quint64 i)
1008 \overload
1009
1010 Writes an unsigned 64-bit integer, \a i, to the stream and returns a
1011 reference to the stream.
1012*/
1013
1014/*!
1015 \overload
1016
1017 Writes a signed 64-bit integer, \a i, to the stream and returns a
1018 reference to the stream.
1019*/
1020
1021QDataStream &QDataStream::operator<<(qint64 i)
1022{
1023 CHECK_STREAM_PRECOND(*this)
1024 if (version() < 6) {
1025 quint32 i1 = i & 0xffffffff;
1026 quint32 i2 = i >> 32;
1027 *this << i2 << i1;
1028 } else if (noswap) { // no conversion needed
1029 dev->write((char *)&i, sizeof(qint64));
1030 } else { // swap bytes
1031 register uchar *p = (uchar *)(&i);
1032 char b[8];
1033 b[7] = *p++;
1034 b[6] = *p++;
1035 b[5] = *p++;
1036 b[4] = *p++;
1037 b[3] = *p++;
1038 b[2] = *p++;
1039 b[1] = *p++;
1040 b[0] = *p;
1041 dev->write(b, 8);
1042 }
1043 return *this;
1044}
1045
1046/*!
1047 \fn QDataStream &QDataStream::operator<<(quint32 i)
1048 \overload
1049
1050 Writes an unsigned integer, \a i, to the stream as a 32-bit
1051 unsigned integer (quint32). Returns a reference to the stream.
1052*/
1053
1054/*!
1055 Writes a boolean value, \a i, to the stream. Returns a reference
1056 to the stream.
1057*/
1058
1059QDataStream &QDataStream::operator<<(bool i)
1060{
1061 CHECK_STREAM_PRECOND(*this)
1062 dev->putChar(qint8(i));
1063 return *this;
1064}
1065
1066/*!
1067 \overload
1068
1069 Writes a 32-bit floating point number, \a f, to the stream using
1070 the standard IEEE 754 format. Returns a reference to the stream.
1071*/
1072
1073QDataStream &QDataStream::operator<<(float f)
1074{
1075 CHECK_STREAM_PRECOND(*this)
1076 float g = f; // fixes float-on-stack problem
1077 if (noswap) { // no conversion needed
1078 dev->write((char *)&g, sizeof(float));
1079 } else { // swap bytes
1080 register uchar *p = (uchar *)(&g);
1081 char b[4];
1082 b[3] = *p++;
1083 b[2] = *p++;
1084 b[1] = *p++;
1085 b[0] = *p;
1086 dev->write(b, 4);
1087 }
1088 return *this;
1089}
1090
1091
1092/*!
1093 \overload
1094
1095 Writes a 64-bit floating point number, \a f, to the stream using
1096 the standard IEEE 754 format. Returns a reference to the stream.
1097*/
1098
1099QDataStream &QDataStream::operator<<(double f)
1100{
1101 CHECK_STREAM_PRECOND(*this)
1102#ifndef Q_DOUBLE_FORMAT
1103 if (noswap) {
1104 dev->write((char *)&f, sizeof(double));
1105 } else {
1106 register uchar *p = (uchar *)(&f);
1107 char b[8];
1108 b[7] = *p++;
1109 b[6] = *p++;
1110 b[5] = *p++;
1111 b[4] = *p++;
1112 b[3] = *p++;
1113 b[2] = *p++;
1114 b[1] = *p++;
1115 b[0] = *p;
1116 dev->write(b, 8);
1117 }
1118#else
1119 register uchar *p = (uchar *)(&f);
1120 char b[8];
1121 if (noswap) {
1122 b[Q_DF(0)] = *p++;
1123 b[Q_DF(1)] = *p++;
1124 b[Q_DF(2)] = *p++;
1125 b[Q_DF(3)] = *p++;
1126 b[Q_DF(4)] = *p++;
1127 b[Q_DF(5)] = *p++;
1128 b[Q_DF(6)] = *p++;
1129 b[Q_DF(7)] = *p;
1130 } else {
1131 b[Q_DF(7)] = *p++;
1132 b[Q_DF(6)] = *p++;
1133 b[Q_DF(5)] = *p++;
1134 b[Q_DF(4)] = *p++;
1135 b[Q_DF(3)] = *p++;
1136 b[Q_DF(2)] = *p++;
1137 b[Q_DF(1)] = *p++;
1138 b[Q_DF(0)] = *p;
1139 }
1140 dev->write(b, 8);
1141#endif
1142 return *this;
1143}
1144
1145
1146/*!
1147 \overload
1148
1149 Writes the '\0'-terminated string \a s to the stream and returns a
1150 reference to the stream.
1151
1152 The string is serialized using writeBytes().
1153*/
1154
1155QDataStream &QDataStream::operator<<(const char *s)
1156{
1157 if (!s) {
1158 *this << (quint32)0;
1159 return *this;
1160 }
1161 uint len = qstrlen(s) + 1; // also write null terminator
1162 *this << (quint32)len; // write length specifier
1163 writeRawData(s, len);
1164 return *this;
1165}
1166
1167
1168/*!
1169 Writes the length specifier \a len and the buffer \a s to the
1170 stream and returns a reference to the stream.
1171
1172 The \a len is serialized as a quint32, followed by \a len bytes
1173 from \a s. Note that the data is \e not encoded.
1174
1175 \sa writeRawData(), readBytes()
1176*/
1177
1178QDataStream &QDataStream::writeBytes(const char *s, uint len)
1179{
1180 CHECK_STREAM_PRECOND(*this)
1181 *this << (quint32)len; // write length specifier
1182 if (len)
1183 writeRawData(s, len);
1184 return *this;
1185}
1186
1187
1188/*!
1189 Writes \a len bytes from \a s to the stream. Returns the
1190 number of bytes actually written, or -1 on error.
1191 The data is \e not encoded.
1192
1193 \sa writeBytes(), QIODevice::write(), readRawData()
1194*/
1195
1196int QDataStream::writeRawData(const char *s, int len)
1197{
1198 CHECK_STREAM_PRECOND(-1)
1199 return dev->write(s, len);
1200}
1201
1202/*!
1203 \since 4.1
1204
1205 Skips \a len bytes from the device. Returns the number of bytes
1206 actually skipped, or -1 on error.
1207
1208 This is equivalent to calling readRawData() on a buffer of length
1209 \a len and ignoring the buffer.
1210
1211 \sa QIODevice::seek()
1212*/
1213int QDataStream::skipRawData(int len)
1214{
1215 CHECK_STREAM_PRECOND(-1)
1216
1217 if (dev->isSequential()) {
1218 char buf[4096];
1219 int sumRead = 0;
1220
1221 while (len > 0) {
1222 int blockSize = qMin(len, (int)sizeof(buf));
1223 int n = dev->read(buf, blockSize);
1224 if (n == -1)
1225 return -1;
1226 if (n == 0)
1227 return sumRead;
1228
1229 sumRead += n;
1230 len -= blockSize;
1231 }
1232 return sumRead;
1233 } else {
1234 qint64 pos = dev->pos();
1235 qint64 size = dev->size();
1236 if (pos + len > size)
1237 len = size - pos;
1238 if (!dev->seek(pos + len))
1239 return -1;
1240 return len;
1241 }
1242}
1243
1244#ifdef QT3_SUPPORT
1245/*!
1246 \fn QDataStream &QDataStream::readRawBytes(char *str, uint len)
1247
1248 Use readRawData() instead.
1249*/
1250
1251/*!
1252 \fn QDataStream &QDataStream::writeRawBytes(const char *str, uint len)
1253
1254 Use writeRawData() instead.
1255*/
1256#endif
1257
1258QT_END_NAMESPACE
1259
1260#endif // QT_NO_DATASTREAM
Note: See TracBrowser for help on using the repository browser.