1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 
43 /*-*-encoding:latin1-*-*/
44 //#include <iostream>
45 //using namespace std;
46 
47 #include <QtTest/QtTest>
48 
49 #ifdef Q_OS_UNIX
50 #include <locale.h>
51 #endif
52 
53 #include <QBuffer>
54 #include <QByteArray>
55 #include <QCoreApplication>
56 #include <QDebug>
57 #include <QFile>
58 #include <QTcpSocket>
59 #include <QTextStream>
60 #include <QTextCodec>
61 #include <QProcess>
62 
63 #include "../network-settings.h"
64 
65 static const char *TestFileName = "testfile";
66 
67 Q_DECLARE_METATYPE(qlonglong)
68 Q_DECLARE_METATYPE(qulonglong)
69 Q_DECLARE_METATYPE(QList<int>)
70 
71 QT_BEGIN_NAMESPACE
72 template<> struct QMetaTypeId<QIODevice::OpenModeFlag>
qt_metatype_idQMetaTypeId73 { enum { Defined = 1 }; static inline int qt_metatype_id() { return QMetaType::Int; } };
74 QT_END_NAMESPACE
75 
76 //TESTED_CLASS=
77 //TESTED_FILES=
78 
79 #ifdef Q_OS_SYMBIAN
80 #define SRCDIR ""
81 #endif
82 
83 class tst_QTextStream : public QObject
84 {
85     Q_OBJECT
86 
87 public:
88     tst_QTextStream();
89     virtual ~tst_QTextStream();
90 
91 public slots:
92     void initTestCase();
93     void init();
94     void cleanup();
95 
96 private slots:
97     void getSetCheck();
98     void construction();
99 
100     // lines
101     void readLineFromDevice_data();
102     void readLineFromDevice();
103     void readLineFromString_data();
104     void readLineFromString();
105     void readLineFromTextDevice_data();
106     void readLineFromTextDevice();
107     void readLineUntilNull();
108     void readLineMaxlen_data();
109     void readLineMaxlen();
110     void readLinesFromBufferCRCR();
111 
112     // all
113     void readAllFromDevice_data();
114     void readAllFromDevice();
115     void readAllFromString_data();
116     void readAllFromString();
117     void readLineFromStringThenChangeString();
118 
119     // device tests
120     void setDevice();
121 
122     // char operators
123     void QChar_operators_FromDevice_data();
124     void QChar_operators_FromDevice();
125     void char_operators_FromDevice_data();
126     void char_operators_FromDevice();
127 
128     // natural number read operator
129     void signedShort_read_operator_FromDevice_data();
130     void signedShort_read_operator_FromDevice();
131     void unsignedShort_read_operator_FromDevice_data();
132     void unsignedShort_read_operator_FromDevice();
133     void signedInt_read_operator_FromDevice_data();
134     void signedInt_read_operator_FromDevice();
135     void unsignedInt_read_operator_FromDevice_data();
136     void unsignedInt_read_operator_FromDevice();
137     void qlonglong_read_operator_FromDevice_data();
138     void qlonglong_read_operator_FromDevice();
139     void qulonglong_read_operator_FromDevice_data();
140     void qulonglong_read_operator_FromDevice();
141 
142     // natural number write operator
143     void signedShort_write_operator_ToDevice_data();
144     void signedShort_write_operator_ToDevice();
145     void unsignedShort_write_operator_ToDevice_data();
146     void unsignedShort_write_operator_ToDevice();
147     void signedInt_write_operator_ToDevice_data();
148     void signedInt_write_operator_ToDevice();
149     void unsignedInt_write_operator_ToDevice_data();
150     void unsignedInt_write_operator_ToDevice();
151     void qlonglong_write_operator_ToDevice_data();
152     void qlonglong_write_operator_ToDevice();
153     void qulonglong_write_operator_ToDevice_data();
154     void qulonglong_write_operator_ToDevice();
155 
156     void int_read_with_locale_data();
157     void int_read_with_locale();
158 
159     void int_write_with_locale_data();
160     void int_write_with_locale();
161 
162     // real number read operator
163     void float_read_operator_FromDevice_data();
164     void float_read_operator_FromDevice();
165     void double_read_operator_FromDevice_data();
166     void double_read_operator_FromDevice();
167 
168     // real number write operator
169     void float_write_operator_ToDevice_data();
170     void float_write_operator_ToDevice();
171     void double_write_operator_ToDevice_data();
172     void double_write_operator_ToDevice();
173 
174     void double_write_with_flags_data();
175     void double_write_with_flags();
176 
177     void double_write_with_precision_data();
178     void double_write_with_precision();
179 
180     // text read operators
181     void charPtr_read_operator_FromDevice_data();
182     void charPtr_read_operator_FromDevice();
183     void stringRef_read_operator_FromDevice_data();
184     void stringRef_read_operator_FromDevice();
185     void byteArray_read_operator_FromDevice_data();
186     void byteArray_read_operator_FromDevice();
187 
188     // text write operators
189     void string_write_operator_ToDevice_data();
190     void string_write_operator_ToDevice();
191 
192     // other
193     void skipWhiteSpace_data();
194     void skipWhiteSpace();
195     void lineCount_data();
196     void lineCount();
197     void performance();
198     void hexTest_data();
199     void hexTest();
200     void binTest_data();
201     void binTest();
202     void octTest_data();
203     void octTest();
204     void zeroTermination();
205     void ws_manipulator();
206     void stillOpenWhenAtEnd();
207     void readNewlines_data();
208     void readNewlines();
209     void seek();
210     void pos();
211     void pos2();
212     void pos3LargeFile();
213     void readStdin();
214     void readAllFromStdin();
215     void readLineFromStdin();
216     void read();
217     void qbool();
218     void forcePoint();
219     void forceSign();
220     void read0d0d0a();
221     void numeralCase_data();
222     void numeralCase();
223     void nanInf();
224     void utf8IncompleteAtBufferBoundary_data();
225     void utf8IncompleteAtBufferBoundary();
226     void writeSeekWriteNoBOM();
227 
228     // status
229     void status_real_read_data();
230     void status_real_read();
231     void status_integer_read();
232     void status_word_read();
233     void status_write_error();
234 
235     // use case tests
236     void useCase1();
237     void useCase2();
238 
239     // manipulators
240     void manipulators_data();
241     void manipulators();
242 
243     // UTF-16 BOM (Byte Order Mark)
244     void generateBOM();
245     void readBomSeekBackReadBomAgain();
246 
247     // old tests
248 #ifdef QT3_SUPPORT
249     void qt3_operator_shiftleft_data();
250     void qt3_operator_shiftleft();
251     void qt3_operator_shiftright_data();
252     void qt3_operator_shiftright();
253     void qt3_operator_shift_QChar_data();
254     void qt3_operator_shift_QChar();
255     void qt3_operator_shift_char_data();
256     void qt3_operator_shift_char();
257     void qt3_operator_shift_short_data();
258     void qt3_operator_shift_short();
259     void qt3_operator_shift_ushort_data();
260     void qt3_operator_shift_ushort();
261     void qt3_operator_shift_int_data();
262     void qt3_operator_shift_int();
263     void qt3_operator_shift_uint_data();
264     void qt3_operator_shift_uint();
265     void qt3_operator_shift_long_data();
266     void qt3_operator_shift_long();
267     void qt3_operator_shift_ulong_data();
268     void qt3_operator_shift_ulong();
269     void qt3_operator_shift_float_data();
270     void qt3_operator_shift_float();
271     void qt3_operator_shift_double_data();
272     void qt3_operator_shift_double();
273     void qt3_operator_shift_QString_data();
274     void qt3_operator_shift_QString();
275     void qt3_operator_shift_QByteArray_data();
276     void qt3_operator_shift_QByteArray();
277 
278     void qt3_writeDataToFileReadAsLines_data();
279     void qt3_writeDataToFileReadAsLines();
280     void qt3_writeDataToQStringReadAsLines_data();
281     void qt3_writeDataToQStringReadAsLines();
282 
283     void qt3_readLineFromString();
284 #endif
285 
286     // task-specific tests
287     void task180679_alignAccountingStyle();
288     void task178772_setCodec();
289 
290 private:
291     void generateLineData(bool for_QString);
292     void generateAllData(bool for_QString);
293     void generateOperatorCharData(bool for_QString);
294     void generateNaturalNumbersData(bool for_QString);
295     void generateRealNumbersData(bool for_QString);
296     void generateStringData(bool for_QString);
297     void generateRealNumbersDataWrite();
298 
299     // Qt 3 privates
300 #ifdef QT3_SUPPORT
301     void qt3_createWriteStream( QTextStream *&os );
302     void qt3_closeWriteStream( QTextStream *os );
303     void qt3_createReadStream( QTextStream *&is );
304     void qt3_closeReadStream( QTextStream *is );
305     void qt3_read_QChar( QTextStream *s );
306     void qt3_write_QChar( QTextStream *s );
307     void qt3_read_char( QTextStream *s );
308     void qt3_write_char( QTextStream *s );
309     void qt3_read_short( QTextStream *s );
310     void qt3_write_short( QTextStream *s );
311     void qt3_read_ushort( QTextStream *s );
312     void qt3_write_ushort( QTextStream *s );
313     void qt3_read_int( QTextStream *s );
314     void qt3_write_int( QTextStream *s );
315     void qt3_read_uint( QTextStream *s );
316     void qt3_write_uint( QTextStream *s );
317     void qt3_read_long( QTextStream *s );
318     void qt3_write_long( QTextStream *s );
319     void qt3_read_ulong( QTextStream *s );
320     void qt3_write_ulong( QTextStream *s );
321     void qt3_read_float( QTextStream *s );
322     void qt3_write_float( QTextStream *s );
323     void qt3_read_double( QTextStream *s );
324     void qt3_write_double( QTextStream *s );
325     void qt3_read_QString( QTextStream *s );
326     void qt3_write_QString( QTextStream *s );
327     void qt3_read_QByteArray( QTextStream *s );
328     void qt3_write_QByteArray( QTextStream *s );
329     void qt3_operatorShift_data( QIODevice::OpenMode );
330     void qt3_do_shiftleft( QTextStream *ts );
331     QTextStream::Encoding qt3_toEncoding( const QString& );
332     QString qt3_decodeString( QByteArray array, const QString& encoding );
333 #endif
334 
335     // Qt 3 data
336     QTextStream *os;
337     QTextStream *is;
338     QTextStream *ts;
339     QFile *inFile;
340     QFile *inResource;
341     QFile *outFile;
342     QByteArray *inArray;
343     QBuffer *inBuffer;
344     QString *inString;
345     bool file_is_empty;
346     QString m_readAllStdinProcess;
347     QString m_stdinProcess;
348     QString m_readLineStdinProcess;
349 };
350 
351 // Testing get/set functions
getSetCheck()352 void tst_QTextStream::getSetCheck()
353 {
354     // Initialize codecs
355     int argc = 0;
356     char **argv = 0;
357     QCoreApplication app(argc, argv);
358 
359     QTextStream obj1;
360     // QTextCodec * QTextStream::codec()
361     // void QTextStream::setCodec(QTextCodec *)
362     QTextCodec *var1 = QTextCodec::codecForName("en");
363     obj1.setCodec(var1);
364     QCOMPARE(var1, obj1.codec());
365     obj1.setCodec((QTextCodec *)0);
366     QCOMPARE((QTextCodec *)0, obj1.codec());
367 
368     // bool QTextStream::autoDetectUnicode()
369     // void QTextStream::setAutoDetectUnicode(bool)
370     obj1.setAutoDetectUnicode(false);
371     QCOMPARE(false, obj1.autoDetectUnicode());
372     obj1.setAutoDetectUnicode(true);
373     QCOMPARE(true, obj1.autoDetectUnicode());
374 
375     // bool QTextStream::generateByteOrderMark()
376     // void QTextStream::setGenerateByteOrderMark(bool)
377     obj1.setGenerateByteOrderMark(false);
378     QCOMPARE(false, obj1.generateByteOrderMark());
379     obj1.setGenerateByteOrderMark(true);
380     QCOMPARE(true, obj1.generateByteOrderMark());
381 
382     // QIODevice * QTextStream::device()
383     // void QTextStream::setDevice(QIODevice *)
384     QFile *var4 = new QFile;
385     obj1.setDevice(var4);
386     QCOMPARE(static_cast<QIODevice *>(var4), obj1.device());
387     obj1.setDevice((QIODevice *)0);
388     QCOMPARE((QIODevice *)0, obj1.device());
389     delete var4;
390 
391     // Status QTextStream::status()
392     // void QTextStream::setStatus(Status)
393     obj1.setStatus(QTextStream::Status(QTextStream::Ok));
394     QCOMPARE(QTextStream::Status(QTextStream::Ok), obj1.status());
395     obj1.setStatus(QTextStream::Status(QTextStream::ReadPastEnd));
396     QCOMPARE(QTextStream::Status(QTextStream::ReadPastEnd), obj1.status());
397     obj1.resetStatus();
398     obj1.setStatus(QTextStream::Status(QTextStream::ReadCorruptData));
399     QCOMPARE(QTextStream::Status(QTextStream::ReadCorruptData), obj1.status());
400 
401     // FieldAlignment QTextStream::fieldAlignment()
402     // void QTextStream::setFieldAlignment(FieldAlignment)
403     obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignLeft));
404     QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignLeft), obj1.fieldAlignment());
405     obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignRight));
406     QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignRight), obj1.fieldAlignment());
407     obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignCenter));
408     QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignCenter), obj1.fieldAlignment());
409     obj1.setFieldAlignment(QTextStream::FieldAlignment(QTextStream::AlignAccountingStyle));
410     QCOMPARE(QTextStream::FieldAlignment(QTextStream::AlignAccountingStyle), obj1.fieldAlignment());
411 
412     // QChar QTextStream::padChar()
413     // void QTextStream::setPadChar(QChar)
414     QChar var7 = 'Q';
415     obj1.setPadChar(var7);
416     QCOMPARE(var7, obj1.padChar());
417     obj1.setPadChar(QChar());
418     QCOMPARE(QChar(), obj1.padChar());
419 
420     // int QTextStream::fieldWidth()
421     // void QTextStream::setFieldWidth(int)
422     obj1.setFieldWidth(0);
423     QCOMPARE(0, obj1.fieldWidth());
424     obj1.setFieldWidth(INT_MIN);
425     QCOMPARE(INT_MIN, obj1.fieldWidth());
426     obj1.setFieldWidth(INT_MAX);
427     QCOMPARE(INT_MAX, obj1.fieldWidth());
428 
429     // NumberFlags QTextStream::numberFlags()
430     // void QTextStream::setNumberFlags(NumberFlags)
431     obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ShowBase));
432     QCOMPARE(QTextStream::NumberFlags(QTextStream::ShowBase), obj1.numberFlags());
433     obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ForcePoint));
434     QCOMPARE(QTextStream::NumberFlags(QTextStream::ForcePoint), obj1.numberFlags());
435     obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::ForceSign));
436     QCOMPARE(QTextStream::NumberFlags(QTextStream::ForceSign), obj1.numberFlags());
437     obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::UppercaseBase));
438     QCOMPARE(QTextStream::NumberFlags(QTextStream::UppercaseBase), obj1.numberFlags());
439     obj1.setNumberFlags(QTextStream::NumberFlags(QTextStream::UppercaseDigits));
440     QCOMPARE(QTextStream::NumberFlags(QTextStream::UppercaseDigits), obj1.numberFlags());
441 
442     // int QTextStream::integerBase()
443     // void QTextStream::setIntegerBase(int)
444     obj1.setIntegerBase(0);
445     QCOMPARE(0, obj1.integerBase());
446     obj1.setIntegerBase(INT_MIN);
447     QCOMPARE(INT_MIN, obj1.integerBase());
448     obj1.setIntegerBase(INT_MAX);
449     QCOMPARE(INT_MAX, obj1.integerBase());
450 
451     // RealNumberNotation QTextStream::realNumberNotation()
452     // void QTextStream::setRealNumberNotation(RealNumberNotation)
453     obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::SmartNotation));
454     QCOMPARE(QTextStream::RealNumberNotation(QTextStream::SmartNotation), obj1.realNumberNotation());
455     obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::FixedNotation));
456     QCOMPARE(QTextStream::RealNumberNotation(QTextStream::FixedNotation), obj1.realNumberNotation());
457     obj1.setRealNumberNotation(QTextStream::RealNumberNotation(QTextStream::ScientificNotation));
458     QCOMPARE(QTextStream::RealNumberNotation(QTextStream::ScientificNotation), obj1.realNumberNotation());
459 
460     // int QTextStream::realNumberPrecision()
461     // void QTextStream::setRealNumberPrecision(int)
462     obj1.setRealNumberPrecision(0);
463     QCOMPARE(0, obj1.realNumberPrecision());
464     obj1.setRealNumberPrecision(INT_MIN);
465     QCOMPARE(6, obj1.realNumberPrecision()); // Setting a negative precision reverts it to the default value (6).
466     obj1.setRealNumberPrecision(INT_MAX);
467     QCOMPARE(INT_MAX, obj1.realNumberPrecision());
468 }
469 
tst_QTextStream()470 tst_QTextStream::tst_QTextStream()
471 {
472     // Initialize Qt 3 data
473     ts = 0;
474     os = 0;
475     is = 0;
476     outFile = 0;
477     inFile = 0;
478     inResource = 0;
479     inArray = 0;
480     inBuffer = 0;
481     inString = 0;
482     file_is_empty = FALSE;
483 
484     Q_SET_DEFAULT_IAP
485 }
486 
~tst_QTextStream()487 tst_QTextStream::~tst_QTextStream()
488 {
489 }
490 
initTestCase()491 void tst_QTextStream::initTestCase()
492 {
493     QDir workingDirectory = QDir::current();
494     QString readAllStdinProcess = QLatin1String("readAllStdinProcess/readAllStdinProcess");
495     QString stdinProcess = QLatin1String("stdinProcess/stdinProcess");
496     QString readLineStdinProcess = QLatin1String("readLineStdinProcess/readLineStdinProcess");
497     // Windows: cd up to be able to locate the binary of the sub-process.
498 #ifdef Q_OS_WIN
499     const QString suffix = QLatin1String(".exe");
500     readAllStdinProcess.append(suffix);
501     stdinProcess.append(suffix);
502     readLineStdinProcess.append(suffix);
503     if (workingDirectory.absolutePath().endsWith(QLatin1String("/debug"), Qt::CaseInsensitive)
504         || workingDirectory.absolutePath().endsWith(QLatin1String("/release"), Qt::CaseInsensitive)) {
505         QVERIFY(workingDirectory.cdUp());
506         QVERIFY(QDir::setCurrent(workingDirectory.absolutePath()));
507     }
508 #endif
509     m_readAllStdinProcess = workingDirectory.absoluteFilePath(readAllStdinProcess);
510     m_readLineStdinProcess = workingDirectory.absoluteFilePath(readLineStdinProcess);
511     m_stdinProcess = workingDirectory.absoluteFilePath(stdinProcess);
512     QVERIFY2(QFileInfo(m_readAllStdinProcess).exists(),
513              qPrintable(QString::fromLatin1("ReadAllStdinProcess executable '%1' does not exist!")
514                         .arg(QDir::toNativeSeparators(m_readAllStdinProcess))));
515     QVERIFY2(QFileInfo(m_readLineStdinProcess).exists(),
516              qPrintable(QString::fromLatin1("ReadLineStdinProcess executable '%1' does not exist!")
517                         .arg(QDir::toNativeSeparators(m_readLineStdinProcess))));
518     QVERIFY2(QFileInfo(m_stdinProcess).exists(),
519              qPrintable(QString::fromLatin1("StdinProcess executable '%1' does not exist!")
520                         .arg(QDir::toNativeSeparators(m_stdinProcess))));
521 }
522 
init()523 void tst_QTextStream::init()
524 {
525     // Initialize Qt 3 data
526     ts = 0;
527     os = 0;
528     is = 0;
529     inFile = 0;
530     inResource = 0;
531     outFile = 0;
532     inArray = 0;
533     inBuffer = 0;
534     inString = 0;
535     file_is_empty = FALSE;
536 }
537 
cleanup()538 void tst_QTextStream::cleanup()
539 {
540     // Clean up Qt 3 data
541     delete ts;
542     ts = 0;
543     delete os;
544     os = 0;
545     delete is;
546     is = 0;
547     delete inResource;
548     inResource = 0;
549     delete inFile;
550     inFile = 0;
551     delete outFile;
552     outFile = 0;
553     delete inArray;
554     inArray = 0;
555     delete inBuffer;
556     inBuffer = 0;
557     delete inString;
558     inString = 0;
559 
560     QCoreApplication::instance()->processEvents();
561 }
562 
563 // ------------------------------------------------------------------------------
construction()564 void tst_QTextStream::construction()
565 {
566     QTextStream stream;
567     QCOMPARE(stream.codec(), QTextCodec::codecForLocale());
568     QCOMPARE(stream.device(), static_cast<QIODevice *>(0));
569     QCOMPARE(stream.string(), static_cast<QString *>(0));
570 
571     QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
572     QVERIFY(stream.atEnd());
573 
574     QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
575     QCOMPARE(stream.readAll(), QString());
576 
577 }
578 
generateLineData(bool for_QString)579 void tst_QTextStream::generateLineData(bool for_QString)
580 {
581     QTest::addColumn<QByteArray>("data");
582     QTest::addColumn<QStringList>("lines");
583 
584     // latin-1
585     QTest::newRow("emptyer") << QByteArray() << QStringList();
586     QTest::newRow("lf") << QByteArray("\n") << (QStringList() << "");
587     QTest::newRow("crlf") << QByteArray("\r\n") << (QStringList() << "");
588     QTest::newRow("oneline/nothing") << QByteArray("ole") << (QStringList() << "ole");
589     QTest::newRow("oneline/lf") << QByteArray("ole\n") << (QStringList() << "ole");
590     QTest::newRow("oneline/crlf") << QByteArray("ole\r\n") << (QStringList() << "ole");
591     QTest::newRow("twolines/lf/lf") << QByteArray("ole\ndole\n") << (QStringList() << "ole" << "dole");
592     QTest::newRow("twolines/crlf/crlf") << QByteArray("ole\r\ndole\r\n") << (QStringList() << "ole" << "dole");
593     QTest::newRow("twolines/lf/crlf") << QByteArray("ole\ndole\r\n") << (QStringList() << "ole" << "dole");
594     QTest::newRow("twolines/lf/nothing") << QByteArray("ole\ndole") << (QStringList() << "ole" << "dole");
595     QTest::newRow("twolines/crlf/nothing") << QByteArray("ole\r\ndole") << (QStringList() << "ole" << "dole");
596     QTest::newRow("threelines/lf/lf/lf") << QByteArray("ole\ndole\ndoffen\n") << (QStringList() << "ole" << "dole" << "doffen");
597     QTest::newRow("threelines/crlf/crlf/crlf") << QByteArray("ole\r\ndole\r\ndoffen\r\n") << (QStringList() << "ole" << "dole" << "doffen");
598     QTest::newRow("threelines/crlf/crlf/nothing") << QByteArray("ole\r\ndole\r\ndoffen") << (QStringList() << "ole" << "dole" << "doffen");
599 
600     if (!for_QString) {
601         // utf-8
602         QTest::newRow("utf8/twolines")
603             << QByteArray("\xef\xbb\xbf"
604                           "\x66\x67\x65\x0a"
605                           "\x66\x67\x65\x0a", 11)
606             << (QStringList() << "fge" << "fge");
607 
608         // utf-16
609         // one line
610         QTest::newRow("utf16-BE/nothing")
611             << QByteArray("\xfe\xff"
612                           "\x00\xe5\x00\x67\x00\x65", 8) << (QStringList() << "\345ge");
613         QTest::newRow("utf16-LE/nothing")
614             << QByteArray("\xff\xfe"
615                           "\xe5\x00\x67\x00\x65\x00", 8) << (QStringList() << "\345ge");
616         QTest::newRow("utf16-BE/lf")
617             << QByteArray("\xfe\xff"
618                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 10) << (QStringList() << "\345ge");
619         QTest::newRow("utf16-LE/lf")
620             << QByteArray("\xff\xfe"
621                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 10) << (QStringList() << "\345ge");
622 
623         // two lines
624         QTest::newRow("utf16-BE/twolines")
625             << QByteArray("\xfe\xff"
626                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
627                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 18)
628             << (QStringList() << "\345ge" << "\345ge");
629         QTest::newRow("utf16-LE/twolines")
630             << QByteArray("\xff\xfe"
631                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
632                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 18)
633             << (QStringList() << "\345ge" << "\345ge");
634 
635         // three lines
636         QTest::newRow("utf16-BE/threelines")
637             << QByteArray("\xfe\xff"
638                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
639                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
640                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 26)
641             << (QStringList() << "\345ge" << "\345ge" << "\345ge");
642         QTest::newRow("utf16-LE/threelines")
643             << QByteArray("\xff\xfe"
644                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
645                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
646                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 26)
647             << (QStringList() << "\345ge" << "\345ge" << "\345ge");
648 
649         // utf-32
650         QTest::newRow("utf32-BE/twolines")
651             << QByteArray("\x00\x00\xfe\xff"
652                           "\x00\x00\x00\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a"
653                           "\x00\x00\x00\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a", 36)
654             << (QStringList() << "\345ge" << "\345ge");
655         QTest::newRow("utf32-LE/twolines")
656             << QByteArray("\xff\xfe\x00\x00"
657                           "\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a\x00\x00\x00"
658                           "\xe5\x00\x00\x00\x67\x00\x00\x00\x65\x00\x00\x00\x0a\x00\x00\x00", 36)
659             << (QStringList() << "\345ge" << "\345ge");
660     }
661 
662     // partials
663     QTest::newRow("cr") << QByteArray("\r") << (QStringList() << "");
664     QTest::newRow("oneline/cr") << QByteArray("ole\r") << (QStringList() << "ole");
665     if (!for_QString)
666         QTest::newRow("utf16-BE/cr") << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65\x00\x0d", 10) << (QStringList() << "\345ge");
667 }
668 
669 // ------------------------------------------------------------------------------
readLineFromDevice_data()670 void tst_QTextStream::readLineFromDevice_data()
671 {
672     generateLineData(false);
673 }
674 
675 // ------------------------------------------------------------------------------
readLineFromDevice()676 void tst_QTextStream::readLineFromDevice()
677 {
678     QFETCH(QByteArray, data);
679     QFETCH(QStringList, lines);
680 
681     QFile::remove(TestFileName);
682     QFile file(TestFileName);
683     QVERIFY(file.open(QFile::ReadWrite));
684     QCOMPARE(file.write(data), qlonglong(data.size()));
685     QVERIFY(file.flush());
686     file.seek(0);
687 
688     QTextStream stream(&file);
689     QStringList list;
690     while (!stream.atEnd())
691         list << stream.readLine();
692 
693     QCOMPARE(list, lines);
694 }
695 
696 // ------------------------------------------------------------------------------
readLineMaxlen_data()697 void tst_QTextStream::readLineMaxlen_data()
698 {
699     QTest::addColumn<QString>("input");
700     QTest::addColumn<QStringList>("lines");
701 
702     QTest::newRow("Hey")
703         << QString("Hey")
704         << (QStringList() << QString("Hey") << QString(""));
705     QTest::newRow("Hey\\n")
706         << QString("Hey\n")
707         << (QStringList() << QString("Hey") << QString(""));
708     QTest::newRow("HelloWorld")
709         << QString("HelloWorld")
710         << (QStringList() << QString("Hello") << QString("World"));
711     QTest::newRow("Helo\\nWorlds")
712         << QString("Helo\nWorlds")
713         << (QStringList() << QString("Helo") << QString("World"));
714     QTest::newRow("AAAAA etc.")
715         << QString(16385, QLatin1Char('A'))
716         << (QStringList() << QString("AAAAA") << QString("AAAAA"));
717     QTest::newRow("multibyte string")
718         << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242\341\233\232\341\232\240\n")
719         << (QStringList() << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242")
720             << QString::fromUtf8("\341\233\232\341\232\240"));
721 }
722 
723 // ------------------------------------------------------------------------------
readLineMaxlen()724 void tst_QTextStream::readLineMaxlen()
725 {
726     QFETCH(QString, input);
727     QFETCH(QStringList, lines);
728     for (int i = 0; i < 2; ++i) {
729         bool useDevice = (i == 1);
730         QTextStream stream;
731         QFile::remove("testfile");
732         QFile file("testfile");
733         if (useDevice) {
734             file.open(QIODevice::ReadWrite);
735             file.write(input.toUtf8());
736             file.seek(0);
737             stream.setDevice(&file);
738             stream.setCodec("utf-8");
739         } else {
740             stream.setString(&input);
741         }
742 
743         QStringList list;
744         list << stream.readLine(5);
745         list << stream.readLine(5);
746 
747         QCOMPARE(list, lines);
748     }
749 }
750 
751 // ------------------------------------------------------------------------------
readLinesFromBufferCRCR()752 void tst_QTextStream::readLinesFromBufferCRCR()
753 {
754     QBuffer buffer;
755     buffer.open(QIODevice::WriteOnly);
756     QByteArray data("0123456789\r\r\n");
757 
758     for (int i = 0; i < 10000; ++i)
759         buffer.write(data);
760 
761     buffer.close();
762     if (buffer.open(QIODevice::ReadOnly|QIODevice::Text)) {
763         QTextStream stream(&buffer);
764         while (!stream.atEnd())
765             QCOMPARE(stream.readLine(), QString("0123456789"));
766     }
767 }
768 
769 // ------------------------------------------------------------------------------
readLineFromString_data()770 void tst_QTextStream::readLineFromString_data()
771 {
772     generateLineData(true);
773 }
774 
775 // ------------------------------------------------------------------------------
readLineFromString()776 void tst_QTextStream::readLineFromString()
777 {
778     QFETCH(QByteArray, data);
779     QFETCH(QStringList, lines);
780 
781     QString dataString = data;
782 
783     QTextStream stream(&dataString, QIODevice::ReadOnly);
784     QStringList list;
785     while (!stream.atEnd())
786         list << stream.readLine();
787 
788     QCOMPARE(list, lines);
789 }
790 
791 // ------------------------------------------------------------------------------
readLineFromStringThenChangeString()792 void tst_QTextStream::readLineFromStringThenChangeString()
793 {
794     QString first = "First string";
795     QString second = "Second string";
796 
797     QTextStream stream(&first, QIODevice::ReadOnly);
798     QString result = stream.readLine();
799     QCOMPARE(first, result);
800 
801     stream.setString(&second, QIODevice::ReadOnly);
802     result = stream.readLine();
803     QCOMPARE(second, result);
804 }
805 
806 // ------------------------------------------------------------------------------
setDevice()807 void tst_QTextStream::setDevice()
808 {
809     // Check that the read buffer is reset after setting a new device
810     QByteArray data1("Hello World");
811     QByteArray data2("How are you");
812 
813     QBuffer bufferOld(&data1);
814     bufferOld.open(QIODevice::ReadOnly);
815 
816     QBuffer bufferNew(&data2);
817     bufferNew.open(QIODevice::ReadOnly);
818 
819     QString text;
820     QTextStream stream(&bufferOld);
821     stream >> text;
822     QCOMPARE(text, QString("Hello"));
823 
824     stream.setDevice(&bufferNew);
825     stream >> text;
826     QCOMPARE(text, QString("How"));
827 }
828 
829 // ------------------------------------------------------------------------------
readLineFromTextDevice_data()830 void tst_QTextStream::readLineFromTextDevice_data()
831 {
832     generateLineData(false);
833 }
834 
835 // ------------------------------------------------------------------------------
readLineFromTextDevice()836 void tst_QTextStream::readLineFromTextDevice()
837 {
838     QFETCH(QByteArray, data);
839     QFETCH(QStringList, lines);
840 
841     for (int i = 0; i < 8; ++i) {
842         QBuffer buffer(&data);
843         if (i < 4)
844             QVERIFY(buffer.open(QIODevice::ReadOnly | QIODevice::Text));
845         else
846             QVERIFY(buffer.open(QIODevice::ReadOnly));
847 
848         QTextStream stream(&buffer);
849         QStringList list;
850         while (!stream.atEnd()) {
851             stream.pos(); // <- triggers side effects
852             QString line;
853 
854             if (i & 1) {
855                 QChar c;
856                 while (!stream.atEnd()) {
857                     stream >> c;
858                     if (stream.status() == QTextStream::Ok) {
859                         if (c != QLatin1Char('\n') && c != QLatin1Char('\r'))
860                             line += c;
861                         if (c == QLatin1Char('\n'))
862                             break;
863                     }
864                 }
865             } else {
866                 line = stream.readLine();
867             }
868 
869             if ((i & 3) == 3 && !QString(QTest::currentDataTag()).contains("utf16"))
870                 stream.seek(stream.pos());
871             list << line;
872         }
873         QCOMPARE(list, lines);
874     }
875 }
876 
877 // ------------------------------------------------------------------------------
generateAllData(bool for_QString)878 void tst_QTextStream::generateAllData(bool for_QString)
879 {
880     QTest::addColumn<QByteArray>("input");
881     QTest::addColumn<QString>("output");
882 
883     // latin-1
884     QTest::newRow("empty") << QByteArray() << QString();
885     QTest::newRow("latin1-a") << QByteArray("a") << QString("a");
886     QTest::newRow("latin1-a\\r") << QByteArray("a\r") << QString("a\r");
887     QTest::newRow("latin1-a\\r\\n") << QByteArray("a\r\n") << QString("a\r\n");
888     QTest::newRow("latin1-a\\n") << QByteArray("a\n") << QString("a\n");
889 
890     // utf-16
891     if (!for_QString) {
892         // one line
893         QTest::newRow("utf16-BE/nothing")
894             << QByteArray("\xfe\xff"
895                           "\x00\xe5\x00\x67\x00\x65", 8) << QString("\345ge");
896         QTest::newRow("utf16-LE/nothing")
897             << QByteArray("\xff\xfe"
898                           "\xe5\x00\x67\x00\x65\x00", 8) << QString("\345ge");
899         QTest::newRow("utf16-BE/lf")
900             << QByteArray("\xfe\xff"
901                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 10) << QString("\345ge\n");
902         QTest::newRow("utf16-LE/lf")
903             << QByteArray("\xff\xfe"
904                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 10) << QString("\345ge\n");
905         QTest::newRow("utf16-BE/crlf")
906             << QByteArray("\xfe\xff"
907                           "\x00\xe5\x00\x67\x00\x65\x00\x0d\x00\x0a", 12) << QString("\345ge\r\n");
908         QTest::newRow("utf16-LE/crlf")
909             << QByteArray("\xff\xfe"
910                           "\xe5\x00\x67\x00\x65\x00\x0d\x00\x0a\x00", 12) << QString("\345ge\r\n");
911 
912         // two lines
913         QTest::newRow("utf16-BE/twolines")
914             << QByteArray("\xfe\xff"
915                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
916                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 18)
917             << QString("\345ge\n\345ge\n");
918         QTest::newRow("utf16-LE/twolines")
919             << QByteArray("\xff\xfe"
920                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
921                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 18)
922             << QString("\345ge\n\345ge\n");
923 
924         // three lines
925         QTest::newRow("utf16-BE/threelines")
926             << QByteArray("\xfe\xff"
927                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
928                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
929                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 26)
930             << QString("\345ge\n\345ge\n\345ge\n");
931         QTest::newRow("utf16-LE/threelines")
932             << QByteArray("\xff\xfe"
933                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
934                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
935                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 26)
936             << QString("\345ge\n\345ge\n\345ge\n");
937     }
938 }
939 
940 // ------------------------------------------------------------------------------
readLineUntilNull()941 void tst_QTextStream::readLineUntilNull()
942 {
943     QFile file(SRCDIR "rfc3261.txt");
944     QVERIFY(file.open(QFile::ReadOnly));
945 
946     QTextStream stream(&file);
947     for (int i = 0; i < 15066; ++i) {
948         QString line = stream.readLine();
949         QVERIFY(!line.isNull());
950         QVERIFY(!line.isNull());
951     }
952     QVERIFY(!stream.readLine().isNull());
953     QVERIFY(stream.readLine().isNull());
954 }
955 
956 // ------------------------------------------------------------------------------
readAllFromDevice_data()957 void tst_QTextStream::readAllFromDevice_data()
958 {
959     generateAllData(false);
960 }
961 
962 // ------------------------------------------------------------------------------
readAllFromDevice()963 void tst_QTextStream::readAllFromDevice()
964 {
965     QFETCH(QByteArray, input);
966     QFETCH(QString, output);
967 
968     QBuffer buffer(&input);
969     buffer.open(QBuffer::ReadOnly);
970 
971     QTextStream stream(&buffer);
972     QCOMPARE(stream.readAll(), output);
973 }
974 
975 // ------------------------------------------------------------------------------
readAllFromString_data()976 void tst_QTextStream::readAllFromString_data()
977 {
978     generateAllData(true);
979 }
980 
981 // ------------------------------------------------------------------------------
readAllFromString()982 void tst_QTextStream::readAllFromString()
983 {
984     QFETCH(QByteArray, input);
985     QFETCH(QString, output);
986 
987     QString str = input;
988 
989     QTextStream stream(&str);
990     QCOMPARE(stream.readAll(), output);
991 }
992 
993 // ------------------------------------------------------------------------------
skipWhiteSpace_data()994 void tst_QTextStream::skipWhiteSpace_data()
995 {
996     QTest::addColumn<QByteArray>("input");
997     QTest::addColumn<QChar>("output");
998 
999     // latin1
1000     QTest::newRow("empty") << QByteArray() << QChar('\0');
1001     QTest::newRow(" one") << QByteArray(" one") << QChar('o');
1002     QTest::newRow("\\none") << QByteArray("\none") << QChar('o');
1003     QTest::newRow("\\n one") << QByteArray("\n one") << QChar('o');
1004     QTest::newRow(" \\r\\n one") << QByteArray(" \r\n one") << QChar('o');
1005 
1006     // utf-16
1007     QTest::newRow("utf16-BE (empty)") << QByteArray("\xfe\xff", 2) << QChar('\0');
1008     QTest::newRow("utf16-BE ( one)") << QByteArray("\xfe\xff\x00 \x00o\x00n\x00e", 10) << QChar('o');
1009     QTest::newRow("utf16-BE (\\none)") << QByteArray("\xfe\xff\x00\n\x00o\x00n\x00e", 10) << QChar('o');
1010     QTest::newRow("utf16-BE (\\n one)") << QByteArray("\xfe\xff\x00\n\x00 \x00o\x00n\x00e", 12) << QChar('o');
1011     QTest::newRow("utf16-BE ( \\r\\n one)") << QByteArray("\xfe\xff\x00 \x00\r\x00\n\x00 \x00o\x00n\x00e", 20) << QChar('o');
1012 
1013     QTest::newRow("utf16-LE (empty)") << QByteArray("\xff\xfe", 2) << QChar('\0');
1014     QTest::newRow("utf16-LE ( one)") << QByteArray("\xff\xfe \x00o\x00n\x00e\x00", 10) << QChar('o');
1015     QTest::newRow("utf16-LE (\\none)") << QByteArray("\xff\xfe\n\x00o\x00n\x00e\x00", 10) << QChar('o');
1016     QTest::newRow("utf16-LE (\\n one)") << QByteArray("\xff\xfe\n\x00 \x00o\x00n\x00e\x00", 12) << QChar('o');
1017     QTest::newRow("utf16-LE ( \\r\\n one)") << QByteArray("\xff\xfe \x00\r\x00\n\x00 \x00o\x00n\x00e\x00", 20) << QChar('o');
1018 }
1019 
1020 // ------------------------------------------------------------------------------
skipWhiteSpace()1021 void tst_QTextStream::skipWhiteSpace()
1022 {
1023     QFETCH(QByteArray, input);
1024     QFETCH(QChar, output);
1025 
1026     QBuffer buffer(&input);
1027     buffer.open(QBuffer::ReadOnly);
1028 
1029     QTextStream stream(&buffer);
1030     stream.skipWhiteSpace();
1031 
1032     QChar tmp;
1033     stream >> tmp;
1034 
1035     QCOMPARE(tmp, output);
1036 
1037     QString str = input;
1038     QTextStream stream2(&input);
1039     stream2.skipWhiteSpace();
1040 
1041     stream2 >> tmp;
1042 
1043     QCOMPARE(tmp, output);
1044 }
1045 
1046 // ------------------------------------------------------------------------------
lineCount_data()1047 void tst_QTextStream::lineCount_data()
1048 {
1049     QTest::addColumn<QByteArray>("data");
1050     QTest::addColumn<int>("lineCount");
1051 
1052     QTest::newRow("empty") << QByteArray() << 0;
1053     QTest::newRow("oneline") << QByteArray("a\n") << 1;
1054     QTest::newRow("twolines") << QByteArray("a\nb\n") << 2;
1055     QTest::newRow("oneemptyline") << QByteArray("\n") << 1;
1056     QTest::newRow("twoemptylines") << QByteArray("\n\n") << 2;
1057     QTest::newRow("buffersize-1 line") << QByteArray(16382, '\n') << 16382;
1058     QTest::newRow("buffersize line") << QByteArray(16383, '\n') << 16383;
1059     QTest::newRow("buffersize+1 line") << QByteArray(16384, '\n') << 16384;
1060     QTest::newRow("buffersize+2 line") << QByteArray(16385, '\n') << 16385;
1061 
1062     QFile file(SRCDIR "rfc3261.txt"); file.open(QFile::ReadOnly);
1063     QTest::newRow("rfc3261") << file.readAll() << 15067;
1064 }
1065 
1066 // ------------------------------------------------------------------------------
lineCount()1067 void tst_QTextStream::lineCount()
1068 {
1069     QFETCH(QByteArray, data);
1070     QFETCH(int, lineCount);
1071 
1072     QFile out("out.txt");
1073     out.open(QFile::WriteOnly);
1074 
1075     QTextStream lineReader(data);
1076     int lines = 0;
1077     while (!lineReader.atEnd()) {
1078         QString line = lineReader.readLine();
1079         out.write(line.toLatin1() + "\n");
1080         ++lines;
1081     }
1082 
1083     out.close();
1084     QCOMPARE(lines, lineCount);
1085 }
1086 
1087 // ------------------------------------------------------------------------------
performance()1088 void tst_QTextStream::performance()
1089 {
1090     // Phase #1 - test speed of reading a huge text file with QFile.
1091     QTime stopWatch;
1092 
1093     int elapsed1 = 0;
1094     int elapsed2 = 0;
1095 
1096         stopWatch.restart();
1097         int nlines1 = 0;
1098         QFile file(SRCDIR "rfc3261.txt");
1099         QVERIFY(file.open(QFile::ReadOnly));
1100 
1101         while (!file.atEnd()) {
1102             ++nlines1;
1103             file.readLine();
1104         }
1105 
1106         elapsed1 += stopWatch.elapsed();
1107         stopWatch.restart();
1108 
1109         int nlines2 = 0;
1110         QFile file2(SRCDIR "rfc3261.txt");
1111         QVERIFY(file2.open(QFile::ReadOnly));
1112 
1113         QTextStream stream(&file2);
1114         while (!stream.atEnd()) {
1115             ++nlines2;
1116             stream.readLine();
1117         }
1118 
1119         elapsed2 += stopWatch.elapsed();
1120         QCOMPARE(nlines1, nlines2);
1121 
1122     qDebug("QFile used %.2f seconds to read the file",
1123            elapsed1 / 1000.0);
1124 
1125     qDebug("QTextStream used %.2f seconds to read the file",
1126            elapsed2 / 1000.0);
1127     if (elapsed2 > elapsed1) {
1128         qDebug("QFile is %.2fx faster than QTextStream",
1129                double(elapsed2) / double(elapsed1));
1130     } else {
1131         qDebug("QTextStream is %.2fx faster than QFile",
1132                double(elapsed1) / double(elapsed2));
1133     }
1134 }
1135 
1136 // ------------------------------------------------------------------------------
hexTest_data()1137 void tst_QTextStream::hexTest_data()
1138 {
1139     QTest::addColumn<qlonglong>("number");
1140     QTest::addColumn<QByteArray>("data");
1141 
1142     QTest::newRow("0") << Q_INT64_C(0) << QByteArray("0x0");
1143     QTest::newRow("1") << Q_INT64_C(1) << QByteArray("0x1");
1144     QTest::newRow("2") << Q_INT64_C(2) << QByteArray("0x2");
1145     QTest::newRow("3") << Q_INT64_C(3) << QByteArray("0x3");
1146     QTest::newRow("4") << Q_INT64_C(4) << QByteArray("0x4");
1147     QTest::newRow("5") << Q_INT64_C(5) << QByteArray("0x5");
1148     QTest::newRow("6") << Q_INT64_C(6) << QByteArray("0x6");
1149     QTest::newRow("7") << Q_INT64_C(7) << QByteArray("0x7");
1150     QTest::newRow("8") << Q_INT64_C(8) << QByteArray("0x8");
1151     QTest::newRow("9") << Q_INT64_C(9) << QByteArray("0x9");
1152     QTest::newRow("a") << Q_INT64_C(0xa) << QByteArray("0xa");
1153     QTest::newRow("b") << Q_INT64_C(0xb) << QByteArray("0xb");
1154     QTest::newRow("c") << Q_INT64_C(0xc) << QByteArray("0xc");
1155     QTest::newRow("d") << Q_INT64_C(0xd) << QByteArray("0xd");
1156     QTest::newRow("e") << Q_INT64_C(0xe) << QByteArray("0xe");
1157     QTest::newRow("f") << Q_INT64_C(0xf) << QByteArray("0xf");
1158     QTest::newRow("-1") << Q_INT64_C(-1) << QByteArray("-0x1");
1159     QTest::newRow("0xffffffff") << Q_INT64_C(0xffffffff) << QByteArray("0xffffffff");
1160     QTest::newRow("0xfffffffffffffffe") << Q_INT64_C(0xfffffffffffffffe) << QByteArray("-0x2");
1161     QTest::newRow("0xffffffffffffffff") << Q_INT64_C(0xffffffffffffffff) << QByteArray("-0x1");
1162     QTest::newRow("0x7fffffffffffffff") << Q_INT64_C(0x7fffffffffffffff) << QByteArray("0x7fffffffffffffff");
1163 }
1164 
1165 // ------------------------------------------------------------------------------
hexTest()1166 void tst_QTextStream::hexTest()
1167 {
1168     QFETCH(qlonglong, number);
1169     QFETCH(QByteArray, data);
1170 
1171     QByteArray array;
1172     QTextStream stream(&array);
1173 
1174     stream << showbase << hex << number;
1175     stream.flush();
1176     QCOMPARE(array, data);
1177 }
1178 
1179 // ------------------------------------------------------------------------------
binTest_data()1180 void tst_QTextStream::binTest_data()
1181 {
1182     QTest::addColumn<int>("number");
1183     QTest::addColumn<QByteArray>("data");
1184 
1185     QTest::newRow("0") << 0 << QByteArray("0b0");
1186     QTest::newRow("1") << 1 << QByteArray("0b1");
1187     QTest::newRow("2") << 2 << QByteArray("0b10");
1188     QTest::newRow("5") << 5 << QByteArray("0b101");
1189     QTest::newRow("-1") << -1 << QByteArray("-0b1");
1190     QTest::newRow("11111111") << 0xff << QByteArray("0b11111111");
1191     QTest::newRow("1111111111111111") << 0xffff << QByteArray("0b1111111111111111");
1192     QTest::newRow("1111111011111110") << 0xfefe << QByteArray("0b1111111011111110");
1193 }
1194 
1195 // ------------------------------------------------------------------------------
binTest()1196 void tst_QTextStream::binTest()
1197 {
1198     QFETCH(int, number);
1199     QFETCH(QByteArray, data);
1200 
1201     QByteArray array;
1202     QTextStream stream(&array);
1203 
1204     stream << showbase << bin << number;
1205     stream.flush();
1206     QCOMPARE(array.constData(), data.constData());
1207 }
1208 
1209 // ------------------------------------------------------------------------------
octTest_data()1210 void tst_QTextStream::octTest_data()
1211 {
1212     QTest::addColumn<int>("number");
1213     QTest::addColumn<QByteArray>("data");
1214 
1215     QTest::newRow("0") << 0 << QByteArray("00");
1216 }
1217 
1218 // ------------------------------------------------------------------------------
octTest()1219 void tst_QTextStream::octTest()
1220 {
1221     QFETCH(int, number);
1222     QFETCH(QByteArray, data);
1223 
1224     QByteArray array;
1225     QTextStream stream(&array);
1226 
1227     stream << showbase << oct << number;
1228     stream.flush();
1229     QCOMPARE(array, data);
1230 }
1231 
1232 // ------------------------------------------------------------------------------
zeroTermination()1233 void tst_QTextStream::zeroTermination()
1234 {
1235     QTextStream stream;
1236     char c = '@';
1237 
1238     QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
1239     stream >> c;
1240     QCOMPARE(c, '\0');
1241 
1242     c = '@';
1243 
1244     QTest::ignoreMessage(QtWarningMsg, "QTextStream: No device");
1245     stream >> &c;
1246     QCOMPARE(c, '\0');
1247 }
1248 
1249 // ------------------------------------------------------------------------------
ws_manipulator()1250 void tst_QTextStream::ws_manipulator()
1251 {
1252     {
1253         QString string = "a b c d";
1254         QTextStream stream(&string);
1255 
1256         char a, b, c, d;
1257         stream >> a >> b >> c >> d;
1258         QCOMPARE(a, 'a');
1259         QCOMPARE(b, ' ');
1260         QCOMPARE(c, 'b');
1261         QCOMPARE(d, ' ');
1262     }
1263     {
1264         QString string = "a b c d";
1265         QTextStream stream(&string);
1266 
1267         char a, b, c, d;
1268         stream >> a >> ws >> b >> ws >> c >> ws >> d;
1269         QCOMPARE(a, 'a');
1270         QCOMPARE(b, 'b');
1271         QCOMPARE(c, 'c');
1272         QCOMPARE(d, 'd');
1273     }
1274 }
1275 
1276 // ------------------------------------------------------------------------------
stillOpenWhenAtEnd()1277 void tst_QTextStream::stillOpenWhenAtEnd()
1278 {
1279     int argc = 0;
1280     char **argv = 0;
1281     QCoreApplication app(argc, argv);
1282 
1283     QFile file(SRCDIR "tst_qtextstream.cpp");
1284     QVERIFY(file.open(QFile::ReadOnly));
1285 
1286     QTextStream stream(&file);
1287     while (!stream.readLine().isNull()) {}
1288     QVERIFY(file.isOpen());
1289 
1290 #ifdef Q_OS_WINCE
1291     QSKIP("Qt/CE: Cannot test network on emulator", SkipAll);
1292 #endif
1293     QTcpSocket socket;
1294     socket.connectToHost(QtNetworkSettings::serverName(), 143);
1295 #if defined(Q_OS_SYMBIAN)
1296     // This number is determined in an arbitrary way; whatever it takes
1297     // to make the test pass.
1298     QVERIFY(socket.waitForReadyRead(30000));
1299 #else
1300     QVERIFY(socket.waitForReadyRead(5000));
1301 #endif
1302 
1303     QTextStream stream2(&socket);
1304     while (!stream2.readLine().isNull()) {}
1305     QVERIFY(socket.isOpen());
1306 }
1307 
1308 // ------------------------------------------------------------------------------
readNewlines_data()1309 void tst_QTextStream::readNewlines_data()
1310 {
1311     QTest::addColumn<QByteArray>("input");
1312     QTest::addColumn<QString>("output");
1313 
1314     QTest::newRow("empty") << QByteArray() << QString();
1315     QTest::newRow("\\r\\n") << QByteArray("\r\n") << QString("\n");
1316     QTest::newRow("\\r\\r\\n") << QByteArray("\r\r\n") << QString("\n");
1317     QTest::newRow("\\r\\n\\r\\n") << QByteArray("\r\n\r\n") << QString("\n\n");
1318     QTest::newRow("\\n") << QByteArray("\n") << QString("\n");
1319     QTest::newRow("\\n\\n") << QByteArray("\n\n") << QString("\n\n");
1320 }
1321 
1322 // ------------------------------------------------------------------------------
readNewlines()1323 void tst_QTextStream::readNewlines()
1324 {
1325     QFETCH(QByteArray, input);
1326     QFETCH(QString, output);
1327 
1328     QBuffer buffer(&input);
1329     buffer.open(QBuffer::ReadOnly | QBuffer::Text);
1330     QTextStream stream(&buffer);
1331     QCOMPARE(stream.readAll(), output);
1332 }
1333 
1334 // ------------------------------------------------------------------------------
seek()1335 void tst_QTextStream::seek()
1336 {
1337     QFile file(SRCDIR "rfc3261.txt");
1338     QVERIFY(file.open(QFile::ReadOnly));
1339 
1340     QTextStream stream(&file);
1341     QString tmp;
1342     stream >> tmp;
1343     QCOMPARE(tmp, QString::fromLatin1("Network"));
1344 
1345     // QTextStream::seek(0) should both clear its internal read/write buffers
1346     // and seek the device.
1347     for (int i = 0; i < 4; ++i) {
1348         stream.seek(12 + i);
1349         stream >> tmp;
1350         QCOMPARE(tmp, QString("Network").mid(i));
1351     }
1352     for (int i = 0; i < 4; ++i) {
1353         stream.seek(16 - i);
1354         stream >> tmp;
1355         QCOMPARE(tmp, QString("Network").mid(4 - i));
1356     }
1357     stream.seek(139181);
1358     stream >> tmp;
1359     QCOMPARE(tmp, QString("information"));
1360     stream.seek(388683);
1361     stream >> tmp;
1362     QCOMPARE(tmp, QString("telephone"));
1363 
1364     // Also test this with a string
1365     QString words = QLatin1String("thisisa");
1366     QTextStream stream2(&words, QIODevice::ReadOnly);
1367     stream2 >> tmp;
1368     QCOMPARE(tmp, QString::fromLatin1("thisisa"));
1369 
1370     for (int i = 0; i < 4; ++i) {
1371         stream2.seek(i);
1372         stream2 >> tmp;
1373         QCOMPARE(tmp, QString("thisisa").mid(i));
1374     }
1375     for (int i = 0; i < 4; ++i) {
1376         stream2.seek(4 - i);
1377         stream2 >> tmp;
1378         QCOMPARE(tmp, QString("thisisa").mid(4 - i));
1379     }
1380 }
1381 
1382 // ------------------------------------------------------------------------------
pos()1383 void tst_QTextStream::pos()
1384 {
1385     int argc = 1;
1386     QCoreApplication app(argc, 0);
1387     {
1388         // Strings
1389         QString str("this is a test");
1390         QTextStream stream(&str, QIODevice::ReadWrite);
1391 
1392         QCOMPARE(stream.pos(), qint64(0));
1393         for (int i = 0; i <= str.size(); ++i) {
1394             QVERIFY(stream.seek(i));
1395             QCOMPARE(stream.pos(), qint64(i));
1396         }
1397         for (int j = str.size(); j >= 0; --j) {
1398             QVERIFY(stream.seek(j));
1399             QCOMPARE(stream.pos(), qint64(j));
1400         }
1401 
1402         QVERIFY(stream.seek(0));
1403 
1404         QChar ch;
1405         stream >> ch;
1406         QCOMPARE(ch, QChar('t'));
1407 
1408         QCOMPARE(stream.pos(), qint64(1));
1409         QVERIFY(stream.seek(1));
1410         QCOMPARE(stream.pos(), qint64(1));
1411         QVERIFY(stream.seek(0));
1412 
1413         QString strtmp;
1414         stream >> strtmp;
1415         QCOMPARE(strtmp, QString("this"));
1416 
1417         QCOMPARE(stream.pos(), qint64(4));
1418         stream.seek(0);
1419         stream.seek(4);
1420 
1421         stream >> ch;
1422         QCOMPARE(ch, QChar(' '));
1423         QCOMPARE(stream.pos(), qint64(5));
1424 
1425         stream.seek(10);
1426         stream >> strtmp;
1427         QCOMPARE(strtmp, QString("test"));
1428         QCOMPARE(stream.pos(), qint64(14));
1429     }
1430     {
1431         // Latin1 device
1432         QFile file(SRCDIR "rfc3261.txt");
1433         QVERIFY(file.open(QIODevice::ReadOnly));
1434 
1435         QTextStream stream(&file);
1436 
1437         QCOMPARE(stream.pos(), qint64(0));
1438 
1439         for (int i = 0; i <= file.size(); i += 7) {
1440             QVERIFY(stream.seek(i));
1441             QCOMPARE(stream.pos(), qint64(i));
1442         }
1443         for (int j = file.size(); j >= 0; j -= 7) {
1444             QVERIFY(stream.seek(j));
1445             QCOMPARE(stream.pos(), qint64(j));
1446         }
1447 
1448         stream.seek(0);
1449 
1450         QString strtmp;
1451         stream >> strtmp;
1452         QCOMPARE(strtmp, QString("Network"));
1453         QCOMPARE(stream.pos(), qint64(19));
1454 
1455         stream.seek(2598);
1456         QCOMPARE(stream.pos(), qint64(2598));
1457         stream >> strtmp;
1458         QCOMPARE(stream.pos(), qint64(2607));
1459         QCOMPARE(strtmp, QString("locations"));
1460     }
1461     {
1462         // Shift-JIS device
1463         for (int i = 0; i < 2; ++i) {
1464             QFile file(SRCDIR "shift-jis.txt");
1465             if (i == 0)
1466                 QVERIFY(file.open(QIODevice::ReadOnly));
1467             else
1468                 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
1469 
1470             QTextStream stream(&file);
1471             stream.setCodec("Shift-JIS");
1472             QVERIFY(stream.codec());
1473 
1474             QCOMPARE(stream.pos(), qint64(0));
1475             for (int i = 0; i <= file.size(); i += 7) {
1476                 QVERIFY(stream.seek(i));
1477                 QCOMPARE(stream.pos(), qint64(i));
1478             }
1479             for (int j = file.size(); j >= 0; j -= 7) {
1480                 QVERIFY(stream.seek(j));
1481                 QCOMPARE(stream.pos(), qint64(j));
1482             }
1483 
1484             stream.seek(2089);
1485             QString strtmp;
1486             stream >> strtmp;
1487             QCOMPARE(strtmp, QString("AUnicode"));
1488             QCOMPARE(stream.pos(), qint64(2097));
1489 
1490             stream.seek(43325);
1491             stream >> strtmp;
1492             QCOMPARE(strtmp, QString("Shift-JIS"));
1493             stream >> strtmp;
1494             QCOMPARE(strtmp, QString::fromUtf8("\343\201\247\346\233\270\343\201\213\343\202\214\343\201\237"));
1495             QCOMPARE(stream.pos(), qint64(43345));
1496             stream >> strtmp;
1497             QCOMPARE(strtmp, QString("POD"));
1498             QCOMPARE(stream.pos(), qint64(43349));
1499         }
1500     }
1501 }
1502 
1503 // ------------------------------------------------------------------------------
pos2()1504 void tst_QTextStream::pos2()
1505 {
1506     QByteArray data("abcdef\r\nghijkl\r\n");
1507     QBuffer buffer(&data);
1508     QVERIFY(buffer.open(QIODevice::ReadOnly | QIODevice::Text));
1509 
1510     QTextStream stream(&buffer);
1511 
1512     QChar ch;
1513 
1514     QCOMPARE(stream.pos(), qint64(0));
1515     stream >> ch;
1516     QCOMPARE(ch, QChar('a'));
1517     QCOMPARE(stream.pos(), qint64(1));
1518 
1519     QString str;
1520     stream >> str;
1521     QCOMPARE(str, QString("bcdef"));
1522     QCOMPARE(stream.pos(), qint64(6));
1523 
1524     stream >> str;
1525     QCOMPARE(str, QString("ghijkl"));
1526     QCOMPARE(stream.pos(), qint64(14));
1527 
1528     // Seek back and try again
1529     stream.seek(1);
1530     QCOMPARE(stream.pos(), qint64(1));
1531     stream >> str;
1532     QCOMPARE(str, QString("bcdef"));
1533     QCOMPARE(stream.pos(), qint64(6));
1534 
1535     stream.seek(6);
1536     stream >> str;
1537     QCOMPARE(str, QString("ghijkl"));
1538     QCOMPARE(stream.pos(), qint64(14));
1539 }
1540 
1541 // ------------------------------------------------------------------------------
pos3LargeFile()1542 void tst_QTextStream::pos3LargeFile()
1543 {
1544     {
1545         QFile file(TestFileName);
1546         file.open(QIODevice::WriteOnly | QIODevice::Text);
1547         QTextStream out( &file );
1548         // NOTE: The unusual spacing is to ensure non-1-character whitespace.
1549         QString lineString = " 0  1  2\t3  4\t \t5  6  7  8   9 \n";
1550         // Approximate 50kb text file
1551         const int NbLines = (50*1024) / lineString.length() + 1;
1552         for (int line = 0; line < NbLines; ++line)
1553             out << lineString;
1554         // File is automatically flushed and closed on destruction.
1555     }
1556     QFile file(TestFileName);
1557     file.open(QIODevice::ReadOnly | QIODevice::Text);
1558     QTextStream in( &file );
1559     const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
1560     int value;
1561     while (true) {
1562         in.pos();
1563         for ( int i = 0; i < 10; ++i ) {
1564             in >> value;
1565             if (in.status() != QTextStream::Ok) {
1566                 // End case, i == 0 && eof reached.
1567                 QCOMPARE(i, 0);
1568                 QCOMPARE(in.status(), QTextStream::ReadPastEnd);
1569                 return;
1570             }
1571             QCOMPARE(value, testValues[i]);
1572         }
1573     }
1574 }
1575 
1576 // ------------------------------------------------------------------------------
readStdin()1577 void tst_QTextStream::readStdin()
1578 {
1579 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
1580     QSKIP("Qt/CE and Symbian have no stdin/out support for processes", SkipAll);
1581 #endif
1582     QProcess stdinProcess;
1583     stdinProcess.start(m_stdinProcess);
1584     stdinProcess.setReadChannel(QProcess::StandardError);
1585 
1586     QTextStream stream(&stdinProcess);
1587     stream << "1" << endl;
1588     stream << "2" << endl;
1589     stream << "3" << endl;
1590 
1591     stdinProcess.closeWriteChannel();
1592 
1593     QVERIFY(stdinProcess.waitForFinished(5000));
1594 
1595     int a, b, c;
1596     stream >> a >> b >> c;
1597     QCOMPARE(a, 1);
1598     QCOMPARE(b, 2);
1599     QCOMPARE(c, 3);
1600 }
1601 
1602 // ------------------------------------------------------------------------------
readAllFromStdin()1603 void tst_QTextStream::readAllFromStdin()
1604 {
1605 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
1606     QSKIP("Qt/CE and Symbian have no stdin/out support for processes", SkipAll);
1607 #endif
1608     QProcess stdinProcess;
1609     stdinProcess.start(m_readAllStdinProcess, QIODevice::ReadWrite | QIODevice::Text);
1610     stdinProcess.setReadChannel(QProcess::StandardError);
1611 
1612     QTextStream stream(&stdinProcess);
1613     stream.setCodec("ISO-8859-1");
1614     stream << "hello world" << flush;
1615 
1616     stdinProcess.closeWriteChannel();
1617 
1618     QVERIFY(stdinProcess.waitForFinished(5000));
1619     QChar quoteChar('"');
1620     QCOMPARE(stream.readAll(), QString::fromLatin1("%1hello world%2 \n").arg(quoteChar).arg(quoteChar));
1621 }
1622 
1623 // ------------------------------------------------------------------------------
readLineFromStdin()1624 void tst_QTextStream::readLineFromStdin()
1625 {
1626 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
1627     QSKIP("Qt/CE and Symbian have no stdin/out support for processes", SkipAll);
1628 #endif
1629     QProcess stdinProcess;
1630     stdinProcess.start(m_readLineStdinProcess, QIODevice::ReadWrite | QIODevice::Text);
1631     stdinProcess.setReadChannel(QProcess::StandardError);
1632 
1633     stdinProcess.write("abc\n");
1634     QVERIFY(stdinProcess.waitForReadyRead(5000));
1635     QCOMPARE(stdinProcess.readAll().data(), QByteArray("abc").data());
1636 
1637     stdinProcess.write("def\n");
1638     QVERIFY(stdinProcess.waitForReadyRead(5000));
1639     QCOMPARE(stdinProcess.readAll(), QByteArray("def"));
1640 
1641     stdinProcess.closeWriteChannel();
1642 
1643     QVERIFY(stdinProcess.waitForFinished(5000));
1644 }
1645 
1646 // ------------------------------------------------------------------------------
read()1647 void tst_QTextStream::read()
1648 {
1649     {
1650         QFile::remove("testfile");
1651         QFile file("testfile");
1652         file.open(QFile::WriteOnly);
1653         file.write("4.15 abc ole");
1654         file.close();
1655 
1656         QVERIFY(file.open(QFile::ReadOnly));
1657         QTextStream stream(&file);
1658         QCOMPARE(stream.read(0), QString(""));
1659         QCOMPARE(stream.read(4), QString("4.15"));
1660         QCOMPARE(stream.read(4), QString(" abc"));
1661         stream.seek(1);
1662         QCOMPARE(stream.read(4), QString(".15 "));
1663         stream.seek(1);
1664         QCOMPARE(stream.read(4), QString(".15 "));
1665         stream.seek(2);
1666         QCOMPARE(stream.read(4), QString("15 a"));
1667         // ### add tests for reading \r\n etc..
1668     }
1669 
1670     {
1671         // File larger than QTEXTSTREAM_BUFFERSIZE
1672         QFile::remove("testfile");
1673         QFile file("testfile");
1674         file.open(QFile::WriteOnly);
1675         for (int i = 0; i < 16384 / 8; ++i)
1676             file.write("01234567");
1677         file.write("0");
1678         file.close();
1679 
1680         QVERIFY(file.open(QFile::ReadOnly));
1681         QTextStream stream(&file);
1682         QCOMPARE(stream.read(10), QString("0123456701"));
1683         QCOMPARE(stream.read(10), QString("2345670123"));
1684         QCOMPARE(stream.readAll().size(), 16385-20);
1685     }
1686 }
1687 
1688 // ------------------------------------------------------------------------------
qbool()1689 void tst_QTextStream::qbool()
1690 {
1691     QString s;
1692     QTextStream stream(&s);
1693     stream << s.contains(QString("hei"));
1694     QCOMPARE(s, QString("0"));
1695 }
1696 
1697 // ------------------------------------------------------------------------------
forcePoint()1698 void tst_QTextStream::forcePoint()
1699 {
1700     QString str;
1701     QTextStream stream(&str);
1702     stream << fixed << forcepoint << 1.0 << " " << 1 << " " << 0 << " " << -1.0 << " " << -1;
1703     QCOMPARE(str, QString("1.000000 1 0 -1.000000 -1"));
1704 
1705     str.clear();
1706     stream.seek(0);
1707     stream << scientific << forcepoint << 1.0 << " " << 1 << " " << 0 << " " << -1.0 << " " << -1;
1708     QCOMPARE(str, QString("1.000000e+00 1 0 -1.000000e+00 -1"));
1709 
1710     str.clear();
1711     stream.seek(0);
1712     stream.setRealNumberNotation(QTextStream::SmartNotation);
1713     stream << forcepoint << 1.0 << " " << 1 << " " << 0 << " " << -1.0 << " " << -1;
1714     QCOMPARE(str, QString("1.00000 1 0 -1.00000 -1"));
1715 
1716 }
1717 
1718 // ------------------------------------------------------------------------------
forceSign()1719 void tst_QTextStream::forceSign()
1720 {
1721     QString str;
1722     QTextStream stream(&str);
1723     stream << forcesign << 1.2 << " " << -1.2 << " " << 0;
1724     QCOMPARE(str, QString("+1.2 -1.2 +0"));
1725 }
1726 
1727 // ------------------------------------------------------------------------------
read0d0d0a()1728 void tst_QTextStream::read0d0d0a()
1729 {
1730     QFile file("task113817.txt");
1731     file.open(QIODevice::ReadOnly | QIODevice::Text);
1732 
1733     QTextStream stream(&file);
1734     while (!stream.atEnd())
1735         stream.readLine();
1736 }
1737 
1738 // ------------------------------------------------------------------------------
1739 
1740 Q_DECLARE_METATYPE(QTextStreamFunction);
1741 
noop(QTextStream & s)1742 QTextStream &noop(QTextStream &s) { return s; }
1743 
numeralCase_data()1744 void tst_QTextStream::numeralCase_data()
1745 {
1746     QTextStreamFunction noop_ = noop;
1747     QTextStreamFunction bin_  = bin;
1748     QTextStreamFunction oct_  = oct;
1749     QTextStreamFunction hex_  = hex;
1750     QTextStreamFunction base  = showbase;
1751     QTextStreamFunction ucb   = uppercasebase;
1752     QTextStreamFunction lcb   = lowercasebase;
1753     QTextStreamFunction ucd   = uppercasedigits;
1754     QTextStreamFunction lcd   = lowercasedigits;
1755 
1756     QTest::addColumn<QTextStreamFunction>("func1");
1757     QTest::addColumn<QTextStreamFunction>("func2");
1758     QTest::addColumn<QTextStreamFunction>("func3");
1759     QTest::addColumn<QTextStreamFunction>("func4");
1760     QTest::addColumn<int>("value");
1761     QTest::addColumn<QString>("expected");
1762     QTest::newRow("dec 1") << noop_ << noop_ << noop_ << noop_ << 31 << "31";
1763     QTest::newRow("dec 2") << noop_ << base  << noop_ << noop_ << 31 << "31";
1764 
1765     QTest::newRow("hex 1")  << hex_  << noop_ << noop_ << noop_ << 31 << "1f";
1766     QTest::newRow("hex 2")  << hex_  << noop_ << noop_ << lcd   << 31 << "1f";
1767     QTest::newRow("hex 3")  << hex_  << noop_ << ucb   << noop_ << 31 << "1f";
1768     QTest::newRow("hex 4")  << hex_  << noop_ << noop_ << ucd   << 31 << "1F";
1769     QTest::newRow("hex 5")  << hex_  << noop_ << lcb   << ucd   << 31 << "1F";
1770     QTest::newRow("hex 6")  << hex_  << noop_ << ucb   << ucd   << 31 << "1F";
1771     QTest::newRow("hex 7")  << hex_  << base  << noop_ << noop_ << 31 << "0x1f";
1772     QTest::newRow("hex 8")  << hex_  << base  << lcb   << lcd   << 31 << "0x1f";
1773     QTest::newRow("hex 9")  << hex_  << base  << ucb   << noop_ << 31 << "0X1f";
1774     QTest::newRow("hex 10") << hex_  << base  << ucb   << lcd   << 31 << "0X1f";
1775     QTest::newRow("hex 11") << hex_  << base  << noop_ << ucd   << 31 << "0x1F";
1776     QTest::newRow("hex 12") << hex_  << base  << lcb   << ucd   << 31 << "0x1F";
1777     QTest::newRow("hex 13") << hex_  << base  << ucb   << ucd   << 31 << "0X1F";
1778 
1779     QTest::newRow("bin 1") << bin_  << noop_ << noop_ << noop_ << 31 << "11111";
1780     QTest::newRow("bin 2") << bin_  << base  << noop_ << noop_ << 31 << "0b11111";
1781     QTest::newRow("bin 3") << bin_  << base  << lcb   << noop_ << 31 << "0b11111";
1782     QTest::newRow("bin 4") << bin_  << base  << ucb   << noop_ << 31 << "0B11111";
1783     QTest::newRow("bin 5") << bin_  << base  << noop_ << ucd   << 31 << "0b11111";
1784     QTest::newRow("bin 6") << bin_  << base  << lcb   << ucd   << 31 << "0b11111";
1785     QTest::newRow("bin 7") << bin_  << base  << ucb   << ucd   << 31 << "0B11111";
1786 
1787     QTest::newRow("oct 1") << oct_  << noop_ << noop_ << noop_ << 31 << "37";
1788     QTest::newRow("oct 2") << oct_  << base  << noop_ << noop_ << 31 << "037";
1789 }
1790 
1791 // From Task 125496
numeralCase()1792 void tst_QTextStream::numeralCase()
1793 {
1794     QFETCH(QTextStreamFunction, func1);
1795     QFETCH(QTextStreamFunction, func2);
1796     QFETCH(QTextStreamFunction, func3);
1797     QFETCH(QTextStreamFunction, func4);
1798     QFETCH(int, value);
1799     QFETCH(QString, expected);
1800 
1801     QString str;
1802     QTextStream stream(&str);
1803     stream << func1 << func2 << func3 << func4 << value;
1804     QCOMPARE(str, expected);
1805 }
1806 
1807 // ------------------------------------------------------------------------------
nanInf()1808 void tst_QTextStream::nanInf()
1809 {
1810     // Cannot use test data in this function, as comparing nans and infs isn't
1811     // well defined.
1812     QString str("nan NAN nAn +nan +NAN +nAn -nan -NAN -nAn"
1813                 " inf INF iNf +inf +INF +iNf -inf -INF -iNf");
1814 
1815     QTextStream stream(&str);
1816 
1817     double tmpD = 0;
1818     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1819     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1820     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1821     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1822     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1823     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1824     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1825     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1826     stream >> tmpD; QVERIFY(qIsNaN(tmpD)); tmpD = 0;
1827     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
1828     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
1829     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
1830     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
1831     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
1832     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD > 0); tmpD = 0;
1833     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0;
1834     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0;
1835     stream >> tmpD; QVERIFY(qIsInf(tmpD)); QVERIFY(tmpD < 0); tmpD = 0;
1836 
1837     stream.seek(0);
1838 
1839     float tmpF = 0;
1840     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1841     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1842     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1843     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1844     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1845     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1846     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1847     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1848     stream >> tmpF; QVERIFY(qIsNaN(tmpF)); tmpD = 0;
1849     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
1850     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
1851     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
1852     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
1853     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
1854     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF > 0); tmpD = 0;
1855     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0;
1856     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0); tmpD = 0;
1857     stream >> tmpF; QVERIFY(qIsInf(tmpF)); QVERIFY(tmpF < 0);
1858 
1859     QString s;
1860     QTextStream out(&s);
1861     out << qInf() << " " << -qInf() << " " << qQNaN()
1862         << uppercasedigits << " "
1863         << qInf() << " " << -qInf() << " " << qQNaN()
1864         << flush;
1865 
1866     QCOMPARE(s, QString("inf -inf nan INF -INF NAN"));
1867 }
1868 
1869 // ------------------------------------------------------------------------------
utf8IncompleteAtBufferBoundary_data()1870 void tst_QTextStream::utf8IncompleteAtBufferBoundary_data()
1871 {
1872     QTest::addColumn<bool>("useLocale");
1873 
1874     QTest::newRow("utf8") << false;
1875 
1876     // is this locale UTF-8?
1877     if (QString(QChar::ReplacementCharacter).toLocal8Bit() == "\xef\xbf\xbd")
1878         QTest::newRow("locale") << true;
1879 }
1880 
utf8IncompleteAtBufferBoundary()1881 void tst_QTextStream::utf8IncompleteAtBufferBoundary()
1882 {
1883     QFile::remove(TestFileName);
1884     QFile data(TestFileName);
1885 
1886     QTextCodec *utf8Codec = QTextCodec::codecForMib(106);
1887     QString lineContents = QString::fromUtf8("\342\200\223" // U+2013 EN DASH
1888                                              "\342\200\223"
1889                                              "\342\200\223"
1890                                              "\342\200\223"
1891                                              "\342\200\223"
1892                                              "\342\200\223");
1893 
1894     data.open(QFile::WriteOnly | QFile::Truncate);
1895     {
1896         QTextStream out(&data);
1897         out.setCodec(utf8Codec);
1898         out.setFieldWidth(3);
1899 
1900         for (int i = 0; i < 1000; ++i) {
1901             out << i << lineContents << endl;
1902         }
1903     }
1904     data.close();
1905 
1906     data.open(QFile::ReadOnly);
1907     QTextStream in(&data);
1908 
1909     QFETCH(bool, useLocale);
1910     if (!useLocale)
1911         in.setCodec(utf8Codec); // QUtf8Codec
1912     else
1913         in.setCodec(QTextCodec::codecForLocale());
1914 
1915     int i = 0;
1916     do {
1917         QString line = in.readLine().trimmed();
1918         ++i;
1919         QVERIFY2(line.endsWith(lineContents), QString("Line %1: %2").arg(i).arg(line).toLocal8Bit());
1920     } while (!in.atEnd());
1921 }
1922 
1923 // ------------------------------------------------------------------------------
1924 
1925 // Make sure we don't write a BOM after seek()ing
1926 
writeSeekWriteNoBOM()1927 void tst_QTextStream::writeSeekWriteNoBOM()
1928 {
1929 
1930     //First with the default codec (normally either latin-1 or UTF-8)
1931 
1932     QBuffer out;
1933     out.open(QIODevice::WriteOnly);
1934     QTextStream stream(&out);
1935 
1936     int number = 0;
1937     QString sizeStr = QLatin1String("Size=")
1938         + QString::number(number).rightJustified(10, QLatin1Char('0'));
1939     stream << sizeStr << endl;
1940     stream << "Version=" << QString::number(14) << endl;
1941     stream << "blah blah blah" << endl;
1942     stream.flush();
1943 
1944     QCOMPARE(out.buffer().constData(), "Size=0000000000\nVersion=14\nblah blah blah\n");
1945 
1946     // Now overwrite the size header item
1947     number = 42;
1948     stream.seek(0);
1949     sizeStr = QLatin1String("Size=")
1950         + QString::number(number).rightJustified(10, QLatin1Char('0'));
1951     stream << sizeStr << endl;
1952     stream.flush();
1953 
1954     // Check buffer is still OK
1955     QCOMPARE(out.buffer().constData(), "Size=0000000042\nVersion=14\nblah blah blah\n");
1956 
1957 
1958     //Then UTF-16
1959 
1960     QBuffer out16;
1961     out16.open(QIODevice::WriteOnly);
1962     QTextStream stream16(&out16);
1963     stream16.setCodec("UTF-16");
1964 
1965     stream16 << "one" << "two" << QLatin1String("three");
1966     stream16.flush();
1967 
1968     // save that output
1969     QByteArray first = out16.buffer();
1970 
1971     stream16.seek(0);
1972     stream16 << "one";
1973     stream16.flush();
1974 
1975     QCOMPARE(out16.buffer(), first);
1976 }
1977 
1978 
1979 
1980 // ------------------------------------------------------------------------------
generateOperatorCharData(bool for_QString)1981 void tst_QTextStream::generateOperatorCharData(bool for_QString)
1982 {
1983     QTest::addColumn<QByteArray>("input");
1984     QTest::addColumn<QChar>("qchar_output");
1985     QTest::addColumn<char>("char_output");
1986     QTest::addColumn<QByteArray>("write_output");
1987 
1988     QTest::newRow("empty") << QByteArray() << QChar('\0') << '\0' << QByteArray("\0", 1);
1989     QTest::newRow("a") << QByteArray("a") << QChar('a') << 'a' << QByteArray("a");
1990     QTest::newRow("\\na") << QByteArray("\na") << QChar('\n') << '\n' << QByteArray("\n");
1991     QTest::newRow("\\0") << QByteArray("\0") << QChar('\0') << '\0' << QByteArray("\0", 1);
1992     QTest::newRow("\\xff") << QByteArray("\xff") << QChar('\xff') << '\xff' << QByteArray("\xff");
1993     QTest::newRow("\\xfe") << QByteArray("\xfe") << QChar('\xfe') << '\xfe' << QByteArray("\xfe");
1994 
1995     if (!for_QString) {
1996         QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QChar('\0') << '\0' << QByteArray("\0", 1);
1997         QTest::newRow("utf16-BE (a)") << QByteArray("\xff\xfe\x61\x00", 4) << QChar('a') << 'a' << QByteArray("a");
1998         QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QChar('\0') << '\0' << QByteArray("\0", 1);
1999         QTest::newRow("utf16-LE (a)") << QByteArray("\xfe\xff\x00\x61", 4) << QChar('a') << 'a' << QByteArray("a");
2000     }
2001 }
2002 
2003 // ------------------------------------------------------------------------------
QChar_operators_FromDevice_data()2004 void tst_QTextStream::QChar_operators_FromDevice_data()
2005 {
2006     generateOperatorCharData(false);
2007 }
2008 
2009 // ------------------------------------------------------------------------------
QChar_operators_FromDevice()2010 void tst_QTextStream::QChar_operators_FromDevice()
2011 {
2012     QFETCH(QByteArray, input);
2013     QFETCH(QChar, qchar_output);
2014     QFETCH(QByteArray, write_output);
2015 
2016     QBuffer buf(&input);
2017     buf.open(QBuffer::ReadOnly);
2018     QTextStream stream(&buf);
2019     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2020     QChar tmp;
2021     stream >> tmp;
2022     QCOMPARE(tmp, qchar_output);
2023 
2024     QBuffer writeBuf;
2025     writeBuf.open(QBuffer::WriteOnly);
2026 
2027     QTextStream writeStream(&writeBuf);
2028     writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2029     writeStream << qchar_output;
2030     writeStream.flush();
2031 
2032     QCOMPARE(writeBuf.buffer().size(), write_output.size());
2033     QCOMPARE(writeBuf.buffer().constData(), write_output.constData());
2034 }
2035 
2036 // ------------------------------------------------------------------------------
char_operators_FromDevice_data()2037 void tst_QTextStream::char_operators_FromDevice_data()
2038 {
2039     generateOperatorCharData(false);
2040 }
2041 
2042 // ------------------------------------------------------------------------------
char_operators_FromDevice()2043 void tst_QTextStream::char_operators_FromDevice()
2044 {
2045     QFETCH(QByteArray, input);
2046     QFETCH(char, char_output);
2047     QFETCH(QByteArray, write_output);
2048 
2049     QBuffer buf(&input);
2050     buf.open(QBuffer::ReadOnly);
2051     QTextStream stream(&buf);
2052     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2053     char tmp;
2054     stream >> tmp;
2055     QCOMPARE(tmp, char_output);
2056 
2057     QBuffer writeBuf;
2058     writeBuf.open(QBuffer::WriteOnly);
2059 
2060     QTextStream writeStream(&writeBuf);
2061     writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2062     writeStream << char_output;
2063     writeStream.flush();
2064 
2065     QCOMPARE(writeBuf.buffer().size(), write_output.size());
2066     QCOMPARE(writeBuf.buffer().constData(), write_output.constData());
2067 }
2068 
2069 // ------------------------------------------------------------------------------
generateNaturalNumbersData(bool for_QString)2070 void tst_QTextStream::generateNaturalNumbersData(bool for_QString)
2071 {
2072     QTest::addColumn<QByteArray>("input");
2073     QTest::addColumn<qulonglong>("output");
2074 
2075     QTest::newRow("empty") << QByteArray() << qulonglong(0);
2076     QTest::newRow("a") << QByteArray("a") << qulonglong(0);
2077     QTest::newRow(" ") << QByteArray(" ") << qulonglong(0);
2078     QTest::newRow("0") << QByteArray("0") << qulonglong(0);
2079     QTest::newRow("1") << QByteArray("1") << qulonglong(1);
2080     QTest::newRow("12") << QByteArray("12") << qulonglong(12);
2081     QTest::newRow("-12") << QByteArray("-12") << qulonglong(-12);
2082     QTest::newRow("-0") << QByteArray("-0") << qulonglong(0);
2083     QTest::newRow(" 1") << QByteArray(" 1") << qulonglong(1);
2084     QTest::newRow(" \\r\\n\\r\\n123") << QByteArray(" \r\n\r\n123") << qulonglong(123);
2085 
2086     // bit boundary tests
2087     QTest::newRow("127") << QByteArray("127") << qulonglong(127);
2088     QTest::newRow("128") << QByteArray("128") << qulonglong(128);
2089     QTest::newRow("129") << QByteArray("129") << qulonglong(129);
2090     QTest::newRow("-127") << QByteArray("-127") << qulonglong(-127);
2091     QTest::newRow("-128") << QByteArray("-128") << qulonglong(-128);
2092     QTest::newRow("-129") << QByteArray("-129") << qulonglong(-129);
2093     QTest::newRow("32767") << QByteArray("32767") << qulonglong(32767);
2094     QTest::newRow("32768") << QByteArray("32768") << qulonglong(32768);
2095     QTest::newRow("32769") << QByteArray("32769") << qulonglong(32769);
2096     QTest::newRow("-32767") << QByteArray("-32767") << qulonglong(-32767);
2097     QTest::newRow("-32768") << QByteArray("-32768") << qulonglong(-32768);
2098     QTest::newRow("-32769") << QByteArray("-32769") << qulonglong(-32769);
2099     QTest::newRow("65537") << QByteArray("65537") << qulonglong(65537);
2100     QTest::newRow("65536") << QByteArray("65536") << qulonglong(65536);
2101     QTest::newRow("65535") << QByteArray("65535") << qulonglong(65535);
2102     QTest::newRow("-65537") << QByteArray("-65537") << qulonglong(-65537);
2103     QTest::newRow("-65536") << QByteArray("-65536") << qulonglong(-65536);
2104     QTest::newRow("-65535") << QByteArray("-65535") << qulonglong(-65535);
2105     QTest::newRow("2147483646") << QByteArray("2147483646") << qulonglong(2147483646);
2106     QTest::newRow("2147483647") << QByteArray("2147483647") << qulonglong(2147483647);
2107     QTest::newRow("2147483648") << QByteArray("2147483648") << Q_UINT64_C(2147483648);
2108     QTest::newRow("-2147483646") << QByteArray("-2147483646") << qulonglong(-2147483646);
2109     QTest::newRow("-2147483647") << QByteArray("-2147483647") << qulonglong(-2147483647);
2110     QTest::newRow("-2147483648") << QByteArray("-2147483648") << Q_UINT64_C(-2147483648);
2111     QTest::newRow("4294967296") << QByteArray("4294967296") << Q_UINT64_C(4294967296);
2112     QTest::newRow("4294967297") << QByteArray("4294967297") << Q_UINT64_C(4294967297);
2113     QTest::newRow("4294967298") << QByteArray("4294967298") << Q_UINT64_C(4294967298);
2114     QTest::newRow("-4294967296") << QByteArray("-4294967296") << Q_UINT64_C(-4294967296);
2115     QTest::newRow("-4294967297") << QByteArray("-4294967297") << Q_UINT64_C(-4294967297);
2116     QTest::newRow("-4294967298") << QByteArray("-4294967298") << Q_UINT64_C(-4294967298);
2117     QTest::newRow("9223372036854775807") << QByteArray("9223372036854775807") << Q_UINT64_C(9223372036854775807);
2118     QTest::newRow("9223372036854775808") << QByteArray("9223372036854775808") << Q_UINT64_C(9223372036854775808);
2119     QTest::newRow("9223372036854775809") << QByteArray("9223372036854775809") << Q_UINT64_C(9223372036854775809);
2120     QTest::newRow("18446744073709551615") << QByteArray("18446744073709551615") << Q_UINT64_C(18446744073709551615);
2121     QTest::newRow("18446744073709551616") << QByteArray("18446744073709551616") << Q_UINT64_C(0);
2122     QTest::newRow("18446744073709551617") << QByteArray("18446744073709551617") << Q_UINT64_C(1);
2123     // 18446744073709551617 bytes should be enough for anyone.... ;-)
2124 
2125     // hex tests
2126     QTest::newRow("0x0") << QByteArray("0x0") << qulonglong(0);
2127     QTest::newRow("0x") << QByteArray("0x") << qulonglong(0);
2128     QTest::newRow("0x1") << QByteArray("0x1") << qulonglong(1);
2129     QTest::newRow("0xf") << QByteArray("0xf") << qulonglong(15);
2130     QTest::newRow("0xdeadbeef") << QByteArray("0xdeadbeef") << Q_UINT64_C(3735928559);
2131     QTest::newRow("0XDEADBEEF") << QByteArray("0XDEADBEEF") << Q_UINT64_C(3735928559);
2132     QTest::newRow("0xdeadbeefZzzzz") << QByteArray("0xdeadbeefZzzzz") << Q_UINT64_C(3735928559);
2133     QTest::newRow("  0xdeadbeefZzzzz") << QByteArray("  0xdeadbeefZzzzz") << Q_UINT64_C(3735928559);
2134 
2135     // oct tests
2136     QTest::newRow("00") << QByteArray("00") << qulonglong(0);
2137     QTest::newRow("0141") << QByteArray("0141") << qulonglong(97);
2138     QTest::newRow("01419999") << QByteArray("01419999") << qulonglong(97);
2139     QTest::newRow("  01419999") << QByteArray("  01419999") << qulonglong(97);
2140 
2141     // bin tests
2142     QTest::newRow("0b0") << QByteArray("0b0") << qulonglong(0);
2143     QTest::newRow("0b1") << QByteArray("0b1") << qulonglong(1);
2144     QTest::newRow("0b10") << QByteArray("0b10") << qulonglong(2);
2145     QTest::newRow("0B10") << QByteArray("0B10") << qulonglong(2);
2146     QTest::newRow("0b101010") << QByteArray("0b101010") << qulonglong(42);
2147     QTest::newRow("0b1010102345") << QByteArray("0b1010102345") << qulonglong(42);
2148     QTest::newRow("  0b1010102345") << QByteArray("  0b1010102345") << qulonglong(42);
2149 
2150     // utf-16 tests
2151     if (!for_QString) {
2152         QTest::newRow("utf16-BE (empty)") << QByteArray("\xfe\xff", 2) << qulonglong(0);
2153         QTest::newRow("utf16-BE (0xdeadbeef)")
2154             << QByteArray("\xfe\xff"
2155                           "\x00\x30\x00\x78\x00\x64\x00\x65\x00\x61\x00\x64\x00\x62\x00\x65\x00\x65\x00\x66", 22)
2156             << Q_UINT64_C(3735928559);
2157         QTest::newRow("utf16-LE (empty)") << QByteArray("\xff\xfe", 2) << Q_UINT64_C(0);
2158         QTest::newRow("utf16-LE (0xdeadbeef)")
2159             << QByteArray("\xff\xfe"
2160                           "\x30\x00\x78\x00\x64\x00\x65\x00\x61\x00\x64\x00\x62\x00\x65\x00\x65\x00\x66\x00", 22)
2161             << Q_UINT64_C(3735928559);
2162     }
2163 }
2164 
2165 // ------------------------------------------------------------------------------
2166 #define IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(texttype, type) \
2167     void tst_QTextStream:: texttype##_read_operator_FromDevice_data() \
2168     { generateNaturalNumbersData(false); } \
2169     void tst_QTextStream:: texttype##_read_operator_FromDevice() \
2170     { \
2171         QFETCH(QByteArray, input); \
2172         QFETCH(qulonglong, output); \
2173         type sh; \
2174         QTextStream stream(&input); \
2175         stream >> sh; \
2176         QCOMPARE(sh, (type)output); \
2177     }
2178 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedShort, signed short)
2179 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedShort, unsigned short)
2180 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(signedInt, signed int)
2181 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(unsignedInt, unsigned int)
2182 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qlonglong, qlonglong)
2183 IMPLEMENT_STREAM_RIGHT_INT_OPERATOR_TEST(qulonglong, qulonglong)
2184     ;
2185 
2186 // ------------------------------------------------------------------------------
generateRealNumbersData(bool for_QString)2187 void tst_QTextStream::generateRealNumbersData(bool for_QString)
2188 {
2189     QTest::addColumn<QByteArray>("input");
2190     QTest::addColumn<double>("output");
2191 
2192     QTest::newRow("empty") << QByteArray() << 0.0;
2193     QTest::newRow("a") << QByteArray("a") << 0.0;
2194     QTest::newRow("1.0") << QByteArray("1.0") << 1.0;
2195     QTest::newRow(" 1") << QByteArray(" 1") << 1.0;
2196     QTest::newRow(" \\r\\n1.2") << QByteArray(" \r\n1.2") << 1.2;
2197     QTest::newRow("3.14") << QByteArray("3.14") << 3.14;
2198     QTest::newRow("-3.14") << QByteArray("-3.14") << -3.14;
2199     QTest::newRow(" -3.14") << QByteArray(" -3.14") << -3.14;
2200     QTest::newRow("314e-02") << QByteArray("314e-02") << 3.14;
2201     QTest::newRow("314E-02") << QByteArray("314E-02") << 3.14;
2202     QTest::newRow("314e+02") << QByteArray("314e+02") << 31400.;
2203     QTest::newRow("314E+02") << QByteArray("314E+02") << 31400.;
2204 
2205     // ### add numbers with exponents
2206 
2207     if (!for_QString) {
2208         QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << 0.0;
2209         QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << 0.0;
2210     }
2211 }
2212 
2213 // ------------------------------------------------------------------------------
2214 #define IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(texttype, type) \
2215     void tst_QTextStream:: texttype##_read_operator_FromDevice_data() \
2216     { generateRealNumbersData(false); } \
2217     void tst_QTextStream:: texttype##_read_operator_FromDevice() \
2218     { \
2219         QFETCH(QByteArray, input); \
2220         QFETCH(double, output); \
2221         type sh; \
2222         QTextStream stream(&input); \
2223         stream >> sh; \
2224         QCOMPARE(sh, (type)output); \
2225     }
2226 IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(float, float)
2227 IMPLEMENT_STREAM_RIGHT_REAL_OPERATOR_TEST(double, double)
2228     ;
2229 
2230 // ------------------------------------------------------------------------------
generateStringData(bool for_QString)2231 void tst_QTextStream::generateStringData(bool for_QString)
2232 {
2233     QTest::addColumn<QByteArray>("input");
2234     QTest::addColumn<QByteArray>("array_output");
2235     QTest::addColumn<QString>("string_output");
2236 
2237     QTest::newRow("empty") << QByteArray() << QByteArray() << QString();
2238     QTest::newRow("a") << QByteArray("a") << QByteArray("a") << QString("a");
2239     QTest::newRow("a b") << QByteArray("a b") << QByteArray("a") << QString("a");
2240     QTest::newRow(" a b") << QByteArray(" a b") << QByteArray("a") << QString("a");
2241     QTest::newRow("a1") << QByteArray("a1") << QByteArray("a1") << QString("a1");
2242     QTest::newRow("a1 b1") << QByteArray("a1 b1") << QByteArray("a1") << QString("a1");
2243     QTest::newRow(" a1 b1") << QByteArray(" a1 b1") << QByteArray("a1") << QString("a1");
2244     QTest::newRow("\\n\\n\\nole i dole\\n") << QByteArray("\n\n\nole i dole\n") << QByteArray("ole") << QString("ole");
2245 
2246     if (!for_QString) {
2247         QTest::newRow("utf16-BE (empty)") << QByteArray("\xff\xfe", 2) << QByteArray() << QString();
2248         QTest::newRow("utf16-BE (corrupt)") << QByteArray("\xff", 1) << QByteArray("\xff") << QString("\xff");
2249         QTest::newRow("utf16-LE (empty)") << QByteArray("\xfe\xff", 2) << QByteArray() << QString();
2250         QTest::newRow("utf16-LE (corrupt)") << QByteArray("\xfe", 1) << QByteArray("\xfe") << QString("\xfe");
2251     }
2252 }
2253 
2254 // ------------------------------------------------------------------------------
charPtr_read_operator_FromDevice_data()2255 void tst_QTextStream::charPtr_read_operator_FromDevice_data()
2256 {
2257     generateStringData(false);
2258 }
2259 
2260 // ------------------------------------------------------------------------------
charPtr_read_operator_FromDevice()2261 void tst_QTextStream::charPtr_read_operator_FromDevice()
2262 {
2263     QFETCH(QByteArray, input);
2264     QFETCH(QByteArray, array_output);
2265 
2266     QBuffer buffer(&input);
2267     buffer.open(QBuffer::ReadOnly);
2268     QTextStream stream(&buffer);
2269     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2270     stream.setAutoDetectUnicode(true);
2271 
2272     char buf[1024];
2273     stream >> buf;
2274 
2275     QCOMPARE((const char *)buf, array_output.constData());
2276 }
2277 
2278 // ------------------------------------------------------------------------------
stringRef_read_operator_FromDevice_data()2279 void tst_QTextStream::stringRef_read_operator_FromDevice_data()
2280 {
2281     generateStringData(false);
2282 }
2283 
2284 // ------------------------------------------------------------------------------
stringRef_read_operator_FromDevice()2285 void tst_QTextStream::stringRef_read_operator_FromDevice()
2286 {
2287     QFETCH(QByteArray, input);
2288     QFETCH(QString, string_output);
2289 
2290     QBuffer buffer(&input);
2291     buffer.open(QBuffer::ReadOnly);
2292     QTextStream stream(&buffer);
2293     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2294     stream.setAutoDetectUnicode(true);
2295 
2296     QString tmp;
2297     stream >> tmp;
2298 
2299     QCOMPARE(tmp, string_output);
2300 }
2301 
2302 // ------------------------------------------------------------------------------
byteArray_read_operator_FromDevice_data()2303 void tst_QTextStream::byteArray_read_operator_FromDevice_data()
2304 {
2305     generateStringData(false);
2306 }
2307 
2308 // ------------------------------------------------------------------------------
byteArray_read_operator_FromDevice()2309 void tst_QTextStream::byteArray_read_operator_FromDevice()
2310 {
2311     QFETCH(QByteArray, input);
2312     QFETCH(QByteArray, array_output);
2313 
2314     QBuffer buffer(&input);
2315     buffer.open(QBuffer::ReadOnly);
2316     QTextStream stream(&buffer);
2317     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2318     stream.setAutoDetectUnicode(true);
2319 
2320     QByteArray array;
2321     stream >> array;
2322 
2323     QCOMPARE(array, array_output);
2324 }
2325 
2326 // ------------------------------------------------------------------------------
2327 #define IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(texttype, type) \
2328     void tst_QTextStream:: texttype##_write_operator_ToDevice() \
2329     { \
2330         QFETCH(qulonglong, number); \
2331         QFETCH(QByteArray, data); \
2332         \
2333         QBuffer buffer; \
2334         buffer.open(QBuffer::WriteOnly); \
2335         QTextStream stream(&buffer); \
2336         stream << (type)number; \
2337         stream.flush(); \
2338         \
2339         QCOMPARE(buffer.data().constData(), data.constData()); \
2340     }
2341 
2342 // ------------------------------------------------------------------------------
signedShort_write_operator_ToDevice_data()2343 void tst_QTextStream::signedShort_write_operator_ToDevice_data()
2344 {
2345     QTest::addColumn<qulonglong>("number");
2346     QTest::addColumn<QByteArray>("data");
2347 
2348     QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
2349     QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
2350     QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("-1");
2351     QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
2352     QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("-32768");
2353     QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("-32767");
2354     QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("-1");
2355     QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("0");
2356     QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("1");
2357 }
2358 IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedShort, signed short)
2359     ;
2360 
2361 // ------------------------------------------------------------------------------
unsignedShort_write_operator_ToDevice_data()2362 void tst_QTextStream::unsignedShort_write_operator_ToDevice_data()
2363 {
2364     QTest::addColumn<qulonglong>("number");
2365     QTest::addColumn<QByteArray>("data");
2366 
2367     QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
2368     QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
2369     QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("65535");
2370     QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
2371     QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
2372     QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
2373     QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
2374     QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("0");
2375     QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("1");
2376 }
2377 IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedShort, unsigned short)
2378     ;
2379 
2380 // ------------------------------------------------------------------------------
signedInt_write_operator_ToDevice_data()2381 void tst_QTextStream::signedInt_write_operator_ToDevice_data()
2382 {
2383     QTest::addColumn<qulonglong>("number");
2384     QTest::addColumn<QByteArray>("data");
2385 
2386     QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
2387     QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
2388     QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("-1");
2389     QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
2390     QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
2391     QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
2392     QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
2393     QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
2394     QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
2395     QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
2396     QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("-2147483648");
2397     QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("-2147483647");
2398     QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("-1");
2399     QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("0");
2400     QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("1");
2401 }
2402 IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(signedInt, signed int)
2403     ;
2404 
2405 // ------------------------------------------------------------------------------
unsignedInt_write_operator_ToDevice_data()2406 void tst_QTextStream::unsignedInt_write_operator_ToDevice_data()
2407 {
2408     QTest::addColumn<qulonglong>("number");
2409     QTest::addColumn<QByteArray>("data");
2410 
2411     QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
2412     QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
2413     QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("4294967295");
2414     QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
2415     QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
2416     QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
2417     QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
2418     QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
2419     QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
2420     QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
2421     QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("2147483648");
2422     QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("2147483649");
2423     QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("4294967295");
2424     QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("0");
2425     QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("1");
2426 }
2427 IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(unsignedInt, unsigned int)
2428     ;
2429 
2430 // ------------------------------------------------------------------------------
qlonglong_write_operator_ToDevice_data()2431 void tst_QTextStream::qlonglong_write_operator_ToDevice_data()
2432 {
2433     QTest::addColumn<qulonglong>("number");
2434     QTest::addColumn<QByteArray>("data");
2435 
2436     QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
2437     QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
2438     QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("-1");
2439     QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
2440     QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
2441     QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
2442     QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
2443     QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
2444     QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
2445     QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
2446     QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("2147483648");
2447     QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("2147483649");
2448     QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("4294967295");
2449     QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("4294967296");
2450     QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("4294967297");
2451     QTest::newRow("9223372036854775807") << Q_UINT64_C(9223372036854775807) << QByteArray("9223372036854775807");
2452     QTest::newRow("9223372036854775808") << Q_UINT64_C(9223372036854775808) << QByteArray("-9223372036854775808");
2453     QTest::newRow("9223372036854775809") << Q_UINT64_C(9223372036854775809) << QByteArray("-9223372036854775807");
2454     QTest::newRow("18446744073709551615") << Q_UINT64_C(18446744073709551615) << QByteArray("-1");
2455 }
2456 IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qlonglong, qlonglong)
2457     ;
2458 
2459 // ------------------------------------------------------------------------------
qulonglong_write_operator_ToDevice_data()2460 void tst_QTextStream::qulonglong_write_operator_ToDevice_data()
2461 {
2462     QTest::addColumn<qulonglong>("number");
2463     QTest::addColumn<QByteArray>("data");
2464 
2465     QTest::newRow("0") << Q_UINT64_C(0) << QByteArray("0");
2466     QTest::newRow("1") << Q_UINT64_C(1) << QByteArray("1");
2467     QTest::newRow("-1") << Q_UINT64_C(-1) << QByteArray("18446744073709551615");
2468     QTest::newRow("32767") << Q_UINT64_C(32767) << QByteArray("32767");
2469     QTest::newRow("32768") << Q_UINT64_C(32768) << QByteArray("32768");
2470     QTest::newRow("32769") << Q_UINT64_C(32769) << QByteArray("32769");
2471     QTest::newRow("65535") << Q_UINT64_C(65535) << QByteArray("65535");
2472     QTest::newRow("65536") << Q_UINT64_C(65536) << QByteArray("65536");
2473     QTest::newRow("65537") << Q_UINT64_C(65537) << QByteArray("65537");
2474     QTest::newRow("2147483647") << Q_UINT64_C(2147483647) << QByteArray("2147483647");
2475     QTest::newRow("2147483648") << Q_UINT64_C(2147483648) << QByteArray("2147483648");
2476     QTest::newRow("2147483649") << Q_UINT64_C(2147483649) << QByteArray("2147483649");
2477     QTest::newRow("4294967295") << Q_UINT64_C(4294967295) << QByteArray("4294967295");
2478     QTest::newRow("4294967296") << Q_UINT64_C(4294967296) << QByteArray("4294967296");
2479     QTest::newRow("4294967297") << Q_UINT64_C(4294967297) << QByteArray("4294967297");
2480     QTest::newRow("9223372036854775807") << Q_UINT64_C(9223372036854775807) << QByteArray("9223372036854775807");
2481     QTest::newRow("9223372036854775808") << Q_UINT64_C(9223372036854775808) << QByteArray("9223372036854775808");
2482     QTest::newRow("9223372036854775809") << Q_UINT64_C(9223372036854775809) << QByteArray("9223372036854775809");
2483     QTest::newRow("18446744073709551615") << Q_UINT64_C(18446744073709551615) << QByteArray("18446744073709551615");
2484 }
2485 IMPLEMENT_STREAM_LEFT_INT_OPERATOR_TEST(qulonglong, qulonglong)
2486     ;
2487 
2488 
2489 // ------------------------------------------------------------------------------
generateRealNumbersDataWrite()2490 void tst_QTextStream::generateRealNumbersDataWrite()
2491 {
2492     QTest::addColumn<double>("number");
2493     QTest::addColumn<QByteArray>("data");
2494 
2495     QTest::newRow("0") << 0.0 << QByteArray("0");
2496     QTest::newRow("3.14") << 3.14 << QByteArray("3.14");
2497     QTest::newRow("-3.14") << -3.14 << QByteArray("-3.14");
2498     QTest::newRow("1.2e+10") << 1.2e+10 << QByteArray("1.2e+10");
2499     QTest::newRow("-1.2e+10") << -1.2e+10 << QByteArray("-1.2e+10");
2500 }
2501 
2502 // ------------------------------------------------------------------------------
2503 #define IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(texttype, type) \
2504     void tst_QTextStream:: texttype##_write_operator_ToDevice_data() \
2505     { generateRealNumbersDataWrite(); } \
2506     void tst_QTextStream:: texttype##_write_operator_ToDevice() \
2507     { \
2508         QFETCH(double, number); \
2509         QFETCH(QByteArray, data); \
2510         \
2511         QBuffer buffer; \
2512         buffer.open(QBuffer::WriteOnly); \
2513         QTextStream stream(&buffer); \
2514         float f = (float)number; \
2515         stream << f; \
2516         stream.flush(); \
2517         QCOMPARE(buffer.data().constData(), data.constData()); \
2518     }
2519 IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(float, float)
2520 IMPLEMENT_STREAM_LEFT_REAL_OPERATOR_TEST(double, float)
2521     ;
2522 
2523 // ------------------------------------------------------------------------------
string_write_operator_ToDevice_data()2524 void tst_QTextStream::string_write_operator_ToDevice_data()
2525 {
2526     QTest::addColumn<QByteArray>("bytedata");
2527     QTest::addColumn<QString>("stringdata");
2528     QTest::addColumn<QByteArray>("result");
2529 
2530     QTest::newRow("empty") << QByteArray("", 1) << QString(1, '\0') << QByteArray("", 1);
2531     QTest::newRow("a") << QByteArray("a") << QString("a") << QByteArray("a");
2532     QTest::newRow("a cow jumped over the moon")
2533         << QByteArray("a cow jumped over the moon")
2534         << QString("a cow jumped over the moon")
2535         << QByteArray("a cow jumped over the moon");
2536 
2537     // ### get the utf16-be test on its legs.
2538     /*
2539     QTest::newRow("utf16-BE (a cow jumped over the moon)")
2540         << 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)
2541         << QString("a cow jumped over the moon")
2542         << QByteArray("a cow jumped over the moon");
2543     */
2544 }
2545 
2546 // ------------------------------------------------------------------------------
string_write_operator_ToDevice()2547 void tst_QTextStream::string_write_operator_ToDevice()
2548 {
2549     QFETCH(QByteArray, bytedata);
2550     QFETCH(QString, stringdata);
2551     QFETCH(QByteArray, result);
2552 
2553     {
2554         // char*
2555         QBuffer buf;
2556         buf.open(QBuffer::WriteOnly);
2557         QTextStream stream(&buf);
2558         stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2559         stream.setAutoDetectUnicode(true);
2560 
2561         stream << bytedata.constData();
2562         stream.flush();
2563         QCOMPARE(buf.buffer().constData(), result.constData());
2564     }
2565     {
2566         // QByteArray
2567         QBuffer buf;
2568         buf.open(QBuffer::WriteOnly);
2569         QTextStream stream(&buf);
2570         stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2571         stream.setAutoDetectUnicode(true);
2572 
2573         stream << bytedata;
2574         stream.flush();
2575         QCOMPARE(buf.buffer().constData(), result.constData());
2576     }
2577     {
2578         // QString
2579         QBuffer buf;
2580         buf.open(QBuffer::WriteOnly);
2581         QTextStream stream(&buf);
2582         stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2583         stream.setAutoDetectUnicode(true);
2584 
2585         stream << stringdata;
2586         stream.flush();
2587         QCOMPARE(buf.buffer().constData(), result.constData());
2588     }
2589 }
2590 
2591 // ------------------------------------------------------------------------------
useCase1()2592 void tst_QTextStream::useCase1()
2593 {
2594     QFile::remove("testfile");
2595     QFile file("testfile");
2596     QVERIFY(file.open(QFile::ReadWrite));
2597 
2598     {
2599         QTextStream stream(&file);
2600         stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2601         stream.setAutoDetectUnicode(true);
2602 
2603         stream << 4.15 << " " << QByteArray("abc") << " " << QString("ole");
2604     }
2605 
2606     file.seek(0);
2607     QCOMPARE(file.readAll(), QByteArray("4.15 abc ole"));
2608     file.seek(0);
2609 
2610     {
2611         double d;
2612         QByteArray a;
2613         QString s;
2614         QTextStream stream(&file);
2615         stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2616         stream.setAutoDetectUnicode(true);
2617 
2618         stream >> d;
2619         stream >> a;
2620         stream >> s;
2621 
2622         QCOMPARE(d, 4.15);
2623         QCOMPARE(a, QByteArray("abc"));
2624         QCOMPARE(s, QString("ole"));
2625     }
2626 }
2627 
2628 // ------------------------------------------------------------------------------
useCase2()2629 void tst_QTextStream::useCase2()
2630 {
2631     QFile::remove("testfile");
2632     QFile file("testfile");
2633     QVERIFY(file.open(QFile::ReadWrite));
2634 
2635     QTextStream stream(&file);
2636     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2637     stream.setAutoDetectUnicode(true);
2638 
2639     stream << 4.15 << " " << QByteArray("abc") << " " << QString("ole");
2640 
2641     file.close();
2642     QVERIFY(file.open(QFile::ReadWrite));
2643 
2644     QCOMPARE(file.readAll(), QByteArray("4.15 abc ole"));
2645 
2646     file.close();
2647     QVERIFY(file.open(QFile::ReadWrite));
2648 
2649     double d;
2650     QByteArray a;
2651     QString s;
2652     QTextStream stream2(&file);
2653     stream2.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2654     stream2.setAutoDetectUnicode(true);
2655 
2656     stream2 >> d;
2657     stream2 >> a;
2658     stream2 >> s;
2659 
2660     QCOMPARE(d, 4.15);
2661     QCOMPARE(a, QByteArray("abc"));
2662     QCOMPARE(s, QString("ole"));
2663 }
2664 
2665 // ------------------------------------------------------------------------------
manipulators_data()2666 void tst_QTextStream::manipulators_data()
2667 {
2668     QTest::addColumn<int>("flags");
2669     QTest::addColumn<int>("width");
2670     QTest::addColumn<double>("realNumber");
2671     QTest::addColumn<int>("intNumber");
2672     QTest::addColumn<QString>("textData");
2673     QTest::addColumn<QByteArray>("result");
2674 
2675     QTest::newRow("no flags") << 0 << 0  << 5.0 << 5 << QString("five") << QByteArray("55five");
2676     QTest::newRow("rightadjust") << 0 << 10 << 5.0 << 5 << QString("five") << QByteArray("         5         5      five");
2677 
2678     // ### FIX
2679 //    QTest::newRow("leftadjust") << int(QTextStream::left) << 10 << 5.0 << 5 << QString("five") << QByteArray("5         5         five      ");
2680 //    QTest::newRow("showpos") << int(QTextStream::showpos) << 10 << 5.0 << 5 << QString("five") << QByteArray("        +5        +5      five");
2681 //    QTest::newRow("showpos2") << int(QTextStream::showpos) << 5 << 3.14 << -5 << QString("five") << QByteArray("+3.14   -5 five");
2682 //    QTest::newRow("hex") << int(QTextStream::hex | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0x5 five");
2683 //    QTest::newRow("hex uppercase") << int(QTextStream::hex | QTextStream::uppercase | QTextStream::showbase) << 5 << 3.14 << -5 << QString("five") << QByteArray(" 3.14 -0X5 five");
2684 }
2685 
2686 // ------------------------------------------------------------------------------
manipulators()2687 void tst_QTextStream::manipulators()
2688 {
2689 //    QFETCH(int, flags);
2690     QFETCH(int, width);
2691     QFETCH(double, realNumber);
2692     QFETCH(int, intNumber);
2693     QFETCH(QString, textData);
2694     QFETCH(QByteArray, result);
2695 
2696     QBuffer buffer;
2697     buffer.open(QBuffer::WriteOnly);
2698 
2699     QTextStream stream(&buffer);
2700     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2701     stream.setAutoDetectUnicode(true);
2702 
2703 //    stream.setFlags(flags);
2704     stream.setFieldWidth(width);
2705     stream << realNumber;
2706     stream << intNumber;
2707     stream << textData;
2708     stream.flush();
2709 
2710     QCOMPARE(buffer.data().constData(), result.constData());
2711 }
2712 
generateBOM()2713 void tst_QTextStream::generateBOM()
2714 {
2715     QFile::remove("bom.txt");
2716     {
2717         QFile file("bom.txt");
2718         QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate));
2719 
2720         QTextStream stream(&file);
2721         stream.setCodec(QTextCodec::codecForName("UTF-16LE"));
2722         stream << "Hello" << endl;
2723 
2724         file.close();
2725         QVERIFY(file.open(QFile::ReadOnly));
2726         QCOMPARE(file.readAll(), QByteArray("\x48\x00\x65\00\x6c\00\x6c\00\x6f\x00\x0a\x00", 12));
2727     }
2728 
2729     QFile::remove("bom.txt");
2730     {
2731         QFile file("bom.txt");
2732         QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate));
2733 
2734         QTextStream stream(&file);
2735         stream.setCodec(QTextCodec::codecForName("UTF-16LE"));
2736         stream << bom << "Hello" << endl;
2737 
2738         file.close();
2739         QVERIFY(file.open(QFile::ReadOnly));
2740         QCOMPARE(file.readAll(), QByteArray("\xff\xfe\x48\x00\x65\00\x6c\00\x6c\00\x6f\x00\x0a\x00", 14));
2741     }
2742 }
2743 
readBomSeekBackReadBomAgain()2744 void tst_QTextStream::readBomSeekBackReadBomAgain()
2745 {
2746     QFile::remove("utf8bom");
2747     QFile file("utf8bom");
2748     QVERIFY(file.open(QFile::ReadWrite));
2749     file.write("\xef\xbb\xbf""Andreas");
2750     file.seek(0);
2751     QCOMPARE(file.pos(), qint64(0));
2752 
2753     QTextStream stream(&file);
2754     stream.setCodec("UTF-8");
2755     QString Andreas;
2756     stream >> Andreas;
2757     QCOMPARE(Andreas, QString("Andreas"));
2758     stream.seek(0);
2759     stream >> Andreas;
2760     QCOMPARE(Andreas, QString("Andreas"));
2761 }
2762 
2763 // ------------------------------------------------------------------------------
2764 // QT 3 tests
2765 // ------------------------------------------------------------------------------
2766 #ifdef QT3_SUPPORT
2767 
qt3_readLineFromString()2768 void tst_QTextStream::qt3_readLineFromString()
2769 {
2770     QString data = "line 1e\nline 2e\nline 3e";
2771     QStringList list;
2772     QTextStream stream(&data, QIODevice::ReadOnly);
2773     stream.setCodec(QTextCodec::codecForName("ISO-8859-1"));
2774     stream.setAutoDetectUnicode(true);
2775 
2776     while (!stream.atEnd()) {
2777         QString line = stream.readLine();
2778         QCOMPARE(QChar(line[line.size()-1]), QChar('e'));
2779         list << line;
2780     }
2781     QVERIFY(list.count() == 3);
2782 }
2783 
2784 // ------------------------------------------------------------------------------
qt3_operator_shiftright_data()2785 void tst_QTextStream::qt3_operator_shiftright_data()
2786 {
2787     qt3_operatorShift_data( QIODevice::ReadOnly );
2788 }
2789 
2790 // ------------------------------------------------------------------------------
qt3_operator_shiftleft_data()2791 void tst_QTextStream::qt3_operator_shiftleft_data()
2792 {
2793     qt3_operatorShift_data( QIODevice::WriteOnly );
2794 }
2795 
2796 static const double doubleDummy = 567.89;
2797 static const int intDummy = 1234;
2798 static const QString stringDummy = "ABCD";
2799 
2800 struct tst_IODevice {
2801     char *n;
2802     QIODevice::OpenModeFlag modes;
nametst_IODevice2803     QString name() const { return QString::fromLatin1(n); }
2804 } devices[] = {
2805     { "file", QIODevice::ReadWrite },
2806     { "bytearray", QIODevice::ReadWrite },
2807     { "buffer", QIODevice::ReadWrite },
2808     { "string", QIODevice::ReadWrite },
2809     { "resource", QIODevice::ReadOnly }, //See discussion (resources) below
2810     { 0, (QIODevice::OpenModeFlag)0 }
2811 };
2812 
2813 /* Resources:
2814 
2815    This will test QTextStream's ability to interact with resources,
2816    however the trouble is the resources must be created correctly and
2817    built into the executable (but this executable also creates the
2818    resource files). So there is a chicken and egg problem, to create
2819    resources (if the file formats change at all):
2820 
2821    1) p4 edit resources/...
2822 
2823    2) Change QIODevice::ReadOnly above in the devices[] for "resource"
2824       to QIODevice::WriteOnly
2825 
2826    3) run the test
2827 
2828    4) revert this file, qmake, make, and run again.
2829 
2830    5) Enjoy.
2831 */
2832 
resourceDir()2833 static inline QString resourceDir()
2834 {
2835     QString ret = "resources/";
2836     if(QSysInfo::ByteOrder == QSysInfo::BigEndian)
2837         ret += "big_endian/";
2838     else
2839         ret += "little_endian/";
2840     return ret;
2841 }
2842 
2843 static const char *const encodings[] = {
2844     "Locale",
2845     "Latin1",
2846     "Unicode",
2847     "UnicodeNetworkOrder",
2848     "UnicodeReverse",
2849     "RawUnicode",
2850     "UnicodeUTF8",
2851     0
2852 };
2853 
2854 // ------------------------------------------------------------------------------
qt3_operatorShift_data(QIODevice::OpenMode mode)2855 void tst_QTextStream::qt3_operatorShift_data( QIODevice::OpenMode mode )
2856 {
2857     QTest::addColumn<QString>("device");
2858     QTest::addColumn<QString>("encoding");
2859     QTest::addColumn<QString>("type");
2860     QTest::addColumn<double>("doubleVal");
2861     QTest::addColumn<int>("intVal");
2862     QTest::addColumn<QString>("stringVal");
2863     QTest::addColumn<QByteArray>("encoded");
2864 
2865     for ( int i=0; !devices[i].name().isNull(); i++ ) {
2866         tst_IODevice *device = devices+i;
2867         if(!(device->modes & mode))
2868             continue;
2869 
2870 	/*
2871 	  We first test each type at least once.
2872 	*/
2873 	QTest::newRow( device->name() + "0" ) << device->name() << QString("UnicodeUTF8") << QString("QChar")
2874 		<< doubleDummy << (int) 'Z' << stringDummy
2875 		<< QByteArray( QByteArray("Z") );
2876 	QTest::newRow( device->name() + "1" ) << device->name() << QString("UnicodeUTF8") << QString("char")
2877 		<< doubleDummy << (int) 'Z' << stringDummy
2878 		<< QByteArray( QByteArray("Z") );
2879 	QTest::newRow( device->name() + "2" ) << device->name() << QString("UnicodeUTF8") << QString("signed short")
2880 		<< doubleDummy << 12345 << stringDummy
2881 		<< QByteArray( QByteArray("12345") );
2882 	QTest::newRow( device->name() + "3" ) << device->name() << QString("UnicodeUTF8") << QString("unsigned short")
2883 		<< doubleDummy << 12345 << stringDummy
2884 		<< QByteArray( QByteArray("12345") );
2885 	QTest::newRow( device->name() + "4" ) << device->name() << QString("UnicodeUTF8") << QString("signed int")
2886 		<< doubleDummy << 12345 << stringDummy
2887 		<< QByteArray( QByteArray("12345") );
2888 	QTest::newRow( device->name() + "5" ) << device->name() << QString("UnicodeUTF8") << QString("unsigned int")
2889 		<< doubleDummy << 12345 << stringDummy
2890 		<< QByteArray( QByteArray("12345") );
2891 	QTest::newRow( device->name() + "6" ) << device->name() << QString("UnicodeUTF8") << QString("signed long")
2892 		<< doubleDummy << 12345 << stringDummy
2893 		<< QByteArray( QByteArray("12345") );
2894 	QTest::newRow( device->name() + "7" ) << device->name() << QString("UnicodeUTF8") << QString("unsigned long")
2895 		<< doubleDummy << 12345 << stringDummy
2896 		<< QByteArray( QByteArray("12345") );
2897 	QTest::newRow( device->name() + "8" ) << device->name() << QString("UnicodeUTF8") << QString("float")
2898 		<< (double)3.1415f << intDummy << stringDummy
2899 		<< QByteArray( QByteArray("3.1415") );
2900 	QTest::newRow( device->name() + "9" ) << device->name() << QString("UnicodeUTF8") << QString("double")
2901 		<< 3.1415 << intDummy << stringDummy
2902 		<< QByteArray( QByteArray("3.1415") );
2903 	QTest::newRow( device->name() + "10" ) << device->name() << QString("UnicodeUTF8") << QString("char *")
2904 		<< doubleDummy << intDummy << QString("I-am-a-string")
2905 		<< QByteArray( QByteArray("I-am-a-string") );
2906 	QTest::newRow( device->name() + "11" ) << device->name() << QString("UnicodeUTF8") << QString("QString")
2907 		<< doubleDummy << intDummy << QString("I-am-a-string")
2908 		<< QByteArray( QByteArray("I-am-a-string") );
2909 	QTest::newRow( device->name() + "12" ) << device->name() << QString("UnicodeUTF8") << QString("QByteArray")
2910 		<< doubleDummy << intDummy << QString("I-am-a-string")
2911 		<< QByteArray( QByteArray("I-am-a-string") );
2912 
2913 	/*
2914 	  Then we test some special cases that have caused problems in the past.
2915 	*/
2916 	QTest::newRow( device->name() + "20" ) << device->name() << QString("UnicodeUTF8") << QString("QChar")
2917 		<< doubleDummy << 0xff8c << stringDummy
2918 		<< QByteArray( QByteArray("\xef\xbe\x8c") );
2919 	QTest::newRow( device->name() + "21" ) << device->name() << QString("UnicodeUTF8") << QString("QChar")
2920 		<< doubleDummy << 0x8cff << stringDummy
2921 		<< QByteArray( QByteArray("\xe8\xb3\xbf") );
2922     }
2923 }
2924 
2925 // ------------------------------------------------------------------------------
qt3_do_shiftleft(QTextStream * ts)2926 void tst_QTextStream::qt3_do_shiftleft( QTextStream *ts )
2927 {
2928     QFETCH( QString, encoding );
2929     QFETCH( QString, type );
2930     QFETCH( double,  doubleVal );
2931     QFETCH( int, intVal );
2932     QFETCH( QString,  stringVal );
2933 
2934     ts->setEncoding( qt3_toEncoding(encoding) );
2935 
2936     if ( type == "QChar" ) {
2937 	if ( intVal >= 0 && intVal <= 0xffff )
2938 	    *ts << QChar( intVal );
2939     } else if ( type == "char" ) {
2940 	*ts << (char) intVal;
2941     } else if ( type == "signed short" ) {
2942 	*ts << (signed short) intVal;
2943     } else if ( type == "unsigned short" ) {
2944 	*ts << (unsigned short) intVal;
2945     } else if ( type == "signed int" ) {
2946 	*ts << (signed int) intVal;
2947     } else if ( type == "unsigned int" ) {
2948 	*ts << (unsigned int) intVal;
2949     } else if ( type == "signed long" ) {
2950 	*ts << (signed long) intVal;
2951     } else if ( type == "unsigned long" ) {
2952 	*ts << (unsigned long) intVal;
2953     } else if ( type == "float" ) {
2954 	*ts << (float) doubleVal;
2955     } else if ( type == "double" ) {
2956 	*ts << (double) doubleVal;
2957     } else if ( type == "char *" ) {
2958 	*ts << stringVal.latin1();
2959     } else if ( type == "QString" ) {
2960 	*ts << stringVal;
2961     } else if ( type == "QByteArray" ) {
2962 	*ts << QByteArray( stringVal.latin1() );
2963     } else {
2964 	QWARN( "Unknown type: %s" + type );
2965     }
2966 
2967     ts->flush();
2968 }
2969 
2970 // ------------------------------------------------------------------------------
qt3_operator_shiftleft()2971 void tst_QTextStream::qt3_operator_shiftleft()
2972 {
2973     QFETCH( QString, device );
2974     QFETCH( QString, encoding );
2975     QFETCH( QByteArray, encoded );
2976 
2977     if ( device == "file" ) {
2978 	QFile outFile( "qtextstream.out" );
2979 	QVERIFY( outFile.open( QIODevice::WriteOnly ) );
2980 	QTextStream ts( &outFile );
2981 
2982 	qt3_do_shiftleft( &ts );
2983 	outFile.close();
2984 
2985 	QFile inFile( "qtextstream.out" );
2986 	QVERIFY( inFile.open( QIODevice::ReadOnly ) );
2987         QCOMPARE( inFile.readAll().constData(), encoded.constData() );
2988     } else if(device == "resource" ) { //ONLY TO CREATE THE RESOURCE!! NOT A TEST!
2989 	QFile outFile( resourceDir() + "operator_shiftright_" + QTest::currentDataTag() + ".data" );
2990 	QVERIFY( outFile.open( QIODevice::WriteOnly ) );
2991 	QTextStream ts( &outFile );
2992 	qt3_do_shiftleft( &ts );
2993 	outFile.close();
2994     } else if ( device == "bytearray" ) {
2995 	QByteArray outArray;
2996 	QTextStream ts(&outArray, QIODevice::WriteOnly );
2997 
2998 	qt3_do_shiftleft( &ts );
2999 
3000 	QVERIFY( outArray == encoded );
3001     } else if ( device == "buffer" ) {
3002 	QByteArray outArray;
3003 	QBuffer outBuffer(&outArray);
3004 	QVERIFY( outBuffer.open(QIODevice::WriteOnly) );
3005 	QTextStream ts( &outBuffer );
3006 
3007 	qt3_do_shiftleft( &ts );
3008 
3009 	QCOMPARE( outArray, encoded );
3010     } else if ( device == "string" ) {
3011 	QString outString;
3012 	QTextStream ts( &outString, QIODevice::WriteOnly );
3013 
3014 	qt3_do_shiftleft( &ts );
3015 
3016 	QString decodedString = qt3_decodeString( encoded, encoding );
3017 	QCOMPARE( outString, decodedString );
3018     } else {
3019 	QWARN( "Unknown device type: " + device );
3020     }
3021 }
3022 
3023 // ------------------------------------------------------------------------------
qt3_operator_shiftright()3024 void tst_QTextStream::qt3_operator_shiftright()
3025 {
3026     QFETCH( QString, device );
3027     QFETCH( QString, encoding );
3028     QFETCH( QString, type );
3029     QFETCH( double,  doubleVal );
3030     QFETCH( int, intVal );
3031     QFETCH( QString,  stringVal );
3032     QFETCH( QByteArray, encoded );
3033 
3034     if ( device == "file" ) {
3035 	QFile outFile( "qtextstream.out" );
3036 	QVERIFY( outFile.open( QIODevice::WriteOnly ) );
3037 	QVERIFY( (int) outFile.write(encoded) == (int) encoded.size() );
3038 	outFile.close();
3039 
3040 	inFile = new QFile( "qtextstream.out" );
3041 	QVERIFY( inFile->open( QIODevice::ReadOnly ) );
3042 	ts = new QTextStream( inFile );
3043     } else if(device == "resource" ) {
3044 	inResource = new QFile( ":/tst_textstream/" + resourceDir() + "operator_shiftright_" + QTest::currentDataTag() + ".data" );
3045 	QVERIFY( inResource->open( QIODevice::ReadOnly ) );
3046 	ts = new QTextStream( inResource );
3047     } else if ( device == "bytearray" ) {
3048 	ts = new QTextStream(&encoded, QIODevice::ReadOnly);
3049     } else if ( device == "buffer" ) {
3050 	inBuffer = new QBuffer(&encoded);
3051 	QVERIFY( inBuffer->open(QIODevice::ReadOnly) );
3052 	ts = new QTextStream( inBuffer );
3053     } else if ( device == "string" ) {
3054 	inString = new QString( qt3_decodeString(encoded, encoding) );
3055 	ts = new QTextStream(inString, QIODevice::ReadOnly);
3056     } else {
3057 	QWARN( "Unknown device type: " + device );
3058     }
3059 
3060     ts->setEncoding( qt3_toEncoding(encoding) );
3061 
3062     if ( type == "QChar" ) {
3063 	QChar c;
3064 	if ( intVal >= 0 && intVal <= 0xffff )
3065 	    *ts >> c;
3066 	QCOMPARE( c.toLatin1(), QChar(intVal).toLatin1() );
3067     } else if ( type == "char" ) {
3068 	char c;
3069 	*ts >> c;
3070 	QCOMPARE( c, (char) intVal );
3071     } else if ( type == "signed short" ) {
3072 	signed short h;
3073 	*ts >> h;
3074 	QCOMPARE( h, (signed short) intVal );
3075     } else if ( type == "unsigned short" ) {
3076 	unsigned short h;
3077 	*ts >> h;
3078 	QCOMPARE( h, (unsigned short) intVal );
3079     } else if ( type == "signed int" ) {
3080 	signed int i;
3081 	*ts >> i;
3082 	QCOMPARE( i, (signed int) intVal );
3083     } else if ( type == "unsigned int" ) {
3084 	unsigned int i;
3085 	*ts >> i;
3086 	QCOMPARE( i, (unsigned int) intVal );
3087     } else if ( type == "signed long" ) {
3088 	signed long ell;
3089 	*ts >> ell;
3090 	QCOMPARE( ell, (signed long) intVal );
3091     } else if ( type == "unsigned long" ) {
3092 	unsigned long ell;
3093 	*ts >> ell;
3094 	QCOMPARE( ell, (unsigned long) intVal );
3095     } else if ( type == "float" ) {
3096 	float f;
3097 	*ts >> f;
3098 	QCOMPARE( f, (float) doubleVal );
3099     } else if ( type == "double" ) {
3100 	double d;
3101 	*ts >> d;
3102 	QCOMPARE( d, (double) doubleVal );
3103     } else if ( type == "char *" ) {
3104 	char *cp = new char[2048];
3105 	*ts >> cp;
3106 	QVERIFY( qstrcmp(cp, stringVal.latin1()) == 0 );
3107 	delete[] cp;
3108     } else if ( type == "QString" ) {
3109 	QString s;
3110 	*ts >> s;
3111 	QCOMPARE( s, stringVal );
3112     } else if ( type == "QByteArray" ) {
3113 	QByteArray s;
3114 	*ts >> s;
3115 	QCOMPARE( QString::fromLatin1(s), stringVal );
3116     } else {
3117 	QWARN( "Unknown type: %s" + type );
3118     }
3119 }
3120 
3121 // ------------------------------------------------------------------------------
qt3_toEncoding(const QString & str)3122 QTextStream::Encoding tst_QTextStream::qt3_toEncoding( const QString &str )
3123 {
3124     if ( str == "Locale" )
3125 	return QTextStream::Locale;
3126     else if ( str == "Latin1" )
3127 	return QTextStream::Latin1;
3128     else if ( str == "Unicode" )
3129 	return QTextStream::Unicode;
3130     else if ( str == "UnicodeNetworkOrder" )
3131 	return QTextStream::UnicodeNetworkOrder;
3132     else if ( str == "UnicodeReverse" )
3133 	return QTextStream::UnicodeReverse;
3134     else if ( str == "RawUnicode" )
3135 	return QTextStream::RawUnicode;
3136     else if ( str == "UnicodeUTF8" )
3137 	return QTextStream::UnicodeUTF8;
3138 
3139     QWARN( "No such encoding " + str );
3140     return QTextStream::Latin1;
3141 }
3142 
3143 // ------------------------------------------------------------------------------
qt3_decodeString(QByteArray array,const QString & encoding)3144 QString tst_QTextStream::qt3_decodeString( QByteArray array, const QString& encoding )
3145 {
3146     switch ( qt3_toEncoding(encoding) ) {
3147     case QTextStream::Locale:
3148 	return QString::fromLocal8Bit( array.data(), array.size() );
3149     case QTextStream::Latin1:
3150 	return QString::fromLatin1( array.data(), array.size() );
3151     case QTextStream::Unicode:
3152     case QTextStream::UnicodeNetworkOrder:
3153     case QTextStream::UnicodeReverse:
3154     case QTextStream::RawUnicode:
3155 	QWARN( "Unicode not implemented ###" );
3156 	return QString();
3157     case QTextStream::UnicodeUTF8:
3158 	return QString::fromUtf8( array.data(), array.size() );
3159     default:
3160 	QWARN( "Unhandled encoding" );
3161 	return QString();
3162     }
3163 }
3164 
3165 // ************************************************
3166 
3167 // ------------------------------------------------------------------------------
qt3_createWriteStream(QTextStream * & os)3168 void tst_QTextStream::qt3_createWriteStream( QTextStream *&os )
3169 {
3170     QFETCH( QString, device );
3171 
3172     if ( device == "file" ) {
3173 	outFile = new QFile( "qtextstream.out" );
3174 	QVERIFY( outFile->open( QIODevice::WriteOnly ) );
3175 	os = new QTextStream( outFile );
3176         os->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3177         os->setAutoDetectUnicode(true);
3178     } else if(device == "resource" ) { //ONLY TO CREATE THE RESOURCE!! NOT A TEST!
3179 	outFile = new QFile( resourceDir() +
3180                              QTest::currentTestFunction() +
3181                              "_" + QTest::currentDataTag() + ".data" );
3182 	QVERIFY( outFile->open( QIODevice::WriteOnly ) );
3183 	os = new QTextStream( outFile );
3184         os->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3185         os->setAutoDetectUnicode(true);
3186     } else if ( device == "bytearray" ) {
3187 	inArray = new QByteArray;
3188 	os = new QTextStream(inArray, QIODevice::WriteOnly);
3189         os->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3190         os->setAutoDetectUnicode(true);
3191     } else if ( device == "buffer" ) {
3192 	inBuffer = new QBuffer;
3193 	QVERIFY( inBuffer->open(QIODevice::WriteOnly) );
3194 	os = new QTextStream( inBuffer );
3195         os->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3196         os->setAutoDetectUnicode(true);
3197     } else if ( device == "string" ) {
3198 	inString = new QString;
3199 	os = new QTextStream( inString, QIODevice::WriteOnly );
3200         os->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3201         os->setAutoDetectUnicode(true);
3202     } else {
3203 	QWARN( "Error creating write stream: Unknown device type '" + device + "'" );
3204     }
3205 
3206     QFETCH( QString, encoding );
3207     os->setEncoding( qt3_toEncoding( encoding ));
3208 }
3209 
3210 // ------------------------------------------------------------------------------
qt3_closeWriteStream(QTextStream * os)3211 void tst_QTextStream::qt3_closeWriteStream( QTextStream *os )
3212 {
3213     QFETCH( QString, device );
3214 
3215     os->flush();
3216     if ( os->device() )
3217 	os->device()->close();
3218 }
3219 
3220 // ------------------------------------------------------------------------------
qt3_createReadStream(QTextStream * & is)3221 void tst_QTextStream::qt3_createReadStream( QTextStream *&is )
3222 {
3223     QFETCH( QString, device );
3224 
3225     if ( device == "file" ) {
3226 	inFile = new QFile( "qtextstream.out" );
3227 	is = new QTextStream( inFile );
3228         is->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3229         is->setAutoDetectUnicode(true);
3230 	QVERIFY( inFile->open( QIODevice::ReadOnly ) );
3231     } else if(device == "resource") {
3232 	inResource = new QFile( ":/tst_textstream/" + resourceDir() +
3233                                 QTest::currentTestFunction() +
3234                                 "_" + QTest::currentDataTag() + ".data" );
3235 	is = new QTextStream( inResource );
3236         is->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3237         is->setAutoDetectUnicode(true);
3238 	QVERIFY( inResource->open( QIODevice::ReadOnly ) );
3239     } else if ( device == "bytearray" ) {
3240 	is = new QTextStream(inArray, QIODevice::ReadOnly);
3241         is->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3242         is->setAutoDetectUnicode(true);
3243     } else if ( device == "buffer" ) {
3244 	QVERIFY( inBuffer->open(QIODevice::ReadOnly) );
3245 	is = new QTextStream( inBuffer );
3246         is->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3247         is->setAutoDetectUnicode(true);
3248     } else if ( device == "string" ) {
3249 	is = new QTextStream( inString, QIODevice::ReadOnly );
3250         is->setCodec(QTextCodec::codecForName("ISO-8859-1"));
3251         is->setAutoDetectUnicode(true);
3252     } else {
3253 	QWARN( "Error creating read stream: Unknown device type '" + device + "'" );
3254     }
3255 
3256     QFETCH( QString, encoding );
3257     is->setEncoding( qt3_toEncoding( encoding ));
3258 
3259     if (!file_is_empty) {
3260 	QVERIFY( !is->atEnd() );
3261     }
3262 }
3263 
3264 // ------------------------------------------------------------------------------
qt3_closeReadStream(QTextStream * is)3265 void tst_QTextStream::qt3_closeReadStream( QTextStream *is )
3266 {
3267     QVERIFY( is->atEnd() );
3268 
3269     if ( is->device() )
3270 	is->device()->close();
3271 }
3272 
3273 // **************** QChar ****************
3274 
3275 // ------------------------------------------------------------------------------
qt3_operator_shift_QChar_data()3276 void tst_QTextStream::qt3_operator_shift_QChar_data()
3277 {
3278     QTest::addColumn<int>("modes");
3279     QTest::addColumn<QString>("device");
3280     QTest::addColumn<QString>("encoding");
3281     QTest::addColumn<ushort>("qchar");
3282 
3283     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3284         tst_IODevice *device = devices+i;
3285 	for ( int e=0; encodings[e] != 0; e++ ) {
3286 	    QString encoding = encodings[e];
3287 
3288 	    QString tag = device->name() + "_" + encoding + "_";
3289 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << QChar( 'A' ).unicode();
3290 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << QChar( 'B' ).unicode();
3291 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << QChar( 'Z' ).unicode();
3292 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << QChar( 'z' ).unicode();
3293 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << QChar( '@' ).unicode();
3294 	}
3295     }
3296 }
3297 
3298 // ------------------------------------------------------------------------------
qt3_operator_shift_QChar()3299 void tst_QTextStream::qt3_operator_shift_QChar()
3300 {
3301     QFETCH( int, modes );
3302     if(modes & QIODevice::WriteOnly) {
3303         qt3_createWriteStream( os );
3304         qt3_write_QChar( os );
3305         qt3_closeWriteStream( os );
3306     }
3307     if(modes & QIODevice::ReadOnly) {
3308         qt3_createReadStream( is );
3309         qt3_read_QChar( is );
3310         qt3_closeReadStream( is );
3311     }
3312 }
3313 
3314 // ------------------------------------------------------------------------------
qt3_read_QChar(QTextStream * s)3315 void tst_QTextStream::qt3_read_QChar( QTextStream *s )
3316 {
3317     QFETCH( ushort, qchar );
3318     QChar expected( qchar );
3319     QChar actual;
3320     *s >> actual;
3321     QCOMPARE( actual, expected );
3322 }
3323 
3324 // ------------------------------------------------------------------------------
qt3_write_QChar(QTextStream * s)3325 void tst_QTextStream::qt3_write_QChar( QTextStream *s )
3326 {
3327     QFETCH( ushort, qchar );
3328     QChar actual( qchar );
3329     *s << actual;
3330 }
3331 
3332 // **************** char ****************
3333 
3334 // ------------------------------------------------------------------------------
qt3_operator_shift_char_data()3335 void tst_QTextStream::qt3_operator_shift_char_data()
3336 {
3337     QTest::addColumn<int>("modes");
3338     QTest::addColumn<QString>("device");
3339     QTest::addColumn<QString>("encoding");
3340     QTest::addColumn<int>("ch");
3341 
3342     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3343         tst_IODevice *device = devices+i;
3344 	for ( int e=0; encodings[e] != 0; e++ ) {
3345 	    QString encoding = encodings[e];
3346 
3347 	    QString tag = device->name() + "_" + encoding + "_";
3348 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << int('A');
3349 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << int('B');
3350 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << int('Z');
3351 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << int(14);
3352 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << int('0');
3353 	}
3354     }
3355 }
3356 
3357 // ------------------------------------------------------------------------------
qt3_operator_shift_char()3358 void tst_QTextStream::qt3_operator_shift_char()
3359 {
3360     QFETCH( int, modes );
3361     if(modes & QIODevice::WriteOnly) {
3362         qt3_createWriteStream( os );
3363         qt3_write_char( os );
3364         qt3_closeWriteStream( os );
3365     }
3366     if(modes & QIODevice::ReadOnly) {
3367         qt3_createReadStream( is );
3368         qt3_read_char( is );
3369         qt3_closeReadStream( is );
3370     }
3371 }
3372 
3373 // ------------------------------------------------------------------------------
qt3_read_char(QTextStream * s)3374 void tst_QTextStream::qt3_read_char( QTextStream *s )
3375 {
3376     QFETCH( int, ch );
3377     char c(ch);
3378     char exp;
3379     *s >> exp;
3380     QCOMPARE( exp, c );
3381 }
3382 
3383 // ------------------------------------------------------------------------------
qt3_write_char(QTextStream * s)3384 void tst_QTextStream::qt3_write_char( QTextStream *s )
3385 {
3386     QFETCH( int, ch );
3387     char c(ch);
3388     *s << c;
3389 }
3390 
3391 // **************** short ****************
3392 
3393 // ------------------------------------------------------------------------------
qt3_operator_shift_short_data()3394 void tst_QTextStream::qt3_operator_shift_short_data()
3395 {
3396     QTest::addColumn<int>("modes");
3397     QTest::addColumn<QString>("device");
3398     QTest::addColumn<QString>("encoding");
3399     QTest::addColumn<short>("ss");
3400 
3401     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3402         tst_IODevice *device = devices+i;
3403 	for ( int e=0; encodings[e] != 0; e++ ) {
3404 	    QString encoding = encodings[e];
3405 
3406 	    QString tag = device->name() + "_" + encoding + "_";
3407 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << short(0);
3408 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << short(-1);
3409 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << short(1);
3410 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << short(255);
3411 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << short(-254);
3412 	}
3413     }
3414 }
3415 
3416 // ------------------------------------------------------------------------------
qt3_operator_shift_short()3417 void tst_QTextStream::qt3_operator_shift_short()
3418 {
3419     QFETCH( int, modes );
3420     if(modes & QIODevice::WriteOnly) {
3421         qt3_createWriteStream( os );
3422         qt3_write_short( os );
3423         qt3_closeWriteStream( os );
3424     }
3425     if(modes & QIODevice::ReadOnly) {
3426         qt3_createReadStream( is );
3427         qt3_read_short( is );
3428         qt3_closeReadStream( is );
3429     }
3430 }
3431 
3432 // ------------------------------------------------------------------------------
qt3_read_short(QTextStream * s)3433 void tst_QTextStream::qt3_read_short( QTextStream *s )
3434 {
3435     QFETCH( short, ss );
3436     short exp;
3437     QString A, B;
3438     *s >> A >> exp >> B;
3439     QCOMPARE( A, QString("A") );
3440     QCOMPARE( B, QString("B") );
3441     QCOMPARE( exp, ss );
3442     s->skipWhiteSpace();
3443 }
3444 
3445 // ------------------------------------------------------------------------------
qt3_write_short(QTextStream * s)3446 void tst_QTextStream::qt3_write_short( QTextStream *s )
3447 {
3448     QFETCH( short, ss );
3449     *s << " A " << ss << " B ";
3450 }
3451 
3452 // **************** ushort ****************
3453 
3454 // ------------------------------------------------------------------------------
qt3_operator_shift_ushort_data()3455 void tst_QTextStream::qt3_operator_shift_ushort_data()
3456 {
3457     QTest::addColumn<int>("modes");
3458     QTest::addColumn<QString>("device");
3459     QTest::addColumn<QString>("encoding");
3460     QTest::addColumn<ushort>("us");
3461 
3462     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3463         tst_IODevice *device = devices+i;
3464 	for ( int e=0; encodings[e] != 0; e++ ) {
3465 	    QString encoding = encodings[e];
3466 
3467 	    QString tag = device->name() + "_" + encoding + "_";
3468 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << ushort(0);
3469 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << ushort(1);
3470 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << ushort(10);
3471 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << ushort(255);
3472 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << ushort(512);
3473 	}
3474     }
3475 }
3476 
3477 // ------------------------------------------------------------------------------
qt3_operator_shift_ushort()3478 void tst_QTextStream::qt3_operator_shift_ushort()
3479 {
3480     QFETCH( int, modes );
3481     if(modes & QIODevice::WriteOnly) {
3482         qt3_createWriteStream( os );
3483         qt3_write_ushort( os );
3484         qt3_closeWriteStream( os );
3485     }
3486     if(modes & QIODevice::ReadOnly) {
3487         qt3_createReadStream( is );
3488         qt3_read_ushort( is );
3489         qt3_closeReadStream( is );
3490     }
3491 }
3492 
3493 // ------------------------------------------------------------------------------
qt3_read_ushort(QTextStream * s)3494 void tst_QTextStream::qt3_read_ushort( QTextStream *s )
3495 {
3496     QFETCH( ushort, us );
3497     ushort exp;
3498     QString A, B;
3499     *s >> A >> exp >> B;
3500     QCOMPARE( A, QString("A") );
3501     QCOMPARE( B, QString("B") );
3502     QCOMPARE( exp, us );
3503     s->skipWhiteSpace();
3504 }
3505 
3506 // ------------------------------------------------------------------------------
qt3_write_ushort(QTextStream * s)3507 void tst_QTextStream::qt3_write_ushort( QTextStream *s )
3508 {
3509     QFETCH( ushort, us );
3510     *s << " A " << us << " B ";
3511 }
3512 
3513 // **************** int ****************
3514 
3515 // ------------------------------------------------------------------------------
qt3_operator_shift_int_data()3516 void tst_QTextStream::qt3_operator_shift_int_data()
3517 {
3518     QTest::addColumn<int>("modes");
3519     QTest::addColumn<QString>("device");
3520     QTest::addColumn<QString>("encoding");
3521     QTest::addColumn<int>("si");
3522 
3523     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3524         tst_IODevice *device = devices+i;
3525 	for ( int e=0; encodings[e] != 0; e++ ) {
3526 	    QString encoding = encodings[e];
3527 
3528 	    QString tag = device->name() + "_" + encoding + "_";
3529 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << int(0);
3530 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << int(1);
3531 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << int(10);
3532 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << int(255);
3533 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << int(512);
3534 	    QTest::newRow( tag + "5" ) << device->modes << device->name() << encoding << int(-1);
3535 	    QTest::newRow( tag + "6" ) << device->modes << device->name() << encoding << int(-10);
3536 	    QTest::newRow( tag + "7" ) << device->modes << device->name() << encoding << int(-255);
3537 	    QTest::newRow( tag + "8" ) << device->modes << device->name() << encoding << int(-512);
3538 	}
3539     }
3540 }
3541 
3542 // ------------------------------------------------------------------------------
qt3_operator_shift_int()3543 void tst_QTextStream::qt3_operator_shift_int()
3544 {
3545     QFETCH( int, modes );
3546     if(modes & QIODevice::WriteOnly) {
3547         qt3_createWriteStream( os );
3548         qt3_write_int( os );
3549         qt3_closeWriteStream( os );
3550     }
3551     if(modes & QIODevice::ReadOnly) {
3552         qt3_createReadStream( is );
3553         qt3_read_int( is );
3554         qt3_closeReadStream( is );
3555     }
3556 }
3557 
3558 // ------------------------------------------------------------------------------
qt3_read_int(QTextStream * s)3559 void tst_QTextStream::qt3_read_int( QTextStream *s )
3560 {
3561     QFETCH( int, si );
3562     int exp;
3563     QString A, B;
3564     *s >> A >> exp >> B;
3565     QCOMPARE( A, QString("A") );
3566     QCOMPARE( B, QString("B") );
3567     QCOMPARE( exp, si );
3568     s->skipWhiteSpace();
3569 }
3570 
3571 // ------------------------------------------------------------------------------
qt3_write_int(QTextStream * s)3572 void tst_QTextStream::qt3_write_int( QTextStream *s )
3573 {
3574     QFETCH( int, si );
3575     *s << " A " << si << " B ";
3576 }
3577 
3578 // **************** uint ****************
3579 
3580 // ------------------------------------------------------------------------------
qt3_operator_shift_uint_data()3581 void tst_QTextStream::qt3_operator_shift_uint_data()
3582 {
3583     QTest::addColumn<int>("modes");
3584     QTest::addColumn<QString>("device");
3585     QTest::addColumn<QString>("encoding");
3586     QTest::addColumn<uint>("ui");
3587 
3588     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3589         tst_IODevice *device = devices+i;
3590 	for ( int e=0; encodings[e] != 0; e++ ) {
3591 	    QString encoding = encodings[e];
3592 
3593 	    QString tag = device->name() + "_" + encoding + "_";
3594 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << uint(0);
3595 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << uint(1);
3596 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << uint(10);
3597 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << uint(255);
3598 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << uint(512);
3599 	}
3600     }
3601 }
3602 
3603 // ------------------------------------------------------------------------------
qt3_operator_shift_uint()3604 void tst_QTextStream::qt3_operator_shift_uint()
3605 {
3606     QFETCH( int, modes );
3607     if(modes & QIODevice::WriteOnly) {
3608         qt3_createWriteStream( os );
3609         qt3_write_uint( os );
3610         qt3_closeWriteStream( os );
3611     }
3612     if(modes & QIODevice::ReadOnly) {
3613         qt3_createReadStream( is );
3614         qt3_read_uint( is );
3615         qt3_closeReadStream( is );
3616     }
3617 }
3618 
3619 // ------------------------------------------------------------------------------
qt3_read_uint(QTextStream * s)3620 void tst_QTextStream::qt3_read_uint( QTextStream *s )
3621 {
3622     QFETCH( uint, ui );
3623     uint exp;
3624     QString A, B;
3625     *s >> A >> exp >> B;
3626     QCOMPARE( A, QString("A") );
3627     QCOMPARE( B, QString("B") );
3628     QCOMPARE( exp, ui );
3629     s->skipWhiteSpace();
3630 }
3631 
3632 // ------------------------------------------------------------------------------
qt3_write_uint(QTextStream * s)3633 void tst_QTextStream::qt3_write_uint( QTextStream *s )
3634 {
3635     QFETCH( uint, ui );
3636     *s << " A " << ui << " B ";
3637 }
3638 
3639 // **************** long ****************
3640 
3641 // ------------------------------------------------------------------------------
qt3_operator_shift_long_data()3642 void tst_QTextStream::qt3_operator_shift_long_data()
3643 {
3644     QTest::addColumn<int>("modes");
3645     QTest::addColumn<QString>("device");
3646     QTest::addColumn<QString>("encoding");
3647     QTest::addColumn<long>("sl");
3648 
3649     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3650         tst_IODevice *device = devices+i;
3651 	for ( int e=0; encodings[e] != 0; e++ ) {
3652 	    QString encoding = encodings[e];
3653 
3654 	    QString tag = device->name() + "_" + encoding + "_";
3655 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << long(0);
3656 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << long(1);
3657 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << long(10);
3658 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << long(255);
3659 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << long(65535);
3660 	    QTest::newRow( tag + "5" ) << device->modes << device->name() << encoding << long(-1);
3661 	    QTest::newRow( tag + "6" ) << device->modes << device->name() << encoding << long(-10);
3662 	    QTest::newRow( tag + "7" ) << device->modes << device->name() << encoding << long(-255);
3663 	    QTest::newRow( tag + "8" ) << device->modes << device->name() << encoding << long(-65534);
3664 	}
3665     }
3666 }
3667 
3668 // ------------------------------------------------------------------------------
qt3_operator_shift_long()3669 void tst_QTextStream::qt3_operator_shift_long()
3670 {
3671     QFETCH( int, modes );
3672     if(modes & QIODevice::WriteOnly) {
3673         qt3_createWriteStream( os );
3674         qt3_write_long( os );
3675         qt3_closeWriteStream( os );
3676     }
3677     if(modes & QIODevice::ReadOnly) {
3678         qt3_createReadStream( is );
3679         qt3_read_long( is );
3680         qt3_closeReadStream( is );
3681     }
3682 }
3683 
3684 // ------------------------------------------------------------------------------
qt3_read_long(QTextStream * s)3685 void tst_QTextStream::qt3_read_long( QTextStream *s )
3686 {
3687     QFETCH( long, sl );
3688     long exp;
3689     QString A, B;
3690     *s >> A >> exp >> B;
3691     QCOMPARE( A, QString("A") );
3692     QCOMPARE( B, QString("B") );
3693     QCOMPARE( exp, sl );
3694     s->skipWhiteSpace();
3695 }
3696 
3697 // ------------------------------------------------------------------------------
qt3_write_long(QTextStream * s)3698 void tst_QTextStream::qt3_write_long( QTextStream *s )
3699 {
3700     QFETCH( long, sl );
3701     *s << " A " << sl << " B ";
3702 }
3703 
3704 // **************** long ****************
3705 
3706 // ------------------------------------------------------------------------------
qt3_operator_shift_ulong_data()3707 void tst_QTextStream::qt3_operator_shift_ulong_data()
3708 {
3709     QTest::addColumn<int>("modes");
3710     QTest::addColumn<QString>("device");
3711     QTest::addColumn<QString>("encoding");
3712     QTest::addColumn<ulong>("ul");
3713 
3714     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3715         tst_IODevice *device = devices+i;
3716 	for ( int e=0; encodings[e] != 0; e++ ) {
3717 	    QString encoding = encodings[e];
3718 
3719 	    QString tag = device->name() + "_" + encoding + "_";
3720 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << ulong(0);
3721 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << ulong(1);
3722 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << ulong(10);
3723 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << ulong(255);
3724 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << ulong(65535);
3725 	}
3726     }
3727 }
3728 
3729 // ------------------------------------------------------------------------------
qt3_operator_shift_ulong()3730 void tst_QTextStream::qt3_operator_shift_ulong()
3731 {
3732     QFETCH( int, modes );
3733     if(modes & QIODevice::WriteOnly) {
3734         qt3_createWriteStream( os );
3735         qt3_write_ulong( os );
3736         qt3_closeWriteStream( os );
3737     }
3738     if(modes & QIODevice::ReadOnly) {
3739         qt3_createReadStream( is );
3740         qt3_read_ulong( is );
3741         qt3_closeReadStream( is );
3742     }
3743 }
3744 
3745 // ------------------------------------------------------------------------------
qt3_read_ulong(QTextStream * s)3746 void tst_QTextStream::qt3_read_ulong( QTextStream *s )
3747 {
3748     QFETCH( ulong, ul );
3749     ulong exp;
3750     QString A, B;
3751     *s >> A >> exp >> B;
3752     QCOMPARE( A, QString("A") );
3753     QCOMPARE( B, QString("B") );
3754     QCOMPARE( exp, ul );
3755     s->skipWhiteSpace();
3756 }
3757 
3758 // ------------------------------------------------------------------------------
qt3_write_ulong(QTextStream * s)3759 void tst_QTextStream::qt3_write_ulong( QTextStream *s )
3760 {
3761     QFETCH( ulong, ul );
3762     *s << " A " << ul << " B ";
3763 }
3764 
3765 // **************** float ****************
3766 
3767 // ------------------------------------------------------------------------------
qt3_operator_shift_float_data()3768 void tst_QTextStream::qt3_operator_shift_float_data()
3769 {
3770     QTest::addColumn<int>("modes");
3771     QTest::addColumn<QString>("device");
3772     QTest::addColumn<QString>("encoding");
3773     QTest::addColumn<float>("f");
3774 
3775     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3776         tst_IODevice *device = devices+i;
3777 	for ( int e=0; encodings[e] != 0; e++ ) {
3778 	    QString encoding = encodings[e];
3779 
3780 	    QString tag = device->name() + "_" + encoding + "_";
3781 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << float(0.0);
3782 	    QTest::newRow( tag + "1" ) << device->modes << device->name()  << encoding << float(0.0001);
3783 	    QTest::newRow( tag + "2" ) << device->modes << device->name()  << encoding << float(-0.0001);
3784 	    QTest::newRow( tag + "3" ) << device->modes << device->name()  << encoding << float(3.45678);
3785 	    QTest::newRow( tag + "4" ) << device->modes << device->name()  << encoding << float(-3.45678);
3786 	}
3787     }
3788 }
3789 
3790 // ------------------------------------------------------------------------------
qt3_operator_shift_float()3791 void tst_QTextStream::qt3_operator_shift_float()
3792 {
3793     QFETCH( int, modes );
3794     if(modes & QIODevice::WriteOnly) {
3795         qt3_createWriteStream( os );
3796         qt3_write_float( os );
3797         qt3_closeWriteStream( os );
3798     }
3799     if(modes & QIODevice::ReadOnly) {
3800         qt3_createReadStream( is );
3801         qt3_read_float( is );
3802         qt3_closeReadStream( is );
3803     }
3804 }
3805 
3806 // ------------------------------------------------------------------------------
qt3_read_float(QTextStream * s)3807 void tst_QTextStream::qt3_read_float( QTextStream *s )
3808 {
3809     QFETCH( float, f );
3810     float exp;
3811     QString A, B;
3812     *s >> A >> exp >> B;
3813     QCOMPARE( A, QString("A") );
3814     QCOMPARE( B, QString("B") );
3815     QCOMPARE( exp, f );
3816     s->skipWhiteSpace();
3817 }
3818 
3819 // ------------------------------------------------------------------------------
qt3_write_float(QTextStream * s)3820 void tst_QTextStream::qt3_write_float( QTextStream *s )
3821 {
3822     QFETCH( float, f );
3823     *s << " A " << f << " B ";
3824 }
3825 
3826 // **************** double ****************
3827 
3828 // ------------------------------------------------------------------------------
qt3_operator_shift_double_data()3829 void tst_QTextStream::qt3_operator_shift_double_data()
3830 {
3831     QTest::addColumn<int>("modes");
3832     QTest::addColumn<QString>("device");
3833     QTest::addColumn<QString>("encoding");
3834     QTest::addColumn<double>("d");
3835 
3836     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3837         tst_IODevice *device = devices+i;
3838 	for ( int e=0; encodings[e] != 0; e++ ) {
3839 	    QString encoding = encodings[e];
3840 
3841 	    QString tag = device->name() + "_" + encoding + "_";
3842 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << double(0.0);
3843 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << double(0.0001);
3844 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << double(-0.0001);
3845 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << double(3.45678);
3846 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << double(-3.45678);
3847 	    QTest::newRow( tag + "5" ) << device->modes << device->name() << encoding << double(1.23456789);
3848 	    QTest::newRow( tag + "6" ) << device->modes << device->name() << encoding << double(-1.23456789);
3849 	}
3850     }
3851 }
3852 
3853 // ------------------------------------------------------------------------------
qt3_operator_shift_double()3854 void tst_QTextStream::qt3_operator_shift_double()
3855 {
3856     QFETCH( int, modes );
3857     if(modes & QIODevice::WriteOnly) {
3858         qt3_createWriteStream( os );
3859         os->precision( 10 );
3860         qt3_write_double( os );
3861         qt3_closeWriteStream( os );
3862     }
3863     if(modes & QIODevice::ReadOnly) {
3864         qt3_createReadStream( is );
3865         is->precision( 10 );
3866         qt3_read_double( is );
3867         qt3_closeReadStream( is );
3868     }
3869 }
3870 
3871 // ------------------------------------------------------------------------------
qt3_read_double(QTextStream * s)3872 void tst_QTextStream::qt3_read_double( QTextStream *s )
3873 {
3874     QFETCH( double, d );
3875     double exp;
3876     QString A, B;
3877     *s >> A >> exp >> B;
3878     QCOMPARE( A, QString("A") );
3879     QCOMPARE( B, QString("B") );
3880     QCOMPARE( exp, d );
3881     s->skipWhiteSpace();
3882 }
3883 
3884 // ------------------------------------------------------------------------------
qt3_write_double(QTextStream * s)3885 void tst_QTextStream::qt3_write_double( QTextStream *s )
3886 {
3887     QFETCH( double, d );
3888     *s << " A " << d << " B ";
3889 }
3890 
3891 // **************** QString ****************
3892 
3893 // ------------------------------------------------------------------------------
qt3_operator_shift_QString_data()3894 void tst_QTextStream::qt3_operator_shift_QString_data()
3895 {
3896     QTest::addColumn<int>("modes");
3897     QTest::addColumn<QString>("device");
3898     QTest::addColumn<QString>("encoding");
3899     QTest::addColumn<QString>("str");
3900     QTest::addColumn<bool>("multi_str");
3901     QTest::addColumn<bool>("zero_length");
3902 
3903     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3904         tst_IODevice *device = devices+i;
3905 	for ( int e=0; encodings[e] != 0; e++ ) {
3906 	    QString encoding = encodings[e];
3907 
3908 	    QString tag = device->name() + "_" + encoding + "_";
3909 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << QString("") << bool(FALSE) << bool(TRUE);
3910 	    QTest::newRow( tag + "1" ) << device->modes << device->name()  << encoding << QString() << bool(FALSE) << bool(TRUE);
3911 	    QTest::newRow( tag + "2" ) << device->modes << device->name()  << encoding << QString("foo") << bool(FALSE) << bool(FALSE);
3912 	    QTest::newRow( tag + "3" ) << device->modes << device->name()  << encoding << QString("foo\nbar") << bool(TRUE) << bool(FALSE);
3913 	    QTest::newRow( tag + "4" ) << device->modes << device->name()  << encoding << QString("cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv") << bool(TRUE) << bool(FALSE);
3914 	}
3915     }
3916 }
3917 
3918 // ------------------------------------------------------------------------------
qt3_operator_shift_QString()3919 void tst_QTextStream::qt3_operator_shift_QString()
3920 {
3921     QFETCH( bool, zero_length );
3922     file_is_empty = zero_length;
3923 
3924     QFETCH( int, modes );
3925     if(modes & QIODevice::WriteOnly) {
3926         qt3_createWriteStream( os );
3927         qt3_write_QString( os );
3928         qt3_closeWriteStream( os );
3929     }
3930     if(modes & QIODevice::ReadOnly) {
3931         qt3_createReadStream( is );
3932         qt3_read_QString( is );
3933         qt3_closeReadStream( is );
3934     }
3935 }
3936 
3937 // ------------------------------------------------------------------------------
qt3_read_QString(QTextStream * s)3938 void tst_QTextStream::qt3_read_QString( QTextStream *s )
3939 {
3940     QString exp;
3941     QFETCH( QString, str );
3942     if (str.isNull())
3943 	str = "";
3944 
3945     QFETCH( bool, multi_str );
3946     if (!multi_str) {
3947 	*s >> exp;
3948 	QCOMPARE( exp, str );
3949     } else {
3950 	QStringList l;
3951 	l = QStringList::split( " ", str );
3952 	if (l.count() < 2)
3953 	    l = QStringList::split( "\n", str );
3954 	for (int i=0; i<l.count(); i++) {
3955 	    *s >> exp;
3956 	    QCOMPARE( exp, l[i] );
3957 	}
3958     }
3959 }
3960 
3961 // ------------------------------------------------------------------------------
qt3_write_QString(QTextStream * s)3962 void tst_QTextStream::qt3_write_QString( QTextStream *s )
3963 {
3964     QFETCH( QString, str );
3965     *s << str;
3966 }
3967 
3968 // **************** QByteArray ****************
3969 
3970 // ------------------------------------------------------------------------------
qt3_operator_shift_QByteArray_data()3971 void tst_QTextStream::qt3_operator_shift_QByteArray_data()
3972 {
3973     QTest::addColumn<int>("modes");
3974     QTest::addColumn<QString>("device");
3975     QTest::addColumn<QString>("encoding");
3976     QTest::addColumn<QByteArray>("cs");
3977     QTest::addColumn<bool>("multi_str");
3978     QTest::addColumn<bool>("zero_length");
3979 
3980     for ( int i=0; !devices[i].name().isNull(); i++ ) {
3981         tst_IODevice *device = devices+i;
3982 	for ( int e=0; encodings[e] != 0; e++ ) {
3983 	    QString encoding = encodings[e];
3984 
3985 	    QString tag = device->name() + "_" + encoding + "_";
3986 	    QTest::newRow( tag + "0" ) << device->modes << device->name() << encoding << QByteArray("") << bool(FALSE) << bool(TRUE);
3987 	    QTest::newRow( tag + "1" ) << device->modes << device->name() << encoding << QByteArray(0) << bool(FALSE) << bool(TRUE);
3988 	    QTest::newRow( tag + "2" ) << device->modes << device->name() << encoding << QByteArray("foo") << bool(FALSE) << bool(FALSE);
3989 	    QTest::newRow( tag + "3" ) << device->modes << device->name() << encoding << QByteArray("foo\nbar") << bool(TRUE) << bool(FALSE);
3990 	    QTest::newRow( tag + "4" ) << device->modes << device->name() << encoding << QByteArray("cjacka ckha cka ckah ckac kahckadhcbkgdk vkzdfbvajef vkahv") << bool(TRUE) << bool(FALSE);
3991 	}
3992     }
3993 }
3994 
3995 // ------------------------------------------------------------------------------
qt3_operator_shift_QByteArray()3996 void tst_QTextStream::qt3_operator_shift_QByteArray()
3997 {
3998     QFETCH( bool, zero_length );
3999     file_is_empty = zero_length;
4000 
4001     QFETCH( int, modes );
4002     if(modes & QIODevice::WriteOnly) {
4003         qt3_createWriteStream( os );
4004         qt3_write_QByteArray( os );
4005         qt3_closeWriteStream( os );
4006     }
4007     if(modes & QIODevice::ReadOnly) {
4008         qt3_createReadStream( is );
4009         qt3_read_QByteArray( is );
4010         qt3_closeReadStream( is );
4011     }
4012 }
4013 
4014 // ------------------------------------------------------------------------------
qt3_read_QByteArray(QTextStream * s)4015 void tst_QTextStream::qt3_read_QByteArray( QTextStream *s )
4016 {
4017 /*
4018     QFETCH( QByteArray, cs );
4019     QByteArray exp;
4020     *s >> exp;
4021     QCOMPARE( exp, cs );
4022 */
4023     QByteArray exp;
4024     QFETCH( QByteArray, cs );
4025     if (cs.isNull())
4026 	cs = "";
4027 
4028     QFETCH( bool, multi_str );
4029     if (!multi_str) {
4030 	*s >> exp;
4031 	QCOMPARE( exp.constData(), cs.constData() );
4032     } else {
4033 	QStringList l;
4034 	l = QStringList::split( " ", cs );
4035 	if (l.count() < 2)
4036 	    l = QStringList::split( "\n", cs );
4037 	for (int i=0; i<l.count(); i++) {
4038 	    *s >> exp;
4039 	    QCOMPARE( exp, QByteArray(l[i].toAscii()) );
4040 	}
4041     }
4042 }
4043 
4044 // ------------------------------------------------------------------------------
qt3_generateLineData(bool for_QString)4045 static void qt3_generateLineData( bool for_QString )
4046 {
4047     QTest::addColumn<QByteArray>("input");
4048     QTest::addColumn<QStringList>("output");
4049 
4050     QTest::newRow("emptyer") << QByteArray() << QStringList();
4051     QTest::newRow("lf") << QByteArray("\n") << (QStringList() << "");
4052     QTest::newRow("crlf") << QByteArray("\r\n") << (QStringList() << "");
4053     QTest::newRow("oneline/nothing") << QByteArray("ole") << (QStringList() << "ole");
4054     QTest::newRow("oneline/lf") << QByteArray("ole\n") << (QStringList() << "ole");
4055     QTest::newRow("oneline/crlf") << QByteArray("ole\r\n") << (QStringList() << "ole");
4056     QTest::newRow("twolines/lf/lf") << QByteArray("ole\ndole\n") << (QStringList() << "ole" << "dole");
4057     QTest::newRow("twolines/crlf/crlf") << QByteArray("ole\r\ndole\r\n") << (QStringList() << "ole" << "dole");
4058     QTest::newRow("twolines/lf/crlf") << QByteArray("ole\ndole\r\n") << (QStringList() << "ole" << "dole");
4059     QTest::newRow("twolines/lf/nothing") << QByteArray("ole\ndole") << (QStringList() << "ole" << "dole");
4060     QTest::newRow("twolines/crlf/nothing") << QByteArray("ole\r\ndole") << (QStringList() << "ole" << "dole");
4061     QTest::newRow("threelines/lf/lf/lf") << QByteArray("ole\ndole\ndoffen\n") << (QStringList() << "ole" << "dole" << "doffen");
4062     QTest::newRow("threelines/crlf/crlf/crlf") << QByteArray("ole\r\ndole\r\ndoffen\r\n") << (QStringList() << "ole" << "dole" << "doffen");
4063     QTest::newRow("threelines/crlf/crlf/nothing") << QByteArray("ole\r\ndole\r\ndoffen") << (QStringList() << "ole" << "dole" << "doffen");
4064 
4065     if (!for_QString) {
4066         QTest::newRow("unicode/nothing") << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65", 8) << (QStringList() << "\345ge");
4067         QTest::newRow("unicode-little/nothing") << QByteArray("\xff\xfe\xe5\x00\x67\x00\x65\x00", 8) << (QStringList() << "\345ge");
4068         QTest::newRow("unicode/lf")        << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65\x00\x0a", 10) << (QStringList() << "\345ge");
4069         QTest::newRow("unicode-little/lf") << QByteArray("\xff\xfe\xe5\x00\x67\x00\x65\x00\x0a\x00", 10) << (QStringList() << "\345ge");
4070 
4071         QTest::newRow("unicode/twolines")  << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65\x00\x0a\x00\xe5\x00\x67\x00\x65\x00\x0a", 18) << (QStringList() << "\345ge" << "\345ge");
4072         QTest::newRow("unicode-little/twolines")  << QByteArray("\xff\xfe\xe5\x00\x67\x00\x65\x00\x0a\x00\xe5\x00\x67\x00\x65\x00\x0a\x00", 18) << (QStringList() << "\345ge" << "\345ge");
4073 
4074         QTest::newRow("unicode/threelines")
4075             << QByteArray("\xfe\xff"
4076                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
4077                           "\x00\xe5\x00\x67\x00\x65\x00\x0a"
4078                           "\x00\xe5\x00\x67\x00\x65\x00\x0a", 26)
4079             << (QStringList() << "\345ge" << "\345ge" << "\345ge");
4080         QTest::newRow("unicode-little/threelines")
4081             << QByteArray("\xff\xfe"
4082                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
4083                           "\xe5\x00\x67\x00\x65\x00\x0a\x00"
4084                           "\xe5\x00\x67\x00\x65\x00\x0a\x00", 26)
4085             << (QStringList() << "\345ge" << "\345ge" << "\345ge");
4086     }
4087 
4088     // partials
4089     QTest::newRow("cr") << QByteArray("\r") << (QStringList() << "");
4090     QTest::newRow("oneline/cr") << QByteArray("ole\r") << (QStringList() << "ole");
4091     if (!for_QString)
4092         QTest::newRow("unicode/cr") << QByteArray("\xfe\xff\x00\xe5\x00\x67\x00\x65\x00\x0d", 10) << (QStringList() << "\345ge");
4093 }
4094 
4095 // ------------------------------------------------------------------------------
qt3_writeDataToFileReadAsLines_data()4096 void tst_QTextStream::qt3_writeDataToFileReadAsLines_data()
4097 {
4098     qt3_generateLineData(false);
4099 }
4100 
4101 // ------------------------------------------------------------------------------
pretty(const QString & input)4102 QByteArray pretty(const QString &input)
4103 {
4104     QByteArray data;
4105 
4106     QByteArray arr = input.toLatin1();
4107     for (int i = 0; i < arr.size(); ++i) {
4108         char buf[64];
4109         memset(buf, 0, sizeof(buf));
4110         char ch = arr.at(i);
4111         sprintf(buf, "\\%2hhx", ch);
4112         data += buf;
4113     }
4114 
4115     return data;
4116 }
4117 
4118 // ------------------------------------------------------------------------------
qt3_writeDataToFileReadAsLines()4119 void tst_QTextStream::qt3_writeDataToFileReadAsLines()
4120 {
4121     QFETCH(QByteArray, input);
4122     QFETCH(QStringList, output);
4123 
4124     QFile::remove("eoltest");
4125 
4126     // Create the file
4127     QFile writer("eoltest");
4128     QVERIFY2(writer.open(QFile::WriteOnly | QFile::Truncate), ("When creating a file: " + writer.errorString()).latin1());
4129     QCOMPARE(writer.write(input), qlonglong(input.size()));
4130     writer.close();
4131 
4132     // Read from it using QTextStream
4133     QVERIFY2(writer.open(QFile::ReadOnly), ("When reading a file: " + writer.errorString()).latin1());
4134     QTextStream stream(&writer);
4135     QStringList tmp;
4136 
4137     while (!stream.atEnd())
4138         tmp << stream.readLine();
4139 
4140     QCOMPARE(tmp, output);
4141 }
4142 
4143 // ------------------------------------------------------------------------------
qt3_writeDataToQStringReadAsLines_data()4144 void tst_QTextStream::qt3_writeDataToQStringReadAsLines_data()
4145 {
4146     qt3_generateLineData(true);
4147 }
4148 
4149 // ------------------------------------------------------------------------------
qt3_writeDataToQStringReadAsLines()4150 void tst_QTextStream::qt3_writeDataToQStringReadAsLines()
4151 {
4152     QFETCH(QByteArray, input);
4153     QFETCH(QStringList, output);
4154 
4155     QString s = input;
4156     QTextStream stream(&s, QIODevice::ReadOnly);
4157 
4158     QStringList tmp;
4159     while (!stream.atEnd())
4160         tmp << stream.readLine();
4161 
4162     QCOMPARE(tmp, output);
4163 }
4164 
4165 // ------------------------------------------------------------------------------
qt3_write_QByteArray(QTextStream * s)4166 void tst_QTextStream::qt3_write_QByteArray( QTextStream *s )
4167 {
4168     QFETCH( QByteArray, cs );
4169     *s << cs;
4170 }
4171 #endif
4172 
4173 // ------------------------------------------------------------------------------
status_real_read_data()4174 void tst_QTextStream::status_real_read_data()
4175 {
4176     QTest::addColumn<QString>("input");
4177     QTest::addColumn<double>("expected_f");
4178     QTest::addColumn<QString>("expected_w");
4179     QTest::addColumn<QList<int> >("results");
4180 
4181     QTest::newRow("1.23 abc   ") << QString("1.23 abc   ") << 1.23 << QString("abc")
4182                               << (QList<int>()
4183                                   << (int)QTextStream::Ok
4184                                   << (int)QTextStream::ReadCorruptData
4185                                   << (int)QTextStream::Ok
4186                                   << (int)QTextStream::Ok
4187                                   << (int)QTextStream::ReadPastEnd);
4188 }
4189 
status_real_read()4190 void tst_QTextStream::status_real_read()
4191 {
4192     QFETCH(QString, input);
4193     QFETCH(double, expected_f);
4194     QFETCH(QString, expected_w);
4195     QFETCH(QList<int>, results);
4196 
4197     QTextStream s(&input);
4198     double f = 0.0;
4199     QString w;
4200     s >> f;
4201     QCOMPARE((int)s.status(), results.at(0));
4202     QCOMPARE(f, expected_f);
4203     s >> f;
4204     QCOMPARE((int)s.status(), results.at(1));
4205     s.resetStatus();
4206     QCOMPARE((int)s.status(), results.at(2));
4207     s >> w;
4208     QCOMPARE((int)s.status(), results.at(3));
4209     QCOMPARE(w, expected_w);
4210     s >> f;
4211     QCOMPARE((int)s.status(), results.at(4));
4212 }
4213 
status_integer_read()4214 void tst_QTextStream::status_integer_read()
4215 {
4216 #ifdef Q_OS_WINCE
4217     QString text = QLatin1String("123 abc   ");
4218     QTextStream s(&text);
4219 #else
4220     QTextStream s("123 abc   ");
4221 #endif
4222     int i;
4223     QString w;
4224     s >> i;
4225     QCOMPARE(s.status(), QTextStream::Ok);
4226     s >> i;
4227     QCOMPARE(s.status(), QTextStream::ReadCorruptData);
4228     s.resetStatus();
4229     QCOMPARE(s.status(), QTextStream::Ok);
4230     s >> w;
4231     QCOMPARE(s.status(), QTextStream::Ok);
4232     QCOMPARE(w, QString("abc"));
4233     s >> i;
4234     QCOMPARE(s.status(), QTextStream::ReadPastEnd);
4235 }
4236 
status_word_read()4237 void tst_QTextStream::status_word_read()
4238 {
4239 #ifdef Q_OS_WINCE
4240     QString text = QLatin1String("abc ");
4241     QTextStream s(&text);
4242 #else
4243     QTextStream s("abc ");
4244 #endif
4245     QString w;
4246     s >> w;
4247     QCOMPARE(s.status(), QTextStream::Ok);
4248     s >> w;
4249     QCOMPARE(s.status(), QTextStream::ReadPastEnd);
4250 }
4251 
4252 class FakeBuffer : public QBuffer
4253 {
4254 protected:
writeData(const char * c,qint64 i)4255     qint64 writeData(const char *c, qint64 i) { return m_lock ? 0 : QBuffer::writeData(c, i); }
4256 public:
FakeBuffer(bool locked=false)4257     FakeBuffer(bool locked = false) : m_lock(locked) {}
setLocked(bool locked)4258     void setLocked(bool locked) { m_lock = locked; }
4259 private:
4260     bool m_lock;
4261 };
4262 
status_write_error()4263 void tst_QTextStream::status_write_error()
4264 {
4265     FakeBuffer fb(false);
4266     QVERIFY(fb.open(QBuffer::ReadWrite));
4267     QTextStream fs(&fb);
4268     fs.setCodec(QTextCodec::codecForName("latin1"));
4269     /* first write some initial content */
4270     fs << "hello";
4271     fs.flush();
4272     QCOMPARE(fs.status(), QTextStream::Ok);
4273     QCOMPARE(fb.data(), QByteArray("hello"));
4274     /* then test that writing can cause an error */
4275     fb.setLocked(true);
4276     fs << "error";
4277     fs.flush();
4278     QCOMPARE(fs.status(), QTextStream::WriteFailed);
4279     QCOMPARE(fb.data(), QByteArray("hello"));
4280     /* finally test that writing after an error doesn't change the stream any more */
4281     fb.setLocked(false);
4282     fs << "can't do that";
4283     fs.flush();
4284     QCOMPARE(fs.status(), QTextStream::WriteFailed);
4285     QCOMPARE(fb.data(), QByteArray("hello"));
4286 }
4287 
task180679_alignAccountingStyle()4288 void tst_QTextStream::task180679_alignAccountingStyle()
4289 {
4290     {
4291     QString result;
4292     QTextStream out(&result);
4293     out.setFieldAlignment(QTextStream::AlignAccountingStyle);
4294     out.setFieldWidth(4);
4295     out.setPadChar('0');
4296     out << -1;
4297     QCOMPARE(result, QLatin1String("-001"));
4298     }
4299 
4300     {
4301     QString result;
4302     QTextStream out(&result);
4303     out.setFieldAlignment(QTextStream::AlignAccountingStyle);
4304     out.setFieldWidth(4);
4305     out.setPadChar('0');
4306     out << "-1";
4307     QCOMPARE(result, QLatin1String("00-1"));
4308     }
4309 
4310     {
4311     QString result;
4312     QTextStream out(&result);
4313     out.setFieldAlignment(QTextStream::AlignAccountingStyle);
4314     out.setFieldWidth(6);
4315     out.setPadChar('0');
4316     out << -1.2;
4317     QCOMPARE(result, QLatin1String("-001.2"));
4318     }
4319 
4320     {
4321     QString result;
4322     QTextStream out(&result);
4323     out.setFieldAlignment(QTextStream::AlignAccountingStyle);
4324     out.setFieldWidth(6);
4325     out.setPadChar('0');
4326     out << "-1.2";
4327     QCOMPARE(result, QLatin1String("00-1.2"));
4328     }
4329 }
4330 
task178772_setCodec()4331 void tst_QTextStream::task178772_setCodec()
4332 {
4333     QByteArray ba("\xe5 v\xe6r\n\xc3\xa5 v\xc3\xa6r\n");
4334     QString res = QLatin1String("\xe5 v\xe6r");
4335 
4336     QTextStream stream(ba);
4337     stream.setCodec("ISO 8859-1");
4338     QCOMPARE(stream.readLine(),res);
4339     stream.setCodec("UTF-8");
4340     QCOMPARE(stream.readLine(),res);
4341 }
4342 
double_write_with_flags_data()4343 void tst_QTextStream::double_write_with_flags_data()
4344 {
4345     QTest::addColumn<double>("number");
4346     QTest::addColumn<QString>("output");
4347     QTest::addColumn<int>("numberFlags");
4348     QTest::addColumn<int>("realNumberNotation");
4349 
4350     QTest::newRow("-ForceSign") << -1.23 << QString("-1.23") << (int)QTextStream::ForceSign << 0;
4351     QTest::newRow("+ForceSign") << 1.23 << QString("+1.23") << (int)QTextStream::ForceSign << 0;
4352     QTest::newRow("inf") << qInf() << QString("inf") << 0 << 0;
4353     QTest::newRow("-inf") << -qInf() << QString("-inf") << 0 << 0;
4354     QTest::newRow("inf uppercase") << qInf() << QString("INF") << (int)QTextStream::UppercaseDigits << 0;
4355     QTest::newRow("-inf uppercase") << -qInf() << QString("-INF") << (int)QTextStream::UppercaseDigits << 0;
4356     QTest::newRow("nan") << qQNaN() << QString("nan") << 0 << 0;
4357     QTest::newRow("nan") << qQNaN() << QString("NAN") << (int)QTextStream::UppercaseDigits << 0;
4358     QTest::newRow("scientific") << 1.234567e+02 << QString("1.234567e+02") << 0  << (int)QTextStream::ScientificNotation;
4359     QTest::newRow("scientific2") << 1.234567e+02 << QString("1.234567e+02") << (int)QTextStream::UppercaseBase << (int)QTextStream::ScientificNotation;
4360     QTest::newRow("scientific uppercase") << 1.234567e+02 << QString("1.234567E+02") << (int)QTextStream::UppercaseDigits << (int)QTextStream::ScientificNotation;
4361 }
4362 
double_write_with_flags()4363 void tst_QTextStream::double_write_with_flags()
4364 {
4365     QFETCH(double, number);
4366     QFETCH(QString, output);
4367     QFETCH(int, numberFlags);
4368     QFETCH(int, realNumberNotation);
4369 
4370     QString buf;
4371     QTextStream stream(&buf);
4372     if (numberFlags)
4373         stream.setNumberFlags(QTextStream::NumberFlag(numberFlags));
4374     if (realNumberNotation)
4375         stream.setRealNumberNotation(QTextStream::RealNumberNotation(realNumberNotation));
4376     stream << number;
4377     QCOMPARE(buf, output);
4378 }
4379 
double_write_with_precision_data()4380 void tst_QTextStream::double_write_with_precision_data()
4381 {
4382     QTest::addColumn<int>("precision");
4383     QTest::addColumn<double>("value");
4384     QTest::addColumn<QString>("result");
4385 
4386     QTest::ignoreMessage(QtWarningMsg, "QTextStream::setRealNumberPrecision: Invalid precision (-1)");
4387     QTest::newRow("-1") << -1 << 3.14159 << QString("3.14159");
4388     QTest::newRow("0") << 0 << 3.14159 << QString("3");
4389     QTest::newRow("1") << 1 << 3.14159 << QString("3");
4390     QTest::newRow("2") << 2 << 3.14159 << QString("3.1");
4391     QTest::newRow("3") << 3 << 3.14159 << QString("3.14");
4392     QTest::newRow("5") << 5 << 3.14159 << QString("3.1416");
4393     QTest::newRow("6") << 6 << 3.14159 << QString("3.14159");
4394     QTest::newRow("7") << 7 << 3.14159 << QString("3.14159");
4395     QTest::newRow("10") << 10 << 3.14159 << QString("3.14159");
4396 }
4397 
double_write_with_precision()4398 void tst_QTextStream::double_write_with_precision()
4399 {
4400     QFETCH(int, precision);
4401     QFETCH(double, value);
4402     QFETCH(QString, result);
4403 
4404     QString buf;
4405     QTextStream stream(&buf);
4406     stream.setRealNumberPrecision(precision);
4407     stream << value;
4408     QCOMPARE(buf, result);
4409 }
4410 
int_read_with_locale_data()4411 void tst_QTextStream::int_read_with_locale_data()
4412 {
4413     QTest::addColumn<QString>("locale");
4414     QTest::addColumn<QString>("input");
4415     QTest::addColumn<int>("output");
4416 
4417     QTest::newRow("C -123") << QString("C") << QString("-123") << -123;
4418     QTest::newRow("C +123") << QString("C") << QString("+123") << 123;
4419     QTest::newRow("C 12345") << QString("C") << QString("12345") << 12345;
4420     QTest::newRow("C 12,345") << QString("C") << QString("12,345") << 12;
4421     QTest::newRow("C 12.345") << QString("C") << QString("12.345") << 12;
4422 
4423     QTest::newRow("de_DE -123") << QString("de_DE") << QString("-123") << -123;
4424     QTest::newRow("de_DE +123") << QString("de_DE") << QString("+123") << 123;
4425     QTest::newRow("de_DE 12345") << QString("de_DE") << QString("12345") << 12345;
4426     QTest::newRow("de_DE 12.345") << QString("de_DE") << QString("12.345") << 12345;
4427     QTest::newRow("de_DE .12345") << QString("de_DE") << QString(".12345") << 0;
4428 }
4429 
int_read_with_locale()4430 void tst_QTextStream::int_read_with_locale()
4431 {
4432     QFETCH(QString, locale);
4433     QFETCH(QString, input);
4434     QFETCH(int, output);
4435 
4436     QTextStream stream(&input);
4437     stream.setLocale(locale);
4438     int result;
4439     stream >> result;
4440     QCOMPARE(result, output);
4441 }
4442 
int_write_with_locale_data()4443 void tst_QTextStream::int_write_with_locale_data()
4444 {
4445     QTest::addColumn<QString>("locale");
4446     QTest::addColumn<int>("numberFlags");
4447     QTest::addColumn<int>("input");
4448     QTest::addColumn<QString>("output");
4449 
4450     QTest::newRow("C -123") << QString("C") << 0 << -123 << QString("-123");
4451     QTest::newRow("C +123") << QString("C") << (int)QTextStream::ForceSign << 123 << QString("+123");
4452     QTest::newRow("C 12345") << QString("C") << 0 << 12345 << QString("12345");
4453 
4454     QTest::newRow("de_DE -123") << QString("de_DE") << 0 << -123 << QString("-123");
4455     QTest::newRow("de_DE +123") << QString("de_DE") << (int)QTextStream::ForceSign << 123 << QString("+123");
4456     QTest::newRow("de_DE 12345") << QString("de_DE") << 0 << 12345 << QString("12.345");
4457 }
4458 
int_write_with_locale()4459 void tst_QTextStream::int_write_with_locale()
4460 {
4461     QFETCH(QString, locale);
4462     QFETCH(int, numberFlags);
4463     QFETCH(int, input);
4464     QFETCH(QString, output);
4465 
4466     QString result;
4467     QTextStream stream(&result);
4468     stream.setLocale(locale);
4469     if (numberFlags)
4470         stream.setNumberFlags(QTextStream::NumberFlags(numberFlags));
4471     stream << input;
4472     QCOMPARE(result, output);
4473 }
4474 
4475 // ------------------------------------------------------------------------------
4476 
4477 // like QTEST_APPLESS_MAIN, but initialising the locale on Unix
4478 #if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)
4479 QT_BEGIN_NAMESPACE
4480 extern bool qt_locale_initialized;
4481 QT_END_NAMESPACE
4482 #endif
4483 
main(int argc,char * argv[])4484 int main(int argc, char *argv[])
4485 {
4486 #if defined (Q_OS_UNIX) && !defined (Q_OS_SYMBIAN)
4487     ::setlocale(LC_ALL, "");
4488     qt_locale_initialized = true;
4489 #endif
4490     tst_QTextStream tc;
4491     return QTest::qExec(&tc, argc, argv);
4492 }
4493 
4494 #include "tst_qtextstream.moc"
4495 
4496