tests/auto/qfile/tst_qfile.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 #include <qplatformdefs.h>
       
    45 
       
    46 #include <QAbstractFileEngine>
       
    47 #include <QFSFileEngine>
       
    48 #include <QCoreApplication>
       
    49 #include <QDebug>
       
    50 #include <QDir>
       
    51 #include <QFile>
       
    52 #include <QFileInfo>
       
    53 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
    54 #include <QHostInfo>
       
    55 #endif
       
    56 #include <QProcess>
       
    57 #ifndef Q_OS_WIN
       
    58 # include <sys/types.h>
       
    59 # include <unistd.h>
       
    60 #endif
       
    61 #ifdef Q_OS_MAC
       
    62 # include <sys/mount.h>
       
    63 #elif defined(Q_OS_LINUX)
       
    64 # include <sys/vfs.h>
       
    65 #elif defined(Q_OS_FREEBSD)
       
    66 # include <sys/param.h>
       
    67 # include <sys/mount.h>
       
    68 #elif defined(Q_OS_IRIX)
       
    69 # include <sys/statfs.h>
       
    70 #elif defined(Q_OS_WINCE)
       
    71 # include <qplatformdefs.h>
       
    72 # include <private/qfsfileengine_p.h>
       
    73 #endif
       
    74 
       
    75 #include <stdio.h>
       
    76 #include "../network-settings.h"
       
    77 
       
    78 #if defined(Q_OS_SYMBIAN)
       
    79 # define SRCDIR ""
       
    80 #endif
       
    81 
       
    82 Q_DECLARE_METATYPE(QFile::FileError)
       
    83 
       
    84 //TESTED_CLASS=
       
    85 //TESTED_FILES=
       
    86 
       
    87 class tst_QFile : public QObject
       
    88 {
       
    89     Q_OBJECT
       
    90 
       
    91 public:
       
    92     tst_QFile();
       
    93     virtual ~tst_QFile();
       
    94 
       
    95 
       
    96 public slots:
       
    97     void init();
       
    98     void cleanup();
       
    99 private slots:
       
   100     void initTestCase();
       
   101     void cleanupTestCase();
       
   102     void exists();
       
   103     void open_data();
       
   104     void open();
       
   105     void openUnbuffered();
       
   106     void size_data();
       
   107     void size();
       
   108     void seek();
       
   109     void setSize();
       
   110     void setSizeSeek();
       
   111     void atEnd();
       
   112     void readLine();
       
   113     void readLine2();
       
   114     void readLineNullInLine();
       
   115     void readAllStdin();
       
   116     void readLineStdin();
       
   117     void readLineStdin_lineByLine();
       
   118     void text();
       
   119     void missingEndOfLine();
       
   120     void readBlock();
       
   121     void getch();
       
   122     void ungetChar();
       
   123     void createFile();
       
   124     void append();
       
   125     void permissions_data();
       
   126     void permissions();
       
   127     void setPermissions();
       
   128     void copy();
       
   129     void copyAfterFail();
       
   130     void copyRemovesTemporaryFile() const;
       
   131     void copyShouldntOverwrite();
       
   132     void copyFallback();
       
   133     void link();
       
   134     void linkToDir();
       
   135     void absolutePathLinkToRelativePath();
       
   136     void readBrokenLink();
       
   137     void readTextFile_data();
       
   138     void readTextFile();
       
   139     void readTextFile2();
       
   140     void writeTextFile_data();
       
   141     void writeTextFile();
       
   142     /* void largeFileSupport(); */
       
   143 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   144     void largeUncFileSupport();
       
   145 #endif
       
   146     void tailFile();
       
   147     void flush();
       
   148     void bufferedRead();
       
   149     void isSequential();
       
   150     void encodeName();
       
   151     void truncate();
       
   152     void seekToPos();
       
   153     void FILEReadWrite();
       
   154     void i18nFileName_data();
       
   155     void i18nFileName();
       
   156     void longFileName_data();
       
   157     void longFileName();
       
   158     void fileEngineHandler();
       
   159     void useQFileInAFileHandler();
       
   160     void getCharFF();
       
   161     void remove_and_exists();
       
   162     void removeOpenFile();
       
   163     void fullDisk();
       
   164     void writeLargeDataBlock_data();
       
   165     void writeLargeDataBlock();
       
   166     void readFromWriteOnlyFile();
       
   167     void writeToReadOnlyFile();
       
   168     void virtualFile();
       
   169     void textFile();
       
   170     void rename_data();
       
   171     void rename();
       
   172     void renameWithAtEndSpecialFile() const;
       
   173     void renameFallback();
       
   174     void renameMultiple();
       
   175     void appendAndRead();
       
   176     void miscWithUncPathAsCurrentDir();
       
   177     void standarderror();
       
   178     void handle();
       
   179 
       
   180     void readEof_data();
       
   181     void readEof();
       
   182 
       
   183     void map_data();
       
   184     void map();
       
   185     void mapResource_data();
       
   186     void mapResource();
       
   187     void mapOpenMode_data();
       
   188     void mapOpenMode();
       
   189 
       
   190     // --- Task related tests below this line
       
   191     void task167217();
       
   192 
       
   193     void openDirectory();
       
   194 
       
   195 public:
       
   196 // disabled this test for the moment... it hangs
       
   197     void invalidFile_data();
       
   198     void invalidFile();
       
   199 };
       
   200 
       
   201 tst_QFile::tst_QFile()
       
   202 {
       
   203 }
       
   204 
       
   205 tst_QFile::~tst_QFile()
       
   206 {
       
   207 
       
   208 }
       
   209 
       
   210 void tst_QFile::init()
       
   211 {
       
   212 // TODO: Add initialization code here.
       
   213 // This will be executed immediately before each test is run.
       
   214 }
       
   215 
       
   216 void tst_QFile::cleanup()
       
   217 {
       
   218 // TODO: Add cleanup code here.
       
   219 // This will be executed immediately after each test is run.
       
   220 
       
   221     // for copyFallback()
       
   222     if (QFile::exists("file-copy-destination.txt")) {
       
   223         QFile::setPermissions("file-copy-destination.txt",
       
   224                 QFile::ReadOwner | QFile::WriteOwner);
       
   225         QFile::remove("file-copy-destination.txt");
       
   226     }
       
   227 
       
   228     // for renameFallback()
       
   229     QFile::remove("file-rename-destination.txt");
       
   230 
       
   231     // for copyAfterFail()
       
   232     QFile::remove("file-to-be-copied.txt");
       
   233     QFile::remove("existing-file.txt");
       
   234     QFile::remove("copied-file-1.txt");
       
   235     QFile::remove("copied-file-2.txt");
       
   236 
       
   237     // for renameMultiple()
       
   238     QFile::remove("file-to-be-renamed.txt");
       
   239     QFile::remove("existing-file.txt");
       
   240     QFile::remove("file-renamed-once.txt");
       
   241     QFile::remove("file-renamed-twice.txt");
       
   242 }
       
   243 
       
   244 void tst_QFile::initTestCase()
       
   245 {
       
   246     QFile::remove("noreadfile");
       
   247 
       
   248     // create a file and make it read-only
       
   249     QFile file("readonlyfile");
       
   250     file.open(QFile::WriteOnly);
       
   251     file.write("a", 1);
       
   252     file.close();
       
   253     file.setPermissions(QFile::ReadOwner);
       
   254 
       
   255     // create another file and make it not readable
       
   256     file.setFileName("noreadfile");
       
   257     file.open(QFile::WriteOnly);
       
   258     file.write("b", 1);
       
   259     file.close();
       
   260     file.setPermissions(0);
       
   261 }
       
   262 
       
   263 void tst_QFile::cleanupTestCase()
       
   264 {
       
   265     // clean up the files we created
       
   266     QFile::remove("readonlyfile");
       
   267     QFile::remove("noreadfile");
       
   268     QFile::remove("myLink.lnk");
       
   269     QFile::remove("appendme.txt");
       
   270     QFile::remove("createme.txt");
       
   271     QFile::remove("file.txt");
       
   272     QFile::remove("genfile.txt");
       
   273     QFile::remove("seekToPos.txt");
       
   274     QFile::remove("setsizeseek.txt");
       
   275     QFile::remove("stdfile.txt");
       
   276     QFile::remove("textfile.txt");
       
   277     QFile::remove("truncate.txt");
       
   278     QFile::remove("winfile.txt");
       
   279     QFile::remove("writeonlyfile");
       
   280     QFile::remove("largeblockfile.txt");
       
   281     QFile::remove("tst_qfile_copy.cpp");
       
   282     QFile::remove("nullinline.txt");
       
   283     QFile::remove("myLink2.lnk");
       
   284     QFile::remove("resources");
       
   285     QFile::remove("qfile_map_testfile");
       
   286 }
       
   287 
       
   288 //------------------------------------------
       
   289 // The 'testfile' is currently just a
       
   290 // testfile. The path of this file, the
       
   291 // attributes and the contents itself
       
   292 // will be changed as far as we have a
       
   293 // proper way to handle files in the
       
   294 // testing enviroment.
       
   295 //------------------------------------------
       
   296 
       
   297 void tst_QFile::exists()
       
   298 {
       
   299     QFile f( SRCDIR "testfile.txt" );
       
   300     QCOMPARE( f.exists(), (bool)TRUE );
       
   301 
       
   302     QFile file("nobodyhassuchafile");
       
   303     file.remove();
       
   304     QVERIFY(!file.exists());
       
   305 
       
   306     QFile file2("nobodyhassuchafile");
       
   307     QVERIFY(file2.open(QIODevice::WriteOnly));
       
   308     file2.close();
       
   309 
       
   310     QVERIFY(file.exists());
       
   311 
       
   312     QVERIFY(file.open(QIODevice::WriteOnly));
       
   313     file.close();
       
   314     QVERIFY(file.exists());
       
   315 
       
   316     file.remove();
       
   317     QVERIFY(!file.exists());
       
   318 
       
   319 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   320     QFile unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt");
       
   321     QVERIFY(unc.exists());
       
   322 #endif
       
   323 }
       
   324 
       
   325 void tst_QFile::open_data()
       
   326 {
       
   327     QTest::addColumn<QString>("filename");
       
   328     QTest::addColumn<int>("mode");
       
   329     QTest::addColumn<bool>("ok");
       
   330     QTest::addColumn<QFile::FileError>("status");
       
   331 
       
   332 #ifdef Q_OS_MAC
       
   333     static const QString denied("Operation not permitted");
       
   334 #else
       
   335     static const QString denied("Permission denied");
       
   336 #endif
       
   337     QTest::newRow( "exist_readOnly"  )
       
   338         << QString(SRCDIR "testfile.txt") << int(QIODevice::ReadOnly)
       
   339         << (bool)TRUE << QFile::NoError;
       
   340 
       
   341     QTest::newRow( "exist_writeOnly" )
       
   342         << QString("readonlyfile")
       
   343         << int(QIODevice::WriteOnly)
       
   344         << (bool)FALSE
       
   345         << QFile::OpenError;
       
   346 
       
   347     QTest::newRow( "exist_append"    )
       
   348         << QString("readonlyfile") << int(QIODevice::Append)
       
   349         << (bool)FALSE << QFile::OpenError;
       
   350 
       
   351     QTest::newRow( "nonexist_readOnly"  )
       
   352         << QString("nonExist.txt") << int(QIODevice::ReadOnly)
       
   353         << (bool)FALSE << QFile::OpenError;
       
   354 
       
   355     QTest::newRow("emptyfile")
       
   356         << QString("")
       
   357         << int(QIODevice::ReadOnly)
       
   358         << (bool)FALSE
       
   359         << QFile::OpenError;
       
   360 
       
   361     QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly) << (bool)FALSE
       
   362         << QFile::OpenError;
       
   363 
       
   364     QTest::newRow("two-dots") << QString(SRCDIR "two.dots.file") << int(QIODevice::ReadOnly) << (bool)TRUE
       
   365         << QFile::NoError;
       
   366 
       
   367     QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly)
       
   368                                   << (bool)FALSE << QFile::OpenError;
       
   369     QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly)
       
   370                                 << (bool)FALSE << QFile::OpenError;
       
   371 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   372     QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
       
   373                                         << (bool)TRUE << QFile::NoError;
       
   374     QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testsharewritable/test.pri" << int(QIODevice::ReadOnly)
       
   375                              << true << QFile::NoError;
       
   376 #endif
       
   377 }
       
   378 
       
   379 void tst_QFile::open()
       
   380 {
       
   381     QFETCH( QString, filename );
       
   382     QFETCH( int, mode );
       
   383 
       
   384     QFile f( filename );
       
   385 
       
   386     QFETCH( bool, ok );
       
   387 
       
   388 #if defined(Q_OS_SYMBIAN)
       
   389     if (qstrcmp(QTest::currentDataTag(), "noreadfile") == 0)
       
   390         QSKIP("Symbian does not support non-readable files", SkipSingle);
       
   391 #elif defined(Q_OS_UNIX)
       
   392     if (::getuid() == 0)
       
   393         // root and Chuck Norris don't care for file permissions. Skip.
       
   394         QSKIP("Running this test as root doesn't make sense", SkipAll);
       
   395 #endif
       
   396 
       
   397 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
       
   398     QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort);
       
   399 #endif
       
   400     if (filename.isEmpty())
       
   401         QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
       
   402 
       
   403     QCOMPARE(f.open( QIODevice::OpenMode(mode) ), ok);
       
   404 
       
   405     QTEST( f.error(), "status" );
       
   406 }
       
   407 
       
   408 void tst_QFile::openUnbuffered()
       
   409 {
       
   410     QFile file(SRCDIR "testfile.txt");
       
   411     QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
       
   412     char c = '\0';
       
   413     QVERIFY(file.seek(1));
       
   414     QCOMPARE(file.pos(), qint64(1));
       
   415     QVERIFY(file.getChar(&c));
       
   416     QCOMPARE(file.pos(), qint64(2));
       
   417     char d = '\0';
       
   418     QVERIFY(file.seek(3));
       
   419     QCOMPARE(file.pos(), qint64(3));
       
   420     QVERIFY(file.getChar(&d));
       
   421     QCOMPARE(file.pos(), qint64(4));
       
   422     QVERIFY(file.seek(1));
       
   423     QCOMPARE(file.pos(), qint64(1));
       
   424     char c2 = '\0';
       
   425     QVERIFY(file.getChar(&c2));
       
   426     QCOMPARE(file.pos(), qint64(2));
       
   427     QVERIFY(file.seek(3));
       
   428     QCOMPARE(file.pos(), qint64(3));
       
   429     char d2 = '\0';
       
   430     QVERIFY(file.getChar(&d2));
       
   431     QCOMPARE(file.pos(), qint64(4));
       
   432     QCOMPARE(c, c2);
       
   433     QCOMPARE(d, d2);
       
   434     QCOMPARE(c, '-');
       
   435     QCOMPARE(d, '-');
       
   436 }
       
   437 
       
   438 void tst_QFile::size_data()
       
   439 {
       
   440     QTest::addColumn<QString>("filename");
       
   441     QTest::addColumn<int>("size");
       
   442 
       
   443     QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << 245;
       
   444     QTest::newRow( "nonexist01" ) << QString("foo.txt") << 0;
       
   445 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
   446     // Only test UNC on Windows./
       
   447     QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << 34;
       
   448 #endif
       
   449 }
       
   450 
       
   451 void tst_QFile::size()
       
   452 {
       
   453     QFETCH( QString, filename );
       
   454     QFile f( filename );
       
   455     QTEST( (int)f.size(), "size" );
       
   456     if (f.open(QFile::ReadOnly))
       
   457         QTEST( (int)f.size(), "size" );
       
   458 }
       
   459 
       
   460 void tst_QFile::seek()
       
   461 {
       
   462     QFile::remove("newfile.txt");
       
   463     QFile file("newfile.txt");
       
   464     file.open(QIODevice::WriteOnly);
       
   465     QCOMPARE(file.size(), qint64(0));
       
   466     QCOMPARE(file.pos(), qint64(0));
       
   467     QVERIFY(file.seek(10));
       
   468     QCOMPARE(file.pos(), qint64(10));
       
   469     QCOMPARE(file.size(), qint64(0));
       
   470     QFile::remove("newfile.txt");
       
   471 }
       
   472 
       
   473 void tst_QFile::setSize()
       
   474 {
       
   475     DEPENDS_ON( "size" );
       
   476 
       
   477     if ( QFile::exists( "createme.txt" ) )
       
   478         QFile::remove( "createme.txt" );
       
   479     QVERIFY( !QFile::exists( "createme.txt" ) );
       
   480 
       
   481     QFile f("createme.txt");
       
   482     QVERIFY(f.open(QIODevice::Truncate | QIODevice::ReadWrite));
       
   483     f.putChar('a');
       
   484 
       
   485     f.seek(0);
       
   486     char c = '\0';
       
   487     f.getChar(&c);
       
   488     QCOMPARE(c, 'a');
       
   489 
       
   490     QCOMPARE(f.size(), (qlonglong)1);
       
   491 	bool ok = f.resize(99);
       
   492     QVERIFY(ok);
       
   493     QCOMPARE(f.size(), (qlonglong)99);
       
   494 
       
   495     f.seek(0);
       
   496     c = '\0';
       
   497     f.getChar(&c);
       
   498     QCOMPARE(c, 'a');
       
   499 
       
   500     QVERIFY(f.resize(1));
       
   501     QCOMPARE(f.size(), (qlonglong)1);
       
   502 
       
   503     f.seek(0);
       
   504     c = '\0';
       
   505     f.getChar(&c);
       
   506     QCOMPARE(c, 'a');
       
   507 
       
   508     f.close();
       
   509 
       
   510     QCOMPARE(f.size(), (qlonglong)1);
       
   511     QVERIFY(f.resize(100));
       
   512     QCOMPARE(f.size(), (qlonglong)100);
       
   513     QVERIFY(f.resize(50));
       
   514     QCOMPARE(f.size(), (qlonglong)50);
       
   515 }
       
   516 
       
   517 void tst_QFile::setSizeSeek()
       
   518 {
       
   519     QFile::remove("setsizeseek.txt");
       
   520     QFile f("setsizeseek.txt");
       
   521     QVERIFY(f.open(QFile::WriteOnly));
       
   522     f.write("ABCD");
       
   523 
       
   524     QCOMPARE(f.pos(), qint64(4));
       
   525     f.resize(2);
       
   526     QCOMPARE(f.pos(), qint64(2));
       
   527     f.resize(4);
       
   528     QCOMPARE(f.pos(), qint64(2));
       
   529     f.resize(0);
       
   530     QCOMPARE(f.pos(), qint64(0));
       
   531     f.resize(4);
       
   532     QCOMPARE(f.pos(), qint64(0));
       
   533 
       
   534     f.seek(3);
       
   535     QCOMPARE(f.pos(), qint64(3));
       
   536     f.resize(2);
       
   537     QCOMPARE(f.pos(), qint64(2));
       
   538 }
       
   539 
       
   540 void tst_QFile::atEnd()
       
   541 {
       
   542     QFile f( SRCDIR "testfile.txt" );
       
   543     QVERIFY(f.open( QIODevice::ReadOnly ));
       
   544 
       
   545     int size = f.size();
       
   546     f.seek( size );
       
   547 
       
   548     bool end = f.atEnd();
       
   549     f.close();
       
   550     QCOMPARE( end, (bool)TRUE );
       
   551 }
       
   552 
       
   553 void tst_QFile::readLine()
       
   554 {
       
   555     QFile f( SRCDIR "testfile.txt" );
       
   556     QVERIFY(f.open( QIODevice::ReadOnly ));
       
   557 
       
   558     int i = 0;
       
   559     char p[128];
       
   560     int foo;
       
   561     while ( (foo=f.readLine( p, 128 )) > 0 ) {
       
   562         ++i;
       
   563         if ( i == 5 ) {
       
   564             QCOMPARE( p[0], 'T' );
       
   565             QCOMPARE( p[3], 's' );
       
   566             QCOMPARE( p[11], 'i' );
       
   567         }
       
   568     }
       
   569     f.close();
       
   570     QCOMPARE( i, 6 );
       
   571 }
       
   572 
       
   573 void tst_QFile::readLine2()
       
   574 {
       
   575     QFile f( SRCDIR "testfile.txt" );
       
   576     f.open( QIODevice::ReadOnly );
       
   577 
       
   578     char p[128];
       
   579     QCOMPARE(f.readLine(p, 60), qlonglong(59));
       
   580     QCOMPARE(f.readLine(p, 60), qlonglong(59));
       
   581     memset(p, '@', sizeof(p));
       
   582     QCOMPARE(f.readLine(p, 60), qlonglong(59));
       
   583 
       
   584     QCOMPARE(p[57], '-');
       
   585     QCOMPARE(p[58], '\n');
       
   586     QCOMPARE(p[59], '\0');
       
   587     QCOMPARE(p[60], '@');
       
   588 }
       
   589 
       
   590 void tst_QFile::readLineNullInLine()
       
   591 {
       
   592     QFile::remove("nullinline.txt");
       
   593     QFile file("nullinline.txt");
       
   594     QVERIFY(file.open(QIODevice::ReadWrite));
       
   595     QVERIFY(file.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0);
       
   596     QVERIFY(file.flush());
       
   597     file.reset();
       
   598 
       
   599     QCOMPARE(file.readLine(), QByteArray("linewith\0null\n", 14));
       
   600     QCOMPARE(file.readLine(), QByteArray("anotherline\0withnull\n", 21));
       
   601     QCOMPARE(file.readLine(), QByteArray("\0\n", 2));
       
   602     QCOMPARE(file.readLine(), QByteArray("null\0", 5));
       
   603     QCOMPARE(file.readLine(), QByteArray());
       
   604 }
       
   605 
       
   606 void tst_QFile::readAllStdin()
       
   607 {
       
   608 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
   609     QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll);
       
   610 #endif
       
   611 #if defined(QT_NO_PROCESS)
       
   612     QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
       
   613 #else
       
   614     QByteArray lotsOfData(1024, '@'); // 10 megs
       
   615 
       
   616     QProcess process;
       
   617     process.start("stdinprocess/stdinprocess all");
       
   618     for (int i = 0; i < 5; ++i) {
       
   619         QTest::qWait(1000);
       
   620         process.write(lotsOfData);
       
   621         while (process.bytesToWrite() > 0) {
       
   622             QVERIFY(process.waitForBytesWritten());
       
   623         }
       
   624     }
       
   625 
       
   626     process.closeWriteChannel();
       
   627     process.waitForFinished();
       
   628     QCOMPARE(process.readAll().size(), lotsOfData.size() * 5);
       
   629 #endif
       
   630 }
       
   631 
       
   632 void tst_QFile::readLineStdin()
       
   633 {
       
   634 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
   635     QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll);
       
   636 #endif
       
   637 #if defined(QT_NO_PROCESS)
       
   638     QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
       
   639 #else
       
   640 
       
   641     QByteArray lotsOfData(1024, '@'); // 10 megs
       
   642     for (int i = 0; i < lotsOfData.size(); ++i) {
       
   643         if ((i % 32) == 31)
       
   644             lotsOfData[i] = '\n';
       
   645         else
       
   646             lotsOfData[i] = char('0' + i % 32);
       
   647     }
       
   648 
       
   649     for (int i = 0; i < 2; ++i) {
       
   650         QProcess process;
       
   651         process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
       
   652         for (int i = 0; i < 5; ++i) {
       
   653             QTest::qWait(1000);
       
   654             process.write(lotsOfData);
       
   655             while (process.bytesToWrite() > 0) {
       
   656                 QVERIFY(process.waitForBytesWritten());
       
   657             }
       
   658         }
       
   659 
       
   660         process.closeWriteChannel();
       
   661         QVERIFY(process.waitForFinished(5000));
       
   662 
       
   663         QByteArray array = process.readAll();
       
   664         QCOMPARE(array.size(), lotsOfData.size() * 5);
       
   665         for (int i = 0; i < array.size(); ++i) {
       
   666             if ((i % 32) == 31)
       
   667                 QCOMPARE(char(array[i]), '\n');
       
   668             else
       
   669                 QCOMPARE(char(array[i]), char('0' + i % 32));
       
   670         }
       
   671     }
       
   672 #endif
       
   673 }
       
   674 
       
   675 void tst_QFile::readLineStdin_lineByLine()
       
   676 {
       
   677 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
   678     QSKIP("Currently no stdin/out supported for Windows CE", SkipAll);
       
   679 #endif
       
   680 #if defined(QT_NO_PROCESS)
       
   681     QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
       
   682 #else
       
   683     for (int i = 0; i < 2; ++i) {
       
   684         QProcess process;
       
   685         process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
       
   686         QVERIFY(process.waitForStarted());
       
   687 
       
   688         for (int j = 0; j < 3; ++j) {
       
   689             QByteArray line = "line " + QByteArray::number(j) + "\n";
       
   690             QCOMPARE(process.write(line), qint64(line.size()));
       
   691             QVERIFY(process.waitForBytesWritten(2000));
       
   692             if (process.bytesAvailable() == 0)
       
   693                 QVERIFY(process.waitForReadyRead(2000));
       
   694             QCOMPARE(process.readAll(), line);
       
   695         }
       
   696 
       
   697         process.closeWriteChannel();
       
   698         QVERIFY(process.waitForFinished(5000));
       
   699     }
       
   700 #endif
       
   701 }
       
   702 
       
   703 void tst_QFile::text()
       
   704 {
       
   705     // dosfile.txt is a binary CRLF file
       
   706     QFile file(SRCDIR "dosfile.txt");
       
   707     QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
       
   708     QCOMPARE(file.readLine(),
       
   709             QByteArray("/dev/system/root     /                    reiserfs   acl,user_xattr        1 1\n"));
       
   710     QCOMPARE(file.readLine(),
       
   711             QByteArray("/dev/sda1            /boot                ext3       acl,user_xattr        1 2\n"));
       
   712     file.ungetChar('\n');
       
   713     file.ungetChar('2');
       
   714     QCOMPARE(file.readLine().constData(), QByteArray("2\n").constData());
       
   715 }
       
   716 
       
   717 void tst_QFile::missingEndOfLine()
       
   718 {
       
   719     QFile file(SRCDIR "noendofline.txt");
       
   720     QVERIFY(file.open(QFile::ReadOnly));
       
   721 
       
   722     int nlines = 0;
       
   723     while (!file.atEnd()) {
       
   724         ++nlines;
       
   725         file.readLine();
       
   726     }
       
   727 
       
   728     QCOMPARE(nlines, 3);
       
   729 }
       
   730 
       
   731 void tst_QFile::readBlock()
       
   732 {
       
   733     QFile f( SRCDIR "testfile.txt" );
       
   734     f.open( QIODevice::ReadOnly );
       
   735 
       
   736     int length = 0;
       
   737     char p[256];
       
   738     length = f.read( p, 256 );
       
   739     f.close();
       
   740     QCOMPARE( length, 245 );
       
   741     QCOMPARE( p[59], 'D' );
       
   742     QCOMPARE( p[178], 'T' );
       
   743     QCOMPARE( p[199], 'l' );
       
   744 }
       
   745 
       
   746 void tst_QFile::getch()
       
   747 {
       
   748     QFile f( SRCDIR "testfile.txt" );
       
   749     f.open( QIODevice::ReadOnly );
       
   750 
       
   751     char c;
       
   752     int i = 0;
       
   753     while (f.getChar(&c)) {
       
   754         QCOMPARE(f.pos(), qint64(i + 1));
       
   755         if ( i == 59 )
       
   756             QCOMPARE( c, 'D' );
       
   757         ++i;
       
   758     }
       
   759     f.close();
       
   760     QCOMPARE( i, 245 );
       
   761 }
       
   762 
       
   763 void tst_QFile::ungetChar()
       
   764 {
       
   765     QFile f(SRCDIR "testfile.txt");
       
   766     QVERIFY(f.open(QIODevice::ReadOnly));
       
   767 
       
   768     QByteArray array = f.readLine();
       
   769     QCOMPARE(array.constData(), "----------------------------------------------------------\n");
       
   770     f.ungetChar('\n');
       
   771 
       
   772     array = f.readLine();
       
   773     QCOMPARE(array.constData(), "\n");
       
   774 
       
   775     f.ungetChar('\n');
       
   776     f.ungetChar('-');
       
   777     f.ungetChar('-');
       
   778 
       
   779     array = f.readLine();
       
   780     QCOMPARE(array.constData(), "--\n");
       
   781 
       
   782     QFile::remove("genfile.txt");
       
   783     QFile out("genfile.txt");
       
   784     QVERIFY(out.open(QIODevice::ReadWrite));
       
   785     out.write("123");
       
   786     out.seek(0);
       
   787     QCOMPARE(out.readAll().constData(), "123");
       
   788     out.ungetChar('3');
       
   789     out.write("4");
       
   790     out.seek(0);
       
   791     QCOMPARE(out.readAll().constData(), "124");
       
   792     out.ungetChar('4');
       
   793     out.ungetChar('2');
       
   794     out.ungetChar('1');
       
   795     char buf[3];
       
   796     QCOMPARE(out.read(buf, sizeof(buf)), qint64(3));
       
   797     QCOMPARE(buf[0], '1');
       
   798     QCOMPARE(buf[1], '2');
       
   799     QCOMPARE(buf[2], '4');
       
   800 }
       
   801 
       
   802 void tst_QFile::invalidFile_data()
       
   803 {
       
   804     QTest::addColumn<QString>("fileName");
       
   805 #if !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN)
       
   806     QTest::newRow( "x11" ) << QString( "qwe//" );
       
   807 #else
       
   808     QTest::newRow( "colon1" ) << QString( "fail:invalid" );
       
   809     QTest::newRow( "colon2" ) << QString( "f:ail:invalid" );
       
   810     QTest::newRow( "colon3" ) << QString( ":failinvalid" );
       
   811     QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
       
   812     QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
       
   813     QTest::newRow( "questionmark" ) << QString( "fail?invalid" );
       
   814     QTest::newRow( "quote" ) << QString( "fail\"invalid" );
       
   815     QTest::newRow( "lt" ) << QString( "fail<invalid" );
       
   816     QTest::newRow( "gt" ) << QString( "fail>invalid" );
       
   817     QTest::newRow( "pipe" ) << QString( "fail|invalid" );
       
   818 #endif
       
   819 }
       
   820 
       
   821 void tst_QFile::invalidFile()
       
   822 {
       
   823     QFETCH( QString, fileName );
       
   824     QFile f( fileName );
       
   825     QVERIFY( !f.open( QIODevice::ReadWrite ) );
       
   826 }
       
   827 
       
   828 void tst_QFile::createFile()
       
   829 {
       
   830     if ( QFile::exists( "createme.txt" ) )
       
   831         QFile::remove( "createme.txt" );
       
   832     QVERIFY( !QFile::exists( "createme.txt" ) );
       
   833 
       
   834     QFile f( "createme.txt" );
       
   835     QVERIFY( f.open( QIODevice::WriteOnly ) );
       
   836     f.close();
       
   837     QVERIFY( QFile::exists( "createme.txt" ) );
       
   838 }
       
   839 
       
   840 void tst_QFile::append()
       
   841 {
       
   842     const QString name("appendme.txt");
       
   843     if (QFile::exists(name))
       
   844         QFile::remove(name);
       
   845     QVERIFY(!QFile::exists(name));
       
   846 
       
   847     QFile f(name);
       
   848     QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
       
   849     f.putChar('a');
       
   850     f.close();
       
   851 
       
   852     QVERIFY(f.open(QIODevice::Append));
       
   853     QVERIFY(f.pos() == 1);
       
   854     f.putChar('a');
       
   855     f.close();
       
   856     QCOMPARE(int(f.size()), 2);
       
   857 }
       
   858 
       
   859 void tst_QFile::permissions_data()
       
   860 {
       
   861     QTest::addColumn<QString>("file");
       
   862     QTest::addColumn<uint>("perms");
       
   863     QTest::addColumn<bool>("expected");
       
   864 
       
   865     QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true;
       
   866     QTest::newRow("data1") << SRCDIR "tst_qfile.cpp" << uint(QFile::ReadUser) << true;
       
   867 //    QTest::newRow("data2") << "tst_qfile.cpp" << int(QFile::WriteUser) << false;
       
   868     QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser) << true;
       
   869     QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser) << false;
       
   870     QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser) << false;
       
   871 }
       
   872 
       
   873 void tst_QFile::permissions()
       
   874 {
       
   875 #if defined(Q_OS_SYMBIAN)
       
   876     if (qstrcmp(QTest::currentDataTag(), "data0") == 0)
       
   877         QSKIP("Symbian does not have execution permissions", SkipSingle);
       
   878 #endif
       
   879     QFETCH(QString, file);
       
   880     QFETCH(uint, perms);
       
   881     QFETCH(bool, expected);
       
   882     QFile f(file);
       
   883     QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected);
       
   884 }
       
   885 
       
   886 void tst_QFile::setPermissions()
       
   887 {
       
   888     DEPENDS_ON( "permissions" ); //if that doesn't work...
       
   889 
       
   890     if ( QFile::exists( "createme.txt" ) )
       
   891         QFile::remove( "createme.txt" );
       
   892     QVERIFY( !QFile::exists( "createme.txt" ) );
       
   893 
       
   894     QFile f("createme.txt");
       
   895     QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
       
   896     f.putChar('a');
       
   897     f.close();
       
   898 
       
   899     QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser);
       
   900     QVERIFY(f.setPermissions(perms));
       
   901     QVERIFY((f.permissions() & perms) == perms);
       
   902 
       
   903 }
       
   904 
       
   905 void tst_QFile::copy()
       
   906 {
       
   907     QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser);
       
   908     QFile::remove("tst_qfile_copy.cpp");
       
   909     QFile::remove("test2");
       
   910     QVERIFY(QFile::copy(SRCDIR "tst_qfile.cpp", "tst_qfile_copy.cpp"));
       
   911     QFile in1(SRCDIR "tst_qfile.cpp"), in2("tst_qfile_copy.cpp");
       
   912     QVERIFY(in1.open(QFile::ReadOnly));
       
   913     QVERIFY(in2.open(QFile::ReadOnly));
       
   914     QByteArray data1 = in1.readAll(), data2 = in2.readAll();
       
   915     QCOMPARE(data1, data2);
       
   916     QFile::remove( "main_copy.cpp" );
       
   917 
       
   918     QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2"));
       
   919 }
       
   920 
       
   921 void tst_QFile::copyAfterFail()
       
   922 {
       
   923     QFile file1("file-to-be-copied.txt");
       
   924     QFile file2("existing-file.txt");
       
   925 
       
   926     QVERIFY(file1.open(QIODevice::ReadWrite) && "(test-precondition)");
       
   927     QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
       
   928     file2.close();
       
   929     QVERIFY(!QFile::exists("copied-file-1.txt") && "(test-precondition)");
       
   930     QVERIFY(!QFile::exists("copied-file-2.txt") && "(test-precondition)");
       
   931 
       
   932     QVERIFY(!file1.copy("existing-file.txt"));
       
   933     QCOMPARE(file1.error(), QFile::CopyError);
       
   934 
       
   935     QVERIFY(file1.copy("copied-file-1.txt"));
       
   936     QVERIFY(!file1.isOpen());
       
   937     QCOMPARE(file1.error(), QFile::NoError);
       
   938 
       
   939     QVERIFY(!file1.copy("existing-file.txt"));
       
   940     QCOMPARE(file1.error(), QFile::CopyError);
       
   941 
       
   942     QVERIFY(file1.copy("copied-file-2.txt"));
       
   943     QVERIFY(!file1.isOpen());
       
   944     QCOMPARE(file1.error(), QFile::NoError);
       
   945 
       
   946     QVERIFY(QFile::exists("copied-file-1.txt"));
       
   947     QVERIFY(QFile::exists("copied-file-2.txt"));
       
   948 
       
   949     QVERIFY(QFile::remove("file-to-be-copied.txt") && "(test-cleanup)");
       
   950     QVERIFY(QFile::remove("existing-file.txt") && "(test-cleanup)");
       
   951     QVERIFY(QFile::remove("copied-file-1.txt") && "(test-cleanup)");
       
   952     QVERIFY(QFile::remove("copied-file-2.txt") && "(test-cleanup)");
       
   953 }
       
   954 
       
   955 void tst_QFile::copyRemovesTemporaryFile() const
       
   956 {
       
   957     const QString newName(QLatin1String("copyRemovesTemporaryFile"));
       
   958     QVERIFY(QFile::copy(SRCDIR "forCopying.txt", newName));
       
   959 
       
   960     QVERIFY(!QFile::exists(QLatin1String( SRCDIR "qt_temp.XXXXXX")));
       
   961     QVERIFY(QFile::remove(newName));
       
   962 }
       
   963 
       
   964 void tst_QFile::copyShouldntOverwrite()
       
   965 {
       
   966     // Copy should not overwrite existing files.
       
   967     QFile::remove("tst_qfile.cpy");
       
   968     QFile file(SRCDIR "tst_qfile.cpp");
       
   969     QVERIFY(file.copy("tst_qfile.cpy"));
       
   970 #if defined(Q_OS_SYMBIAN)
       
   971 	bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteUser);
       
   972 #else
       
   973 	bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther);
       
   974 #endif
       
   975     QVERIFY(ok);
       
   976     QVERIFY(!file.copy("tst_qfile.cpy"));
       
   977     QFile::remove("tst_qfile.cpy");
       
   978 }
       
   979 
       
   980 void tst_QFile::copyFallback()
       
   981 {
       
   982     // Using a resource file to trigger QFile::copy's fallback handling
       
   983     QFile file(":/copy-fallback.qrc");
       
   984     QFile::remove("file-copy-destination.txt");
       
   985 
       
   986     QVERIFY2(file.exists(), "test precondition");
       
   987     QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition");
       
   988 
       
   989     // Fallback copy of closed file.
       
   990     QVERIFY(file.copy("file-copy-destination.txt"));
       
   991     QVERIFY(QFile::exists("file-copy-destination.txt"));
       
   992     QVERIFY(!file.isOpen());
       
   993 
       
   994     // Need to reset permissions on Windows to be able to delete
       
   995     QVERIFY(QFile::setPermissions("file-copy-destination.txt",
       
   996             QFile::ReadOwner | QFile::WriteOwner));
       
   997     QVERIFY(QFile::remove("file-copy-destination.txt"));
       
   998 
       
   999     // Fallback copy of open file.
       
  1000     QVERIFY(file.open(QIODevice::ReadOnly));
       
  1001     QVERIFY(file.copy("file-copy-destination.txt"));
       
  1002     QVERIFY(QFile::exists("file-copy-destination.txt"));
       
  1003     QVERIFY(!file.isOpen());
       
  1004 
       
  1005     QFile::remove("file-copy-destination.txt");
       
  1006 }
       
  1007 
       
  1008 #ifdef Q_OS_WIN
       
  1009 #include <objbase.h>
       
  1010 #include <shlobj.h>
       
  1011 #endif
       
  1012 
       
  1013 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1014 static QString getWorkingDirectoryForLink(const QString &linkFileName)
       
  1015 {
       
  1016     bool neededCoInit = false;
       
  1017     QString ret;
       
  1018 
       
  1019     IShellLink *psl;
       
  1020     HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
       
  1021     if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
       
  1022         neededCoInit = true;
       
  1023         CoInitialize(NULL);
       
  1024         hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
       
  1025     }
       
  1026 
       
  1027     if (SUCCEEDED(hres)) {    // Get pointer to the IPersistFile interface.
       
  1028         IPersistFile *ppf;
       
  1029         hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
       
  1030         if (SUCCEEDED(hres))  {
       
  1031             hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
       
  1032             //The original path of the link is retrieved. If the file/folder
       
  1033             //was moved, the return value still have the old path.
       
  1034             if(SUCCEEDED(hres)) {
       
  1035                 wchar_t szGotPath[MAX_PATH];
       
  1036                 if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
       
  1037                     ret = QString::fromWCharArray(szGotPath);
       
  1038             }
       
  1039             ppf->Release();
       
  1040         }
       
  1041         psl->Release();
       
  1042     }
       
  1043 
       
  1044     if (neededCoInit) {
       
  1045         CoUninitialize();
       
  1046     }
       
  1047 
       
  1048     return ret;
       
  1049 }
       
  1050 #endif
       
  1051 
       
  1052 void tst_QFile::link()
       
  1053 {
       
  1054     QFile::remove("myLink.lnk");
       
  1055     QFileInfo info1("tst_qfile.cpp");
       
  1056     QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk"));
       
  1057     QFileInfo info2("myLink.lnk");
       
  1058     QVERIFY(info2.isSymLink());
       
  1059     QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
       
  1060 
       
  1061 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1062     QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath());
       
  1063     QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath());
       
  1064 #endif
       
  1065     QVERIFY(QFile::remove(info2.absoluteFilePath()));
       
  1066 }
       
  1067 
       
  1068 void tst_QFile::linkToDir()
       
  1069 {
       
  1070 #if defined(Q_OS_SYMBIAN)
       
  1071     QSKIP("Symbian does not support linking to directories", SkipAll);
       
  1072 #endif
       
  1073     QFile::remove("myLinkToDir.lnk");
       
  1074     QDir dir;
       
  1075     dir.mkdir("myDir");
       
  1076     QFileInfo info1("myDir");
       
  1077     QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
       
  1078     QFileInfo info2("myLinkToDir.lnk");
       
  1079 #if !(defined Q_OS_HPUX && defined(__ia64))
       
  1080     // absurd HP-UX filesystem bug on gravlaks - checking if a symlink
       
  1081     // resolves or not alters the file system to make the broken symlink
       
  1082     // later fail...
       
  1083     QVERIFY(info2.isSymLink());
       
  1084 #endif
       
  1085     QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
       
  1086     QVERIFY(QFile::remove(info2.absoluteFilePath()));
       
  1087     QFile::remove("myLinkToDir.lnk");
       
  1088     dir.rmdir("myDir");
       
  1089 }
       
  1090 
       
  1091 void tst_QFile::absolutePathLinkToRelativePath()
       
  1092 {
       
  1093     QFile::remove("myDir/test.txt");
       
  1094     QFile::remove("myDir/myLink.lnk");
       
  1095     QDir dir;
       
  1096     dir.mkdir("myDir");
       
  1097     QFile("myDir/test.txt").open(QFile::WriteOnly);
       
  1098 
       
  1099 #ifdef Q_OS_WIN
       
  1100     QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
       
  1101 #else
       
  1102     QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
       
  1103 #endif
       
  1104     QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix/Symbian", Continue);
       
  1105     QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(),
       
  1106              QFileInfo("myDir/test.txt").absoluteFilePath());
       
  1107 
       
  1108     QFile::remove("myDir/test.txt");
       
  1109     QFile::remove("myDir/myLink.lnk");
       
  1110     dir.rmdir("myDir");
       
  1111 }
       
  1112 
       
  1113 void tst_QFile::readBrokenLink()
       
  1114 {
       
  1115     QFile::remove("myLink2.lnk");
       
  1116     QFileInfo info1("file12");
       
  1117 #if defined(Q_OS_SYMBIAN)
       
  1118     // In Symbian can't link to nonexisting file directly, so create the file temporarily
       
  1119     QFile tempFile("file12");
       
  1120     tempFile.open(QIODevice::WriteOnly);
       
  1121     tempFile.link("myLink2.lnk");
       
  1122     tempFile.remove();
       
  1123 #else
       
  1124     QVERIFY(QFile::link("file12", "myLink2.lnk"));
       
  1125 #endif
       
  1126     QFileInfo info2("myLink2.lnk");
       
  1127     QVERIFY(info2.isSymLink());
       
  1128     QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
       
  1129     QVERIFY(QFile::remove(info2.absoluteFilePath()));
       
  1130 
       
  1131 #if !defined(Q_OS_SYMBIAN)
       
  1132     QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
       
  1133     QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
       
  1134 #endif
       
  1135 }
       
  1136 
       
  1137 void tst_QFile::readTextFile_data()
       
  1138 {
       
  1139     QTest::addColumn<QByteArray>("in");
       
  1140     QTest::addColumn<QByteArray>("out");
       
  1141 
       
  1142     QTest::newRow("empty") << QByteArray() << QByteArray();
       
  1143     QTest::newRow("a") << QByteArray("a") << QByteArray("a");
       
  1144     QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab");
       
  1145     QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n");
       
  1146     QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n");
       
  1147     QTest::newRow("\\r") << QByteArray("\r") << QByteArray();
       
  1148     QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n");
       
  1149     QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld");
       
  1150 }
       
  1151 
       
  1152 void tst_QFile::readTextFile()
       
  1153 {
       
  1154     QFETCH(QByteArray, in);
       
  1155     QFETCH(QByteArray, out);
       
  1156 
       
  1157     QFile winfile("winfile.txt");
       
  1158     QVERIFY(winfile.open(QFile::WriteOnly | QFile::Truncate));
       
  1159     winfile.write(in);
       
  1160     winfile.close();
       
  1161 
       
  1162     QVERIFY(winfile.open(QFile::ReadOnly));
       
  1163     QCOMPARE(winfile.readAll(), in);
       
  1164     winfile.close();
       
  1165 
       
  1166     QVERIFY(winfile.open(QFile::ReadOnly | QFile::Text));
       
  1167     QCOMPARE(winfile.readAll(), out);
       
  1168 }
       
  1169 
       
  1170 void tst_QFile::readTextFile2()
       
  1171 {
       
  1172     {
       
  1173         QFile file(SRCDIR "testlog.txt");
       
  1174         QVERIFY(file.open(QIODevice::ReadOnly));
       
  1175         file.read(4097);
       
  1176     }
       
  1177 
       
  1178     {
       
  1179         QFile file(SRCDIR "testlog.txt");
       
  1180         QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
       
  1181         file.read(4097);
       
  1182     }
       
  1183 }
       
  1184 
       
  1185 void tst_QFile::writeTextFile_data()
       
  1186 {
       
  1187     QTest::addColumn<QByteArray>("in");
       
  1188 
       
  1189     QTest::newRow("empty") << QByteArray();
       
  1190     QTest::newRow("a") << QByteArray("a");
       
  1191     QTest::newRow("a\\rb") << QByteArray("a\rb");
       
  1192     QTest::newRow("\\n") << QByteArray("\n");
       
  1193     QTest::newRow("\\r\\n") << QByteArray("\r\n");
       
  1194     QTest::newRow("\\r") << QByteArray("\r");
       
  1195     QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n");
       
  1196     QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld");
       
  1197     QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n");
       
  1198     QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld");
       
  1199     QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n");
       
  1200 }
       
  1201 
       
  1202 void tst_QFile::writeTextFile()
       
  1203 {
       
  1204     QFETCH(QByteArray, in);
       
  1205 
       
  1206     QFile file("textfile.txt");
       
  1207     QVERIFY(file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text));
       
  1208     QByteArray out = in;
       
  1209 #ifdef Q_OS_WIN
       
  1210     out.replace('\n', "\r\n");
       
  1211 #endif
       
  1212     QCOMPARE(file.write(in), qlonglong(in.size()));
       
  1213     file.close();
       
  1214 
       
  1215     file.open(QFile::ReadOnly);
       
  1216     QCOMPARE(file.readAll(), out);
       
  1217 }
       
  1218 
       
  1219 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1220 void tst_QFile::largeUncFileSupport()
       
  1221 {
       
  1222     qint64 size = Q_INT64_C(8589934592);
       
  1223     qint64 dataOffset = Q_INT64_C(8589914592);
       
  1224     QByteArray knownData("LargeFile content at offset 8589914592");
       
  1225     QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
       
  1226 
       
  1227     {
       
  1228         // 1) Native file handling.
       
  1229         QFile file(largeFile);
       
  1230         QCOMPARE(file.size(), size);
       
  1231         QVERIFY(file.open(QIODevice::ReadOnly));
       
  1232         QCOMPARE(file.size(), size);
       
  1233         QVERIFY(file.seek(dataOffset));
       
  1234         QCOMPARE(file.read(knownData.size()), knownData);
       
  1235     }
       
  1236     {
       
  1237         // 2) stdlib file handling.
       
  1238 #if _MSC_VER <= 1310
       
  1239         QSKIP("platform SDK for MSVC 2003 does not support large files", SkipAll);
       
  1240 #endif
       
  1241         QFile file;
       
  1242         FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
       
  1243         QVERIFY(file.open(fh, QIODevice::ReadOnly));
       
  1244         QCOMPARE(file.size(), size);
       
  1245         QVERIFY(file.seek(dataOffset));
       
  1246         QCOMPARE(file.read(knownData.size()), knownData);
       
  1247         fclose(fh);
       
  1248     }
       
  1249     {
       
  1250         // 3) stdio file handling.
       
  1251         QFile file;
       
  1252         FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
       
  1253         int fd = int(_fileno(fh));
       
  1254         QVERIFY(file.open(fd, QIODevice::ReadOnly));
       
  1255         QCOMPARE(file.size(), size);
       
  1256         QVERIFY(file.seek(dataOffset));
       
  1257         QCOMPARE(file.read(knownData.size()), knownData);
       
  1258         fclose(fh);
       
  1259     }
       
  1260 }
       
  1261 #endif
       
  1262 
       
  1263 void tst_QFile::tailFile()
       
  1264 {
       
  1265     QSKIP("File change notifications are so far unsupported.", SkipAll);
       
  1266 
       
  1267     QFile file("tail.txt");
       
  1268     QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
       
  1269 
       
  1270     QFile tailFile("tail.txt");
       
  1271     QVERIFY(tailFile.open(QFile::ReadOnly));
       
  1272     tailFile.seek(file.size());
       
  1273 
       
  1274     QSignalSpy readSignal(&tailFile, SIGNAL(readyRead()));
       
  1275 
       
  1276     file.write("", 1);
       
  1277 
       
  1278     QTestEventLoop::instance().enterLoop(5);
       
  1279 
       
  1280     QVERIFY(!QTestEventLoop::instance().timeout());
       
  1281     QCOMPARE(readSignal.count(), 1);
       
  1282 }
       
  1283 
       
  1284 void tst_QFile::flush()
       
  1285 {
       
  1286 	QString fileName("stdfile.txt");
       
  1287 
       
  1288 	QFile::remove(fileName);
       
  1289 
       
  1290 	{
       
  1291 		QFile file(fileName);
       
  1292 		QVERIFY(file.open(QFile::WriteOnly));
       
  1293 		QCOMPARE(file.write("abc", 3),qint64(3));
       
  1294 	}
       
  1295 
       
  1296 	{
       
  1297 		QFile file(fileName);
       
  1298 		QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
       
  1299         QCOMPARE(file.pos(), qlonglong(3));
       
  1300         QCOMPARE(file.write("def", 3), qlonglong(3));
       
  1301         QCOMPARE(file.pos(), qlonglong(6));
       
  1302     }
       
  1303 
       
  1304     {
       
  1305         QFile file("stdfile.txt");
       
  1306         QVERIFY(file.open(QFile::ReadOnly));
       
  1307         QCOMPARE(file.readAll(), QByteArray("abcdef"));
       
  1308     }
       
  1309 
       
  1310 	QFile::remove(fileName);
       
  1311 }
       
  1312 
       
  1313 void tst_QFile::bufferedRead()
       
  1314 {
       
  1315     QFile::remove("stdfile.txt");
       
  1316 
       
  1317     QFile file("stdfile.txt");
       
  1318     QVERIFY(file.open(QFile::WriteOnly));
       
  1319     file.write("abcdef");
       
  1320     file.close();
       
  1321 
       
  1322 #if defined(Q_OS_WINCE)
       
  1323 	FILE *stdFile = fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r");
       
  1324 #else
       
  1325     FILE *stdFile = fopen("stdfile.txt", "r");
       
  1326 #endif
       
  1327     QVERIFY(stdFile);
       
  1328     char c;
       
  1329     QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1);
       
  1330     QCOMPARE(c, 'a');
       
  1331     QCOMPARE(int(ftell(stdFile)), 1);
       
  1332 
       
  1333     {
       
  1334         QFile file;
       
  1335         QVERIFY(file.open(stdFile, QFile::ReadOnly));
       
  1336         QCOMPARE(file.pos(), qlonglong(1));
       
  1337         QCOMPARE(file.read(&c, 1), qlonglong(1));
       
  1338         QCOMPARE(c, 'b');
       
  1339         QCOMPARE(file.pos(), qlonglong(2));
       
  1340     }
       
  1341 
       
  1342     fclose(stdFile);
       
  1343 }
       
  1344 
       
  1345 void tst_QFile::isSequential()
       
  1346 {
       
  1347 #if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
  1348     QSKIP("Unix only test.", SkipAll);
       
  1349 #endif
       
  1350 
       
  1351     QFile zero("/dev/null");
       
  1352     QVERIFY(zero.open(QFile::ReadOnly));
       
  1353     QVERIFY(zero.isSequential());
       
  1354 }
       
  1355 
       
  1356 void tst_QFile::encodeName()
       
  1357 {
       
  1358     QCOMPARE(QFile::encodeName(QString::null), QByteArray());
       
  1359 }
       
  1360 
       
  1361 void tst_QFile::truncate()
       
  1362 {
       
  1363     for (int i = 0; i < 2; ++i) {
       
  1364         QFile file("truncate.txt");
       
  1365         QVERIFY(file.open(QFile::WriteOnly));
       
  1366         file.write(QByteArray(200, '@'));
       
  1367         file.close();
       
  1368 
       
  1369         QVERIFY(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate));
       
  1370         file.write(QByteArray(100, '$'));
       
  1371         file.close();
       
  1372 
       
  1373         QVERIFY(file.open(QFile::ReadOnly));
       
  1374         QCOMPARE(file.readAll(), QByteArray(100, '$'));
       
  1375     }
       
  1376 }
       
  1377 
       
  1378 void tst_QFile::seekToPos()
       
  1379 {
       
  1380     {
       
  1381         QFile file("seekToPos.txt");
       
  1382         QVERIFY(file.open(QFile::WriteOnly));
       
  1383         file.write("a\r\nb\r\nc\r\n");
       
  1384         file.flush();
       
  1385     }
       
  1386 
       
  1387     QFile file("seekToPos.txt");
       
  1388     QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
       
  1389     file.seek(1);
       
  1390     char c;
       
  1391     QVERIFY(file.getChar(&c));
       
  1392     QCOMPARE(c, '\n');
       
  1393 
       
  1394     QCOMPARE(file.pos(), qint64(3));
       
  1395     file.seek(file.pos());
       
  1396     QCOMPARE(file.pos(), qint64(3));
       
  1397 
       
  1398     file.seek(1);
       
  1399     file.seek(file.pos());
       
  1400     QCOMPARE(file.pos(), qint64(1));
       
  1401 
       
  1402 }
       
  1403 
       
  1404 
       
  1405 void tst_QFile::FILEReadWrite()
       
  1406 {
       
  1407     // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these
       
  1408     // 4 bytes with new values. At the end check to see the file contains the new values.
       
  1409 
       
  1410     QFile::remove("FILEReadWrite.txt");
       
  1411 
       
  1412     // create test file
       
  1413     {
       
  1414         QFile f("FILEReadWrite.txt");
       
  1415         QVERIFY(f.open(QFile::WriteOnly));
       
  1416         QDataStream ds(&f);
       
  1417         qint8 c = 0;
       
  1418         ds << c;
       
  1419         c = 1;
       
  1420         ds << c;
       
  1421         c = 2;
       
  1422         ds << c;
       
  1423         c = 3;
       
  1424         ds << c;
       
  1425         c = 4;
       
  1426         ds << c;
       
  1427         c = 5;
       
  1428         ds << c;
       
  1429         c = 6;
       
  1430         ds << c;
       
  1431         c = 7;
       
  1432         ds << c;
       
  1433         c = 8;
       
  1434         ds << c;
       
  1435         c = 9;
       
  1436         ds << c;
       
  1437         c = 10;
       
  1438         ds << c;
       
  1439         c = 11;
       
  1440         ds << c;
       
  1441         f.close();
       
  1442     }
       
  1443 
       
  1444 #ifdef Q_OS_WINCE
       
  1445     FILE *fp = fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
       
  1446 #else
       
  1447     FILE *fp = fopen("FILEReadWrite.txt", "r+b");
       
  1448 #endif
       
  1449     QVERIFY(fp);
       
  1450     QFile file;
       
  1451     QVERIFY(file.open(fp, QFile::ReadWrite));
       
  1452     QDataStream sfile(&file) ;
       
  1453 
       
  1454     qint8 var1,var2,var3,var4;
       
  1455     while (!sfile.atEnd())
       
  1456     {
       
  1457         qint64 base = file.pos();
       
  1458 
       
  1459         QCOMPARE(file.pos(), base + 0);
       
  1460         sfile >> var1;
       
  1461         QCOMPARE(file.pos(), base + 1);
       
  1462         file.flush(); // flushing should not change the base
       
  1463         QCOMPARE(file.pos(), base + 1);
       
  1464         sfile >> var2;
       
  1465         QCOMPARE(file.pos(), base + 2);
       
  1466         sfile >> var3;
       
  1467         QCOMPARE(file.pos(), base + 3);
       
  1468         sfile >> var4;
       
  1469         QCOMPARE(file.pos(), base + 4);
       
  1470         file.seek(file.pos() - 4) ;   // Move it back 4, for we are going to write new values based on old ones
       
  1471         QCOMPARE(file.pos(), base + 0);
       
  1472         sfile << qint8(var1 + 5);
       
  1473         QCOMPARE(file.pos(), base + 1);
       
  1474         sfile << qint8(var2 + 5);
       
  1475         QCOMPARE(file.pos(), base + 2);
       
  1476         sfile << qint8(var3 + 5);
       
  1477         QCOMPARE(file.pos(), base + 3);
       
  1478         sfile << qint8(var4 + 5);
       
  1479         QCOMPARE(file.pos(), base + 4);
       
  1480 
       
  1481     }
       
  1482     file.close();
       
  1483     fclose(fp);
       
  1484 
       
  1485     // check modified file
       
  1486     {
       
  1487         QFile f("FILEReadWrite.txt");
       
  1488         QVERIFY(f.open(QFile::ReadOnly));
       
  1489         QDataStream ds(&f);
       
  1490         qint8 c = 0;
       
  1491         ds >> c;
       
  1492         QCOMPARE(c, (qint8)5);
       
  1493         ds >> c;
       
  1494         QCOMPARE(c, (qint8)6);
       
  1495         ds >> c;
       
  1496         QCOMPARE(c, (qint8)7);
       
  1497         ds >> c;
       
  1498         QCOMPARE(c, (qint8)8);
       
  1499         ds >> c;
       
  1500         QCOMPARE(c, (qint8)9);
       
  1501         ds >> c;
       
  1502         QCOMPARE(c, (qint8)10);
       
  1503         ds >> c;
       
  1504         QCOMPARE(c, (qint8)11);
       
  1505         ds >> c;
       
  1506         QCOMPARE(c, (qint8)12);
       
  1507         ds >> c;
       
  1508         QCOMPARE(c, (qint8)13);
       
  1509         ds >> c;
       
  1510         QCOMPARE(c, (qint8)14);
       
  1511         ds >> c;
       
  1512         QCOMPARE(c, (qint8)15);
       
  1513         ds >> c;
       
  1514         QCOMPARE(c, (qint8)16);
       
  1515         f.close();
       
  1516     }
       
  1517 
       
  1518     QFile::remove("FILEReadWrite.txt");
       
  1519 }
       
  1520 
       
  1521 
       
  1522 /*
       
  1523 #include <qglobal.h>
       
  1524 #define BUFFSIZE 1
       
  1525 #define FILESIZE   0x10000000f
       
  1526 void tst_QFile::largeFileSupport()
       
  1527 {
       
  1528 #ifdef Q_OS_SOLARIS
       
  1529     QSKIP("Solaris does not support statfs", SkipAll);
       
  1530 #else
       
  1531     qlonglong sizeNeeded = 2147483647;
       
  1532     sizeNeeded *= 2;
       
  1533     sizeNeeded += 1024;
       
  1534     qlonglong freespace = qlonglong(0);
       
  1535 #ifdef Q_WS_WIN
       
  1536     _ULARGE_INTEGER free;
       
  1537     if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0))
       
  1538         freespace = free.QuadPart;
       
  1539     if (freespace != 0) {
       
  1540 #elif defined(Q_OS_IRIX)
       
  1541     struct statfs info;
       
  1542     if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
       
  1543         freespace = qlonglong(info.f_bfree * info.f_bsize);
       
  1544 #else
       
  1545     struct statfs info;
       
  1546     if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
       
  1547         freespace = qlonglong(info.f_bavail * info.f_bsize);
       
  1548 #endif
       
  1549         if (freespace > sizeNeeded) {
       
  1550             QFile bigFile("bigfile");
       
  1551             if (bigFile.open(QFile::ReadWrite)) {
       
  1552                 char c[BUFFSIZE] = {'a'};
       
  1553                 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
       
  1554                 qlonglong oldPos = bigFile.pos();
       
  1555                 QVERIFY(bigFile.resize(sizeNeeded));
       
  1556                 QCOMPARE(oldPos, bigFile.pos());
       
  1557                 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
       
  1558                 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
       
  1559 
       
  1560                 bigFile.close();
       
  1561                 if (bigFile.open(QFile::ReadOnly)) {
       
  1562                     QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
       
  1563                     int i = 0;
       
  1564                     for (i=0; i<BUFFSIZE; i++)
       
  1565                         QCOMPARE(c[i], 'a');
       
  1566                     QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
       
  1567                     QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
       
  1568                     for (i=0; i<BUFFSIZE; i++)
       
  1569                         QCOMPARE(c[i], 'a');
       
  1570                     bigFile.close();
       
  1571                     QVERIFY(bigFile.remove());
       
  1572                 } else {
       
  1573                     QVERIFY(bigFile.remove());
       
  1574                     QFAIL("Could not reopen file");
       
  1575                 }
       
  1576             } else {
       
  1577                 QFAIL("Could not open file");
       
  1578             }
       
  1579         } else {
       
  1580             QSKIP("Not enough space to run test", SkipSingle);
       
  1581         }
       
  1582     } else {
       
  1583         QFAIL("Could not determin disk space");
       
  1584     }
       
  1585 #endif
       
  1586 }
       
  1587 */
       
  1588 
       
  1589 void tst_QFile::i18nFileName_data()
       
  1590 {
       
  1591     QTest::addColumn<QString>("fileName");
       
  1592 
       
  1593     QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt");
       
  1594 }
       
  1595 
       
  1596 void tst_QFile::i18nFileName()
       
  1597 {
       
  1598      QFETCH(QString, fileName);
       
  1599      if (QFile::exists(fileName)) {
       
  1600          QVERIFY(QFile::remove(fileName));
       
  1601      }
       
  1602      {
       
  1603         QFile file(fileName);
       
  1604         QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
       
  1605         QTextStream ts(&file);
       
  1606         ts.setCodec("UTF-8");
       
  1607         ts << fileName << endl;
       
  1608      }
       
  1609      {
       
  1610         QFile file(fileName);
       
  1611         QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
       
  1612         QTextStream ts(&file);
       
  1613         ts.setCodec("UTF-8");
       
  1614         QString line = ts.readLine();
       
  1615         QCOMPARE(line, fileName);
       
  1616      }
       
  1617      QVERIFY(QFile::remove(fileName));
       
  1618 }
       
  1619 
       
  1620 
       
  1621 void tst_QFile::longFileName_data()
       
  1622 {
       
  1623     QTest::addColumn<QString>("fileName");
       
  1624 
       
  1625     QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt");
       
  1626     QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt");
       
  1627     QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
       
  1628                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1629                                                      "longFileNamelongFileNamelongFileNamelongFileName.txt");
       
  1630     QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
       
  1631                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1632                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1633                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1634                                                      "longFileNamelongFileNamelongFileNamelongFileName.txt");
       
  1635     QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
       
  1636                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1637                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1638                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1639                                                      "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
       
  1640   /* needs to be put on a windows 2000 > test machine
       
  1641   QTest::newRow( "244 chars on UNC" ) <<  QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName"
       
  1642                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1643                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1644                                                      "longFileNamelongFileNamelongFileNamelongFileName"
       
  1645                                                      "longFileNamelongFileNamelongFileNamelongFileName.txt");*/
       
  1646 }
       
  1647 
       
  1648 void tst_QFile::longFileName()
       
  1649 {
       
  1650     QFETCH(QString, fileName);
       
  1651     if (QFile::exists(fileName)) {
       
  1652         QVERIFY(QFile::remove(fileName));
       
  1653     }
       
  1654     {
       
  1655         QFile file(fileName);
       
  1656 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
  1657         QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
       
  1658         QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
       
  1659 #endif
       
  1660         QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
       
  1661         QTextStream ts(&file);
       
  1662         ts << fileName << endl;
       
  1663     }
       
  1664     {
       
  1665         QFile file(fileName);
       
  1666         QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
       
  1667         QTextStream ts(&file);
       
  1668         QString line = ts.readLine();
       
  1669         QCOMPARE(line, fileName);
       
  1670     }
       
  1671     QString newName = fileName + QLatin1String("1");
       
  1672     {
       
  1673         QVERIFY(QFile::copy(fileName, newName));
       
  1674         QFile file(newName);
       
  1675         QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
       
  1676         QTextStream ts(&file);
       
  1677         QString line = ts.readLine();
       
  1678         QCOMPARE(line, fileName);
       
  1679 
       
  1680     }
       
  1681     QVERIFY(QFile::remove(newName));
       
  1682     {
       
  1683         QVERIFY(QFile::rename(fileName, newName));
       
  1684         QFile file(newName);
       
  1685         QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
       
  1686         QTextStream ts(&file);
       
  1687         QString line = ts.readLine();
       
  1688         QCOMPARE(line, fileName);
       
  1689     }
       
  1690     QVERIFY(QFile::exists(newName));
       
  1691     QVERIFY(QFile::remove(newName));
       
  1692 }
       
  1693 
       
  1694 class MyEngine : public QAbstractFileEngine
       
  1695 {
       
  1696 public:
       
  1697     MyEngine(int n) { number = n; }
       
  1698     virtual ~MyEngine() {}
       
  1699 
       
  1700     void setFileName(const QString &) {}
       
  1701     bool open(int ) { return false; }
       
  1702     bool close() { return false; }
       
  1703     bool flush() { return false; }
       
  1704     qint64 size() const { return 123 + number; }
       
  1705     qint64 at() const { return -1; }
       
  1706     bool seek(qint64) { return false; }
       
  1707     bool isSequential() const { return false; }
       
  1708     qint64 read(char *, qint64) { return -1; }
       
  1709     qint64 write(const char *, qint64) { return -1; }
       
  1710     bool remove() { return false; }
       
  1711     bool copy(const QString &) { return false; }
       
  1712     bool rename(const QString &) { return false; }
       
  1713     bool link(const QString &) { return false; }
       
  1714     bool mkdir(const QString &, bool) const { return false; }
       
  1715     bool rmdir(const QString &, bool) const { return false; }
       
  1716     bool setSize(qint64) { return false; }
       
  1717     QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); }
       
  1718     bool caseSensitive() const { return false; }
       
  1719     bool isRelativePath() const { return false; }
       
  1720     FileFlags fileFlags(FileFlags) const { return 0; }
       
  1721     bool chmod(uint) { return false; }
       
  1722     QString fileName(FileName) const { return name; }
       
  1723     uint ownerId(FileOwner) const { return 0; }
       
  1724     QString owner(FileOwner) const { return QString(); }
       
  1725     QDateTime fileTime(FileTime) const { return QDateTime(); }
       
  1726 
       
  1727 private:
       
  1728     int number;
       
  1729     QString name;
       
  1730 };
       
  1731 
       
  1732 class MyHandler : public QAbstractFileEngineHandler
       
  1733 {
       
  1734 public:
       
  1735     inline QAbstractFileEngine *create(const QString &) const
       
  1736     {
       
  1737         return new MyEngine(1);
       
  1738     }
       
  1739 };
       
  1740 
       
  1741 class MyHandler2 : public QAbstractFileEngineHandler
       
  1742 {
       
  1743 public:
       
  1744     inline QAbstractFileEngine *create(const QString &) const
       
  1745     {
       
  1746         return new MyEngine(2);
       
  1747     }
       
  1748 };
       
  1749 
       
  1750 void tst_QFile::fileEngineHandler()
       
  1751 {
       
  1752     // A file that does not exist has a size of 0.
       
  1753     QFile::remove("ole.bull");
       
  1754     QFile file("ole.bull");
       
  1755     QCOMPARE(file.size(), qint64(0));
       
  1756 
       
  1757     // Instantiating our handler will enable the new engine.
       
  1758     MyHandler handler;
       
  1759     file.setFileName("ole.bull");
       
  1760     QCOMPARE(file.size(), qint64(124));
       
  1761 
       
  1762     // A new, identical handler should take preference over the last one.
       
  1763     MyHandler2 handler2;
       
  1764     file.setFileName("ole.bull");
       
  1765     QCOMPARE(file.size(), qint64(125));
       
  1766 
       
  1767 }
       
  1768 
       
  1769 class MyRecursiveHandler : public QAbstractFileEngineHandler
       
  1770 {
       
  1771 public:
       
  1772     inline QAbstractFileEngine *create(const QString &fileName) const
       
  1773     {
       
  1774         if (fileName.startsWith(":!")) {
       
  1775             QDir dir;
       
  1776             QString realFile = SRCDIR + fileName.mid(2);
       
  1777             if (dir.exists(realFile))
       
  1778                 return new QFSFileEngine(realFile);
       
  1779         }
       
  1780         return 0;
       
  1781     }
       
  1782 };
       
  1783 
       
  1784 void tst_QFile::useQFileInAFileHandler()
       
  1785 {
       
  1786     // This test should not dead-lock
       
  1787     MyRecursiveHandler handler;
       
  1788     QFile file(":!tst_qfile.cpp");
       
  1789     QVERIFY(file.exists());
       
  1790 }
       
  1791 
       
  1792 void tst_QFile::getCharFF()
       
  1793 {
       
  1794     QFile file("file.txt");
       
  1795     file.open(QFile::ReadWrite);
       
  1796     file.write("\xff\xff\xff");
       
  1797     file.flush();
       
  1798     file.seek(0);
       
  1799 
       
  1800     char c;
       
  1801     QVERIFY(file.getChar(&c));
       
  1802     QVERIFY(file.getChar(&c));
       
  1803     QVERIFY(file.getChar(&c));
       
  1804 }
       
  1805 
       
  1806 void tst_QFile::remove_and_exists()
       
  1807 {
       
  1808     QFile::remove("tull_i_grunn.txt");
       
  1809     QFile f("tull_i_grunn.txt");
       
  1810 
       
  1811     QVERIFY(!f.exists());
       
  1812 
       
  1813     bool opened = f.open(QIODevice::WriteOnly);
       
  1814     QVERIFY(opened);
       
  1815 
       
  1816     f.write(QString("testing that remove/exists work...").toLatin1());
       
  1817     f.close();
       
  1818 
       
  1819     QVERIFY(f.exists());
       
  1820 
       
  1821     f.remove();
       
  1822     QVERIFY(!f.exists());
       
  1823 }
       
  1824 
       
  1825 void tst_QFile::removeOpenFile()
       
  1826 {
       
  1827     {
       
  1828         // remove an opened, write-only file
       
  1829         QFile::remove("remove_unclosed.txt");
       
  1830         QFile f("remove_unclosed.txt");
       
  1831 
       
  1832         QVERIFY(!f.exists());
       
  1833         bool opened = f.open(QIODevice::WriteOnly);
       
  1834         QVERIFY(opened);
       
  1835         f.write(QString("testing that remove closes the file first...").toLatin1());
       
  1836 
       
  1837         bool removed = f.remove(); // remove should both close and remove the file
       
  1838         QVERIFY(removed);
       
  1839         QVERIFY(!f.isOpen());
       
  1840         QVERIFY(!f.exists());
       
  1841         QVERIFY(f.error() == QFile::NoError);
       
  1842     }
       
  1843 
       
  1844     {
       
  1845         // remove an opened, read-only file
       
  1846         QFile::remove("remove_unclosed.txt");
       
  1847 
       
  1848         // first, write a file that we can remove
       
  1849         {
       
  1850             QFile f("remove_unclosed.txt");
       
  1851             QVERIFY(!f.exists());
       
  1852             bool opened = f.open(QIODevice::WriteOnly);
       
  1853             QVERIFY(opened);
       
  1854             f.write(QString("testing that remove closes the file first...").toLatin1());
       
  1855             f.close();
       
  1856         }
       
  1857 
       
  1858         QFile f("remove_unclosed.txt");
       
  1859         bool opened = f.open(QIODevice::ReadOnly);
       
  1860         QVERIFY(opened);
       
  1861         f.readAll();
       
  1862         // this used to only fail on FreeBSD (and Mac OS X)
       
  1863         QVERIFY(f.flush());
       
  1864         bool removed = f.remove(); // remove should both close and remove the file
       
  1865         QVERIFY(removed);
       
  1866         QVERIFY(!f.isOpen());
       
  1867         QVERIFY(!f.exists());
       
  1868         QVERIFY(f.error() == QFile::NoError);
       
  1869     }
       
  1870 }
       
  1871 
       
  1872 void tst_QFile::fullDisk()
       
  1873 {
       
  1874     QFile file("/dev/full");
       
  1875     if (!file.exists())
       
  1876         QSKIP("/dev/full doesn't exist on this system", SkipAll);
       
  1877 
       
  1878     QVERIFY(file.open(QIODevice::WriteOnly));
       
  1879     file.write("foobar", 6);
       
  1880 
       
  1881     QVERIFY(!file.flush());
       
  1882     QCOMPARE(file.error(), QFile::ResourceError);
       
  1883     QVERIFY(!file.flush());
       
  1884     QCOMPARE(file.error(), QFile::ResourceError);
       
  1885 
       
  1886     char c = 0;
       
  1887     file.write(&c, 0);
       
  1888     QVERIFY(!file.flush());
       
  1889     QCOMPARE(file.error(), QFile::ResourceError);
       
  1890     file.write(&c, 1);
       
  1891     QVERIFY(!file.flush());
       
  1892     QCOMPARE(file.error(), QFile::ResourceError);
       
  1893 
       
  1894     file.close();
       
  1895     QVERIFY(!file.isOpen());
       
  1896     QCOMPARE(file.error(), QFile::ResourceError);
       
  1897     file.open(QIODevice::WriteOnly);
       
  1898     QCOMPARE(file.error(), QFile::NoError);
       
  1899     file.close();
       
  1900     QCOMPARE(file.error(), QFile::NoError);
       
  1901 
       
  1902     // try again without flush:
       
  1903     QVERIFY(file.open(QIODevice::WriteOnly));
       
  1904     file.write("foobar", 6);
       
  1905     file.close();
       
  1906     QVERIFY(file.error() != QFile::NoError);
       
  1907 }
       
  1908 
       
  1909 void tst_QFile::writeLargeDataBlock_data()
       
  1910 {
       
  1911     QTest::addColumn<QString>("fileName");
       
  1912 
       
  1913     QTest::newRow("localfile") << QString("./largeblockfile.txt");
       
  1914 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1915     // Some semi-randomness to avoid collisions.
       
  1916     QTest::newRow("unc file")
       
  1917         << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
       
  1918         .arg(QHostInfo::localHostName())
       
  1919         .arg(QTime::currentTime().msec());
       
  1920 #endif
       
  1921 }
       
  1922 
       
  1923 void tst_QFile::writeLargeDataBlock()
       
  1924 {
       
  1925     QFETCH(QString, fileName);
       
  1926 
       
  1927     // Generate a 64MB array with well defined contents.
       
  1928     QByteArray array;
       
  1929 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
  1930 	int resizeSize = 1024 * 1024; // WinCE and Symbian do not have much space
       
  1931 #else
       
  1932 	int resizeSize = 64 * 1024 * 1024;
       
  1933 #endif
       
  1934     array.resize(resizeSize);
       
  1935     for (int i = 0; i < array.size(); ++i)
       
  1936         array[i] = uchar(i);
       
  1937 
       
  1938     // Remove and open the target file
       
  1939     QFile file(fileName);
       
  1940     file.remove();
       
  1941     if (file.open(QFile::WriteOnly)) {
       
  1942         QCOMPARE(file.write(array), qint64(array.size()));
       
  1943         file.close();
       
  1944         QVERIFY(file.open(QFile::ReadOnly));
       
  1945         array.clear();
       
  1946         array = file.readAll();
       
  1947         file.remove();
       
  1948     } else {
       
  1949         QFAIL(qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName)));
       
  1950     }
       
  1951     // Check that we got the right content
       
  1952     QCOMPARE(array.size(), resizeSize);
       
  1953     for (int i = 0; i < array.size(); ++i) {
       
  1954         if (array[i] != char(i)) {
       
  1955             QFAIL(qPrintable(QString("Wrong contents! Char at %1 = %2, expected %3")
       
  1956                   .arg(i).arg(int(uchar(array[i]))).arg(int(uchar(i)))));
       
  1957         }
       
  1958     }
       
  1959 }
       
  1960 
       
  1961 void tst_QFile::readFromWriteOnlyFile()
       
  1962 {
       
  1963     QFile file("writeonlyfile");
       
  1964     QVERIFY(file.open(QFile::WriteOnly));
       
  1965     char c;
       
  1966     QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device");
       
  1967     QCOMPARE(file.read(&c, 1), qint64(-1));
       
  1968 }
       
  1969 
       
  1970 void tst_QFile::writeToReadOnlyFile()
       
  1971 {
       
  1972     QFile file("readonlyfile");
       
  1973     QVERIFY(file.open(QFile::ReadOnly));
       
  1974     char c = 0;
       
  1975     QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device");
       
  1976     QCOMPARE(file.write(&c, 1), qint64(-1));
       
  1977 }
       
  1978 
       
  1979 void tst_QFile::virtualFile()
       
  1980 {
       
  1981     // test if QFile works with virtual files
       
  1982     QString fname;
       
  1983 #if defined(Q_OS_LINUX)
       
  1984     fname = "/proc/self/maps";
       
  1985 #elif defined(Q_OS_AIX)
       
  1986     fname = QString("/proc/%1/map").arg(getpid());
       
  1987 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
       
  1988     fname = "/proc/curproc/map";
       
  1989 #else
       
  1990     QSKIP("This platform does not have 0-sized virtual files", SkipAll);
       
  1991 #endif
       
  1992 
       
  1993     // consistency check
       
  1994     QFileInfo fi(fname);
       
  1995     QVERIFY(fi.exists());
       
  1996     QVERIFY(fi.isFile());
       
  1997     QCOMPARE(fi.size(), Q_INT64_C(0));
       
  1998 
       
  1999     // open the file
       
  2000     QFile f(fname);
       
  2001     QVERIFY(f.open(QIODevice::ReadOnly));
       
  2002     QCOMPARE(f.size(), Q_INT64_C(0));
       
  2003     QVERIFY(f.atEnd());
       
  2004 
       
  2005     // read data
       
  2006     QByteArray data = f.read(16);
       
  2007     QCOMPARE(data.size(), 16);
       
  2008     QCOMPARE(f.pos(), Q_INT64_C(16));
       
  2009 
       
  2010     // line-reading
       
  2011     data = f.readLine();
       
  2012     QVERIFY(!data.isEmpty());
       
  2013 
       
  2014     // read all:
       
  2015     data = f.readAll();
       
  2016     QVERIFY(f.pos() != 0);
       
  2017     QVERIFY(!data.isEmpty());
       
  2018 
       
  2019     // seeking
       
  2020     QVERIFY(f.seek(1));
       
  2021     QCOMPARE(f.pos(), Q_INT64_C(1));
       
  2022 }
       
  2023 
       
  2024 void tst_QFile::textFile()
       
  2025 {
       
  2026 #if defined(Q_OS_WINCE)
       
  2027 	FILE *fs = ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toAscii() , "wt");
       
  2028 #elif defined(Q_OS_WIN)
       
  2029     FILE *fs = ::fopen("writeabletextfile", "wt");
       
  2030 #else
       
  2031     FILE *fs = ::fopen("writeabletextfile", "w");
       
  2032 #endif
       
  2033     QFile f;
       
  2034     QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n");
       
  2035     QByteArray part2("Add\nsome\nmore\nnewlines\n");
       
  2036 
       
  2037     QVERIFY(f.open(fs, QIODevice::WriteOnly));
       
  2038     f.write(part1);
       
  2039     f.write(part2);
       
  2040     f.close();
       
  2041     ::fclose(fs);
       
  2042 
       
  2043     QFile file("writeabletextfile");
       
  2044     QVERIFY(file.open(QIODevice::ReadOnly));
       
  2045 
       
  2046     QByteArray data = file.readAll();
       
  2047 
       
  2048     QByteArray expected = part1 + part2;
       
  2049 #ifdef Q_OS_WIN
       
  2050     expected.replace("\n", "\015\012");
       
  2051 #endif
       
  2052     QCOMPARE(data, expected);
       
  2053     file.close();
       
  2054     file.remove();
       
  2055 }
       
  2056 
       
  2057 void tst_QFile::rename_data()
       
  2058 {
       
  2059     QTest::addColumn<QString>("source");
       
  2060     QTest::addColumn<QString>("destination");
       
  2061     QTest::addColumn<bool>("result");
       
  2062 
       
  2063     QTest::newRow("a -> b") << QString("a") << QString("b") << false;
       
  2064     QTest::newRow("a -> .") << QString("a") << QString(".") << false;
       
  2065     QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
       
  2066     QTest::newRow("renamefile -> Makefile") << QString("renamefile") << QString("Makefile") << false;
       
  2067 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
       
  2068     QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
       
  2069 #endif
       
  2070     QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true;
       
  2071     QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false;
       
  2072 }
       
  2073 
       
  2074 void tst_QFile::rename()
       
  2075 {
       
  2076     QFETCH(QString, source);
       
  2077     QFETCH(QString, destination);
       
  2078     QFETCH(bool, result);
       
  2079 
       
  2080     QFile::remove("renamedfile");
       
  2081     QFile f("renamefile");
       
  2082     f.open(QFile::WriteOnly);
       
  2083     f.close();
       
  2084 
       
  2085     QFile file(source);
       
  2086     QCOMPARE(file.rename(destination), result);
       
  2087     if (result)
       
  2088         QCOMPARE(file.error(), QFile::NoError);
       
  2089     else
       
  2090         QCOMPARE(file.error(), QFile::RenameError);
       
  2091 
       
  2092     QFile::remove("renamefile");
       
  2093 }
       
  2094 
       
  2095 /*!
       
  2096  \since 4.5
       
  2097 
       
  2098  Some special files have QFile::atEnd() returning true, even though there is
       
  2099  more data available. True for corner cases, as well as some mounts on OS X.
       
  2100 
       
  2101  Here, we reproduce that condition by having a QFile sub-class with this
       
  2102  peculiar atEnd() behavior.
       
  2103 
       
  2104  See task 231583.
       
  2105  */
       
  2106 void tst_QFile::renameWithAtEndSpecialFile() const
       
  2107 {
       
  2108     class PeculiarAtEnd : public QFile
       
  2109     {
       
  2110     public:
       
  2111         virtual bool atEnd() const
       
  2112         {
       
  2113             return true;
       
  2114         }
       
  2115     };
       
  2116 
       
  2117     const QString newName(QLatin1String("newName.txt"));
       
  2118     /* Cleanup, so we're a bit more robust. */
       
  2119     QFile::remove(newName);
       
  2120 
       
  2121     const QString originalName(QString(SRCDIR "forRenaming.txt"));
       
  2122 
       
  2123     PeculiarAtEnd file;
       
  2124     file.setFileName(originalName);
       
  2125     QVERIFY(file.open(QIODevice::ReadOnly));
       
  2126 
       
  2127     QVERIFY(file.rename(newName));
       
  2128 
       
  2129     file.close();
       
  2130     /* Guess what, we have to rename it back, otherwise we'll fail on second
       
  2131      * invocation. */
       
  2132     QVERIFY(QFile::rename(newName, originalName));
       
  2133 }
       
  2134 
       
  2135 void tst_QFile::renameFallback()
       
  2136 {
       
  2137     // Using a resource file both to trigger QFile::rename's fallback handling
       
  2138     // and as a *read-only* source whose move should fail.
       
  2139     QFile file(":/rename-fallback.qrc");
       
  2140     QVERIFY(file.exists() && "(test-precondition)");
       
  2141     QFile::remove("file-rename-destination.txt");
       
  2142 
       
  2143     QVERIFY(!file.rename("file-rename-destination.txt"));
       
  2144     QVERIFY(!QFile::exists("file-rename-destination.txt"));
       
  2145     QVERIFY(!file.isOpen());
       
  2146 }
       
  2147 
       
  2148 void tst_QFile::renameMultiple()
       
  2149 {
       
  2150     // create the file if it doesn't exist
       
  2151     QFile file("file-to-be-renamed.txt");
       
  2152     QFile file2("existing-file.txt");
       
  2153     QVERIFY(file.open(QIODevice::ReadWrite) && "(test-precondition)");
       
  2154     QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
       
  2155 
       
  2156     // any stale files from previous test failures?
       
  2157     QFile::remove("file-renamed-once.txt");
       
  2158     QFile::remove("file-renamed-twice.txt");
       
  2159 
       
  2160     // begin testing
       
  2161     QVERIFY(QFile::exists("existing-file.txt"));
       
  2162     QVERIFY(!file.rename("existing-file.txt"));
       
  2163     QCOMPARE(file.error(), QFile::RenameError);
       
  2164     QCOMPARE(file.fileName(), QString("file-to-be-renamed.txt"));
       
  2165 
       
  2166     QVERIFY(file.rename("file-renamed-once.txt"));
       
  2167     QVERIFY(!file.isOpen());
       
  2168     QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
       
  2169 
       
  2170     QVERIFY(QFile::exists("existing-file.txt"));
       
  2171     QVERIFY(!file.rename("existing-file.txt"));
       
  2172     QCOMPARE(file.error(), QFile::RenameError);
       
  2173     QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
       
  2174 
       
  2175     QVERIFY(file.rename("file-renamed-twice.txt"));
       
  2176     QVERIFY(!file.isOpen());
       
  2177     QCOMPARE(file.fileName(), QString("file-renamed-twice.txt"));
       
  2178 
       
  2179     QVERIFY(QFile::exists("existing-file.txt"));
       
  2180     QVERIFY(!QFile::exists("file-to-be-renamed.txt"));
       
  2181     QVERIFY(!QFile::exists("file-renamed-once.txt"));
       
  2182     QVERIFY(QFile::exists("file-renamed-twice.txt"));
       
  2183 
       
  2184     file.remove();
       
  2185     file2.remove();
       
  2186     QVERIFY(!QFile::exists("file-renamed-twice.txt"));
       
  2187     QVERIFY(!QFile::exists("existing-file.txt"));
       
  2188 }
       
  2189 
       
  2190 void tst_QFile::appendAndRead()
       
  2191 {
       
  2192     QFile writeFile(QLatin1String("appendfile.txt"));
       
  2193     QVERIFY(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
       
  2194 
       
  2195     QFile readFile(QLatin1String("appendfile.txt"));
       
  2196     QVERIFY(readFile.open(QIODevice::ReadOnly));
       
  2197 
       
  2198     // Write to the end of the file, then read that character back, and so on.
       
  2199     for (int i = 0; i < 100; ++i) {
       
  2200         char c = '\0';
       
  2201         writeFile.putChar(char(i % 256));
       
  2202         writeFile.flush();
       
  2203         QVERIFY(readFile.getChar(&c));
       
  2204         QCOMPARE(c, char(i % 256));
       
  2205         QCOMPARE(readFile.pos(), writeFile.pos());
       
  2206     }
       
  2207 
       
  2208     // Write blocks and read them back
       
  2209     for (int j = 0; j < 18; ++j) {
       
  2210         writeFile.write(QByteArray(1 << j, '@'));
       
  2211         writeFile.flush();
       
  2212         QCOMPARE(readFile.read(1 << j).size(), 1 << j);
       
  2213     }
       
  2214 
       
  2215     QFile::remove(QLatin1String("appendfile.txt"));
       
  2216 }
       
  2217 
       
  2218 void tst_QFile::miscWithUncPathAsCurrentDir()
       
  2219 {
       
  2220 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  2221     QString current = QDir::currentPath();
       
  2222     QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testsharewritable"));
       
  2223     QFile file("test.pri");
       
  2224     QVERIFY(file.exists());
       
  2225     QCOMPARE(int(file.size()), 34);
       
  2226     QVERIFY(file.open(QIODevice::ReadOnly));
       
  2227     QVERIFY(QDir::setCurrent(current));
       
  2228 #endif
       
  2229 }
       
  2230 
       
  2231 void tst_QFile::standarderror()
       
  2232 {
       
  2233     QFile f;
       
  2234     bool ok = f.open(stderr, QFile::WriteOnly);
       
  2235     QVERIFY(ok);
       
  2236     f.close();
       
  2237 }
       
  2238 
       
  2239 void tst_QFile::handle()
       
  2240 {
       
  2241 #ifndef Q_OS_WINCE
       
  2242     QFile file(SRCDIR "tst_qfile.cpp");
       
  2243     QVERIFY(file.open(QIODevice::ReadOnly));
       
  2244     int fd = int(file.handle());
       
  2245     QVERIFY(fd > 2);
       
  2246     QCOMPARE(int(file.handle()), fd);
       
  2247     char c = '\0';
       
  2248     QT_READ(int(file.handle()), &c, 1);
       
  2249     QCOMPARE(c, '/');
       
  2250 
       
  2251     // test if the QFile and the handle remain in sync
       
  2252     QVERIFY(file.getChar(&c));
       
  2253     QCOMPARE(c, '*');
       
  2254 
       
  2255     // same, but read from QFile first now
       
  2256     file.close();
       
  2257     QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
       
  2258     fd = int(file.handle());
       
  2259     QVERIFY(fd > 2);
       
  2260     QVERIFY(file.getChar(&c));
       
  2261     QCOMPARE(c, '/');
       
  2262 #ifdef Q_OS_UNIX
       
  2263     QCOMPARE(QT_READ(fd, &c, 1), ssize_t(1));
       
  2264 #else
       
  2265     QCOMPARE(QT_READ(fd, &c, 1), 1);
       
  2266 #endif
       
  2267 
       
  2268     QCOMPARE(c, '*');
       
  2269 #endif
       
  2270 
       
  2271     QFile file2;
       
  2272     FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r");
       
  2273     file2.open(fp, QIODevice::ReadOnly);
       
  2274     QCOMPARE(int(file2.handle()), int(fileno(fp)));
       
  2275     QCOMPARE(int(file2.handle()), int(fileno(fp)));
       
  2276     fclose(fp);
       
  2277 
       
  2278 #ifdef Q_OS_UNIX
       
  2279     QFile file3;
       
  2280     fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY);
       
  2281     file3.open(fd, QIODevice::ReadOnly);
       
  2282     QCOMPARE(int(file3.handle()), fd);
       
  2283     QT_CLOSE(fd);
       
  2284 #endif
       
  2285 }
       
  2286 
       
  2287 void tst_QFile::readEof_data()
       
  2288 {
       
  2289     QTest::addColumn<QString>("filename");
       
  2290     QTest::addColumn<int>("imode");
       
  2291 
       
  2292     QTest::newRow("buffered") << SRCDIR "testfile.txt" << 0;
       
  2293     QTest::newRow("unbuffered") << SRCDIR "testfile.txt" << int(QIODevice::Unbuffered);
       
  2294 
       
  2295 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
       
  2296     QTest::newRow("sequential,buffered") << "/dev/null" << 0;
       
  2297     QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered);
       
  2298 #endif
       
  2299 }
       
  2300 
       
  2301 void tst_QFile::readEof()
       
  2302 {
       
  2303     QFETCH(QString, filename);
       
  2304     QFETCH(int, imode);
       
  2305     QIODevice::OpenMode mode = QIODevice::OpenMode(imode);
       
  2306 
       
  2307     {
       
  2308         QFile file(filename);
       
  2309         QVERIFY(file.open(QIODevice::ReadOnly | mode));
       
  2310         bool isSequential = file.isSequential();
       
  2311         if (!isSequential) {
       
  2312             QVERIFY(file.seek(245));
       
  2313             QVERIFY(file.atEnd());
       
  2314         }
       
  2315 
       
  2316         char buf[10];
       
  2317         int ret = file.read(buf, sizeof buf);
       
  2318         QCOMPARE(ret, 0);
       
  2319         QVERIFY(file.error() == QFile::NoError);
       
  2320         QVERIFY(file.atEnd());
       
  2321 
       
  2322         // Do it again to ensure that we get the same result
       
  2323         ret = file.read(buf, sizeof buf);
       
  2324         QCOMPARE(ret, 0);
       
  2325         QVERIFY(file.error() == QFile::NoError);
       
  2326         QVERIFY(file.atEnd());
       
  2327     }
       
  2328 
       
  2329     {
       
  2330         QFile file(filename);
       
  2331         QVERIFY(file.open(QIODevice::ReadOnly | mode));
       
  2332         bool isSequential = file.isSequential();
       
  2333         if (!isSequential) {
       
  2334             QVERIFY(file.seek(245));
       
  2335             QVERIFY(file.atEnd());
       
  2336         }
       
  2337 
       
  2338         QByteArray ret = file.read(10);
       
  2339         QVERIFY(ret.isNull());
       
  2340         QVERIFY(file.error() == QFile::NoError);
       
  2341         QVERIFY(file.atEnd());
       
  2342 
       
  2343         // Do it again to ensure that we get the same result
       
  2344         ret = file.read(10);
       
  2345         QVERIFY(ret.isNull());
       
  2346         QVERIFY(file.error() == QFile::NoError);
       
  2347         QVERIFY(file.atEnd());
       
  2348     }
       
  2349 
       
  2350     {
       
  2351         QFile file(filename);
       
  2352         QVERIFY(file.open(QIODevice::ReadOnly | mode));
       
  2353         bool isSequential = file.isSequential();
       
  2354         if (!isSequential) {
       
  2355             QVERIFY(file.seek(245));
       
  2356             QVERIFY(file.atEnd());
       
  2357         }
       
  2358 
       
  2359         char buf[10];
       
  2360         int ret = file.readLine(buf, sizeof buf);
       
  2361         QCOMPARE(ret, -1);
       
  2362         QVERIFY(file.error() == QFile::NoError);
       
  2363         QVERIFY(file.atEnd());
       
  2364 
       
  2365         // Do it again to ensure that we get the same result
       
  2366         ret = file.readLine(buf, sizeof buf);
       
  2367         QCOMPARE(ret, -1);
       
  2368         QVERIFY(file.error() == QFile::NoError);
       
  2369         QVERIFY(file.atEnd());
       
  2370     }
       
  2371 
       
  2372     {
       
  2373         QFile file(filename);
       
  2374         QVERIFY(file.open(QIODevice::ReadOnly | mode));
       
  2375         bool isSequential = file.isSequential();
       
  2376         if (!isSequential) {
       
  2377             QVERIFY(file.seek(245));
       
  2378             QVERIFY(file.atEnd());
       
  2379         }
       
  2380 
       
  2381         QByteArray ret = file.readLine();
       
  2382         QVERIFY(ret.isNull());
       
  2383         QVERIFY(file.error() == QFile::NoError);
       
  2384         QVERIFY(file.atEnd());
       
  2385 
       
  2386         // Do it again to ensure that we get the same result
       
  2387         ret = file.readLine();
       
  2388         QVERIFY(ret.isNull());
       
  2389         QVERIFY(file.error() == QFile::NoError);
       
  2390         QVERIFY(file.atEnd());
       
  2391     }
       
  2392 
       
  2393     {
       
  2394         QFile file(filename);
       
  2395         QVERIFY(file.open(QIODevice::ReadOnly | mode));
       
  2396         bool isSequential = file.isSequential();
       
  2397         if (!isSequential) {
       
  2398             QVERIFY(file.seek(245));
       
  2399             QVERIFY(file.atEnd());
       
  2400         }
       
  2401 
       
  2402         char c;
       
  2403         QVERIFY(!file.getChar(&c));
       
  2404         QVERIFY(file.error() == QFile::NoError);
       
  2405         QVERIFY(file.atEnd());
       
  2406 
       
  2407         // Do it again to ensure that we get the same result
       
  2408         QVERIFY(!file.getChar(&c));
       
  2409         QVERIFY(file.error() == QFile::NoError);
       
  2410         QVERIFY(file.atEnd());
       
  2411     }
       
  2412 }
       
  2413 
       
  2414 void tst_QFile::task167217()
       
  2415 {
       
  2416     // Regression introduced in 4.3.0; after a failed stat, pos() could no
       
  2417     // longer be calculated correctly.
       
  2418     QFile::remove("tmp.txt");
       
  2419     QFile file("tmp.txt");
       
  2420     QVERIFY(!file.exists());
       
  2421     QVERIFY(file.open(QIODevice::Append));
       
  2422     QVERIFY(file.exists());
       
  2423     file.write("qt430", 5);
       
  2424     QVERIFY(!file.isSequential());
       
  2425     QCOMPARE(file.pos(), qint64(5));
       
  2426     file.remove();
       
  2427 }
       
  2428 
       
  2429 #define FILESIZE 65536 * 3
       
  2430 
       
  2431 void tst_QFile::map_data()
       
  2432 {
       
  2433     QTest::addColumn<int>("fileSize");
       
  2434     QTest::addColumn<int>("offset");
       
  2435     QTest::addColumn<int>("size");
       
  2436     QTest::addColumn<QFile::FileError>("error");
       
  2437 
       
  2438     QTest::newRow("zero")         << FILESIZE << 0     << FILESIZE         << QFile::NoError;
       
  2439     QTest::newRow("small, but 0") << FILESIZE << 30    << FILESIZE - 30    << QFile::NoError;
       
  2440     QTest::newRow("a page")       << FILESIZE << 4096  << FILESIZE - 4096  << QFile::NoError;
       
  2441     QTest::newRow("+page")        << FILESIZE << 5000  << FILESIZE - 5000  << QFile::NoError;
       
  2442     QTest::newRow("++page")       << FILESIZE << 65576 << FILESIZE - 65576 << QFile::NoError;
       
  2443     QTest::newRow("bad size")     << FILESIZE << 0     << -1               << QFile::ResourceError;
       
  2444     QTest::newRow("bad offset")   << FILESIZE << -1    << 1                << QFile::UnspecifiedError;
       
  2445     QTest::newRow("zerozero")     << FILESIZE << 0     << 0                << QFile::UnspecifiedError;
       
  2446 }
       
  2447 
       
  2448 void tst_QFile::map()
       
  2449 {
       
  2450     QFETCH(int, fileSize);
       
  2451     QFETCH(int, offset);
       
  2452     QFETCH(int, size);
       
  2453     QFETCH(QFile::FileError, error);
       
  2454 
       
  2455     QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
       
  2456     if (QFile::exists(fileName)) {
       
  2457         QVERIFY(QFile::setPermissions(fileName,
       
  2458             QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
       
  2459 	QFile::remove(fileName);
       
  2460     }
       
  2461     QFile file(fileName);
       
  2462 
       
  2463     // invalid, not open
       
  2464     uchar *memory = file.map(0, size);
       
  2465     QVERIFY(!memory);
       
  2466     QCOMPARE(file.error(), QFile::PermissionsError);
       
  2467     QVERIFY(!file.unmap(memory));
       
  2468     QCOMPARE(file.error(), QFile::PermissionsError);
       
  2469 
       
  2470     // make a file
       
  2471     QVERIFY(file.open(QFile::ReadWrite));
       
  2472     QVERIFY(file.resize(fileSize));
       
  2473     QVERIFY(file.flush());
       
  2474     file.close();
       
  2475     QVERIFY(file.open(QFile::ReadWrite));
       
  2476     memory = file.map(offset, size);
       
  2477     if (error != QFile::NoError) {
       
  2478 
       
  2479 	QVERIFY(file.error() != QFile::NoError);
       
  2480         return;
       
  2481     }
       
  2482 
       
  2483     QCOMPARE(file.error(), error);
       
  2484     QVERIFY(memory);
       
  2485     memory[0] = 'Q';
       
  2486     QVERIFY(file.unmap(memory));
       
  2487     QCOMPARE(file.error(), QFile::NoError);
       
  2488 
       
  2489     // Verify changes were saved
       
  2490     memory = file.map(offset, size);
       
  2491     QCOMPARE(file.error(), QFile::NoError);
       
  2492     QVERIFY(memory);
       
  2493     QVERIFY(memory[0] == 'Q');
       
  2494     QVERIFY(file.unmap(memory));
       
  2495     QCOMPARE(file.error(), QFile::NoError);
       
  2496 
       
  2497     // hpux wont let you map multiple times.
       
  2498 #if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API)
       
  2499     // exotic test to make sure that multiple maps work
       
  2500     uchar *memory1 = file.map(0, file.size());
       
  2501     QCOMPARE(file.error(), QFile::NoError);
       
  2502     uchar *memory2 = file.map(0, file.size());
       
  2503     QCOMPARE(file.error(), QFile::NoError);
       
  2504     QVERIFY(memory1);
       
  2505     QVERIFY(memory2);
       
  2506     QVERIFY(file.unmap(memory1));
       
  2507     QCOMPARE(file.error(), QFile::NoError);
       
  2508     QVERIFY(file.unmap(memory2));
       
  2509     QCOMPARE(file.error(), QFile::NoError);
       
  2510     memory1 = file.map(0, file.size());
       
  2511     QCOMPARE(file.error(), QFile::NoError);
       
  2512     QVERIFY(memory1);
       
  2513     QVERIFY(file.unmap(memory1));
       
  2514     QCOMPARE(file.error(), QFile::NoError);
       
  2515 #endif
       
  2516 
       
  2517     file.close();
       
  2518 
       
  2519 #if defined(Q_OS_SYMBIAN)
       
  2520 	 if (false) // No permissions for user makes no sense in Symbian
       
  2521 #elif defined(Q_OS_UNIX)
       
  2522     if (::getuid() != 0)
       
  2523         // root always has permissions
       
  2524 #endif
       
  2525     {
       
  2526         // Change permissions on a file, just to confirm it would fail
       
  2527         QFile::Permissions originalPermissions = file.permissions();
       
  2528         QVERIFY(file.setPermissions(QFile::ReadOther));
       
  2529         QVERIFY(!file.open(QFile::ReadWrite));
       
  2530         memory = file.map(offset, size);
       
  2531         QCOMPARE(file.error(), QFile::PermissionsError);
       
  2532         QVERIFY(!memory);
       
  2533         QVERIFY(file.setPermissions(originalPermissions));
       
  2534     }
       
  2535 
       
  2536     QVERIFY(file.remove());
       
  2537 }
       
  2538 
       
  2539 void tst_QFile::mapResource_data()
       
  2540 {
       
  2541     QTest::addColumn<int>("offset");
       
  2542     QTest::addColumn<int>("size");
       
  2543     QTest::addColumn<QFile::FileError>("error");
       
  2544     QTest::addColumn<QString>("fileName");
       
  2545 
       
  2546     QString validFile = ":/tst_qfileinfo/resources/file1.ext1";
       
  2547     QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1";
       
  2548 
       
  2549     for (int i = 0; i < 2; ++i) {
       
  2550         QString file = (i == 0) ? validFile : invalidFile;
       
  2551         QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file;
       
  2552         QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file;
       
  2553         QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file;
       
  2554         QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file;
       
  2555     }
       
  2556 
       
  2557     QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile;
       
  2558 }
       
  2559 
       
  2560 void tst_QFile::mapResource()
       
  2561 {
       
  2562     QFETCH(QString, fileName);
       
  2563     QFETCH(int, offset);
       
  2564     QFETCH(int, size);
       
  2565     QFETCH(QFile::FileError, error);
       
  2566 
       
  2567     QFile file(fileName);
       
  2568     uchar *memory = file.map(offset, size);
       
  2569     QCOMPARE(file.error(), error);
       
  2570     QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0));
       
  2571     if (error == QFile::NoError)
       
  2572         QCOMPARE(QString(memory[0]), QString::number(offset + 1));
       
  2573     QVERIFY(file.unmap(memory));
       
  2574 }
       
  2575 
       
  2576 void tst_QFile::mapOpenMode_data()
       
  2577 {
       
  2578     QTest::addColumn<int>("openMode");
       
  2579 
       
  2580     QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly);
       
  2581     //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense
       
  2582     QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite);
       
  2583     QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly | QIODevice::Unbuffered);
       
  2584     QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite | QIODevice::Unbuffered);
       
  2585 }
       
  2586 
       
  2587 void tst_QFile::mapOpenMode()
       
  2588 {
       
  2589     QFETCH(int, openMode);
       
  2590     static const qint64 fileSize = 4096;
       
  2591     QByteArray pattern(fileSize, 'A');
       
  2592 
       
  2593     QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
       
  2594     if (QFile::exists(fileName)) {
       
  2595         QVERIFY(QFile::setPermissions(fileName,
       
  2596             QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
       
  2597 	QFile::remove(fileName);
       
  2598     }
       
  2599     QFile file(fileName);
       
  2600 
       
  2601     // make a file
       
  2602     QVERIFY(file.open(QFile::ReadWrite));
       
  2603     QVERIFY(file.write(pattern));
       
  2604     QVERIFY(file.flush());
       
  2605     file.close();
       
  2606 
       
  2607     // open according to our mode
       
  2608     QVERIFY(file.open(QIODevice::OpenMode(openMode)));
       
  2609 
       
  2610     uchar *memory = file.map(0, fileSize);
       
  2611     QVERIFY(memory);
       
  2612     QVERIFY(memcmp(memory, pattern, fileSize) == 0);
       
  2613 
       
  2614     if (openMode & QIODevice::WriteOnly) {
       
  2615         // try to write to the file
       
  2616         *memory = 'a';
       
  2617         file.unmap(memory);
       
  2618         file.close();
       
  2619         file.open(QIODevice::OpenMode(openMode));
       
  2620         file.seek(0);
       
  2621         char c;
       
  2622         QVERIFY(file.getChar(&c));
       
  2623         QCOMPARE(c, 'a');
       
  2624     }
       
  2625 
       
  2626     file.close();
       
  2627 }
       
  2628 
       
  2629 void tst_QFile::openDirectory()
       
  2630 {
       
  2631     QFile f1("resources");
       
  2632     QVERIFY(!f1.open(QIODevice::ReadOnly));
       
  2633     f1.close();
       
  2634     QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered));
       
  2635 }
       
  2636 
       
  2637 QTEST_MAIN(tst_QFile)
       
  2638 #include "tst_qfile.moc"