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

source code of qtbase/src/corelib/serialization/qdatastream.cpp