summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qfile.cpp')
-rw-r--r--src/corelib/io/qfile.cpp635
1 files changed, 18 insertions, 617 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 6640dca70b..433d4493e5 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE
-static const int QFILE_WRITEBUFFER_SIZE = 16384;
-
static QByteArray locale_encode(const QString &f)
{
#if defined(Q_OS_DARWIN)
@@ -86,16 +84,11 @@ QFile::EncoderFn QFilePrivate::encoder = locale_encode;
QFile::DecoderFn QFilePrivate::decoder = locale_decode;
QFilePrivate::QFilePrivate()
- : fileEngine(0), lastWasWrite(false),
- writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
- cachedSize(0)
{
}
QFilePrivate::~QFilePrivate()
{
- delete fileEngine;
- fileEngine = 0;
}
bool
@@ -137,39 +130,6 @@ QAbstractFileEngine *QFilePrivate::engine() const
return fileEngine;
}
-inline bool QFilePrivate::ensureFlushed() const
-{
- // This function ensures that the write buffer has been flushed (const
- // because certain const functions need to call it.
- if (lastWasWrite) {
- const_cast<QFilePrivate *>(this)->lastWasWrite = false;
- if (!const_cast<QFile *>(q_func())->flush())
- return false;
- }
- return true;
-}
-
-void
-QFilePrivate::setError(QFile::FileError err)
-{
- error = err;
- errorString.clear();
-}
-
-void
-QFilePrivate::setError(QFile::FileError err, const QString &errStr)
-{
- error = err;
- errorString = errStr;
-}
-
-void
-QFilePrivate::setError(QFile::FileError err, int errNum)
-{
- error = err;
- errorString = qt_error_string(errNum);
-}
-
//************* QFile
/*!
@@ -278,98 +238,18 @@ QFilePrivate::setError(QFile::FileError err, int errNum)
\sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
*/
-/*!
- \enum QFile::FileError
-
- This enum describes the errors that may be returned by the error()
- function.
-
- \value NoError No error occurred.
- \value ReadError An error occurred when reading from the file.
- \value WriteError An error occurred when writing to the file.
- \value FatalError A fatal error occurred.
- \value ResourceError
- \value OpenError The file could not be opened.
- \value AbortError The operation was aborted.
- \value TimeOutError A timeout occurred.
- \value UnspecifiedError An unspecified error occurred.
- \value RemoveError The file could not be removed.
- \value RenameError The file could not be renamed.
- \value PositionError The position in the file could not be changed.
- \value ResizeError The file could not be resized.
- \value PermissionsError The file could not be accessed.
- \value CopyError The file could not be copied.
-
- \omitvalue ConnectError
-*/
-
-/*!
- \enum QFile::Permission
-
- This enum is used by the permission() function to report the
- permissions and ownership of a file. The values may be OR-ed
- together to test multiple permissions and ownership values.
-
- \value ReadOwner The file is readable by the owner of the file.
- \value WriteOwner The file is writable by the owner of the file.
- \value ExeOwner The file is executable by the owner of the file.
- \value ReadUser The file is readable by the user.
- \value WriteUser The file is writable by the user.
- \value ExeUser The file is executable by the user.
- \value ReadGroup The file is readable by the group.
- \value WriteGroup The file is writable by the group.
- \value ExeGroup The file is executable by the group.
- \value ReadOther The file is readable by anyone.
- \value WriteOther The file is writable by anyone.
- \value ExeOther The file is executable by anyone.
-
- \warning Because of differences in the platforms supported by Qt,
- the semantics of ReadUser, WriteUser and ExeUser are
- platform-dependent: On Unix, the rights of the owner of the file
- are returned and on Windows the rights of the current user are
- returned. This behavior might change in a future Qt version.
-
- Note that Qt does not by default check for permissions on NTFS
- file systems, as this may decrease the performance of file
- handling considerably. It is possible to force permission checking
- on NTFS by including the following code in your source:
-
- \snippet doc/src/snippets/ntfsp.cpp 0
-
- Permission checking is then turned on and off by incrementing and
- decrementing \c qt_ntfs_permission_lookup by 1.
-
- \snippet doc/src/snippets/ntfsp.cpp 1
-*/
-
-/*!
- \enum QFile::FileHandleFlag
-
- This enum is used when opening a file to specify additional
- options which only apply to files and not to a generic
- QIODevice.
-
- \value AutoCloseHandle The file handle passed into open() should be
- closed by close(), the default behavior is that close just flushes
- the file and the application is responsible for closing the file handle.
- When opening a file by name, this flag is ignored as Qt always owns the
- file handle and must close it.
- \value DontCloseHandle If not explicitly closed, the underlying file
- handle is left open when the QFile object is destroyed.
- */
-
#ifdef QT_NO_QOBJECT
QFile::QFile()
- : QIODevice(*new QFilePrivate)
+ : QFileDevice(*new QFilePrivate)
{
}
QFile::QFile(const QString &name)
- : QIODevice(*new QFilePrivate)
+ : QFileDevice(*new QFilePrivate)
{
d_func()->fileName = name;
}
QFile::QFile(QFilePrivate &dd)
- : QIODevice(dd)
+ : QFileDevice(dd)
{
}
#else
@@ -377,21 +257,21 @@ QFile::QFile(QFilePrivate &dd)
\internal
*/
QFile::QFile()
- : QIODevice(*new QFilePrivate, 0)
+ : QFileDevice(*new QFilePrivate, 0)
{
}
/*!
Constructs a new file object with the given \a parent.
*/
QFile::QFile(QObject *parent)
- : QIODevice(*new QFilePrivate, parent)
+ : QFileDevice(*new QFilePrivate, parent)
{
}
/*!
Constructs a new file object to represent the file with the given \a name.
*/
QFile::QFile(const QString &name)
- : QIODevice(*new QFilePrivate, 0)
+ : QFileDevice(*new QFilePrivate, 0)
{
Q_D(QFile);
d->fileName = name;
@@ -401,7 +281,7 @@ QFile::QFile(const QString &name)
file with the specified \a name.
*/
QFile::QFile(const QString &name, QObject *parent)
- : QIODevice(*new QFilePrivate, parent)
+ : QFileDevice(*new QFilePrivate, parent)
{
Q_D(QFile);
d->fileName = name;
@@ -410,7 +290,7 @@ QFile::QFile(const QString &name, QObject *parent)
\internal
*/
QFile::QFile(QFilePrivate &dd, QObject *parent)
- : QIODevice(dd, parent)
+ : QFileDevice(dd, parent)
{
}
#endif
@@ -420,7 +300,6 @@ QFile::QFile(QFilePrivate &dd, QObject *parent)
*/
QFile::~QFile()
{
- close();
}
/*!
@@ -962,20 +841,6 @@ QFile::copy(const QString &fileName, const QString &newName)
}
/*!
- Returns true if the file can only be manipulated sequentially;
- otherwise returns false.
-
- Most files support random-access, but some special files may not.
-
- \sa QIODevice::isSequential()
-*/
-bool QFile::isSequential() const
-{
- Q_D(const QFile);
- return d->fileEngine && d->fileEngine->isSequential();
-}
-
-/*!
Opens the file using OpenMode \a mode, returning true if successful;
otherwise false.
@@ -1149,119 +1014,11 @@ bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
}
/*!
- Returns the file handle of the file.
-
- This is a small positive integer, suitable for use with C library
- functions such as fdopen() and fcntl(). On systems that use file
- descriptors for sockets (i.e. Unix systems, but not Windows) the handle
- can be used with QSocketNotifier as well.
-
- If the file is not open, or there is an error, handle() returns -1.
-
- This function is not supported on Windows CE.
-
- \sa QSocketNotifier
-*/
-
-int
-QFile::handle() const
-{
- Q_D(const QFile);
- if (!isOpen() || !d->fileEngine)
- return -1;
-
- return d->fileEngine->handle();
-}
-
-/*!
- \enum QFile::MemoryMapFlags
- \since 4.4
-
- This enum describes special options that may be used by the map()
- function.
-
- \value NoOptions No options.
-*/
-
-/*!
- \since 4.4
- Maps \a size bytes of the file into memory starting at \a offset. A file
- should be open for a map to succeed but the file does not need to stay
- open after the memory has been mapped. When the QFile is destroyed
- or a new file is opened with this object, any maps that have not been
- unmapped will automatically be unmapped.
-
- Any mapping options can be passed through \a flags.
-
- Returns a pointer to the memory or 0 if there is an error.
-
- \note On Windows CE 5.0 the file will be closed before mapping occurs.
-
- \sa unmap()
- */
-uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
-{
- Q_D(QFile);
- if (d->engine()
- && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
- unsetError();
- uchar *address = d->fileEngine->map(offset, size, flags);
- if (address == 0)
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- return address;
- }
- return 0;
-}
-
-/*!
- \since 4.4
- Unmaps the memory \a address.
-
- Returns true if the unmap succeeds; false otherwise.
-
- \sa map()
- */
-bool QFile::unmap(uchar *address)
-{
- Q_D(QFile);
- if (d->engine()
- && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
- unsetError();
- bool success = d->fileEngine->unmap(address);
- if (!success)
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- return success;
- }
- d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
- return false;
-}
-
-/*!
- Sets the file size (in bytes) \a sz. Returns true if the file if the
- resize succeeds; false otherwise. If \a sz is larger than the file
- currently is the new bytes will be set to 0, if \a sz is smaller the
- file is simply truncated.
-
- \sa size(), setFileName()
+ \reimp
*/
-
-bool
-QFile::resize(qint64 sz)
+bool QFile::resize(qint64 sz)
{
- Q_D(QFile);
- if (!d->ensureFlushed())
- return false;
- d->engine();
- if (isOpen() && d->fileEngine->pos() > sz)
- seek(sz);
- if(d->fileEngine->setSize(sz)) {
- unsetError();
- d->cachedSize = sz;
- return true;
- }
- d->cachedSize = 0;
- d->setError(QFile::ResizeError, d->fileEngine->errorString());
- return false;
+ return QFileDevice::resize(sz); // for now
}
/*!
@@ -1282,18 +1039,11 @@ QFile::resize(const QString &fileName, qint64 sz)
}
/*!
- Returns the complete OR-ed together combination of
- QFile::Permission for the file.
-
- \sa setPermissions(), setFileName()
+ \reimp
*/
-
-QFile::Permissions
-QFile::permissions() const
+QFile::Permissions QFile::permissions() const
{
- Q_D(const QFile);
- QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
- return QFile::Permissions((int)perms); //ewww
+ return QFileDevice::permissions(); // for now
}
/*!
@@ -1317,16 +1067,9 @@ QFile::permissions(const QString &fileName)
\sa permissions(), setFileName()
*/
-bool
-QFile::setPermissions(Permissions permissions)
+bool QFile::setPermissions(Permissions permissions)
{
- Q_D(QFile);
- if (d->engine()->setPermissions(permissions)) {
- unsetError();
- return true;
- }
- d->setError(QFile::PermissionsError, d->fileEngine->errorString());
- return false;
+ return QFileDevice::setPermissions(permissions); // for now
}
/*!
@@ -1341,354 +1084,12 @@ QFile::setPermissions(const QString &fileName, Permissions permissions)
return QFile(fileName).setPermissions(permissions);
}
-static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
-{
- qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
- if (ret > 0)
- buffer->free(ret);
- return ret;
-}
-
-/*!
- Flushes any buffered data to the file. Returns true if successful;
- otherwise returns false.
-*/
-
-bool
-QFile::flush()
-{
- Q_D(QFile);
- if (!d->fileEngine) {
- qWarning("QFile::flush: No file engine. Is IODevice open?");
- return false;
- }
-
- if (!d->writeBuffer.isEmpty()) {
- qint64 size = d->writeBuffer.size();
- if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::WriteError;
- d->setError(err, d->fileEngine->errorString());
- return false;
- }
- }
-
- if (!d->fileEngine->flush()) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::WriteError;
- d->setError(err, d->fileEngine->errorString());
- return false;
- }
- return true;
-}
-
-/*!
- Calls QFile::flush() and closes the file. Errors from flush are ignored.
-
- \sa QIODevice::close()
-*/
-void
-QFile::close()
-{
- Q_D(QFile);
- if(!isOpen())
- return;
- bool flushed = flush();
- QIODevice::close();
-
- // reset write buffer
- d->lastWasWrite = false;
- d->writeBuffer.clear();
-
- // keep earlier error from flush
- if (d->fileEngine->close() && flushed)
- unsetError();
- else if (flushed)
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
-}
-
-/*!
- Returns the size of the file.
-
- For regular empty files on Unix (e.g. those in \c /proc), this function
- returns 0; the contents of such a file are generated on demand in response
- to you calling read().
-*/
-
-qint64 QFile::size() const
-{
- Q_D(const QFile);
- if (!d->ensureFlushed())
- return 0;
- d->cachedSize = d->engine()->size();
- return d->cachedSize;
-}
-
-/*!
- \reimp
-*/
-
-qint64 QFile::pos() const
-{
- return QIODevice::pos();
-}
-
-/*!
- Returns true if the end of the file has been reached; otherwise returns
- false.
-
- For regular empty files on Unix (e.g. those in \c /proc), this function
- returns true, since the file system reports that the size of such a file is
- 0. Therefore, you should not depend on atEnd() when reading data from such a
- file, but rather call read() until no more data can be read.
-*/
-
-bool QFile::atEnd() const
-{
- Q_D(const QFile);
-
- // If there's buffered data left, we're not at the end.
- if (!d->buffer.isEmpty())
- return false;
-
- if (!isOpen())
- return true;
-
- if (!d->ensureFlushed())
- return false;
-
- // If the file engine knows best, say what it says.
- if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
- // Check if the file engine supports AtEndExtension, and if it does,
- // check if the file engine claims to be at the end.
- return d->fileEngine->atEnd();
- }
-
- // if it looks like we are at the end, or if size is not cached,
- // fall through to bytesAvailable() to make sure.
- if (pos() < d->cachedSize)
- return false;
-
- // Fall back to checking how much is available (will stat files).
- return bytesAvailable() == 0;
-}
-
-/*!
- \fn bool QFile::seek(qint64 pos)
-
- For random-access devices, this function sets the current position
- to \a pos, returning true on success, or false if an error occurred.
- For sequential devices, the default behavior is to do nothing and
- return false.
-
- Seeking beyond the end of a file:
- If the position is beyond the end of a file, then seek() shall not
- immediately extend the file. If a write is performed at this position,
- then the file shall be extended. The content of the file between the
- previous end of file and the newly written data is UNDEFINED and
- varies between platforms and file systems.
-*/
-
-bool QFile::seek(qint64 off)
-{
- Q_D(QFile);
- if (!isOpen()) {
- qWarning("QFile::seek: IODevice is not open");
- return false;
- }
-
- if (!d->ensureFlushed())
- return false;
-
- if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::PositionError;
- d->setError(err, d->fileEngine->errorString());
- return false;
- }
- unsetError();
- return true;
-}
-
-/*!
- \reimp
-*/
-qint64 QFile::readLineData(char *data, qint64 maxlen)
-{
- Q_D(QFile);
- if (!d->ensureFlushed())
- return -1;
-
- qint64 read;
- if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
- read = d->fileEngine->readLine(data, maxlen);
- } else {
- // Fall back to QIODevice's readLine implementation if the engine
- // cannot do it faster.
- read = QIODevice::readLineData(data, maxlen);
- }
-
- if (read < maxlen) {
- // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
- d->cachedSize = 0;
- }
-
- return read;
-}
-
-/*!
- \reimp
-*/
-
-qint64 QFile::readData(char *data, qint64 len)
-{
- Q_D(QFile);
- unsetError();
- if (!d->ensureFlushed())
- return -1;
-
- qint64 read = d->fileEngine->read(data, len);
- if(read < 0) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::ReadError;
- d->setError(err, d->fileEngine->errorString());
- }
-
- if (read < len) {
- // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
- d->cachedSize = 0;
- }
-
- return read;
-}
-
-/*!
- \internal
-*/
-bool QFilePrivate::putCharHelper(char c)
-{
-#ifdef QT_NO_QOBJECT
- return QIODevicePrivate::putCharHelper(c);
-#else
-
- // Cutoff for code that doesn't only touch the buffer.
- int writeBufferSize = writeBuffer.size();
- if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
-#ifdef Q_OS_WIN
- || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
-#endif
- ) {
- return QIODevicePrivate::putCharHelper(c);
- }
-
- if (!(openMode & QIODevice::WriteOnly)) {
- if (openMode == QIODevice::NotOpen)
- qWarning("QIODevice::putChar: Closed device");
- else
- qWarning("QIODevice::putChar: ReadOnly device");
- return false;
- }
-
- // Make sure the device is positioned correctly.
- const bool sequential = isSequential();
- if (pos != devicePos && !sequential && !q_func()->seek(pos))
- return false;
-
- lastWasWrite = true;
-
- int len = 1;
-#ifdef Q_OS_WIN
- if ((openMode & QIODevice::Text) && c == '\n') {
- ++len;
- *writeBuffer.reserve(1) = '\r';
- }
-#endif
-
- // Write to buffer.
- *writeBuffer.reserve(1) = c;
-
- if (!sequential) {
- pos += len;
- devicePos += len;
- if (!buffer.isEmpty())
- buffer.skip(len);
- }
-
- return true;
-#endif
-}
-
/*!
\reimp
*/
-
-qint64
-QFile::writeData(const char *data, qint64 len)
-{
- Q_D(QFile);
- unsetError();
- d->lastWasWrite = true;
- bool buffered = !(d->openMode & Unbuffered);
-
- // Flush buffered data if this read will overflow.
- if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
- if (!flush())
- return -1;
- }
-
- // Write directly to the engine if the block size is larger than
- // the write buffer size.
- if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
- qint64 ret = d->fileEngine->write(data, len);
- if(ret < 0) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::WriteError;
- d->setError(err, d->fileEngine->errorString());
- }
- return ret;
- }
-
- // Write to the buffer.
- char *writePointer = d->writeBuffer.reserve(len);
- if (len == 1)
- *writePointer = *data;
- else
- ::memcpy(writePointer, data, len);
- return len;
-}
-
-/*!
- Returns the file error status.
-
- The I/O device status returns an error code. For example, if open()
- returns false, or a read/write operation returns -1, this function can
- be called to find out the reason why the operation failed.
-
- \sa unsetError()
-*/
-
-QFile::FileError
-QFile::error() const
-{
- Q_D(const QFile);
- return d->error;
-}
-
-/*!
- Sets the file's error to QFile::NoError.
-
- \sa error()
-*/
-void
-QFile::unsetError()
+qint64 QFile::size() const
{
- Q_D(QFile);
- d->setError(QFile::NoError);
+ return QFileDevice::size(); // for now
}
QT_END_NAMESPACE