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

Last change on this file since 616 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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