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