From cfd3c84184c7be2e1e3c4a8be51a1a45cb61a18e Mon Sep 17 00:00:00 2001 From: Tatiana Borisova Date: Wed, 4 Dec 2024 16:40:28 +0100 Subject: [PATCH] [QTextStream] Add operator bool() to QTextStream class - Add operator bool() that checks whether the associated stream has no error status. This operator makes it possible to use streams and functions that return references to streams as loop conditions: `while (stream >> text)`. - Add testcase for testing the new operator. - Update existing testcases that use or can use the status of stream operations. [ChangeLog][QtCore][QTextStream] Added implicit conversion to bool, returning `status() == Ok`. Task-number: QTBUG-52189 Change-Id: I21cbe02ec194078304bcfe606a6f2f572dd09c84 Reviewed-by: Marc Mutz --- src/corelib/serialization/qtextstream.cpp | 7 + src/corelib/serialization/qtextstream.h | 2 + .../qtextstream/tst_qtextstream.cpp | 403 ++++++++++-------- 3 files changed, 241 insertions(+), 171 deletions(-) diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index 6373a500fa1..13a8d20a305 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -2556,6 +2556,13 @@ QTextStream &QTextStream::operator<<(const void *ptr) return *this; } +/*! + \fn QTextStream::operator bool() const + \since 6.10 + + Returns whether this stream has no errors (status() == \l{OK}). +*/ + namespace Qt { /*! diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h index 84fa14ec5ed..2b4caf549c7 100644 --- a/src/corelib/serialization/qtextstream.h +++ b/src/corelib/serialization/qtextstream.h @@ -170,6 +170,8 @@ public: QTextStream &operator<<(const char *c); QTextStream &operator<<(const void *ptr); + explicit operator bool() const noexcept { return status() == Ok; } + private: Q_DISABLE_COPY(QTextStream) friend class QDebugStateSaverPrivate; diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp index 1fb69680291..cd0e30f9536 100644 --- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp @@ -142,6 +142,9 @@ private slots: void stringref_write_operator_ToDevice(); void stringview_write_operator_ToDevice(); + // bool operator + void stream_bool_operator_Test(); + // other void skipWhiteSpace_data(); void skipWhiteSpace(); @@ -694,11 +697,11 @@ void tst_QTextStream::setDevice() QString text; QTextStream stream(&bufferOld); - stream >> text; + QVERIFY(stream >> text); QCOMPARE(text, QString("Hello")); stream.setDevice(&bufferNew); - stream >> text; + QVERIFY(stream >> text); QCOMPARE(text, QString("How")); } @@ -730,8 +733,7 @@ void tst_QTextStream::readLineFromTextDevice() if (i & 1) { QChar c; while (!stream.atEnd()) { - stream >> c; - if (stream.status() == QTextStream::Ok) { + if (stream >> c) { if (c != QLatin1Char('\n') && c != QLatin1Char('\r')) line += c; if (c == QLatin1Char('\n')) @@ -1111,7 +1113,7 @@ void tst_QTextStream::binTest() QByteArray array; QTextStream stream(&array); - stream << Qt::showbase << Qt::bin << number; + QVERIFY(stream << Qt::showbase << Qt::bin << number); stream.flush(); QCOMPARE(array.constData(), data.constData()); } @@ -1134,7 +1136,7 @@ void tst_QTextStream::octTest() QByteArray array; QTextStream stream(&array); - stream << Qt::showbase << Qt::oct << number; + QVERIFY(stream << Qt::showbase << Qt::oct << number); stream.flush(); QCOMPARE(array, data); } @@ -1146,13 +1148,13 @@ void tst_QTextStream::zeroTermination() char c = '@'; QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device"); - stream >> c; + QVERIFY(stream >> c); QCOMPARE(c, '\0'); c = '@'; QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device"); - stream >> &c; + QVERIFY(stream >> &c); QCOMPARE(c, '\0'); } @@ -1164,7 +1166,7 @@ void tst_QTextStream::ws_manipulator() QTextStream stream(&string); char a, b, c, d; - stream >> a >> b >> c >> d; + QVERIFY(stream >> a >> b >> c >> d); QCOMPARE(a, 'a'); QCOMPARE(b, ' '); QCOMPARE(c, 'b'); @@ -1175,7 +1177,7 @@ void tst_QTextStream::ws_manipulator() QTextStream stream(&string); char a, b, c, d; - stream >> a >> Qt::ws >> b >> Qt::ws >> c >> Qt::ws >> d; + QVERIFY(stream >> a >> Qt::ws >> b >> Qt::ws >> c >> Qt::ws >> d); QCOMPARE(a, 'a'); QCOMPARE(b, 'b'); QCOMPARE(c, 'c'); @@ -1244,42 +1246,42 @@ void tst_QTextStream::seek() QTextStream stream(&file); QString tmp; - stream >> tmp; + QVERIFY(stream >> tmp); QCOMPARE(tmp, QString::fromLatin1("Network")); // QTextStream::seek(0) should both clear its internal read/write buffers // and seek the device. for (int i = 0; i < 4; ++i) { stream.seek(12 + i); - stream >> tmp; + QVERIFY(stream >> tmp); QCOMPARE(tmp, QString("Network").mid(i)); } for (int i = 0; i < 4; ++i) { stream.seek(16 - i); - stream >> tmp; + QVERIFY(stream >> tmp); QCOMPARE(tmp, QString("Network").mid(4 - i)); } stream.seek(139181); - stream >> tmp; + QVERIFY(stream >> tmp); QCOMPARE(tmp, QString("information")); stream.seek(388683); - stream >> tmp; + QVERIFY(stream >> tmp); QCOMPARE(tmp, QString("telephone")); // Also test this with a string QString words = QLatin1String("thisisa"); QTextStream stream2(&words, QIODevice::ReadOnly); - stream2 >> tmp; + QVERIFY(stream2 >> tmp); QCOMPARE(tmp, QString::fromLatin1("thisisa")); for (int i = 0; i < 4; ++i) { stream2.seek(i); - stream2 >> tmp; + QVERIFY(stream2 >> tmp); QCOMPARE(tmp, QString("thisisa").mid(i)); } for (int i = 0; i < 4; ++i) { stream2.seek(4 - i); - stream2 >> tmp; + QVERIFY(stream2 >> tmp); QCOMPARE(tmp, QString("thisisa").mid(4 - i)); } } @@ -1305,7 +1307,7 @@ void tst_QTextStream::pos() QVERIFY(stream.seek(0)); QChar ch; - stream >> ch; + QVERIFY(stream >> ch); QCOMPARE(ch, QChar('t')); QCOMPARE(stream.pos(), qint64(1)); @@ -1314,19 +1316,19 @@ void tst_QTextStream::pos() QVERIFY(stream.seek(0)); QString strtmp; - stream >> strtmp; + QVERIFY(stream >> strtmp); QCOMPARE(strtmp, QString("this")); QCOMPARE(stream.pos(), qint64(4)); stream.seek(0); stream.seek(4); - stream >> ch; + QVERIFY(stream >> ch); QCOMPARE(ch, QChar(' ')); QCOMPARE(stream.pos(), qint64(5)); stream.seek(10); - stream >> strtmp; + QVERIFY(stream >> strtmp); QCOMPARE(strtmp, QString("test")); QCOMPARE(stream.pos(), qint64(14)); } @@ -1351,13 +1353,13 @@ void tst_QTextStream::pos() stream.seek(0); QString strtmp; - stream >> strtmp; + QVERIFY(stream >> strtmp); QCOMPARE(strtmp, QString("Network")); QCOMPARE(stream.pos(), qint64(19)); stream.seek(2598); QCOMPARE(stream.pos(), qint64(2598)); - stream >> strtmp; + QVERIFY(stream >> strtmp); QCOMPARE(stream.pos(), qint64(2607)); QCOMPARE(strtmp, QString("locations")); } @@ -1375,28 +1377,28 @@ void tst_QTextStream::pos2() QChar ch; QCOMPARE(stream.pos(), qint64(0)); - stream >> ch; + QVERIFY(stream >> ch); QCOMPARE(ch, QChar('a')); QCOMPARE(stream.pos(), qint64(1)); QString str; - stream >> str; + QVERIFY(stream >> str); QCOMPARE(str, QString("bcdef")); QCOMPARE(stream.pos(), qint64(6)); - stream >> str; + QVERIFY(stream >> str); QCOMPARE(str, QString("ghijkl")); QCOMPARE(stream.pos(), qint64(14)); // Seek back and try again stream.seek(1); QCOMPARE(stream.pos(), qint64(1)); - stream >> str; + QVERIFY(stream >> str); QCOMPARE(str, QString("bcdef")); QCOMPARE(stream.pos(), qint64(6)); stream.seek(6); - stream >> str; + QVERIFY(stream >> str); QCOMPARE(str, QString("ghijkl")); QCOMPARE(stream.pos(), qint64(14)); } @@ -1416,7 +1418,7 @@ void tst_QTextStream::pos3LargeFile() // Approximate 50kb text file const int NbLines = (50*1024) / lineString.size() + 1; for (int line = 0; line < NbLines; ++line) - out << lineString; + QVERIFY(out << lineString); // File is automatically flushed and closed on destruction. } QFile file(testFileName); @@ -1427,8 +1429,7 @@ void tst_QTextStream::pos3LargeFile() while (true) { in.pos(); for ( int i = 0; i < 10; ++i ) { - in >> value; - if (in.status() != QTextStream::Ok) { + if (!(in >> value)) { // End case, i == 0 && eof reached. QCOMPARE(i, 0); QCOMPARE(in.status(), QTextStream::ReadPastEnd); @@ -1450,16 +1451,16 @@ void tst_QTextStream::readStdin() stdinProcess.setReadChannel(QProcess::StandardError); QTextStream stream(&stdinProcess); - stream << "1" << Qt::endl; - stream << "2" << Qt::endl; - stream << "3" << Qt::endl; + QVERIFY(stream << "1" << Qt::endl); + QVERIFY(stream << "2" << Qt::endl); + QVERIFY(stream << "3" << Qt::endl); stdinProcess.closeWriteChannel(); QVERIFY(stdinProcess.waitForFinished(5000)); int a, b, c; - stream >> a >> b >> c; + QVERIFY(stream >> a >> b >> c); QCOMPARE(a, 1); QCOMPARE(b, 2); QCOMPARE(c, 3); @@ -1478,7 +1479,7 @@ void tst_QTextStream::readAllFromStdin() QTextStream stream(&stdinProcess); stream.setEncoding(QStringConverter::Latin1); - stream << "hello world" << Qt::flush; + QVERIFY(stream << "hello world" << Qt::flush); stdinProcess.closeWriteChannel(); @@ -1558,7 +1559,7 @@ void tst_QTextStream::qbool() { QString s; QTextStream stream(&s); - stream << s.contains(QString("hei")); + QVERIFY(stream << s.contains(QString("hei"))); QCOMPARE(s, QString("0")); } @@ -1567,18 +1568,20 @@ void tst_QTextStream::forcePoint() { QString str; QTextStream stream(&str); - stream << Qt::fixed << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1; + QVERIFY(stream << Qt::fixed << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 + << ' ' << -1.0 << ' ' << -1); QCOMPARE(str, QString("1.000000 1 0 -1.000000 -1")); str.clear(); stream.seek(0); - stream << Qt::scientific << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1; + QVERIFY(stream << Qt::scientific << Qt::forcepoint << 1.0 << ' ' << 1 + << ' ' << 0 << ' ' << -1.0 << ' ' << -1); QCOMPARE(str, QString("1.000000e+00 1 0 -1.000000e+00 -1")); str.clear(); stream.seek(0); stream.setRealNumberNotation(QTextStream::SmartNotation); - stream << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1; + QVERIFY(stream << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1); QCOMPARE(str, QString("1.00000 1 0 -1.00000 -1")); } @@ -1588,7 +1591,7 @@ void tst_QTextStream::forceSign() { QString str; QTextStream stream(&str); - stream << Qt::forcesign << 1.2 << ' ' << -1.2 << ' ' << 0; + QVERIFY(stream << Qt::forcesign << 1.2 << ' ' << -1.2 << ' ' << 0); QCOMPARE(str, QString("+1.2 -1.2 +0")); } @@ -1670,7 +1673,7 @@ void tst_QTextStream::numeralCase() QString str; QTextStream stream(&str); - stream << func1 << func2 << func3 << func4 << value; + QVERIFY(stream << func1 << func2 << func3 << func4 << value); QCOMPARE(str, expected); } @@ -1685,53 +1688,53 @@ void tst_QTextStream::nanInf() QTextStream stream(&str); double tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; - stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsNaN(tmpD)); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; + QVERIFY(stream >> tmpD); QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; stream.seek(0); float tmpF = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0; - stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsNaN(tmpF)); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0; + QVERIFY(stream >> tmpF); QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); QString s; QTextStream out(&s); - out << qInf() << ' ' << -qInf() << ' ' << qQNaN() - << Qt::uppercasedigits << ' ' - << qInf() << ' ' << -qInf() << ' ' << qQNaN() - << Qt::flush; + QVERIFY(out << qInf() << ' ' << -qInf() << ' ' << qQNaN() + << Qt::uppercasedigits << ' ' + << qInf() << ' ' << -qInf() << ' ' << qQNaN() + << Qt::flush); QCOMPARE(s, QString("inf -inf nan INF -INF NAN")); } @@ -1767,7 +1770,7 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary() out.setFieldWidth(3); for (int i = 0; i < 1000; ++i) { - out << i << lineContents << Qt::endl; + QVERIFY(out << i << lineContents << Qt::endl); } } data.close(); @@ -1805,9 +1808,9 @@ void tst_QTextStream::writeSeekWriteNoBOM() int number = 0; QString sizeStr = QLatin1String("Size=") + QString::number(number).rightJustified(10, QLatin1Char('0')); - stream << sizeStr << Qt::endl; - stream << "Version=" << QString::number(14) << Qt::endl; - stream << "blah blah blah" << Qt::endl; + QVERIFY(stream << sizeStr << Qt::endl); + QVERIFY(stream << "Version=" << QString::number(14) << Qt::endl); + QVERIFY(stream << "blah blah blah" << Qt::endl); stream.flush(); QCOMPARE(out.buffer().constData(), "Size=0000000000\nVersion=14\nblah blah blah\n"); @@ -1817,7 +1820,7 @@ void tst_QTextStream::writeSeekWriteNoBOM() stream.seek(0); sizeStr = QLatin1String("Size=") + QString::number(number).rightJustified(10, QLatin1Char('0')); - stream << sizeStr << Qt::endl; + QVERIFY(stream << sizeStr << Qt::endl); stream.flush(); // Check buffer is still OK @@ -1831,14 +1834,14 @@ void tst_QTextStream::writeSeekWriteNoBOM() QTextStream stream16(&out16); stream16.setEncoding(QStringConverter::Utf16); - stream16 << "one" << "two" << QLatin1String("three"); + QVERIFY(stream16 << "one" << "two" << QLatin1String("three")); stream16.flush(); // save that output QByteArray first = out16.buffer(); stream16.seek(0); - stream16 << "one"; + QVERIFY(stream16 << "one"); stream16.flush(); QCOMPARE(out16.buffer(), first); @@ -1851,19 +1854,30 @@ void tst_QTextStream::generateOperatorCharData(bool for_QString) QTest::addColumn("qchar_output"); QTest::addColumn("char_output"); QTest::addColumn("write_output"); + QTest::addColumn("status"); - QTest::newRow("empty") << QByteArray() << QChar('\0') << '\0' << QByteArray("\0", 1); - QTest::newRow("a") << QByteArray("a") << QChar('a') << 'a' << QByteArray("a"); - QTest::newRow("\\na") << QByteArray("\na") << QChar('\n') << '\n' << QByteArray("\n"); - QTest::newRow("\\0") << QByteArray("\0") << QChar('\0') << '\0' << QByteArray("\0", 1); - QTest::newRow("\\xff") << QByteArray("\xff") << QChar('\xff') << '\xff' << QByteArray("\xff"); - QTest::newRow("\\xfe") << QByteArray("\xfe") << QChar('\xfe') << '\xfe' << QByteArray("\xfe"); + QTest::newRow("empty") << QByteArray() << QChar('\0') << '\0' + << QByteArray("\0", 1) << false; + QTest::newRow("a") << QByteArray("a") << QChar('a') << 'a' + << QByteArray("a") << true; + QTest::newRow("\\na") << QByteArray("\na") << QChar('\n') << '\n' + << QByteArray("\n") << true; + QTest::newRow("\\0") << QByteArray("\0") << QChar('\0') << '\0' + << QByteArray("\0", 1) << false; + QTest::newRow("\\xff") << QByteArray("\xff") << QChar('\xff') << '\xff' + << QByteArray("\xff") << true; + QTest::newRow("\\xfe") << QByteArray("\xfe") << QChar('\xfe') << '\xfe' + << QByteArray("\xfe") << true; if (!for_QString) { - QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QChar('\0') << '\0' << QByteArray("\0", 1); - QTest::newRow("utf16-BE (a)") << QByteArray("\xff\xfe\x61\x00", 4) << QChar('a') << 'a' << QByteArray("a"); - QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QChar('\0') << '\0' << QByteArray("\0", 1); - QTest::newRow("utf16-LE (a)") << QByteArray("\xfe\xff\x00\x61", 4) << QChar('a') << 'a' << QByteArray("a"); + QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QChar('\0') << '\0' + << QByteArray("\0", 1) << false; + QTest::newRow("utf16-BE (a)") << QByteArray("\xff\xfe\x61\x00", 4) << QChar('a') << 'a' + << QByteArray("a") << true; + QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QChar('\0') << '\0' + << QByteArray("\0", 1) << false; + QTest::newRow("utf16-LE (a)") << QByteArray("\xfe\xff\x00\x61", 4) << QChar('a') << 'a' + << QByteArray("a") << true; } } @@ -1879,13 +1893,14 @@ void tst_QTextStream::QChar_operators_FromDevice() QFETCH(QByteArray, input); QFETCH(QChar, qchar_output); QFETCH(QByteArray, write_output); + QFETCH(bool, status); QBuffer buf(&input); buf.open(QBuffer::ReadOnly); QTextStream stream(&buf); stream.setEncoding(QStringConverter::Latin1); QChar tmp; - stream >> tmp; + QCOMPARE(static_cast(stream >> tmp), status); QCOMPARE(tmp, qchar_output); QBuffer writeBuf; @@ -1893,7 +1908,7 @@ void tst_QTextStream::QChar_operators_FromDevice() QTextStream writeStream(&writeBuf); writeStream.setEncoding(QStringConverter::Latin1); - writeStream << qchar_output; + QVERIFY(writeStream << qchar_output); writeStream.flush(); QCOMPARE(writeBuf.buffer().size(), write_output.size()); @@ -1912,6 +1927,7 @@ void tst_QTextStream::char16_t_operators_FromDevice() QFETCH(QByteArray, input); QFETCH(const QChar, qchar_output); QFETCH(const QByteArray, write_output); + QFETCH(bool, status); const char16_t char16_t_output = qchar_output.unicode(); QBuffer buf(&input); @@ -1919,7 +1935,7 @@ void tst_QTextStream::char16_t_operators_FromDevice() QTextStream stream(&buf); stream.setEncoding(QStringConverter::Latin1); char16_t tmp; - stream >> tmp; + QCOMPARE(static_cast(stream >> tmp), status); QCOMPARE(tmp, qchar_output); QBuffer writeBuf; @@ -1927,7 +1943,7 @@ void tst_QTextStream::char16_t_operators_FromDevice() QTextStream writeStream(&writeBuf); writeStream.setEncoding(QStringConverter::Latin1); - writeStream << char16_t_output; + QVERIFY(writeStream << char16_t_output); writeStream.flush(); QCOMPARE(writeBuf.buffer().size(), write_output.size()); @@ -1946,13 +1962,14 @@ void tst_QTextStream::char_operators_FromDevice() QFETCH(QByteArray, input); QFETCH(char, char_output); QFETCH(QByteArray, write_output); + QFETCH(bool, status); QBuffer buf(&input); buf.open(QBuffer::ReadOnly); QTextStream stream(&buf); stream.setEncoding(QStringConverter::Latin1); char tmp; - stream >> tmp; + QCOMPARE(static_cast(stream >> tmp), status); QCOMPARE(tmp, char_output); QBuffer writeBuf; @@ -1960,7 +1977,7 @@ void tst_QTextStream::char_operators_FromDevice() QTextStream writeStream(&writeBuf); writeStream.setEncoding(QStringConverter::Latin1); - writeStream << char_output; + QVERIFY(writeStream << char_output); writeStream.flush(); QCOMPARE(writeBuf.buffer().size(), write_output.size()); @@ -2134,21 +2151,27 @@ void tst_QTextStream::generateStringData(bool for_QString) QTest::addColumn("input"); QTest::addColumn("array_output"); QTest::addColumn("string_output"); + QTest::addColumn("status"); - QTest::newRow("empty") << QByteArray() << QByteArray() << QString(); - QTest::newRow("a") << QByteArray("a") << QByteArray("a") << QString("a"); - QTest::newRow("a b") << QByteArray("a b") << QByteArray("a") << QString("a"); - QTest::newRow(" a b") << QByteArray(" a b") << QByteArray("a") << QString("a"); - QTest::newRow("a1") << QByteArray("a1") << QByteArray("a1") << QString("a1"); - QTest::newRow("a1 b1") << QByteArray("a1 b1") << QByteArray("a1") << QString("a1"); - QTest::newRow(" a1 b1") << QByteArray(" a1 b1") << QByteArray("a1") << QString("a1"); - QTest::newRow("\\n\\n\\nole i dole\\n") << QByteArray("\n\n\nole i dole\n") << QByteArray("ole") << QString("ole"); + QTest::newRow("empty") << QByteArray() << QByteArray() << QString() << false; + QTest::newRow("a") << QByteArray("a") << QByteArray("a") << QString("a") << true; + QTest::newRow("a b") << QByteArray("a b") << QByteArray("a") << QString("a") << true; + QTest::newRow(" a b") << QByteArray(" a b") << QByteArray("a") << QString("a") << true; + QTest::newRow("a1") << QByteArray("a1") << QByteArray("a1") << QString("a1") << true; + QTest::newRow("a1 b1") << QByteArray("a1 b1") << QByteArray("a1") << QString("a1") << true; + QTest::newRow(" a1 b1") << QByteArray(" a1 b1") << QByteArray("a1") << QString("a1") << true; + QTest::newRow("\\n\\n\\nole i dole\\n") << QByteArray("\n\n\nole i dole\n") + << QByteArray("ole") << QString("ole") << true; if (!for_QString) { - QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QByteArray() << QString(); - QTest::newRow("utf16-BE (corrupt)") << QByteArray("\xff", 1) << QByteArray("\xc3\xbf") << QString::fromUtf8("\xc3\xbf"); - QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QByteArray() << QString(); - QTest::newRow("utf16-LE (corrupt)") << QByteArray("\xfe", 1) << QByteArray("\xc3\xbe") << QString::fromUtf8("\xc3\xbe"); + QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QByteArray() + << QString() << false; + QTest::newRow("utf16-BE (corrupt)") << QByteArray("\xff", 1) << QByteArray("\xc3\xbf") + << QString::fromUtf8("\xc3\xbf") << true; + QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QByteArray() + << QString() << false; + QTest::newRow("utf16-LE (corrupt)") << QByteArray("\xfe", 1) << QByteArray("\xc3\xbe") + << QString::fromUtf8("\xc3\xbe") << true; } } @@ -2163,6 +2186,7 @@ void tst_QTextStream::charPtr_read_operator_FromDevice() { QFETCH(QByteArray, input); QFETCH(QByteArray, array_output); + QFETCH(bool, status); QBuffer buffer(&input); buffer.open(QBuffer::ReadOnly); @@ -2171,7 +2195,7 @@ void tst_QTextStream::charPtr_read_operator_FromDevice() stream.setAutoDetectUnicode(true); char buf[1024]; - stream >> buf; + QCOMPARE(static_cast(stream >> buf), status); QCOMPARE((const char *)buf, array_output.constData()); } @@ -2187,6 +2211,7 @@ void tst_QTextStream::stringRef_read_operator_FromDevice() { QFETCH(QByteArray, input); QFETCH(QString, string_output); + QFETCH(bool, status); QBuffer buffer(&input); buffer.open(QBuffer::ReadOnly); @@ -2195,7 +2220,7 @@ void tst_QTextStream::stringRef_read_operator_FromDevice() stream.setAutoDetectUnicode(true); QString tmp; - stream >> tmp; + QCOMPARE(static_cast(stream >> tmp), status); QCOMPARE(tmp, string_output); } @@ -2211,6 +2236,7 @@ void tst_QTextStream::byteArray_read_operator_FromDevice() { QFETCH(QByteArray, input); QFETCH(QByteArray, array_output); + QFETCH(bool, status); QBuffer buffer(&input); buffer.open(QBuffer::ReadOnly); @@ -2219,7 +2245,7 @@ void tst_QTextStream::byteArray_read_operator_FromDevice() stream.setAutoDetectUnicode(true); QByteArray array; - stream >> array; + QCOMPARE(static_cast(stream >> array), status); QCOMPARE(array, array_output); } @@ -2236,28 +2262,28 @@ void tst_QTextStream::byteArray_read_operator_FromDevice() buffer.open(QBuffer::WriteOnly); \ QTextStream stream(&buffer); \ stream.setLocale(QLocale::c()); \ - stream << (type)number; \ + QVERIFY(stream << (type)number); \ stream.flush(); \ QCOMPARE(buffer.data().constData(), data.constData()); \ \ QLocale locale("en-US"); \ buffer.reset(); buffer.buffer().clear(); \ stream.setLocale(locale); \ - stream << (type)number; \ + QVERIFY(stream << (type)number); \ stream.flush(); \ QCOMPARE(buffer.data(), dataWithSeparators); \ \ locale.setNumberOptions(QLocale::OmitGroupSeparator); \ buffer.reset(); buffer.buffer().clear(); \ stream.setLocale(locale); \ - stream << (type)number; \ + QVERIFY(stream << (type)number); \ stream.flush(); \ QCOMPARE(buffer.data().constData(), data.constData()); \ \ locale = QLocale("de-DE"); \ buffer.reset(); buffer.buffer().clear(); \ stream.setLocale(locale); \ - stream << (type)number; \ + QVERIFY(stream << (type)number); \ stream.flush(); \ QCOMPARE(buffer.data(), dataWithSeparators.replace(',', '.')); \ } @@ -2445,13 +2471,13 @@ void tst_QTextStream::generateRealNumbersDataWrite() QTextStream stream(&buffer); \ stream.setLocale(QLocale::c()); \ float f = (float)number; \ - stream << f; \ + QVERIFY(stream << f); \ stream.flush(); \ QCOMPARE(buffer.data().constData(), data.constData()); \ \ buffer.reset(); \ stream.setLocale(QLocale("en-US")); \ - stream << f; \ + QVERIFY(stream << f); \ stream.flush(); \ QCOMPARE(buffer.data(), dataWithSeparators); \ } @@ -2497,7 +2523,7 @@ void tst_QTextStream::string_write_operator_ToDevice() stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); - stream << bytedata.constData(); + QVERIFY(stream << bytedata.constData()); stream.flush(); QCOMPARE(buf.buffer().constData(), result.constData()); } @@ -2509,7 +2535,7 @@ void tst_QTextStream::string_write_operator_ToDevice() stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); - stream << bytedata; + QVERIFY(stream << bytedata); stream.flush(); QCOMPARE(buf.buffer().constData(), result.constData()); } @@ -2521,7 +2547,7 @@ void tst_QTextStream::string_write_operator_ToDevice() stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); - stream << stringdata; + QVERIFY(stream << stringdata); stream.flush(); QCOMPARE(buf.buffer().constData(), result.constData()); } @@ -2535,8 +2561,8 @@ void tst_QTextStream::latin1String_write_operator_ToDevice() stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); - stream << QLatin1String("No explicit length"); - stream << QLatin1String("Explicit length - ignore this part", 15); + QVERIFY(stream << QLatin1String("No explicit length")); + QVERIFY(stream << QLatin1String("Explicit length - ignore this part", 15)); stream.flush(); QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length"); } @@ -2551,8 +2577,8 @@ void tst_QTextStream::stringref_write_operator_ToDevice() const QStringView expected = u"No explicit lengthExplicit length"; - stream << expected.left(18); - stream << expected.mid(18); + QVERIFY(stream << expected.left(18)); + QVERIFY(stream << expected.mid(18)); stream.flush(); QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length"); } @@ -2563,11 +2589,44 @@ void tst_QTextStream::stringview_write_operator_ToDevice() buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); const QStringView expected = u"expectedStringView"; - stream << expected; + QVERIFY(stream << expected); stream.flush(); QCOMPARE(buf.buffer().constData(), "expectedStringView"); } +// ------------------------------------------------------------------------------ +void tst_QTextStream::stream_bool_operator_Test() +{ + const QStringView expected = u"expectedStringView"; + QString line("exp"); + QTextStream stream(&line); + QChar ch1, ch2, ch3; + + QVERIFY(stream >> ch1); + QCOMPARE(ch1, 'e'); + QVERIFY(stream >> ch2); + QCOMPARE(ch2, 'x'); + QVERIFY(stream >> ch3); + QCOMPARE(ch3, 'p'); + + QVERIFY(stream << "ectedStringView"); + stream.flush(); + QCOMPARE(*stream.string(), expected); + + QTextStream emptyStream(""); + QVERIFY(!(emptyStream >> ch1)); + QVERIFY(!(emptyStream << "Hello")); + + QTextStream textStream("1 2 3 error"); + int n; + for (int i = 0; i < 3; ++i) { + QVERIFY(textStream >> n); + QCOMPARE_EQ(n, i + 1); + } + QVERIFY(!textStream.atEnd()); + QVERIFY(!(textStream >> n)); +} + // ------------------------------------------------------------------------------ void tst_QTextStream::useCase1() { @@ -2633,9 +2692,9 @@ void tst_QTextStream::useCase2() stream2.setEncoding(QStringConverter::Latin1); stream2.setAutoDetectUnicode(true); - stream2 >> d; - stream2 >> a; - stream2 >> s; + QVERIFY(stream2 >> d); + QVERIFY(stream2 >> a); + QVERIFY(stream2 >> s); QCOMPARE(d, 4.15); QCOMPARE(a, QByteArray("abc")); @@ -2700,9 +2759,9 @@ void tst_QTextStream::manipulators() stream.setFieldAlignment(QTextStream::FieldAlignment(alignFlag)); stream.setNumberFlags(QTextStream::NumberFlag(numberFlag)); stream.setFieldWidth(width); - stream << realNumber; - stream << intNumber; - stream << textData; + QVERIFY(stream << realNumber); + QVERIFY(stream << intNumber); + QVERIFY(stream << textData); stream.flush(); QCOMPARE(buffer.data(), result); @@ -2731,7 +2790,7 @@ void tst_QTextStream::generateBOM() QTextStream stream(&file); stream.setEncoding(QStringConverter::Utf16LE); - stream << Qt::bom << "Hello" << Qt::endl; + QVERIFY(stream << Qt::bom << "Hello" << Qt::endl); file.close(); QVERIFY(file.open(QFile::ReadOnly)); @@ -2751,10 +2810,10 @@ void tst_QTextStream::readBomSeekBackReadBomAgain() QTextStream stream(&file); stream.setEncoding(QStringConverter::Utf8); QString Andreas; - stream >> Andreas; + QVERIFY(stream >> Andreas); QCOMPARE(Andreas, QString("Andreas")); stream.seek(0); - stream >> Andreas; + QVERIFY(stream >> Andreas); QCOMPARE(Andreas, QString("Andreas")); } @@ -2804,16 +2863,16 @@ void tst_QTextStream::status_integer_read() QTextStream s("123 abc "); int i; QString w; - s >> i; + QVERIFY(s >> i); QCOMPARE(s.status(), QTextStream::Ok); - s >> i; + QVERIFY(!(s >> i)); QCOMPARE(s.status(), QTextStream::ReadCorruptData); s.resetStatus(); QCOMPARE(s.status(), QTextStream::Ok); - s >> w; + QVERIFY(s >> w); QCOMPARE(s.status(), QTextStream::Ok); QCOMPARE(w, QString("abc")); - s >> i; + QVERIFY(!(s >> i)); QCOMPARE(s.status(), QTextStream::ReadPastEnd); } @@ -2821,9 +2880,9 @@ void tst_QTextStream::status_word_read() { QTextStream s("abc "); QString w; - s >> w; + QVERIFY(s >> w); QCOMPARE(s.status(), QTextStream::Ok); - s >> w; + QVERIFY(!(s >> w)); QCOMPARE(s.status(), QTextStream::ReadPastEnd); } @@ -2845,13 +2904,13 @@ void tst_QTextStream::status_write_error() QTextStream fs(&fb); fs.setEncoding(QStringConverter::Latin1); /* first write some initial content */ - fs << "hello"; + QVERIFY(fs << "hello"); fs.flush(); QCOMPARE(fs.status(), QTextStream::Ok); QCOMPARE(fb.data(), QByteArray("hello")); /* then test that writing can cause an error */ fb.setLocked(true); - fs << "error"; + QVERIFY(fs << "error"); fs.flush(); QCOMPARE(fs.status(), QTextStream::WriteFailed); QCOMPARE(fb.data(), QByteArray("hello")); @@ -2881,7 +2940,7 @@ void tst_QTextStream::alignAccountingStyle() out.setFieldAlignment(QTextStream::AlignAccountingStyle); out.setFieldWidth(4); out.setPadChar('0'); - out << "-1"; + QVERIFY(out << "-1"); QCOMPARE(result, QLatin1String("00-1")); } @@ -2891,7 +2950,7 @@ void tst_QTextStream::alignAccountingStyle() out.setFieldAlignment(QTextStream::AlignAccountingStyle); out.setFieldWidth(6); out.setPadChar('0'); - out << -1.2; + QVERIFY(out << -1.2); QCOMPARE(result, QLatin1String("-001.2")); } @@ -2901,7 +2960,7 @@ void tst_QTextStream::alignAccountingStyle() out.setFieldAlignment(QTextStream::AlignAccountingStyle); out.setFieldWidth(6); out.setPadChar('0'); - out << "-1.2"; + QVERIFY(out << "-1.2"); QCOMPARE(result, QLatin1String("00-1.2")); } } @@ -2951,7 +3010,7 @@ void tst_QTextStream::double_write_with_flags() stream.setNumberFlags(QTextStream::NumberFlag(numberFlags)); if (realNumberNotation) stream.setRealNumberNotation(QTextStream::RealNumberNotation(realNumberNotation)); - stream << number; + QVERIFY(stream << number); QCOMPARE(buf, output); } @@ -2982,7 +3041,7 @@ void tst_QTextStream::double_write_with_precision() QString buf; QTextStream stream(&buf); stream.setRealNumberPrecision(precision); - stream << value; + QVERIFY(stream << value); QCOMPARE(buf, result); } @@ -2991,18 +3050,19 @@ void tst_QTextStream::int_read_with_locale_data() QTest::addColumn("locale"); QTest::addColumn("input"); QTest::addColumn("output"); + QTest::addColumn("status"); - QTest::newRow("C -123") << QString("C") << QString("-123") << -123; - QTest::newRow("C +123") << QString("C") << QString("+123") << 123; - QTest::newRow("C 12345") << QString("C") << QString("12345") << 12345; - QTest::newRow("C 12,345") << QString("C") << QString("12,345") << 12; - QTest::newRow("C 12.345") << QString("C") << QString("12.345") << 12; + QTest::newRow("C -123") << QString("C") << QString("-123") << -123 << true; + QTest::newRow("C +123") << QString("C") << QString("+123") << 123 << true; + QTest::newRow("C 12345") << QString("C") << QString("12345") << 12345 << true; + QTest::newRow("C 12,345") << QString("C") << QString("12,345") << 12 << true; + QTest::newRow("C 12.345") << QString("C") << QString("12.345") << 12 << true; - QTest::newRow("de_DE -123") << QString("de_DE") << QString("-123") << -123; - QTest::newRow("de_DE +123") << QString("de_DE") << QString("+123") << 123; - QTest::newRow("de_DE 12345") << QString("de_DE") << QString("12345") << 12345; - QTest::newRow("de_DE 12.345") << QString("de_DE") << QString("12.345") << 12345; - QTest::newRow("de_DE .12345") << QString("de_DE") << QString(".12345") << 0; + QTest::newRow("de_DE -123") << QString("de_DE") << QString("-123") << -123 << true; + QTest::newRow("de_DE +123") << QString("de_DE") << QString("+123") << 123 << true; + QTest::newRow("de_DE 12345") << QString("de_DE") << QString("12345") << 12345 << true; + QTest::newRow("de_DE 12.345") << QString("de_DE") << QString("12.345") << 12345 << true; + QTest::newRow("de_DE .12345") << QString("de_DE") << QString(".12345") << 0 << false; } void tst_QTextStream::int_read_with_locale() @@ -3010,11 +3070,12 @@ void tst_QTextStream::int_read_with_locale() QFETCH(QString, locale); QFETCH(QString, input); QFETCH(int, output); + QFETCH(bool, status); QTextStream stream(&input); stream.setLocale(QLocale(locale)); int result; - stream >> result; + QCOMPARE(static_cast(stream >> result), status); QCOMPARE(result, output); } @@ -3046,7 +3107,7 @@ void tst_QTextStream::int_write_with_locale() stream.setLocale(QLocale(locale)); if (numberFlags) stream.setNumberFlags(QTextStream::NumberFlags(numberFlags)); - stream << input; + QVERIFY(stream << input); QCOMPARE(result, output); } @@ -3091,7 +3152,7 @@ void tst_QTextStream::autodetectUnicode() { QTextStream in(&file); QString actual; - in >> actual; + QVERIFY(in >> actual); QCOMPARE(actual, original); QCOMPARE(in.encoding(), encoding); } @@ -3107,7 +3168,7 @@ void tst_QTextStream::autodetectUnicode() { QTextStream in(&file); QString actual; - in >> actual; + QVERIFY(in >> actual); QCOMPARE(actual, original); QCOMPARE(in.encoding(), encoding); }