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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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