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
50QT_BEGIN_NAMESPACE
51template<> struct QMetaTypeId<QIODevice::OpenModeFlag>
52{ enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
53QT_END_NAMESPACE
54
55class tst_QTextStream : public QObject
56{
57 Q_OBJECT
58
59public:
60 tst_QTextStream();
61
62public slots:
63 void initTestCase();
64 void cleanup();
65 void cleanupTestCase();
66
67private 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
228private:
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
246void runOnExit()
247{
248 QByteArray buffer;
249 QTextStream(&buffer) << "This will try to use QTextCodec::codecForLocale" << Qt::endl;
250}
251Q_DESTRUCTOR_FUNCTION(runOnExit)
252
253tst_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
260void 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
279void 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
393void tst_QTextStream::cleanup()
394{
395 QCoreApplication::instance()->processEvents();
396}
397
398void tst_QTextStream::cleanupTestCase()
399{
400#ifdef BUILTIN_TESTDATA
401 QDir::setCurrent(QCoreApplication::applicationDirPath());
402#endif
403}
404
405// ------------------------------------------------------------------------------
406void 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
421void 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// ------------------------------------------------------------------------------
512void tst_QTextStream::readLineFromDevice_data()
513{
514 generateLineData(for_QString: false);
515}
516
517// ------------------------------------------------------------------------------
518void 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// ------------------------------------------------------------------------------
539void 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// ------------------------------------------------------------------------------
566void 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// ------------------------------------------------------------------------------
594void 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
611class ErrorDevice : public QIODevice
612{
613protected:
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
629void 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// ------------------------------------------------------------------------------
669void tst_QTextStream::readLineFromString_data()
670{
671 generateLineData(for_QString: true);
672}
673
674// ------------------------------------------------------------------------------
675void 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// ------------------------------------------------------------------------------
691void 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// ------------------------------------------------------------------------------
706void 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// ------------------------------------------------------------------------------
729void tst_QTextStream::readLineFromTextDevice_data()
730{
731 generateLineData(for_QString: false);
732}
733
734// ------------------------------------------------------------------------------
735void 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// ------------------------------------------------------------------------------
777void 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// ------------------------------------------------------------------------------
840void 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// ------------------------------------------------------------------------------
856void tst_QTextStream::readAllFromDevice_data()
857{
858 generateAllData(for_QString: false);
859}
860
861// ------------------------------------------------------------------------------
862void 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// ------------------------------------------------------------------------------
875void tst_QTextStream::readAllFromString_data()
876{
877 generateAllData(for_QString: true);
878}
879
880// ------------------------------------------------------------------------------
881void 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// ------------------------------------------------------------------------------
893void 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// ------------------------------------------------------------------------------
920void 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// ------------------------------------------------------------------------------
946void 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// ------------------------------------------------------------------------------
966void 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// ------------------------------------------------------------------------------
987struct 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
997void 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// ------------------------------------------------------------------------------
1069void 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// ------------------------------------------------------------------------------
1098void 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// ------------------------------------------------------------------------------
1112void 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// ------------------------------------------------------------------------------
1128void 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// ------------------------------------------------------------------------------
1142void 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// ------------------------------------------------------------------------------
1151void 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// ------------------------------------------------------------------------------
1165void 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// ------------------------------------------------------------------------------
1182void 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// ------------------------------------------------------------------------------
1209void 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// ------------------------------------------------------------------------------
1231void 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// ------------------------------------------------------------------------------
1245void 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// ------------------------------------------------------------------------------
1257void 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// ------------------------------------------------------------------------------
1305void 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// ------------------------------------------------------------------------------
1424void 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// ------------------------------------------------------------------------------
1462void 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// ------------------------------------------------------------------------------
1500void 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// ------------------------------------------------------------------------------
1527void 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// ------------------------------------------------------------------------------
1548void 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// ------------------------------------------------------------------------------
1572void 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// ------------------------------------------------------------------------------
1614void 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// ------------------------------------------------------------------------------
1623void 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// ------------------------------------------------------------------------------
1644void 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// ------------------------------------------------------------------------------
1653void 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
1665Q_DECLARE_METATYPE(QTextStreamFunction);
1666
1667// Also tests that we can have namespaces that conflict with our QTextStream constants.
1668namespace ws {
1669QTextStream &noop(QTextStream &s) { return s; }
1670}
1671
1672void 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
1719void 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// ------------------------------------------------------------------------------
1735void 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// ------------------------------------------------------------------------------
1797void 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
1808void 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
1854void 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// ------------------------------------------------------------------------------
1906void 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// ------------------------------------------------------------------------------
1929void tst_QTextStream::QChar_operators_FromDevice_data()
1930{
1931 generateOperatorCharData(for_QString: false);
1932}
1933
1934// ------------------------------------------------------------------------------
1935void 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// ------------------------------------------------------------------------------
1962void tst_QTextStream::char_operators_FromDevice_data()
1963{
1964 generateOperatorCharData(for_QString: false);
1965}
1966
1967// ------------------------------------------------------------------------------
1968void 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// ------------------------------------------------------------------------------
1995void 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 }
2103IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedShort, signed short)
2104IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedShort, unsigned short)
2105IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedInt, signed int)
2106IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedInt, unsigned int)
2107IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qlonglong, qlonglong)
2108IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qulonglong, qulonglong)
2109 ;
2110
2111// ------------------------------------------------------------------------------
2112void 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 }
2151IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(float, float)
2152IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(double, double)
2153 ;
2154
2155// ------------------------------------------------------------------------------
2156void 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// ------------------------------------------------------------------------------
2180void tst_QTextStream::charPtr_read_operator_FromDevice_data()
2181{
2182 generateStringData(for_QString: false);
2183}
2184
2185// ------------------------------------------------------------------------------
2186void 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// ------------------------------------------------------------------------------
2204void tst_QTextStream::stringRef_read_operator_FromDevice_data()
2205{
2206 generateStringData(for_QString: false);
2207}
2208
2209// ------------------------------------------------------------------------------
2210void 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// ------------------------------------------------------------------------------
2228void tst_QTextStream::byteArray_read_operator_FromDevice_data()
2229{
2230 generateStringData(for_QString: false);
2231}
2232
2233// ------------------------------------------------------------------------------
2234void 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// ------------------------------------------------------------------------------
2290void 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}
2306IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedShort, signed short)
2307 ;
2308
2309// ------------------------------------------------------------------------------
2310void 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}
2326IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedShort, unsigned short)
2327 ;
2328
2329// ------------------------------------------------------------------------------
2330void 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}
2352IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedInt, signed int)
2353 ;
2354
2355// ------------------------------------------------------------------------------
2356void 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}
2378IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedInt, unsigned int)
2379 ;
2380
2381// ------------------------------------------------------------------------------
2382void 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}
2408IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qlonglong, qlonglong)
2409 ;
2410
2411// ------------------------------------------------------------------------------
2412void 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}
2438IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qulonglong, qulonglong)
2439 ;
2440
2441
2442// ------------------------------------------------------------------------------
2443void 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 }
2482IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(float, float)
2483IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(double, float)
2484 ;
2485
2486// ------------------------------------------------------------------------------
2487void 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// ------------------------------------------------------------------------------
2510void 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
2554void 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
2568void 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
2584void 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// ------------------------------------------------------------------------------
2596void 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// ------------------------------------------------------------------------------
2633void 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// ------------------------------------------------------------------------------
2670void 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// ------------------------------------------------------------------------------
2691void 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
2721void 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
2752void 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// ------------------------------------------------------------------------------
2772void 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
2788void 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
2812void 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
2830void 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
2840class FakeBuffer : public QBuffer
2841{
2842protected:
2843 qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(data: c, len: i); }
2844public:
2845 FakeBuffer(bool locked = false) : m_lock(locked) {}
2846 void setLocked(bool locked) { m_lock = locked; }
2847private:
2848 bool m_lock;
2849};
2850
2851void 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
2876void 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
2919void 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
2931void 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
2951void 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
2968void 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
2986void 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
2999void 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
3018void 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
3031void 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
3047void 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
3063void 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
3078QTEST_MAIN(tst_QTextStream)
3079#include "tst_qtextstream.moc"
3080
3081

source code of qtbase/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp