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

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