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