diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2018-10-02 12:36:04 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2018-10-15 07:18:57 +0000 |
commit | f2f040ae1c4fe48bff68bb45b2e20308fa895c50 (patch) | |
tree | 19818b75f10a14af8e8c5ce39d8af966f31a575b /tests | |
parent | 0479379d2463ff44c54e774d41746fb1500cf481 (diff) | |
download | qtbase-f2f040ae1c4fe48bff68bb45b2e20308fa895c50.tar.gz |
Improve support for QImages in QDataStream read transactions
QImage's operator>>(QDataStream&) did not set an error mode on the
stream on read failures. That would break QDataStream transactions.
Since the current QImage serialization cannot differentiate between
truncated and corrupted data, we set the ReadPastEnd error as expected
by the transaction system.
Also specify the expected file format on decoding QImage from stream,
to avoid all the format handlers' canRead() being invoked. This is
necessary since some of them may call ungetChar(), which fails when
the stream is in a transaction.
Also add testing of this feature to the QDataStram transaction
autotest. That required a slight rewrite of the fake sequential
QIODevice subclass. The previous implementation had incorrect
behavior of peek(), which is required by QImage decoders.
Task-number: QTBUG-70875
Change-Id: If3f1ca7186ad1e6ca0e6e8ea81d2b2fbece6ea01
Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index c6faf8c7d5..011a0e1a85 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -2211,25 +2211,22 @@ void tst_QDataStream::setVersion() } } -class SequentialBuffer : public QBuffer +class SequentialBuffer : public QIODevice { public: - SequentialBuffer(QByteArray *data) : QBuffer(data) { offset = 0; } + SequentialBuffer(QByteArray *data) : QIODevice() { buf.setBuffer(data); } - bool isSequential() const { return true; } - bool seek(qint64 pos) { offset = pos; return QBuffer::seek(pos); } - qint64 pos() const { return qint64(offset); } + bool isSequential() const override { return true; } + bool open(OpenMode mode) override { return buf.open(mode) && QIODevice::open(mode | QIODevice::Unbuffered); } + void close() override { buf.close(); QIODevice::close(); } + qint64 bytesAvailable() const override { return QIODevice::bytesAvailable() + buf.bytesAvailable(); } protected: - qint64 readData(char *data, qint64 maxSize) - { - qint64 ret = QBuffer::readData(data, maxSize); - offset += ret; - return ret; - } + qint64 readData(char *data, qint64 maxSize) override { return buf.read(data, maxSize); } + qint64 writeData(const char *data, qint64 maxSize) override { return buf.write(data, maxSize); } private: - int offset; + QBuffer buf; }; void tst_QDataStream::skipRawData_data() @@ -3329,15 +3326,21 @@ void tst_QDataStream::transaction_data() QTest::addColumn<bool>("bData"); QTest::addColumn<float>("fData"); QTest::addColumn<double>("dData"); + QTest::addColumn<QImage>("imgData"); QTest::addColumn<QByteArray>("strData"); QTest::addColumn<QByteArray>("rawData"); + QImage img1(open_xpm); + QImage img2; + QImage img3(50, 50, QImage::Format_ARGB32); + img3.fill(qRgba(12, 34, 56, 78)); + QTest::newRow("1") << qint8(1) << qint16(2) << qint32(3) << qint64(4) << true << 5.0f - << double(6.0) << QByteArray("Hello world!") << QByteArray("Qt rocks!"); + << double(6.0) << img1 << QByteArray("Hello world!") << QByteArray("Qt rocks!"); QTest::newRow("2") << qint8(1 << 6) << qint16(1 << 14) << qint32(1 << 30) << qint64Data(3) << false << 123.0f - << double(234.0) << stringData(5).toUtf8() << stringData(6).toUtf8(); + << double(234.0) << img2 << stringData(5).toUtf8() << stringData(6).toUtf8(); QTest::newRow("3") << qint8(-1) << qint16(-2) << qint32(-3) << qint64(-4) << true << -123.0f - << double(-234.0) << stringData(3).toUtf8() << stringData(4).toUtf8(); + << double(-234.0) << img3 << stringData(3).toUtf8() << stringData(4).toUtf8(); } void tst_QDataStream::transaction() @@ -3351,6 +3354,7 @@ void tst_QDataStream::transaction() QFETCH(bool, bData); QFETCH(float, fData); QFETCH(double, dData); + QFETCH(QImage, imgData); QFETCH(QByteArray, strData); QFETCH(QByteArray, rawData); @@ -3358,12 +3362,13 @@ void tst_QDataStream::transaction() QDataStream stream(&testBuffer, QIODevice::WriteOnly); stream << i8Data << i16Data << i32Data << i64Data - << bData << fData << dData << strData.constData(); + << bData << fData << dData << imgData << strData.constData(); stream.writeRawData(rawData.constData(), rawData.size()); } for (int splitPos = 0; splitPos <= testBuffer.size(); ++splitPos) { QByteArray readBuffer(testBuffer.left(splitPos)); + SequentialBuffer dev(&readBuffer); dev.open(QIODevice::ReadOnly); QDataStream stream(&dev); @@ -3375,12 +3380,13 @@ void tst_QDataStream::transaction() bool b; float f; double d; + QImage img; char *str; QByteArray raw(rawData.size(), 0); forever { stream.startTransaction(); - stream >> i8 >> i16 >> i32 >> i64 >> b >> f >> d >> str; + stream >> i8 >> i16 >> i32 >> i64 >> b >> f >> d >> img >> str; stream.readRawData(raw.data(), raw.size()); if (stream.commitTransaction()) @@ -3402,6 +3408,7 @@ void tst_QDataStream::transaction() QCOMPARE(b, bData); QCOMPARE(f, fData); QCOMPARE(d, dData); + QCOMPARE(img, imgData); QVERIFY(strData == str); delete [] str; QCOMPARE(raw, rawData); |