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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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