| 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 | |
| 31 | #ifdef Q_OS_UNIX |
| 32 | #include <locale.h> |
| 33 | #endif |
| 34 | |
| 35 | #include <QBuffer> |
| 36 | #include <QByteArray> |
| 37 | #include <QDebug> |
| 38 | #include <QElapsedTimer> |
| 39 | #include <QFile> |
| 40 | #include <QTcpSocket> |
| 41 | #include <QTemporaryDir> |
| 42 | #include <QTextStream> |
| 43 | #include <QTextCodec> |
| 44 | #if QT_CONFIG(process) |
| 45 | # include <QProcess> |
| 46 | #endif |
| 47 | #include "../../../network-settings.h" |
| 48 | #include "emulationdetector.h" |
| 49 | |
| 50 | QT_BEGIN_NAMESPACE |
| 51 | template<> struct QMetaTypeId<QIODevice::OpenModeFlag> |
| 52 | { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } }; |
| 53 | QT_END_NAMESPACE |
| 54 | |
| 55 | class tst_QTextStream : public QObject |
| 56 | { |
| 57 | Q_OBJECT |
| 58 | |
| 59 | public: |
| 60 | tst_QTextStream(); |
| 61 | |
| 62 | public slots: |
| 63 | void initTestCase(); |
| 64 | void cleanup(); |
| 65 | void cleanupTestCase(); |
| 66 | |
| 67 | private slots: |
| 68 | void getSetCheck(); |
| 69 | void construction(); |
| 70 | |
| 71 | // lines |
| 72 | void readLineFromDevice_data(); |
| 73 | void readLineFromDevice(); |
| 74 | void readLineFromString_data(); |
| 75 | void readLineFromString(); |
| 76 | void readLineFromTextDevice_data(); |
| 77 | void readLineFromTextDevice(); |
| 78 | void readLineUntilNull(); |
| 79 | void readLineMaxlen_data(); |
| 80 | void readLineMaxlen(); |
| 81 | void readLinesFromBufferCRCR(); |
| 82 | void readLineInto(); |
| 83 | |
| 84 | // all |
| 85 | void readAllFromDevice_data(); |
| 86 | void readAllFromDevice(); |
| 87 | void readAllFromString_data(); |
| 88 | void readAllFromString(); |
| 89 | void readLineFromStringThenChangeString(); |
| 90 | |
| 91 | // device tests |
| 92 | void setDevice(); |
| 93 | |
| 94 | // char operators |
| 95 | void QChar_operators_FromDevice_data(); |
| 96 | void QChar_operators_FromDevice(); |
| 97 | void char_operators_FromDevice_data(); |
| 98 | void char_operators_FromDevice(); |
| 99 | |
| 100 | // natural number read operator |
| 101 | void signedShort_read_operator_FromDevice_data(); |
| 102 | void signedShort_read_operator_FromDevice(); |
| 103 | void unsignedShort_read_operator_FromDevice_data(); |
| 104 | void unsignedShort_read_operator_FromDevice(); |
| 105 | void signedInt_read_operator_FromDevice_data(); |
| 106 | void signedInt_read_operator_FromDevice(); |
| 107 | void unsignedInt_read_operator_FromDevice_data(); |
| 108 | void unsignedInt_read_operator_FromDevice(); |
| 109 | void qlonglong_read_operator_FromDevice_data(); |
| 110 | void qlonglong_read_operator_FromDevice(); |
| 111 | void qulonglong_read_operator_FromDevice_data(); |
| 112 | void qulonglong_read_operator_FromDevice(); |
| 113 | |
| 114 | // natural number write operator |
| 115 | void signedShort_write_operator_ToDevice_data(); |
| 116 | void signedShort_write_operator_ToDevice(); |
| 117 | void unsignedShort_write_operator_ToDevice_data(); |
| 118 | void unsignedShort_write_operator_ToDevice(); |
| 119 | void signedInt_write_operator_ToDevice_data(); |
| 120 | void signedInt_write_operator_ToDevice(); |
| 121 | void unsignedInt_write_operator_ToDevice_data(); |
| 122 | void unsignedInt_write_operator_ToDevice(); |
| 123 | void qlonglong_write_operator_ToDevice_data(); |
| 124 | void qlonglong_write_operator_ToDevice(); |
| 125 | void qulonglong_write_operator_ToDevice_data(); |
| 126 | void qulonglong_write_operator_ToDevice(); |
| 127 | |
| 128 | void int_read_with_locale_data(); |
| 129 | void int_read_with_locale(); |
| 130 | |
| 131 | void int_write_with_locale_data(); |
| 132 | void int_write_with_locale(); |
| 133 | |
| 134 | // real number read operator |
| 135 | void float_read_operator_FromDevice_data(); |
| 136 | void float_read_operator_FromDevice(); |
| 137 | void double_read_operator_FromDevice_data(); |
| 138 | void double_read_operator_FromDevice(); |
| 139 | |
| 140 | // real number write operator |
| 141 | void float_write_operator_ToDevice_data(); |
| 142 | void float_write_operator_ToDevice(); |
| 143 | void double_write_operator_ToDevice_data(); |
| 144 | void double_write_operator_ToDevice(); |
| 145 | |
| 146 | void double_write_with_flags_data(); |
| 147 | void double_write_with_flags(); |
| 148 | |
| 149 | void double_write_with_precision_data(); |
| 150 | void double_write_with_precision(); |
| 151 | |
| 152 | // text read operators |
| 153 | void charPtr_read_operator_FromDevice_data(); |
| 154 | void charPtr_read_operator_FromDevice(); |
| 155 | void stringRef_read_operator_FromDevice_data(); |
| 156 | void stringRef_read_operator_FromDevice(); |
| 157 | void byteArray_read_operator_FromDevice_data(); |
| 158 | void byteArray_read_operator_FromDevice(); |
| 159 | |
| 160 | // text write operators |
| 161 | void string_write_operator_ToDevice_data(); |
| 162 | void string_write_operator_ToDevice(); |
| 163 | void latin1String_write_operator_ToDevice(); |
| 164 | void stringref_write_operator_ToDevice(); |
| 165 | void stringview_write_operator_ToDevice(); |
| 166 | |
| 167 | // other |
| 168 | void skipWhiteSpace_data(); |
| 169 | void skipWhiteSpace(); |
| 170 | void lineCount_data(); |
| 171 | void lineCount(); |
| 172 | void performance(); |
| 173 | void hexTest_data(); |
| 174 | void hexTest(); |
| 175 | void binTest_data(); |
| 176 | void binTest(); |
| 177 | void octTest_data(); |
| 178 | void octTest(); |
| 179 | void zeroTermination(); |
| 180 | void ws_manipulator(); |
| 181 | void stillOpenWhenAtEnd(); |
| 182 | void readNewlines_data(); |
| 183 | void readNewlines(); |
| 184 | void seek(); |
| 185 | void pos(); |
| 186 | void pos2(); |
| 187 | void pos3LargeFile(); |
| 188 | void readStdin(); |
| 189 | void readAllFromStdin(); |
| 190 | void readLineFromStdin(); |
| 191 | void read(); |
| 192 | void qbool(); |
| 193 | void forcePoint(); |
| 194 | void forceSign(); |
| 195 | void read0d0d0a(); |
| 196 | void numeralCase_data(); |
| 197 | void numeralCase(); |
| 198 | void nanInf(); |
| 199 | void utf8IncompleteAtBufferBoundary_data(); |
| 200 | void utf8IncompleteAtBufferBoundary(); |
| 201 | void writeSeekWriteNoBOM(); |
| 202 | |
| 203 | // status |
| 204 | void status_real_read_data(); |
| 205 | void status_real_read(); |
| 206 | void status_integer_read(); |
| 207 | void status_word_read(); |
| 208 | void status_write_error(); |
| 209 | |
| 210 | // use case tests |
| 211 | void useCase1(); |
| 212 | void useCase2(); |
| 213 | |
| 214 | // manipulators |
| 215 | void manipulators_data(); |
| 216 | void manipulators(); |
| 217 | |
| 218 | // UTF-16 BOM (Byte Order Mark) |
| 219 | void generateBOM(); |
| 220 | void readBomSeekBackReadBomAgain(); |
| 221 | |
| 222 | // Regression tests for old bugs |
| 223 | void alignAccountingStyle(); |
| 224 | void setCodec(); |
| 225 | |
| 226 | void textModeOnEmptyRead(); |
| 227 | |
| 228 | private: |
| 229 | void generateLineData(bool for_QString); |
| 230 | void generateAllData(bool for_QString); |
| 231 | void generateOperatorCharData(bool for_QString); |
| 232 | void generateNaturalNumbersData(bool for_QString); |
| 233 | void generateRealNumbersData(bool for_QString); |
| 234 | void generateStringData(bool for_QString); |
| 235 | void generateRealNumbersDataWrite(); |
| 236 | |
| 237 | QTemporaryDir tempDir; |
| 238 | QString testFileName; |
| 239 | #ifdef BUILTIN_TESTDATA |
| 240 | QSharedPointer<QTemporaryDir> m_dataDir; |
| 241 | #endif |
| 242 | const QString m_rfc3261FilePath; |
| 243 | const QString m_shiftJisFilePath; |
| 244 | }; |
| 245 | |
| 246 | void runOnExit() |
| 247 | { |
| 248 | QByteArray buffer; |
| 249 | QTextStream(&buffer) << "This will try to use QTextCodec::codecForLocale" << Qt::endl; |
| 250 | } |
| 251 | Q_DESTRUCTOR_FUNCTION(runOnExit) |
| 252 | |
| 253 | tst_QTextStream::tst_QTextStream() |
| 254 | : tempDir(QDir::tempPath() + "/tst_qtextstream.XXXXXX" ) |
| 255 | , m_rfc3261FilePath(QFINDTESTDATA("rfc3261.txt" )) |
| 256 | , m_shiftJisFilePath(QFINDTESTDATA("shift-jis.txt" )) |
| 257 | { |
| 258 | } |
| 259 | |
| 260 | void tst_QTextStream::initTestCase() |
| 261 | { |
| 262 | QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); |
| 263 | QVERIFY(!m_rfc3261FilePath.isEmpty()); |
| 264 | QVERIFY(!m_shiftJisFilePath.isEmpty()); |
| 265 | |
| 266 | testFileName = tempDir.path() + "/testfile" ; |
| 267 | |
| 268 | #ifdef BUILTIN_TESTDATA |
| 269 | m_dataDir = QEXTRACTTESTDATA("/" ); |
| 270 | QVERIFY2(QDir::setCurrent(m_dataDir->path()), qPrintable("Could not chdir to " + m_dataDir->path())); |
| 271 | #else |
| 272 | // chdir into the testdata dir and refer to our helper apps with relative paths |
| 273 | QString testdata_dir = QFileInfo(QFINDTESTDATA("stdinProcess" )).absolutePath(); |
| 274 | QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir)); |
| 275 | #endif |
| 276 | } |
| 277 | |
| 278 | // Testing get/set functions |
| 279 | void tst_QTextStream::getSetCheck() |
| 280 | { |
| 281 | // Initialize codecs |
| 282 | QTextStream obj1; |
| 283 | // QTextCodec * QTextStream::codec() |
| 284 | // void QTextStream::setCodec(QTextCodec *) |
| 285 | QTextCodec *var1 = QTextCodec::codecForName(name: "en" ); |
| 286 | obj1.setCodec(var1); |
| 287 | QCOMPARE(var1, obj1.codec()); |
| 288 | obj1.setCodec((QTextCodec *)0); |
| 289 | QCOMPARE((QTextCodec *)0, obj1.codec()); |
| 290 | |
| 291 | // bool QTextStream::autoDetectUnicode() |
| 292 | // void QTextStream::setAutoDetectUnicode(bool) |
| 293 | obj1.setAutoDetectUnicode(false); |
| 294 | QCOMPARE(false, obj1.autoDetectUnicode()); |
| 295 | obj1.setAutoDetectUnicode(true); |
| 296 | QCOMPARE(true, obj1.autoDetectUnicode()); |
| 297 | |
| 298 | // bool QTextStream::generateByteOrderMark() |
| 299 | // void QTextStream::setGenerateByteOrderMark(bool) |
| 300 | obj1.setGenerateByteOrderMark(false); |
| 301 | QCOMPARE(false, obj1.generateByteOrderMark()); |
| 302 | obj1.setGenerateByteOrderMark(true); |
| 303 | QCOMPARE(true, obj1.generateByteOrderMark()); |
| 304 | |
| 305 | // QIODevice * QTextStream::device() |
| 306 | // void QTextStream::setDevice(QIODevice *) |
| 307 | QFile *var4 = new QFile; |
| 308 | obj1.setDevice(var4); |
| 309 | QCOMPARE(static_cast<QIODevice *>(var4), obj1.device()); |
| 310 | obj1.setDevice((QIODevice *)0); |
| 311 | QCOMPARE((QIODevice *)0, obj1.device()); |
| 312 | delete var4; |
| 313 | |
| 314 | // Status QTextStream::status() |
| 315 | // void QTextStream::setStatus(Status) |
| 316 | obj1.setStatus(QTextStream::Status(QTextStream::Ok)); |
| 317 | QCOMPARE(QTextStream::Status(QTextStream::Ok), obj1.status()); |
| 318 | obj1.setStatus(QTextStream::Status(QTextStream::ReadPastEnd)); |
| 319 | QCOMPARE(QTextStream::Status(QTextStream::ReadPastEnd), obj1.status()); |
| 320 | obj1.resetStatus(); |
| 321 | obj1.setStatus(QTextStream::Status(QTextStream::ReadCorruptData)); |
| 322 | QCOMPARE(QTextStream::Status(QTextStream::ReadCorruptData), obj1.status()); |
| 323 | |
| 324 | // FieldAlignment QTextStream::fieldAlignment() |
| 325 | // void QTextStream::setFieldAlignment(FieldAlignment) |
| 326 | obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignLeft)); |
| 327 | QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignLeft), obj1.fieldAlignment()); |
| 328 | obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignRight)); |
| 329 | QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignRight), obj1.fieldAlignment()); |
| 330 | obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignCenter)); |
| 331 | QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignCenter), obj1.fieldAlignment()); |
| 332 | obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignAccountingStyle)); |
| 333 | QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignAccountingStyle), obj1.fieldAlignment()); |
| 334 | |
| 335 | // QChar QTextStream::padChar() |
| 336 | // void QTextStream::setPadChar(QChar) |
| 337 | QChar var7 = 'Q'; |
| 338 | obj1.setPadChar(var7); |
| 339 | QCOMPARE(var7, obj1.padChar()); |
| 340 | obj1.setPadChar(QChar()); |
| 341 | QCOMPARE(QChar(), obj1.padChar()); |
| 342 | |
| 343 | // int QTextStream::fieldWidth() |
| 344 | // void QTextStream::setFieldWidth(int) |
| 345 | obj1.setFieldWidth(0); |
| 346 | QCOMPARE(0, obj1.fieldWidth()); |
| 347 | obj1.setFieldWidth(INT_MIN); |
| 348 | QCOMPARE(INT_MIN, obj1.fieldWidth()); |
| 349 | obj1.setFieldWidth(INT_MAX); |
| 350 | QCOMPARE(INT_MAX, obj1.fieldWidth()); |
| 351 | |
| 352 | // NumberFlags QTextStream::numberFlags() |
| 353 | // void QTextStream::setNumberFlags(NumberFlags) |
| 354 | obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ShowBase)); |
| 355 | QCOMPARE(QTextStream::NumberFlags(QTextStream::ShowBase), obj1.numberFlags()); |
| 356 | obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ForcePoint)); |
| 357 | QCOMPARE(QTextStream::NumberFlags(QTextStream::ForcePoint), obj1.numberFlags()); |
| 358 | obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ForceSign)); |
| 359 | QCOMPARE(QTextStream::NumberFlags(QTextStream::ForceSign), obj1.numberFlags()); |
| 360 | obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::UppercaseBase)); |
| 361 | QCOMPARE(QTextStream::NumberFlags(QTextStream::UppercaseBase), obj1.numberFlags()); |
| 362 | obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::UppercaseDigits)); |
| 363 | QCOMPARE(QTextStream::NumberFlags(QTextStream::UppercaseDigits), obj1.numberFlags()); |
| 364 | |
| 365 | // int QTextStream::integerBase() |
| 366 | // void QTextStream::setIntegerBase(int) |
| 367 | obj1.setIntegerBase(0); |
| 368 | QCOMPARE(0, obj1.integerBase()); |
| 369 | obj1.setIntegerBase(INT_MIN); |
| 370 | QCOMPARE(INT_MIN, obj1.integerBase()); |
| 371 | obj1.setIntegerBase(INT_MAX); |
| 372 | QCOMPARE(INT_MAX, obj1.integerBase()); |
| 373 | |
| 374 | // RealNumberNotation QTextStream::realNumberNotation() |
| 375 | // void QTextStream::setRealNumberNotation(RealNumberNotation) |
| 376 | obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::SmartNotation)); |
| 377 | QCOMPARE(QTextStream::RealNumberNotation(QTextStream::SmartNotation), obj1.realNumberNotation()); |
| 378 | obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::FixedNotation)); |
| 379 | QCOMPARE(QTextStream::RealNumberNotation(QTextStream::FixedNotation), obj1.realNumberNotation()); |
| 380 | obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::ScientificNotation)); |
| 381 | QCOMPARE(QTextStream::RealNumberNotation(QTextStream::ScientificNotation), obj1.realNumberNotation()); |
| 382 | |
| 383 | // int QTextStream::realNumberPrecision() |
| 384 | // void QTextStream::setRealNumberPrecision(int) |
| 385 | obj1.setRealNumberPrecision(0); |
| 386 | QCOMPARE(0, obj1.realNumberPrecision()); |
| 387 | obj1.setRealNumberPrecision(INT_MIN); |
| 388 | QCOMPARE(6, obj1.realNumberPrecision()); // Setting a negative precision reverts it to the default value (6). |
| 389 | obj1.setRealNumberPrecision(INT_MAX); |
| 390 | QCOMPARE(INT_MAX, obj1.realNumberPrecision()); |
| 391 | } |
| 392 | |
| 393 | void tst_QTextStream::cleanup() |
| 394 | { |
| 395 | QCoreApplication::instance()->processEvents(); |
| 396 | } |
| 397 | |
| 398 | void tst_QTextStream::cleanupTestCase() |
| 399 | { |
| 400 | #ifdef BUILTIN_TESTDATA |
| 401 | QDir::setCurrent(QCoreApplication::applicationDirPath()); |
| 402 | #endif |
| 403 | } |
| 404 | |
| 405 | // ------------------------------------------------------------------------------ |
| 406 | void tst_QTextStream::construction() |
| 407 | { |
| 408 | QTextStream stream; |
| 409 | QCOMPARE(stream.codec(), QTextCodec::codecForLocale()); |
| 410 | QCOMPARE(stream.device(), static_cast<QIODevice *>(0)); |
| 411 | QCOMPARE(stream.string(), static_cast<QString *>(0)); |
| 412 | |
| 413 | QTest::ignoreMessage(type: QtWarningMsg, message: "QTextStream: No device" ); |
| 414 | QVERIFY(stream.atEnd()); |
| 415 | |
| 416 | QTest::ignoreMessage(type: QtWarningMsg, message: "QTextStream: No device" ); |
| 417 | QCOMPARE(stream.readAll(), QString()); |
| 418 | |
| 419 | } |
| 420 | |
| 421 | void tst_QTextStream::generateLineData(bool for_QString) |
| 422 | { |
| 423 | QTest::addColumn<QByteArray>(name: "data" ); |
| 424 | QTest::addColumn<QStringList>(name: "lines" ); |
| 425 | |
| 426 | // latin-1 |
| 427 | QTest::newRow(dataTag: "emptyer" ) << QByteArray() << QStringList(); |
| 428 | QTest::newRow(dataTag: "lf" ) << QByteArray("\n" ) << (QStringList() << "" ); |
| 429 | QTest::newRow(dataTag: "crlf" ) << QByteArray("\r\n" ) << (QStringList() << "" ); |
| 430 | QTest::newRow(dataTag: "oneline/nothing" ) << QByteArray("ole" ) << (QStringList() << "ole" ); |
| 431 | QTest::newRow(dataTag: "oneline/lf" ) << QByteArray("ole\n" ) << (QStringList() << "ole" ); |
| 432 | QTest::newRow(dataTag: "oneline/crlf" ) << QByteArray("ole\r\n" ) << (QStringList() << "ole" ); |
| 433 | QTest::newRow(dataTag: "twolines/lf/lf" ) << QByteArray("ole\ndole\n" ) << (QStringList() << "ole" << "dole" ); |
| 434 | QTest::newRow(dataTag: "twolines/crlf/crlf" ) << QByteArray("ole\r\ndole\r\n" ) << (QStringList() << "ole" << "dole" ); |
| 435 | QTest::newRow(dataTag: "twolines/lf/crlf" ) << QByteArray("ole\ndole\r\n" ) << (QStringList() << "ole" << "dole" ); |
| 436 | QTest::newRow(dataTag: "twolines/lf/nothing" ) << QByteArray("ole\ndole" ) << (QStringList() << "ole" << "dole" ); |
| 437 | QTest::newRow(dataTag: "twolines/crlf/nothing" ) << QByteArray("ole\r\ndole" ) << (QStringList() << "ole" << "dole" ); |
| 438 | QTest::newRow(dataTag: "threelines/lf/lf/lf" ) << QByteArray("ole\ndole\ndoffen\n" ) << (QStringList() << "ole" << "dole" << "doffen" ); |
| 439 | QTest::newRow(dataTag: "threelines/crlf/crlf/crlf" ) << QByteArray("ole\r\ndole\r\ndoffen\r\n" ) << (QStringList() << "ole" << "dole" << "doffen" ); |
| 440 | QTest::newRow(dataTag: "threelines/crlf/crlf/nothing" ) << QByteArray("ole\r\ndole\r\ndoffen" ) << (QStringList() << "ole" << "dole" << "doffen" ); |
| 441 | |
| 442 | if (!for_QString) { |
| 443 | // utf-8 |
| 444 | QTest::newRow(dataTag: "utf8/twolines" ) |
| 445 | << QByteArray("\xef\xbb\xbf" |
| 446 | "\x66\x67\x65\x0a" |
| 447 | "\x66\x67\x65\x0a" , 11) |
| 448 | << (QStringList() << "fge" << "fge" ); |
| 449 | |
| 450 | // utf-16 |
| 451 | // one line |
| 452 | QTest::newRow(dataTag: "utf16-BE/nothing" ) |
| 453 | << QByteArray("\xfe\xff" |
| 454 | "\x00\xe5\x00\x67\x00\x65" , 8) << (QStringList() << QLatin1String("\345ge" )); |
| 455 | QTest::newRow(dataTag: "utf16-LE/nothing" ) |
| 456 | << QByteArray("\xff\xfe" |
| 457 | "\xe5\x00\x67\x00\x65\x00" , 8) << (QStringList() << QLatin1String("\345ge" )); |
| 458 | QTest::newRow(dataTag: "utf16-BE/lf" ) |
| 459 | << QByteArray("\xfe\xff" |
| 460 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" , 10) << (QStringList() << QLatin1String("\345ge" )); |
| 461 | QTest::newRow(dataTag: "utf16-LE/lf" ) |
| 462 | << QByteArray("\xff\xfe" |
| 463 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" , 10) << (QStringList() << QLatin1String("\345ge" )); |
| 464 | |
| 465 | // two lines |
| 466 | QTest::newRow(dataTag: "utf16-BE/twolines" ) |
| 467 | << QByteArray("\xfe\xff" |
| 468 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" |
| 469 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" , 18) |
| 470 | << (QStringList() << QLatin1String("\345ge" ) << QLatin1String("\345ge" )); |
| 471 | QTest::newRow(dataTag: "utf16-LE/twolines" ) |
| 472 | << QByteArray("\xff\xfe" |
| 473 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" |
| 474 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" , 18) |
| 475 | << (QStringList() << QLatin1String("\345ge" ) << QLatin1String("\345ge" )); |
| 476 | |
| 477 | // three lines |
| 478 | QTest::newRow(dataTag: "utf16-BE/threelines" ) |
| 479 | << QByteArray("\xfe\xff" |
| 480 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" |
| 481 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" |
| 482 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" , 26) |
| 483 | << (QStringList() << QLatin1String("\345ge" ) << QLatin1String("\345ge" ) << QLatin1String("\345ge" )); |
| 484 | QTest::newRow(dataTag: "utf16-LE/threelines" ) |
| 485 | << QByteArray("\xff\xfe" |
| 486 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" |
| 487 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" |
| 488 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" , 26) |
| 489 | << (QStringList() << QLatin1String("\345ge" ) << QLatin1String("\345ge" ) << QLatin1String("\345ge" )); |
| 490 | |
| 491 | // utf-32 |
| 492 | QTest::newRow(dataTag: "utf32-BE/twolines" ) |
| 493 | << QByteArray("\x00\x00\xfe\xff" |
| 494 | "\x00\x00\x00\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a" |
| 495 | "\x00\x00\x00\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a" , 36) |
| 496 | << (QStringList() << QLatin1String("\345ge" ) << QLatin1String("\345ge" )); |
| 497 | QTest::newRow(dataTag: "utf32-LE/twolines" ) |
| 498 | << QByteArray("\xff\xfe\x00\x00" |
| 499 | "\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a\x00\x00\x00" |
| 500 | "\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a\x00\x00\x00" , 36) |
| 501 | << (QStringList() << QLatin1String("\345ge" ) << QLatin1String("\345ge" )); |
| 502 | } |
| 503 | |
| 504 | // partials |
| 505 | QTest::newRow(dataTag: "cr" ) << QByteArray("\r" ) << (QStringList() << "" ); |
| 506 | QTest::newRow(dataTag: "oneline/cr" ) << QByteArray("ole\r" ) << (QStringList() << "ole" ); |
| 507 | if (!for_QString) |
| 508 | QTest::newRow(dataTag: "utf16-BE/cr" ) << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65\x00\x0d" , 10) << (QStringList() << QLatin1String("\345ge" )); |
| 509 | } |
| 510 | |
| 511 | // ------------------------------------------------------------------------------ |
| 512 | void tst_QTextStream::readLineFromDevice_data() |
| 513 | { |
| 514 | generateLineData(for_QString: false); |
| 515 | } |
| 516 | |
| 517 | // ------------------------------------------------------------------------------ |
| 518 | void tst_QTextStream::readLineFromDevice() |
| 519 | { |
| 520 | QFETCH(QByteArray, data); |
| 521 | QFETCH(QStringList, lines); |
| 522 | |
| 523 | QFile::remove(fileName: testFileName); |
| 524 | QFile file(testFileName); |
| 525 | QVERIFY(file.open(QFile::ReadWrite)); |
| 526 | QCOMPARE(file.write(data), qlonglong(data.size())); |
| 527 | QVERIFY(file.flush()); |
| 528 | file.seek(offset: 0); |
| 529 | |
| 530 | QTextStream stream(&file); |
| 531 | QStringList list; |
| 532 | while (!stream.atEnd()) |
| 533 | list << stream.readLine(); |
| 534 | |
| 535 | QCOMPARE(list, lines); |
| 536 | } |
| 537 | |
| 538 | // ------------------------------------------------------------------------------ |
| 539 | void tst_QTextStream::readLineMaxlen_data() |
| 540 | { |
| 541 | QTest::addColumn<QString>(name: "input" ); |
| 542 | QTest::addColumn<QStringList>(name: "lines" ); |
| 543 | |
| 544 | QTest::newRow(dataTag: "Hey" ) |
| 545 | << QString("Hey" ) |
| 546 | << (QStringList() << QString("Hey" ) << QString("" )); |
| 547 | QTest::newRow(dataTag: "Hey\\n" ) |
| 548 | << QString("Hey\n" ) |
| 549 | << (QStringList() << QString("Hey" ) << QString("" )); |
| 550 | QTest::newRow(dataTag: "HelloWorld" ) |
| 551 | << QString("HelloWorld" ) |
| 552 | << (QStringList() << QString("Hello" ) << QString("World" )); |
| 553 | QTest::newRow(dataTag: "Helo\\nWorlds" ) |
| 554 | << QString("Helo\nWorlds" ) |
| 555 | << (QStringList() << QString("Helo" ) << QString("World" )); |
| 556 | QTest::newRow(dataTag: "AAAAA etc." ) |
| 557 | << QString(16385, QLatin1Char('A')) |
| 558 | << (QStringList() << QString("AAAAA" ) << QString("AAAAA" )); |
| 559 | QTest::newRow(dataTag: "multibyte string" ) |
| 560 | << QString::fromUtf8(str: "\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242\341\233\232\341\232\240\n" ) |
| 561 | << (QStringList() << QString::fromUtf8(str: "\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242" ) |
| 562 | << QString::fromUtf8(str: "\341\233\232\341\232\240" )); |
| 563 | } |
| 564 | |
| 565 | // ------------------------------------------------------------------------------ |
| 566 | void tst_QTextStream::readLineMaxlen() |
| 567 | { |
| 568 | QFETCH(QString, input); |
| 569 | QFETCH(QStringList, lines); |
| 570 | for (int i = 0; i < 2; ++i) { |
| 571 | bool useDevice = (i == 1); |
| 572 | QTextStream stream; |
| 573 | QFile::remove(fileName: "testfile" ); |
| 574 | QFile file("testfile" ); |
| 575 | if (useDevice) { |
| 576 | file.open(flags: QIODevice::ReadWrite); |
| 577 | file.write(data: input.toUtf8()); |
| 578 | file.seek(offset: 0); |
| 579 | stream.setDevice(&file); |
| 580 | stream.setCodec("utf-8" ); |
| 581 | } else { |
| 582 | stream.setString(string: &input); |
| 583 | } |
| 584 | |
| 585 | QStringList list; |
| 586 | list << stream.readLine(maxlen: 5); |
| 587 | list << stream.readLine(maxlen: 5); |
| 588 | |
| 589 | QCOMPARE(list, lines); |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | // ------------------------------------------------------------------------------ |
| 594 | void tst_QTextStream::readLinesFromBufferCRCR() |
| 595 | { |
| 596 | QBuffer buffer; |
| 597 | buffer.open(openMode: QIODevice::WriteOnly); |
| 598 | QByteArray data("0123456789\r\r\n" ); |
| 599 | |
| 600 | for (int i = 0; i < 10000; ++i) |
| 601 | buffer.write(data); |
| 602 | |
| 603 | buffer.close(); |
| 604 | if (buffer.open(openMode: QIODevice::ReadOnly|QIODevice::Text)) { |
| 605 | QTextStream stream(&buffer); |
| 606 | while (!stream.atEnd()) |
| 607 | QCOMPARE(stream.readLine(), QString("0123456789" )); |
| 608 | } |
| 609 | } |
| 610 | |
| 611 | class ErrorDevice : public QIODevice |
| 612 | { |
| 613 | protected: |
| 614 | qint64 readData(char *data, qint64 maxlen) override |
| 615 | { |
| 616 | Q_UNUSED(data) |
| 617 | Q_UNUSED(maxlen) |
| 618 | return -1; |
| 619 | } |
| 620 | |
| 621 | qint64 writeData(const char *data, qint64 len) override |
| 622 | { |
| 623 | Q_UNUSED(data) |
| 624 | Q_UNUSED(len) |
| 625 | return -1; |
| 626 | } |
| 627 | }; |
| 628 | |
| 629 | void tst_QTextStream::readLineInto() |
| 630 | { |
| 631 | QByteArray data = "1\n2\n3" ; |
| 632 | |
| 633 | QTextStream ts(&data); |
| 634 | QString line; |
| 635 | |
| 636 | ts.readLineInto(line: &line); |
| 637 | QCOMPARE(line, QStringLiteral("1" )); |
| 638 | |
| 639 | ts.readLineInto(line: nullptr, maxlen: 0); // read the second line, but don't store it |
| 640 | |
| 641 | ts.readLineInto(line: &line); |
| 642 | QCOMPARE(line, QStringLiteral("3" )); |
| 643 | |
| 644 | QVERIFY(!ts.readLineInto(&line)); |
| 645 | QVERIFY(line.isEmpty()); |
| 646 | |
| 647 | QFile file(m_rfc3261FilePath); |
| 648 | QVERIFY(file.open(QFile::ReadOnly)); |
| 649 | |
| 650 | ts.setDevice(&file); |
| 651 | line.reserve(asize: 1); |
| 652 | int maxLineCapacity = line.capacity(); |
| 653 | |
| 654 | while (ts.readLineInto(line: &line)) { |
| 655 | QVERIFY(line.capacity() >= maxLineCapacity); |
| 656 | maxLineCapacity = line.capacity(); |
| 657 | } |
| 658 | |
| 659 | line = "Test string" ; |
| 660 | ErrorDevice errorDevice; |
| 661 | QVERIFY(errorDevice.open(QIODevice::ReadOnly)); |
| 662 | ts.setDevice(&errorDevice); |
| 663 | |
| 664 | QVERIFY(!ts.readLineInto(&line)); |
| 665 | QVERIFY(line.isEmpty()); |
| 666 | } |
| 667 | |
| 668 | // ------------------------------------------------------------------------------ |
| 669 | void tst_QTextStream::readLineFromString_data() |
| 670 | { |
| 671 | generateLineData(for_QString: true); |
| 672 | } |
| 673 | |
| 674 | // ------------------------------------------------------------------------------ |
| 675 | void tst_QTextStream::readLineFromString() |
| 676 | { |
| 677 | QFETCH(QByteArray, data); |
| 678 | QFETCH(QStringList, lines); |
| 679 | |
| 680 | QString dataString = data; |
| 681 | |
| 682 | QTextStream stream(&dataString, QIODevice::ReadOnly); |
| 683 | QStringList list; |
| 684 | while (!stream.atEnd()) |
| 685 | list << stream.readLine(); |
| 686 | |
| 687 | QCOMPARE(list, lines); |
| 688 | } |
| 689 | |
| 690 | // ------------------------------------------------------------------------------ |
| 691 | void tst_QTextStream::readLineFromStringThenChangeString() |
| 692 | { |
| 693 | QString first = "First string" ; |
| 694 | QString second = "Second string" ; |
| 695 | |
| 696 | QTextStream stream(&first, QIODevice::ReadOnly); |
| 697 | QString result = stream.readLine(); |
| 698 | QCOMPARE(first, result); |
| 699 | |
| 700 | stream.setString(string: &second, openMode: QIODevice::ReadOnly); |
| 701 | result = stream.readLine(); |
| 702 | QCOMPARE(second, result); |
| 703 | } |
| 704 | |
| 705 | // ------------------------------------------------------------------------------ |
| 706 | void tst_QTextStream::setDevice() |
| 707 | { |
| 708 | // Check that the read buffer is reset after setting a new device |
| 709 | QByteArray data1("Hello World" ); |
| 710 | QByteArray data2("How are you" ); |
| 711 | |
| 712 | QBuffer bufferOld(&data1); |
| 713 | bufferOld.open(openMode: QIODevice::ReadOnly); |
| 714 | |
| 715 | QBuffer bufferNew(&data2); |
| 716 | bufferNew.open(openMode: QIODevice::ReadOnly); |
| 717 | |
| 718 | QString text; |
| 719 | QTextStream stream(&bufferOld); |
| 720 | stream >> text; |
| 721 | QCOMPARE(text, QString("Hello" )); |
| 722 | |
| 723 | stream.setDevice(&bufferNew); |
| 724 | stream >> text; |
| 725 | QCOMPARE(text, QString("How" )); |
| 726 | } |
| 727 | |
| 728 | // ------------------------------------------------------------------------------ |
| 729 | void tst_QTextStream::readLineFromTextDevice_data() |
| 730 | { |
| 731 | generateLineData(for_QString: false); |
| 732 | } |
| 733 | |
| 734 | // ------------------------------------------------------------------------------ |
| 735 | void tst_QTextStream::readLineFromTextDevice() |
| 736 | { |
| 737 | QFETCH(QByteArray, data); |
| 738 | QFETCH(QStringList, lines); |
| 739 | |
| 740 | for (int i = 0; i < 8; ++i) { |
| 741 | QBuffer buffer(&data); |
| 742 | if (i < 4) |
| 743 | QVERIFY(buffer.open(QIODevice::ReadOnly | QIODevice::Text)); |
| 744 | else |
| 745 | QVERIFY(buffer.open(QIODevice::ReadOnly)); |
| 746 | |
| 747 | QTextStream stream(&buffer); |
| 748 | QStringList list; |
| 749 | while (!stream.atEnd()) { |
| 750 | stream.pos(); // <- triggers side effects |
| 751 | QString line; |
| 752 | |
| 753 | if (i & 1) { |
| 754 | QChar c; |
| 755 | while (!stream.atEnd()) { |
| 756 | stream >> c; |
| 757 | if (stream.status() == QTextStream::Ok) { |
| 758 | if (c != QLatin1Char('\n') && c != QLatin1Char('\r')) |
| 759 | line += c; |
| 760 | if (c == QLatin1Char('\n')) |
| 761 | break; |
| 762 | } |
| 763 | } |
| 764 | } else { |
| 765 | line = stream.readLine(); |
| 766 | } |
| 767 | |
| 768 | if ((i & 3) == 3 && !QString(QTest::currentDataTag()).contains(s: "utf16" )) |
| 769 | stream.seek(pos: stream.pos()); |
| 770 | list << line; |
| 771 | } |
| 772 | QCOMPARE(list, lines); |
| 773 | } |
| 774 | } |
| 775 | |
| 776 | // ------------------------------------------------------------------------------ |
| 777 | void tst_QTextStream::generateAllData(bool for_QString) |
| 778 | { |
| 779 | QTest::addColumn<QByteArray>(name: "input" ); |
| 780 | QTest::addColumn<QString>(name: "output" ); |
| 781 | |
| 782 | // latin-1 |
| 783 | QTest::newRow(dataTag: "empty" ) << QByteArray() << QString(); |
| 784 | QTest::newRow(dataTag: "latin1-a" ) << QByteArray("a" ) << QString("a" ); |
| 785 | QTest::newRow(dataTag: "latin1-a\\r" ) << QByteArray("a\r" ) << QString("a\r" ); |
| 786 | QTest::newRow(dataTag: "latin1-a\\r\\n" ) << QByteArray("a\r\n" ) << QString("a\r\n" ); |
| 787 | QTest::newRow(dataTag: "latin1-a\\n" ) << QByteArray("a\n" ) << QString("a\n" ); |
| 788 | |
| 789 | // utf-16 |
| 790 | if (!for_QString) { |
| 791 | // one line |
| 792 | QTest::newRow(dataTag: "utf16-BE/nothing" ) |
| 793 | << QByteArray("\xfe\xff" |
| 794 | "\x00\xe5\x00\x67\x00\x65" , 8) << QString::fromLatin1(str: "\345ge" ); |
| 795 | QTest::newRow(dataTag: "utf16-LE/nothing" ) |
| 796 | << QByteArray("\xff\xfe" |
| 797 | "\xe5\x00\x67\x00\x65\x00" , 8) << QString::fromLatin1(str: "\345ge" ); |
| 798 | QTest::newRow(dataTag: "utf16-BE/lf" ) |
| 799 | << QByteArray("\xfe\xff" |
| 800 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" , 10) << QString::fromLatin1(str: "\345ge\n" ); |
| 801 | QTest::newRow(dataTag: "utf16-LE/lf" ) |
| 802 | << QByteArray("\xff\xfe" |
| 803 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" , 10) << QString::fromLatin1(str: "\345ge\n" ); |
| 804 | QTest::newRow(dataTag: "utf16-BE/crlf" ) |
| 805 | << QByteArray("\xfe\xff" |
| 806 | "\x00\xe5\x00\x67\x00\x65\x00\x0d\x00\x0a" , 12) << QString::fromLatin1(str: "\345ge\r\n" ); |
| 807 | QTest::newRow(dataTag: "utf16-LE/crlf" ) |
| 808 | << QByteArray("\xff\xfe" |
| 809 | "\xe5\x00\x67\x00\x65\x00\x0d\x00\x0a\x00" , 12) << QString::fromLatin1(str: "\345ge\r\n" ); |
| 810 | |
| 811 | // two lines |
| 812 | QTest::newRow(dataTag: "utf16-BE/twolines" ) |
| 813 | << QByteArray("\xfe\xff" |
| 814 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" |
| 815 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" , 18) |
| 816 | << QString::fromLatin1(str: "\345ge\n\345ge\n" ); |
| 817 | QTest::newRow(dataTag: "utf16-LE/twolines" ) |
| 818 | << QByteArray("\xff\xfe" |
| 819 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" |
| 820 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" , 18) |
| 821 | << QString::fromLatin1(str: "\345ge\n\345ge\n" ); |
| 822 | |
| 823 | // three lines |
| 824 | QTest::newRow(dataTag: "utf16-BE/threelines" ) |
| 825 | << QByteArray("\xfe\xff" |
| 826 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" |
| 827 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" |
| 828 | "\x00\xe5\x00\x67\x00\x65\x00\x0a" , 26) |
| 829 | << QString::fromLatin1(str: "\345ge\n\345ge\n\345ge\n" ); |
| 830 | QTest::newRow(dataTag: "utf16-LE/threelines" ) |
| 831 | << QByteArray("\xff\xfe" |
| 832 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" |
| 833 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" |
| 834 | "\xe5\x00\x67\x00\x65\x00\x0a\x00" , 26) |
| 835 | << QString::fromLatin1(str: "\345ge\n\345ge\n\345ge\n" ); |
| 836 | } |
| 837 | } |
| 838 | |
| 839 | // ------------------------------------------------------------------------------ |
| 840 | void tst_QTextStream::readLineUntilNull() |
| 841 | { |
| 842 | QFile file(m_rfc3261FilePath); |
| 843 | QVERIFY(file.open(QFile::ReadOnly)); |
| 844 | |
| 845 | QTextStream stream(&file); |
| 846 | for (int i = 0; i < 15066; ++i) { |
| 847 | QString line = stream.readLine(); |
| 848 | QVERIFY(!line.isNull()); |
| 849 | QVERIFY(!line.isNull()); |
| 850 | } |
| 851 | QVERIFY(!stream.readLine().isNull()); |
| 852 | QVERIFY(stream.readLine().isNull()); |
| 853 | } |
| 854 | |
| 855 | // ------------------------------------------------------------------------------ |
| 856 | void tst_QTextStream::readAllFromDevice_data() |
| 857 | { |
| 858 | generateAllData(for_QString: false); |
| 859 | } |
| 860 | |
| 861 | // ------------------------------------------------------------------------------ |
| 862 | void tst_QTextStream::readAllFromDevice() |
| 863 | { |
| 864 | QFETCH(QByteArray, input); |
| 865 | QFETCH(QString, output); |
| 866 | |
| 867 | QBuffer buffer(&input); |
| 868 | buffer.open(openMode: QBuffer::ReadOnly); |
| 869 | |
| 870 | QTextStream stream(&buffer); |
| 871 | QCOMPARE(stream.readAll(), output); |
| 872 | } |
| 873 | |
| 874 | // ------------------------------------------------------------------------------ |
| 875 | void tst_QTextStream::readAllFromString_data() |
| 876 | { |
| 877 | generateAllData(for_QString: true); |
| 878 | } |
| 879 | |
| 880 | // ------------------------------------------------------------------------------ |
| 881 | void tst_QTextStream::readAllFromString() |
| 882 | { |
| 883 | QFETCH(QByteArray, input); |
| 884 | QFETCH(QString, output); |
| 885 | |
| 886 | QString str = input; |
| 887 | |
| 888 | QTextStream stream(&str); |
| 889 | QCOMPARE(stream.readAll(), output); |
| 890 | } |
| 891 | |
| 892 | // ------------------------------------------------------------------------------ |
| 893 | void tst_QTextStream::skipWhiteSpace_data() |
| 894 | { |
| 895 | QTest::addColumn<QByteArray>(name: "input" ); |
| 896 | QTest::addColumn<QChar>(name: "output" ); |
| 897 | |
| 898 | // latin1 |
| 899 | QTest::newRow(dataTag: "empty" ) << QByteArray() << QChar('\0'); |
| 900 | QTest::newRow(dataTag: " one" ) << QByteArray(" one" ) << QChar('o'); |
| 901 | QTest::newRow(dataTag: "\\none" ) << QByteArray("\none" ) << QChar('o'); |
| 902 | QTest::newRow(dataTag: "\\n one" ) << QByteArray("\n one" ) << QChar('o'); |
| 903 | QTest::newRow(dataTag: " \\r\\n one" ) << QByteArray(" \r\n one" ) << QChar('o'); |
| 904 | |
| 905 | // utf-16 |
| 906 | QTest::newRow(dataTag: "utf16-BE (empty)" ) << QByteArray("\xfe\xff" , 2) << QChar('\0'); |
| 907 | QTest::newRow(dataTag: "utf16-BE ( one)" ) << QByteArray("\xfe\xff\x00 \x00o\x00n\x00e" , 10) << QChar('o'); |
| 908 | QTest::newRow(dataTag: "utf16-BE (\\none)" ) << QByteArray("\xfe\xff\x00\n\x00o\x00n\x00e" , 10) << QChar('o'); |
| 909 | QTest::newRow(dataTag: "utf16-BE (\\n one)" ) << QByteArray("\xfe\xff\x00\n\x00 \x00o\x00n\x00e" , 12) << QChar('o'); |
| 910 | QTest::newRow(dataTag: "utf16-BE ( \\r\\n one)" ) << QByteArray("\xfe\xff\x00 \x00\r\x00\n\x00 \x00o\x00n\x00e" , 16) << QChar('o'); |
| 911 | |
| 912 | QTest::newRow(dataTag: "utf16-LE (empty)" ) << QByteArray("\xff\xfe" , 2) << QChar('\0'); |
| 913 | QTest::newRow(dataTag: "utf16-LE ( one)" ) << QByteArray("\xff\xfe \x00o\x00n\x00e\x00" , 10) << QChar('o'); |
| 914 | QTest::newRow(dataTag: "utf16-LE (\\none)" ) << QByteArray("\xff\xfe\n\x00o\x00n\x00e\x00" , 10) << QChar('o'); |
| 915 | QTest::newRow(dataTag: "utf16-LE (\\n one)" ) << QByteArray("\xff\xfe\n\x00 \x00o\x00n\x00e\x00" , 12) << QChar('o'); |
| 916 | QTest::newRow(dataTag: "utf16-LE ( \\r\\n one)" ) << QByteArray("\xff\xfe \x00\r\x00\n\x00 \x00o\x00n\x00e\x00" , 16) << QChar('o'); |
| 917 | } |
| 918 | |
| 919 | // ------------------------------------------------------------------------------ |
| 920 | void tst_QTextStream::skipWhiteSpace() |
| 921 | { |
| 922 | QFETCH(QByteArray, input); |
| 923 | QFETCH(QChar, output); |
| 924 | |
| 925 | QBuffer buffer(&input); |
| 926 | buffer.open(openMode: QBuffer::ReadOnly); |
| 927 | |
| 928 | QTextStream stream(&buffer); |
| 929 | stream.skipWhiteSpace(); |
| 930 | |
| 931 | QChar tmp; |
| 932 | stream >> tmp; |
| 933 | |
| 934 | QCOMPARE(tmp, output); |
| 935 | |
| 936 | QString str = input; |
| 937 | QTextStream stream2(&input); |
| 938 | stream2.skipWhiteSpace(); |
| 939 | |
| 940 | stream2 >> tmp; |
| 941 | |
| 942 | QCOMPARE(tmp, output); |
| 943 | } |
| 944 | |
| 945 | // ------------------------------------------------------------------------------ |
| 946 | void tst_QTextStream::lineCount_data() |
| 947 | { |
| 948 | QTest::addColumn<QByteArray>(name: "data" ); |
| 949 | QTest::addColumn<int>(name: "lineCount" ); |
| 950 | |
| 951 | QTest::newRow(dataTag: "empty" ) << QByteArray() << 0; |
| 952 | QTest::newRow(dataTag: "oneline" ) << QByteArray("a\n" ) << 1; |
| 953 | QTest::newRow(dataTag: "twolines" ) << QByteArray("a\nb\n" ) << 2; |
| 954 | QTest::newRow(dataTag: "oneemptyline" ) << QByteArray("\n" ) << 1; |
| 955 | QTest::newRow(dataTag: "twoemptylines" ) << QByteArray("\n\n" ) << 2; |
| 956 | QTest::newRow(dataTag: "buffersize-1 line" ) << QByteArray(16382, '\n') << 16382; |
| 957 | QTest::newRow(dataTag: "buffersize line" ) << QByteArray(16383, '\n') << 16383; |
| 958 | QTest::newRow(dataTag: "buffersize+1 line" ) << QByteArray(16384, '\n') << 16384; |
| 959 | QTest::newRow(dataTag: "buffersize+2 line" ) << QByteArray(16385, '\n') << 16385; |
| 960 | |
| 961 | QFile file(m_rfc3261FilePath); file.open(flags: QFile::ReadOnly); |
| 962 | QTest::newRow(dataTag: "rfc3261" ) << file.readAll() << 15067; |
| 963 | } |
| 964 | |
| 965 | // ------------------------------------------------------------------------------ |
| 966 | void tst_QTextStream::lineCount() |
| 967 | { |
| 968 | QFETCH(QByteArray, data); |
| 969 | QFETCH(int, lineCount); |
| 970 | |
| 971 | QFile out("out.txt" ); |
| 972 | out.open(flags: QFile::WriteOnly); |
| 973 | |
| 974 | QTextStream lineReader(data); |
| 975 | int lines = 0; |
| 976 | while (!lineReader.atEnd()) { |
| 977 | QString line = lineReader.readLine(); |
| 978 | out.write(data: line.toLatin1() + "\n" ); |
| 979 | ++lines; |
| 980 | } |
| 981 | |
| 982 | out.close(); |
| 983 | QCOMPARE(lines, lineCount); |
| 984 | } |
| 985 | |
| 986 | // ------------------------------------------------------------------------------ |
| 987 | struct CompareIndicesForArray |
| 988 | { |
| 989 | int *array; |
| 990 | CompareIndicesForArray(int *array) : array(array) {} |
| 991 | bool operator() (const int i1, const int i2) |
| 992 | { |
| 993 | return array[i1] < array[i2]; |
| 994 | } |
| 995 | }; |
| 996 | |
| 997 | void tst_QTextStream::performance() |
| 998 | { |
| 999 | // Phase #1 - test speed of reading a huge text file with QFile. |
| 1000 | QElapsedTimer stopWatch; |
| 1001 | |
| 1002 | const int N = 3; |
| 1003 | const char * readMethods[N] = { |
| 1004 | "QFile::readLine()" , |
| 1005 | "QTextStream::readLine()" , |
| 1006 | "QTextStream::readLine(QString *)" |
| 1007 | }; |
| 1008 | int elapsed[N] = {0, 0, 0}; |
| 1009 | |
| 1010 | stopWatch.restart(); |
| 1011 | int nlines1 = 0; |
| 1012 | QFile file(m_rfc3261FilePath); |
| 1013 | QVERIFY(file.open(QFile::ReadOnly)); |
| 1014 | |
| 1015 | while (!file.atEnd()) { |
| 1016 | ++nlines1; |
| 1017 | file.readLine(); |
| 1018 | } |
| 1019 | |
| 1020 | elapsed[0] = stopWatch.elapsed(); |
| 1021 | stopWatch.restart(); |
| 1022 | |
| 1023 | int nlines2 = 0; |
| 1024 | QFile file2(m_rfc3261FilePath); |
| 1025 | QVERIFY(file2.open(QFile::ReadOnly)); |
| 1026 | |
| 1027 | QTextStream stream(&file2); |
| 1028 | while (!stream.atEnd()) { |
| 1029 | ++nlines2; |
| 1030 | stream.readLine(); |
| 1031 | } |
| 1032 | |
| 1033 | elapsed[1] = stopWatch.elapsed(); |
| 1034 | stopWatch.restart(); |
| 1035 | |
| 1036 | int nlines3 = 0; |
| 1037 | QFile file3(m_rfc3261FilePath); |
| 1038 | QVERIFY(file3.open(QFile::ReadOnly)); |
| 1039 | |
| 1040 | QTextStream stream2(&file3); |
| 1041 | QString line; |
| 1042 | while (stream2.readLineInto(line: &line)) |
| 1043 | ++nlines3; |
| 1044 | |
| 1045 | elapsed[2] = stopWatch.elapsed(); |
| 1046 | |
| 1047 | QCOMPARE(nlines1, nlines2); |
| 1048 | QCOMPARE(nlines2, nlines3); |
| 1049 | |
| 1050 | for (int i = 0; i < N; i++) { |
| 1051 | qDebug(msg: "%s used %.3f seconds to read the file" , readMethods[i], |
| 1052 | elapsed[i] / 1000.0); |
| 1053 | } |
| 1054 | |
| 1055 | int idx[N] = {0, 1, 2}; |
| 1056 | std::sort(first: idx, last: idx + N, comp: CompareIndicesForArray(elapsed)); |
| 1057 | |
| 1058 | for (int i = 0; i < N-1; i++) { |
| 1059 | int i1 = idx[i]; |
| 1060 | int i2 = idx[i+1]; |
| 1061 | qDebug(msg: "Reading by %s is %.2fx faster than by %s" , |
| 1062 | readMethods[i1], |
| 1063 | double(elapsed[i2]) / double(elapsed[i1]), |
| 1064 | readMethods[i2]); |
| 1065 | } |
| 1066 | } |
| 1067 | |
| 1068 | // ------------------------------------------------------------------------------ |
| 1069 | void tst_QTextStream::hexTest_data() |
| 1070 | { |
| 1071 | QTest::addColumn<qlonglong>(name: "number" ); |
| 1072 | QTest::addColumn<QByteArray>(name: "data" ); |
| 1073 | |
| 1074 | QTest::newRow(dataTag: "0" ) << Q_INT64_C(0) << QByteArray("0x0" ); |
| 1075 | QTest::newRow(dataTag: "1" ) << Q_INT64_C(1) << QByteArray("0x1" ); |
| 1076 | QTest::newRow(dataTag: "2" ) << Q_INT64_C(2) << QByteArray("0x2" ); |
| 1077 | QTest::newRow(dataTag: "3" ) << Q_INT64_C(3) << QByteArray("0x3" ); |
| 1078 | QTest::newRow(dataTag: "4" ) << Q_INT64_C(4) << QByteArray("0x4" ); |
| 1079 | QTest::newRow(dataTag: "5" ) << Q_INT64_C(5) << QByteArray("0x5" ); |
| 1080 | QTest::newRow(dataTag: "6" ) << Q_INT64_C(6) << QByteArray("0x6" ); |
| 1081 | QTest::newRow(dataTag: "7" ) << Q_INT64_C(7) << QByteArray("0x7" ); |
| 1082 | QTest::newRow(dataTag: "8" ) << Q_INT64_C(8) << QByteArray("0x8" ); |
| 1083 | QTest::newRow(dataTag: "9" ) << Q_INT64_C(9) << QByteArray("0x9" ); |
| 1084 | QTest::newRow(dataTag: "a" ) << Q_INT64_C(0xa) << QByteArray("0xa" ); |
| 1085 | QTest::newRow(dataTag: "b" ) << Q_INT64_C(0xb) << QByteArray("0xb" ); |
| 1086 | QTest::newRow(dataTag: "c" ) << Q_INT64_C(0xc) << QByteArray("0xc" ); |
| 1087 | QTest::newRow(dataTag: "d" ) << Q_INT64_C(0xd) << QByteArray("0xd" ); |
| 1088 | QTest::newRow(dataTag: "e" ) << Q_INT64_C(0xe) << QByteArray("0xe" ); |
| 1089 | QTest::newRow(dataTag: "f" ) << Q_INT64_C(0xf) << QByteArray("0xf" ); |
| 1090 | QTest::newRow(dataTag: "-1" ) << Q_INT64_C(-1) << QByteArray("-0x1" ); |
| 1091 | QTest::newRow(dataTag: "0xffffffff" ) << Q_INT64_C(0xffffffff) << QByteArray("0xffffffff" ); |
| 1092 | QTest::newRow(dataTag: "0xfffffffffffffffe" ) << Q_INT64_C(0xfffffffffffffffe) << QByteArray("-0x2" ); |
| 1093 | QTest::newRow(dataTag: "0xffffffffffffffff" ) << Q_INT64_C(0xffffffffffffffff) << QByteArray("-0x1" ); |
| 1094 | QTest::newRow(dataTag: "0x7fffffffffffffff" ) << Q_INT64_C(0x7fffffffffffffff) << QByteArray("0x7fffffffffffffff" ); |
| 1095 | } |
| 1096 | |
| 1097 | // ------------------------------------------------------------------------------ |
| 1098 | void tst_QTextStream::hexTest() |
| 1099 | { |
| 1100 | QFETCH(qlonglong, number); |
| 1101 | QFETCH(QByteArray, data); |
| 1102 | |
| 1103 | QByteArray array; |
| 1104 | QTextStream stream(&array); |
| 1105 | |
| 1106 | stream << Qt::showbase << Qt::hex << number; |
| 1107 | stream.flush(); |
| 1108 | QCOMPARE(array, data); |
| 1109 | } |
| 1110 | |
| 1111 | // ------------------------------------------------------------------------------ |
| 1112 | void tst_QTextStream::binTest_data() |
| 1113 | { |
| 1114 | QTest::addColumn<int>(name: "number" ); |
| 1115 | QTest::addColumn<QByteArray>(name: "data" ); |
| 1116 | |
| 1117 | QTest::newRow(dataTag: "0" ) << 0 << QByteArray("0b0" ); |
| 1118 | QTest::newRow(dataTag: "1" ) << 1 << QByteArray("0b1" ); |
| 1119 | QTest::newRow(dataTag: "2" ) << 2 << QByteArray("0b10" ); |
| 1120 | QTest::newRow(dataTag: "5" ) << 5 << QByteArray("0b101" ); |
| 1121 | QTest::newRow(dataTag: "-1" ) << -1 << QByteArray("-0b1" ); |
| 1122 | QTest::newRow(dataTag: "11111111" ) << 0xff << QByteArray("0b11111111" ); |
| 1123 | QTest::newRow(dataTag: "1111111111111111" ) << 0xffff << QByteArray("0b1111111111111111" ); |
| 1124 | QTest::newRow(dataTag: "1111111011111110" ) << 0xfefe << QByteArray("0b1111111011111110" ); |
| 1125 | } |
| 1126 | |
| 1127 | // ------------------------------------------------------------------------------ |
| 1128 | void tst_QTextStream::binTest() |
| 1129 | { |
| 1130 | QFETCH(int, number); |
| 1131 | QFETCH(QByteArray, data); |
| 1132 | |
| 1133 | QByteArray array; |
| 1134 | QTextStream stream(&array); |
| 1135 | |
| 1136 | stream << Qt::showbase << Qt::bin << number; |
| 1137 | stream.flush(); |
| 1138 | QCOMPARE(array.constData(), data.constData()); |
| 1139 | } |
| 1140 | |
| 1141 | // ------------------------------------------------------------------------------ |
| 1142 | void tst_QTextStream::octTest_data() |
| 1143 | { |
| 1144 | QTest::addColumn<int>(name: "number" ); |
| 1145 | QTest::addColumn<QByteArray>(name: "data" ); |
| 1146 | |
| 1147 | QTest::newRow(dataTag: "0" ) << 0 << QByteArray("00" ); |
| 1148 | } |
| 1149 | |
| 1150 | // ------------------------------------------------------------------------------ |
| 1151 | void tst_QTextStream::octTest() |
| 1152 | { |
| 1153 | QFETCH(int, number); |
| 1154 | QFETCH(QByteArray, data); |
| 1155 | |
| 1156 | QByteArray array; |
| 1157 | QTextStream stream(&array); |
| 1158 | |
| 1159 | stream << Qt::showbase << Qt::oct << number; |
| 1160 | stream.flush(); |
| 1161 | QCOMPARE(array, data); |
| 1162 | } |
| 1163 | |
| 1164 | // ------------------------------------------------------------------------------ |
| 1165 | void tst_QTextStream::zeroTermination() |
| 1166 | { |
| 1167 | QTextStream stream; |
| 1168 | char c = '@'; |
| 1169 | |
| 1170 | QTest::ignoreMessage(type: QtWarningMsg, message: "QTextStream: No device" ); |
| 1171 | stream >> c; |
| 1172 | QCOMPARE(c, '\0'); |
| 1173 | |
| 1174 | c = '@'; |
| 1175 | |
| 1176 | QTest::ignoreMessage(type: QtWarningMsg, message: "QTextStream: No device" ); |
| 1177 | stream >> &c; |
| 1178 | QCOMPARE(c, '\0'); |
| 1179 | } |
| 1180 | |
| 1181 | // ------------------------------------------------------------------------------ |
| 1182 | void tst_QTextStream::ws_manipulator() |
| 1183 | { |
| 1184 | { |
| 1185 | QString string = "a b c d" ; |
| 1186 | QTextStream stream(&string); |
| 1187 | |
| 1188 | char a, b, c, d; |
| 1189 | stream >> a >> b >> c >> d; |
| 1190 | QCOMPARE(a, 'a'); |
| 1191 | QCOMPARE(b, ' '); |
| 1192 | QCOMPARE(c, 'b'); |
| 1193 | QCOMPARE(d, ' '); |
| 1194 | } |
| 1195 | { |
| 1196 | QString string = "a b c d" ; |
| 1197 | QTextStream stream(&string); |
| 1198 | |
| 1199 | char a, b, c, d; |
| 1200 | stream >> a >> Qt::ws >> b >> Qt::ws >> c >> Qt::ws >> d; |
| 1201 | QCOMPARE(a, 'a'); |
| 1202 | QCOMPARE(b, 'b'); |
| 1203 | QCOMPARE(c, 'c'); |
| 1204 | QCOMPARE(d, 'd'); |
| 1205 | } |
| 1206 | } |
| 1207 | |
| 1208 | // ------------------------------------------------------------------------------ |
| 1209 | void tst_QTextStream::stillOpenWhenAtEnd() |
| 1210 | { |
| 1211 | QFile file(QFINDTESTDATA("tst_qtextstream.cpp" )); |
| 1212 | QVERIFY(file.open(QFile::ReadOnly)); |
| 1213 | |
| 1214 | QTextStream stream(&file); |
| 1215 | while (!stream.readLine().isNull()) {} |
| 1216 | QVERIFY(file.isOpen()); |
| 1217 | |
| 1218 | if (!QtNetworkSettings::verifyTestNetworkSettings()) |
| 1219 | QSKIP("No network test server available" ); |
| 1220 | |
| 1221 | QTcpSocket socket; |
| 1222 | socket.connectToHost(hostName: QtNetworkSettings::serverName(), port: 143); |
| 1223 | QVERIFY(socket.waitForReadyRead(5000)); |
| 1224 | |
| 1225 | QTextStream stream2(&socket); |
| 1226 | while (!stream2.readLine().isNull()) {} |
| 1227 | QVERIFY(socket.isOpen()); |
| 1228 | } |
| 1229 | |
| 1230 | // ------------------------------------------------------------------------------ |
| 1231 | void tst_QTextStream::readNewlines_data() |
| 1232 | { |
| 1233 | QTest::addColumn<QByteArray>(name: "input" ); |
| 1234 | QTest::addColumn<QString>(name: "output" ); |
| 1235 | |
| 1236 | QTest::newRow(dataTag: "empty" ) << QByteArray() << QString(); |
| 1237 | QTest::newRow(dataTag: "\\r\\n" ) << QByteArray("\r\n" ) << QString("\n" ); |
| 1238 | QTest::newRow(dataTag: "\\r\\r\\n" ) << QByteArray("\r\r\n" ) << QString("\n" ); |
| 1239 | QTest::newRow(dataTag: "\\r\\n\\r\\n" ) << QByteArray("\r\n\r\n" ) << QString("\n\n" ); |
| 1240 | QTest::newRow(dataTag: "\\n" ) << QByteArray("\n" ) << QString("\n" ); |
| 1241 | QTest::newRow(dataTag: "\\n\\n" ) << QByteArray("\n\n" ) << QString("\n\n" ); |
| 1242 | } |
| 1243 | |
| 1244 | // ------------------------------------------------------------------------------ |
| 1245 | void tst_QTextStream::readNewlines() |
| 1246 | { |
| 1247 | QFETCH(QByteArray, input); |
| 1248 | QFETCH(QString, output); |
| 1249 | |
| 1250 | QBuffer buffer(&input); |
| 1251 | buffer.open(openMode: QBuffer::ReadOnly | QBuffer::Text); |
| 1252 | QTextStream stream(&buffer); |
| 1253 | QCOMPARE(stream.readAll(), output); |
| 1254 | } |
| 1255 | |
| 1256 | // ------------------------------------------------------------------------------ |
| 1257 | void tst_QTextStream::seek() |
| 1258 | { |
| 1259 | QFile file(m_rfc3261FilePath); |
| 1260 | QVERIFY(file.open(QFile::ReadOnly)); |
| 1261 | |
| 1262 | QTextStream stream(&file); |
| 1263 | QString tmp; |
| 1264 | stream >> tmp; |
| 1265 | QCOMPARE(tmp, QString::fromLatin1("Network" )); |
| 1266 | |
| 1267 | // QTextStream::seek(0) should both clear its internal read/write buffers |
| 1268 | // and seek the device. |
| 1269 | for (int i = 0; i < 4; ++i) { |
| 1270 | stream.seek(pos: 12 + i); |
| 1271 | stream >> tmp; |
| 1272 | QCOMPARE(tmp, QString("Network" ).mid(i)); |
| 1273 | } |
| 1274 | for (int i = 0; i < 4; ++i) { |
| 1275 | stream.seek(pos: 16 - i); |
| 1276 | stream >> tmp; |
| 1277 | QCOMPARE(tmp, QString("Network" ).mid(4 - i)); |
| 1278 | } |
| 1279 | stream.seek(pos: 139181); |
| 1280 | stream >> tmp; |
| 1281 | QCOMPARE(tmp, QString("information" )); |
| 1282 | stream.seek(pos: 388683); |
| 1283 | stream >> tmp; |
| 1284 | QCOMPARE(tmp, QString("telephone" )); |
| 1285 | |
| 1286 | // Also test this with a string |
| 1287 | QString words = QLatin1String("thisisa" ); |
| 1288 | QTextStream stream2(&words, QIODevice::ReadOnly); |
| 1289 | stream2 >> tmp; |
| 1290 | QCOMPARE(tmp, QString::fromLatin1("thisisa" )); |
| 1291 | |
| 1292 | for (int i = 0; i < 4; ++i) { |
| 1293 | stream2.seek(pos: i); |
| 1294 | stream2 >> tmp; |
| 1295 | QCOMPARE(tmp, QString("thisisa" ).mid(i)); |
| 1296 | } |
| 1297 | for (int i = 0; i < 4; ++i) { |
| 1298 | stream2.seek(pos: 4 - i); |
| 1299 | stream2 >> tmp; |
| 1300 | QCOMPARE(tmp, QString("thisisa" ).mid(4 - i)); |
| 1301 | } |
| 1302 | } |
| 1303 | |
| 1304 | // ------------------------------------------------------------------------------ |
| 1305 | void tst_QTextStream::pos() |
| 1306 | { |
| 1307 | { |
| 1308 | // Strings |
| 1309 | QString str("this is a test" ); |
| 1310 | QTextStream stream(&str, QIODevice::ReadWrite); |
| 1311 | |
| 1312 | QCOMPARE(stream.pos(), qint64(0)); |
| 1313 | for (int i = 0; i <= str.size(); ++i) { |
| 1314 | QVERIFY(stream.seek(i)); |
| 1315 | QCOMPARE(stream.pos(), qint64(i)); |
| 1316 | } |
| 1317 | for (int j = str.size(); j >= 0; --j) { |
| 1318 | QVERIFY(stream.seek(j)); |
| 1319 | QCOMPARE(stream.pos(), qint64(j)); |
| 1320 | } |
| 1321 | |
| 1322 | QVERIFY(stream.seek(0)); |
| 1323 | |
| 1324 | QChar ch; |
| 1325 | stream >> ch; |
| 1326 | QCOMPARE(ch, QChar('t')); |
| 1327 | |
| 1328 | QCOMPARE(stream.pos(), qint64(1)); |
| 1329 | QVERIFY(stream.seek(1)); |
| 1330 | QCOMPARE(stream.pos(), qint64(1)); |
| 1331 | QVERIFY(stream.seek(0)); |
| 1332 | |
| 1333 | QString strtmp; |
| 1334 | stream >> strtmp; |
| 1335 | QCOMPARE(strtmp, QString("this" )); |
| 1336 | |
| 1337 | QCOMPARE(stream.pos(), qint64(4)); |
| 1338 | stream.seek(pos: 0); |
| 1339 | stream.seek(pos: 4); |
| 1340 | |
| 1341 | stream >> ch; |
| 1342 | QCOMPARE(ch, QChar(' ')); |
| 1343 | QCOMPARE(stream.pos(), qint64(5)); |
| 1344 | |
| 1345 | stream.seek(pos: 10); |
| 1346 | stream >> strtmp; |
| 1347 | QCOMPARE(strtmp, QString("test" )); |
| 1348 | QCOMPARE(stream.pos(), qint64(14)); |
| 1349 | } |
| 1350 | { |
| 1351 | // Latin1 device |
| 1352 | QFile file(m_rfc3261FilePath); |
| 1353 | QVERIFY(file.open(QIODevice::ReadOnly)); |
| 1354 | |
| 1355 | QTextStream stream(&file); |
| 1356 | |
| 1357 | QCOMPARE(stream.pos(), qint64(0)); |
| 1358 | |
| 1359 | for (int i = 0; i <= file.size(); i += 7) { |
| 1360 | QVERIFY(stream.seek(i)); |
| 1361 | QCOMPARE(stream.pos(), qint64(i)); |
| 1362 | } |
| 1363 | for (int j = file.size(); j >= 0; j -= 7) { |
| 1364 | QVERIFY(stream.seek(j)); |
| 1365 | QCOMPARE(stream.pos(), qint64(j)); |
| 1366 | } |
| 1367 | |
| 1368 | stream.seek(pos: 0); |
| 1369 | |
| 1370 | QString strtmp; |
| 1371 | stream >> strtmp; |
| 1372 | QCOMPARE(strtmp, QString("Network" )); |
| 1373 | QCOMPARE(stream.pos(), qint64(19)); |
| 1374 | |
| 1375 | stream.seek(pos: 2598); |
| 1376 | QCOMPARE(stream.pos(), qint64(2598)); |
| 1377 | stream >> strtmp; |
| 1378 | QCOMPARE(stream.pos(), qint64(2607)); |
| 1379 | QCOMPARE(strtmp, QString("locations" )); |
| 1380 | } |
| 1381 | { |
| 1382 | // Shift-JIS device |
| 1383 | for (int i = 0; i < 2; ++i) { |
| 1384 | QFile file(m_shiftJisFilePath); |
| 1385 | if (i == 0) |
| 1386 | QVERIFY(file.open(QIODevice::ReadOnly)); |
| 1387 | else |
| 1388 | QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); |
| 1389 | |
| 1390 | QTextStream stream(&file); |
| 1391 | stream.setCodec("Shift-JIS" ); |
| 1392 | QVERIFY(stream.codec()); |
| 1393 | |
| 1394 | QCOMPARE(stream.pos(), qint64(0)); |
| 1395 | for (int i = 0; i <= file.size(); i += 7) { |
| 1396 | QVERIFY(stream.seek(i)); |
| 1397 | QCOMPARE(stream.pos(), qint64(i)); |
| 1398 | } |
| 1399 | for (int j = file.size(); j >= 0; j -= 7) { |
| 1400 | QVERIFY(stream.seek(j)); |
| 1401 | QCOMPARE(stream.pos(), qint64(j)); |
| 1402 | } |
| 1403 | |
| 1404 | stream.seek(pos: 2089); |
| 1405 | QString strtmp; |
| 1406 | stream >> strtmp; |
| 1407 | QCOMPARE(strtmp, QString("AUnicode" )); |
| 1408 | QCOMPARE(stream.pos(), qint64(2097)); |
| 1409 | |
| 1410 | stream.seek(pos: 43325); |
| 1411 | stream >> strtmp; |
| 1412 | QCOMPARE(strtmp, QString("Shift-JIS" )); |
| 1413 | stream >> strtmp; |
| 1414 | QCOMPARE(strtmp, QString::fromUtf8("\343\201\247\346\233\270\343\201\213\343\202\214\343\201\237" )); |
| 1415 | QCOMPARE(stream.pos(), qint64(43345)); |
| 1416 | stream >> strtmp; |
| 1417 | QCOMPARE(strtmp, QString("POD" )); |
| 1418 | QCOMPARE(stream.pos(), qint64(43349)); |
| 1419 | } |
| 1420 | } |
| 1421 | } |
| 1422 | |
| 1423 | // ------------------------------------------------------------------------------ |
| 1424 | void tst_QTextStream::pos2() |
| 1425 | { |
| 1426 | QByteArray data("abcdef\r\nghijkl\r\n" ); |
| 1427 | QBuffer buffer(&data); |
| 1428 | QVERIFY(buffer.open(QIODevice::ReadOnly | QIODevice::Text)); |
| 1429 | |
| 1430 | QTextStream stream(&buffer); |
| 1431 | |
| 1432 | QChar ch; |
| 1433 | |
| 1434 | QCOMPARE(stream.pos(), qint64(0)); |
| 1435 | stream >> ch; |
| 1436 | QCOMPARE(ch, QChar('a')); |
| 1437 | QCOMPARE(stream.pos(), qint64(1)); |
| 1438 | |
| 1439 | QString str; |
| 1440 | stream >> str; |
| 1441 | QCOMPARE(str, QString("bcdef" )); |
| 1442 | QCOMPARE(stream.pos(), qint64(6)); |
| 1443 | |
| 1444 | stream >> str; |
| 1445 | QCOMPARE(str, QString("ghijkl" )); |
| 1446 | QCOMPARE(stream.pos(), qint64(14)); |
| 1447 | |
| 1448 | // Seek back and try again |
| 1449 | stream.seek(pos: 1); |
| 1450 | QCOMPARE(stream.pos(), qint64(1)); |
| 1451 | stream >> str; |
| 1452 | QCOMPARE(str, QString("bcdef" )); |
| 1453 | QCOMPARE(stream.pos(), qint64(6)); |
| 1454 | |
| 1455 | stream.seek(pos: 6); |
| 1456 | stream >> str; |
| 1457 | QCOMPARE(str, QString("ghijkl" )); |
| 1458 | QCOMPARE(stream.pos(), qint64(14)); |
| 1459 | } |
| 1460 | |
| 1461 | // ------------------------------------------------------------------------------ |
| 1462 | void tst_QTextStream::pos3LargeFile() |
| 1463 | { |
| 1464 | if (EmulationDetector::isRunningArmOnX86()) |
| 1465 | QSKIP("Running QTextStream::pos() in tight loop is too slow on emulator" ); |
| 1466 | |
| 1467 | { |
| 1468 | QFile file(testFileName); |
| 1469 | file.open(flags: QIODevice::WriteOnly | QIODevice::Text); |
| 1470 | QTextStream out( &file ); |
| 1471 | // NOTE: The unusual spacing is to ensure non-1-character whitespace. |
| 1472 | QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n" ; |
| 1473 | // Approximate 50kb text file |
| 1474 | const int NbLines = (50*1024) / lineString.length() + 1; |
| 1475 | for (int line = 0; line < NbLines; ++line) |
| 1476 | out << lineString; |
| 1477 | // File is automatically flushed and closed on destruction. |
| 1478 | } |
| 1479 | QFile file(testFileName); |
| 1480 | file.open(flags: QIODevice::ReadOnly | QIODevice::Text); |
| 1481 | QTextStream in( &file ); |
| 1482 | const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; |
| 1483 | int value; |
| 1484 | while (true) { |
| 1485 | in.pos(); |
| 1486 | for ( int i = 0; i < 10; ++i ) { |
| 1487 | in >> value; |
| 1488 | if (in.status() != QTextStream::Ok) { |
| 1489 | // End case, i == 0 && eof reached. |
| 1490 | QCOMPARE(i, 0); |
| 1491 | QCOMPARE(in.status(), QTextStream::ReadPastEnd); |
| 1492 | return; |
| 1493 | } |
| 1494 | QCOMPARE(value, testValues[i]); |
| 1495 | } |
| 1496 | } |
| 1497 | } |
| 1498 | |
| 1499 | // ------------------------------------------------------------------------------ |
| 1500 | void tst_QTextStream::readStdin() |
| 1501 | { |
| 1502 | #if !QT_CONFIG(process) |
| 1503 | QSKIP("No qprocess support" , SkipAll); |
| 1504 | #else |
| 1505 | QProcess stdinProcess; |
| 1506 | stdinProcess.start(command: "stdinProcess/stdinProcess" ); |
| 1507 | stdinProcess.setReadChannel(QProcess::StandardError); |
| 1508 | |
| 1509 | QTextStream stream(&stdinProcess); |
| 1510 | stream << "1" << Qt::endl; |
| 1511 | stream << "2" << Qt::endl; |
| 1512 | stream << "3" << Qt::endl; |
| 1513 | |
| 1514 | stdinProcess.closeWriteChannel(); |
| 1515 | |
| 1516 | QVERIFY(stdinProcess.waitForFinished(5000)); |
| 1517 | |
| 1518 | int a, b, c; |
| 1519 | stream >> a >> b >> c; |
| 1520 | QCOMPARE(a, 1); |
| 1521 | QCOMPARE(b, 2); |
| 1522 | QCOMPARE(c, 3); |
| 1523 | #endif |
| 1524 | } |
| 1525 | |
| 1526 | // ------------------------------------------------------------------------------ |
| 1527 | void tst_QTextStream::readAllFromStdin() |
| 1528 | { |
| 1529 | #if !QT_CONFIG(process) |
| 1530 | QSKIP("No qprocess support" , SkipAll); |
| 1531 | #else |
| 1532 | QProcess stdinProcess; |
| 1533 | stdinProcess.start(command: "readAllStdinProcess/readAllStdinProcess" , mode: QIODevice::ReadWrite | QIODevice::Text); |
| 1534 | stdinProcess.setReadChannel(QProcess::StandardError); |
| 1535 | |
| 1536 | QTextStream stream(&stdinProcess); |
| 1537 | stream.setCodec("ISO-8859-1" ); |
| 1538 | stream << "hello world" << Qt::flush; |
| 1539 | |
| 1540 | stdinProcess.closeWriteChannel(); |
| 1541 | |
| 1542 | QVERIFY(stdinProcess.waitForFinished(5000)); |
| 1543 | QCOMPARE(stream.readAll(), QString::fromLatin1("hello world\n" )); |
| 1544 | #endif |
| 1545 | } |
| 1546 | |
| 1547 | // ------------------------------------------------------------------------------ |
| 1548 | void tst_QTextStream::readLineFromStdin() |
| 1549 | { |
| 1550 | #if !QT_CONFIG(process) |
| 1551 | QSKIP("No qprocess support" , SkipAll); |
| 1552 | #else |
| 1553 | QProcess stdinProcess; |
| 1554 | stdinProcess.start(command: "readLineStdinProcess/readLineStdinProcess" , mode: QIODevice::ReadWrite | QIODevice::Text); |
| 1555 | stdinProcess.setReadChannel(QProcess::StandardError); |
| 1556 | |
| 1557 | stdinProcess.write(data: "abc\n" ); |
| 1558 | QVERIFY(stdinProcess.waitForReadyRead(5000)); |
| 1559 | QCOMPARE(stdinProcess.readAll().data(), QByteArray("abc" ).data()); |
| 1560 | |
| 1561 | stdinProcess.write(data: "def\n" ); |
| 1562 | QVERIFY(stdinProcess.waitForReadyRead(5000)); |
| 1563 | QCOMPARE(stdinProcess.readAll(), QByteArray("def" )); |
| 1564 | |
| 1565 | stdinProcess.closeWriteChannel(); |
| 1566 | |
| 1567 | QVERIFY(stdinProcess.waitForFinished(5000)); |
| 1568 | #endif |
| 1569 | } |
| 1570 | |
| 1571 | // ------------------------------------------------------------------------------ |
| 1572 | void tst_QTextStream::read() |
| 1573 | { |
| 1574 | { |
| 1575 | QFile::remove(fileName: "testfile" ); |
| 1576 | QFile file("testfile" ); |
| 1577 | file.open(flags: QFile::WriteOnly); |
| 1578 | file.write(data: "4.15 abc ole" ); |
| 1579 | file.close(); |
| 1580 | |
| 1581 | QVERIFY(file.open(QFile::ReadOnly)); |
| 1582 | QTextStream stream(&file); |
| 1583 | QCOMPARE(stream.read(0), QString("" )); |
| 1584 | QCOMPARE(stream.read(4), QString("4.15" )); |
| 1585 | QCOMPARE(stream.read(4), QString(" abc" )); |
| 1586 | stream.seek(pos: 1); |
| 1587 | QCOMPARE(stream.read(4), QString(".15 " )); |
| 1588 | stream.seek(pos: 1); |
| 1589 | QCOMPARE(stream.read(4), QString(".15 " )); |
| 1590 | stream.seek(pos: 2); |
| 1591 | QCOMPARE(stream.read(4), QString("15 a" )); |
| 1592 | // ### add tests for reading \r\n etc.. |
| 1593 | } |
| 1594 | |
| 1595 | { |
| 1596 | // File larger than QTEXTSTREAM_BUFFERSIZE |
| 1597 | QFile::remove(fileName: "testfile" ); |
| 1598 | QFile file("testfile" ); |
| 1599 | file.open(flags: QFile::WriteOnly); |
| 1600 | for (int i = 0; i < 16384 / 8; ++i) |
| 1601 | file.write(data: "01234567" ); |
| 1602 | file.write(data: "0" ); |
| 1603 | file.close(); |
| 1604 | |
| 1605 | QVERIFY(file.open(QFile::ReadOnly)); |
| 1606 | QTextStream stream(&file); |
| 1607 | QCOMPARE(stream.read(10), QString("0123456701" )); |
| 1608 | QCOMPARE(stream.read(10), QString("2345670123" )); |
| 1609 | QCOMPARE(stream.readAll().size(), 16385-20); |
| 1610 | } |
| 1611 | } |
| 1612 | |
| 1613 | // ------------------------------------------------------------------------------ |
| 1614 | void tst_QTextStream::qbool() |
| 1615 | { |
| 1616 | QString s; |
| 1617 | QTextStream stream(&s); |
| 1618 | stream << s.contains(s: QString("hei" )); |
| 1619 | QCOMPARE(s, QString("0" )); |
| 1620 | } |
| 1621 | |
| 1622 | // ------------------------------------------------------------------------------ |
| 1623 | void tst_QTextStream::forcePoint() |
| 1624 | { |
| 1625 | QString str; |
| 1626 | QTextStream stream(&str); |
| 1627 | stream << Qt::fixed << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1; |
| 1628 | QCOMPARE(str, QString("1.000000 1 0 -1.000000 -1" )); |
| 1629 | |
| 1630 | str.clear(); |
| 1631 | stream.seek(pos: 0); |
| 1632 | stream << Qt::scientific << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1; |
| 1633 | QCOMPARE(str, QString("1.000000e+00 1 0 -1.000000e+00 -1" )); |
| 1634 | |
| 1635 | str.clear(); |
| 1636 | stream.seek(pos: 0); |
| 1637 | stream.setRealNumberNotation(QTextStream::SmartNotation); |
| 1638 | stream << Qt::forcepoint << 1.0 << ' ' << 1 << ' ' << 0 << ' ' << -1.0 << ' ' << -1; |
| 1639 | QCOMPARE(str, QString("1.00000 1 0 -1.00000 -1" )); |
| 1640 | |
| 1641 | } |
| 1642 | |
| 1643 | // ------------------------------------------------------------------------------ |
| 1644 | void tst_QTextStream::forceSign() |
| 1645 | { |
| 1646 | QString str; |
| 1647 | QTextStream stream(&str); |
| 1648 | stream << Qt::forcesign << 1.2 << ' ' << -1.2 << ' ' << 0; |
| 1649 | QCOMPARE(str, QString("+1.2 -1.2 +0" )); |
| 1650 | } |
| 1651 | |
| 1652 | // ------------------------------------------------------------------------------ |
| 1653 | void tst_QTextStream::read0d0d0a() |
| 1654 | { |
| 1655 | QFile file("task113817.txt" ); |
| 1656 | file.open(flags: QIODevice::ReadOnly | QIODevice::Text); |
| 1657 | |
| 1658 | QTextStream stream(&file); |
| 1659 | while (!stream.atEnd()) |
| 1660 | stream.readLine(); |
| 1661 | } |
| 1662 | |
| 1663 | // ------------------------------------------------------------------------------ |
| 1664 | |
| 1665 | Q_DECLARE_METATYPE(QTextStreamFunction); |
| 1666 | |
| 1667 | // Also tests that we can have namespaces that conflict with our QTextStream constants. |
| 1668 | namespace ws { |
| 1669 | QTextStream &noop(QTextStream &s) { return s; } |
| 1670 | } |
| 1671 | |
| 1672 | void tst_QTextStream::numeralCase_data() |
| 1673 | { |
| 1674 | QTextStreamFunction noop_ = ws::noop; |
| 1675 | QTextStreamFunction bin = Qt::bin; |
| 1676 | QTextStreamFunction oct = Qt::oct; |
| 1677 | QTextStreamFunction hex = Qt::hex; |
| 1678 | QTextStreamFunction base = Qt::showbase; |
| 1679 | QTextStreamFunction ucb = Qt::uppercasebase; |
| 1680 | QTextStreamFunction lcb = Qt::lowercasebase; |
| 1681 | QTextStreamFunction ucd = Qt::uppercasedigits; |
| 1682 | QTextStreamFunction lcd = Qt::lowercasedigits; |
| 1683 | |
| 1684 | QTest::addColumn<QTextStreamFunction>(name: "func1" ); |
| 1685 | QTest::addColumn<QTextStreamFunction>(name: "func2" ); |
| 1686 | QTest::addColumn<QTextStreamFunction>(name: "func3" ); |
| 1687 | QTest::addColumn<QTextStreamFunction>(name: "func4" ); |
| 1688 | QTest::addColumn<int>(name: "value" ); |
| 1689 | QTest::addColumn<QString>(name: "expected" ); |
| 1690 | QTest::newRow(dataTag: "dec 1" ) << noop_ << noop_ << noop_ << noop_ << 31 << "31" ; |
| 1691 | QTest::newRow(dataTag: "dec 2" ) << noop_ << base << noop_ << noop_ << 31 << "31" ; |
| 1692 | |
| 1693 | QTest::newRow(dataTag: "hex 1" ) << hex << noop_ << noop_ << noop_ << 31 << "1f" ; |
| 1694 | QTest::newRow(dataTag: "hex 2" ) << hex << noop_ << noop_ << lcd << 31 << "1f" ; |
| 1695 | QTest::newRow(dataTag: "hex 3" ) << hex << noop_ << ucb << noop_ << 31 << "1f" ; |
| 1696 | QTest::newRow(dataTag: "hex 4" ) << hex << noop_ << noop_ << ucd << 31 << "1F" ; |
| 1697 | QTest::newRow(dataTag: "hex 5" ) << hex << noop_ << lcb << ucd << 31 << "1F" ; |
| 1698 | QTest::newRow(dataTag: "hex 6" ) << hex << noop_ << ucb << ucd << 31 << "1F" ; |
| 1699 | QTest::newRow(dataTag: "hex 7" ) << hex << base << noop_ << noop_ << 31 << "0x1f" ; |
| 1700 | QTest::newRow(dataTag: "hex 8" ) << hex << base << lcb << lcd << 31 << "0x1f" ; |
| 1701 | QTest::newRow(dataTag: "hex 9" ) << hex << base << ucb << noop_ << 31 << "0X1f" ; |
| 1702 | QTest::newRow(dataTag: "hex 10" ) << hex << base << ucb << lcd << 31 << "0X1f" ; |
| 1703 | QTest::newRow(dataTag: "hex 11" ) << hex << base << noop_ << ucd << 31 << "0x1F" ; |
| 1704 | QTest::newRow(dataTag: "hex 12" ) << hex << base << lcb << ucd << 31 << "0x1F" ; |
| 1705 | QTest::newRow(dataTag: "hex 13" ) << hex << base << ucb << ucd << 31 << "0X1F" ; |
| 1706 | |
| 1707 | QTest::newRow(dataTag: "bin 1" ) << bin << noop_ << noop_ << noop_ << 31 << "11111" ; |
| 1708 | QTest::newRow(dataTag: "bin 2" ) << bin << base << noop_ << noop_ << 31 << "0b11111" ; |
| 1709 | QTest::newRow(dataTag: "bin 3" ) << bin << base << lcb << noop_ << 31 << "0b11111" ; |
| 1710 | QTest::newRow(dataTag: "bin 4" ) << bin << base << ucb << noop_ << 31 << "0B11111" ; |
| 1711 | QTest::newRow(dataTag: "bin 5" ) << bin << base << noop_ << ucd << 31 << "0b11111" ; |
| 1712 | QTest::newRow(dataTag: "bin 6" ) << bin << base << lcb << ucd << 31 << "0b11111" ; |
| 1713 | QTest::newRow(dataTag: "bin 7" ) << bin << base << ucb << ucd << 31 << "0B11111" ; |
| 1714 | |
| 1715 | QTest::newRow(dataTag: "oct 1" ) << oct << noop_ << noop_ << noop_ << 31 << "37" ; |
| 1716 | QTest::newRow(dataTag: "oct 2" ) << oct << base << noop_ << noop_ << 31 << "037" ; |
| 1717 | } |
| 1718 | |
| 1719 | void tst_QTextStream::numeralCase() |
| 1720 | { |
| 1721 | QFETCH(QTextStreamFunction, func1); |
| 1722 | QFETCH(QTextStreamFunction, func2); |
| 1723 | QFETCH(QTextStreamFunction, func3); |
| 1724 | QFETCH(QTextStreamFunction, func4); |
| 1725 | QFETCH(int, value); |
| 1726 | QFETCH(QString, expected); |
| 1727 | |
| 1728 | QString str; |
| 1729 | QTextStream stream(&str); |
| 1730 | stream << func1 << func2 << func3 << func4 << value; |
| 1731 | QCOMPARE(str, expected); |
| 1732 | } |
| 1733 | |
| 1734 | // ------------------------------------------------------------------------------ |
| 1735 | void tst_QTextStream::nanInf() |
| 1736 | { |
| 1737 | // Cannot use test data in this function, as comparing nans and infs isn't |
| 1738 | // well defined. |
| 1739 | QString str("nan NAN nAn +nan +NAN +nAn -nan -NAN -nAn" |
| 1740 | " inf INF iNf +inf +INF +iNf -inf -INF -iNf" ); |
| 1741 | |
| 1742 | QTextStream stream(&str); |
| 1743 | |
| 1744 | double tmpD = 0; |
| 1745 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1746 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1747 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1748 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1749 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1750 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1751 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1752 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1753 | stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0; |
| 1754 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; |
| 1755 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; |
| 1756 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; |
| 1757 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; |
| 1758 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; |
| 1759 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0; |
| 1760 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; |
| 1761 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; |
| 1762 | stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0; |
| 1763 | |
| 1764 | stream.seek(pos: 0); |
| 1765 | |
| 1766 | float tmpF = 0; |
| 1767 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1768 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1769 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1770 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1771 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1772 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1773 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1774 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1775 | stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0; |
| 1776 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; |
| 1777 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; |
| 1778 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; |
| 1779 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; |
| 1780 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; |
| 1781 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0; |
| 1782 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0; |
| 1783 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0; |
| 1784 | stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); |
| 1785 | |
| 1786 | QString s; |
| 1787 | QTextStream out(&s); |
| 1788 | out << qInf() << ' ' << -qInf() << ' ' << qQNaN() |
| 1789 | << Qt::uppercasedigits << ' ' |
| 1790 | << qInf() << ' ' << -qInf() << ' ' << qQNaN() |
| 1791 | << Qt::flush; |
| 1792 | |
| 1793 | QCOMPARE(s, QString("inf -inf nan INF -INF NAN" )); |
| 1794 | } |
| 1795 | |
| 1796 | // ------------------------------------------------------------------------------ |
| 1797 | void tst_QTextStream::utf8IncompleteAtBufferBoundary_data() |
| 1798 | { |
| 1799 | QTest::addColumn<bool>(name: "useLocale" ); |
| 1800 | |
| 1801 | QTest::newRow(dataTag: "utf8" ) << false; |
| 1802 | |
| 1803 | // is this locale UTF-8? |
| 1804 | if (QString(QChar::ReplacementCharacter).toLocal8Bit() == "\xef\xbf\xbd" ) |
| 1805 | QTest::newRow(dataTag: "locale" ) << true; |
| 1806 | } |
| 1807 | |
| 1808 | void tst_QTextStream::utf8IncompleteAtBufferBoundary() |
| 1809 | { |
| 1810 | QFile::remove(fileName: testFileName); |
| 1811 | QFile data(testFileName); |
| 1812 | |
| 1813 | QTextCodec *utf8Codec = QTextCodec::codecForMib(mib: 106); |
| 1814 | QString lineContents = QString::fromUtf8(str: "\342\200\223" // U+2013 EN DASH |
| 1815 | "\342\200\223" |
| 1816 | "\342\200\223" |
| 1817 | "\342\200\223" |
| 1818 | "\342\200\223" |
| 1819 | "\342\200\223" ); |
| 1820 | |
| 1821 | data.open(flags: QFile::WriteOnly | QFile::Truncate); |
| 1822 | { |
| 1823 | QTextStream out(&data); |
| 1824 | out.setCodec(utf8Codec); |
| 1825 | out.setFieldWidth(3); |
| 1826 | |
| 1827 | for (int i = 0; i < 1000; ++i) { |
| 1828 | out << i << lineContents << Qt::endl; |
| 1829 | } |
| 1830 | } |
| 1831 | data.close(); |
| 1832 | |
| 1833 | data.open(flags: QFile::ReadOnly); |
| 1834 | QTextStream in(&data); |
| 1835 | |
| 1836 | QFETCH(bool, useLocale); |
| 1837 | if (!useLocale) |
| 1838 | in.setCodec(utf8Codec); // QUtf8Codec |
| 1839 | else |
| 1840 | in.setCodec(QTextCodec::codecForLocale()); |
| 1841 | |
| 1842 | int i = 0; |
| 1843 | do { |
| 1844 | QString line = in.readLine().trimmed(); |
| 1845 | ++i; |
| 1846 | QVERIFY2(line.endsWith(lineContents), QString("Line %1: %2" ).arg(i).arg(line).toLocal8Bit()); |
| 1847 | } while (!in.atEnd()); |
| 1848 | } |
| 1849 | |
| 1850 | // ------------------------------------------------------------------------------ |
| 1851 | |
| 1852 | // Make sure we don't write a BOM after seek()ing |
| 1853 | |
| 1854 | void tst_QTextStream::writeSeekWriteNoBOM() |
| 1855 | { |
| 1856 | |
| 1857 | //First with the default codec (normally either latin-1 or UTF-8) |
| 1858 | |
| 1859 | QBuffer out; |
| 1860 | out.open(openMode: QIODevice::WriteOnly); |
| 1861 | QTextStream stream(&out); |
| 1862 | |
| 1863 | int number = 0; |
| 1864 | QString sizeStr = QLatin1String("Size=" ) |
| 1865 | + QString::number(number).rightJustified(width: 10, fill: QLatin1Char('0')); |
| 1866 | stream << sizeStr << Qt::endl; |
| 1867 | stream << "Version=" << QString::number(14) << Qt::endl; |
| 1868 | stream << "blah blah blah" << Qt::endl; |
| 1869 | stream.flush(); |
| 1870 | |
| 1871 | QCOMPARE(out.buffer().constData(), "Size=0000000000\nVersion=14\nblah blah blah\n" ); |
| 1872 | |
| 1873 | // Now overwrite the size header item |
| 1874 | number = 42; |
| 1875 | stream.seek(pos: 0); |
| 1876 | sizeStr = QLatin1String("Size=" ) |
| 1877 | + QString::number(number).rightJustified(width: 10, fill: QLatin1Char('0')); |
| 1878 | stream << sizeStr << Qt::endl; |
| 1879 | stream.flush(); |
| 1880 | |
| 1881 | // Check buffer is still OK |
| 1882 | QCOMPARE(out.buffer().constData(), "Size=0000000042\nVersion=14\nblah blah blah\n" ); |
| 1883 | |
| 1884 | |
| 1885 | //Then UTF-16 |
| 1886 | |
| 1887 | QBuffer out16; |
| 1888 | out16.open(openMode: QIODevice::WriteOnly); |
| 1889 | QTextStream stream16(&out16); |
| 1890 | stream16.setCodec("UTF-16" ); |
| 1891 | |
| 1892 | stream16 << "one" << "two" << QLatin1String("three" ); |
| 1893 | stream16.flush(); |
| 1894 | |
| 1895 | // save that output |
| 1896 | QByteArray first = out16.buffer(); |
| 1897 | |
| 1898 | stream16.seek(pos: 0); |
| 1899 | stream16 << "one" ; |
| 1900 | stream16.flush(); |
| 1901 | |
| 1902 | QCOMPARE(out16.buffer(), first); |
| 1903 | } |
| 1904 | |
| 1905 | // ------------------------------------------------------------------------------ |
| 1906 | void tst_QTextStream::generateOperatorCharData(bool for_QString) |
| 1907 | { |
| 1908 | QTest::addColumn<QByteArray>(name: "input" ); |
| 1909 | QTest::addColumn<QChar>(name: "qchar_output" ); |
| 1910 | QTest::addColumn<char>(name: "char_output" ); |
| 1911 | QTest::addColumn<QByteArray>(name: "write_output" ); |
| 1912 | |
| 1913 | QTest::newRow(dataTag: "empty" ) << QByteArray() << QChar('\0') << '\0' << QByteArray("\0" , 1); |
| 1914 | QTest::newRow(dataTag: "a" ) << QByteArray("a" ) << QChar('a') << 'a' << QByteArray("a" ); |
| 1915 | QTest::newRow(dataTag: "\\na" ) << QByteArray("\na" ) << QChar('\n') << '\n' << QByteArray("\n" ); |
| 1916 | QTest::newRow(dataTag: "\\0" ) << QByteArray("\0" ) << QChar('\0') << '\0' << QByteArray("\0" , 1); |
| 1917 | QTest::newRow(dataTag: "\\xff" ) << QByteArray("\xff" ) << QChar('\xff') << '\xff' << QByteArray("\xff" ); |
| 1918 | QTest::newRow(dataTag: "\\xfe" ) << QByteArray("\xfe" ) << QChar('\xfe') << '\xfe' << QByteArray("\xfe" ); |
| 1919 | |
| 1920 | if (!for_QString) { |
| 1921 | QTest::newRow(dataTag: "utf16-BE (empty)" ) << QByteArray("\xff\xfe" , 2) << QChar('\0') << '\0' << QByteArray("\0" , 1); |
| 1922 | QTest::newRow(dataTag: "utf16-BE (a)" ) << QByteArray("\xff\xfe\x61\x00" , 4) << QChar('a') << 'a' << QByteArray("a" ); |
| 1923 | QTest::newRow(dataTag: "utf16-LE (empty)" ) << QByteArray("\xfe\xff" , 2) << QChar('\0') << '\0' << QByteArray("\0" , 1); |
| 1924 | QTest::newRow(dataTag: "utf16-LE (a)" ) << QByteArray("\xfe\xff\x00\x61" , 4) << QChar('a') << 'a' << QByteArray("a" ); |
| 1925 | } |
| 1926 | } |
| 1927 | |
| 1928 | // ------------------------------------------------------------------------------ |
| 1929 | void tst_QTextStream::QChar_operators_FromDevice_data() |
| 1930 | { |
| 1931 | generateOperatorCharData(for_QString: false); |
| 1932 | } |
| 1933 | |
| 1934 | // ------------------------------------------------------------------------------ |
| 1935 | void tst_QTextStream::QChar_operators_FromDevice() |
| 1936 | { |
| 1937 | QFETCH(QByteArray, input); |
| 1938 | QFETCH(QChar, qchar_output); |
| 1939 | QFETCH(QByteArray, write_output); |
| 1940 | |
| 1941 | QBuffer buf(&input); |
| 1942 | buf.open(openMode: QBuffer::ReadOnly); |
| 1943 | QTextStream stream(&buf); |
| 1944 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 1945 | QChar tmp; |
| 1946 | stream >> tmp; |
| 1947 | QCOMPARE(tmp, qchar_output); |
| 1948 | |
| 1949 | QBuffer writeBuf; |
| 1950 | writeBuf.open(openMode: QBuffer::WriteOnly); |
| 1951 | |
| 1952 | QTextStream writeStream(&writeBuf); |
| 1953 | writeStream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 1954 | writeStream << qchar_output; |
| 1955 | writeStream.flush(); |
| 1956 | |
| 1957 | QCOMPARE(writeBuf.buffer().size(), write_output.size()); |
| 1958 | QCOMPARE(writeBuf.buffer().constData(), write_output.constData()); |
| 1959 | } |
| 1960 | |
| 1961 | // ------------------------------------------------------------------------------ |
| 1962 | void tst_QTextStream::char_operators_FromDevice_data() |
| 1963 | { |
| 1964 | generateOperatorCharData(for_QString: false); |
| 1965 | } |
| 1966 | |
| 1967 | // ------------------------------------------------------------------------------ |
| 1968 | void tst_QTextStream::char_operators_FromDevice() |
| 1969 | { |
| 1970 | QFETCH(QByteArray, input); |
| 1971 | QFETCH(char, char_output); |
| 1972 | QFETCH(QByteArray, write_output); |
| 1973 | |
| 1974 | QBuffer buf(&input); |
| 1975 | buf.open(openMode: QBuffer::ReadOnly); |
| 1976 | QTextStream stream(&buf); |
| 1977 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 1978 | char tmp; |
| 1979 | stream >> tmp; |
| 1980 | QCOMPARE(tmp, char_output); |
| 1981 | |
| 1982 | QBuffer writeBuf; |
| 1983 | writeBuf.open(openMode: QBuffer::WriteOnly); |
| 1984 | |
| 1985 | QTextStream writeStream(&writeBuf); |
| 1986 | writeStream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 1987 | writeStream << char_output; |
| 1988 | writeStream.flush(); |
| 1989 | |
| 1990 | QCOMPARE(writeBuf.buffer().size(), write_output.size()); |
| 1991 | QCOMPARE(writeBuf.buffer().constData(), write_output.constData()); |
| 1992 | } |
| 1993 | |
| 1994 | // ------------------------------------------------------------------------------ |
| 1995 | void tst_QTextStream::generateNaturalNumbersData(bool for_QString) |
| 1996 | { |
| 1997 | QTest::addColumn<QByteArray>(name: "input" ); |
| 1998 | QTest::addColumn<qulonglong>(name: "output" ); |
| 1999 | |
| 2000 | QTest::newRow(dataTag: "empty" ) << QByteArray() << qulonglong(0); |
| 2001 | QTest::newRow(dataTag: "a" ) << QByteArray("a" ) << qulonglong(0); |
| 2002 | QTest::newRow(dataTag: " " ) << QByteArray(" " ) << qulonglong(0); |
| 2003 | QTest::newRow(dataTag: "0" ) << QByteArray("0" ) << qulonglong(0); |
| 2004 | QTest::newRow(dataTag: "1" ) << QByteArray("1" ) << qulonglong(1); |
| 2005 | QTest::newRow(dataTag: "12" ) << QByteArray("12" ) << qulonglong(12); |
| 2006 | QTest::newRow(dataTag: "-12" ) << QByteArray("-12" ) << qulonglong(-12); |
| 2007 | QTest::newRow(dataTag: "-0" ) << QByteArray("-0" ) << qulonglong(0); |
| 2008 | QTest::newRow(dataTag: " 1" ) << QByteArray(" 1" ) << qulonglong(1); |
| 2009 | QTest::newRow(dataTag: " \\r\\n\\r\\n123" ) << QByteArray(" \r\n\r\n123" ) << qulonglong(123); |
| 2010 | |
| 2011 | // bit boundary tests |
| 2012 | QTest::newRow(dataTag: "127" ) << QByteArray("127" ) << qulonglong(127); |
| 2013 | QTest::newRow(dataTag: "128" ) << QByteArray("128" ) << qulonglong(128); |
| 2014 | QTest::newRow(dataTag: "129" ) << QByteArray("129" ) << qulonglong(129); |
| 2015 | QTest::newRow(dataTag: "-127" ) << QByteArray("-127" ) << qulonglong(-127); |
| 2016 | QTest::newRow(dataTag: "-128" ) << QByteArray("-128" ) << qulonglong(-128); |
| 2017 | QTest::newRow(dataTag: "-129" ) << QByteArray("-129" ) << qulonglong(-129); |
| 2018 | QTest::newRow(dataTag: "32767" ) << QByteArray("32767" ) << qulonglong(32767); |
| 2019 | QTest::newRow(dataTag: "32768" ) << QByteArray("32768" ) << qulonglong(32768); |
| 2020 | QTest::newRow(dataTag: "32769" ) << QByteArray("32769" ) << qulonglong(32769); |
| 2021 | QTest::newRow(dataTag: "-32767" ) << QByteArray("-32767" ) << qulonglong(-32767); |
| 2022 | QTest::newRow(dataTag: "-32768" ) << QByteArray("-32768" ) << qulonglong(-32768); |
| 2023 | QTest::newRow(dataTag: "-32769" ) << QByteArray("-32769" ) << qulonglong(-32769); |
| 2024 | QTest::newRow(dataTag: "65537" ) << QByteArray("65537" ) << qulonglong(65537); |
| 2025 | QTest::newRow(dataTag: "65536" ) << QByteArray("65536" ) << qulonglong(65536); |
| 2026 | QTest::newRow(dataTag: "65535" ) << QByteArray("65535" ) << qulonglong(65535); |
| 2027 | QTest::newRow(dataTag: "-65537" ) << QByteArray("-65537" ) << qulonglong(-65537); |
| 2028 | QTest::newRow(dataTag: "-65536" ) << QByteArray("-65536" ) << qulonglong(-65536); |
| 2029 | QTest::newRow(dataTag: "-65535" ) << QByteArray("-65535" ) << qulonglong(-65535); |
| 2030 | QTest::newRow(dataTag: "2147483646" ) << QByteArray("2147483646" ) << qulonglong(2147483646); |
| 2031 | QTest::newRow(dataTag: "2147483647" ) << QByteArray("2147483647" ) << qulonglong(2147483647); |
| 2032 | QTest::newRow(dataTag: "2147483648" ) << QByteArray("2147483648" ) << Q_UINT64_C(2147483648); |
| 2033 | QTest::newRow(dataTag: "-2147483646" ) << QByteArray("-2147483646" ) << qulonglong(-2147483646); |
| 2034 | QTest::newRow(dataTag: "-2147483647" ) << QByteArray("-2147483647" ) << qulonglong(-2147483647); |
| 2035 | QTest::newRow(dataTag: "-2147483648" ) << QByteArray("-2147483648" ) << quint64(-2147483648LL); |
| 2036 | QTest::newRow(dataTag: "4294967296" ) << QByteArray("4294967296" ) << Q_UINT64_C(4294967296); |
| 2037 | QTest::newRow(dataTag: "4294967297" ) << QByteArray("4294967297" ) << Q_UINT64_C(4294967297); |
| 2038 | QTest::newRow(dataTag: "4294967298" ) << QByteArray("4294967298" ) << Q_UINT64_C(4294967298); |
| 2039 | QTest::newRow(dataTag: "-4294967296" ) << QByteArray("-4294967296" ) << quint64(-4294967296); |
| 2040 | QTest::newRow(dataTag: "-4294967297" ) << QByteArray("-4294967297" ) << quint64(-4294967297); |
| 2041 | QTest::newRow(dataTag: "-4294967298" ) << QByteArray("-4294967298" ) << quint64(-4294967298); |
| 2042 | QTest::newRow(dataTag: "9223372036854775807" ) << QByteArray("9223372036854775807" ) << Q_UINT64_C(9223372036854775807); |
| 2043 | QTest::newRow(dataTag: "9223372036854775808" ) << QByteArray("9223372036854775808" ) << Q_UINT64_C(9223372036854775808); |
| 2044 | QTest::newRow(dataTag: "9223372036854775809" ) << QByteArray("9223372036854775809" ) << Q_UINT64_C(9223372036854775809); |
| 2045 | QTest::newRow(dataTag: "18446744073709551615" ) << QByteArray("18446744073709551615" ) << Q_UINT64_C(18446744073709551615); |
| 2046 | QTest::newRow(dataTag: "18446744073709551616" ) << QByteArray("18446744073709551616" ) << Q_UINT64_C(0); |
| 2047 | QTest::newRow(dataTag: "18446744073709551617" ) << QByteArray("18446744073709551617" ) << Q_UINT64_C(1); |
| 2048 | // 18446744073709551617 bytes should be enough for anyone.... ;-) |
| 2049 | |
| 2050 | // hex tests |
| 2051 | QTest::newRow(dataTag: "0x0" ) << QByteArray("0x0" ) << qulonglong(0); |
| 2052 | QTest::newRow(dataTag: "0x" ) << QByteArray("0x" ) << qulonglong(0); |
| 2053 | QTest::newRow(dataTag: "0x1" ) << QByteArray("0x1" ) << qulonglong(1); |
| 2054 | QTest::newRow(dataTag: "0xf" ) << QByteArray("0xf" ) << qulonglong(15); |
| 2055 | QTest::newRow(dataTag: "0xdeadbeef" ) << QByteArray("0xdeadbeef" ) << Q_UINT64_C(3735928559); |
| 2056 | QTest::newRow(dataTag: "0XDEADBEEF" ) << QByteArray("0XDEADBEEF" ) << Q_UINT64_C(3735928559); |
| 2057 | QTest::newRow(dataTag: "0xdeadbeefZzzzz" ) << QByteArray("0xdeadbeefZzzzz" ) << Q_UINT64_C(3735928559); |
| 2058 | QTest::newRow(dataTag: " 0xdeadbeefZzzzz" ) << QByteArray(" 0xdeadbeefZzzzz" ) << Q_UINT64_C(3735928559); |
| 2059 | |
| 2060 | // oct tests |
| 2061 | QTest::newRow(dataTag: "00" ) << QByteArray("00" ) << qulonglong(0); |
| 2062 | QTest::newRow(dataTag: "0141" ) << QByteArray("0141" ) << qulonglong(97); |
| 2063 | QTest::newRow(dataTag: "01419999" ) << QByteArray("01419999" ) << qulonglong(97); |
| 2064 | QTest::newRow(dataTag: " 01419999" ) << QByteArray(" 01419999" ) << qulonglong(97); |
| 2065 | |
| 2066 | // bin tests |
| 2067 | QTest::newRow(dataTag: "0b0" ) << QByteArray("0b0" ) << qulonglong(0); |
| 2068 | QTest::newRow(dataTag: "0b1" ) << QByteArray("0b1" ) << qulonglong(1); |
| 2069 | QTest::newRow(dataTag: "0b10" ) << QByteArray("0b10" ) << qulonglong(2); |
| 2070 | QTest::newRow(dataTag: "0B10" ) << QByteArray("0B10" ) << qulonglong(2); |
| 2071 | QTest::newRow(dataTag: "0b101010" ) << QByteArray("0b101010" ) << qulonglong(42); |
| 2072 | QTest::newRow(dataTag: "0b1010102345" ) << QByteArray("0b1010102345" ) << qulonglong(42); |
| 2073 | QTest::newRow(dataTag: " 0b1010102345" ) << QByteArray(" 0b1010102345" ) << qulonglong(42); |
| 2074 | |
| 2075 | // utf-16 tests |
| 2076 | if (!for_QString) { |
| 2077 | QTest::newRow(dataTag: "utf16-BE (empty)" ) << QByteArray("\xfe\xff" , 2) << qulonglong(0); |
| 2078 | QTest::newRow(dataTag: "utf16-BE (0xdeadbeef)" ) |
| 2079 | << QByteArray("\xfe\xff" |
| 2080 | "\x00\x30\x00\x78\x00\x64\x00\x65\x00\x61\x00\x64\x00\x62\x00\x65\x00\x65\x00\x66" , 22) |
| 2081 | << Q_UINT64_C(3735928559); |
| 2082 | QTest::newRow(dataTag: "utf16-LE (empty)" ) << QByteArray("\xff\xfe" , 2) << Q_UINT64_C(0); |
| 2083 | QTest::newRow(dataTag: "utf16-LE (0xdeadbeef)" ) |
| 2084 | << QByteArray("\xff\xfe" |
| 2085 | "\x30\x00\x78\x00\x64\x00\x65\x00\x61\x00\x64\x00\x62\x00\x65\x00\x65\x00\x66\x00" , 22) |
| 2086 | << Q_UINT64_C(3735928559); |
| 2087 | } |
| 2088 | } |
| 2089 | |
| 2090 | // ------------------------------------------------------------------------------ |
| 2091 | #define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(texttype, type) \ |
| 2092 | void tst_QTextStream:: texttype##_read_operator_FromDevice_data() \ |
| 2093 | { generateNaturalNumbersData(false); } \ |
| 2094 | void tst_QTextStream:: texttype##_read_operator_FromDevice() \ |
| 2095 | { \ |
| 2096 | QFETCH(QByteArray, input); \ |
| 2097 | QFETCH(qulonglong, output); \ |
| 2098 | type sh; \ |
| 2099 | QTextStream stream(&input); \ |
| 2100 | stream >> sh; \ |
| 2101 | QCOMPARE(sh, (type)output); \ |
| 2102 | } |
| 2103 | IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedShort, signed short) |
| 2104 | IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedShort, unsigned short) |
| 2105 | IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedInt, signed int) |
| 2106 | IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedInt, unsigned int) |
| 2107 | IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qlonglong, qlonglong) |
| 2108 | IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qulonglong, qulonglong) |
| 2109 | ; |
| 2110 | |
| 2111 | // ------------------------------------------------------------------------------ |
| 2112 | void tst_QTextStream::generateRealNumbersData(bool for_QString) |
| 2113 | { |
| 2114 | QTest::addColumn<QByteArray>(name: "input" ); |
| 2115 | QTest::addColumn<double>(name: "output" ); |
| 2116 | |
| 2117 | QTest::newRow(dataTag: "empty" ) << QByteArray() << 0.0; |
| 2118 | QTest::newRow(dataTag: "a" ) << QByteArray("a" ) << 0.0; |
| 2119 | QTest::newRow(dataTag: "1.0" ) << QByteArray("1.0" ) << 1.0; |
| 2120 | QTest::newRow(dataTag: " 1" ) << QByteArray(" 1" ) << 1.0; |
| 2121 | QTest::newRow(dataTag: " \\r\\n1.2" ) << QByteArray(" \r\n1.2" ) << 1.2; |
| 2122 | QTest::newRow(dataTag: "3.14" ) << QByteArray("3.14" ) << 3.14; |
| 2123 | QTest::newRow(dataTag: "-3.14" ) << QByteArray("-3.14" ) << -3.14; |
| 2124 | QTest::newRow(dataTag: " -3.14" ) << QByteArray(" -3.14" ) << -3.14; |
| 2125 | QTest::newRow(dataTag: "314e-02" ) << QByteArray("314e-02" ) << 3.14; |
| 2126 | QTest::newRow(dataTag: "314E-02" ) << QByteArray("314E-02" ) << 3.14; |
| 2127 | QTest::newRow(dataTag: "314e+02" ) << QByteArray("314e+02" ) << 31400.; |
| 2128 | QTest::newRow(dataTag: "314E+02" ) << QByteArray("314E+02" ) << 31400.; |
| 2129 | |
| 2130 | // ### add numbers with exponents |
| 2131 | |
| 2132 | if (!for_QString) { |
| 2133 | QTest::newRow(dataTag: "utf16-BE (empty)" ) << QByteArray("\xff\xfe" , 2) << 0.0; |
| 2134 | QTest::newRow(dataTag: "utf16-LE (empty)" ) << QByteArray("\xfe\xff" , 2) << 0.0; |
| 2135 | } |
| 2136 | } |
| 2137 | |
| 2138 | // ------------------------------------------------------------------------------ |
| 2139 | #define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(texttype, type) \ |
| 2140 | void tst_QTextStream:: texttype##_read_operator_FromDevice_data() \ |
| 2141 | { generateRealNumbersData(false); } \ |
| 2142 | void tst_QTextStream:: texttype##_read_operator_FromDevice() \ |
| 2143 | { \ |
| 2144 | QFETCH(QByteArray, input); \ |
| 2145 | QFETCH(double, output); \ |
| 2146 | type sh; \ |
| 2147 | QTextStream stream(&input); \ |
| 2148 | stream >> sh; \ |
| 2149 | QCOMPARE(sh, (type)output); \ |
| 2150 | } |
| 2151 | IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(float, float) |
| 2152 | IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(double, double) |
| 2153 | ; |
| 2154 | |
| 2155 | // ------------------------------------------------------------------------------ |
| 2156 | void tst_QTextStream::generateStringData(bool for_QString) |
| 2157 | { |
| 2158 | QTest::addColumn<QByteArray>(name: "input" ); |
| 2159 | QTest::addColumn<QByteArray>(name: "array_output" ); |
| 2160 | QTest::addColumn<QString>(name: "string_output" ); |
| 2161 | |
| 2162 | QTest::newRow(dataTag: "empty" ) << QByteArray() << QByteArray() << QString(); |
| 2163 | QTest::newRow(dataTag: "a" ) << QByteArray("a" ) << QByteArray("a" ) << QString("a" ); |
| 2164 | QTest::newRow(dataTag: "a b" ) << QByteArray("a b" ) << QByteArray("a" ) << QString("a" ); |
| 2165 | QTest::newRow(dataTag: " a b" ) << QByteArray(" a b" ) << QByteArray("a" ) << QString("a" ); |
| 2166 | QTest::newRow(dataTag: "a1" ) << QByteArray("a1" ) << QByteArray("a1" ) << QString("a1" ); |
| 2167 | QTest::newRow(dataTag: "a1 b1" ) << QByteArray("a1 b1" ) << QByteArray("a1" ) << QString("a1" ); |
| 2168 | QTest::newRow(dataTag: " a1 b1" ) << QByteArray(" a1 b1" ) << QByteArray("a1" ) << QString("a1" ); |
| 2169 | QTest::newRow(dataTag: "\\n\\n\\nole i dole\\n" ) << QByteArray("\n\n\nole i dole\n" ) << QByteArray("ole" ) << QString("ole" ); |
| 2170 | |
| 2171 | if (!for_QString) { |
| 2172 | QTest::newRow(dataTag: "utf16-BE (empty)" ) << QByteArray("\xff\xfe" , 2) << QByteArray() << QString(); |
| 2173 | QTest::newRow(dataTag: "utf16-BE (corrupt)" ) << QByteArray("\xff" , 1) << QByteArray("\xff" ) << QString::fromLatin1(str: "\xff" ); |
| 2174 | QTest::newRow(dataTag: "utf16-LE (empty)" ) << QByteArray("\xfe\xff" , 2) << QByteArray() << QString(); |
| 2175 | QTest::newRow(dataTag: "utf16-LE (corrupt)" ) << QByteArray("\xfe" , 1) << QByteArray("\xfe" ) << QString::fromLatin1(str: "\xfe" ); |
| 2176 | } |
| 2177 | } |
| 2178 | |
| 2179 | // ------------------------------------------------------------------------------ |
| 2180 | void tst_QTextStream::charPtr_read_operator_FromDevice_data() |
| 2181 | { |
| 2182 | generateStringData(for_QString: false); |
| 2183 | } |
| 2184 | |
| 2185 | // ------------------------------------------------------------------------------ |
| 2186 | void tst_QTextStream::charPtr_read_operator_FromDevice() |
| 2187 | { |
| 2188 | QFETCH(QByteArray, input); |
| 2189 | QFETCH(QByteArray, array_output); |
| 2190 | |
| 2191 | QBuffer buffer(&input); |
| 2192 | buffer.open(openMode: QBuffer::ReadOnly); |
| 2193 | QTextStream stream(&buffer); |
| 2194 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2195 | stream.setAutoDetectUnicode(true); |
| 2196 | |
| 2197 | char buf[1024]; |
| 2198 | stream >> buf; |
| 2199 | |
| 2200 | QCOMPARE((const char *)buf, array_output.constData()); |
| 2201 | } |
| 2202 | |
| 2203 | // ------------------------------------------------------------------------------ |
| 2204 | void tst_QTextStream::stringRef_read_operator_FromDevice_data() |
| 2205 | { |
| 2206 | generateStringData(for_QString: false); |
| 2207 | } |
| 2208 | |
| 2209 | // ------------------------------------------------------------------------------ |
| 2210 | void tst_QTextStream::stringRef_read_operator_FromDevice() |
| 2211 | { |
| 2212 | QFETCH(QByteArray, input); |
| 2213 | QFETCH(QString, string_output); |
| 2214 | |
| 2215 | QBuffer buffer(&input); |
| 2216 | buffer.open(openMode: QBuffer::ReadOnly); |
| 2217 | QTextStream stream(&buffer); |
| 2218 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2219 | stream.setAutoDetectUnicode(true); |
| 2220 | |
| 2221 | QString tmp; |
| 2222 | stream >> tmp; |
| 2223 | |
| 2224 | QCOMPARE(tmp, string_output); |
| 2225 | } |
| 2226 | |
| 2227 | // ------------------------------------------------------------------------------ |
| 2228 | void tst_QTextStream::byteArray_read_operator_FromDevice_data() |
| 2229 | { |
| 2230 | generateStringData(for_QString: false); |
| 2231 | } |
| 2232 | |
| 2233 | // ------------------------------------------------------------------------------ |
| 2234 | void tst_QTextStream::byteArray_read_operator_FromDevice() |
| 2235 | { |
| 2236 | QFETCH(QByteArray, input); |
| 2237 | QFETCH(QByteArray, array_output); |
| 2238 | |
| 2239 | QBuffer buffer(&input); |
| 2240 | buffer.open(openMode: QBuffer::ReadOnly); |
| 2241 | QTextStream stream(&buffer); |
| 2242 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2243 | stream.setAutoDetectUnicode(true); |
| 2244 | |
| 2245 | QByteArray array; |
| 2246 | stream >> array; |
| 2247 | |
| 2248 | QCOMPARE(array, array_output); |
| 2249 | } |
| 2250 | |
| 2251 | // ------------------------------------------------------------------------------ |
| 2252 | #define IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(texttype, type) \ |
| 2253 | void tst_QTextStream:: texttype##_write_operator_ToDevice() \ |
| 2254 | { \ |
| 2255 | QFETCH(qulonglong, number); \ |
| 2256 | QFETCH(QByteArray, data); \ |
| 2257 | QFETCH(QByteArray, dataWithSeparators); \ |
| 2258 | \ |
| 2259 | QBuffer buffer; \ |
| 2260 | buffer.open(QBuffer::WriteOnly); \ |
| 2261 | QTextStream stream(&buffer); \ |
| 2262 | stream.setLocale(QLocale::c()); \ |
| 2263 | stream << (type)number; \ |
| 2264 | stream.flush(); \ |
| 2265 | QCOMPARE(buffer.data().constData(), data.constData()); \ |
| 2266 | \ |
| 2267 | QLocale locale("en-US"); \ |
| 2268 | buffer.reset(); buffer.buffer().clear(); \ |
| 2269 | stream.setLocale(locale); \ |
| 2270 | stream << (type)number; \ |
| 2271 | stream.flush(); \ |
| 2272 | QCOMPARE(buffer.data(), dataWithSeparators); \ |
| 2273 | \ |
| 2274 | locale.setNumberOptions(QLocale::OmitGroupSeparator); \ |
| 2275 | buffer.reset(); buffer.buffer().clear(); \ |
| 2276 | stream.setLocale(locale); \ |
| 2277 | stream << (type)number; \ |
| 2278 | stream.flush(); \ |
| 2279 | QCOMPARE(buffer.data().constData(), data.constData()); \ |
| 2280 | \ |
| 2281 | locale = QLocale("de-DE"); \ |
| 2282 | buffer.reset(); buffer.buffer().clear(); \ |
| 2283 | stream.setLocale(locale); \ |
| 2284 | stream << (type)number; \ |
| 2285 | stream.flush(); \ |
| 2286 | QCOMPARE(buffer.data(), dataWithSeparators.replace(',', '.')); \ |
| 2287 | } |
| 2288 | |
| 2289 | // ------------------------------------------------------------------------------ |
| 2290 | void tst_QTextStream::signedShort_write_operator_ToDevice_data() |
| 2291 | { |
| 2292 | QTest::addColumn<qulonglong>(name: "number" ); |
| 2293 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2294 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2295 | |
| 2296 | QTest::newRow(dataTag: "0" ) << Q_UINT64_C(0) << QByteArray("0" ) << QByteArray("0" ); |
| 2297 | QTest::newRow(dataTag: "1" ) << Q_UINT64_C(1) << QByteArray("1" ) << QByteArray("1" ); |
| 2298 | QTest::newRow(dataTag: "-1" ) << quint64(-1) << QByteArray("-1" ) << QByteArray("-1" ); |
| 2299 | QTest::newRow(dataTag: "32767" ) << Q_UINT64_C(32767) << QByteArray("32767" ) << QByteArray("32,767" ); |
| 2300 | QTest::newRow(dataTag: "32768" ) << Q_UINT64_C(32768) << QByteArray("-32768" ) << QByteArray("-32,768" ); |
| 2301 | QTest::newRow(dataTag: "32769" ) << Q_UINT64_C(32769) << QByteArray("-32767" ) << QByteArray("-32,767" ); |
| 2302 | QTest::newRow(dataTag: "65535" ) << Q_UINT64_C(65535) << QByteArray("-1" ) << QByteArray("-1" ); |
| 2303 | QTest::newRow(dataTag: "65536" ) << Q_UINT64_C(65536) << QByteArray("0" ) << QByteArray("0" ); |
| 2304 | QTest::newRow(dataTag: "65537" ) << Q_UINT64_C(65537) << QByteArray("1" ) << QByteArray("1" ); |
| 2305 | } |
| 2306 | IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedShort, signed short) |
| 2307 | ; |
| 2308 | |
| 2309 | // ------------------------------------------------------------------------------ |
| 2310 | void tst_QTextStream::unsignedShort_write_operator_ToDevice_data() |
| 2311 | { |
| 2312 | QTest::addColumn<qulonglong>(name: "number" ); |
| 2313 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2314 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2315 | |
| 2316 | QTest::newRow(dataTag: "0" ) << Q_UINT64_C(0) << QByteArray("0" ) << QByteArray("0" ); |
| 2317 | QTest::newRow(dataTag: "1" ) << Q_UINT64_C(1) << QByteArray("1" ) << QByteArray("1" ); |
| 2318 | QTest::newRow(dataTag: "-1" ) << quint64(-1) << QByteArray("65535" ) << QByteArray("65,535" ); |
| 2319 | QTest::newRow(dataTag: "32767" ) << Q_UINT64_C(32767) << QByteArray("32767" ) << QByteArray("32,767" ); |
| 2320 | QTest::newRow(dataTag: "32768" ) << Q_UINT64_C(32768) << QByteArray("32768" ) << QByteArray("32,768" ); |
| 2321 | QTest::newRow(dataTag: "32769" ) << Q_UINT64_C(32769) << QByteArray("32769" ) << QByteArray("32,769" ); |
| 2322 | QTest::newRow(dataTag: "65535" ) << Q_UINT64_C(65535) << QByteArray("65535" ) << QByteArray("65,535" ); |
| 2323 | QTest::newRow(dataTag: "65536" ) << Q_UINT64_C(65536) << QByteArray("0" ) << QByteArray("0" ); |
| 2324 | QTest::newRow(dataTag: "65537" ) << Q_UINT64_C(65537) << QByteArray("1" ) << QByteArray("1" ); |
| 2325 | } |
| 2326 | IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedShort, unsigned short) |
| 2327 | ; |
| 2328 | |
| 2329 | // ------------------------------------------------------------------------------ |
| 2330 | void tst_QTextStream::signedInt_write_operator_ToDevice_data() |
| 2331 | { |
| 2332 | QTest::addColumn<qulonglong>(name: "number" ); |
| 2333 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2334 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2335 | |
| 2336 | QTest::newRow(dataTag: "0" ) << Q_UINT64_C(0) << QByteArray("0" ) << QByteArray("0" ); |
| 2337 | QTest::newRow(dataTag: "1" ) << Q_UINT64_C(1) << QByteArray("1" ) << QByteArray("1" ); |
| 2338 | QTest::newRow(dataTag: "-1" ) << quint64(-1) << QByteArray("-1" ) << QByteArray("-1" ); |
| 2339 | QTest::newRow(dataTag: "32767" ) << Q_UINT64_C(32767) << QByteArray("32767" ) << QByteArray("32,767" ); |
| 2340 | QTest::newRow(dataTag: "32768" ) << Q_UINT64_C(32768) << QByteArray("32768" ) << QByteArray("32,768" ); |
| 2341 | QTest::newRow(dataTag: "32769" ) << Q_UINT64_C(32769) << QByteArray("32769" ) << QByteArray("32,769" ); |
| 2342 | QTest::newRow(dataTag: "65535" ) << Q_UINT64_C(65535) << QByteArray("65535" ) << QByteArray("65,535" ); |
| 2343 | QTest::newRow(dataTag: "65536" ) << Q_UINT64_C(65536) << QByteArray("65536" ) << QByteArray("65,536" ); |
| 2344 | QTest::newRow(dataTag: "65537" ) << Q_UINT64_C(65537) << QByteArray("65537" ) << QByteArray("65,537" ); |
| 2345 | QTest::newRow(dataTag: "2147483647" ) << Q_UINT64_C(2147483647) << QByteArray("2147483647" ) << QByteArray("2,147,483,647" ); |
| 2346 | QTest::newRow(dataTag: "2147483648" ) << Q_UINT64_C(2147483648) << QByteArray("-2147483648" ) << QByteArray("-2,147,483,648" ); |
| 2347 | QTest::newRow(dataTag: "2147483649" ) << Q_UINT64_C(2147483649) << QByteArray("-2147483647" ) << QByteArray("-2,147,483,647" ); |
| 2348 | QTest::newRow(dataTag: "4294967295" ) << Q_UINT64_C(4294967295) << QByteArray("-1" ) << QByteArray("-1" ); |
| 2349 | QTest::newRow(dataTag: "4294967296" ) << Q_UINT64_C(4294967296) << QByteArray("0" ) << QByteArray("0" ); |
| 2350 | QTest::newRow(dataTag: "4294967297" ) << Q_UINT64_C(4294967297) << QByteArray("1" ) << QByteArray("1" ); |
| 2351 | } |
| 2352 | IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedInt, signed int) |
| 2353 | ; |
| 2354 | |
| 2355 | // ------------------------------------------------------------------------------ |
| 2356 | void tst_QTextStream::unsignedInt_write_operator_ToDevice_data() |
| 2357 | { |
| 2358 | QTest::addColumn<qulonglong>(name: "number" ); |
| 2359 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2360 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2361 | |
| 2362 | QTest::newRow(dataTag: "0" ) << Q_UINT64_C(0) << QByteArray("0" ) << QByteArray("0" ); |
| 2363 | QTest::newRow(dataTag: "1" ) << Q_UINT64_C(1) << QByteArray("1" ) << QByteArray("1" ); |
| 2364 | QTest::newRow(dataTag: "-1" ) << quint64(-1) << QByteArray("4294967295" ) << QByteArray("4,294,967,295" ); |
| 2365 | QTest::newRow(dataTag: "32767" ) << Q_UINT64_C(32767) << QByteArray("32767" ) << QByteArray("32,767" ); |
| 2366 | QTest::newRow(dataTag: "32768" ) << Q_UINT64_C(32768) << QByteArray("32768" ) << QByteArray("32,768" ); |
| 2367 | QTest::newRow(dataTag: "32769" ) << Q_UINT64_C(32769) << QByteArray("32769" ) << QByteArray("32,769" ); |
| 2368 | QTest::newRow(dataTag: "65535" ) << Q_UINT64_C(65535) << QByteArray("65535" ) << QByteArray("65,535" ); |
| 2369 | QTest::newRow(dataTag: "65536" ) << Q_UINT64_C(65536) << QByteArray("65536" ) << QByteArray("65,536" ); |
| 2370 | QTest::newRow(dataTag: "65537" ) << Q_UINT64_C(65537) << QByteArray("65537" ) << QByteArray("65,537" ); |
| 2371 | QTest::newRow(dataTag: "2147483647" ) << Q_UINT64_C(2147483647) << QByteArray("2147483647" ) << QByteArray("2,147,483,647" ); |
| 2372 | QTest::newRow(dataTag: "2147483648" ) << Q_UINT64_C(2147483648) << QByteArray("2147483648" ) << QByteArray("2,147,483,648" ); |
| 2373 | QTest::newRow(dataTag: "2147483649" ) << Q_UINT64_C(2147483649) << QByteArray("2147483649" ) << QByteArray("2,147,483,649" ); |
| 2374 | QTest::newRow(dataTag: "4294967295" ) << Q_UINT64_C(4294967295) << QByteArray("4294967295" ) << QByteArray("4,294,967,295" ); |
| 2375 | QTest::newRow(dataTag: "4294967296" ) << Q_UINT64_C(4294967296) << QByteArray("0" ) << QByteArray("0" ); |
| 2376 | QTest::newRow(dataTag: "4294967297" ) << Q_UINT64_C(4294967297) << QByteArray("1" ) << QByteArray("1" ); |
| 2377 | } |
| 2378 | IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedInt, unsigned int) |
| 2379 | ; |
| 2380 | |
| 2381 | // ------------------------------------------------------------------------------ |
| 2382 | void tst_QTextStream::qlonglong_write_operator_ToDevice_data() |
| 2383 | { |
| 2384 | QTest::addColumn<qulonglong>(name: "number" ); |
| 2385 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2386 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2387 | |
| 2388 | QTest::newRow(dataTag: "0" ) << Q_UINT64_C(0) << QByteArray("0" ) << QByteArray("0" ); |
| 2389 | QTest::newRow(dataTag: "1" ) << Q_UINT64_C(1) << QByteArray("1" ) << QByteArray("1" ); |
| 2390 | QTest::newRow(dataTag: "-1" ) << quint64(-1) << QByteArray("-1" ) << QByteArray("-1" ); |
| 2391 | QTest::newRow(dataTag: "32767" ) << Q_UINT64_C(32767) << QByteArray("32767" ) << QByteArray("32,767" ); |
| 2392 | QTest::newRow(dataTag: "32768" ) << Q_UINT64_C(32768) << QByteArray("32768" ) << QByteArray("32,768" ); |
| 2393 | QTest::newRow(dataTag: "32769" ) << Q_UINT64_C(32769) << QByteArray("32769" ) << QByteArray("32,769" ); |
| 2394 | QTest::newRow(dataTag: "65535" ) << Q_UINT64_C(65535) << QByteArray("65535" ) << QByteArray("65,535" ); |
| 2395 | QTest::newRow(dataTag: "65536" ) << Q_UINT64_C(65536) << QByteArray("65536" ) << QByteArray("65,536" ); |
| 2396 | QTest::newRow(dataTag: "65537" ) << Q_UINT64_C(65537) << QByteArray("65537" ) << QByteArray("65,537" ); |
| 2397 | QTest::newRow(dataTag: "2147483647" ) << Q_UINT64_C(2147483647) << QByteArray("2147483647" ) << QByteArray("2,147,483,647" ); |
| 2398 | QTest::newRow(dataTag: "2147483648" ) << Q_UINT64_C(2147483648) << QByteArray("2147483648" ) << QByteArray("2,147,483,648" ); |
| 2399 | QTest::newRow(dataTag: "2147483649" ) << Q_UINT64_C(2147483649) << QByteArray("2147483649" ) << QByteArray("2,147,483,649" ); |
| 2400 | QTest::newRow(dataTag: "4294967295" ) << Q_UINT64_C(4294967295) << QByteArray("4294967295" ) << QByteArray("4,294,967,295" ); |
| 2401 | QTest::newRow(dataTag: "4294967296" ) << Q_UINT64_C(4294967296) << QByteArray("4294967296" ) << QByteArray("4,294,967,296" ); |
| 2402 | QTest::newRow(dataTag: "4294967297" ) << Q_UINT64_C(4294967297) << QByteArray("4294967297" ) << QByteArray("4,294,967,297" ); |
| 2403 | QTest::newRow(dataTag: "9223372036854775807" ) << Q_UINT64_C(9223372036854775807) << QByteArray("9223372036854775807" ) << QByteArray("9,223,372,036,854,775,807" ); |
| 2404 | QTest::newRow(dataTag: "9223372036854775808" ) << Q_UINT64_C(9223372036854775808) << QByteArray("-9223372036854775808" ) << QByteArray("-9,223,372,036,854,775,808" ); |
| 2405 | QTest::newRow(dataTag: "9223372036854775809" ) << Q_UINT64_C(9223372036854775809) << QByteArray("-9223372036854775807" ) << QByteArray("-9,223,372,036,854,775,807" ); |
| 2406 | QTest::newRow(dataTag: "18446744073709551615" ) << Q_UINT64_C(18446744073709551615) << QByteArray("-1" ) << QByteArray("-1" ); |
| 2407 | } |
| 2408 | IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qlonglong, qlonglong) |
| 2409 | ; |
| 2410 | |
| 2411 | // ------------------------------------------------------------------------------ |
| 2412 | void tst_QTextStream::qulonglong_write_operator_ToDevice_data() |
| 2413 | { |
| 2414 | QTest::addColumn<qulonglong>(name: "number" ); |
| 2415 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2416 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2417 | |
| 2418 | QTest::newRow(dataTag: "0" ) << Q_UINT64_C(0) << QByteArray("0" ) << QByteArray("0" ); |
| 2419 | QTest::newRow(dataTag: "1" ) << Q_UINT64_C(1) << QByteArray("1" ) << QByteArray("1" ); |
| 2420 | QTest::newRow(dataTag: "-1" ) << quint64(-1) << QByteArray("18446744073709551615" ) << QByteArray("18,446,744,073,709,551,615" ); |
| 2421 | QTest::newRow(dataTag: "32767" ) << Q_UINT64_C(32767) << QByteArray("32767" ) << QByteArray("32,767" ); |
| 2422 | QTest::newRow(dataTag: "32768" ) << Q_UINT64_C(32768) << QByteArray("32768" ) << QByteArray("32,768" ); |
| 2423 | QTest::newRow(dataTag: "32769" ) << Q_UINT64_C(32769) << QByteArray("32769" ) << QByteArray("32,769" ); |
| 2424 | QTest::newRow(dataTag: "65535" ) << Q_UINT64_C(65535) << QByteArray("65535" ) << QByteArray("65,535" ); |
| 2425 | QTest::newRow(dataTag: "65536" ) << Q_UINT64_C(65536) << QByteArray("65536" ) << QByteArray("65,536" ); |
| 2426 | QTest::newRow(dataTag: "65537" ) << Q_UINT64_C(65537) << QByteArray("65537" ) << QByteArray("65,537" ); |
| 2427 | QTest::newRow(dataTag: "2147483647" ) << Q_UINT64_C(2147483647) << QByteArray("2147483647" ) << QByteArray("2,147,483,647" ); |
| 2428 | QTest::newRow(dataTag: "2147483648" ) << Q_UINT64_C(2147483648) << QByteArray("2147483648" ) << QByteArray("2,147,483,648" ); |
| 2429 | QTest::newRow(dataTag: "2147483649" ) << Q_UINT64_C(2147483649) << QByteArray("2147483649" ) << QByteArray("2,147,483,649" ); |
| 2430 | QTest::newRow(dataTag: "4294967295" ) << Q_UINT64_C(4294967295) << QByteArray("4294967295" ) << QByteArray("4,294,967,295" ); |
| 2431 | QTest::newRow(dataTag: "4294967296" ) << Q_UINT64_C(4294967296) << QByteArray("4294967296" ) << QByteArray("4,294,967,296" ); |
| 2432 | QTest::newRow(dataTag: "4294967297" ) << Q_UINT64_C(4294967297) << QByteArray("4294967297" ) << QByteArray("4,294,967,297" ); |
| 2433 | QTest::newRow(dataTag: "9223372036854775807" ) << Q_UINT64_C(9223372036854775807) << QByteArray("9223372036854775807" ) << QByteArray("9,223,372,036,854,775,807" ); |
| 2434 | QTest::newRow(dataTag: "9223372036854775808" ) << Q_UINT64_C(9223372036854775808) << QByteArray("9223372036854775808" ) << QByteArray("9,223,372,036,854,775,808" ); |
| 2435 | QTest::newRow(dataTag: "9223372036854775809" ) << Q_UINT64_C(9223372036854775809) << QByteArray("9223372036854775809" ) << QByteArray("9,223,372,036,854,775,809" ); |
| 2436 | QTest::newRow(dataTag: "18446744073709551615" ) << Q_UINT64_C(18446744073709551615) << QByteArray("18446744073709551615" ) << QByteArray("18,446,744,073,709,551,615" ); |
| 2437 | } |
| 2438 | IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qulonglong, qulonglong) |
| 2439 | ; |
| 2440 | |
| 2441 | |
| 2442 | // ------------------------------------------------------------------------------ |
| 2443 | void tst_QTextStream::generateRealNumbersDataWrite() |
| 2444 | { |
| 2445 | QTest::addColumn<double>(name: "number" ); |
| 2446 | QTest::addColumn<QByteArray>(name: "data" ); |
| 2447 | QTest::addColumn<QByteArray>(name: "dataWithSeparators" ); |
| 2448 | |
| 2449 | QTest::newRow(dataTag: "0" ) << 0.0 << QByteArray("0" ) << QByteArray("0" ); |
| 2450 | QTest::newRow(dataTag: "3.14" ) << 3.14 << QByteArray("3.14" ) << QByteArray("3.14" ); |
| 2451 | QTest::newRow(dataTag: "-3.14" ) << -3.14 << QByteArray("-3.14" ) << QByteArray("-3.14" ); |
| 2452 | QTest::newRow(dataTag: "1.2e+10" ) << 1.2e+10 << QByteArray("1.2e+10" ) << QByteArray("1.2e+10" ); |
| 2453 | QTest::newRow(dataTag: "-1.2e+10" ) << -1.2e+10 << QByteArray("-1.2e+10" ) << QByteArray("-1.2e+10" ); |
| 2454 | QTest::newRow(dataTag: "12345" ) << 12345. << QByteArray("12345" ) << QByteArray("12,345" ); |
| 2455 | } |
| 2456 | |
| 2457 | // ------------------------------------------------------------------------------ |
| 2458 | #define IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(texttype, type) \ |
| 2459 | void tst_QTextStream:: texttype##_write_operator_ToDevice_data() \ |
| 2460 | { generateRealNumbersDataWrite(); } \ |
| 2461 | void tst_QTextStream:: texttype##_write_operator_ToDevice() \ |
| 2462 | { \ |
| 2463 | QFETCH(double, number); \ |
| 2464 | QFETCH(QByteArray, data); \ |
| 2465 | QFETCH(QByteArray, dataWithSeparators); \ |
| 2466 | \ |
| 2467 | QBuffer buffer; \ |
| 2468 | buffer.open(QBuffer::WriteOnly); \ |
| 2469 | QTextStream stream(&buffer); \ |
| 2470 | stream.setLocale(QLocale::c()); \ |
| 2471 | float f = (float)number; \ |
| 2472 | stream << f; \ |
| 2473 | stream.flush(); \ |
| 2474 | QCOMPARE(buffer.data().constData(), data.constData()); \ |
| 2475 | \ |
| 2476 | buffer.reset(); \ |
| 2477 | stream.setLocale(QLocale("en-US")); \ |
| 2478 | stream << f; \ |
| 2479 | stream.flush(); \ |
| 2480 | QCOMPARE(buffer.data(), dataWithSeparators); \ |
| 2481 | } |
| 2482 | IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(float, float) |
| 2483 | IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(double, float) |
| 2484 | ; |
| 2485 | |
| 2486 | // ------------------------------------------------------------------------------ |
| 2487 | void tst_QTextStream::string_write_operator_ToDevice_data() |
| 2488 | { |
| 2489 | QTest::addColumn<QByteArray>(name: "bytedata" ); |
| 2490 | QTest::addColumn<QString>(name: "stringdata" ); |
| 2491 | QTest::addColumn<QByteArray>(name: "result" ); |
| 2492 | |
| 2493 | QTest::newRow(dataTag: "empty" ) << QByteArray("" , 1) << QString(1, '\0') << QByteArray("" , 1); |
| 2494 | QTest::newRow(dataTag: "a" ) << QByteArray("a" ) << QString("a" ) << QByteArray("a" ); |
| 2495 | QTest::newRow(dataTag: "a cow jumped over the moon" ) |
| 2496 | << QByteArray("a cow jumped over the moon" ) |
| 2497 | << QString("a cow jumped over the moon" ) |
| 2498 | << QByteArray("a cow jumped over the moon" ); |
| 2499 | |
| 2500 | // ### get the utf16-be test on its legs. |
| 2501 | /* |
| 2502 | QTest::newRow("utf16-BE (a cow jumped over the moon)") |
| 2503 | << QByteArray("\xff\xfe\x00\x61\x00\x20\x00\x63\x00\x6f\x00\x77\x00\x20\x00\x6a\x00\x75\x00\x6d\x00\x70\x00\x65\x00\x64\x00\x20\x00\x6f\x00\x76\x00\x65\x00\x72\x00\x20\x00\x74\x00\x68\x00\x65\x00\x20\x00\x6d\x00\x6f\x00\x6f\x00\x6e\x00\x0a", 56) |
| 2504 | << QString("a cow jumped over the moon") |
| 2505 | << QByteArray("a cow jumped over the moon"); |
| 2506 | */ |
| 2507 | } |
| 2508 | |
| 2509 | // ------------------------------------------------------------------------------ |
| 2510 | void tst_QTextStream::string_write_operator_ToDevice() |
| 2511 | { |
| 2512 | QFETCH(QByteArray, bytedata); |
| 2513 | QFETCH(QString, stringdata); |
| 2514 | QFETCH(QByteArray, result); |
| 2515 | |
| 2516 | { |
| 2517 | // char* |
| 2518 | QBuffer buf; |
| 2519 | buf.open(openMode: QBuffer::WriteOnly); |
| 2520 | QTextStream stream(&buf); |
| 2521 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2522 | stream.setAutoDetectUnicode(true); |
| 2523 | |
| 2524 | stream << bytedata.constData(); |
| 2525 | stream.flush(); |
| 2526 | QCOMPARE(buf.buffer().constData(), result.constData()); |
| 2527 | } |
| 2528 | { |
| 2529 | // QByteArray |
| 2530 | QBuffer buf; |
| 2531 | buf.open(openMode: QBuffer::WriteOnly); |
| 2532 | QTextStream stream(&buf); |
| 2533 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2534 | stream.setAutoDetectUnicode(true); |
| 2535 | |
| 2536 | stream << bytedata; |
| 2537 | stream.flush(); |
| 2538 | QCOMPARE(buf.buffer().constData(), result.constData()); |
| 2539 | } |
| 2540 | { |
| 2541 | // QString |
| 2542 | QBuffer buf; |
| 2543 | buf.open(openMode: QBuffer::WriteOnly); |
| 2544 | QTextStream stream(&buf); |
| 2545 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2546 | stream.setAutoDetectUnicode(true); |
| 2547 | |
| 2548 | stream << stringdata; |
| 2549 | stream.flush(); |
| 2550 | QCOMPARE(buf.buffer().constData(), result.constData()); |
| 2551 | } |
| 2552 | } |
| 2553 | |
| 2554 | void tst_QTextStream::latin1String_write_operator_ToDevice() |
| 2555 | { |
| 2556 | QBuffer buf; |
| 2557 | buf.open(openMode: QBuffer::WriteOnly); |
| 2558 | QTextStream stream(&buf); |
| 2559 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2560 | stream.setAutoDetectUnicode(true); |
| 2561 | |
| 2562 | stream << QLatin1String("No explicit length" ); |
| 2563 | stream << QLatin1String("Explicit length - ignore this part" , 15); |
| 2564 | stream.flush(); |
| 2565 | QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length" ); |
| 2566 | } |
| 2567 | |
| 2568 | void tst_QTextStream::stringref_write_operator_ToDevice() |
| 2569 | { |
| 2570 | QBuffer buf; |
| 2571 | buf.open(openMode: QBuffer::WriteOnly); |
| 2572 | QTextStream stream(&buf); |
| 2573 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2574 | stream.setAutoDetectUnicode(true); |
| 2575 | |
| 2576 | const QString expected = "No explicit lengthExplicit length" ; |
| 2577 | |
| 2578 | stream << expected.leftRef(n: 18); |
| 2579 | stream << expected.midRef(position: 18); |
| 2580 | stream.flush(); |
| 2581 | QCOMPARE(buf.buffer().constData(), "No explicit lengthExplicit length" ); |
| 2582 | } |
| 2583 | |
| 2584 | void tst_QTextStream::stringview_write_operator_ToDevice() |
| 2585 | { |
| 2586 | QBuffer buf; |
| 2587 | buf.open(openMode: QBuffer::WriteOnly); |
| 2588 | QTextStream stream(&buf); |
| 2589 | const QStringView expected = u"expectedStringView" ; |
| 2590 | stream << expected; |
| 2591 | stream.flush(); |
| 2592 | QCOMPARE(buf.buffer().constData(), "expectedStringView" ); |
| 2593 | } |
| 2594 | |
| 2595 | // ------------------------------------------------------------------------------ |
| 2596 | void tst_QTextStream::useCase1() |
| 2597 | { |
| 2598 | QFile::remove(fileName: "testfile" ); |
| 2599 | QFile file("testfile" ); |
| 2600 | QVERIFY(file.open(QFile::ReadWrite)); |
| 2601 | |
| 2602 | { |
| 2603 | QTextStream stream(&file); |
| 2604 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2605 | stream.setAutoDetectUnicode(true); |
| 2606 | |
| 2607 | stream << 4.15 << ' ' << QByteArray("abc" ) << ' ' << QString("ole" ); |
| 2608 | } |
| 2609 | |
| 2610 | file.seek(offset: 0); |
| 2611 | QCOMPARE(file.readAll(), QByteArray("4.15 abc ole" )); |
| 2612 | file.seek(offset: 0); |
| 2613 | |
| 2614 | { |
| 2615 | double d; |
| 2616 | QByteArray a; |
| 2617 | QString s; |
| 2618 | QTextStream stream(&file); |
| 2619 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2620 | stream.setAutoDetectUnicode(true); |
| 2621 | |
| 2622 | stream >> d; |
| 2623 | stream >> a; |
| 2624 | stream >> s; |
| 2625 | |
| 2626 | QCOMPARE(d, 4.15); |
| 2627 | QCOMPARE(a, QByteArray("abc" )); |
| 2628 | QCOMPARE(s, QString("ole" )); |
| 2629 | } |
| 2630 | } |
| 2631 | |
| 2632 | // ------------------------------------------------------------------------------ |
| 2633 | void tst_QTextStream::useCase2() |
| 2634 | { |
| 2635 | QFile::remove(fileName: "testfile" ); |
| 2636 | QFile file("testfile" ); |
| 2637 | QVERIFY(file.open(QFile::ReadWrite)); |
| 2638 | |
| 2639 | QTextStream stream(&file); |
| 2640 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2641 | stream.setAutoDetectUnicode(true); |
| 2642 | |
| 2643 | stream << 4.15 << ' ' << QByteArray("abc" ) << ' ' << QString("ole" ); |
| 2644 | |
| 2645 | file.close(); |
| 2646 | QVERIFY(file.open(QFile::ReadWrite)); |
| 2647 | |
| 2648 | QCOMPARE(file.readAll(), QByteArray("4.15 abc ole" )); |
| 2649 | |
| 2650 | file.close(); |
| 2651 | QVERIFY(file.open(QFile::ReadWrite)); |
| 2652 | |
| 2653 | double d; |
| 2654 | QByteArray a; |
| 2655 | QString s; |
| 2656 | QTextStream stream2(&file); |
| 2657 | stream2.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2658 | stream2.setAutoDetectUnicode(true); |
| 2659 | |
| 2660 | stream2 >> d; |
| 2661 | stream2 >> a; |
| 2662 | stream2 >> s; |
| 2663 | |
| 2664 | QCOMPARE(d, 4.15); |
| 2665 | QCOMPARE(a, QByteArray("abc" )); |
| 2666 | QCOMPARE(s, QString("ole" )); |
| 2667 | } |
| 2668 | |
| 2669 | // ------------------------------------------------------------------------------ |
| 2670 | void tst_QTextStream::manipulators_data() |
| 2671 | { |
| 2672 | QTest::addColumn<int>(name: "base" ); |
| 2673 | QTest::addColumn<int>(name: "alignFlag" ); |
| 2674 | QTest::addColumn<int>(name: "numberFlag" ); |
| 2675 | QTest::addColumn<int>(name: "width" ); |
| 2676 | QTest::addColumn<double>(name: "realNumber" ); |
| 2677 | QTest::addColumn<int>(name: "intNumber" ); |
| 2678 | QTest::addColumn<QString>(name: "textData" ); |
| 2679 | QTest::addColumn<QByteArray>(name: "result" ); |
| 2680 | |
| 2681 | QTest::newRow(dataTag: "no flags" ) << 10 << 0 << 0 << 0 << 5.0 << 5 << QString("five" ) << QByteArray("55five" ); |
| 2682 | QTest::newRow(dataTag: "rightadjust" ) << 10 << int(QTextStream::AlignRight) << 0 << 10 << 5.0 << 5 << QString("five" ) << QByteArray(" 5 5 five" ); |
| 2683 | QTest::newRow(dataTag: "leftadjust" ) << 10 << int(QTextStream::AlignLeft) << 0 << 10 << 5.0 << 5 << QString("five" ) << QByteArray("5 5 five " ); |
| 2684 | QTest::newRow(dataTag: "showpos" ) << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 10 << 5.0 << 5 << QString("five" ) << QByteArray(" +5 +5 five" ); |
| 2685 | QTest::newRow(dataTag: "showpos2" ) << 10 << int(QTextStream::AlignRight) << int(QTextStream::ForceSign) << 5 << 3.14 << -5 << QString("five" ) << QByteArray("+3.14 -5 five" ); |
| 2686 | QTest::newRow(dataTag: "hex" ) << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase) << 5 << 3.14 << -5 << QString("five" ) << QByteArray(" 3.14 -0x5 five" ); |
| 2687 | QTest::newRow(dataTag: "hex" ) << 16 << int(QTextStream::AlignRight) << int(QTextStream::ShowBase | QTextStream::UppercaseBase) << 5 << 3.14 << -5 << QString("five" ) << QByteArray(" 3.14 -0X5 five" ); |
| 2688 | } |
| 2689 | |
| 2690 | // ------------------------------------------------------------------------------ |
| 2691 | void tst_QTextStream::manipulators() |
| 2692 | { |
| 2693 | QFETCH(int, base); |
| 2694 | QFETCH(int, alignFlag); |
| 2695 | QFETCH(int, numberFlag); |
| 2696 | QFETCH(int, width); |
| 2697 | QFETCH(double, realNumber); |
| 2698 | QFETCH(int, intNumber); |
| 2699 | QFETCH(QString, textData); |
| 2700 | QFETCH(QByteArray, result); |
| 2701 | |
| 2702 | QBuffer buffer; |
| 2703 | buffer.open(openMode: QBuffer::WriteOnly); |
| 2704 | |
| 2705 | QTextStream stream(&buffer); |
| 2706 | stream.setCodec(QTextCodec::codecForName(name: "ISO-8859-1" )); |
| 2707 | stream.setAutoDetectUnicode(true); |
| 2708 | |
| 2709 | stream.setIntegerBase(base); |
| 2710 | stream.setFieldAlignment(QTextStream::FieldAlignment(alignFlag)); |
| 2711 | stream.setNumberFlags(QTextStream::NumberFlag(numberFlag)); |
| 2712 | stream.setFieldWidth(width); |
| 2713 | stream << realNumber; |
| 2714 | stream << intNumber; |
| 2715 | stream << textData; |
| 2716 | stream.flush(); |
| 2717 | |
| 2718 | QCOMPARE(buffer.data(), result); |
| 2719 | } |
| 2720 | |
| 2721 | void tst_QTextStream::generateBOM() |
| 2722 | { |
| 2723 | QFile::remove(fileName: "bom.txt" ); |
| 2724 | { |
| 2725 | QFile file("bom.txt" ); |
| 2726 | QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate)); |
| 2727 | |
| 2728 | QTextStream stream(&file); |
| 2729 | stream.setCodec(QTextCodec::codecForName(name: "UTF-16LE" )); |
| 2730 | stream << "Hello" << Qt::endl; |
| 2731 | |
| 2732 | file.close(); |
| 2733 | QVERIFY(file.open(QFile::ReadOnly)); |
| 2734 | QCOMPARE(file.readAll(), QByteArray("\x48\x00\x65\00\x6c\00\x6c\00\x6f\x00\x0a\x00" , 12)); |
| 2735 | } |
| 2736 | |
| 2737 | QFile::remove(fileName: "bom.txt" ); |
| 2738 | { |
| 2739 | QFile file("bom.txt" ); |
| 2740 | QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate)); |
| 2741 | |
| 2742 | QTextStream stream(&file); |
| 2743 | stream.setCodec(QTextCodec::codecForName(name: "UTF-16LE" )); |
| 2744 | stream << Qt::bom << "Hello" << Qt::endl; |
| 2745 | |
| 2746 | file.close(); |
| 2747 | QVERIFY(file.open(QFile::ReadOnly)); |
| 2748 | QCOMPARE(file.readAll(), QByteArray("\xff\xfe\x48\x00\x65\00\x6c\00\x6c\00\x6f\x00\x0a\x00" , 14)); |
| 2749 | } |
| 2750 | } |
| 2751 | |
| 2752 | void tst_QTextStream::readBomSeekBackReadBomAgain() |
| 2753 | { |
| 2754 | QFile::remove(fileName: "utf8bom" ); |
| 2755 | QFile file("utf8bom" ); |
| 2756 | QVERIFY(file.open(QFile::ReadWrite)); |
| 2757 | file.write(data: "\xef\xbb\xbf" "Andreas" ); |
| 2758 | file.seek(offset: 0); |
| 2759 | QCOMPARE(file.pos(), qint64(0)); |
| 2760 | |
| 2761 | QTextStream stream(&file); |
| 2762 | stream.setCodec("UTF-8" ); |
| 2763 | QString Andreas; |
| 2764 | stream >> Andreas; |
| 2765 | QCOMPARE(Andreas, QString("Andreas" )); |
| 2766 | stream.seek(pos: 0); |
| 2767 | stream >> Andreas; |
| 2768 | QCOMPARE(Andreas, QString("Andreas" )); |
| 2769 | } |
| 2770 | |
| 2771 | // ------------------------------------------------------------------------------ |
| 2772 | void tst_QTextStream::status_real_read_data() |
| 2773 | { |
| 2774 | QTest::addColumn<QString>(name: "input" ); |
| 2775 | QTest::addColumn<double>(name: "expected_f" ); |
| 2776 | QTest::addColumn<QString>(name: "expected_w" ); |
| 2777 | QTest::addColumn<QList<int> >(name: "results" ); |
| 2778 | |
| 2779 | QTest::newRow(dataTag: "1.23 abc " ) << QString("1.23 abc " ) << 1.23 << QString("abc" ) |
| 2780 | << (QList<int>() |
| 2781 | << (int)QTextStream::Ok |
| 2782 | << (int)QTextStream::ReadCorruptData |
| 2783 | << (int)QTextStream::Ok |
| 2784 | << (int)QTextStream::Ok |
| 2785 | << (int)QTextStream::ReadPastEnd); |
| 2786 | } |
| 2787 | |
| 2788 | void tst_QTextStream::status_real_read() |
| 2789 | { |
| 2790 | QFETCH(QString, input); |
| 2791 | QFETCH(double, expected_f); |
| 2792 | QFETCH(QString, expected_w); |
| 2793 | QFETCH(QList<int>, results); |
| 2794 | |
| 2795 | QTextStream s(&input); |
| 2796 | double f = 0.0; |
| 2797 | QString w; |
| 2798 | s >> f; |
| 2799 | QCOMPARE((int)s.status(), results.at(0)); |
| 2800 | QCOMPARE(f, expected_f); |
| 2801 | s >> f; |
| 2802 | QCOMPARE((int)s.status(), results.at(1)); |
| 2803 | s.resetStatus(); |
| 2804 | QCOMPARE((int)s.status(), results.at(2)); |
| 2805 | s >> w; |
| 2806 | QCOMPARE((int)s.status(), results.at(3)); |
| 2807 | QCOMPARE(w, expected_w); |
| 2808 | s >> f; |
| 2809 | QCOMPARE((int)s.status(), results.at(4)); |
| 2810 | } |
| 2811 | |
| 2812 | void tst_QTextStream::status_integer_read() |
| 2813 | { |
| 2814 | QTextStream s("123 abc " ); |
| 2815 | int i; |
| 2816 | QString w; |
| 2817 | s >> i; |
| 2818 | QCOMPARE(s.status(), QTextStream::Ok); |
| 2819 | s >> i; |
| 2820 | QCOMPARE(s.status(), QTextStream::ReadCorruptData); |
| 2821 | s.resetStatus(); |
| 2822 | QCOMPARE(s.status(), QTextStream::Ok); |
| 2823 | s >> w; |
| 2824 | QCOMPARE(s.status(), QTextStream::Ok); |
| 2825 | QCOMPARE(w, QString("abc" )); |
| 2826 | s >> i; |
| 2827 | QCOMPARE(s.status(), QTextStream::ReadPastEnd); |
| 2828 | } |
| 2829 | |
| 2830 | void tst_QTextStream::status_word_read() |
| 2831 | { |
| 2832 | QTextStream s("abc " ); |
| 2833 | QString w; |
| 2834 | s >> w; |
| 2835 | QCOMPARE(s.status(), QTextStream::Ok); |
| 2836 | s >> w; |
| 2837 | QCOMPARE(s.status(), QTextStream::ReadPastEnd); |
| 2838 | } |
| 2839 | |
| 2840 | class FakeBuffer : public QBuffer |
| 2841 | { |
| 2842 | protected: |
| 2843 | qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(data: c, len: i); } |
| 2844 | public: |
| 2845 | FakeBuffer(bool locked = false) : m_lock(locked) {} |
| 2846 | void setLocked(bool locked) { m_lock = locked; } |
| 2847 | private: |
| 2848 | bool m_lock; |
| 2849 | }; |
| 2850 | |
| 2851 | void tst_QTextStream::status_write_error() |
| 2852 | { |
| 2853 | FakeBuffer fb(false); |
| 2854 | QVERIFY(fb.open(QBuffer::ReadWrite)); |
| 2855 | QTextStream fs(&fb); |
| 2856 | fs.setCodec(QTextCodec::codecForName(name: "latin1" )); |
| 2857 | /* first write some initial content */ |
| 2858 | fs << "hello" ; |
| 2859 | fs.flush(); |
| 2860 | QCOMPARE(fs.status(), QTextStream::Ok); |
| 2861 | QCOMPARE(fb.data(), QByteArray("hello" )); |
| 2862 | /* then test that writing can cause an error */ |
| 2863 | fb.setLocked(true); |
| 2864 | fs << "error" ; |
| 2865 | fs.flush(); |
| 2866 | QCOMPARE(fs.status(), QTextStream::WriteFailed); |
| 2867 | QCOMPARE(fb.data(), QByteArray("hello" )); |
| 2868 | /* finally test that writing after an error doesn't change the stream any more */ |
| 2869 | fb.setLocked(false); |
| 2870 | fs << "can't do that" ; |
| 2871 | fs.flush(); |
| 2872 | QCOMPARE(fs.status(), QTextStream::WriteFailed); |
| 2873 | QCOMPARE(fb.data(), QByteArray("hello" )); |
| 2874 | } |
| 2875 | |
| 2876 | void tst_QTextStream::alignAccountingStyle() |
| 2877 | { |
| 2878 | { |
| 2879 | QString result; |
| 2880 | QTextStream out(&result); |
| 2881 | out.setFieldAlignment(QTextStream::AlignAccountingStyle); |
| 2882 | out.setFieldWidth(4); |
| 2883 | out.setPadChar('0'); |
| 2884 | out << -1; |
| 2885 | QCOMPARE(result, QLatin1String("-001" )); |
| 2886 | } |
| 2887 | |
| 2888 | { |
| 2889 | QString result; |
| 2890 | QTextStream out(&result); |
| 2891 | out.setFieldAlignment(QTextStream::AlignAccountingStyle); |
| 2892 | out.setFieldWidth(4); |
| 2893 | out.setPadChar('0'); |
| 2894 | out << "-1" ; |
| 2895 | QCOMPARE(result, QLatin1String("00-1" )); |
| 2896 | } |
| 2897 | |
| 2898 | { |
| 2899 | QString result; |
| 2900 | QTextStream out(&result); |
| 2901 | out.setFieldAlignment(QTextStream::AlignAccountingStyle); |
| 2902 | out.setFieldWidth(6); |
| 2903 | out.setPadChar('0'); |
| 2904 | out << -1.2; |
| 2905 | QCOMPARE(result, QLatin1String("-001.2" )); |
| 2906 | } |
| 2907 | |
| 2908 | { |
| 2909 | QString result; |
| 2910 | QTextStream out(&result); |
| 2911 | out.setFieldAlignment(QTextStream::AlignAccountingStyle); |
| 2912 | out.setFieldWidth(6); |
| 2913 | out.setPadChar('0'); |
| 2914 | out << "-1.2" ; |
| 2915 | QCOMPARE(result, QLatin1String("00-1.2" )); |
| 2916 | } |
| 2917 | } |
| 2918 | |
| 2919 | void tst_QTextStream::setCodec() |
| 2920 | { |
| 2921 | QByteArray ba("\xe5 v\xe6r\n\xc3\xa5 v\xc3\xa6r\n" ); |
| 2922 | QString res = QLatin1String("\xe5 v\xe6r" ); |
| 2923 | |
| 2924 | QTextStream stream(ba); |
| 2925 | stream.setCodec("ISO 8859-1" ); |
| 2926 | QCOMPARE(stream.readLine(),res); |
| 2927 | stream.setCodec("UTF-8" ); |
| 2928 | QCOMPARE(stream.readLine(),res); |
| 2929 | } |
| 2930 | |
| 2931 | void tst_QTextStream::double_write_with_flags_data() |
| 2932 | { |
| 2933 | QTest::addColumn<double>(name: "number" ); |
| 2934 | QTest::addColumn<QString>(name: "output" ); |
| 2935 | QTest::addColumn<int>(name: "numberFlags" ); |
| 2936 | QTest::addColumn<int>(name: "realNumberNotation" ); |
| 2937 | |
| 2938 | QTest::newRow(dataTag: "-ForceSign" ) << -1.23 << QString("-1.23" ) << (int)QTextStream::ForceSign << 0; |
| 2939 | QTest::newRow(dataTag: "+ForceSign" ) << 1.23 << QString("+1.23" ) << (int)QTextStream::ForceSign << 0; |
| 2940 | QTest::newRow(dataTag: "inf" ) << qInf() << QString("inf" ) << 0 << 0; |
| 2941 | QTest::newRow(dataTag: "-inf" ) << -qInf() << QString("-inf" ) << 0 << 0; |
| 2942 | QTest::newRow(dataTag: "inf uppercase" ) << qInf() << QString("INF" ) << (int)QTextStream::UppercaseDigits << 0; |
| 2943 | QTest::newRow(dataTag: "-inf uppercase" ) << -qInf() << QString("-INF" ) << (int)QTextStream::UppercaseDigits << 0; |
| 2944 | QTest::newRow(dataTag: "nan" ) << qQNaN() << QString("nan" ) << 0 << 0; |
| 2945 | QTest::newRow(dataTag: "NAN" ) << qQNaN() << QString("NAN" ) << (int)QTextStream::UppercaseDigits << 0; |
| 2946 | QTest::newRow(dataTag: "scientific" ) << 1.234567e+02 << QString("1.234567e+02" ) << 0 << (int)QTextStream::ScientificNotation; |
| 2947 | QTest::newRow(dataTag: "scientific2" ) << 1.234567e+02 << QString("1.234567e+02" ) << (int)QTextStream::UppercaseBase << (int)QTextStream::ScientificNotation; |
| 2948 | QTest::newRow(dataTag: "scientific uppercase" ) << 1.234567e+02 << QString("1.234567E+02" ) << (int)QTextStream::UppercaseDigits << (int)QTextStream::ScientificNotation; |
| 2949 | } |
| 2950 | |
| 2951 | void tst_QTextStream::double_write_with_flags() |
| 2952 | { |
| 2953 | QFETCH(double, number); |
| 2954 | QFETCH(QString, output); |
| 2955 | QFETCH(int, numberFlags); |
| 2956 | QFETCH(int, realNumberNotation); |
| 2957 | |
| 2958 | QString buf; |
| 2959 | QTextStream stream(&buf); |
| 2960 | if (numberFlags) |
| 2961 | stream.setNumberFlags(QTextStream::NumberFlag(numberFlags)); |
| 2962 | if (realNumberNotation) |
| 2963 | stream.setRealNumberNotation(QTextStream::RealNumberNotation(realNumberNotation)); |
| 2964 | stream << number; |
| 2965 | QCOMPARE(buf, output); |
| 2966 | } |
| 2967 | |
| 2968 | void tst_QTextStream::double_write_with_precision_data() |
| 2969 | { |
| 2970 | QTest::addColumn<int>(name: "precision" ); |
| 2971 | QTest::addColumn<double>(name: "value" ); |
| 2972 | QTest::addColumn<QString>(name: "result" ); |
| 2973 | |
| 2974 | QTest::ignoreMessage(type: QtWarningMsg, message: "QTextStream::setRealNumberPrecision: Invalid precision (-1)" ); |
| 2975 | QTest::newRow(dataTag: "-1" ) << -1 << 3.14159 << QString("3.14159" ); |
| 2976 | QTest::newRow(dataTag: "0" ) << 0 << 3.14159 << QString("3" ); |
| 2977 | QTest::newRow(dataTag: "1" ) << 1 << 3.14159 << QString("3" ); |
| 2978 | QTest::newRow(dataTag: "2" ) << 2 << 3.14159 << QString("3.1" ); |
| 2979 | QTest::newRow(dataTag: "3" ) << 3 << 3.14159 << QString("3.14" ); |
| 2980 | QTest::newRow(dataTag: "5" ) << 5 << 3.14159 << QString("3.1416" ); |
| 2981 | QTest::newRow(dataTag: "6" ) << 6 << 3.14159 << QString("3.14159" ); |
| 2982 | QTest::newRow(dataTag: "7" ) << 7 << 3.14159 << QString("3.14159" ); |
| 2983 | QTest::newRow(dataTag: "10" ) << 10 << 3.14159 << QString("3.14159" ); |
| 2984 | } |
| 2985 | |
| 2986 | void tst_QTextStream::double_write_with_precision() |
| 2987 | { |
| 2988 | QFETCH(int, precision); |
| 2989 | QFETCH(double, value); |
| 2990 | QFETCH(QString, result); |
| 2991 | |
| 2992 | QString buf; |
| 2993 | QTextStream stream(&buf); |
| 2994 | stream.setRealNumberPrecision(precision); |
| 2995 | stream << value; |
| 2996 | QCOMPARE(buf, result); |
| 2997 | } |
| 2998 | |
| 2999 | void tst_QTextStream::int_read_with_locale_data() |
| 3000 | { |
| 3001 | QTest::addColumn<QString>(name: "locale" ); |
| 3002 | QTest::addColumn<QString>(name: "input" ); |
| 3003 | QTest::addColumn<int>(name: "output" ); |
| 3004 | |
| 3005 | QTest::newRow(dataTag: "C -123" ) << QString("C" ) << QString("-123" ) << -123; |
| 3006 | QTest::newRow(dataTag: "C +123" ) << QString("C" ) << QString("+123" ) << 123; |
| 3007 | QTest::newRow(dataTag: "C 12345" ) << QString("C" ) << QString("12345" ) << 12345; |
| 3008 | QTest::newRow(dataTag: "C 12,345" ) << QString("C" ) << QString("12,345" ) << 12; |
| 3009 | QTest::newRow(dataTag: "C 12.345" ) << QString("C" ) << QString("12.345" ) << 12; |
| 3010 | |
| 3011 | QTest::newRow(dataTag: "de_DE -123" ) << QString("de_DE" ) << QString("-123" ) << -123; |
| 3012 | QTest::newRow(dataTag: "de_DE +123" ) << QString("de_DE" ) << QString("+123" ) << 123; |
| 3013 | QTest::newRow(dataTag: "de_DE 12345" ) << QString("de_DE" ) << QString("12345" ) << 12345; |
| 3014 | QTest::newRow(dataTag: "de_DE 12.345" ) << QString("de_DE" ) << QString("12.345" ) << 12345; |
| 3015 | QTest::newRow(dataTag: "de_DE .12345" ) << QString("de_DE" ) << QString(".12345" ) << 0; |
| 3016 | } |
| 3017 | |
| 3018 | void tst_QTextStream::int_read_with_locale() |
| 3019 | { |
| 3020 | QFETCH(QString, locale); |
| 3021 | QFETCH(QString, input); |
| 3022 | QFETCH(int, output); |
| 3023 | |
| 3024 | QTextStream stream(&input); |
| 3025 | stream.setLocale(locale); |
| 3026 | int result; |
| 3027 | stream >> result; |
| 3028 | QCOMPARE(result, output); |
| 3029 | } |
| 3030 | |
| 3031 | void tst_QTextStream::int_write_with_locale_data() |
| 3032 | { |
| 3033 | QTest::addColumn<QString>(name: "locale" ); |
| 3034 | QTest::addColumn<int>(name: "numberFlags" ); |
| 3035 | QTest::addColumn<int>(name: "input" ); |
| 3036 | QTest::addColumn<QString>(name: "output" ); |
| 3037 | |
| 3038 | QTest::newRow(dataTag: "C -123" ) << QString("C" ) << 0 << -123 << QString("-123" ); |
| 3039 | QTest::newRow(dataTag: "C +123" ) << QString("C" ) << (int)QTextStream::ForceSign << 123 << QString("+123" ); |
| 3040 | QTest::newRow(dataTag: "C 12345" ) << QString("C" ) << 0 << 12345 << QString("12345" ); |
| 3041 | |
| 3042 | QTest::newRow(dataTag: "de_DE -123" ) << QString("de_DE" ) << 0 << -123 << QString("-123" ); |
| 3043 | QTest::newRow(dataTag: "de_DE +123" ) << QString("de_DE" ) << (int)QTextStream::ForceSign << 123 << QString("+123" ); |
| 3044 | QTest::newRow(dataTag: "de_DE 12345" ) << QString("de_DE" ) << 0 << 12345 << QString("12.345" ); |
| 3045 | } |
| 3046 | |
| 3047 | void tst_QTextStream::int_write_with_locale() |
| 3048 | { |
| 3049 | QFETCH(QString, locale); |
| 3050 | QFETCH(int, numberFlags); |
| 3051 | QFETCH(int, input); |
| 3052 | QFETCH(QString, output); |
| 3053 | |
| 3054 | QString result; |
| 3055 | QTextStream stream(&result); |
| 3056 | stream.setLocale(locale); |
| 3057 | if (numberFlags) |
| 3058 | stream.setNumberFlags(QTextStream::NumberFlags(numberFlags)); |
| 3059 | stream << input; |
| 3060 | QCOMPARE(result, output); |
| 3061 | } |
| 3062 | |
| 3063 | void tst_QTextStream::textModeOnEmptyRead() |
| 3064 | { |
| 3065 | const QString filename(tempDir.path() + QLatin1String("/textmodetest.txt" )); |
| 3066 | |
| 3067 | QFile file(filename); |
| 3068 | QVERIFY2(file.open(QIODevice::ReadWrite | QIODevice::Text), qPrintable(file.errorString())); |
| 3069 | QTextStream stream(&file); |
| 3070 | QVERIFY(file.isTextModeEnabled()); |
| 3071 | QString emptyLine = stream.readLine(); // Text mode flag cleared here |
| 3072 | QVERIFY(file.isTextModeEnabled()); |
| 3073 | } |
| 3074 | |
| 3075 | |
| 3076 | // ------------------------------------------------------------------------------ |
| 3077 | |
| 3078 | QTEST_MAIN(tst_QTextStream) |
| 3079 | #include "tst_qtextstream.moc" |
| 3080 | |
| 3081 | |