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 test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <QtGui/QBitmap>
31#include <QtGui/QPainter>
32#include <QtGui/QPainterPath>
33#include <QtGui/QPalette>
34#include <QtGui/QPen>
35#include <QtGui/QPicture>
36#include <QtGui/QPixmap>
37#include <QtGui/QTextLength>
38
39class tst_QDataStream : public QObject
40{
41Q_OBJECT
42
43public:
44 void stream_data(int noOfElements);
45
46public slots:
47 void initTestCase();
48 void cleanupTestCase();
49
50private slots:
51 void getSetCheck();
52 void stream_bool_data();
53 void stream_bool();
54
55 void stream_QBitArray_data();
56 void stream_QBitArray();
57
58 void stream_QBrush_data();
59 void stream_QBrush();
60
61 void stream_QColor_data();
62 void stream_QColor();
63
64 void stream_QByteArray_data();
65 void stream_QByteArray();
66
67#ifndef QT_NO_CURSOR
68 void stream_QCursor_data();
69 void stream_QCursor();
70#endif
71
72 void stream_QDate_data();
73 void stream_QDate();
74
75 void stream_QTime_data();
76 void stream_QTime();
77
78 void stream_QDateTime_data();
79 void stream_QDateTime();
80
81 void stream_nullptr_t_data();
82 void stream_nullptr_t();
83
84 void stream_QFont_data();
85 void stream_QFont();
86
87 void stream_QImage_data();
88 void stream_QImage();
89
90 void stream_QPen_data();
91 void stream_QPen();
92
93 void stream_QPixmap_data();
94 void stream_QPixmap();
95
96 void stream_QPoint_data();
97 void stream_QPoint();
98
99 void stream_QRect_data();
100 void stream_QRect();
101
102 void stream_QPolygon_data();
103 void stream_QPolygon();
104
105 void stream_QRegion_data();
106 void stream_QRegion();
107
108 void stream_QSize_data();
109 void stream_QSize();
110
111 void stream_QString_data();
112 void stream_QString();
113
114 void stream_QRegExp_data();
115 void stream_QRegExp();
116
117#if QT_CONFIG(regularexpression)
118 void stream_QRegularExpression_data();
119 void stream_QRegularExpression();
120#endif
121
122 void stream_Map_data();
123 void stream_Map();
124
125 void stream_Hash_data();
126 void stream_Hash();
127
128 void stream_qint64_data();
129 void stream_qint64();
130
131 void stream_QIcon_data();
132 void stream_QIcon();
133
134 void stream_QEasingCurve_data();
135 void stream_QEasingCurve();
136
137 void stream_atEnd_data();
138 void stream_atEnd();
139
140 void stream_writeError();
141
142 void stream_QByteArray2();
143
144 void stream_QJsonDocument();
145 void stream_QJsonArray();
146 void stream_QJsonObject();
147 void stream_QJsonValue();
148
149 void stream_QCborArray();
150 void stream_QCborMap();
151 void stream_QCborValue();
152
153 void setVersion_data();
154 void setVersion();
155
156 void skipRawData_data();
157 void skipRawData();
158
159 void status_qint8_data();
160 void status_qint8();
161 void status_qint16_data();
162 void status_qint16();
163 void status_qint32_data();
164 void status_qint32();
165 void status_qint64_data();
166 void status_qint64();
167
168 void status_float_data();
169 void status_float();
170 void status_double_data();
171 void status_double();
172
173 void status_charptr_QByteArray_data();
174 void status_charptr_QByteArray();
175
176 void status_QString_data();
177 void status_QString();
178
179 void status_QBitArray_data();
180 void status_QBitArray();
181
182 void status_QHash_QMap();
183
184 void status_QLinkedList_QList_QVector();
185
186 void streamToAndFromQByteArray();
187
188 void streamRealDataTypes();
189
190 void enumTest();
191
192 void floatingPointPrecision();
193
194 void compatibility_Qt5();
195 void compatibility_Qt3();
196 void compatibility_Qt2();
197
198 void floatingPointNaN();
199
200 void transaction_data();
201 void transaction();
202 void nestedTransactionsResult_data();
203 void nestedTransactionsResult();
204
205private:
206 void writebool(QDataStream *s);
207 void writeQBitArray(QDataStream *s);
208 void writeQBrush(QDataStream *s);
209 void writeQColor(QDataStream *s);
210 void writeQByteArray(QDataStream *s);
211 void writenullptr_t(QDataStream *s);
212#ifndef QT_NO_CURSOR
213 void writeQCursor(QDataStream *s);
214#endif
215 void writeQWaitCursor(QDataStream *s);
216 void writeQDate(QDataStream *s);
217 void writeQTime(QDataStream *s);
218 void writeQDateTime(QDataStream *s);
219 void writeQFont(QDataStream *s);
220 void writeQImage(QDataStream *s);
221 void writeQPen(QDataStream *s);
222 void writeQPixmap(QDataStream *s);
223 void writeQPoint(QDataStream *s);
224 void writeQRect(QDataStream *s);
225 void writeQPolygon(QDataStream *s);
226 void writeQRegion(QDataStream *s);
227 void writeQSize(QDataStream *s);
228 void writeQString(QDataStream* dev);
229 void writeQRegExp(QDataStream* dev);
230#if QT_CONFIG(regularexpression)
231 void writeQRegularExpression(QDataStream *dev);
232#endif
233 void writeMap(QDataStream* dev);
234 void writeHash(QDataStream* dev);
235 void writeqint64(QDataStream *s);
236 void writeQIcon(QDataStream *s);
237 void writeQEasingCurve(QDataStream *s);
238
239 void readbool(QDataStream *s);
240 void readQBitArray(QDataStream *s);
241 void readQBrush(QDataStream *s);
242 void readQColor(QDataStream *s);
243 void readQByteArray(QDataStream *s);
244 void readnullptr_t(QDataStream *s);
245#ifndef QT_NO_CURSOR
246 void readQCursor(QDataStream *s);
247#endif
248 void readQDate(QDataStream *s);
249 void readQTime(QDataStream *s);
250 void readQDateTime(QDataStream *s);
251 void readQFont(QDataStream *s);
252 void readQImage(QDataStream *s);
253 void readQPen(QDataStream *s);
254 void readQPixmap(QDataStream *s);
255 void readQPoint(QDataStream *s);
256 void readQRect(QDataStream *s);
257 void readQPolygon(QDataStream *s);
258 void readQRegion(QDataStream *s);
259 void readQSize(QDataStream *s);
260 void readQString(QDataStream *s);
261 void readQRegExp(QDataStream *s);
262#if QT_CONFIG(regularexpression)
263 void readQRegularExpression(QDataStream *s);
264#endif
265 void readMap(QDataStream *s);
266 void readHash(QDataStream *s);
267 void readqint64(QDataStream *s);
268 void readQIcon(QDataStream *s);
269 void readQEasingCurve(QDataStream *s);
270
271private:
272 QSharedPointer<QTemporaryDir> m_tempDir;
273 QString m_previousCurrent;
274};
275
276static int NColorRoles[] = {
277 QPalette::NoRole, // No Version
278 QPalette::NoRole, // Qt_1_0
279 QPalette::HighlightedText + 1, // Qt_2_0
280 QPalette::HighlightedText + 1, // Qt_2_1
281 QPalette::LinkVisited + 1, // Qt_3_0
282 QPalette::HighlightedText + 1, // Qt_3_1
283 QPalette::HighlightedText + 1, // Qt_3_3
284 QPalette::HighlightedText + 1, // Qt_4_0, Qt_4_1
285 QPalette::HighlightedText + 1, // Qt_4_2
286 QPalette::AlternateBase + 1, // Qt_4_3
287 QPalette::ToolTipText + 1, // Qt_4_4
288 QPalette::ToolTipText + 1, // Qt_4_5
289 QPalette::ToolTipText + 1, // Qt_4_6, Qt_4_7, Qt_4_8, Qt_4_9
290 QPalette::ToolTipText + 1, // Qt_5_0
291 QPalette::ToolTipText + 1, // Qt_5_1
292 QPalette::ToolTipText + 1, // Qt_5_2, Qt_5_3
293 QPalette::ToolTipText + 1, // Qt_5_4, Qt_5_5
294 QPalette::ToolTipText + 1, // Qt_5_6, Qt_5_7, Qt_5_8, Qt_5_9, Qt_5_10, Qt_5_11
295 QPalette::PlaceholderText + 1, // Qt_5_12
296 QPalette::PlaceholderText + 1, // Qt_5_13
297 0 // add the correct value for Qt_5_14 here later
298};
299
300// Testing get/set functions
301void tst_QDataStream::getSetCheck()
302{
303 QDataStream obj1;
304 // QIODevice * QDataStream::device()
305 // void QDataStream::setDevice(QIODevice *)
306 QFile *var1 = new QFile;
307 obj1.setDevice(var1);
308 QCOMPARE((QIODevice *)var1, (QIODevice *)obj1.device());
309 obj1.setDevice((QIODevice *)0);
310 QCOMPARE((QIODevice *)0, (QIODevice *)obj1.device());
311 delete var1;
312
313 // Status QDataStream::status()
314 // void QDataStream::setStatus(Status)
315 obj1.setStatus(QDataStream::Ok);
316 QCOMPARE(QDataStream::Ok, obj1.status());
317 obj1.setStatus(QDataStream::ReadPastEnd);
318 QCOMPARE(QDataStream::ReadPastEnd, obj1.status());
319 obj1.resetStatus();
320 obj1.setStatus(QDataStream::ReadCorruptData);
321 QCOMPARE(QDataStream::ReadCorruptData, obj1.status());
322}
323
324void tst_QDataStream::initTestCase()
325{
326 m_previousCurrent = QDir::currentPath();
327 m_tempDir = QSharedPointer<QTemporaryDir>::create();
328 QVERIFY2(!m_tempDir.isNull(), qPrintable("Could not create temporary directory."));
329 QVERIFY2(QDir::setCurrent(m_tempDir->path()), qPrintable("Could not switch current directory"));
330}
331
332void tst_QDataStream::cleanupTestCase()
333{
334 QFile::remove(fileName: QLatin1String("qdatastream.out"));
335 QFile::remove(fileName: QLatin1String("datastream.tmp"));
336
337 QDir::setCurrent(m_previousCurrent);
338}
339
340static int dataIndex(const QString &tag)
341{
342 int pos = tag.lastIndexOf(c: QLatin1Char('_'));
343 if (pos >= 0) {
344 int ret = 0;
345 QString count = tag.mid(position: pos + 1);
346 bool ok;
347 ret = count.toInt(ok: &ok);
348 if (ok)
349 return ret;
350 }
351 return -1;
352}
353
354static const char * const devices[] = {
355 "file",
356 "bytearray",
357 "buffer",
358 0
359};
360
361/*
362 IMPORTANT.
363 In this testcase i follow a different approach than usual: I don't use the full power of
364 QtTestTable and QtTestData. This is done deliberately because QtTestData uses a QDataStream
365 itself to handle its data. So it would be a bit inapropriate to fully rely on QtTestData in this
366 testcase.
367 I do use QString in QtTestData because this is thouroughly tested in the selftest.
368*/
369void tst_QDataStream::stream_data(int noOfElements)
370{
371 QTest::addColumn<QString>(name: "device");
372 QTest::addColumn<QString>(name: "byteOrder");
373
374 for (int d=0; devices[d] != 0; d++) {
375 QString device = devices[d];
376 for (int b=0; b<2; b++) {
377 QString byte_order = b == 0 ? "BigEndian" : "LittleEndian";
378
379 QString tag = device + QLatin1Char('_') + byte_order;
380 for (int e=0; e<noOfElements; e++) {
381 QTest::newRow(qPrintable(tag + QLatin1Char('_') + QString::number(e))) << device << byte_order;
382 }
383 }
384 }
385}
386
387static const char* open_xpm[]={
388"16 13 6 1",
389". c None",
390"b c #ffff00",
391"d c #000000",
392"* c #999999",
393"c c #cccccc",
394"a c #ffffff",
395"...*****........",
396"..*aaaaa*.......",
397".*abcbcba******.",
398".*acbcbcaaaaaa*d",
399".*abcbcbcbcbcb*d",
400"*************b*d",
401"*aaaaaaaaaa**c*d",
402"*abcbcbcbcbbd**d",
403".*abcbcbcbcbcd*d",
404".*acbcbcbcbcbd*d",
405"..*acbcbcbcbb*dd",
406"..*************d",
407"...ddddddddddddd"};
408
409#define STREAM_IMPL(TYPE) \
410 QFETCH(QString, device); \
411 if (device == "bytearray") { \
412 QByteArray ba; \
413 QDataStream sout(&ba, QIODevice::WriteOnly); \
414 write##TYPE(&sout); \
415 QDataStream sin(&ba, QIODevice::ReadOnly); \
416 read##TYPE(&sin); \
417 } else if (device == "file") { \
418 QString fileName = "qdatastream.out"; \
419 QFile fOut(fileName); \
420 QVERIFY(fOut.open(QIODevice::WriteOnly)); \
421 QDataStream sout(&fOut); \
422 write##TYPE(&sout); \
423 fOut.close(); \
424 QFile fIn(fileName); \
425 QVERIFY(fIn.open(QIODevice::ReadOnly)); \
426 QDataStream sin(&fIn); \
427 read##TYPE(&sin); \
428 fIn.close(); \
429 } else if (device == "buffer") { \
430 QByteArray ba(10000, '\0'); \
431 QBuffer bOut(&ba); \
432 bOut.open(QIODevice::WriteOnly); \
433 QDataStream sout(&bOut); \
434 write##TYPE(&sout); \
435 bOut.close(); \
436 QBuffer bIn(&ba); \
437 bIn.open(QIODevice::ReadOnly); \
438 QDataStream sin(&bIn); \
439 read##TYPE(&sin); \
440 bIn.close(); \
441 }
442
443// ************************************
444
445static QString stringData(int index)
446{
447 switch (index) {
448 case 0: return QString();
449 case 1: return QString("");
450 case 2: return QString("A");
451 case 3: return QString("ABCDE FGHI");
452 case 4: return QString("This is a long string");
453 case 5: return QString("And again a string with a \nCRLF");
454 case 6: return QString("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/");
455 }
456 return QString("foo");
457}
458#define MAX_QSTRING_DATA 7
459
460void tst_QDataStream::stream_QString_data()
461{
462 stream_data(MAX_QSTRING_DATA);
463}
464
465void tst_QDataStream::stream_QString()
466{
467 STREAM_IMPL(QString);
468}
469
470void tst_QDataStream::writeQString(QDataStream* s)
471{
472 QString test(stringData(index: dataIndex(tag: QTest::currentDataTag())));
473 *s << test;
474 *s << QString("Her er det noe tekst");
475 *s << test;
476 *s << QString();
477 *s << test;
478 *s << QString("");
479 *s << test;
480 *s << QString("nonempty");
481 *s << test;
482}
483
484void tst_QDataStream::readQString(QDataStream *s)
485{
486 QString S;
487 QString test(stringData(index: dataIndex(tag: QTest::currentDataTag())));
488
489 *s >> S;
490 QCOMPARE(S, test);
491 *s >> S;
492 QCOMPARE(S, QString("Her er det noe tekst"));
493 *s >> S;
494 QCOMPARE(S, test);
495 *s >> S;
496 QVERIFY(S.isNull());
497 *s >> S;
498 QCOMPARE(S, test);
499 *s >> S;
500 QVERIFY(S.isEmpty());
501 *s >> S;
502 QCOMPARE(S, test);
503 *s >> S;
504 QCOMPARE(S, QString("nonempty"));
505 *s >> S;
506 QCOMPARE(S, test);
507}
508
509// ************************************
510
511static QRegExp QRegExpData(int index)
512{
513 switch (index) {
514 case 0: return QRegExp();
515 case 1: return QRegExp("");
516 case 2: return QRegExp("A", Qt::CaseInsensitive);
517 case 3: return QRegExp("ABCDE FGHI", Qt::CaseSensitive, QRegExp::Wildcard);
518 case 4: return QRegExp("This is a long string", Qt::CaseInsensitive, QRegExp::FixedString);
519 case 5: return QRegExp("And again a string with a \nCRLF", Qt::CaseInsensitive, QRegExp::RegExp);
520 case 6:
521 {
522 QRegExp rx("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/");
523 rx.setMinimal(true);
524 return rx;
525 }
526 }
527 return QRegExp("foo");
528}
529#define MAX_QREGEXP_DATA 7
530
531void tst_QDataStream::stream_QRegExp_data()
532{
533 stream_data(MAX_QREGEXP_DATA);
534}
535
536void tst_QDataStream::stream_QRegExp()
537{
538 STREAM_IMPL(QRegExp);
539}
540
541void tst_QDataStream::writeQRegExp(QDataStream* s)
542{
543 QRegExp test(QRegExpData(index: dataIndex(tag: QTest::currentDataTag())));
544 *s << test;
545 *s << QString("Her er det noe tekst");
546 *s << test;
547 *s << QString("nonempty");
548 *s << test;
549 *s << QVariant(test);
550}
551
552void tst_QDataStream::readQRegExp(QDataStream *s)
553{
554 QRegExp R;
555 QString S;
556 QVariant V;
557 QRegExp test(QRegExpData(index: dataIndex(tag: QTest::currentDataTag())));
558
559 *s >> R;
560 QCOMPARE(R, test);
561 *s >> S;
562 QCOMPARE(S, QString("Her er det noe tekst"));
563 *s >> R;
564 QCOMPARE(R, test);
565 *s >> S;
566 QCOMPARE(S, QString("nonempty"));
567 *s >> R;
568 QCOMPARE(R, test);
569 *s >> V;
570 QCOMPARE(V.type(), QVariant::RegExp);
571 QCOMPARE(V.toRegExp(), test);
572}
573
574// ************************************
575
576#if QT_CONFIG(regularexpression)
577static QRegularExpression QRegularExpressionData(int index)
578{
579 switch (index) {
580 case 0: return QRegularExpression();
581 case 1: return QRegularExpression("");
582 case 2: return QRegularExpression("A", QRegularExpression::CaseInsensitiveOption);
583 case 3: return QRegularExpression(QRegularExpression::wildcardToRegularExpression(str: "ABCDE FGHI"));
584 case 4: return QRegularExpression(QRegularExpression::anchoredPattern(expression: "This is a long string"), QRegularExpression::CaseInsensitiveOption);
585 case 5: return QRegularExpression("And again a string with a \nCRLF", QRegularExpression::CaseInsensitiveOption);
586 case 6: return QRegularExpression("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRESTUVWXYZ 1234567890 ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/", QRegularExpression::InvertedGreedinessOption);
587 }
588 return QRegularExpression("foo");
589}
590#define MAX_QREGULAREXPRESSION_DATA 7
591
592void tst_QDataStream::stream_QRegularExpression_data()
593{
594 stream_data(MAX_QREGULAREXPRESSION_DATA);
595}
596
597void tst_QDataStream::stream_QRegularExpression()
598{
599 STREAM_IMPL(QRegularExpression);
600}
601
602void tst_QDataStream::writeQRegularExpression(QDataStream* s)
603{
604 QRegularExpression test(QRegularExpressionData(index: dataIndex(tag: QTest::currentDataTag())));
605 *s << test;
606 *s << QString("Her er det noe tekst");
607 *s << test;
608 *s << QString("nonempty");
609 *s << test;
610 *s << QVariant(test);
611}
612
613void tst_QDataStream::readQRegularExpression(QDataStream *s)
614{
615 QRegularExpression R;
616 QString S;
617 QVariant V;
618 QRegularExpression test(QRegularExpressionData(index: dataIndex(tag: QTest::currentDataTag())));
619
620 *s >> R;
621
622 QCOMPARE(R, test);
623 *s >> S;
624 QCOMPARE(S, QString("Her er det noe tekst"));
625 *s >> R;
626 QCOMPARE(R, test);
627 *s >> S;
628 QCOMPARE(S, QString("nonempty"));
629 *s >> R;
630 QCOMPARE(R, test);
631 *s >> V;
632 QCOMPARE(V.type(), QVariant::RegularExpression);
633 QCOMPARE(V.toRegularExpression(), test);
634}
635#endif //QT_CONFIG(regularexpression)
636
637// ************************************
638
639typedef QMap<int, QString> Map;
640
641static Map MapData(int index)
642{
643 Map map;
644
645 switch (index) {
646 case 0:
647 default:
648 break;
649 case 1:
650 map.insert(key: 1, value: "a");
651 map.insert(key: 2, value: "bbb");
652 map.insert(key: 3, value: "cccccc");
653 break;
654 case 2:
655 map.insert(key: 1, value: "a");
656 map.insert(key: 2, value: "one");
657 map.insertMulti(key: 2, value: "two");
658 map.insertMulti(key: 2, value: "three");
659 map.insert(key: 3, value: "cccccc");
660 }
661 return map;
662}
663#define MAX_MAP_DATA 3
664
665void tst_QDataStream::stream_Map_data()
666{
667 stream_data(MAX_MAP_DATA);
668}
669
670void tst_QDataStream::stream_Map()
671{
672 STREAM_IMPL(Map);
673}
674
675void tst_QDataStream::writeMap(QDataStream* s)
676{
677 Map test(MapData(index: dataIndex(tag: QTest::currentDataTag())));
678 *s << test;
679 *s << test;
680}
681
682void tst_QDataStream::readMap(QDataStream *s)
683{
684 Map S;
685 Map test(MapData(index: dataIndex(tag: QTest::currentDataTag())));
686
687 *s >> S;
688 QCOMPARE(S, test);
689 *s >> S;
690 QCOMPARE(S, test);
691}
692
693// ************************************
694
695typedef QHash<int, QString> Hash;
696
697static Hash HashData(int index)
698{
699 Hash map;
700
701 switch (index) {
702 case 0:
703 default:
704 break;
705 case 1:
706 map.insert(key: 1, value: "a");
707 map.insert(key: 2, value: "bbb");
708 map.insert(key: 3, value: "cccccc");
709 break;
710 case 2:
711 map.insert(key: 1, value: "a");
712 map.insert(key: 2, value: "one");
713 map.insertMulti(key: 2, value: "two");
714 map.insertMulti(key: 2, value: "three");
715 map.insert(key: 3, value: "cccccc");
716 }
717 return map;
718}
719#define MAX_HASH_DATA 3
720
721void tst_QDataStream::stream_Hash_data()
722{
723 stream_data(MAX_HASH_DATA);
724}
725
726void tst_QDataStream::stream_Hash()
727{
728 STREAM_IMPL(Hash);
729}
730
731void tst_QDataStream::writeHash(QDataStream* s)
732{
733 Hash test(HashData(index: dataIndex(tag: QTest::currentDataTag())));
734 *s << test;
735 *s << test;
736}
737
738void tst_QDataStream::readHash(QDataStream *s)
739{
740 Hash S;
741 Hash test(HashData(index: dataIndex(tag: QTest::currentDataTag())));
742
743 *s >> S;
744 QCOMPARE(S, test);
745 *s >> S;
746 QCOMPARE(S, test);
747}
748
749// ************************************
750
751static QEasingCurve QEasingCurveData(int index)
752{
753 QEasingCurve easing;
754
755 switch (index) {
756 case 0:
757 default:
758 break;
759 case 1:
760 easing.setType(QEasingCurve::Linear);
761 break;
762 case 2:
763 easing.setType(QEasingCurve::OutCubic);
764 break;
765 case 3:
766 easing.setType(QEasingCurve::InOutSine);
767 break;
768 case 4:
769 easing.setType(QEasingCurve::InOutElastic);
770 easing.setPeriod(1.5);
771 easing.setAmplitude(2.0);
772 break;
773 case 5:
774 easing.setType(QEasingCurve::OutInBack);
775 break;
776 case 6:
777 easing.setType(QEasingCurve::OutCurve);
778 break;
779 case 7:
780 easing.setType(QEasingCurve::InOutBack);
781 easing.setOvershoot(0.5);
782 break;
783 }
784 return easing;
785}
786#define MAX_EASING_DATA 8
787
788void tst_QDataStream::stream_QEasingCurve_data()
789{
790 stream_data(MAX_EASING_DATA);
791}
792
793void tst_QDataStream::stream_QEasingCurve()
794{
795 STREAM_IMPL(QEasingCurve);
796}
797
798void tst_QDataStream::writeQEasingCurve(QDataStream* s)
799{
800 QEasingCurve test(QEasingCurveData(index: dataIndex(tag: QTest::currentDataTag())));
801 *s << test;
802}
803
804void tst_QDataStream::readQEasingCurve(QDataStream *s)
805{
806 QEasingCurve S;
807 QEasingCurve expected(QEasingCurveData(index: dataIndex(tag: QTest::currentDataTag())));
808
809 *s >> S;
810 QCOMPARE(S, expected);
811}
812
813// ************************************
814
815// contains some quint64 testing as well
816
817#define MAX_qint64_DATA 4
818
819static qint64 qint64Data(int index)
820{
821 switch (index) {
822 case 0: return qint64(0);
823 case 1: return qint64(1);
824 case 2: return qint64(-1);
825 case 3: return qint64(1) << 40;
826 case MAX_qint64_DATA: return -(qint64(1) << 40);
827 }
828
829 return -1;
830}
831
832void tst_QDataStream::stream_qint64_data()
833{
834 stream_data(MAX_qint64_DATA+1);
835}
836
837void tst_QDataStream::stream_qint64()
838{
839 STREAM_IMPL(qint64);
840}
841
842void tst_QDataStream::writeqint64(QDataStream* s)
843{
844 qint64 test = qint64Data(index: dataIndex(tag: QTest::currentDataTag()));
845 *s << test;
846 *s << int(1);
847 *s << (quint64)test;
848}
849
850void tst_QDataStream::readqint64(QDataStream *s)
851{
852 qint64 test = qint64Data(index: dataIndex(tag: QTest::currentDataTag()));
853 qint64 i64;
854 quint64 ui64;
855 int i;
856 *s >> i64;
857 QCOMPARE(i64, test);
858 *s >> i;
859 QCOMPARE(i, int(1));
860 *s >> ui64;
861 QCOMPARE(ui64, (quint64)test);
862}
863
864// ************************************
865
866static bool boolData(int index)
867{
868 switch (index) {
869 case 0: return true;
870 case 1: return false;
871 case 2: return bool(2);
872 case 3: return bool(-1);
873 case 4: return bool(127);
874 }
875
876 return false;
877}
878
879void tst_QDataStream::stream_bool_data()
880{
881 stream_data(noOfElements: 5);
882}
883
884void tst_QDataStream::stream_bool()
885{
886 STREAM_IMPL(bool);
887}
888
889void tst_QDataStream::writebool(QDataStream *s)
890{
891 bool d1 = boolData(index: dataIndex(tag: QTest::currentDataTag()));
892 *s << d1;
893}
894
895void tst_QDataStream::readbool(QDataStream *s)
896{
897 bool expected = boolData(index: dataIndex(tag: QTest::currentDataTag()));
898
899 bool d1;
900 *s >> d1;
901 QCOMPARE(d1, expected);
902}
903
904// ************************************
905
906static void QBitArrayData(QBitArray *b, int index)
907{
908 QString filler = "";
909 switch (index) {
910 case 0: filler = ""; break;
911 case 1: filler = ""; break;
912 case 2: filler = "0"; break;
913 case 3: filler = "1"; break;
914 case 4: filler = "0000"; break;
915 case 5: filler = "0001"; break;
916 case 6: filler = "0010"; break;
917 case 7: filler = "0100"; break;
918 case 8: filler = "1000"; break;
919 case 9: filler = "1111"; break;
920 case 10: filler = "00000000"; break;
921 case 11: filler = "00000001"; break;
922 case 12: filler = "11111111"; break;
923 case 13: filler = "000000001"; break;
924 case 14: filler = "000000000001"; break;
925 case 15: filler = "0000000000000001"; break;
926 case 16: filler = "0101010101010101010101010101010101010101010101010101010101010101"; break;
927 case 17: filler = "1010101010101010101010101010101010101010101010101010101010101010"; break;
928 case 18: filler = "1111111111111111111111111111111111111111111111111111111111111111"; break;
929 }
930
931 b->resize(size: filler.length());
932 b->fill(aval: 0); // reset all bits to zero
933
934 for (int i = 0; i < filler.length(); ++i) {
935 if (filler.at(i) == '1')
936 b->setBit(i, val: true);
937 }
938}
939
940void tst_QDataStream::stream_QBitArray_data()
941{
942 stream_data(noOfElements: 19);
943}
944
945void tst_QDataStream::stream_QBitArray()
946{
947 STREAM_IMPL(QBitArray);
948}
949
950void tst_QDataStream::writeQBitArray(QDataStream *s)
951{
952 QBitArray d1;
953 QBitArrayData(b: &d1, index: dataIndex(tag: QTest::currentDataTag()));
954 *s << d1;
955}
956
957void tst_QDataStream::readQBitArray(QDataStream *s)
958{
959 QBitArray expected;
960 QBitArrayData(b: &expected, index: dataIndex(tag: QTest::currentDataTag()));
961
962 QBitArray d1;
963 *s >> d1;
964 QCOMPARE(d1, expected);
965}
966
967// ************************************
968
969static QBrush qBrushData(int index)
970{
971 switch (index) {
972 case 0: return QBrush(Qt::NoBrush);
973 case 1: return QBrush(Qt::SolidPattern);
974 case 2: return QBrush(Qt::Dense7Pattern);
975 case 3: return QBrush(Qt::red, Qt::NoBrush);
976 case 4: return QBrush(Qt::green, Qt::SolidPattern);
977 case 5: return QBrush(Qt::blue, Qt::Dense7Pattern);
978 case 6:
979 {
980 QPixmap pm(open_xpm);
981 QBrush custom(Qt::black, pm);
982 return custom;
983 }
984 case 7:
985 QLinearGradient gradient(QPointF(2.718, 3.142), QPointF(3.1337, 42));
986 gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
987 gradient.setSpread(QGradient::ReflectSpread);
988 gradient.setInterpolationMode(QGradient::ComponentInterpolation);
989 gradient.setColorAt(pos: 0.2, color: Qt::red);
990 gradient.setColorAt(pos: 0.6, color: Qt::transparent);
991 gradient.setColorAt(pos: 0.8, color: Qt::blue);
992 return QBrush(gradient);
993 }
994
995 return QBrush(Qt::NoBrush);
996}
997
998void tst_QDataStream::stream_QBrush_data()
999{
1000 stream_data(noOfElements: 8);
1001}
1002
1003void tst_QDataStream::stream_QBrush()
1004{
1005 if (QString(QTest::currentDataTag()).endsWith(s: "6"))
1006 QSKIP("Custom brushes don't seem to be supported with QDataStream");
1007
1008 STREAM_IMPL(QBrush);
1009}
1010
1011void tst_QDataStream::writeQBrush(QDataStream *s)
1012{
1013 QBrush brush = qBrushData(index: dataIndex(tag: QTest::currentDataTag()));
1014 *s << brush;
1015}
1016
1017void tst_QDataStream::readQBrush(QDataStream *s)
1018{
1019 QBrush d2;
1020 *s >> d2;
1021
1022 QBrush brush = qBrushData(index: dataIndex(tag: QTest::currentDataTag()));
1023 QCOMPARE(d2, brush);
1024}
1025
1026// ************************************
1027
1028static QColor QColorData(int index)
1029{
1030 switch (index) {
1031 case 0: return QColor(0,0,0);
1032 case 1: return QColor(0,0,0);
1033 case 2: return QColor(0,0,0);
1034 case 3: return QColor(0,0,0);
1035 case 4: return QColor(0,0,0);
1036 case 5: return QColor(0,0,0);
1037 case 6: return QColor(0,0,0);
1038 case 7: return QColor(0,0,0);
1039 }
1040
1041 return QColor(0,0,0);
1042}
1043
1044void tst_QDataStream::stream_QColor_data()
1045{
1046 stream_data(noOfElements: 8);
1047}
1048
1049void tst_QDataStream::stream_QColor()
1050{
1051 STREAM_IMPL(QColor);
1052}
1053
1054void tst_QDataStream::writeQColor(QDataStream *s)
1055{
1056 QColor d3(QColorData(index: dataIndex(tag: QTest::currentDataTag())));
1057 *s << d3;
1058}
1059
1060void tst_QDataStream::readQColor(QDataStream *s)
1061{
1062 QColor test(QColorData(index: dataIndex(tag: QTest::currentDataTag())));
1063 QColor d3;
1064 *s >> d3;
1065 QCOMPARE(d3, test);
1066}
1067
1068
1069// ************************************
1070
1071static QByteArray qByteArrayData(int index)
1072{
1073 switch (index) {
1074 case 0: return QByteArray();
1075 case 1: return QByteArray("");
1076 case 2: return QByteArray("foo");
1077 case 3: return QByteArray("foo bar");
1078 case 4: return QByteArray("two\nlines");
1079 case 5: return QByteArray("ABCDEFG");
1080 case 6: return QByteArray("baec zxv 123"); // kept for nostalgic reasons
1081 case 7: return QByteArray("jbc;UBC;jd clhdbcahd vcbd vgdv dhvb laifv kadf jkhfbvljd khd lhvjh ");
1082 }
1083
1084 return QByteArray("foo");
1085}
1086
1087void tst_QDataStream::stream_QByteArray_data()
1088{
1089 stream_data(noOfElements: 8);
1090}
1091
1092void tst_QDataStream::stream_QByteArray()
1093{
1094 STREAM_IMPL(QByteArray);
1095}
1096
1097void tst_QDataStream::writeQByteArray(QDataStream *s)
1098{
1099 QByteArray d4(qByteArrayData(index: dataIndex(tag: QTest::currentDataTag())));
1100 *s << d4;
1101}
1102
1103void tst_QDataStream::writenullptr_t(QDataStream *s)
1104{
1105 *s << nullptr;
1106}
1107
1108void tst_QDataStream::readQByteArray(QDataStream *s)
1109{
1110 QByteArray test(qByteArrayData(index: dataIndex(tag: QTest::currentDataTag())));
1111 QByteArray d4;
1112 *s >> d4;
1113 QCOMPARE(d4, test);
1114}
1115
1116void tst_QDataStream::readnullptr_t(QDataStream *s)
1117{
1118 std::nullptr_t ptr;
1119 *s >> ptr;
1120 QCOMPARE(ptr, nullptr);
1121}
1122
1123// ************************************
1124#ifndef QT_NO_CURSOR
1125static QCursor qCursorData(int index)
1126{
1127 switch (index) {
1128 case 0: return QCursor(Qt::ArrowCursor);
1129 case 1: return QCursor(Qt::WaitCursor);
1130 case 2: return QCursor(Qt::BitmapCursor);
1131 case 3: return QCursor(Qt::BlankCursor);
1132 case 4: return QCursor(Qt::BlankCursor);
1133 case 5: return QCursor(QPixmap(open_xpm), 1, 1);
1134 case 6: { QPixmap pm(open_xpm); return QCursor(QBitmap(pm), pm.mask(), 3, 4); }
1135 case 7: return QCursor(QPixmap(open_xpm), -1, 5);
1136 case 8: return QCursor(QPixmap(open_xpm), 5, -1);
1137 }
1138
1139 return QCursor();
1140}
1141#endif
1142
1143#ifndef QT_NO_CURSOR
1144void tst_QDataStream::stream_QCursor_data()
1145{
1146 stream_data(noOfElements: 9);
1147}
1148#endif
1149
1150#ifndef QT_NO_CURSOR
1151void tst_QDataStream::stream_QCursor()
1152{
1153 STREAM_IMPL(QCursor);
1154}
1155#endif
1156
1157#ifndef QT_NO_CURSOR
1158void tst_QDataStream::writeQCursor(QDataStream *s)
1159{
1160 QCursor d5(qCursorData(index: dataIndex(tag: QTest::currentDataTag())));
1161 *s << d5;
1162}
1163#endif
1164
1165#ifndef QT_NO_CURSOR
1166void tst_QDataStream::readQCursor(QDataStream *s)
1167{
1168 QCursor test(qCursorData(index: dataIndex(tag: QTest::currentDataTag())));
1169 QCursor d5;
1170 *s >> d5;
1171
1172 QVERIFY(d5.shape() == test.shape()); //## lacks operator==
1173 QCOMPARE(d5.hotSpot(), test.hotSpot());
1174
1175 // Comparing non-null QBitmaps will fail. Upcast them first to pass.
1176 QCOMPARE(d5.bitmap(Qt::ReturnByValue).isNull(), test.bitmap(Qt::ReturnByValue).isNull());
1177 QCOMPARE(
1178 static_cast<QPixmap>(d5.bitmap(Qt::ReturnByValue)),
1179 static_cast<QPixmap>(test.bitmap(Qt::ReturnByValue))
1180 );
1181 QCOMPARE(d5.mask(Qt::ReturnByValue).isNull(), test.mask(Qt::ReturnByValue).isNull());
1182 QCOMPARE(
1183 static_cast<QPixmap>(d5.mask(Qt::ReturnByValue)),
1184 static_cast<QPixmap>(test.mask(Qt::ReturnByValue))
1185 );
1186}
1187#endif
1188
1189// ************************************
1190
1191static QDate qDateData(int index)
1192{
1193 switch (index) {
1194 case 0: return QDate(1752, 9, 14); // the first valid date
1195 case 1: return QDate(1900, 1, 1);
1196 case 2: return QDate(1976, 4, 5);
1197 case 3: return QDate(1960, 5, 27);
1198 case 4: return QDate(1999, 12, 31); // w2k effects?
1199 case 5: return QDate(2000, 1, 1);
1200 case 6: return QDate(2050, 1, 1);// test some values far in the future too
1201 case 7: return QDate(3001, 12, 31);
1202 case 8: return QDate(4002, 1, 1);
1203 case 9: return QDate(4003, 12, 31);
1204 case 10: return QDate(5004, 1, 1);
1205 case 11: return QDate(5005, 12, 31);
1206 case 12: return QDate(6006, 1, 1);
1207 case 13: return QDate(6007, 12, 31);
1208 case 14: return QDate(7008, 1, 1);
1209 case 15: return QDate(7009, 12, 31);
1210 }
1211 return QDate();
1212}
1213#define MAX_QDATE_DATA 16
1214
1215void tst_QDataStream::stream_QDate_data()
1216{
1217 stream_data(MAX_QDATE_DATA);
1218}
1219
1220void tst_QDataStream::stream_QDate()
1221{
1222 STREAM_IMPL(QDate);
1223}
1224
1225void tst_QDataStream::writeQDate(QDataStream *s)
1226{
1227 QDate d6(qDateData(index: dataIndex(tag: QTest::currentDataTag())));
1228 *s << d6;
1229}
1230
1231void tst_QDataStream::readQDate(QDataStream *s)
1232{
1233 QDate test(qDateData(index: dataIndex(tag: QTest::currentDataTag())));
1234 QDate d6;
1235 *s >> d6;
1236 QCOMPARE(d6, test);
1237}
1238
1239// ************************************
1240
1241static QTime qTimeData(int index)
1242{
1243 switch (index) {
1244 case 0 : return QTime(0, 0, 0, 0);
1245 case 1 : return QTime(0, 0, 0, 1);
1246 case 2 : return QTime(0, 0, 0, 99);
1247 case 3 : return QTime(0, 0, 0, 100);
1248 case 4 : return QTime(0, 0, 0, 999);
1249 case 5 : return QTime(0, 0, 1, 0);
1250 case 6 : return QTime(0, 0, 1, 1);
1251 case 7 : return QTime(0, 0, 1, 99);
1252 case 8 : return QTime(0, 0, 1, 100);
1253 case 9 : return QTime(0, 0, 1, 999);
1254 case 10: return QTime(0, 0, 59, 0);
1255 case 11: return QTime(0, 0, 59, 1);
1256 case 12: return QTime(0, 0, 59, 99);
1257 case 13: return QTime(0, 0, 59, 100);
1258 case 14: return QTime(0, 0, 59, 999);
1259 case 15: return QTime(0, 59, 0, 0);
1260 case 16: return QTime(0, 59, 0, 1);
1261 case 17: return QTime(0, 59, 0, 99);
1262 case 18: return QTime(0, 59, 0, 100);
1263 case 19: return QTime(0, 59, 0, 999);
1264 case 20: return QTime(0, 59, 1, 0);
1265 case 21: return QTime(0, 59, 1, 1);
1266 case 22: return QTime(0, 59, 1, 99);
1267 case 23: return QTime(0, 59, 1, 100);
1268 case 24: return QTime(0, 59, 1, 999);
1269 case 25: return QTime(0, 59, 59, 0);
1270 case 26: return QTime(0, 59, 59, 1);
1271 case 27: return QTime(0, 59, 59, 99);
1272 case 28: return QTime(0, 59, 59, 100);
1273 case 29: return QTime(0, 59, 59, 999);
1274 case 30: return QTime(23, 0, 0, 0);
1275 case 31: return QTime(23, 0, 0, 1);
1276 case 32: return QTime(23, 0, 0, 99);
1277 case 33: return QTime(23, 0, 0, 100);
1278 case 34: return QTime(23, 0, 0, 999);
1279 case 35: return QTime(23, 0, 1, 0);
1280 case 36: return QTime(23, 0, 1, 1);
1281 case 37: return QTime(23, 0, 1, 99);
1282 case 38: return QTime(23, 0, 1, 100);
1283 case 39: return QTime(23, 0, 1, 999);
1284 case 40: return QTime(23, 0, 59, 0);
1285 case 41: return QTime(23, 0, 59, 1);
1286 case 42: return QTime(23, 0, 59, 99);
1287 case 43: return QTime(23, 0, 59, 100);
1288 case 44: return QTime(23, 0, 59, 999);
1289 case 45: return QTime(23, 59, 0, 0);
1290 case 46: return QTime(23, 59, 0, 1);
1291 case 47: return QTime(23, 59, 0, 99);
1292 case 48: return QTime(23, 59, 0, 100);
1293 case 49: return QTime(23, 59, 0, 999);
1294 case 50: return QTime(23, 59, 1, 0);
1295 case 51: return QTime(23, 59, 1, 1);
1296 case 52: return QTime(23, 59, 1, 99);
1297 case 53: return QTime(23, 59, 1, 100);
1298 case 54: return QTime(23, 59, 1, 999);
1299 case 55: return QTime(23, 59, 59, 0);
1300 case 56: return QTime(23, 59, 59, 1);
1301 case 57: return QTime(23, 59, 59, 99);
1302 case 58: return QTime(23, 59, 59, 100);
1303 case 59: return QTime(23, 59, 59, 999);
1304 case 60: return QTime();
1305 }
1306 return QTime(0, 0, 0);
1307}
1308#define MAX_QTIME_DATA 61
1309
1310void tst_QDataStream::stream_QTime_data()
1311{
1312 stream_data(MAX_QTIME_DATA);
1313}
1314
1315void tst_QDataStream::stream_QTime()
1316{
1317 STREAM_IMPL(QTime);
1318}
1319
1320void tst_QDataStream::writeQTime(QDataStream *s)
1321{
1322 QTime d7 = qTimeData(index: dataIndex(tag: QTest::currentDataTag()));
1323 *s << d7;
1324}
1325
1326void tst_QDataStream::readQTime(QDataStream *s)
1327{
1328 QTime test = qTimeData(index: dataIndex(tag: QTest::currentDataTag()));
1329 QTime d7;
1330 *s >> d7;
1331 QCOMPARE(d7, test);
1332}
1333
1334// ************************************
1335
1336static QDateTime qDateTimeData(int index)
1337{
1338 switch (index) {
1339 case 0: return QDateTime(QDate(1900, 1, 1), QTime(0,0,0,0));
1340 case 1: return QDateTime(QDate(1900, 1, 2), QTime(1,1,1,1));
1341 case 2: return QDateTime(QDate(1900, 1, 3), QTime(12,0,0,0));
1342 case 3: return QDateTime(QDate(1900, 1, 4), QTime(23,59,59,999));
1343 case 4: return QDateTime(QDate(1999, 1, 1), QTime(0,0,0,0));
1344 case 5: return QDateTime(QDate(1999, 1, 2), QTime(1,1,1,1));
1345 case 6: return QDateTime(QDate(1999, 1, 3), QTime(12,0,0,0));
1346 case 7: return QDateTime(QDate(1999, 1, 4), QTime(23,59,59,999));
1347 case 8: return QDateTime(QDate(2000, 1, 1), QTime(0,0,0,0));
1348 case 9: return QDateTime(QDate(2000, 1, 2), QTime(1,1,1,1));
1349 case 10: return QDateTime(QDate(2000, 1, 3), QTime(12,0,0,0));
1350 case 11: return QDateTime(QDate(2000, 1, 4), QTime(23,59,59,999));
1351 case 12: return QDateTime(QDate(2000, 12, 31), QTime(0,0,0,0));
1352 case 13: return QDateTime(QDate(2000, 12, 31), QTime(1,1,1,1));
1353 case 14: return QDateTime(QDate(2000, 12, 31), QTime(12,0,0,0));
1354 case 15: return QDateTime(QDate(2000, 12, 31), QTime(23,59,59,999));
1355 }
1356 return QDateTime(QDate(1900, 1, 1), QTime(0,0,0));
1357}
1358#define MAX_QDATETIME_DATA 16
1359
1360void tst_QDataStream::stream_QDateTime_data()
1361{
1362 stream_data(MAX_QDATETIME_DATA);
1363}
1364
1365void tst_QDataStream::stream_QDateTime()
1366{
1367 STREAM_IMPL(QDateTime);
1368}
1369
1370void tst_QDataStream::stream_nullptr_t_data()
1371{
1372 stream_data(noOfElements: 1); // there's only one value possible
1373}
1374
1375void tst_QDataStream::stream_nullptr_t()
1376{
1377 using namespace std;
1378 STREAM_IMPL(nullptr_t);
1379}
1380
1381void tst_QDataStream::writeQDateTime(QDataStream *s)
1382{
1383 QDateTime dt(qDateTimeData(index: dataIndex(tag: QTest::currentDataTag())));
1384 *s << dt;
1385}
1386
1387void tst_QDataStream::readQDateTime(QDataStream *s)
1388{
1389 QDateTime test(qDateTimeData(index: dataIndex(tag: QTest::currentDataTag())));
1390 QDateTime d8;
1391 *s >> d8;
1392 QCOMPARE(d8, test);
1393}
1394
1395// ************************************
1396
1397static QFont qFontData(int index)
1398{
1399 switch (index) {
1400 case 0: return QFont("Courier", 20, QFont::Bold, true);
1401 case 1: return QFont("Courier", 18, QFont::Bold, false);
1402 case 2: return QFont("Courier", 16, QFont::Light, true);
1403 case 3: return QFont("Courier", 14, QFont::Normal, false);
1404 case 4: return QFont("Courier", 12, QFont::DemiBold, true);
1405 case 5: return QFont("Courier", 10, QFont::Black, false);
1406 case 6:
1407 {
1408 QFont f("Helvetica", 10, QFont::Normal, false);
1409 f.setPixelSize(2);
1410 f.setUnderline(false);
1411 f.setStrikeOut(false);
1412 f.setFixedPitch(false);
1413 return f;
1414 }
1415 case 7:
1416 {
1417 QFont f("Helvetica", 10, QFont::Bold, false);
1418 f.setPixelSize(4);
1419 f.setUnderline(true);
1420 f.setStrikeOut(false);
1421 f.setFixedPitch(false);
1422 return f;
1423 }
1424 case 8:
1425 {
1426 QFont f("Helvetica", 10, QFont::Light, false);
1427 f.setPixelSize(6);
1428 f.setUnderline(false);
1429 f.setStrikeOut(true);
1430 f.setFixedPitch(false);
1431 return f;
1432 }
1433 case 9:
1434 {
1435 QFont f("Helvetica", 10, QFont::DemiBold, false);
1436 f.setPixelSize(8);
1437 f.setUnderline(false);
1438 f.setStrikeOut(false);
1439 f.setFixedPitch(true);
1440 return f;
1441 }
1442 case 10:
1443 {
1444 QFont f("Helvetica", 10, QFont::Black, false);
1445 f.setPixelSize(10);
1446 f.setUnderline(true);
1447 f.setStrikeOut(true);
1448 f.setFixedPitch(false);
1449 return f;
1450 }
1451 case 11:
1452 {
1453 QFont f("Helvetica", 10, QFont::Normal, true);
1454 f.setPixelSize(12);
1455 f.setUnderline(false);
1456 f.setStrikeOut(true);
1457 f.setFixedPitch(true);
1458 return f;
1459 }
1460 case 12:
1461 {
1462 QFont f("Helvetica", 10, QFont::Bold, true);
1463 f.setPixelSize(14);
1464 f.setUnderline(true);
1465 f.setStrikeOut(true);
1466 f.setFixedPitch(true);
1467 return f;
1468 }
1469 case 13:
1470 {
1471 QFont f("Helvetica", 10, QFont::Bold, true);
1472 f.setStretch(200);
1473 return f;
1474 }
1475 }
1476 return QFont("Courier", 18, QFont::Bold, true);
1477}
1478#define MAX_QFONT_DATA 14
1479
1480void tst_QDataStream::stream_QFont_data()
1481{
1482 stream_data(MAX_QFONT_DATA);
1483}
1484
1485void tst_QDataStream::stream_QFont()
1486{
1487 STREAM_IMPL(QFont);
1488}
1489
1490void tst_QDataStream::writeQFont(QDataStream *s)
1491{
1492 QFont d9(qFontData(index: dataIndex(tag: QTest::currentDataTag())));
1493 *s << d9;
1494}
1495
1496void tst_QDataStream::readQFont(QDataStream *s)
1497{
1498 QFont test(qFontData(index: dataIndex(tag: QTest::currentDataTag())));
1499 QFont d9;
1500 *s >> d9;
1501
1502 // maybe a bit overkill ...
1503 QCOMPARE(d9.family(), test.family());
1504 QCOMPARE(d9.pointSize(), test.pointSize());
1505 QCOMPARE(d9.pixelSize(), test.pixelSize());
1506 QCOMPARE(d9.weight(), test.weight());
1507 QCOMPARE(d9.bold(), test.bold());
1508 QCOMPARE(d9.italic(), test.italic());
1509 QCOMPARE(d9.underline(), test.underline());
1510 QCOMPARE(d9.overline(), test.overline());
1511 QCOMPARE(d9.strikeOut(), test.strikeOut());
1512 QCOMPARE(d9.fixedPitch(), test.fixedPitch());
1513 QCOMPARE(d9.styleHint(), test.styleHint());
1514 QCOMPARE(d9.toString(), test.toString());
1515
1516 QCOMPARE(d9, test);
1517}
1518
1519// ************************************
1520
1521void tst_QDataStream::stream_QImage_data()
1522{
1523 stream_data(noOfElements: 1);
1524}
1525
1526void tst_QDataStream::stream_QImage()
1527{
1528 STREAM_IMPL(QImage);
1529}
1530
1531void tst_QDataStream::writeQImage(QDataStream *s)
1532{
1533 QImage d12(open_xpm);
1534 *s << d12;
1535}
1536
1537void tst_QDataStream::readQImage(QDataStream *s)
1538{
1539 QImage ref(open_xpm);
1540
1541 QImage d12;
1542 *s >> d12;
1543 QCOMPARE(d12, ref);
1544
1545 // do some extra neurotic tests
1546 QCOMPARE(d12.size(), ref.size());
1547 QCOMPARE(d12.isNull(), ref.isNull());
1548 QCOMPARE(d12.width(), ref.width());
1549 QCOMPARE(d12.height(), ref.height());
1550 QCOMPARE(d12.depth(), ref.depth());
1551 QCOMPARE(d12.colorCount(), ref.colorCount());
1552 QCOMPARE(d12.hasAlphaChannel(), ref.hasAlphaChannel());
1553}
1554
1555// ************************************
1556
1557static QPen qPenData(int index)
1558{
1559 switch (index) {
1560 case 0:
1561 {
1562 QPen p(Qt::blue, 0, Qt::NoPen);
1563 p.setCapStyle(Qt::FlatCap);
1564 p.setJoinStyle(Qt::MiterJoin);
1565 return p;
1566 }
1567 case 1:
1568 {
1569 QPen p(Qt::red, 1, Qt::SolidLine);
1570 p.setCapStyle(Qt::SquareCap);
1571 p.setJoinStyle(Qt::BevelJoin);
1572 return p;
1573 }
1574 case 2:
1575 {
1576 QPen p(Qt::red, 4, Qt::DashDotDotLine);
1577 p.setCapStyle(Qt::RoundCap);
1578 p.setJoinStyle(Qt::RoundJoin);
1579 return p;
1580 }
1581 case 3:
1582 {
1583 QPen p(Qt::blue, 12, Qt::NoPen);
1584 p.setCapStyle(Qt::FlatCap);
1585 p.setJoinStyle(Qt::RoundJoin);
1586 return p;
1587 }
1588 case 4:
1589 {
1590 QPen p(Qt::red, 99, Qt::SolidLine);
1591 p.setCapStyle(Qt::SquareCap);
1592 p.setJoinStyle(Qt::MiterJoin);
1593 return p;
1594 }
1595 case 5:
1596 {
1597 QPen p(Qt::red, 255, Qt::DashDotLine);
1598 p.setCapStyle(Qt::RoundCap);
1599 p.setJoinStyle(Qt::BevelJoin);
1600 return p;
1601 }
1602 case 6:
1603 {
1604 QPen p(Qt::red, 256, Qt::DashDotLine);
1605 p.setCapStyle(Qt::RoundCap);
1606 p.setJoinStyle(Qt::BevelJoin);
1607 return p;
1608 }
1609 case 7:
1610 {
1611 QPen p(Qt::red, 0.25, Qt::DashDotLine);
1612 p.setCapStyle(Qt::RoundCap);
1613 p.setJoinStyle(Qt::BevelJoin);
1614 return p;
1615 }
1616 }
1617
1618 return QPen();
1619}
1620#define MAX_QPEN_DATA 8
1621
1622void tst_QDataStream::stream_QPen_data()
1623{
1624 stream_data(MAX_QPEN_DATA);
1625}
1626
1627void tst_QDataStream::stream_QPen()
1628{
1629 STREAM_IMPL(QPen);
1630}
1631
1632void tst_QDataStream::writeQPen(QDataStream *s)
1633{
1634 QPen d15(qPenData(index: dataIndex(tag: QTest::currentDataTag())));
1635 *s << d15;
1636}
1637
1638void tst_QDataStream::readQPen(QDataStream *s)
1639{
1640 QPen origPen(qPenData(index: dataIndex(tag: QTest::currentDataTag())));
1641 QPen d15;
1642 *s >> d15;
1643 QCOMPARE(d15.style(), origPen.style());
1644 QCOMPARE(d15.width(), origPen.width());
1645 QCOMPARE(d15.color(), origPen.color());
1646 QCOMPARE(d15.capStyle(), origPen.capStyle());
1647 QCOMPARE(d15.joinStyle(), origPen.joinStyle());
1648 QCOMPARE(d15, origPen);
1649}
1650
1651// ************************************
1652
1653// pixmap testing is currently limited to one pixmap only.
1654//
1655void tst_QDataStream::stream_QPixmap_data()
1656{
1657 stream_data(noOfElements: 1);
1658}
1659
1660void tst_QDataStream::stream_QPixmap()
1661{
1662 STREAM_IMPL(QPixmap);
1663}
1664
1665void tst_QDataStream::stream_QIcon_data()
1666{
1667 stream_data(noOfElements: 1);
1668}
1669
1670void tst_QDataStream::stream_QIcon()
1671{
1672 STREAM_IMPL(QIcon);
1673}
1674
1675void tst_QDataStream::writeQPixmap(QDataStream *s)
1676{
1677 QPixmap d16(open_xpm);
1678 *s << d16;
1679}
1680
1681void tst_QDataStream::readQPixmap(QDataStream *s)
1682{
1683 QPixmap pm(open_xpm);
1684 QPixmap d16;
1685 *s >> d16;
1686 QVERIFY(!d16.isNull() && !pm.isNull());
1687 QCOMPARE(d16.width(), pm.width());
1688 QCOMPARE(d16.height(), pm.height());
1689 QCOMPARE(d16.size(), pm.size());
1690 QCOMPARE(d16.rect(), pm.rect());
1691 QCOMPARE(d16.depth(), pm.depth());
1692}
1693
1694void tst_QDataStream::writeQIcon(QDataStream *s)
1695{
1696 QPixmap pm(open_xpm);
1697 QIcon d16(pm);
1698 *s << d16;
1699}
1700
1701void tst_QDataStream::readQIcon(QDataStream *s)
1702{
1703 QPixmap pm(open_xpm);
1704 QIcon icon(pm);
1705 QIcon d16;
1706 *s >> d16;
1707 QVERIFY(!d16.isNull() && !icon.isNull());
1708 QCOMPARE(d16.pixmap(100), pm);
1709}
1710
1711// ************************************
1712
1713QPoint qPointData(int index)
1714{
1715 switch (index) {
1716 case 0: return QPoint(0, 0);
1717 case 1: return QPoint(-1, 0);
1718 case 2: return QPoint(0, -1);
1719 case 3: return QPoint(1, 0);
1720 case 4: return QPoint(0, 1);
1721 case 5: return QPoint(-1, -1);
1722 case 6: return QPoint(1, 1);
1723 case 7: return QPoint(255, 255);
1724 case 8: return QPoint(256, 256);
1725 case 9: return QPoint(-254, -254);
1726 case 10: return QPoint(-255, -255);
1727 }
1728
1729 return QPoint();
1730}
1731#define MAX_QPOINT_DATA 11
1732
1733
1734void tst_QDataStream::stream_QPoint_data()
1735{
1736 stream_data(MAX_QPOINT_DATA);
1737}
1738
1739void tst_QDataStream::stream_QPoint()
1740{
1741 STREAM_IMPL(QPoint);
1742}
1743
1744void tst_QDataStream::writeQPoint(QDataStream *s)
1745{
1746 QPoint d17(qPointData(index: dataIndex(tag: QTest::currentDataTag())));
1747 *s << d17;
1748
1749 QPointF d17f = d17;
1750 *s << d17f;
1751}
1752
1753void tst_QDataStream::readQPoint(QDataStream *s)
1754{
1755 QPoint ref(qPointData(index: dataIndex(tag: QTest::currentDataTag())));
1756 QPoint d17;
1757 *s >> d17;
1758 QCOMPARE(d17, ref);
1759
1760 QPointF d17f;
1761 *s >> d17f;
1762 QCOMPARE(d17f, QPointF(ref));
1763}
1764
1765// ************************************
1766
1767static QRect qRectData(int index)
1768{
1769 switch (index) {
1770 case 0: return QRect(0, 0, 0, 0);
1771 case 1: return QRect(1, 1, 1, 1);
1772 case 2: return QRect(1, 2, 3, 4);
1773 case 3: return QRect(-1, -1, -1, -1);
1774 case 4: return QRect(-1, -2, -3, -4);
1775 case 5: return QRect(255, -5, 256, -6);
1776 case 6: return QRect(-7, 255, -8, 256);
1777 case 7: return QRect(9, -255, 10, -255);
1778 case 8: return QRect(-255, 11, -255, 12);
1779 case 9: return QRect(256, 512, 1024, 2048);
1780 case 10: return QRect(-256, -512, -1024, -2048);
1781 }
1782 return QRect();
1783}
1784#define MAX_QRECT_DATA 11
1785
1786void tst_QDataStream::stream_QRect_data()
1787{
1788 stream_data(MAX_QRECT_DATA);
1789}
1790
1791void tst_QDataStream::stream_QRect()
1792{
1793 STREAM_IMPL(QRect);
1794}
1795
1796void tst_QDataStream::writeQRect(QDataStream *s)
1797{
1798 QRect d18(qRectData(index: dataIndex(tag: QTest::currentDataTag())));
1799 *s << d18;
1800
1801 QRectF d18f(d18);
1802 *s << d18f;
1803}
1804
1805void tst_QDataStream::readQRect(QDataStream *s)
1806{
1807 QRect ref(qRectData(index: dataIndex(tag: QTest::currentDataTag())));
1808 QRect d18;
1809 *s >> d18;
1810 QCOMPARE(d18, ref);
1811
1812 QRectF d18f;
1813 *s >> d18f;
1814 QCOMPARE(d18f, QRectF(ref));
1815}
1816
1817// ************************************
1818
1819static QPolygon qPolygonData(int index)
1820{
1821 QPoint p0(0, 0);
1822 QPoint p1(1, 1);
1823 QPoint p2(-1, -1);
1824 QPoint p3(1, -1);
1825 QPoint p4(-1, 1);
1826 QPoint p5(0, 255);
1827 QPoint p6(0, 256);
1828 QPoint p7(0, 1024);
1829 QPoint p8(255, 0);
1830 QPoint p9(256, 0);
1831 QPoint p10(1024, 0);
1832 QPoint p11(345, 678);
1833 QPoint p12(23456, 99999);
1834 QPoint p13(-99998, -34567);
1835 QPoint p14(45678, -99999);
1836
1837 switch (index) {
1838 case 0:
1839 return QPolygon(0);
1840 case 1:
1841 {
1842 QPolygon p(1);
1843 p.setPoint(index: 0, pt: p0);
1844 return p;
1845 }
1846 case 2:
1847 {
1848 QPolygon p(1);
1849 p.setPoint(index: 0, pt: p5);
1850 return p;
1851 }
1852 case 3:
1853 {
1854 QPolygon p(1);
1855 p.setPoint(index: 0, pt: p12);
1856 return p;
1857 }
1858 case 4:
1859 {
1860 QPolygon p(3);
1861 p.setPoint(index: 0, pt: p1);
1862 p.setPoint(index: 1, pt: p10);
1863 p.setPoint(index: 2, pt: p13);
1864 return p;
1865 }
1866 case 5:
1867 {
1868 QPolygon p(6);
1869 p.setPoint(index: 0, pt: p2);
1870 p.setPoint(index: 1, pt: p11);
1871 p.setPoint(index: 2, pt: p14);
1872 return p;
1873 }
1874 case 6:
1875 {
1876 QPolygon p(15);
1877 p.setPoint(index: 0, pt: p0);
1878 p.setPoint(index: 1, pt: p1);
1879 p.setPoint(index: 2, pt: p2);
1880 p.setPoint(index: 3, pt: p3);
1881 p.setPoint(index: 4, pt: p4);
1882 p.setPoint(index: 5, pt: p5);
1883 p.setPoint(index: 6, pt: p6);
1884 p.setPoint(index: 7, pt: p7);
1885 p.setPoint(index: 8, pt: p8);
1886 p.setPoint(index: 9, pt: p9);
1887 p.setPoint(index: 10, pt: p10);
1888 p.setPoint(index: 11, pt: p11);
1889 p.setPoint(index: 12, pt: p12);
1890 p.setPoint(index: 13, pt: p13);
1891 p.setPoint(index: 14, pt: p14);
1892 return p;
1893 }
1894 }
1895 return QRect();
1896}
1897#define MAX_QPOINTARRAY_DATA 7
1898
1899void tst_QDataStream::stream_QPolygon_data()
1900{
1901 stream_data(noOfElements: 1);
1902}
1903
1904void tst_QDataStream::stream_QPolygon()
1905{
1906 STREAM_IMPL(QPolygon);
1907}
1908
1909void tst_QDataStream::writeQPolygon(QDataStream *s)
1910{
1911 QPolygon d19(qPolygonData(index: dataIndex(tag: QTest::currentDataTag())));
1912 *s << d19;
1913
1914 QPolygonF d19f(d19);
1915 *s << d19f;
1916}
1917
1918void tst_QDataStream::readQPolygon(QDataStream *s)
1919{
1920 QPolygon ref(qPolygonData(index: dataIndex(tag: QTest::currentDataTag())));
1921 QPolygon d19;
1922 *s >> d19;
1923 QCOMPARE(d19, ref);
1924
1925 QPolygonF d19f;
1926 *s >> d19f;
1927 QCOMPARE(d19f, QPolygonF(ref));
1928}
1929
1930// ************************************
1931
1932static QRegion qRegionData(int index)
1933{
1934 switch (index) {
1935 case 0: return QRegion(0, 0, 0, 0, QRegion::Rectangle);
1936 case 1:
1937 {
1938 QRegion r(1, 2, 300, 400, QRegion::Rectangle);
1939 if (r != QRegion(1, 2, 300, 400, QRegion::Rectangle))
1940 qDebug(msg: "Error creating a region");
1941 return r;
1942 }
1943 case 2: return QRegion(100, 100, 1024, 768, QRegion::Rectangle);
1944 case 3: return QRegion(-100, -100, 1024, 1024, QRegion::Rectangle);
1945 case 4: return QRegion(100, -100, 2048, 4096, QRegion::Rectangle);
1946 case 5: return QRegion(-100, 100, 4096, 2048, QRegion::Rectangle);
1947 case 6: return QRegion(0, 0, 0, 0, QRegion::Ellipse);
1948#if !defined(Q_OS_UNIX) // all our Unix platforms use X regions.
1949 case 7: return QRegion(1, 2, 300, 400, QRegion::Ellipse);
1950 case 8: return QRegion(100, 100, 1024, 768, QRegion::Ellipse);
1951 case 9: return QRegion(-100, -100, 1024, 1024, QRegion::Ellipse);
1952 case 10: return QRegion(100, -100, 2048, 4096, QRegion::Ellipse);
1953 case 11: return QRegion(-100, 100, 4096, 2048, QRegion::Ellipse);
1954 // simplest X11 case that fails:
1955 case 12: return QRegion(0, 0, 3, 3, QRegion::Ellipse);
1956#else
1957 case 7:
1958 qWarning(msg: "Skipping streaming of elliptical regions on embedded, OS X, and X11;"
1959 " our pointarray stuff is not that great at approximating.");
1960#endif
1961 }
1962 return QRegion();
1963}
1964#define MAX_QREGION_DATA 12
1965
1966void tst_QDataStream::stream_QRegion_data()
1967{
1968 stream_data(MAX_QREGION_DATA);
1969}
1970
1971void tst_QDataStream::stream_QRegion()
1972{
1973 STREAM_IMPL(QRegion);
1974}
1975
1976void tst_QDataStream::writeQRegion(QDataStream *s)
1977{
1978 QRegion r(qRegionData(index: dataIndex(tag: QTest::currentDataTag())));
1979 *s << r;
1980}
1981
1982void tst_QDataStream::readQRegion(QDataStream *s)
1983{
1984 QRegion ref(qRegionData(index: dataIndex(tag: QTest::currentDataTag())));
1985 QRegion r;
1986 *s >> r;
1987 QCOMPARE(r, ref);
1988}
1989
1990// ************************************
1991
1992static QSize qSizeData(int index)
1993{
1994 switch (index) {
1995 case 0: return QSize(0, 0);
1996 case 1: return QSize(-1, 0);
1997 case 2: return QSize(0, -1);
1998 case 3: return QSize(1, 0);
1999 case 4: return QSize(0, 1);
2000 case 5: return QSize(-1, -1);
2001 case 6: return QSize(1, 1);
2002 case 7: return QSize(255, 255);
2003 case 8: return QSize(256, 256);
2004 case 9: return QSize(-254, -254);
2005 case 10: return QSize(-255, -255);
2006 }
2007 return QSize();
2008}
2009#define MAX_QSIZE_DATA 11
2010
2011void tst_QDataStream::stream_QSize_data()
2012{
2013 stream_data(MAX_QSIZE_DATA);
2014}
2015
2016void tst_QDataStream::stream_QSize()
2017{
2018 STREAM_IMPL(QSize);
2019}
2020
2021void tst_QDataStream::writeQSize(QDataStream *s)
2022{
2023 QSize d21(qSizeData(index: dataIndex(tag: QTest::currentDataTag())));
2024 *s << d21;
2025
2026 QSizeF d21f(d21);
2027 *s << d21f;
2028}
2029
2030void tst_QDataStream::readQSize(QDataStream *s)
2031{
2032 QSize ref(qSizeData(index: dataIndex(tag: QTest::currentDataTag())));
2033 QSize d21;
2034 *s >> d21;
2035 QCOMPARE(d21, ref);
2036
2037 QSizeF d21f;
2038 *s >> d21f;
2039 QCOMPARE(d21f, QSizeF(ref));
2040}
2041
2042// *********************** atEnd ******************************
2043
2044void tst_QDataStream::stream_atEnd_data()
2045{
2046 stream_data(MAX_QSTRING_DATA);
2047}
2048
2049void tst_QDataStream::stream_atEnd()
2050{
2051 QFETCH(QString, device);
2052 if (device == "bytearray") {
2053 QByteArray ba;
2054 QDataStream sout(&ba, QIODevice::WriteOnly);
2055 writeQString(s: &sout);
2056
2057 QDataStream sin(&ba, QIODevice::ReadOnly);
2058 readQString(s: &sin);
2059 QVERIFY(sin.atEnd());
2060 } else if (device == "file") {
2061 QString fileName = "qdatastream.out";
2062 QFile fOut(fileName);
2063 QVERIFY(fOut.open(QIODevice::WriteOnly));
2064 QDataStream sout(&fOut);
2065 writeQString(s: &sout);
2066 fOut.close();
2067
2068 QFile fIn(fileName);
2069 QVERIFY(fIn.open(QIODevice::ReadOnly));
2070 QDataStream sin(&fIn);
2071 readQString(s: &sin);
2072 QVERIFY(sin.atEnd());
2073 fIn.close();
2074 } else if (device == "buffer") {
2075 {
2076 QByteArray ba(0);
2077 QBuffer bOut(&ba);
2078 bOut.open(openMode: QIODevice::WriteOnly);
2079 QDataStream sout(&bOut);
2080 writeQString(s: &sout);
2081 bOut.close();
2082
2083 QBuffer bIn(&ba);
2084 bIn.open(openMode: QIODevice::ReadOnly);
2085 QDataStream sin(&bIn);
2086 readQString(s: &sin);
2087 QVERIFY(sin.atEnd());
2088 bIn.close();
2089 }
2090
2091 // Do the same test again, but this time with an initial size for the bytearray.
2092 {
2093 QByteArray ba(10000, '\0');
2094 QBuffer bOut(&ba);
2095 bOut.open(openMode: QIODevice::WriteOnly | QIODevice::Truncate);
2096 QDataStream sout(&bOut);
2097 writeQString(s: &sout);
2098 bOut.close();
2099
2100 QBuffer bIn(&ba);
2101 bIn.open(openMode: QIODevice::ReadOnly);
2102 QDataStream sin(&bIn);
2103 readQString(s: &sin);
2104 QVERIFY(sin.atEnd());
2105 bIn.close();
2106 }
2107 }
2108}
2109
2110class FakeBuffer : public QBuffer
2111{
2112protected:
2113 qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(data: c, len: i); }
2114public:
2115 FakeBuffer(bool locked = false) : m_lock(locked) {}
2116 void setLocked(bool locked) { m_lock = locked; }
2117private:
2118 bool m_lock;
2119};
2120
2121#define TEST_WRITE_ERROR(op) \
2122 { \
2123 FakeBuffer fb(false); \
2124 QVERIFY(fb.open(QBuffer::ReadWrite)); \
2125 QDataStream fs(&fb); \
2126 fs.writeRawData("hello", 5); \
2127 /* first write some initial content */ \
2128 QCOMPARE(fs.status(), QDataStream::Ok); \
2129 QCOMPARE(fb.data(), QByteArray("hello")); \
2130 /* then test that writing can cause an error */ \
2131 fb.setLocked(true); \
2132 fs op; \
2133 QCOMPARE(fs.status(), QDataStream::WriteFailed); \
2134 QCOMPARE(fb.data(), QByteArray("hello")); \
2135 /* finally test that writing after an error doesn't change the stream any more */ \
2136 fb.setLocked(false); \
2137 fs op; \
2138 QCOMPARE(fs.status(), QDataStream::WriteFailed); \
2139 QCOMPARE(fb.data(), QByteArray("hello")); \
2140 }
2141
2142void tst_QDataStream::stream_writeError()
2143{
2144 TEST_WRITE_ERROR(<< true)
2145 TEST_WRITE_ERROR(<< (qint8)1)
2146 TEST_WRITE_ERROR(<< (quint8)1)
2147 TEST_WRITE_ERROR(<< (qint16)1)
2148 TEST_WRITE_ERROR(<< (quint16)1)
2149 TEST_WRITE_ERROR(<< (qint32)1)
2150 TEST_WRITE_ERROR(<< (quint32)1)
2151 TEST_WRITE_ERROR(<< (qint64)1)
2152 TEST_WRITE_ERROR(<< (quint64)1)
2153 TEST_WRITE_ERROR(<< "hello")
2154 TEST_WRITE_ERROR(<< (float)1.0)
2155 TEST_WRITE_ERROR(<< (double)1.0)
2156 TEST_WRITE_ERROR(.writeRawData("test", 4))
2157}
2158
2159void tst_QDataStream::stream_QByteArray2()
2160{
2161 QByteArray ba;
2162 {
2163 QDataStream s(&ba, QIODevice::WriteOnly);
2164 s << QByteArray("hallo");
2165 s << QByteArray("");
2166 s << QByteArray();
2167 }
2168
2169 {
2170 QDataStream s(&ba, QIODevice::ReadOnly);
2171 QByteArray res;
2172 s >> res;
2173 QCOMPARE(res, QByteArray("hallo"));
2174 s >> res;
2175 QCOMPARE(res, QByteArray(""));
2176 QVERIFY(res.isEmpty());
2177 QVERIFY(!res.isNull());
2178 s >> res;
2179 QCOMPARE(res, QByteArray());
2180 QVERIFY(res.isEmpty());
2181 QVERIFY(res.isNull());
2182 }
2183}
2184
2185void tst_QDataStream::stream_QJsonDocument()
2186{
2187 QByteArray buffer;
2188 {
2189 QDataStream save(&buffer, QIODevice::WriteOnly);
2190 save << QByteArrayLiteral("invalidJson");
2191 QDataStream load(&buffer, QIODevice::ReadOnly);
2192 QJsonDocument doc;
2193 load >> doc;
2194 QVERIFY(doc.isEmpty());
2195 QVERIFY(load.status() != QDataStream::Ok);
2196 QCOMPARE(load.status(), QDataStream::ReadCorruptData);
2197 }
2198 {
2199 QDataStream save(&buffer, QIODevice::WriteOnly);
2200 QJsonDocument docSave(QJsonArray{1,2,3});
2201 save << docSave;
2202 QDataStream load(&buffer, QIODevice::ReadOnly);
2203 QJsonDocument docLoad;
2204 load >> docLoad;
2205 QCOMPARE(docLoad, docSave);
2206 }
2207}
2208
2209void tst_QDataStream::stream_QJsonArray()
2210{
2211 QByteArray buffer;
2212 {
2213 QDataStream save(&buffer, QIODevice::WriteOnly);
2214 save << QByteArrayLiteral("invalidJson");
2215 QDataStream load(&buffer, QIODevice::ReadOnly);
2216 QJsonArray array;
2217 load >> array;
2218 QVERIFY(array.isEmpty());
2219 QVERIFY(load.status() != QDataStream::Ok);
2220 QCOMPARE(load.status(), QDataStream::ReadCorruptData);
2221 }
2222 {
2223 QDataStream save(&buffer, QIODevice::WriteOnly);
2224 QJsonArray arraySave(QJsonArray{1,2,3});
2225 save << arraySave;
2226 QDataStream load(&buffer, QIODevice::ReadOnly);
2227 QJsonArray arrayLoad;
2228 load >> arrayLoad;
2229 QCOMPARE(arrayLoad, arraySave);
2230 }
2231}
2232
2233void tst_QDataStream::stream_QJsonObject()
2234{
2235 QByteArray buffer;
2236 {
2237 QDataStream save(&buffer, QIODevice::WriteOnly);
2238 save << QByteArrayLiteral("invalidJson");
2239 QDataStream load(&buffer, QIODevice::ReadOnly);
2240 QJsonObject object;
2241 load >> object;
2242 QVERIFY(object.isEmpty());
2243 QVERIFY(load.status() != QDataStream::Ok);
2244 QCOMPARE(load.status(), QDataStream::ReadCorruptData);
2245 }
2246 {
2247 QDataStream save(&buffer, QIODevice::WriteOnly);
2248 QJsonObject objSave{{"foo", 1}, {"bar", 2}};
2249 save << objSave;
2250 QDataStream load(&buffer, QIODevice::ReadOnly);
2251 QJsonObject objLoad;
2252 load >> objLoad;
2253 QCOMPARE(objLoad, objSave);
2254 }
2255}
2256
2257void tst_QDataStream::stream_QJsonValue()
2258{
2259 QByteArray buffer;
2260 {
2261 QDataStream save(&buffer, QIODevice::WriteOnly);
2262 save << quint8(42);
2263 QDataStream load(&buffer, QIODevice::ReadOnly);
2264 QJsonValue value;
2265 load >> value;
2266 QVERIFY(value.isUndefined());
2267 QVERIFY(load.status() != QDataStream::Ok);
2268 QCOMPARE(load.status(), QDataStream::ReadCorruptData);
2269 }
2270 {
2271 QDataStream save(&buffer, QIODevice::WriteOnly);
2272 QJsonValue valueSave{42};
2273 save << valueSave;
2274 QDataStream load(&buffer, QIODevice::ReadOnly);
2275 QJsonValue valueLoad;
2276 load >> valueLoad;
2277 QCOMPARE(valueLoad, valueSave);
2278 }
2279}
2280
2281void tst_QDataStream::stream_QCborArray()
2282{
2283 QByteArray buffer;
2284 QDataStream save(&buffer, QIODevice::WriteOnly);
2285 QCborArray arraySave({1, 2, 3});
2286 save << arraySave;
2287 QDataStream load(&buffer, QIODevice::ReadOnly);
2288 QCborArray arrayLoad;
2289 load >> arrayLoad;
2290 QCOMPARE(arrayLoad, arraySave);
2291}
2292
2293void tst_QDataStream::stream_QCborMap()
2294{
2295 QByteArray buffer;
2296 QDataStream save(&buffer, QIODevice::WriteOnly);
2297 QCborMap objSave{{"foo", 1}, {"bar", 2}};
2298 save << objSave;
2299 QDataStream load(&buffer, QIODevice::ReadOnly);
2300 QCborMap objLoad;
2301 load >> objLoad;
2302 QCOMPARE(objLoad, objSave);
2303}
2304
2305void tst_QDataStream::stream_QCborValue()
2306{
2307 QByteArray buffer;
2308 QDataStream save(&buffer, QIODevice::WriteOnly);
2309 QCborValue valueSave{42};
2310 save << valueSave;
2311 QDataStream load(&buffer, QIODevice::ReadOnly);
2312 QCborValue valueLoad;
2313 load >> valueLoad;
2314 QCOMPARE(valueLoad, valueSave);
2315}
2316
2317void tst_QDataStream::setVersion_data()
2318{
2319 QTest::addColumn<int>(name: "vers");
2320 QDataStream latest;
2321
2322 for (int vers = 1; vers <= latest.version(); ++vers)
2323 QTest::newRow(dataTag: ("v_" + QByteArray::number(vers)).constData()) << vers;
2324}
2325
2326void tst_QDataStream::setVersion()
2327{
2328 QDataStream latest;
2329 QFETCH(int, vers);
2330
2331 /*
2332 Test QKeySequence.
2333 */
2334 QByteArray ba1;
2335 {
2336 QDataStream out(&ba1, QIODevice::WriteOnly);
2337 out.setVersion(vers);
2338 out << QKeySequence(Qt::Key_A) << QKeySequence(Qt::Key_B, Qt::Key_C)
2339 << (quint32)0xDEADBEEF;
2340 }
2341 {
2342 QKeySequence keyseq1, keyseq2;
2343 quint32 deadbeef;
2344 QDataStream in(&ba1, QIODevice::ReadOnly);
2345 in.setVersion(vers);
2346 in >> keyseq1 >> keyseq2 >> deadbeef;
2347 QCOMPARE(keyseq1, QKeySequence(Qt::Key_A));
2348 if (vers >= 5) {
2349 QVERIFY(keyseq2 == QKeySequence(Qt::Key_B, Qt::Key_C));
2350 } else {
2351 QCOMPARE(keyseq2, QKeySequence(Qt::Key_B));
2352 }
2353 QCOMPARE(deadbeef, 0xDEADBEEF);
2354 }
2355
2356 /*
2357 Test QPalette.
2358 */
2359
2360 // revise the test if new color roles or color groups are added
2361 QVERIFY(QPalette::NColorRoles == QPalette::PlaceholderText + 1);
2362 QCOMPARE(int(QPalette::NColorGroups), 3);
2363
2364 QByteArray ba2;
2365 QPalette pal1, pal2;
2366 for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
2367 for (int role = 0; role < (int)QPalette::NColorRoles; ++role) {
2368 // random stuff
2369 pal1.setColor(acg: (QPalette::ColorGroup)grp, acr: (QPalette::ColorRole)role,
2370 acolor: QColor(grp * 13, 255 - grp, role));
2371 pal2.setColor(acg: (QPalette::ColorGroup)grp, acr: (QPalette::ColorRole)role,
2372 acolor: QColor(role * 11, 254 - role, grp));
2373 }
2374 }
2375
2376 {
2377 QDataStream out(&ba2, QIODevice::WriteOnly);
2378 out.setVersion(vers);
2379 out << pal1 << pal2 << (quint32)0xCAFEBABE;
2380 }
2381 {
2382 QPalette inPal1, inPal2;
2383 quint32 cafebabe;
2384 QDataStream in(&ba2, QIODevice::ReadOnly);
2385 in.setVersion(vers);
2386 in >> inPal1 >> inPal2;
2387 in >> cafebabe;
2388
2389 QCOMPARE(cafebabe, 0xCAFEBABE);
2390
2391 QCOMPARE(NColorRoles[latest.version()], (int)QPalette::NColorRoles); //if this fails you need to update the NColorRoles array
2392
2393 if (vers == 1) {
2394 for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
2395 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::WindowText)
2396 == inPal1.color((QPalette::ColorGroup)grp, QPalette::WindowText));
2397 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Window)
2398 == inPal1.color((QPalette::ColorGroup)grp, QPalette::Window));
2399 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Light)
2400 == inPal1.color((QPalette::ColorGroup)grp, QPalette::Light));
2401 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Dark)
2402 == inPal1.color((QPalette::ColorGroup)grp, QPalette::Dark));
2403 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Mid)
2404 == inPal1.color((QPalette::ColorGroup)grp, QPalette::Mid));
2405 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Text)
2406 == inPal1.color((QPalette::ColorGroup)grp, QPalette::Text));
2407 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Base)
2408 == inPal1.color((QPalette::ColorGroup)grp, QPalette::Base));
2409
2410 QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Midlight)
2411 != inPal1.color((QPalette::ColorGroup)grp, QPalette::Midlight));
2412 }
2413 } else {
2414 if (NColorRoles[vers] < QPalette::NColorRoles) {
2415 QVERIFY(pal1 != inPal1);
2416 QVERIFY(pal2 != inPal2);
2417
2418 for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) {
2419 for (int i = NColorRoles[vers]; i < QPalette::NColorRoles; ++i) {
2420 inPal1.setColor(acg: (QPalette::ColorGroup)grp, acr: (QPalette::ColorRole)i,
2421 acolor: pal1.color(cg: (QPalette::ColorGroup)grp, cr: (QPalette::ColorRole)i));
2422 inPal2.setColor(acg: (QPalette::ColorGroup)grp, acr: (QPalette::ColorRole)i,
2423 acolor: pal2.color(cg: (QPalette::ColorGroup)grp, cr: (QPalette::ColorRole)i));
2424 }
2425 }
2426 }
2427 QCOMPARE(pal1, inPal1);
2428 QCOMPARE(pal2, inPal2);
2429 }
2430 }
2431}
2432
2433class SequentialBuffer : public QIODevice
2434{
2435public:
2436 SequentialBuffer(QByteArray *data) : QIODevice() { buf.setBuffer(data); }
2437
2438 bool isSequential() const override { return true; }
2439 bool open(OpenMode mode) override { return buf.open(openMode: mode) && QIODevice::open(mode: mode | QIODevice::Unbuffered); }
2440 void close() override { buf.close(); QIODevice::close(); }
2441 qint64 bytesAvailable() const override { return QIODevice::bytesAvailable() + buf.bytesAvailable(); }
2442
2443protected:
2444 qint64 readData(char *data, qint64 maxSize) override { return buf.read(data, maxlen: maxSize); }
2445 qint64 writeData(const char *data, qint64 maxSize) override { return buf.write(data, len: maxSize); }
2446
2447private:
2448 QBuffer buf;
2449};
2450
2451void tst_QDataStream::skipRawData_data()
2452{
2453 QTest::addColumn<QString>(name: "deviceType");
2454 QTest::addColumn<QByteArray>(name: "data");
2455 QTest::addColumn<int>(name: "read");
2456 QTest::addColumn<int>(name: "skip");
2457 QTest::addColumn<int>(name: "skipped");
2458 QTest::addColumn<char>(name: "expect");
2459
2460 QByteArray bigData;
2461 bigData.fill(c: 'a', size: 20000);
2462 bigData[10001] = 'x';
2463
2464 QTest::newRow(dataTag: "1") << QString("sequential") << QByteArray("abcdefghij") << 3 << 6 << 6 << 'j';
2465 QTest::newRow(dataTag: "2") << QString("random-access") << QByteArray("abcdefghij") << 3 << 6 << 6 << 'j';
2466 QTest::newRow(dataTag: "3") << QString("sequential") << bigData << 1 << 10000 << 10000 << 'x';
2467 QTest::newRow(dataTag: "4") << QString("random-access") << bigData << 1 << 10000 << 10000 << 'x';
2468 QTest::newRow(dataTag: "5") << QString("sequential") << bigData << 1 << 20000 << 19999 << '\0';
2469 QTest::newRow(dataTag: "6") << QString("random-access") << bigData << 1 << 20000 << 19999 << '\0';
2470}
2471
2472void tst_QDataStream::skipRawData()
2473{
2474 QFETCH(QString, deviceType);
2475 QFETCH(QByteArray, data);
2476 QFETCH(int, read);
2477 QFETCH(int, skip);
2478 QFETCH(int, skipped);
2479 QFETCH(char, expect);
2480 qint8 dummy;
2481
2482 QIODevice *dev = 0;
2483 if (deviceType == "sequential") {
2484 dev = new SequentialBuffer(&data);
2485 } else if (deviceType == "random-access") {
2486 dev = new QBuffer(&data);
2487 }
2488 QVERIFY(dev);
2489 dev->open(mode: QIODevice::ReadOnly);
2490
2491 QDataStream in(dev);
2492 for (int i = 0; i < read; ++i)
2493 in >> dummy;
2494
2495 QCOMPARE(in.skipRawData(skip), skipped);
2496 in >> dummy;
2497 QCOMPARE((char)dummy, expect);
2498
2499 delete dev;
2500}
2501
2502#define TEST_qint(T, UT) \
2503 void tst_QDataStream::status_##T() \
2504 { \
2505 QFETCH(QByteArray, bigEndianData); \
2506 QFETCH(QByteArray, littleEndianData); \
2507 QFETCH(int, expectedStatus); \
2508 QFETCH(qint64, expectedValue); \
2509 \
2510 { \
2511 QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \
2512 T i; \
2513 stream >> i; \
2514 QCOMPARE((int) stream.status(), expectedStatus); \
2515 QCOMPARE(i, (T) expectedValue); \
2516 } \
2517 { \
2518 QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \
2519 UT i; \
2520 stream >> i; \
2521 QCOMPARE((int) stream.status(), expectedStatus); \
2522 QCOMPARE((T) i, (T) expectedValue); \
2523 } \
2524 { \
2525 QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \
2526 stream.setByteOrder(QDataStream::LittleEndian); \
2527 T i; \
2528 stream >> i; \
2529 QCOMPARE((int) stream.status(), expectedStatus); \
2530 QCOMPARE(i, (T) expectedValue); \
2531 } \
2532 { \
2533 QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \
2534 stream.setByteOrder(QDataStream::LittleEndian); \
2535 UT i; \
2536 stream >> i; \
2537 QCOMPARE((int) stream.status(), expectedStatus); \
2538 QCOMPARE((T) i, (T) expectedValue); \
2539 } \
2540 }
2541
2542#define TEST_FLOAT(T) \
2543 void tst_QDataStream::status_##T() \
2544 { \
2545 QFETCH(QByteArray, bigEndianData); \
2546 QFETCH(QByteArray, littleEndianData); \
2547 QFETCH(int, expectedStatus); \
2548 QFETCH(double, expectedValue); \
2549 \
2550 QDataStream::FloatingPointPrecision prec = sizeof(T) == sizeof(double) ? QDataStream::DoublePrecision : QDataStream::SinglePrecision; \
2551 \
2552 { \
2553 QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \
2554 stream.setFloatingPointPrecision(prec); \
2555 T i; \
2556 stream >> i; \
2557 QCOMPARE((int) stream.status(), expectedStatus); \
2558 QCOMPARE((float) i, (float) expectedValue); \
2559 } \
2560 { \
2561 QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \
2562 stream.setByteOrder(QDataStream::LittleEndian); \
2563 stream.setFloatingPointPrecision(prec); \
2564 T i; \
2565 stream >> i; \
2566 QCOMPARE((int) stream.status(), expectedStatus); \
2567 QCOMPARE((float) i, (float) expectedValue); \
2568 } \
2569 }
2570
2571void tst_QDataStream::status_qint8_data()
2572{
2573 QTest::addColumn<QByteArray>(name: "bigEndianData");
2574 QTest::addColumn<QByteArray>(name: "littleEndianData");
2575 QTest::addColumn<int>(name: "expectedStatus");
2576 QTest::addColumn<qint64>(name: "expectedValue");
2577
2578 // ok
2579 QTest::newRow(dataTag: "0") << QByteArray(1, '\x0') << QByteArray(1, '\x0') << (int) QDataStream::Ok << qint64(0);
2580 QTest::newRow(dataTag: "-1") << QByteArray(1, '\xff') << QByteArray(1, '\xff') << (int) QDataStream::Ok << qint64(-1);
2581 QTest::newRow(dataTag: "1") << QByteArray(1, '\x01') << QByteArray(1, '\x01') << (int) QDataStream::Ok << qint64(1);
2582 QTest::newRow(dataTag: "37") << QByteArray(1, '\x25') << QByteArray(1, '\x25') << (int) QDataStream::Ok << qint64(37);
2583 QTest::newRow(dataTag: "37j") << QByteArray("\x25j") << QByteArray("\x25j") << (int) QDataStream::Ok << qint64(37);
2584
2585 // past end
2586 QTest::newRow(dataTag: "empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
2587}
2588
2589TEST_qint(qint8, quint8)
2590
2591void tst_QDataStream::status_qint16_data()
2592{
2593 QTest::addColumn<QByteArray>(name: "bigEndianData");
2594 QTest::addColumn<QByteArray>(name: "littleEndianData");
2595 QTest::addColumn<int>(name: "expectedStatus");
2596 QTest::addColumn<qint64>(name: "expectedValue");
2597
2598 // ok
2599 QTest::newRow(dataTag: "0") << QByteArray(2, '\x0') << QByteArray(2, '\x0') << (int) QDataStream::Ok << qint64(0);
2600 QTest::newRow(dataTag: "-1") << QByteArray("\xff\xff", 2) << QByteArray("\xff\xff", 2) << (int) QDataStream::Ok << qint64(-1);
2601 QTest::newRow(dataTag: "1") << QByteArray("\x00\x01", 2) << QByteArray("\x01\x00", 2) << (int) QDataStream::Ok << qint64(1);
2602 QTest::newRow(dataTag: "37") << QByteArray("\x00\x25", 2) << QByteArray("\x25\x00", 2) << (int) QDataStream::Ok << qint64(37);
2603 QTest::newRow(dataTag: "37j") << QByteArray("\x00\x25j", 3) << QByteArray("\x25\x00j", 3) << (int) QDataStream::Ok << qint64(37);
2604 QTest::newRow(dataTag: "0x1234") << QByteArray("\x12\x34", 2) << QByteArray("\x34\x12", 2) << (int) QDataStream::Ok << qint64(0x1234);
2605
2606 // past end
2607 QTest::newRow(dataTag: "empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
2608 QTest::newRow(dataTag: "end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
2609 QTest::newRow(dataTag: "end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
2610}
2611
2612TEST_qint(qint16, quint16)
2613
2614void tst_QDataStream::status_qint32_data()
2615{
2616 QTest::addColumn<QByteArray>(name: "bigEndianData");
2617 QTest::addColumn<QByteArray>(name: "littleEndianData");
2618 QTest::addColumn<int>(name: "expectedStatus");
2619 QTest::addColumn<qint64>(name: "expectedValue");
2620
2621 // ok
2622 QTest::newRow(dataTag: "0") << QByteArray(4, '\x0') << QByteArray(4, '\x0') << (int) QDataStream::Ok << qint64(0);
2623 QTest::newRow(dataTag: "-1") << QByteArray("\xff\xff\xff\xff", 4) << QByteArray("\xff\xff\xff\xff", 4) << (int) QDataStream::Ok << qint64(-1);
2624 QTest::newRow(dataTag: "1") << QByteArray("\x00\x00\x00\x01", 4) << QByteArray("\x01\x00\x00\x00", 4) << (int) QDataStream::Ok << qint64(1);
2625 QTest::newRow(dataTag: "37") << QByteArray("\x00\x00\x00\x25", 4) << QByteArray("\x25\x00\x00\x00", 4) << (int) QDataStream::Ok << qint64(37);
2626 QTest::newRow(dataTag: "37j") << QByteArray("\x00\x00\x00\x25j", 5) << QByteArray("\x25\x00\x00\x00j", 5) << (int) QDataStream::Ok << qint64(37);
2627 QTest::newRow(dataTag: "0x12345678") << QByteArray("\x12\x34\x56\x78", 4) << QByteArray("\x78\x56\x34\x12", 4) << (int) QDataStream::Ok << qint64(0x12345678);
2628
2629 // past end
2630 QTest::newRow(dataTag: "empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
2631 QTest::newRow(dataTag: "end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
2632 QTest::newRow(dataTag: "end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
2633 QTest::newRow(dataTag: "end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << qint64(0);
2634 QTest::newRow(dataTag: "end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << qint64(0);
2635}
2636
2637TEST_qint(qint32, quint32)
2638
2639void tst_QDataStream::status_qint64_data()
2640{
2641 QTest::addColumn<QByteArray>(name: "bigEndianData");
2642 QTest::addColumn<QByteArray>(name: "littleEndianData");
2643 QTest::addColumn<int>(name: "expectedStatus");
2644 QTest::addColumn<qint64>(name: "expectedValue");
2645
2646 // ok
2647 QTest::newRow(dataTag: "0") << QByteArray(8, '\x0') << QByteArray(8, '\x0') << (int) QDataStream::Ok << qint64(0);
2648 QTest::newRow(dataTag: "-1") << QByteArray("\xff\xff\xff\xff\xff\xff\xff\xff", 8) << QByteArray("\xff\xff\xff\xff\xff\xff\xff\xff", 8) << (int) QDataStream::Ok << qint64(-1);
2649 QTest::newRow(dataTag: "1") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x01", 8) << QByteArray("\x01\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << qint64(1);
2650 QTest::newRow(dataTag: "37") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x25", 8) << QByteArray("\x25\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << qint64(37);
2651 QTest::newRow(dataTag: "37j") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x25j", 9) << QByteArray("\x25\x00\x00\x00\x00\x00\x00\x00j", 9) << (int) QDataStream::Ok << qint64(37);
2652 QTest::newRow(dataTag: "0x123456789ABCDEF0") << QByteArray("\x12\x34\x56\x78\x9a\xbc\xde\xf0", 8) << QByteArray("\xf0\xde\xbc\x9a\x78\x56\x34\x12", 8) << (int) QDataStream::Ok << (qint64)Q_INT64_C(0x123456789ABCDEF0);
2653
2654 // past end
2655 QTest::newRow(dataTag: "empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << qint64(0);
2656 QTest::newRow(dataTag: "end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
2657 QTest::newRow(dataTag: "end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << qint64(0);
2658 QTest::newRow(dataTag: "end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << qint64(0);
2659 QTest::newRow(dataTag: "end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << qint64(0);
2660 QTest::newRow(dataTag: "end 5") << QByteArray("1111", 4) << QByteArray("1111", 4) << (int) QDataStream::ReadPastEnd << qint64(0);
2661 QTest::newRow(dataTag: "end 6") << QByteArray("11111", 5) << QByteArray("11111", 5) << (int) QDataStream::ReadPastEnd << qint64(0);
2662 QTest::newRow(dataTag: "end 7") << QByteArray("111111", 6) << QByteArray("111111", 6) << (int) QDataStream::ReadPastEnd << qint64(0);
2663 QTest::newRow(dataTag: "end 8") << QByteArray("1111111", 7) << QByteArray("1111111", 7) << (int) QDataStream::ReadPastEnd << qint64(0);
2664}
2665
2666TEST_qint(qint64, quint64)
2667
2668void tst_QDataStream::status_float_data()
2669{
2670 QTest::addColumn<QByteArray>(name: "bigEndianData");
2671 QTest::addColumn<QByteArray>(name: "littleEndianData");
2672 QTest::addColumn<int>(name: "expectedStatus");
2673 QTest::addColumn<double>(name: "expectedValue");
2674
2675 // ok
2676 QTest::newRow(dataTag: "0") << QByteArray(4, '\0') << QByteArray(4, '\0') << (int) QDataStream::Ok << (double) 0.0;
2677 QTest::newRow(dataTag: "-1") << QByteArray("\xbf\x80\x00\x00", 4) << QByteArray("\x00\x00\x80\xbf", 4) << (int) QDataStream::Ok << (double) -1;
2678 QTest::newRow(dataTag: "1") << QByteArray("\x3f\x80\x00\x00", 4) << QByteArray("\x00\x00\x80\x3f", 4) << (int) QDataStream::Ok << (double) 1;
2679 QTest::newRow(dataTag: "37") << QByteArray("\x42\x14\x00\x00", 4) << QByteArray("\x00\x00\x14\x42", 4) << (int) QDataStream::Ok << (double) 37;
2680 QTest::newRow(dataTag: "37j") << QByteArray("\x42\x14\x00\x00j", 5) << QByteArray("\x00\x00\x14\x42j", 5) << (int) QDataStream::Ok << (double) 37;
2681 QTest::newRow(dataTag: "3.14") << QByteArray("\x40\x48\xf5\xc3", 4) << QByteArray("\xc3\xf5\x48\x40", 4) << (int) QDataStream::Ok << (double) 3.14;
2682
2683 // past end
2684 QTest::newRow(dataTag: "empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << double(0);
2685 QTest::newRow(dataTag: "end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << double(0);
2686 QTest::newRow(dataTag: "end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << double(0);
2687 QTest::newRow(dataTag: "end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << double(0);
2688 QTest::newRow(dataTag: "end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << double(0);
2689}
2690
2691TEST_FLOAT(float)
2692
2693void tst_QDataStream::status_double_data()
2694{
2695 QTest::addColumn<QByteArray>(name: "bigEndianData");
2696 QTest::addColumn<QByteArray>(name: "littleEndianData");
2697 QTest::addColumn<int>(name: "expectedStatus");
2698 QTest::addColumn<double>(name: "expectedValue");
2699
2700 // ok
2701 QTest::newRow(dataTag: "0") << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x00", 8) << (int) QDataStream::Ok << (double) 0;
2702 QTest::newRow(dataTag: "-1") << QByteArray("\xbf\xf0\x00\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x00\xf0\xbf", 8) << (int) QDataStream::Ok << (double) -1;
2703 QTest::newRow(dataTag: "1") << QByteArray("\x3f\xf0\x00\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x00\xf0\x3f", 8) << (int) QDataStream::Ok << (double) 1;
2704 QTest::newRow(dataTag: "37") << QByteArray("\x40\x42\x80\x00\x00\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x00\x00\x80\x42\x40", 8) << (int) QDataStream::Ok << (double) 37;
2705 QTest::newRow(dataTag: "37j") << QByteArray("\x40\x42\x80\x00\x00\x00\x00\x00j", 9) << QByteArray("\x00\x00\x00\x00\x00\x80\x42\x40j", 9) << (int) QDataStream::Ok << (double) 37;
2706 QTest::newRow(dataTag: "3.14") << QByteArray("\x40\x09\x1e\xb8\x60\x00\x00\x00", 8) << QByteArray("\x00\x00\x00\x60\xb8\x1e\x09\x40", 8) << (int) QDataStream::Ok << (double) 3.14;
2707 QTest::newRow(dataTag: "1234.5678") << QByteArray("\x40\x93\x4a\x45\x6d\x5c\xfa\xad", 8) << QByteArray("\xad\xfa\x5c\x6d\x45\x4a\x93\x40", 8) << (int) QDataStream::Ok << (double) 1234.5678;
2708
2709 // past end
2710 QTest::newRow(dataTag: "empty") << QByteArray() << QByteArray() << (int) QDataStream::ReadPastEnd << double(0);
2711 QTest::newRow(dataTag: "end 1") << QByteArray("", 1) << QByteArray("", 1) << (int) QDataStream::ReadPastEnd << double(0);
2712 QTest::newRow(dataTag: "end 2") << QByteArray("\x25", 1) << QByteArray("\x25", 1) << (int) QDataStream::ReadPastEnd << double(0);
2713 QTest::newRow(dataTag: "end 3") << QByteArray("11", 2) << QByteArray("11", 2) << (int) QDataStream::ReadPastEnd << double(0);
2714 QTest::newRow(dataTag: "end 4") << QByteArray("111", 3) << QByteArray("111", 3) << (int) QDataStream::ReadPastEnd << double(0);
2715 QTest::newRow(dataTag: "end 5") << QByteArray("1111", 4) << QByteArray("1111", 4) << (int) QDataStream::ReadPastEnd << double(0);
2716 QTest::newRow(dataTag: "end 6") << QByteArray("11111", 5) << QByteArray("11111", 5) << (int) QDataStream::ReadPastEnd << double(0);
2717 QTest::newRow(dataTag: "end 7") << QByteArray("111111", 6) << QByteArray("111111", 6) << (int) QDataStream::ReadPastEnd << double(0);
2718 QTest::newRow(dataTag: "end 8") << QByteArray("1111111", 7) << QByteArray("1111111", 7) << (int) QDataStream::ReadPastEnd << double(0);
2719}
2720
2721TEST_FLOAT(double)
2722
2723void tst_QDataStream::status_charptr_QByteArray_data()
2724{
2725 QTest::addColumn<QByteArray>(name: "data");
2726 QTest::addColumn<int>(name: "expectedStatus");
2727 QTest::addColumn<QByteArray>(name: "expectedString");
2728
2729 QByteArray oneMbMinus1(1024 * 1024 - 1, '\0');
2730 for (int i = 0; i < oneMbMinus1.size(); ++i)
2731 oneMbMinus1[i] = 0x1 | (8 * ((uchar)i / 9));
2732 QByteArray threeMbMinus1 = oneMbMinus1 + 'j' + oneMbMinus1 + 'k' + oneMbMinus1;
2733
2734 // ok
2735 QTest::newRow(dataTag: "size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QByteArray();
2736 QTest::newRow(dataTag: "size 1") << QByteArray("\x00\x00\x00\x01j", 5) << (int) QDataStream::Ok << QByteArray("j");
2737 QTest::newRow(dataTag: "size 2") << QByteArray("\x00\x00\x00\x02jk", 6) << (int) QDataStream::Ok << QByteArray("jk");
2738 QTest::newRow(dataTag: "size 3") << QByteArray("\x00\x00\x00\x03jkl", 7) << (int) QDataStream::Ok << QByteArray("jkl");
2739 QTest::newRow(dataTag: "size 4") << QByteArray("\x00\x00\x00\x04jklm", 8) << (int) QDataStream::Ok << QByteArray("jklm");
2740 QTest::newRow(dataTag: "size 4j") << QByteArray("\x00\x00\x00\x04jklmj", 8) << (int) QDataStream::Ok << QByteArray("jklm");
2741 QTest::newRow(dataTag: "size 1MB-1") << QByteArray("\x00\x0f\xff\xff", 4) + oneMbMinus1 + QByteArray("j") << (int) QDataStream::Ok << oneMbMinus1;
2742 QTest::newRow(dataTag: "size 1MB") << QByteArray("\x00\x10\x00\x00", 4) + oneMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << oneMbMinus1 + "j";
2743 QTest::newRow(dataTag: "size 1MB+1") << QByteArray("\x00\x10\x00\x01", 4) + oneMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << oneMbMinus1 + "jk";
2744 QTest::newRow(dataTag: "size 3MB-1") << QByteArray("\x00\x2f\xff\xff", 4) + threeMbMinus1 + QByteArray("j") << (int) QDataStream::Ok << threeMbMinus1;
2745 QTest::newRow(dataTag: "size 3MB") << QByteArray("\x00\x30\x00\x00", 4) + threeMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << threeMbMinus1 + "j";
2746 QTest::newRow(dataTag: "size 3MB+1") << QByteArray("\x00\x30\x00\x01", 4) + threeMbMinus1 + QByteArray("jkl") << (int) QDataStream::Ok << threeMbMinus1 + "jk";
2747
2748 // past end
2749 QTest::newRow(dataTag: "empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QByteArray();
2750 QTest::newRow(dataTag: "trunclen 1") << QByteArray("x") << (int) QDataStream::ReadPastEnd << QByteArray();
2751 QTest::newRow(dataTag: "trunclen 2") << QByteArray("xx") << (int) QDataStream::ReadPastEnd << QByteArray();
2752 QTest::newRow(dataTag: "trunclen 3") << QByteArray("xxx") << (int) QDataStream::ReadPastEnd << QByteArray();
2753 QTest::newRow(dataTag: "truncdata 1") << QByteArray("xxxx") << (int) QDataStream::ReadPastEnd << QByteArray();
2754 QTest::newRow(dataTag: "truncdata 2") << QByteArray("xxxxyyyy") << (int) QDataStream::ReadPastEnd << QByteArray();
2755 QTest::newRow(dataTag: "badsize 1") << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
2756 QTest::newRow(dataTag: "badsize 2") << QByteArray("\x00\x00\x00\x02j", 5) << (int) QDataStream::ReadPastEnd << QByteArray();
2757 QTest::newRow(dataTag: "badsize 3") << QByteArray("\x00\x00\x00\x03jk", 6) << (int) QDataStream::ReadPastEnd << QByteArray();
2758 QTest::newRow(dataTag: "badsize 4") << QByteArray("\x00\x00\x00\x04jkl", 7) << (int) QDataStream::ReadPastEnd << QByteArray();
2759 QTest::newRow(dataTag: "badsize 1MB") << QByteArray("\x00\x10\x00\x00", 4) + oneMbMinus1 << (int) QDataStream::ReadPastEnd << QByteArray();
2760 QTest::newRow(dataTag: "badsize 1MB+1") << QByteArray("\x00\x10\x00\x01", 4) + oneMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
2761 QTest::newRow(dataTag: "badsize 3MB") << QByteArray("\x00\x30\x00\x00", 4) + threeMbMinus1 << (int) QDataStream::ReadPastEnd << QByteArray();
2762 QTest::newRow(dataTag: "badsize 3MB+1") << QByteArray("\x00\x30\x00\x01", 4) + threeMbMinus1 + QByteArray("j") << (int) QDataStream::ReadPastEnd << QByteArray();
2763 QTest::newRow(dataTag: "size -1") << QByteArray("\xff\xff\xff\xff", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
2764 QTest::newRow(dataTag: "size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QByteArray();
2765}
2766
2767void tst_QDataStream::status_charptr_QByteArray()
2768{
2769 QFETCH(QByteArray, data);
2770 QFETCH(int, expectedStatus);
2771 QFETCH(QByteArray, expectedString);
2772
2773 {
2774 QDataStream stream(&data, QIODevice::ReadOnly);
2775 char *buf;
2776 stream >> buf;
2777
2778 QCOMPARE((int)qstrlen(buf), expectedString.size());
2779 QCOMPARE(QByteArray(buf), expectedString);
2780 QCOMPARE(int(stream.status()), expectedStatus);
2781 delete [] buf;
2782 }
2783 {
2784 QDataStream stream(&data, QIODevice::ReadOnly);
2785 char *buf;
2786 uint len;
2787 stream.readBytes(buf, len);
2788
2789 QCOMPARE((int)len, expectedString.size());
2790 QCOMPARE(QByteArray(buf, len), expectedString);
2791 QCOMPARE(int(stream.status()), expectedStatus);
2792 delete [] buf;
2793 }
2794 {
2795 QDataStream stream(&data, QIODevice::ReadOnly);
2796 QByteArray buf;
2797 stream >> buf;
2798
2799 if (data.startsWith(c: "\xff\xff\xff\xff")) {
2800 // QByteArray, unlike 'char *', supports the null/empty distinction
2801 QVERIFY(buf.isNull());
2802 } else {
2803 QCOMPARE(buf.size(), expectedString.size());
2804 QCOMPARE(buf, expectedString);
2805 QCOMPARE(int(stream.status()), expectedStatus);
2806 }
2807 }
2808}
2809
2810static QByteArray qstring2qbytearray(const QString &str)
2811{
2812 QByteArray ba(str.size() * 2 , '\0');
2813 for (int i = 0; i < str.size(); ++i) {
2814 // BigEndian
2815 ba[2 * i] = str[i].row();
2816 ba[2 * i + 1] = str[i].cell();
2817 }
2818 return ba;
2819}
2820
2821void tst_QDataStream::status_QString_data()
2822{
2823 QTest::addColumn<QByteArray>(name: "data");
2824 QTest::addColumn<int>(name: "expectedStatus");
2825 QTest::addColumn<QString>(name: "expectedString");
2826
2827 QString oneMbMinus1;
2828 oneMbMinus1.resize(size: 1024 * 1024 - 1);
2829 for (int i = 0; i < oneMbMinus1.size(); ++i)
2830 oneMbMinus1[i] = 0x1 | (8 * ((uchar)i / 9));
2831 QString threeMbMinus1 = oneMbMinus1 + QChar('j') + oneMbMinus1 + QChar('k') + oneMbMinus1;
2832
2833 QByteArray threeMbMinus1Data = qstring2qbytearray(str: threeMbMinus1);
2834 QByteArray oneMbMinus1Data = qstring2qbytearray(str: oneMbMinus1);
2835
2836 // ok
2837 QTest::newRow(dataTag: "size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QString();
2838 QTest::newRow(dataTag: "size 1") << QByteArray("\x00\x00\x00\x02\x00j", 6) << (int) QDataStream::Ok << QString("j");
2839 QTest::newRow(dataTag: "size 2") << QByteArray("\x00\x00\x00\x04\x00j\x00k", 8) << (int) QDataStream::Ok << QString("jk");
2840 QTest::newRow(dataTag: "size 3") << QByteArray("\x00\x00\x00\x06\x00j\x00k\x00l", 10) << (int) QDataStream::Ok << QString("jkl");
2841 QTest::newRow(dataTag: "size 4") << QByteArray("\x00\x00\x00\x08\x00j\x00k\x00l\x00m", 12) << (int) QDataStream::Ok << QString("jklm");
2842 QTest::newRow(dataTag: "size 4j") << QByteArray("\x00\x00\x00\x08\x00j\x00k\x00l\x00mjj", 14) << (int) QDataStream::Ok << QString("jklm");
2843 QTest::newRow(dataTag: "size 1MB-1") << QByteArray("\x00\x1f\xff\xfe", 4) + oneMbMinus1Data + QByteArray("jj") << (int) QDataStream::Ok << oneMbMinus1;
2844 QTest::newRow(dataTag: "size 1MB") << QByteArray("\x00\x20\x00\x00", 4) + oneMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << oneMbMinus1 + "j";
2845 QTest::newRow(dataTag: "size 1MB+1") << QByteArray("\x00\x20\x00\x02", 4) + oneMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << oneMbMinus1 + "jk";
2846 QTest::newRow(dataTag: "size 3MB-1") << QByteArray("\x00\x5f\xff\xfe", 4) + threeMbMinus1Data + QByteArray("jj") << (int) QDataStream::Ok << threeMbMinus1;
2847 QTest::newRow(dataTag: "size 3MB") << QByteArray("\x00\x60\x00\x00", 4) + threeMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << threeMbMinus1 + "j";
2848 QTest::newRow(dataTag: "size 3MB+1") << QByteArray("\x00\x60\x00\x02", 4) + threeMbMinus1Data + QByteArray("\x00j\x00k\x00l", 6) << (int) QDataStream::Ok << threeMbMinus1 + "jk";
2849
2850 // past end
2851 QTest::newRow(dataTag: "empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QString();
2852 QTest::newRow(dataTag: "trunclen 1") << QByteArray("x") << (int) QDataStream::ReadPastEnd << QString();
2853 QTest::newRow(dataTag: "trunclen 2") << QByteArray("xx") << (int) QDataStream::ReadPastEnd << QString();
2854 QTest::newRow(dataTag: "trunclen 3") << QByteArray("xxx") << (int) QDataStream::ReadPastEnd << QString();
2855 QTest::newRow(dataTag: "truncdata 1") << QByteArray("xxxx") << (int) QDataStream::ReadPastEnd << QString();
2856 QTest::newRow(dataTag: "truncdata 2") << QByteArray("xxxxyyyy") << (int) QDataStream::ReadPastEnd << QString();
2857 QTest::newRow(dataTag: "badsize 1") << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QString();
2858 QTest::newRow(dataTag: "badsize 2") << QByteArray("\x00\x00\x00\x04jj", 6) << (int) QDataStream::ReadPastEnd << QString();
2859 QTest::newRow(dataTag: "badsize 3") << QByteArray("\x00\x00\x00\x06jjkk", 8) << (int) QDataStream::ReadPastEnd << QString();
2860 QTest::newRow(dataTag: "badsize 4") << QByteArray("\x00\x00\x00\x08jjkkll", 10) << (int) QDataStream::ReadPastEnd << QString();
2861 QTest::newRow(dataTag: "badsize 1MB") << QByteArray("\x00\x20\x00\x00", 4) + oneMbMinus1Data << (int) QDataStream::ReadPastEnd << QString();
2862 QTest::newRow(dataTag: "badsize 1MB+1") << QByteArray("\x00\x20\x00\x02", 4) + oneMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
2863 QTest::newRow(dataTag: "badsize 3MB") << QByteArray("\x00\x60\x00\x00", 4) + threeMbMinus1Data << (int) QDataStream::ReadPastEnd << QString();
2864 QTest::newRow(dataTag: "badsize 3MB+1") << QByteArray("\x00\x60\x00\x02", 4) + threeMbMinus1Data + QByteArray("j") << (int) QDataStream::ReadPastEnd << QString();
2865 QTest::newRow(dataTag: "size -2") << QByteArray("\xff\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
2866 QTest::newRow(dataTag: "size MAX") << QByteArray("\x7f\xff\xff\xfe", 4) << (int) QDataStream::ReadPastEnd << QString();
2867
2868 // corrupt data
2869 QTest::newRow(dataTag: "corrupt1") << QByteArray("yyyy") << (int) QDataStream::ReadCorruptData << QString();
2870 QTest::newRow(dataTag: "size -3") << QByteArray("\xff\xff\xff\xfd", 4) << (int) QDataStream::ReadCorruptData << QString();
2871}
2872
2873void tst_QDataStream::status_QString()
2874{
2875 QFETCH(QByteArray, data);
2876 QFETCH(int, expectedStatus);
2877 QFETCH(QString, expectedString);
2878
2879 QDataStream stream(&data, QIODevice::ReadOnly);
2880 QString str;
2881 stream >> str;
2882
2883 QCOMPARE(str.size(), expectedString.size());
2884 QCOMPARE(str, expectedString);
2885 QCOMPARE(int(stream.status()), expectedStatus);
2886}
2887
2888static QBitArray bitarray(const QString &str)
2889{
2890 QBitArray array(str.size());
2891 for (int i = 0; i < str.size(); ++i)
2892 array[i] = (str[i] != '0');
2893 return array;
2894}
2895
2896void tst_QDataStream::status_QBitArray_data()
2897{
2898 QTest::addColumn<QByteArray>(name: "data");
2899 QTest::addColumn<int>(name: "expectedStatus");
2900 QTest::addColumn<QBitArray>(name: "expectedString");
2901
2902 // ok
2903 QTest::newRow(dataTag: "size 0") << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::Ok << QBitArray();
2904 QTest::newRow(dataTag: "size 1a") << QByteArray("\x00\x00\x00\x01\x00", 5) << (int) QDataStream::Ok << bitarray(str: "0");
2905 QTest::newRow(dataTag: "size 1b") << QByteArray("\x00\x00\x00\x01\x01", 5) << (int) QDataStream::Ok << bitarray(str: "1");
2906 QTest::newRow(dataTag: "size 2") << QByteArray("\x00\x00\x00\x02\x03", 5) << (int) QDataStream::Ok << bitarray(str: "11");
2907 QTest::newRow(dataTag: "size 3") << QByteArray("\x00\x00\x00\x03\x07", 5) << (int) QDataStream::Ok << bitarray(str: "111");
2908 QTest::newRow(dataTag: "size 4") << QByteArray("\x00\x00\x00\x04\x0f", 5) << (int) QDataStream::Ok << bitarray(str: "1111");
2909 QTest::newRow(dataTag: "size 5") << QByteArray("\x00\x00\x00\x05\x1f", 5) << (int) QDataStream::Ok << bitarray(str: "11111");
2910 QTest::newRow(dataTag: "size 6") << QByteArray("\x00\x00\x00\x06\x3f", 5) << (int) QDataStream::Ok << bitarray(str: "111111");
2911 QTest::newRow(dataTag: "size 7a") << QByteArray("\x00\x00\x00\x07\x7f", 5) << (int) QDataStream::Ok << bitarray(str: "1111111");
2912 QTest::newRow(dataTag: "size 7b") << QByteArray("\x00\x00\x00\x07\x7e", 5) << (int) QDataStream::Ok << bitarray(str: "0111111");
2913 QTest::newRow(dataTag: "size 7c") << QByteArray("\x00\x00\x00\x07\x00", 5) << (int) QDataStream::Ok << bitarray(str: "0000000");
2914 QTest::newRow(dataTag: "size 7d") << QByteArray("\x00\x00\x00\x07\x39", 5) << (int) QDataStream::Ok << bitarray(str: "1001110");
2915 QTest::newRow(dataTag: "size 8") << QByteArray("\x00\x00\x00\x08\xff", 5) << (int) QDataStream::Ok << bitarray(str: "11111111");
2916 QTest::newRow(dataTag: "size 9") << QByteArray("\x00\x00\x00\x09\xff\x01", 6) << (int) QDataStream::Ok << bitarray(str: "111111111");
2917 QTest::newRow(dataTag: "size 15") << QByteArray("\x00\x00\x00\x0f\xff\x7f", 6) << (int) QDataStream::Ok << bitarray(str: "111111111111111");
2918 QTest::newRow(dataTag: "size 16") << QByteArray("\x00\x00\x00\x10\xff\xff", 6) << (int) QDataStream::Ok << bitarray(str: "1111111111111111");
2919 QTest::newRow(dataTag: "size 17") << QByteArray("\x00\x00\x00\x11\xff\xff\x01", 7) << (int) QDataStream::Ok << bitarray(str: "11111111111111111");
2920 QTest::newRow(dataTag: "size 32") << QByteArray("\x00\x00\x00\x20\xff\xff\xff\xff", 8) << (int) QDataStream::Ok << bitarray(str: "11111111111111111111111111111111");
2921
2922 // past end
2923 QTest::newRow(dataTag: "empty") << QByteArray() << (int) QDataStream::ReadPastEnd << QBitArray();
2924 QTest::newRow(dataTag: "badsize 0a") << QByteArray("\x00", 1) << (int) QDataStream::ReadPastEnd << QBitArray();
2925 QTest::newRow(dataTag: "badsize 0b") << QByteArray("\x00\x00", 2) << (int) QDataStream::ReadPastEnd << QBitArray();
2926 QTest::newRow(dataTag: "badsize 0c") << QByteArray("\x00\x00\x00", 3) << (int) QDataStream::ReadPastEnd << QBitArray();
2927 QTest::newRow(dataTag: "badsize 1") << QByteArray("\x00\x00\x00\x01", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
2928 QTest::newRow(dataTag: "badsize 2") << QByteArray("\x00\x00\x00\x02", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
2929 QTest::newRow(dataTag: "badsize 3") << QByteArray("\x00\x00\x00\x03", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
2930 QTest::newRow(dataTag: "badsize 7") << QByteArray("\x00\x00\x00\x04", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
2931 QTest::newRow(dataTag: "size 8") << QByteArray("\x00\x00\x00\x08", 4) << (int) QDataStream::ReadPastEnd << QBitArray();
2932 QTest::newRow(dataTag: "size 9") << QByteArray("\x00\x00\x00\x09\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
2933 QTest::newRow(dataTag: "size 15") << QByteArray("\x00\x00\x00\x0f\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
2934 QTest::newRow(dataTag: "size 16") << QByteArray("\x00\x00\x00\x10\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray();
2935 QTest::newRow(dataTag: "size 17") << QByteArray("\x00\x00\x00\x11\xff\xff", 6) << (int) QDataStream::ReadPastEnd << QBitArray();
2936 QTest::newRow(dataTag: "size 32") << QByteArray("\x00\x00\x00\x20\xff\xff\xff", 7) << (int) QDataStream::ReadPastEnd << QBitArray();
2937
2938 // corrupt data
2939 QTest::newRow(dataTag: "junk 1a") << QByteArray("\x00\x00\x00\x01\x02", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2940 QTest::newRow(dataTag: "junk 1b") << QByteArray("\x00\x00\x00\x01\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2941 QTest::newRow(dataTag: "junk 1c") << QByteArray("\x00\x00\x00\x01\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2942 QTest::newRow(dataTag: "junk 1d") << QByteArray("\x00\x00\x00\x01\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2943 QTest::newRow(dataTag: "junk 1e") << QByteArray("\x00\x00\x00\x01\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2944 QTest::newRow(dataTag: "junk 1f") << QByteArray("\x00\x00\x00\x01\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2945 QTest::newRow(dataTag: "junk 1g") << QByteArray("\x00\x00\x00\x01\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2946 QTest::newRow(dataTag: "junk 2") << QByteArray("\x00\x00\x00\x02\x04", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2947 QTest::newRow(dataTag: "junk 3") << QByteArray("\x00\x00\x00\x03\x08", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2948 QTest::newRow(dataTag: "junk 4") << QByteArray("\x00\x00\x00\x04\x10", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2949 QTest::newRow(dataTag: "junk 5") << QByteArray("\x00\x00\x00\x05\x20", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2950 QTest::newRow(dataTag: "junk 6") << QByteArray("\x00\x00\x00\x06\x40", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2951 QTest::newRow(dataTag: "junk 7") << QByteArray("\x00\x00\x00\x07\x80", 5) << (int) QDataStream::ReadCorruptData << QBitArray();
2952}
2953
2954void tst_QDataStream::status_QBitArray()
2955{
2956 QFETCH(QByteArray, data);
2957 QFETCH(int, expectedStatus);
2958 QFETCH(QBitArray, expectedString);
2959
2960 QDataStream stream(&data, QIODevice::ReadOnly);
2961 QBitArray str;
2962 stream >> str;
2963
2964 QCOMPARE(int(stream.status()), expectedStatus);
2965 QCOMPARE(str.size(), expectedString.size());
2966 QCOMPARE(str, expectedString);
2967}
2968
2969#define MAP_TEST(byteArray, initialStatus, expectedStatus, expectedHash) \
2970 for (bool inTransaction = false;; inTransaction = true) { \
2971 { \
2972 QByteArray ba = byteArray; \
2973 QDataStream stream(&ba, QIODevice::ReadOnly); \
2974 if (inTransaction) \
2975 stream.startTransaction(); \
2976 stream.setStatus(initialStatus); \
2977 stream >> hash; \
2978 QCOMPARE((int)stream.status(), (int)expectedStatus); \
2979 if (!inTransaction || stream.commitTransaction()) { \
2980 QCOMPARE(hash.size(), expectedHash.size()); \
2981 QCOMPARE(hash, expectedHash); \
2982 } else { \
2983 QVERIFY(hash.isEmpty()); \
2984 } \
2985 } \
2986 { \
2987 QByteArray ba = byteArray; \
2988 StringMap expectedMap; \
2989 StringHash::const_iterator it = expectedHash.constBegin(); \
2990 for (; it != expectedHash.constEnd(); ++it) \
2991 expectedMap.insert(it.key(), it.value()); \
2992 QDataStream stream(&ba, QIODevice::ReadOnly); \
2993 if (inTransaction) \
2994 stream.startTransaction(); \
2995 stream.setStatus(initialStatus); \
2996 stream >> map; \
2997 QCOMPARE((int)stream.status(), (int)expectedStatus); \
2998 if (!inTransaction || stream.commitTransaction()) { \
2999 QCOMPARE(map.size(), expectedMap.size()); \
3000 QCOMPARE(map, expectedMap); \
3001 } else { \
3002 QVERIFY(map.isEmpty()); \
3003 } \
3004 } \
3005 if (inTransaction) \
3006 break; \
3007 }
3008
3009void tst_QDataStream::status_QHash_QMap()
3010{
3011 typedef QHash<QString, QString> StringHash;
3012 typedef QMap<QString, QString> StringMap;
3013 StringHash hash;
3014 StringMap map;
3015
3016 StringHash hash1;
3017 hash1.insert(key: "", value: "");
3018
3019 StringHash hash2;
3020 hash2.insert(key: "J", value: "K");
3021 hash2.insert(key: "L", value: "MN");
3022
3023 // ok
3024 MAP_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, StringHash());
3025 MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 12), QDataStream::Ok, QDataStream::Ok, hash1);
3026 MAP_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J\x00\x00\x00\x02\x00K"
3027 "\x00\x00\x00\x02\x00L\x00\x00\x00\x04\x00M\x00N", 30), QDataStream::Ok, QDataStream::Ok, hash2);
3028
3029 // past end
3030 MAP_TEST(QByteArray(), QDataStream::Ok, QDataStream::ReadPastEnd, StringHash());
3031 MAP_TEST(QByteArray("\x00", 1), QDataStream::Ok, QDataStream::ReadPastEnd, StringHash());
3032 MAP_TEST(QByteArray("\x00\x00", 2), QDataStream::Ok, QDataStream::ReadPastEnd, StringHash());
3033 MAP_TEST(QByteArray("\x00\x00\x00", 3), QDataStream::Ok, QDataStream::ReadPastEnd, StringHash());
3034 MAP_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::Ok, QDataStream::ReadPastEnd, StringHash());
3035 for (int i = 4; i < 12; ++i) {
3036 MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", i), QDataStream::Ok, QDataStream::ReadPastEnd, StringHash());
3037 }
3038
3039 // corrupt data
3040 MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::Ok, QDataStream::ReadCorruptData, StringHash());
3041 MAP_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x01\x00J\x00\x00\x00\x01\x00K"
3042 "\x00\x00\x00\x01\x00L\x00\x00\x00\x02\x00M\x00N", 30), QDataStream::Ok, QDataStream::ReadCorruptData, StringHash());
3043
3044 // test the previously latched error status is not affected by reading
3045 MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 12), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, hash1);
3046 MAP_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::ReadCorruptData, QDataStream::ReadCorruptData, StringHash());
3047 MAP_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, StringHash());
3048}
3049
3050#define LIST_TEST(byteArray, initialStatus, expectedStatus, expectedList) \
3051 for (bool inTransaction = false;; inTransaction = true) { \
3052 { \
3053 QByteArray ba = byteArray; \
3054 QDataStream stream(&ba, QIODevice::ReadOnly); \
3055 if (inTransaction) \
3056 stream.startTransaction(); \
3057 stream.setStatus(initialStatus); \
3058 stream >> list; \
3059 QCOMPARE((int)stream.status(), (int)expectedStatus); \
3060 if (!inTransaction || stream.commitTransaction()) { \
3061 QCOMPARE(list.size(), expectedList.size()); \
3062 QCOMPARE(list, expectedList); \
3063 } else { \
3064 QVERIFY(list.isEmpty()); \
3065 } \
3066 } \
3067 { \
3068 Vector expectedVector; \
3069 for (int i = 0; i < expectedList.count(); ++i) \
3070 expectedVector << expectedList.at(i); \
3071 QByteArray ba = byteArray; \
3072 QDataStream stream(&ba, QIODevice::ReadOnly); \
3073 if (inTransaction) \
3074 stream.startTransaction(); \
3075 stream.setStatus(initialStatus); \
3076 stream >> vector; \
3077 QCOMPARE((int)stream.status(), (int)expectedStatus); \
3078 if (!inTransaction || stream.commitTransaction()) { \
3079 QCOMPARE(vector.size(), expectedVector.size()); \
3080 QCOMPARE(vector, expectedVector); \
3081 } else { \
3082 QVERIFY(vector.isEmpty()); \
3083 } \
3084 } \
3085 if (inTransaction) \
3086 break; \
3087 }
3088
3089#define LINKED_LIST_TEST(byteArray, initialStatus, expectedStatus, expectedList) \
3090 for (bool inTransaction = false;; inTransaction = true) { \
3091 { \
3092 LinkedList expectedLinkedList; \
3093 for (int i = 0; i < expectedList.count(); ++i) \
3094 expectedLinkedList << expectedList.at(i); \
3095 QByteArray ba = byteArray; \
3096 QDataStream stream(&ba, QIODevice::ReadOnly); \
3097 if (inTransaction) \
3098 stream.startTransaction(); \
3099 stream.setStatus(initialStatus); \
3100 stream >> linkedList; \
3101 QCOMPARE((int)stream.status(), (int)expectedStatus); \
3102 if (!inTransaction || stream.commitTransaction()) { \
3103 QCOMPARE(linkedList.size(), expectedLinkedList.size()); \
3104 QCOMPARE(linkedList, expectedLinkedList); \
3105 } else { \
3106 QVERIFY(linkedList.isEmpty()); \
3107 } \
3108 } \
3109 if (inTransaction) \
3110 break; \
3111 }
3112
3113void tst_QDataStream::status_QLinkedList_QList_QVector()
3114{
3115 typedef QList<QString> List;
3116 typedef QVector<QString> Vector;
3117 List list;
3118 Vector vector;
3119
3120 // ok
3121 {
3122 List listWithEmptyString;
3123 listWithEmptyString.append(t: "");
3124
3125 List someList;
3126 someList.append(t: "J");
3127 someList.append(t: "MN");
3128
3129 LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, List());
3130 LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::Ok, QDataStream::Ok, listWithEmptyString);
3131 LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J"
3132 "\x00\x00\x00\x04\x00M\x00N", 18), QDataStream::Ok, QDataStream::Ok, someList);
3133 }
3134
3135 // past end
3136 {
3137 LIST_TEST(QByteArray(), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3138 LIST_TEST(QByteArray("\x00", 1), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3139 LIST_TEST(QByteArray("\x00\x00", 2), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3140 LIST_TEST(QByteArray("\x00\x00\x00", 3), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3141 LIST_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3142 for (int i = 4; i < 12; ++i) {
3143 LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", i), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3144 }
3145 }
3146
3147 // corrupt data
3148 {
3149 LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::Ok, QDataStream::ReadCorruptData, List());
3150 LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x01\x00J"
3151 "\x00\x00\x00\x02\x00M\x00N", 18), QDataStream::Ok, QDataStream::ReadCorruptData, List());
3152 }
3153
3154 // test the previously latched error status is not affected by reading
3155 {
3156 List listWithEmptyString;
3157 listWithEmptyString.append(t: "");
3158
3159 LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, listWithEmptyString);
3160 LIST_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::ReadCorruptData, QDataStream::ReadCorruptData, List());
3161 LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, List());
3162 }
3163
3164#if QT_DEPRECATED_SINCE(5, 15)
3165QT_WARNING_PUSH
3166QT_WARNING_DISABLE_DEPRECATED
3167 // The same as above with QLinkedList
3168
3169 typedef QLinkedList<QString> LinkedList;
3170 LinkedList linkedList;
3171
3172 // ok
3173 {
3174 List listWithEmptyString;
3175 listWithEmptyString.append(t: "");
3176
3177 List someList;
3178 someList.append(t: "J");
3179 someList.append(t: "MN");
3180
3181 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x00", 4), QDataStream::Ok, QDataStream::Ok, List());
3182 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::Ok, QDataStream::Ok, listWithEmptyString);
3183 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x02\x00J"
3184 "\x00\x00\x00\x04\x00M\x00N", 18), QDataStream::Ok, QDataStream::Ok, someList);
3185 }
3186
3187 // past end
3188 {
3189 LINKED_LIST_TEST(QByteArray(), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3190 LINKED_LIST_TEST(QByteArray("\x00", 1), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3191 LINKED_LIST_TEST(QByteArray("\x00\x00", 2), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3192 LINKED_LIST_TEST(QByteArray("\x00\x00\x00", 3), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3193 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3194 for (int i = 4; i < 12; ++i) {
3195 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", i), QDataStream::Ok, QDataStream::ReadPastEnd, List());
3196 }
3197 }
3198
3199 // corrupt data
3200 {
3201 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::Ok, QDataStream::ReadCorruptData, List());
3202 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x02\x00\x00\x00\x01\x00J"
3203 "\x00\x00\x00\x02\x00M\x00N", 18), QDataStream::Ok, QDataStream::ReadCorruptData, List());
3204 }
3205
3206 // test the previously latched error status is not affected by reading
3207 {
3208 List listWithEmptyString;
3209 listWithEmptyString.append(t: "");
3210
3211 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, listWithEmptyString);
3212 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x01", 4), QDataStream::ReadCorruptData, QDataStream::ReadCorruptData, List());
3213 LINKED_LIST_TEST(QByteArray("\x00\x00\x00\x01\x00\x00\x00\x01", 8), QDataStream::ReadPastEnd, QDataStream::ReadPastEnd, List());
3214 }
3215
3216QT_WARNING_POP
3217#endif
3218}
3219
3220void tst_QDataStream::streamToAndFromQByteArray()
3221{
3222 QByteArray data;
3223 QDataStream in(&data, QIODevice::WriteOnly);
3224 QDataStream out(&data, QIODevice::ReadOnly);
3225
3226 quint32 x = 0xdeadbeef;
3227 quint32 y;
3228 in << x;
3229 out >> y;
3230
3231 QCOMPARE(y, x);
3232}
3233
3234void tst_QDataStream::streamRealDataTypes()
3235{
3236 // Generate QPicture from pixmap.
3237 QPixmap pm(open_xpm);
3238 QVERIFY(!pm.isNull());
3239 QPicture picture;
3240 picture.setBoundingRect(QRect(QPoint(0, 0), pm.size()));
3241 QPainter painter(&picture);
3242 painter.drawPixmap(x: 0, y: 0, pm);
3243 painter.end();
3244
3245 // Generate path
3246 QPainterPath path;
3247 path.lineTo(x: 10, y: 0);
3248 path.cubicTo(ctrlPt1x: 0, ctrlPt1y: 0, ctrlPt2x: 10, ctrlPt2y: 10, endPtx: 20, endPty: 20);
3249 path.arcTo(x: 4, y: 5, w: 6, h: 7, startAngle: 8, arcLength: 9);
3250 path.quadTo(ctrlPtx: 1, ctrlPty: 2, endPtx: 3, endPty: 4);
3251
3252 QColor color(64, 64, 64);
3253 color.setAlphaF(0.5);
3254 QRadialGradient radialGradient(5, 6, 7, 8, 9);
3255 QBrush radialBrush(radialGradient);
3256 QConicalGradient conicalGradient(5, 6, 7);
3257 QBrush conicalBrush(conicalGradient);
3258
3259 for (int i = 0; i < 2; ++i) {
3260 QFile file;
3261 if (i == 0) {
3262 file.setFileName(QFINDTESTDATA("datastream.q42"));
3263 } else {
3264 file.setFileName("datastream.tmp");
3265
3266 // Generate data
3267 QVERIFY(file.open(QIODevice::WriteOnly));
3268 QDataStream stream(&file);
3269 stream.setVersion(QDataStream::Qt_4_2);
3270 stream << qreal(0) << qreal(1.0) << qreal(1.1) << qreal(3.14) << qreal(-3.14) << qreal(-1);
3271 stream << QPointF(3, 5) << QRectF(-1, -2, 3, 4) << (QPolygonF() << QPointF(0, 0) << QPointF(1, 2));
3272 stream << QMatrix().rotate(a: 90).scale(sx: 2, sy: 2);
3273 stream << path;
3274 stream << picture;
3275 stream << QTextLength(QTextLength::VariableLength, 1.5);
3276 stream << color;
3277 stream << radialBrush << conicalBrush;
3278 stream << QPen(QBrush(Qt::red), 1.5);
3279
3280 file.close();
3281 }
3282
3283 QPointF point;
3284 QRectF rect;
3285 QPolygonF polygon;
3286 QMatrix matrix;
3287 QPainterPath p;
3288 QPicture pict;
3289 QTextLength textLength;
3290 QColor col;
3291 QBrush rGrad;
3292 QBrush cGrad;
3293 QPen pen;
3294
3295 QVERIFY(file.open(QIODevice::ReadOnly));
3296 QDataStream stream(&file);
3297 stream.setVersion(QDataStream::Qt_4_2);
3298
3299 if (i == 0) {
3300 // the reference stream for 4.2 contains doubles,
3301 // so we must read them out as doubles!
3302 double a, b, c, d, e, f;
3303 stream >> a;
3304 QCOMPARE(a, 0.0);
3305 stream >> b;
3306 QCOMPARE(b, 1.0);
3307 stream >> c;
3308 QCOMPARE(c, 1.1);
3309 stream >> d;
3310 QCOMPARE(d, 3.14);
3311 stream >> e;
3312 QCOMPARE(e, -3.14);
3313 stream >> f;
3314 QCOMPARE(f, -1.0);
3315 } else {
3316 qreal a, b, c, d, e, f;
3317 stream >> a;
3318 QCOMPARE(a, qreal(0));
3319 stream >> b;
3320 QCOMPARE(b, qreal(1.0));
3321 stream >> c;
3322 QCOMPARE(c, qreal(1.1));
3323 stream >> d;
3324 QCOMPARE(d, qreal(3.14));
3325 stream >> e;
3326 QCOMPARE(e, qreal(-3.14));
3327 stream >> f;
3328 QCOMPARE(f, qreal(-1));
3329 }
3330 stream >> point;
3331 QCOMPARE(point, QPointF(3, 5));
3332 stream >> rect;
3333 QCOMPARE(rect, QRectF(-1, -2, 3, 4));
3334 stream >> polygon;
3335 QCOMPARE((QVector<QPointF> &)polygon, (QPolygonF() << QPointF(0, 0) << QPointF(1, 2)));
3336 stream >> matrix;
3337 QCOMPARE(matrix, QMatrix().rotate(90).scale(2, 2));
3338 stream >> p;
3339 QCOMPARE(p, path);
3340 if (i == 1) {
3341 stream >> pict;
3342
3343 QByteArray pictA, pictB;
3344 QBuffer bufA, bufB;
3345 QVERIFY(bufA.open(QIODevice::ReadWrite));
3346 QVERIFY(bufB.open(QIODevice::ReadWrite));
3347
3348 picture.save(dev: &bufA);
3349 pict.save(dev: &bufB);
3350
3351 QCOMPARE(pictA, pictB);
3352 }
3353 stream >> textLength;
3354 QCOMPARE(textLength, QTextLength(QTextLength::VariableLength, 1.5));
3355 stream >> col;
3356 QCOMPARE(col, color);
3357 stream >> rGrad;
3358 QCOMPARE(rGrad.style(), radialBrush.style());
3359QT_WARNING_PUSH
3360QT_WARNING_DISABLE_DEPRECATED
3361 QCOMPARE(rGrad.matrix(), radialBrush.matrix());
3362QT_WARNING_POP
3363 QCOMPARE(rGrad.gradient()->type(), radialBrush.gradient()->type());
3364 QCOMPARE(rGrad.gradient()->stops(), radialBrush.gradient()->stops());
3365 QCOMPARE(rGrad.gradient()->spread(), radialBrush.gradient()->spread());
3366 QCOMPARE(((QRadialGradient *)rGrad.gradient())->center(), ((QRadialGradient *)radialBrush.gradient())->center());
3367 QCOMPARE(((QRadialGradient *)rGrad.gradient())->focalPoint(), ((QRadialGradient *)radialBrush.gradient())->focalPoint());
3368 QCOMPARE(((QRadialGradient *)rGrad.gradient())->radius(), ((QRadialGradient *)radialBrush.gradient())->radius());
3369 stream >> cGrad;
3370 QCOMPARE(cGrad.style(), conicalBrush.style());
3371QT_WARNING_PUSH
3372QT_WARNING_DISABLE_DEPRECATED
3373 QCOMPARE(cGrad.matrix(), conicalBrush.matrix());
3374QT_WARNING_POP
3375 QCOMPARE(cGrad.gradient()->type(), conicalBrush.gradient()->type());
3376 QCOMPARE(cGrad.gradient()->stops(), conicalBrush.gradient()->stops());
3377 QCOMPARE(cGrad.gradient()->spread(), conicalBrush.gradient()->spread());
3378 QCOMPARE(((QConicalGradient *)cGrad.gradient())->center(), ((QConicalGradient *)conicalBrush.gradient())->center());
3379 QCOMPARE(((QConicalGradient *)cGrad.gradient())->angle(), ((QConicalGradient *)conicalBrush.gradient())->angle());
3380
3381 QCOMPARE(cGrad, conicalBrush);
3382 stream >> pen;
3383 QCOMPARE(pen.widthF(), qreal(1.5));
3384
3385 QCOMPARE(stream.status(), QDataStream::Ok);
3386 }
3387}
3388
3389void tst_QDataStream::compatibility_Qt5()
3390{
3391 QLinearGradient gradient(QPointF(0,0), QPointF(1,1));
3392 gradient.setColorAt(pos: 0, color: Qt::red);
3393 gradient.setColorAt(pos: 1, color: Qt::blue);
3394
3395 QBrush brush(gradient);
3396 QPalette palette;
3397 palette.setBrush(acr: QPalette::Button, abrush: brush);
3398 palette.setColor(acr: QPalette::Light, acolor: Qt::green);
3399
3400 QByteArray stream;
3401 {
3402 QDataStream out(&stream, QIODevice::WriteOnly);
3403 out.setVersion(QDataStream::Qt_5_7);
3404 out << palette;
3405 out << brush;
3406 }
3407 QBrush in_brush;
3408 QPalette in_palette;
3409 {
3410 QDataStream in(stream);
3411 in.setVersion(QDataStream::Qt_5_7);
3412 in >> in_palette;
3413 in >> in_brush;
3414 }
3415 QCOMPARE(in_brush.style(), Qt::LinearGradientPattern);
3416 QCOMPARE(in_palette.brush(QPalette::Button).style(), Qt::LinearGradientPattern);
3417 QCOMPARE(in_palette.color(QPalette::Light), QColor(Qt::green));
3418}
3419
3420void tst_QDataStream::compatibility_Qt3()
3421{
3422 QByteArray ba("hello");
3423 QVariant var = ba;
3424 const quint32 invalidColor = 0x49000000;
3425 QByteArray stream;
3426 {
3427 QDataStream out(&stream, QIODevice::WriteOnly);
3428 out.setVersion(QDataStream::Qt_3_3);
3429 out << var;
3430 out << QColor();
3431 out << QColor(Qt::darkYellow);
3432 out << QColor(Qt::darkCyan);
3433 out << invalidColor;
3434 }
3435 {
3436 QDataStream in(stream);
3437 in.setVersion(QDataStream::Qt_3_3);
3438
3439 quint32 type;
3440 in >> type;
3441 //29 is the type of a QByteArray in Qt3
3442 QCOMPARE(type, quint32(29));
3443 QByteArray ba2;
3444 in >> ba2;
3445 QCOMPARE(ba2, ba);
3446
3447 quint32 color;
3448 in >> color;
3449 QCOMPARE(color, invalidColor);
3450 in >> color;
3451 QCOMPARE(color, QColor(Qt::darkYellow).rgb());
3452 QColor col;
3453 in >> col;
3454 QCOMPARE(col, QColor(Qt::darkCyan));
3455 in >> col;
3456 QVERIFY(!col.isValid());
3457 }
3458 {
3459 QLinearGradient gradient(QPointF(0,0), QPointF(1,1));
3460 gradient.setColorAt(pos: 0, color: Qt::red);
3461 gradient.setColorAt(pos: 1, color: Qt::blue);
3462
3463 QBrush brush(gradient);
3464 QPalette palette;
3465 palette.setBrush(acr: QPalette::Button, abrush: brush);
3466 palette.setColor(acr: QPalette::Light, acolor: Qt::green);
3467
3468 QByteArray stream;
3469 {
3470 QDataStream out(&stream, QIODevice::WriteOnly);
3471 out.setVersion(QDataStream::Qt_3_3);
3472 out << palette;
3473 out << brush;
3474 }
3475 QBrush in_brush;
3476 QPalette in_palette;
3477 {
3478 QDataStream in(stream);
3479 in.setVersion(QDataStream::Qt_3_3);
3480 in >> in_palette;
3481 in >> in_brush;
3482 }
3483 QCOMPARE(in_brush.style(), Qt::NoBrush);
3484 QCOMPARE(in_palette.brush(QPalette::Button).style(), Qt::NoBrush);
3485 QCOMPARE(in_palette.color(QPalette::Light), QColor(Qt::green));
3486 }
3487 // QTime() was serialized to (0, 0, 0, 0) in Qt3, not (0xFF, 0xFF, 0xFF, 0xFF)
3488 // This is because in Qt3 a null time was valid, and there was no support for deserializing a value of -1.
3489 {
3490 QByteArray stream;
3491 {
3492 QDataStream out(&stream, QIODevice::WriteOnly);
3493 out.setVersion(QDataStream::Qt_3_3);
3494 out << QTime();
3495 }
3496 QTime in_time;
3497 {
3498 QDataStream in(stream);
3499 in.setVersion(QDataStream::Qt_3_3);
3500 in >> in_time;
3501 }
3502 QVERIFY(in_time.isNull());
3503
3504 quint32 rawValue;
3505 QDataStream in(stream);
3506 in.setVersion(QDataStream::Qt_3_3);
3507 in >> rawValue;
3508 QCOMPARE(rawValue, quint32(0));
3509 }
3510
3511}
3512
3513void tst_QDataStream::compatibility_Qt2()
3514{
3515 QLinearGradient gradient(QPointF(0,0), QPointF(1,1));
3516 gradient.setColorAt(pos: 0, color: Qt::red);
3517 gradient.setColorAt(pos: 1, color: Qt::blue);
3518
3519 QBrush brush(gradient);
3520 QPalette palette;
3521 palette.setBrush(acr: QPalette::Button, abrush: brush);
3522 palette.setColor(acr: QPalette::Light, acolor: Qt::green);
3523
3524 QByteArray stream;
3525 {
3526 QDataStream out(&stream, QIODevice::WriteOnly);
3527 out.setVersion(QDataStream::Qt_2_1);
3528 out << palette;
3529 out << brush;
3530 }
3531 QBrush in_brush;
3532 QPalette in_palette;
3533 {
3534 QDataStream in(stream);
3535 in.setVersion(QDataStream::Qt_2_1);
3536 in >> in_palette;
3537 in >> in_brush;
3538 }
3539 QCOMPARE(in_brush.style(), Qt::NoBrush);
3540 QCOMPARE(in_palette.brush(QPalette::Button).style(), Qt::NoBrush);
3541 QCOMPARE(in_palette.color(QPalette::Light), QColor(Qt::green));
3542}
3543
3544void tst_QDataStream::floatingPointNaN()
3545{
3546 QDataStream::ByteOrder bo = QSysInfo::ByteOrder == QSysInfo::BigEndian
3547 ? QDataStream::LittleEndian
3548 : QDataStream::BigEndian;
3549
3550 // Test and verify that values that become (s)nan's after swapping endianness
3551 // don't change in the process.
3552 // When compiling with e.g., MSVC (32bit) and when the fpu is used (fp:precise)
3553 // all snan's will be converted to qnan's (default behavior).
3554 // IF we get a snan after swapping endianness we can not copy the value to another
3555 // float as this will cause the value to differ from the original value.
3556 QByteArray ba;
3557
3558 union {
3559 float f;
3560 quint32 i;
3561 } xs[2];
3562
3563 xs[0].i = qbswap<quint32>(source: 0xff800001);
3564 xs[1].i = qbswap<quint32>(source: 0x7f800001);
3565
3566 {
3567 QDataStream stream(&ba, QIODevice::WriteOnly);
3568 stream.setByteOrder(bo);
3569 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
3570 stream << xs[0].f;
3571 stream << xs[1].f;
3572 }
3573
3574 {
3575 QDataStream stream(ba);
3576 stream.setByteOrder(bo);
3577 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
3578 float fr = 0.0f;
3579 stream >> fr;
3580 QCOMPARE(fr, xs[0].f);
3581 stream >> fr;
3582 QCOMPARE(fr, xs[1].f);
3583 }
3584}
3585
3586void tst_QDataStream::enumTest()
3587{
3588 QByteArray ba;
3589
3590 enum class E1 : qint8
3591 {
3592 A,
3593 B,
3594 C
3595 };
3596 {
3597 QDataStream stream(&ba, QIODevice::WriteOnly);
3598 stream << E1::A;
3599 QCOMPARE(ba.size(), int(sizeof(E1)));
3600 }
3601 {
3602 QDataStream stream(ba);
3603 E1 e;
3604 stream >> e;
3605 QCOMPARE(e, E1::A);
3606 }
3607 ba.clear();
3608
3609 enum class E2 : qint16
3610 {
3611 A,
3612 B,
3613 C
3614 };
3615 {
3616 QDataStream stream(&ba, QIODevice::WriteOnly);
3617 stream << E2::B;
3618 QCOMPARE(ba.size(), int(sizeof(E2)));
3619 }
3620 {
3621 QDataStream stream(ba);
3622 E2 e;
3623 stream >> e;
3624 QCOMPARE(e, E2::B);
3625 }
3626 ba.clear();
3627
3628 enum class E4 : qint32
3629 {
3630 A,
3631 B,
3632 C
3633 };
3634 {
3635 QDataStream stream(&ba, QIODevice::WriteOnly);
3636 stream << E4::C;
3637 QCOMPARE(ba.size(), int(sizeof(E4)));
3638 }
3639 {
3640 QDataStream stream(ba);
3641 E4 e;
3642 stream >> e;
3643 QCOMPARE(e, E4::C);
3644 }
3645 ba.clear();
3646
3647
3648 enum E
3649 {
3650 A,
3651 B,
3652 C,
3653 D
3654 };
3655 {
3656 QDataStream stream(&ba, QIODevice::WriteOnly);
3657 stream << E::D;
3658 QCOMPARE(ba.size(), 4);
3659 }
3660 {
3661 QDataStream stream(ba);
3662 E e;
3663 stream >> e;
3664 QCOMPARE(e, E::D);
3665 }
3666 ba.clear();
3667
3668}
3669
3670void tst_QDataStream::floatingPointPrecision()
3671{
3672 QByteArray ba;
3673 {
3674 QDataStream stream(&ba, QIODevice::WriteOnly);
3675 QCOMPARE(QDataStream::DoublePrecision, stream.floatingPointPrecision());
3676
3677 float f = 123.0f;
3678 stream << f;
3679 QCOMPARE(ba.size(), int(sizeof(double)));
3680
3681 double d = 234.0;
3682 stream << d;
3683 QCOMPARE(ba.size(), int(sizeof(double)*2));
3684
3685 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
3686
3687 f = 123.0f;
3688 stream << f;
3689 QCOMPARE(ba.size(), int(sizeof(double)*2 + sizeof(float)));
3690
3691 d = 234.0;
3692 stream << d;
3693 QCOMPARE(ba.size(), int(sizeof(double)*2 + sizeof(float)*2));
3694 }
3695
3696 {
3697 QDataStream stream(ba);
3698
3699 float f = 0.0f;
3700 stream >> f;
3701 QCOMPARE(123.0f, f);
3702
3703 double d = 0.0;
3704 stream >> d;
3705 QCOMPARE(234.0, d);
3706
3707 f = 0.0f;
3708 stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
3709 stream >> f;
3710 QCOMPARE(123.0f, f);
3711
3712 d = 0.0;
3713 stream >> d;
3714 QCOMPARE(234.0, d);
3715 }
3716
3717}
3718
3719void tst_QDataStream::transaction_data()
3720{
3721 QTest::addColumn<qint8>(name: "i8Data");
3722 QTest::addColumn<qint16>(name: "i16Data");
3723 QTest::addColumn<qint32>(name: "i32Data");
3724 QTest::addColumn<qint64>(name: "i64Data");
3725 QTest::addColumn<bool>(name: "bData");
3726 QTest::addColumn<float>(name: "fData");
3727 QTest::addColumn<double>(name: "dData");
3728 QTest::addColumn<QImage>(name: "imgData");
3729 QTest::addColumn<QByteArray>(name: "strData");
3730 QTest::addColumn<QByteArray>(name: "rawData");
3731
3732 QImage img1(open_xpm);
3733 QImage img2;
3734 QImage img3(50, 50, QImage::Format_ARGB32);
3735 img3.fill(pixel: qRgba(r: 12, g: 34, b: 56, a: 78));
3736
3737 QTest::newRow(dataTag: "1") << qint8(1) << qint16(2) << qint32(3) << qint64(4) << true << 5.0f
3738 << double(6.0) << img1 << QByteArray("Hello world!") << QByteArray("Qt rocks!");
3739 QTest::newRow(dataTag: "2") << qint8(1 << 6) << qint16(1 << 14) << qint32(1 << 30) << qint64Data(index: 3) << false << 123.0f
3740 << double(234.0) << img2 << stringData(index: 5).toUtf8() << stringData(index: 6).toUtf8();
3741 QTest::newRow(dataTag: "3") << qint8(-1) << qint16(-2) << qint32(-3) << qint64(-4) << true << -123.0f
3742 << double(-234.0) << img3 << stringData(index: 3).toUtf8() << stringData(index: 4).toUtf8();
3743}
3744
3745void tst_QDataStream::transaction()
3746{
3747 QByteArray testBuffer;
3748
3749 QFETCH(qint8, i8Data);
3750 QFETCH(qint16, i16Data);
3751 QFETCH(qint32, i32Data);
3752 QFETCH(qint64, i64Data);
3753 QFETCH(bool, bData);
3754 QFETCH(float, fData);
3755 QFETCH(double, dData);
3756 QFETCH(QImage, imgData);
3757 QFETCH(QByteArray, strData);
3758 QFETCH(QByteArray, rawData);
3759
3760 {
3761 QDataStream stream(&testBuffer, QIODevice::WriteOnly);
3762
3763 stream << i8Data << i16Data << i32Data << i64Data
3764 << bData << fData << dData << imgData << strData.constData();
3765 stream.writeRawData(rawData.constData(), len: rawData.size());
3766 }
3767
3768 for (int splitPos = 0; splitPos <= testBuffer.size(); ++splitPos) {
3769 QByteArray readBuffer(testBuffer.left(len: splitPos));
3770
3771 SequentialBuffer dev(&readBuffer);
3772 dev.open(mode: QIODevice::ReadOnly);
3773 QDataStream stream(&dev);
3774
3775 qint8 i8;
3776 qint16 i16;
3777 qint32 i32;
3778 qint64 i64;
3779 bool b;
3780 float f;
3781 double d;
3782 QImage img;
3783 char *str;
3784 QByteArray raw(rawData.size(), 0);
3785
3786 forever {
3787 stream.startTransaction();
3788 stream >> i8 >> i16 >> i32 >> i64 >> b >> f >> d >> img >> str;
3789 stream.readRawData(raw.data(), len: raw.size());
3790
3791 if (stream.commitTransaction())
3792 break;
3793
3794 QVERIFY(stream.status() == QDataStream::ReadPastEnd);
3795 QVERIFY(splitPos == 0 || !stream.atEnd());
3796 QVERIFY(readBuffer.size() < testBuffer.size());
3797 delete [] str;
3798 raw.fill(c: 0);
3799 readBuffer.append(a: testBuffer.right(len: testBuffer.size() - splitPos));
3800 }
3801
3802 QVERIFY(stream.atEnd());
3803 QCOMPARE(i8, i8Data);
3804 QCOMPARE(i16, i16Data);
3805 QCOMPARE(i32, i32Data);
3806 QCOMPARE(i64, i64Data);
3807 QCOMPARE(b, bData);
3808 QCOMPARE(f, fData);
3809 QCOMPARE(d, dData);
3810 QCOMPARE(img, imgData);
3811 QVERIFY(strData == str);
3812 delete [] str;
3813 QCOMPARE(raw, rawData);
3814 }
3815}
3816
3817void tst_QDataStream::nestedTransactionsResult_data()
3818{
3819 QTest::addColumn<bool>(name: "commitFirst");
3820 QTest::addColumn<bool>(name: "rollbackFirst");
3821 QTest::addColumn<bool>(name: "commitSecond");
3822 QTest::addColumn<bool>(name: "rollbackSecond");
3823 QTest::addColumn<bool>(name: "successExpected");
3824 QTest::addColumn<bool>(name: "expectedAtEnd");
3825 QTest::addColumn<int>(name: "expectedStatus");
3826
3827 QTest::newRow(dataTag: "1") << false << false << false << false
3828 << false << true << int(QDataStream::ReadCorruptData);
3829 QTest::newRow(dataTag: "2") << false << false << false << true
3830 << false << true << int(QDataStream::ReadCorruptData);
3831 QTest::newRow(dataTag: "3") << false << false << true << false
3832 << false << true << int(QDataStream::ReadCorruptData);
3833
3834 QTest::newRow(dataTag: "4") << false << true << false << false
3835 << false << true << int(QDataStream::ReadCorruptData);
3836 QTest::newRow(dataTag: "5") << false << true << false << true
3837 << false << false << int(QDataStream::ReadPastEnd);
3838 QTest::newRow(dataTag: "6") << false << true << true << false
3839 << false << false << int(QDataStream::ReadPastEnd);
3840
3841 QTest::newRow(dataTag: "7") << true << false << false << false
3842 << false << true << int(QDataStream::ReadCorruptData);
3843 QTest::newRow(dataTag: "8") << true << false << false << true
3844 << false << false << int(QDataStream::ReadPastEnd);
3845 QTest::newRow(dataTag: "9") << true << false << true << false
3846 << true << true << int(QDataStream::Ok);
3847}
3848
3849void tst_QDataStream::nestedTransactionsResult()
3850{
3851 QByteArray testBuffer(1, 0);
3852 QDataStream stream(&testBuffer, QIODevice::ReadOnly);
3853 uchar c;
3854
3855 QFETCH(bool, commitFirst);
3856 QFETCH(bool, rollbackFirst);
3857 QFETCH(bool, commitSecond);
3858 QFETCH(bool, rollbackSecond);
3859 QFETCH(bool, successExpected);
3860 QFETCH(bool, expectedAtEnd);
3861 QFETCH(int, expectedStatus);
3862
3863 stream.startTransaction();
3864 stream.startTransaction();
3865 stream >> c;
3866
3867 if (commitFirst)
3868 QVERIFY(stream.commitTransaction());
3869 else if (rollbackFirst)
3870 stream.rollbackTransaction();
3871 else
3872 stream.abortTransaction();
3873
3874 stream.startTransaction();
3875
3876 if (commitSecond)
3877 QCOMPARE(stream.commitTransaction(), commitFirst);
3878 else if (rollbackSecond)
3879 stream.rollbackTransaction();
3880 else
3881 stream.abortTransaction();
3882
3883 QCOMPARE(stream.commitTransaction(), successExpected);
3884 QCOMPARE(stream.atEnd(), expectedAtEnd);
3885 QCOMPARE(int(stream.status()), expectedStatus);
3886}
3887
3888QTEST_MAIN(tst_QDataStream)
3889#include "tst_qdatastream.moc"
3890
3891

source code of qtbase/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp