src/corelib/io/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 QtCore module 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 #include "qplatformdefs.h"
       
    43 #include "qdebug.h"
       
    44 #include "qfile.h"
       
    45 #include "qfsfileengine.h"
       
    46 #include "qtemporaryfile.h"
       
    47 #include "qlist.h"
       
    48 #include "qfileinfo.h"
       
    49 #include "private/qiodevice_p.h"
       
    50 #include "private/qfile_p.h"
       
    51 #if defined(QT_BUILD_CORE_LIB)
       
    52 # include "qcoreapplication.h"
       
    53 #endif
       
    54 
       
    55 #ifdef QT_NO_QOBJECT
       
    56 #define tr(X) QString::fromLatin1(X)
       
    57 #endif
       
    58 
       
    59 QT_BEGIN_NAMESPACE
       
    60 
       
    61 static const int QFILE_WRITEBUFFER_SIZE = 16384;
       
    62 
       
    63 static QByteArray locale_encode(const QString &f)
       
    64 {
       
    65 #ifndef Q_OS_DARWIN
       
    66     return f.toLocal8Bit();
       
    67 #else
       
    68     // Mac always expects UTF-8... and decomposed...
       
    69     return f.normalized(QString::NormalizationForm_D).toUtf8();
       
    70 #endif
       
    71 }
       
    72 
       
    73 static QString locale_decode(const QByteArray &f)
       
    74 {
       
    75 #ifndef Q_OS_DARWIN
       
    76     return QString::fromLocal8Bit(f);
       
    77 #else
       
    78     // Mac always gives us UTF-8 and decomposed, we want that composed...
       
    79     return QString::fromUtf8(f).normalized(QString::NormalizationForm_C);
       
    80 #endif
       
    81 }
       
    82 
       
    83 //************* QFilePrivate
       
    84 QFile::EncoderFn QFilePrivate::encoder = locale_encode;
       
    85 QFile::DecoderFn QFilePrivate::decoder = locale_decode;
       
    86 
       
    87 QFilePrivate::QFilePrivate()
       
    88     : fileEngine(0), lastWasWrite(false),
       
    89       writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError)
       
    90 {
       
    91 }
       
    92 
       
    93 QFilePrivate::~QFilePrivate()
       
    94 {
       
    95     delete fileEngine;
       
    96     fileEngine = 0;
       
    97 }
       
    98 
       
    99 bool
       
   100 QFilePrivate::openExternalFile(int flags, int fd)
       
   101 {
       
   102 #ifdef QT_NO_FSFILEENGINE
       
   103     Q_UNUSED(flags);
       
   104     Q_UNUSED(fd);
       
   105     return false;
       
   106 #else
       
   107     delete fileEngine;
       
   108     fileEngine = 0;
       
   109     QFSFileEngine *fe = new QFSFileEngine;
       
   110     fe->setFileName(fileName);
       
   111     fileEngine = fe;
       
   112     return fe->open(QIODevice::OpenMode(flags), fd);
       
   113 #endif
       
   114 }
       
   115 
       
   116 bool
       
   117 QFilePrivate::openExternalFile(int flags, FILE *fh)
       
   118 {
       
   119 #ifdef QT_NO_FSFILEENGINE
       
   120     Q_UNUSED(flags);
       
   121     Q_UNUSED(fh);
       
   122     return false;
       
   123 #else
       
   124     delete fileEngine;
       
   125     fileEngine = 0;
       
   126     QFSFileEngine *fe = new QFSFileEngine;
       
   127     fe->setFileName(fileName);
       
   128     fileEngine = fe;
       
   129     return fe->open(QIODevice::OpenMode(flags), fh);
       
   130 #endif
       
   131 }
       
   132 
       
   133 inline bool QFilePrivate::ensureFlushed() const
       
   134 {
       
   135     // This function ensures that the write buffer has been flushed (const
       
   136     // because certain const functions need to call it.
       
   137     if (lastWasWrite) {
       
   138         const_cast<QFilePrivate *>(this)->lastWasWrite = false;
       
   139         if (!const_cast<QFile *>(q_func())->flush())
       
   140             return false;
       
   141     }
       
   142     return true;
       
   143 }
       
   144 
       
   145 void
       
   146 QFilePrivate::setError(QFile::FileError err)
       
   147 {
       
   148     error = err;
       
   149     errorString.clear();
       
   150 }
       
   151 
       
   152 void
       
   153 QFilePrivate::setError(QFile::FileError err, const QString &errStr)
       
   154 {
       
   155     error = err;
       
   156     errorString = errStr;
       
   157 }
       
   158 
       
   159 void
       
   160 QFilePrivate::setError(QFile::FileError err, int errNum)
       
   161 {
       
   162     error = err;
       
   163     errorString = qt_error_string(errNum);
       
   164 }
       
   165 
       
   166 //************* QFile
       
   167 
       
   168 /*!
       
   169     \class QFile
       
   170     \brief The QFile class provides an interface for reading from and writing to files.
       
   171 
       
   172     \ingroup io
       
   173 
       
   174     \reentrant
       
   175 
       
   176     QFile is an I/O device for reading and writing text and binary
       
   177     files and \l{The Qt Resource System}{resources}. A QFile may be
       
   178     used by itself or, more conveniently, with a QTextStream or
       
   179     QDataStream.
       
   180 
       
   181     The file name is usually passed in the constructor, but it can be
       
   182     set at any time using setFileName(). QFile expects the file
       
   183     separator to be '/' regardless of operating system. The use of
       
   184     other separators (e.g., '\\') is not supported.
       
   185 
       
   186     You can check for a file's existence using exists(), and remove a
       
   187     file using remove(). (More advanced file system related operations
       
   188     are provided by QFileInfo and QDir.)
       
   189 
       
   190     The file is opened with open(), closed with close(), and flushed
       
   191     with flush(). Data is usually read and written using QDataStream
       
   192     or QTextStream, but you can also call the QIODevice-inherited
       
   193     functions read(), readLine(), readAll(), write(). QFile also
       
   194     inherits getChar(), putChar(), and ungetChar(), which work one
       
   195     character at a time.
       
   196 
       
   197     The size of the file is returned by size(). You can get the
       
   198     current file position using pos(), or move to a new file position
       
   199     using seek(). If you've reached the end of the file, atEnd()
       
   200     returns true.
       
   201 
       
   202     \section1 Reading Files Directly
       
   203 
       
   204     The following example reads a text file line by line:
       
   205 
       
   206     \snippet doc/src/snippets/file/file.cpp 0
       
   207 
       
   208     The QIODevice::Text flag passed to open() tells Qt to convert
       
   209     Windows-style line terminators ("\\r\\n") into C++-style
       
   210     terminators ("\\n"). By default, QFile assumes binary, i.e. it
       
   211     doesn't perform any conversion on the bytes stored in the file.
       
   212 
       
   213     \section1 Using Streams to Read Files
       
   214 
       
   215     The next example uses QTextStream to read a text file
       
   216     line by line:
       
   217 
       
   218     \snippet doc/src/snippets/file/file.cpp 1
       
   219 
       
   220     QTextStream takes care of converting the 8-bit data stored on
       
   221     disk into a 16-bit Unicode QString. By default, it assumes that
       
   222     the user system's local 8-bit encoding is used (e.g., ISO 8859-1
       
   223     for most of Europe; see QTextCodec::codecForLocale() for
       
   224     details). This can be changed using setCodec().
       
   225 
       
   226     To write text, we can use operator<<(), which is overloaded to
       
   227     take a QTextStream on the left and various data types (including
       
   228     QString) on the right:
       
   229 
       
   230     \snippet doc/src/snippets/file/file.cpp 2
       
   231 
       
   232     QDataStream is similar, in that you can use operator<<() to write
       
   233     data and operator>>() to read it back. See the class
       
   234     documentation for details.
       
   235 
       
   236     When you use QFile, QFileInfo, and QDir to access the file system
       
   237     with Qt, you can use Unicode file names. On Unix, these file
       
   238     names are converted to an 8-bit encoding. If you want to use
       
   239     standard C++ APIs (\c <cstdio> or \c <iostream>) or
       
   240     platform-specific APIs to access files instead of QFile, you can
       
   241     use the encodeName() and decodeName() functions to convert
       
   242     between Unicode file names and 8-bit file names.
       
   243 
       
   244     On Unix, there are some special system files (e.g. in \c /proc) for which
       
   245     size() will always return 0, yet you may still be able to read more data
       
   246     from such a file; the data is generated in direct response to you calling
       
   247     read(). In this case, however, you cannot use atEnd() to determine if
       
   248     there is more data to read (since atEnd() will return true for a file that
       
   249     claims to have size 0). Instead, you should either call readAll(), or call
       
   250     read() or readLine() repeatedly until no more data can be read. The next
       
   251     example uses QTextStream to read \c /proc/modules line by line:
       
   252 
       
   253     \snippet doc/src/snippets/file/file.cpp 3
       
   254 
       
   255     \section1 Signals
       
   256 
       
   257     Unlike other QIODevice implementations, such as QTcpSocket, QFile does not
       
   258     emit the aboutToClose(), bytesWritten(), or readyRead() signals. This
       
   259     implementation detail means that QFile is not suitable for reading and
       
   260     writing certain types of files, such as device files on Unix platforms.
       
   261 
       
   262     \section1 Platform Specific Issues
       
   263 
       
   264     File permissions are handled differently on Linux/Mac OS X and
       
   265     Windows.  In a non \l{QIODevice::isWritable()}{writable}
       
   266     directory on Linux, files cannot be created. This is not always
       
   267     the case on Windows, where, for instance, the 'My Documents'
       
   268     directory usually is not writable, but it is still possible to
       
   269     create files in it.
       
   270 
       
   271     \sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
       
   272 */
       
   273 
       
   274 /*!
       
   275     \enum QFile::FileError
       
   276 
       
   277     This enum describes the errors that may be returned by the error()
       
   278     function.
       
   279 
       
   280     \value NoError          No error occurred.
       
   281     \value ReadError        An error occurred when reading from the file.
       
   282     \value WriteError       An error occurred when writing to the file.
       
   283     \value FatalError       A fatal error occurred.
       
   284     \value ResourceError
       
   285     \value OpenError        The file could not be opened.
       
   286     \value AbortError       The operation was aborted.
       
   287     \value TimeOutError     A timeout occurred.
       
   288     \value UnspecifiedError An unspecified error occurred.
       
   289     \value RemoveError      The file could not be removed.
       
   290     \value RenameError      The file could not be renamed.
       
   291     \value PositionError    The position in the file could not be changed.
       
   292     \value ResizeError      The file could not be resized.
       
   293     \value PermissionsError The file could not be accessed.
       
   294     \value CopyError        The file could not be copied.
       
   295 
       
   296     \omitvalue ConnectError
       
   297 */
       
   298 
       
   299 /*!
       
   300     \enum QFile::Permission
       
   301 
       
   302     This enum is used by the permission() function to report the
       
   303     permissions and ownership of a file. The values may be OR-ed
       
   304     together to test multiple permissions and ownership values.
       
   305 
       
   306     \value ReadOwner The file is readable by the owner of the file.
       
   307     \value WriteOwner The file is writable by the owner of the file.
       
   308     \value ExeOwner The file is executable by the owner of the file.
       
   309     \value ReadUser The file is readable by the user.
       
   310     \value WriteUser The file is writable by the user.
       
   311     \value ExeUser The file is executable by the user.
       
   312     \value ReadGroup The file is readable by the group.
       
   313     \value WriteGroup The file is writable by the group.
       
   314     \value ExeGroup The file is executable by the group.
       
   315     \value ReadOther The file is readable by anyone.
       
   316     \value WriteOther The file is writable by anyone.
       
   317     \value ExeOther The file is executable by anyone.
       
   318 
       
   319     \warning Because of differences in the platforms supported by Qt,
       
   320     the semantics of ReadUser, WriteUser and ExeUser are
       
   321     platform-dependent: On Unix, the rights of the owner of the file
       
   322     are returned and on Windows the rights of the current user are
       
   323     returned. This behavior might change in a future Qt version.
       
   324 
       
   325     Note that Qt does not by default check for permissions on NTFS
       
   326     file systems, as this may decrease the performance of file
       
   327     handling considerably. It is possible to force permission checking
       
   328     on NTFS by including the following code in your source:
       
   329 
       
   330     \snippet doc/src/snippets/ntfsp.cpp 0
       
   331 
       
   332     Permission checking is then turned on and off by incrementing and
       
   333     decrementing \c qt_ntfs_permission_lookup by 1.
       
   334 
       
   335     \snippet doc/src/snippets/ntfsp.cpp 1
       
   336 */
       
   337 
       
   338 #ifdef QT3_SUPPORT
       
   339 /*!
       
   340     \typedef QFile::PermissionSpec
       
   341 
       
   342     Use QFile::Permission instead.
       
   343 */
       
   344 #endif
       
   345 
       
   346 #ifdef QT_NO_QOBJECT
       
   347 QFile::QFile()
       
   348     : QIODevice(*new QFilePrivate)
       
   349 {
       
   350 }
       
   351 QFile::QFile(const QString &name)
       
   352     : QIODevice(*new QFilePrivate)
       
   353 {
       
   354     d_func()->fileName = name;
       
   355 }
       
   356 QFile::QFile(QFilePrivate &dd)
       
   357     : QIODevice(dd)
       
   358 {
       
   359 }
       
   360 #else
       
   361 /*!
       
   362     \internal
       
   363 */
       
   364 QFile::QFile()
       
   365     : QIODevice(*new QFilePrivate, 0)
       
   366 {
       
   367 }
       
   368 /*!
       
   369     Constructs a new file object with the given \a parent.
       
   370 */
       
   371 QFile::QFile(QObject *parent)
       
   372     : QIODevice(*new QFilePrivate, parent)
       
   373 {
       
   374 }
       
   375 /*!
       
   376     Constructs a new file object to represent the file with the given \a name.
       
   377 */
       
   378 QFile::QFile(const QString &name)
       
   379     : QIODevice(*new QFilePrivate, 0)
       
   380 {
       
   381     Q_D(QFile);
       
   382     d->fileName = name;
       
   383 }
       
   384 /*!
       
   385     Constructs a new file object with the given \a parent to represent the
       
   386     file with the specified \a name.
       
   387 */
       
   388 QFile::QFile(const QString &name, QObject *parent)
       
   389     : QIODevice(*new QFilePrivate, parent)
       
   390 {
       
   391     Q_D(QFile);
       
   392     d->fileName = name;
       
   393 }
       
   394 /*!
       
   395     \internal
       
   396 */
       
   397 QFile::QFile(QFilePrivate &dd, QObject *parent)
       
   398     : QIODevice(dd, parent)
       
   399 {
       
   400 }
       
   401 #endif
       
   402 
       
   403 /*!
       
   404     Destroys the file object, closing it if necessary.
       
   405 */
       
   406 QFile::~QFile()
       
   407 {
       
   408     close();
       
   409 }
       
   410 
       
   411 /*!
       
   412     Returns the name set by setFileName() or to the QFile
       
   413     constructors.
       
   414 
       
   415     \sa setFileName(), QFileInfo::fileName()
       
   416 */
       
   417 QString QFile::fileName() const
       
   418 {
       
   419     return fileEngine()->fileName(QAbstractFileEngine::DefaultName);
       
   420 }
       
   421 
       
   422 /*!
       
   423     Sets the \a name of the file. The name can have no path, a
       
   424     relative path, or an absolute path.
       
   425 
       
   426     Do not call this function if the file has already been opened.
       
   427 
       
   428     If the file name has no path or a relative path, the path used
       
   429     will be the application's current directory path
       
   430     \e{at the time of the open()} call.
       
   431 
       
   432     Example:
       
   433     \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 0
       
   434 
       
   435     Note that the directory separator "/" works for all operating
       
   436     systems supported by Qt.
       
   437 
       
   438     \sa fileName(), QFileInfo, QDir
       
   439 */
       
   440 void
       
   441 QFile::setFileName(const QString &name)
       
   442 {
       
   443     Q_D(QFile);
       
   444     if (isOpen()) {
       
   445         qWarning("QFile::setFileName: File (%s) is already opened",
       
   446                  qPrintable(fileName()));
       
   447         close();
       
   448     }
       
   449     if(d->fileEngine) { //get a new file engine later
       
   450         delete d->fileEngine;
       
   451         d->fileEngine = 0;
       
   452     }
       
   453     d->fileName = name;
       
   454 }
       
   455 
       
   456 /*!
       
   457     \fn QString QFile::decodeName(const char *localFileName)
       
   458 
       
   459     \overload
       
   460 
       
   461     Returns the Unicode version of the given \a localFileName. See
       
   462     encodeName() for details.
       
   463 */
       
   464 
       
   465 /*!
       
   466     By default, this function converts \a fileName to the local 8-bit
       
   467     encoding determined by the user's locale. This is sufficient for
       
   468     file names that the user chooses. File names hard-coded into the
       
   469     application should only use 7-bit ASCII filename characters.
       
   470 
       
   471     \sa decodeName() setEncodingFunction()
       
   472 */
       
   473 
       
   474 QByteArray
       
   475 QFile::encodeName(const QString &fileName)
       
   476 {
       
   477     return (*QFilePrivate::encoder)(fileName);
       
   478 }
       
   479 
       
   480 /*!
       
   481     \typedef QFile::EncoderFn
       
   482 
       
   483     This is a typedef for a pointer to a function with the following
       
   484     signature:
       
   485 
       
   486     \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 1
       
   487 
       
   488     \sa setEncodingFunction(), encodeName()
       
   489 */
       
   490 
       
   491 /*!
       
   492     This does the reverse of QFile::encodeName() using \a localFileName.
       
   493 
       
   494     \sa setDecodingFunction(), encodeName()
       
   495 */
       
   496 
       
   497 QString
       
   498 QFile::decodeName(const QByteArray &localFileName)
       
   499 {
       
   500     return (*QFilePrivate::decoder)(localFileName);
       
   501 }
       
   502 
       
   503 /*!
       
   504     \fn void QFile::setEncodingFunction(EncoderFn function)
       
   505 
       
   506     \nonreentrant
       
   507 
       
   508     Sets the \a function for encoding Unicode file names. The
       
   509     default encodes in the locale-specific 8-bit encoding.
       
   510 
       
   511     \sa encodeName(), setDecodingFunction()
       
   512 */
       
   513 
       
   514 void
       
   515 QFile::setEncodingFunction(EncoderFn f)
       
   516 {
       
   517     if (!f)
       
   518         f = locale_encode;
       
   519     QFilePrivate::encoder = f;
       
   520 }
       
   521 
       
   522 /*!
       
   523     \typedef QFile::DecoderFn
       
   524 
       
   525     This is a typedef for a pointer to a function with the following
       
   526     signature:
       
   527 
       
   528     \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 2
       
   529 
       
   530     \sa setDecodingFunction()
       
   531 */
       
   532 
       
   533 /*!
       
   534     \fn void QFile::setDecodingFunction(DecoderFn function)
       
   535 
       
   536     \nonreentrant
       
   537 
       
   538     Sets the \a function for decoding 8-bit file names. The
       
   539     default uses the locale-specific 8-bit encoding.
       
   540 
       
   541     \sa setEncodingFunction(), decodeName()
       
   542 */
       
   543 
       
   544 void
       
   545 QFile::setDecodingFunction(DecoderFn f)
       
   546 {
       
   547     if (!f)
       
   548         f = locale_decode;
       
   549     QFilePrivate::decoder = f;
       
   550 }
       
   551 
       
   552 /*!
       
   553     \overload
       
   554 
       
   555     Returns true if the file specified by fileName() exists; otherwise
       
   556     returns false.
       
   557 
       
   558     \sa fileName(), setFileName()
       
   559 */
       
   560 
       
   561 bool
       
   562 QFile::exists() const
       
   563 {
       
   564     // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update
       
   565     return (fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask
       
   566                                     | QAbstractFileEngine::FileFlag(0x1000000)) & QAbstractFileEngine::ExistsFlag);
       
   567 }
       
   568 
       
   569 /*!
       
   570     Returns true if the file specified by \a fileName exists; otherwise
       
   571     returns false.
       
   572 */
       
   573 
       
   574 bool
       
   575 QFile::exists(const QString &fileName)
       
   576 {
       
   577     return QFileInfo(fileName).exists();
       
   578 }
       
   579 
       
   580 /*!
       
   581     \fn QString QFile::symLinkTarget() const
       
   582     \since 4.2
       
   583     \overload
       
   584 
       
   585     Returns the absolute path of the file or directory a symlink (or shortcut
       
   586     on Windows) points to, or a an empty string if the object isn't a symbolic
       
   587     link.
       
   588 
       
   589     This name may not represent an existing file; it is only a string.
       
   590     QFile::exists() returns true if the symlink points to an existing file.
       
   591 
       
   592     \sa fileName() setFileName()
       
   593 */
       
   594 
       
   595 /*!
       
   596     \obsolete
       
   597 
       
   598     Use symLinkTarget() instead.
       
   599 */
       
   600 QString
       
   601 QFile::readLink() const
       
   602 {
       
   603     return fileEngine()->fileName(QAbstractFileEngine::LinkName);
       
   604 }
       
   605 
       
   606 /*!
       
   607     \fn static QString QFile::symLinkTarget(const QString &fileName)
       
   608     \since 4.2
       
   609 
       
   610     Returns the absolute path of the file or directory referred to by the
       
   611     symlink (or shortcut on Windows) specified by \a fileName, or returns an
       
   612     empty string if the \a fileName does not correspond to a symbolic link.
       
   613 
       
   614     This name may not represent an existing file; it is only a string.
       
   615     QFile::exists() returns true if the symlink points to an existing file.
       
   616 */
       
   617 
       
   618 /*!
       
   619     \obsolete
       
   620 
       
   621     Use symLinkTarget() instead.
       
   622 */
       
   623 QString
       
   624 QFile::readLink(const QString &fileName)
       
   625 {
       
   626     return QFileInfo(fileName).readLink();
       
   627 }
       
   628 
       
   629 /*!
       
   630     Removes the file specified by fileName(). Returns true if successful;
       
   631     otherwise returns false.
       
   632 
       
   633     The file is closed before it is removed.
       
   634 
       
   635     \sa setFileName()
       
   636 */
       
   637 
       
   638 bool
       
   639 QFile::remove()
       
   640 {
       
   641     Q_D(QFile);
       
   642     if (d->fileName.isEmpty()) {
       
   643         qWarning("QFile::remove: Empty or null file name");
       
   644         return false;
       
   645     }
       
   646     close();
       
   647     if(error() == QFile::NoError) {
       
   648         if(fileEngine()->remove()) {
       
   649             unsetError();
       
   650             return true;
       
   651         }
       
   652         d->setError(QFile::RemoveError, fileEngine()->errorString());
       
   653     }
       
   654     return false;
       
   655 }
       
   656 
       
   657 /*!
       
   658     \overload
       
   659 
       
   660     Removes the file specified by the \a fileName given.
       
   661 
       
   662     Returns true if successful; otherwise returns false.
       
   663 
       
   664     \sa remove()
       
   665 */
       
   666 
       
   667 bool
       
   668 QFile::remove(const QString &fileName)
       
   669 {
       
   670     return QFile(fileName).remove();
       
   671 }
       
   672 
       
   673 /*!
       
   674     Renames the file currently specified by fileName() to \a newName.
       
   675     Returns true if successful; otherwise returns false.
       
   676 
       
   677     If a file with the name \a newName already exists, rename() returns false
       
   678     (i.e., QFile will not overwrite it).
       
   679 
       
   680     The file is closed before it is renamed.
       
   681 
       
   682     \sa setFileName()
       
   683 */
       
   684 
       
   685 bool
       
   686 QFile::rename(const QString &newName)
       
   687 {
       
   688     Q_D(QFile);
       
   689     if (d->fileName.isEmpty()) {
       
   690         qWarning("QFile::rename: Empty or null file name");
       
   691         return false;
       
   692     }
       
   693     if (QFile(newName).exists()) {
       
   694         // ### Race condition. If a file is moved in after this, it /will/ be
       
   695         // overwritten. On Unix, the proper solution is to use hardlinks:
       
   696         // return ::link(old, new) && ::remove(old);
       
   697         d->setError(QFile::RenameError, tr("Destination file exists"));
       
   698         return false;
       
   699     }
       
   700     unsetError();
       
   701     close();
       
   702     if(error() == QFile::NoError) {
       
   703         if (fileEngine()->rename(newName)) {
       
   704             unsetError();
       
   705             // engine was able to handle the new name so we just reset it
       
   706             fileEngine()->setFileName(newName);
       
   707             d->fileName = newName;
       
   708             return true;
       
   709         }
       
   710 
       
   711         if (isSequential()) {
       
   712             d->setError(QFile::RenameError, tr("Will not rename sequential file using block copy"));
       
   713             return false;
       
   714         }
       
   715 
       
   716         QFile out(newName);
       
   717         if (open(QIODevice::ReadOnly)) {
       
   718             if (out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
       
   719                 bool error = false;
       
   720                 char block[4096];
       
   721                 qint64 bytes;
       
   722                 while ((bytes = read(block, sizeof(block))) > 0) {
       
   723                     if (bytes != out.write(block, bytes)) {
       
   724                         d->setError(QFile::RenameError, out.errorString());
       
   725                         error = true;
       
   726                         break;
       
   727                     }
       
   728                 }
       
   729                 if (bytes == -1) {
       
   730                     d->setError(QFile::RenameError, errorString());
       
   731                     error = true;
       
   732                 }
       
   733                 if(!error) {
       
   734                     if (!remove()) {
       
   735                         d->setError(QFile::RenameError, tr("Cannot remove source file"));
       
   736                         error = true;
       
   737                     }
       
   738                 }
       
   739                 if (error) {
       
   740                     out.remove();
       
   741                 } else {
       
   742                     fileEngine()->setFileName(newName);
       
   743                     setPermissions(permissions());
       
   744                     unsetError();
       
   745                     setFileName(newName);
       
   746                 }
       
   747                 close();
       
   748                 return !error;
       
   749             }
       
   750             close();
       
   751         }
       
   752         d->setError(QFile::RenameError, out.isOpen() ? errorString() : out.errorString());
       
   753     }
       
   754     return false;
       
   755 }
       
   756 
       
   757 /*!
       
   758     \overload
       
   759 
       
   760     Renames the file \a oldName to \a newName. Returns true if
       
   761     successful; otherwise returns false.
       
   762 
       
   763     If a file with the name \a newName already exists, rename() returns false
       
   764     (i.e., QFile will not overwrite it).
       
   765 
       
   766     \sa rename()
       
   767 */
       
   768 
       
   769 bool
       
   770 QFile::rename(const QString &oldName, const QString &newName)
       
   771 {
       
   772     return QFile(oldName).rename(newName);
       
   773 }
       
   774 
       
   775 /*!
       
   776 
       
   777     Creates a link named \a linkName that points to the file currently specified by
       
   778     fileName().  What a link is depends on the underlying filesystem (be it a
       
   779     shortcut on Windows or a symbolic link on Unix). Returns true if successful;
       
   780     otherwise returns false.
       
   781 
       
   782     This function will not overwrite an already existing entity in the file system;
       
   783     in this case, \c link() will return false and set \l{QFile::}{error()} to
       
   784     return \l{QFile::}{RenameError}.
       
   785 
       
   786     \note To create a valid link on Windows, \a linkName must have a \c{.lnk} file extension.
       
   787 
       
   788     \note On Symbian, no link is created and false is returned if fileName()
       
   789     currently specifies a directory.
       
   790 
       
   791     \sa setFileName()
       
   792 */
       
   793 
       
   794 bool
       
   795 QFile::link(const QString &linkName)
       
   796 {
       
   797     Q_D(QFile);
       
   798     if (d->fileName.isEmpty()) {
       
   799         qWarning("QFile::link: Empty or null file name");
       
   800         return false;
       
   801     }
       
   802     QFileInfo fi(linkName);
       
   803     if(fileEngine()->link(fi.absoluteFilePath())) {
       
   804         unsetError();
       
   805         return true;
       
   806     }
       
   807     d->setError(QFile::RenameError, fileEngine()->errorString());
       
   808     return false;
       
   809 }
       
   810 
       
   811 /*!
       
   812     \overload
       
   813 
       
   814     Creates a link named \a linkName that points to the file \a fileName. What a link is
       
   815     depends on the underlying filesystem (be it a shortcut on Windows
       
   816     or a symbolic link on Unix). Returns true if successful; otherwise
       
   817     returns false.
       
   818 
       
   819     \sa link()
       
   820 */
       
   821 
       
   822 bool
       
   823 QFile::link(const QString &fileName, const QString &linkName)
       
   824 {
       
   825     return QFile(fileName).link(linkName);
       
   826 }
       
   827 
       
   828 /*!
       
   829     Copies the file currently specified by fileName() to a file called
       
   830     \a newName.  Returns true if successful; otherwise returns false.
       
   831 
       
   832     Note that if a file with the name \a newName already exists,
       
   833     copy() returns false (i.e. QFile will not overwrite it).
       
   834 
       
   835     The source file is closed before it is copied.
       
   836 
       
   837     \sa setFileName()
       
   838 */
       
   839 
       
   840 bool
       
   841 QFile::copy(const QString &newName)
       
   842 {
       
   843     Q_D(QFile);
       
   844     if (d->fileName.isEmpty()) {
       
   845         qWarning("QFile::copy: Empty or null file name");
       
   846         return false;
       
   847     }
       
   848     if (QFile(newName).exists()) {
       
   849         // ### Race condition. If a file is moved in after this, it /will/ be
       
   850         // overwritten. On Unix, the proper solution is to use hardlinks:
       
   851         // return ::link(old, new) && ::remove(old); See also rename().
       
   852         d->setError(QFile::CopyError, tr("Destination file exists"));
       
   853         return false;
       
   854     }
       
   855     unsetError();
       
   856     close();
       
   857     if(error() == QFile::NoError) {
       
   858         if(fileEngine()->copy(newName)) {
       
   859             unsetError();
       
   860             return true;
       
   861         } else {
       
   862             bool error = false;
       
   863             if(!open(QFile::ReadOnly)) {
       
   864                 error = true;
       
   865                 d->setError(QFile::CopyError, tr("Cannot open %1 for input").arg(d->fileName));
       
   866             } else {
       
   867                 QString fileTemplate = QLatin1String("%1/qt_temp.XXXXXX");
       
   868 #ifdef QT_NO_TEMPORARYFILE
       
   869                 QFile out(fileTemplate.arg(QFileInfo(newName).path()));
       
   870                 if (!out.open(QIODevice::ReadWrite))
       
   871                     error = true;
       
   872 #else
       
   873                 QTemporaryFile out(fileTemplate.arg(QFileInfo(newName).path()));
       
   874                 if (!out.open()) {
       
   875                     out.setFileTemplate(fileTemplate.arg(QDir::tempPath()));
       
   876                     if (!out.open())
       
   877                         error = true;
       
   878                 }
       
   879 #endif
       
   880                 if (error) {
       
   881                     out.close();
       
   882                     d->setError(QFile::CopyError, tr("Cannot open for output"));
       
   883                 } else {
       
   884                     char block[4096];
       
   885                     qint64 totalRead = 0;
       
   886                     while(!atEnd()) {
       
   887                         qint64 in = read(block, sizeof(block));
       
   888                         if (in <= 0)
       
   889                             break;
       
   890                         totalRead += in;
       
   891                         if(in != out.write(block, in)) {
       
   892                             d->setError(QFile::CopyError, tr("Failure to write block"));
       
   893                             error = true;
       
   894                             break;
       
   895                         }
       
   896                     }
       
   897 
       
   898                     if (totalRead != size()) {
       
   899                         // Unable to read from the source. The error string is
       
   900                         // already set from read().
       
   901                         error = true;
       
   902                     }
       
   903                     if (!error && !out.rename(newName)) {
       
   904                         error = true;
       
   905                         d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName));
       
   906                     }
       
   907 #ifdef QT_NO_TEMPORARYFILE
       
   908                     if (error)
       
   909                         out.remove();
       
   910 #else
       
   911                     if (!error)
       
   912                         out.setAutoRemove(false);
       
   913 #endif
       
   914                 }
       
   915                 close();
       
   916             }
       
   917             if(!error) {
       
   918                 QFile::setPermissions(newName, permissions());
       
   919                 unsetError();
       
   920                 return true;
       
   921             }
       
   922         }
       
   923     }
       
   924     return false;
       
   925 }
       
   926 
       
   927 /*!
       
   928     \overload
       
   929 
       
   930     Copies the file \a fileName to \a newName. Returns true if successful;
       
   931     otherwise returns false.
       
   932 
       
   933     If a file with the name \a newName already exists, copy() returns false
       
   934     (i.e., QFile will not overwrite it).
       
   935 
       
   936     \sa rename()
       
   937 */
       
   938 
       
   939 bool
       
   940 QFile::copy(const QString &fileName, const QString &newName)
       
   941 {
       
   942     return QFile(fileName).copy(newName);
       
   943 }
       
   944 
       
   945 /*!
       
   946     Returns true if the file can only be manipulated sequentially;
       
   947     otherwise returns false.
       
   948 
       
   949     Most files support random-access, but some special files may not.
       
   950 
       
   951     \sa QIODevice::isSequential()
       
   952 */
       
   953 bool QFile::isSequential() const
       
   954 {
       
   955     Q_D(const QFile);
       
   956     return d->fileEngine && d->fileEngine->isSequential();
       
   957 }
       
   958 
       
   959 /*!
       
   960     Opens the file using OpenMode \a mode, returning true if successful;
       
   961     otherwise false.
       
   962 
       
   963     The \a mode must be QIODevice::ReadOnly, QIODevice::WriteOnly, or
       
   964     QIODevice::ReadWrite. It may also have additional flags, such as
       
   965     QIODevice::Text and QIODevice::Unbuffered.
       
   966 
       
   967     \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
       
   968     mode, if the relevant file does not already exist, this function
       
   969     will try to create a new file before opening it.
       
   970 
       
   971     \note Because of limitations in the native API, QFile ignores the
       
   972     Unbuffered flag on Windows.
       
   973 
       
   974     \sa QIODevice::OpenMode, setFileName()
       
   975 */
       
   976 bool QFile::open(OpenMode mode)
       
   977 {
       
   978     Q_D(QFile);
       
   979     if (isOpen()) {
       
   980         qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
       
   981         return false;
       
   982     }
       
   983     if (mode & Append)
       
   984         mode |= WriteOnly;
       
   985 
       
   986     unsetError();
       
   987     if ((mode & (ReadOnly | WriteOnly)) == 0) {
       
   988         qWarning("QIODevice::open: File access not specified");
       
   989         return false;
       
   990     }
       
   991     if (fileEngine()->open(mode)) {
       
   992         QIODevice::open(mode);
       
   993         if (mode & Append)
       
   994             seek(size());
       
   995         return true;
       
   996     }
       
   997     QFile::FileError err = fileEngine()->error();
       
   998     if(err == QFile::UnspecifiedError)
       
   999         err = QFile::OpenError;
       
  1000     d->setError(err, fileEngine()->errorString());
       
  1001     return false;
       
  1002 }
       
  1003 
       
  1004 /*! \fn QFile::open(OpenMode, FILE*)
       
  1005 
       
  1006     Use open(FILE *, OpenMode) instead.
       
  1007 */
       
  1008 
       
  1009 /*!
       
  1010     \overload
       
  1011 
       
  1012     Opens the existing file handle \a fh in the given \a mode.
       
  1013     Returns true if successful; otherwise returns false.
       
  1014 
       
  1015     Example:
       
  1016     \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 3
       
  1017 
       
  1018     When a QFile is opened using this function, close() does not actually
       
  1019     close the file, but only flushes it.
       
  1020 
       
  1021     \bold{Warning:}
       
  1022     \list 1
       
  1023         \o If \a fh is \c stdin, \c stdout, or \c stderr, you may not be able
       
  1024            to seek(). See QIODevice::isSequential() for more information.
       
  1025         \o Since this function opens the file without specifying the file name,
       
  1026            you cannot use this QFile with a QFileInfo.
       
  1027     \endlist
       
  1028 
       
  1029     \note For Windows CE you may not be able to call seek() and resize().
       
  1030     Also, size() is set to \c 0.
       
  1031 
       
  1032     \sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference}
       
  1033 
       
  1034     \bold{Note for the Windows Platform}
       
  1035 
       
  1036     \a fh must be opened in binary mode (i.e., the mode string must contain
       
  1037     'b', as in "rb" or "wb") when accessing files and other random-access
       
  1038     devices. Qt will translate the end-of-line characters if you pass
       
  1039     QIODevice::Text to \a mode. Sequential devices, such as stdin and stdout,
       
  1040     are unaffected by this limitation.
       
  1041 
       
  1042     You need to enable support for console applications in order to use the
       
  1043     stdin, stdout and stderr streams at the console. To do this, add the
       
  1044     following declaration to your application's project file:
       
  1045 
       
  1046     \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 4
       
  1047 */
       
  1048 bool QFile::open(FILE *fh, OpenMode mode)
       
  1049 {
       
  1050     Q_D(QFile);
       
  1051     if (isOpen()) {
       
  1052         qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
       
  1053         return false;
       
  1054     }
       
  1055     if (mode & Append)
       
  1056         mode |= WriteOnly;
       
  1057     unsetError();
       
  1058     if ((mode & (ReadOnly | WriteOnly)) == 0) {
       
  1059         qWarning("QFile::open: File access not specified");
       
  1060         return false;
       
  1061     }
       
  1062     if(d->openExternalFile(mode, fh)) {
       
  1063         QIODevice::open(mode);
       
  1064         if (mode & Append) {
       
  1065             seek(size());
       
  1066         } else {
       
  1067             long pos = ftell(fh);
       
  1068             if (pos != -1)
       
  1069                 seek(pos);
       
  1070         }
       
  1071         return true;
       
  1072     }
       
  1073     return false;
       
  1074 }
       
  1075 
       
  1076 /*! \fn QFile::open(OpenMode, int)
       
  1077 
       
  1078     Use open(int, OpenMode) instead.
       
  1079 */
       
  1080 
       
  1081 /*!
       
  1082     \overload
       
  1083 
       
  1084     Opens the existing file descripter \a fd in the given \a mode.
       
  1085     Returns true if successful; otherwise returns false.
       
  1086 
       
  1087     When a QFile is opened using this function, close() does not
       
  1088     actually close the file.
       
  1089 
       
  1090     The QFile that is opened using this function is automatically set
       
  1091     to be in raw mode; this means that the file input/output functions
       
  1092     are slow. If you run into performance issues, you should try to
       
  1093     use one of the other open functions.
       
  1094 
       
  1095     \warning If \a fd is 0 (\c stdin), 1 (\c stdout), or 2 (\c
       
  1096     stderr), you may not be able to seek(). size() is set to \c
       
  1097     LLONG_MAX (in \c <climits>).
       
  1098 
       
  1099     \warning For Windows CE you may not be able to call seek(), setSize(),
       
  1100     fileTime(). size() is set to \c 0.
       
  1101 
       
  1102     \warning Since this function opens the file without specifying the file name,
       
  1103              you cannot use this QFile with a QFileInfo.
       
  1104 
       
  1105     \sa close()
       
  1106 */
       
  1107 bool QFile::open(int fd, OpenMode mode)
       
  1108 {
       
  1109     Q_D(QFile);
       
  1110     if (isOpen()) {
       
  1111         qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
       
  1112         return false;
       
  1113     }
       
  1114     if (mode & Append)
       
  1115         mode |= WriteOnly;
       
  1116     unsetError();
       
  1117     if ((mode & (ReadOnly | WriteOnly)) == 0) {
       
  1118         qWarning("QFile::open: File access not specified");
       
  1119         return false;
       
  1120     }
       
  1121     if(d->openExternalFile(mode, fd)) {
       
  1122         QIODevice::open(mode);
       
  1123         if (mode & Append)
       
  1124             seek(size());
       
  1125         return true;
       
  1126     }
       
  1127     return false;
       
  1128 }
       
  1129 
       
  1130 /*!
       
  1131   Returns the file handle of the file.
       
  1132 
       
  1133   This is a small positive integer, suitable for use with C library
       
  1134   functions such as fdopen() and fcntl(). On systems that use file
       
  1135   descriptors for sockets (i.e. Unix systems, but not Windows) the handle
       
  1136   can be used with QSocketNotifier as well.
       
  1137 
       
  1138   If the file is not open, or there is an error, handle() returns -1.
       
  1139 
       
  1140   This function is not supported on Windows CE.
       
  1141 
       
  1142   \sa QSocketNotifier
       
  1143 */
       
  1144 
       
  1145 int
       
  1146 QFile::handle() const
       
  1147 {
       
  1148     if (!isOpen())
       
  1149         return -1;
       
  1150 
       
  1151     if (QAbstractFileEngine *engine = fileEngine())
       
  1152         return engine->handle();
       
  1153     return -1;
       
  1154 }
       
  1155 
       
  1156 /*!
       
  1157     \enum QFile::MemoryMapFlags
       
  1158     \since 4.4
       
  1159 
       
  1160     This enum describes special options that may be used by the map()
       
  1161     function.
       
  1162 
       
  1163     \value NoOptions        No options.
       
  1164 */
       
  1165 
       
  1166 /*!
       
  1167     \since 4.4
       
  1168     Maps \a size bytes of the file into memory starting at \a offset.  A file
       
  1169     should be open for a map to succeed but the file does not need to stay
       
  1170     open after the memory has been mapped.  When the QFile is destroyed
       
  1171     or a new file is opened with this object, any maps that have not been
       
  1172     unmapped will automatically be unmapped.
       
  1173 
       
  1174     Any mapping options can be passed through \a flags.
       
  1175 
       
  1176     Returns a pointer to the memory or 0 if there is an error.
       
  1177 
       
  1178     \note On Windows CE 5.0 the file will be closed before mapping occurs.
       
  1179 
       
  1180     \sa unmap(), QAbstractFileEngine::supportsExtension()
       
  1181  */
       
  1182 uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
       
  1183 {
       
  1184     Q_D(QFile);
       
  1185     QAbstractFileEngine *engine = fileEngine();
       
  1186     if (engine
       
  1187         && engine->supportsExtension(QAbstractFileEngine::MapExtension)) {
       
  1188         unsetError();
       
  1189         uchar *address = engine->map(offset, size, flags);
       
  1190         if (address == 0)
       
  1191             d->setError(engine->error(), engine->errorString());
       
  1192         return address;
       
  1193     }
       
  1194     return 0;
       
  1195 }
       
  1196 
       
  1197 /*!
       
  1198     \since 4.4
       
  1199     Unmaps the memory \a address.
       
  1200 
       
  1201     Returns true if the unmap succeeds; false otherwise.
       
  1202 
       
  1203     \sa map(), QAbstractFileEngine::supportsExtension()
       
  1204  */
       
  1205 bool QFile::unmap(uchar *address)
       
  1206 {
       
  1207     Q_D(QFile);
       
  1208     QAbstractFileEngine *engine = fileEngine();
       
  1209     if (engine
       
  1210         && engine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
       
  1211         unsetError();
       
  1212         bool success = engine->unmap(address);
       
  1213         if (!success)
       
  1214             d->setError(engine->error(), engine->errorString());
       
  1215         return success;
       
  1216     }
       
  1217     return false;
       
  1218 }
       
  1219 
       
  1220 /*!
       
  1221     \fn QString QFile::name() const
       
  1222 
       
  1223     Use fileName() instead.
       
  1224 */
       
  1225 
       
  1226 /*!
       
  1227     \fn void QFile::setName(const QString &name)
       
  1228 
       
  1229     Use setFileName() instead.
       
  1230 */
       
  1231 
       
  1232 /*!
       
  1233     Sets the file size (in bytes) \a sz. Returns true if the file if the
       
  1234     resize succeeds; false otherwise. If \a sz is larger than the file
       
  1235     currently is the new bytes will be set to 0, if \a sz is smaller the
       
  1236     file is simply truncated.
       
  1237 
       
  1238     \sa size(), setFileName()
       
  1239 */
       
  1240 
       
  1241 bool
       
  1242 QFile::resize(qint64 sz)
       
  1243 {
       
  1244     Q_D(QFile);
       
  1245     if (!d->ensureFlushed())
       
  1246         return false;
       
  1247     if (isOpen() && fileEngine()->pos() > sz)
       
  1248         seek(sz);
       
  1249     if(fileEngine()->setSize(sz)) {
       
  1250         unsetError();
       
  1251         return true;
       
  1252     }
       
  1253     d->setError(QFile::ResizeError, fileEngine()->errorString());
       
  1254     return false;
       
  1255 }
       
  1256 
       
  1257 /*!
       
  1258     \overload
       
  1259 
       
  1260     Sets \a fileName to size (in bytes) \a sz. Returns true if the file if
       
  1261     the resize succeeds; false otherwise. If \a sz is larger than \a
       
  1262     fileName currently is the new bytes will be set to 0, if \a sz is
       
  1263     smaller the file is simply truncated.
       
  1264 
       
  1265     \sa resize()
       
  1266 */
       
  1267 
       
  1268 bool
       
  1269 QFile::resize(const QString &fileName, qint64 sz)
       
  1270 {
       
  1271     return QFile(fileName).resize(sz);
       
  1272 }
       
  1273 
       
  1274 /*!
       
  1275     Returns the complete OR-ed together combination of
       
  1276     QFile::Permission for the file.
       
  1277 
       
  1278     \sa setPermissions(), setFileName()
       
  1279 */
       
  1280 
       
  1281 QFile::Permissions
       
  1282 QFile::permissions() const
       
  1283 {
       
  1284     QAbstractFileEngine::FileFlags perms = fileEngine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
       
  1285     return QFile::Permissions((int)perms); //ewww
       
  1286 }
       
  1287 
       
  1288 /*!
       
  1289     \overload
       
  1290 
       
  1291     Returns the complete OR-ed together combination of
       
  1292     QFile::Permission for \a fileName.
       
  1293 */
       
  1294 
       
  1295 QFile::Permissions
       
  1296 QFile::permissions(const QString &fileName)
       
  1297 {
       
  1298     return QFile(fileName).permissions();
       
  1299 }
       
  1300 
       
  1301 /*!
       
  1302     Sets the permissions for the file to the \a permissions specified.
       
  1303     Returns true if successful, or false if the permissions cannot be
       
  1304     modified.
       
  1305 
       
  1306     \sa permissions(), setFileName()
       
  1307 */
       
  1308 
       
  1309 bool
       
  1310 QFile::setPermissions(Permissions permissions)
       
  1311 {
       
  1312     Q_D(QFile);
       
  1313     if(fileEngine()->setPermissions(permissions)) {
       
  1314         unsetError();
       
  1315         return true;
       
  1316     }
       
  1317     d->setError(QFile::PermissionsError, fileEngine()->errorString());
       
  1318     return false;
       
  1319 }
       
  1320 
       
  1321 /*!
       
  1322     \overload
       
  1323 
       
  1324     Sets the permissions for \a fileName file to \a permissions.
       
  1325 */
       
  1326 
       
  1327 bool
       
  1328 QFile::setPermissions(const QString &fileName, Permissions permissions)
       
  1329 {
       
  1330     return QFile(fileName).setPermissions(permissions);
       
  1331 }
       
  1332 
       
  1333 static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
       
  1334 {
       
  1335     qint64 ret = engine->write(buffer->readPointer(), buffer->size());
       
  1336     if (ret > 0)
       
  1337         buffer->free(ret);
       
  1338     return ret;
       
  1339 }
       
  1340 
       
  1341 /*!
       
  1342     Flushes any buffered data to the file. Returns true if successful;
       
  1343     otherwise returns false.
       
  1344 */
       
  1345 
       
  1346 bool
       
  1347 QFile::flush()
       
  1348 {
       
  1349     Q_D(QFile);
       
  1350     if (!d->writeBuffer.isEmpty()) {
       
  1351         qint64 size = d->writeBuffer.size();
       
  1352         if (_qfile_writeData(d->fileEngine ? d->fileEngine : fileEngine(),
       
  1353                              &d->writeBuffer) != size) {
       
  1354             QFile::FileError err = fileEngine()->error();
       
  1355             if(err == QFile::UnspecifiedError)
       
  1356                 err = QFile::WriteError;
       
  1357             d->setError(err, fileEngine()->errorString());
       
  1358             return false;
       
  1359         }
       
  1360     }
       
  1361 
       
  1362     if (!fileEngine()->flush()) {
       
  1363         QFile::FileError err = fileEngine()->error();
       
  1364         if(err == QFile::UnspecifiedError)
       
  1365             err = QFile::WriteError;
       
  1366         d->setError(err, fileEngine()->errorString());
       
  1367         return false;
       
  1368     }
       
  1369     return true;
       
  1370 }
       
  1371 
       
  1372 /*!
       
  1373   Calls QFile::flush() and closes the file. Errors from flush are ignored.
       
  1374 
       
  1375   \sa QIODevice::close()
       
  1376 */
       
  1377 void
       
  1378 QFile::close()
       
  1379 {
       
  1380     Q_D(QFile);
       
  1381     if(!isOpen())
       
  1382         return;
       
  1383     flush();
       
  1384     QIODevice::close();
       
  1385 
       
  1386     unsetError();
       
  1387     if(!fileEngine()->close())
       
  1388         d->setError(fileEngine()->error(), fileEngine()->errorString());
       
  1389 }
       
  1390 
       
  1391 /*!
       
  1392   Returns the size of the file.
       
  1393 
       
  1394   For regular empty files on Unix (e.g. those in \c /proc), this function
       
  1395   returns 0; the contents of such a file are generated on demand in response
       
  1396   to you calling read().
       
  1397 */
       
  1398 
       
  1399 qint64 QFile::size() const
       
  1400 {
       
  1401     Q_D(const QFile);
       
  1402     if (!d->ensureFlushed())
       
  1403         return 0;
       
  1404     return fileEngine()->size();
       
  1405 }
       
  1406 
       
  1407 /*!
       
  1408   \reimp
       
  1409 */
       
  1410 
       
  1411 qint64 QFile::pos() const
       
  1412 {
       
  1413     return QIODevice::pos();
       
  1414 }
       
  1415 
       
  1416 /*!
       
  1417   Returns true if the end of the file has been reached; otherwise returns
       
  1418   false.
       
  1419 
       
  1420   For regular empty files on Unix (e.g. those in \c /proc), this function
       
  1421   returns true, since the file system reports that the size of such a file is
       
  1422   0. Therefore, you should not depend on atEnd() when reading data from such a
       
  1423   file, but rather call read() until no more data can be read.
       
  1424 */
       
  1425 
       
  1426 bool QFile::atEnd() const
       
  1427 {
       
  1428     Q_D(const QFile);
       
  1429 
       
  1430     if (!isOpen())
       
  1431         return true;
       
  1432 
       
  1433     if (!d->ensureFlushed())
       
  1434         return false;
       
  1435 
       
  1436     // If there's buffered data left, we're not at the end.
       
  1437     if (!d->buffer.isEmpty())
       
  1438         return false;
       
  1439 
       
  1440     // If the file engine knows best, say what it says.
       
  1441     if (fileEngine()->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
       
  1442         // Check if the file engine supports AtEndExtension, and if it does,
       
  1443         // check if the file engine claims to be at the end.
       
  1444         return fileEngine()->atEnd();
       
  1445     }
       
  1446 
       
  1447     // Fall back to checking how much is available (will stat files).
       
  1448     return bytesAvailable() == 0;
       
  1449 }
       
  1450 
       
  1451 /*!
       
  1452   \reimp
       
  1453 */
       
  1454 
       
  1455 bool QFile::seek(qint64 off)
       
  1456 {
       
  1457     Q_D(QFile);
       
  1458     if (!isOpen()) {
       
  1459         qWarning("QFile::seek: IODevice is not open");
       
  1460         return false;
       
  1461     }
       
  1462 
       
  1463     if (!d->ensureFlushed())
       
  1464         return false;
       
  1465 
       
  1466     if (!fileEngine()->seek(off) || !QIODevice::seek(off)) {
       
  1467         QFile::FileError err = fileEngine()->error();
       
  1468         if(err == QFile::UnspecifiedError)
       
  1469             err = QFile::PositionError;
       
  1470         d->setError(err, fileEngine()->errorString());
       
  1471         return false;
       
  1472     }
       
  1473     unsetError();
       
  1474     return true;
       
  1475 }
       
  1476 
       
  1477 /*!
       
  1478   \reimp
       
  1479 */
       
  1480 qint64 QFile::readLineData(char *data, qint64 maxlen)
       
  1481 {
       
  1482     Q_D(QFile);
       
  1483     if (!d->ensureFlushed())
       
  1484         return -1;
       
  1485 
       
  1486     if (fileEngine()->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
       
  1487         return fileEngine()->readLine(data, maxlen);
       
  1488 
       
  1489     // Fall back to QIODevice's readLine implementation if the engine
       
  1490     // cannot do it faster.
       
  1491     return QIODevice::readLineData(data, maxlen);
       
  1492 }
       
  1493 
       
  1494 /*!
       
  1495   \reimp
       
  1496 */
       
  1497 
       
  1498 qint64 QFile::readData(char *data, qint64 len)
       
  1499 {
       
  1500     Q_D(QFile);
       
  1501     unsetError();
       
  1502     if (!d->ensureFlushed())
       
  1503         return -1;
       
  1504 
       
  1505     qint64 ret = -1;
       
  1506     qint64 read = fileEngine()->read(data, len);
       
  1507     if (read != -1)
       
  1508         ret = read;
       
  1509 
       
  1510     if(ret < 0) {
       
  1511         QFile::FileError err = fileEngine()->error();
       
  1512         if(err == QFile::UnspecifiedError)
       
  1513             err = QFile::ReadError;
       
  1514         d->setError(err, fileEngine()->errorString());
       
  1515     }
       
  1516     return ret;
       
  1517 }
       
  1518 
       
  1519 /*!
       
  1520     \internal
       
  1521 */
       
  1522 bool QFilePrivate::putCharHelper(char c)
       
  1523 {
       
  1524 #ifdef QT_NO_QOBJECT
       
  1525     return QIODevicePrivate::putCharHelper(c);
       
  1526 #else
       
  1527 
       
  1528     // Cutoff for code that doesn't only touch the buffer.
       
  1529     int writeBufferSize = writeBuffer.size();
       
  1530     if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
       
  1531 #ifdef Q_OS_WIN
       
  1532         || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
       
  1533 #endif
       
  1534         ) {
       
  1535         return QIODevicePrivate::putCharHelper(c);
       
  1536     }
       
  1537 
       
  1538     if (!(openMode & QIODevice::WriteOnly)) {
       
  1539         if (openMode == QIODevice::NotOpen)
       
  1540             qWarning("QIODevice::putChar: Closed device");
       
  1541         else
       
  1542             qWarning("QIODevice::putChar: ReadOnly device");
       
  1543         return false;
       
  1544     }
       
  1545 
       
  1546     // Make sure the device is positioned correctly.
       
  1547     const bool sequential = isSequential();
       
  1548     if (pos != devicePos && !sequential && !q_func()->seek(pos))
       
  1549         return false;
       
  1550 
       
  1551     lastWasWrite = true;
       
  1552 
       
  1553     int len = 1;
       
  1554 #ifdef Q_OS_WIN
       
  1555     if ((openMode & QIODevice::Text) && c == '\n') {
       
  1556         ++len;
       
  1557         *writeBuffer.reserve(1) = '\r';
       
  1558     }
       
  1559 #endif
       
  1560 
       
  1561     // Write to buffer.
       
  1562     *writeBuffer.reserve(1) = c;
       
  1563 
       
  1564     if (!sequential) {
       
  1565         pos += len;
       
  1566         devicePos += len;
       
  1567         if (!buffer.isEmpty())
       
  1568             buffer.skip(len);
       
  1569     }
       
  1570 
       
  1571     return true;
       
  1572 #endif
       
  1573 }
       
  1574 
       
  1575 /*!
       
  1576   \reimp
       
  1577 */
       
  1578 
       
  1579 qint64
       
  1580 QFile::writeData(const char *data, qint64 len)
       
  1581 {
       
  1582     Q_D(QFile);
       
  1583     unsetError();
       
  1584     d->lastWasWrite = true;
       
  1585     bool buffered = !(d->openMode & Unbuffered);
       
  1586 
       
  1587     // Flush buffered data if this read will overflow.
       
  1588     if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
       
  1589         if (!flush())
       
  1590             return -1;
       
  1591     }
       
  1592 
       
  1593     // Write directly to the engine if the block size is larger than
       
  1594     // the write buffer size.
       
  1595     if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
       
  1596         QAbstractFileEngine *fe = d->fileEngine ? d->fileEngine : fileEngine();
       
  1597         qint64 ret = fe->write(data, len);
       
  1598         if(ret < 0) {
       
  1599             QFile::FileError err = fileEngine()->error();
       
  1600             if(err == QFile::UnspecifiedError)
       
  1601                 err = QFile::WriteError;
       
  1602             d->setError(err, fileEngine()->errorString());
       
  1603         }
       
  1604         return ret;
       
  1605     }
       
  1606 
       
  1607     // Write to the buffer.
       
  1608     char *writePointer = d->writeBuffer.reserve(len);
       
  1609     if (len == 1)
       
  1610         *writePointer = *data;
       
  1611     else
       
  1612         ::memcpy(writePointer, data, len);
       
  1613     return len;
       
  1614 }
       
  1615 
       
  1616 /*!
       
  1617     \internal
       
  1618     Returns the QIOEngine for this QFile object.
       
  1619 */
       
  1620 QAbstractFileEngine *QFile::fileEngine() const
       
  1621 {
       
  1622     Q_D(const QFile);
       
  1623     if(!d->fileEngine)
       
  1624         d->fileEngine = QAbstractFileEngine::create(d->fileName);
       
  1625     return d->fileEngine;
       
  1626 }
       
  1627 
       
  1628 /*!
       
  1629     Returns the file error status.
       
  1630 
       
  1631     The I/O device status returns an error code. For example, if open()
       
  1632     returns false, or a read/write operation returns -1, this function can
       
  1633     be called to find out the reason why the operation failed.
       
  1634 
       
  1635     \sa unsetError()
       
  1636 */
       
  1637 
       
  1638 QFile::FileError
       
  1639 QFile::error() const
       
  1640 {
       
  1641     Q_D(const QFile);
       
  1642     return d->error;
       
  1643 }
       
  1644 
       
  1645 /*!
       
  1646     Sets the file's error to QFile::NoError.
       
  1647 
       
  1648     \sa error()
       
  1649 */
       
  1650 void
       
  1651 QFile::unsetError()
       
  1652 {
       
  1653     Q_D(QFile);
       
  1654     d->setError(QFile::NoError);
       
  1655 }
       
  1656 
       
  1657 QT_END_NAMESPACE