Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdatastream.cpp
Go to the documentation of this file.
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
17
206/*****************************************************************************
207 QDataStream member functions
208 *****************************************************************************/
209
210#define Q_VOID
211
212#undef CHECK_STREAM_PRECOND
213#ifndef QT_NO_DEBUG
214#define CHECK_STREAM_PRECOND(retVal) \
215 if (!dev) { \
216 qWarning("QDataStream: No device"); \
217 return retVal; \
218 }
219#else
220#define CHECK_STREAM_PRECOND(retVal) \
221 if (!dev) { \
222 return retVal; \
223 }
224#endif
225
226#define CHECK_STREAM_WRITE_PRECOND(retVal) \
227 CHECK_STREAM_PRECOND(retVal) \
228 if (q_status != Ok) \
229 return retVal;
230
231#define CHECK_STREAM_TRANSACTION_PRECOND(retVal) \
232 if (!d || d->transactionDepth == 0) { \
233 qWarning("QDataStream: No transaction in progress"); \
234 return retVal; \
235 }
236
244{
245 dev = nullptr;
246 owndev = false;
247 byteorder = BigEndian;
250 q_status = Ok;
251}
252
260{
261 dev = d; // set device
262 owndev = false;
263 byteorder = BigEndian; // default byte order
266 q_status = Ok;
267}
268
283{
284 QBuffer *buf = new QBuffer(a);
285#ifndef QT_NO_QOBJECT
286 buf->blockSignals(true);
287#endif
288 buf->open(flags);
289 dev = buf;
290 owndev = true;
291 byteorder = BigEndian;
294 q_status = Ok;
295}
296
306{
307 QBuffer *buf = new QBuffer;
308#ifndef QT_NO_QOBJECT
309 buf->blockSignals(true);
310#endif
311 buf->setData(a);
313 dev = buf;
314 owndev = true;
315 byteorder = BigEndian;
318 q_status = Ok;
319}
320
331{
332 if (owndev)
333 delete dev;
334}
335
336
356{
357 if (owndev) {
358 delete dev;
359 owndev = false;
360 }
361 dev = d;
362}
363
375{
376 return dev ? dev->atEnd() : true;
377}
378
387{
389}
390
412{
413 if (!d)
414 d.reset(new QDataStreamPrivate());
416}
417
425{
426 return q_status;
427}
428
435{
436 q_status = Ok;
437}
438
448{
449 if (q_status == Ok)
450 q_status = status;
451}
452
475{
476 byteorder = bo;
478 noswap = (byteorder == BigEndian);
479 else
480 noswap = (byteorder == LittleEndian);
481}
482
483
600{
602
603 if (!d)
604 d.reset(new QDataStreamPrivate());
605
606 if (++d->transactionDepth == 1) {
607 dev->startTransaction();
608 resetStatus();
609 }
610}
611
633{
635 if (--d->transactionDepth == 0) {
637
638 if (q_status == ReadPastEnd) {
639 dev->rollbackTransaction();
640 return false;
641 }
642 dev->commitTransaction();
643 }
644 return q_status == Ok;
645}
646
671{
673
675 if (--d->transactionDepth != 0)
676 return;
677
679 if (q_status == ReadPastEnd)
680 dev->rollbackTransaction();
681 else
682 dev->commitTransaction();
683}
684
707{
708 q_status = ReadCorruptData;
709
711 if (--d->transactionDepth != 0)
712 return;
713
715 dev->commitTransaction();
716}
717
722{
723 return dev && dev->isTransactionStarted();
724}
725
726/*****************************************************************************
727 QDataStream read functions
728 *****************************************************************************/
729
734int QDataStream::readBlock(char *data, int len)
735{
736 // Disable reads on failure in transacted stream
737 if (q_status != Ok && dev->isTransactionStarted())
738 return -1;
739
740 const int readResult = dev->read(data, len);
741 if (readResult != len)
743 return readResult;
744}
745
771{
772 i = 0;
774 char c;
775 if (readBlock(&c, 1) == 1)
776 i = qint8(c);
777 return *this;
778}
779
780
797{
798 i = 0;
800 if (readBlock(reinterpret_cast<char *>(&i), 2) != 2) {
801 i = 0;
802 } else {
803 if (!noswap) {
804 i = qbswap(i);
805 }
806 }
807 return *this;
808}
809
810
827{
828 i = 0;
830 if (readBlock(reinterpret_cast<char *>(&i), 4) != 4) {
831 i = 0;
832 } else {
833 if (!noswap) {
834 i = qbswap(i);
835 }
836 }
837 return *this;
838}
839
856{
857 i = qint64(0);
859 if (version() < 6) {
860 quint32 i1, i2;
861 *this >> i2 >> i1;
862 i = ((quint64)i1 << 32) + i2;
863 } else {
864 if (readBlock(reinterpret_cast<char *>(&i), 8) != 8) {
865 i = qint64(0);
866 } else {
867 if (!noswap) {
868 i = qbswap(i);
869 }
870 }
871 }
872 return *this;
873}
874
880{
881 qint8 v;
882 *this >> v;
883 i = !!v;
884 return *this;
885}
886
898{
901 double d;
902 *this >> d;
903 f = d;
904 return *this;
905 }
906
907 f = 0.0f;
909 if (readBlock(reinterpret_cast<char *>(&f), 4) != 4) {
910 f = 0.0f;
911 } else {
912 if (!noswap) {
913 union {
914 float val1;
915 quint32 val2;
916 } x;
917 x.val2 = qbswap(*reinterpret_cast<quint32 *>(&f));
918 f = x.val1;
919 }
920 }
921 return *this;
922}
923
935{
938 float d;
939 *this >> d;
940 f = d;
941 return *this;
942 }
943
944 f = 0.0;
946 if (readBlock(reinterpret_cast<char *>(&f), 8) != 8) {
947 f = 0.0;
948 } else {
949 if (!noswap) {
950 union {
951 double val1;
952 quint64 val2;
953 } x;
954 x.val2 = qbswap(*reinterpret_cast<quint64 *>(&f));
955 f = x.val1;
956 }
957 }
958 return *this;
959}
960
961
977{
978 uint len = 0;
979 return readBytes(s, len);
980}
981
990{
991 quint16 u;
992 *this >> u;
993 c = char16_t(u);
994 return *this;
995}
996
1005{
1006 quint32 u;
1007 *this >> u;
1008 c = char32_t(u);
1009 return *this;
1010}
1011
1029{
1030 s = nullptr;
1031 l = 0;
1033
1034 quint32 len;
1035 *this >> len;
1036 if (len == 0)
1037 return *this;
1038
1039 const quint32 Step = 1024 * 1024;
1040 quint32 allocated = 0;
1041 char *prevBuf = nullptr;
1042 char *curBuf = nullptr;
1043
1044 do {
1045 int blockSize = qMin(Step, len - allocated);
1046 prevBuf = curBuf;
1047 curBuf = new char[allocated + blockSize + 1];
1048 if (prevBuf) {
1049 memcpy(curBuf, prevBuf, allocated);
1050 delete [] prevBuf;
1051 }
1052 if (readBlock(curBuf + allocated, blockSize) != blockSize) {
1053 delete [] curBuf;
1054 return *this;
1055 }
1056 allocated += blockSize;
1057 } while (allocated < len);
1058
1059 s = curBuf;
1060 s[len] = '\0';
1061 l = (uint)len;
1062 return *this;
1063}
1064
1075{
1077 return readBlock(s, len);
1078}
1079
1091/*****************************************************************************
1092 QDataStream write functions
1093 *****************************************************************************/
1094
1119{
1121 if (!dev->putChar(i))
1122 q_status = WriteFailed;
1123 return *this;
1124}
1125
1126
1143{
1145 if (!noswap) {
1146 i = qbswap(i);
1147 }
1148 if (dev->write((char *)&i, sizeof(qint16)) != sizeof(qint16))
1149 q_status = WriteFailed;
1150 return *this;
1151}
1152
1161{
1163 if (!noswap) {
1164 i = qbswap(i);
1165 }
1166 if (dev->write((char *)&i, sizeof(qint32)) != sizeof(qint32))
1167 q_status = WriteFailed;
1168 return *this;
1169}
1170
1187{
1189 if (version() < 6) {
1190 quint32 i1 = i & 0xffffffff;
1191 quint32 i2 = i >> 32;
1192 *this << i2 << i1;
1193 } else {
1194 if (!noswap) {
1195 i = qbswap(i);
1196 }
1197 if (dev->write((char *)&i, sizeof(qint64)) != sizeof(qint64))
1198 q_status = WriteFailed;
1199 }
1200 return *this;
1201}
1202
1217{
1219 if (!dev->putChar(qint8(i)))
1220 q_status = WriteFailed;
1221 return *this;
1222}
1223
1234{
1237 *this << double(f);
1238 return *this;
1239 }
1240
1242 float g = f; // fixes float-on-stack problem
1243 if (!noswap) {
1244 union {
1245 float val1;
1246 quint32 val2;
1247 } x;
1248 x.val1 = g;
1249 x.val2 = qbswap(x.val2);
1250
1251 if (dev->write((char *)&x.val2, sizeof(float)) != sizeof(float))
1252 q_status = WriteFailed;
1253 return *this;
1254 }
1255
1256 if (dev->write((char *)&g, sizeof(float)) != sizeof(float))
1257 q_status = WriteFailed;
1258 return *this;
1259}
1260
1261
1272{
1275 *this << float(f);
1276 return *this;
1277 }
1278
1280 if (noswap) {
1281 if (dev->write((char *)&f, sizeof(double)) != sizeof(double))
1282 q_status = WriteFailed;
1283 } else {
1284 union {
1285 double val1;
1286 quint64 val2;
1287 } x;
1288 x.val1 = f;
1289 x.val2 = qbswap(x.val2);
1290 if (dev->write((char *)&x.val2, sizeof(double)) != sizeof(double))
1291 q_status = WriteFailed;
1292 }
1293 return *this;
1294}
1295
1296
1309{
1310 if (!s) {
1311 *this << (quint32)0;
1312 return *this;
1313 }
1314 int len = int(qstrlen(s)) + 1; // also write null terminator
1315 *this << (quint32)len; // write length specifier
1316 writeRawData(s, len);
1317 return *this;
1318}
1319
1328{
1329 return *this << qint16(c);
1330}
1331
1340{
1341 return *this << qint32(c);
1342}
1343
1355{
1357 *this << (quint32)len; // write length specifier
1358 if (len)
1359 writeRawData(s, len);
1360 return *this;
1361}
1362
1363
1372int QDataStream::writeRawData(const char *s, int len)
1373{
1375 int ret = dev->write(s, len);
1376 if (ret != len)
1377 q_status = WriteFailed;
1378 return ret;
1379}
1380
1393{
1395 if (q_status != Ok && dev->isTransactionStarted())
1396 return -1;
1397
1398 const int skipResult = dev->skip(len);
1399 if (skipResult != len)
1401 return skipResult;
1402}
1403
1417
1418#endif // QT_NO_DATASTREAM
\inmodule QtCore \reentrant
Definition qbuffer.h:16
\inmodule QtCore
Definition qbytearray.h:57
QDataStream::FloatingPointPrecision floatingPointPrecision
\inmodule QtCore\reentrant
Definition qdatastream.h:30
QDataStream & operator>>(char &i)
void setFloatingPointPrecision(FloatingPointPrecision precision)
Sets the floating point precision of the data stream to precision.
ByteOrder
The byte order used for reading/writing the data.
Definition qdatastream.h:79
int readRawData(char *, int len)
Reads at most len bytes from the stream into s and returns the number of bytes read.
@ Qt_DefaultCompiledVersion
Definition qdatastream.h:73
bool commitTransaction()
QDataStream & readBytes(char *&, uint &len)
Reads the buffer s from the stream and returns a reference to the stream.
bool isDeviceTransactionStarted() const
Status
This enum describes the current status of the data stream.
Definition qdatastream.h:84
int skipRawData(int len)
int writeRawData(const char *, int len)
Writes len bytes from s to the stream.
~QDataStream()
Destroys the data stream.
void rollbackTransaction()
QDataStream & writeBytes(const char *, uint len)
Writes the length specifier len and the buffer s to the stream and returns a reference to the stream.
void resetStatus()
Resets the status of the data stream.
void setDevice(QIODevice *)
void QDataStream::setDevice(QIODevice *d)
void abortTransaction()
Status status() const
Returns the status of the data stream.
FloatingPointPrecision floatingPointPrecision() const
Returns the floating point precision of the data stream.
FloatingPointPrecision
The precision of floating point numbers used for reading/writing the data.
Definition qdatastream.h:91
void startTransaction()
QDataStream()
Constructs a data stream that has no I/O device.
bool atEnd() const
Returns true if the I/O device has reached the end position (end of the stream or file) or if there i...
int version() const
Returns the version number of the data serialization format.
void setStatus(Status status)
Sets the status of the data stream to the status given.
QDataStream & operator<<(char i)
void setByteOrder(ByteOrder)
Sets the serialization byte order to bo.
\inmodule QtCore \reentrant
Definition qiodevice.h:34
bool putChar(char c)
Writes the character c to the device.
void rollbackTransaction()
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
void startTransaction()
qint64 skip(qint64 maxSize)
bool isTransactionStarted() const
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i....
void commitTransaction()
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
bool blockSignals(bool b) noexcept
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke...
Definition qobject.cpp:1548
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
@ BigEndian
Definition qsysinfo.h:29
@ ByteOrder
Definition qsysinfo.h:34
Combined button and popup list for selecting options.
const int blockSize
size_t qstrlen(const char *str)
#define CHECK_STREAM_WRITE_PRECOND(retVal)
#define CHECK_STREAM_PRECOND(retVal)
#define CHECK_STREAM_TRANSACTION_PRECOND(retVal)
constexpr T qbswap(T source)
Definition qendian.h:103
#define Q_VOID
Definition qiodevice.cpp:46
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLfloat GLfloat f
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean GLboolean g
const GLubyte * c
GLenum GLsizei len
GLdouble s
[6]
Definition qopenglext.h:235
GLenum GLint GLint * precision
unsigned int quint32
Definition qtypes.h:45
short qint16
Definition qtypes.h:42
unsigned short quint16
Definition qtypes.h:43
int qint32
Definition qtypes.h:44
unsigned long long quint64
Definition qtypes.h:56
unsigned int uint
Definition qtypes.h:29
long long qint64
Definition qtypes.h:55
QT_BEGIN_NAMESPACE typedef signed char qint8
Definition qtypes.h:40