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