Split up base class QFileDevice for open-file operations (read/write)
This will be used later on as a base class for QTemporaryFile and QSaveFile. Change-Id: Ic2e1d232f95dc29b8e2f75e24a881ab459d3f037 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
parent
d51abed57a
commit
dc75c20397
@ -15,7 +15,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \
|
||||
|
||||
#qt code
|
||||
QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
|
||||
qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \
|
||||
qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \
|
||||
qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o qfilesystemiterator_unix.o \
|
||||
qfsfileengine_unix.o qfsfileengine.o \
|
||||
qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \
|
||||
@ -37,6 +37,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
|
||||
generators/integrity/gbuild.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/global/qglobal.cpp $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \
|
||||
@ -176,6 +177,9 @@ qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
|
||||
qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
|
||||
|
||||
qfiledevice.o: $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp
|
||||
|
||||
qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
|
||||
|
||||
|
@ -82,6 +82,7 @@ QTOBJS= \
|
||||
qdatetime.obj \
|
||||
qdir.obj \
|
||||
qdiriterator.obj \
|
||||
qfiledevice.obj \
|
||||
qfile.obj \
|
||||
qtemporaryfile.obj \
|
||||
qabstractfileengine.obj \
|
||||
|
@ -84,6 +84,7 @@ QTOBJS= \
|
||||
qdatetime.o \
|
||||
qdir.o \
|
||||
qdiriterator.o \
|
||||
qfiledevice.o \
|
||||
qfile.o \
|
||||
qtemporaryfile.o \
|
||||
qfileinfo.o \
|
||||
|
@ -42,6 +42,7 @@ bootstrap { #Qt code
|
||||
qdatetime.cpp \
|
||||
qdir.cpp \
|
||||
qdiriterator.cpp \
|
||||
qfiledevice.cpp \
|
||||
qfile.cpp \
|
||||
qabstractfileengine.cpp \
|
||||
qfileinfo.cpp \
|
||||
|
@ -11,6 +11,8 @@ HEADERS += \
|
||||
io/qdir_p.h \
|
||||
io/qdiriterator.h \
|
||||
io/qfile.h \
|
||||
io/qfiledevice.h \
|
||||
io/qfiledevice_p.h \
|
||||
io/qfileinfo.h \
|
||||
io/qfileinfo_p.h \
|
||||
io/qiodevice.h \
|
||||
@ -49,6 +51,7 @@ SOURCES += \
|
||||
io/qdir.cpp \
|
||||
io/qdiriterator.cpp \
|
||||
io/qfile.cpp \
|
||||
io/qfiledevice.cpp \
|
||||
io/qfileinfo.cpp \
|
||||
io/qiodevice.cpp \
|
||||
io/qnoncontiguousbytedevice.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();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -961,20 +840,6 @@ QFile::copy(const QString &fileName, const QString &newName)
|
||||
return QFile(fileName).copy(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
|
||||
\reimp
|
||||
*/
|
||||
|
||||
int
|
||||
QFile::handle() const
|
||||
bool QFile::resize(qint64 sz)
|
||||
{
|
||||
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()
|
||||
*/
|
||||
|
||||
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.
|
||||
\reimp
|
||||
*/
|
||||
|
||||
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()
|
||||
{
|
||||
Q_D(QFile);
|
||||
d->setError(QFile::NoError);
|
||||
return QFileDevice::size(); // for now
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -42,7 +42,7 @@
|
||||
#ifndef QFILE_H
|
||||
#define QFILE_H
|
||||
|
||||
#include <QtCore/qiodevice.h>
|
||||
#include <QtCore/qfiledevice.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QTemporaryFile;
|
||||
class QFilePrivate;
|
||||
|
||||
class Q_CORE_EXPORT QFile : public QIODevice
|
||||
class Q_CORE_EXPORT QFile : public QFileDevice
|
||||
{
|
||||
#ifndef QT_NO_QOBJECT
|
||||
Q_OBJECT
|
||||
@ -65,39 +65,6 @@ class Q_CORE_EXPORT QFile : public QIODevice
|
||||
Q_DECLARE_PRIVATE(QFile)
|
||||
|
||||
public:
|
||||
|
||||
enum FileError {
|
||||
NoError = 0,
|
||||
ReadError = 1,
|
||||
WriteError = 2,
|
||||
FatalError = 3,
|
||||
ResourceError = 4,
|
||||
OpenError = 5,
|
||||
AbortError = 6,
|
||||
TimeOutError = 7,
|
||||
UnspecifiedError = 8,
|
||||
RemoveError = 9,
|
||||
RenameError = 10,
|
||||
PositionError = 11,
|
||||
ResizeError = 12,
|
||||
PermissionsError = 13,
|
||||
CopyError = 14
|
||||
};
|
||||
|
||||
enum Permission {
|
||||
ReadOwner = 0x4000, WriteOwner = 0x2000, ExeOwner = 0x1000,
|
||||
ReadUser = 0x0400, WriteUser = 0x0200, ExeUser = 0x0100,
|
||||
ReadGroup = 0x0040, WriteGroup = 0x0020, ExeGroup = 0x0010,
|
||||
ReadOther = 0x0004, WriteOther = 0x0002, ExeOther = 0x0001
|
||||
};
|
||||
Q_DECLARE_FLAGS(Permissions, Permission)
|
||||
|
||||
enum FileHandleFlag {
|
||||
AutoCloseHandle = 0x0001,
|
||||
DontCloseHandle = 0
|
||||
};
|
||||
Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)
|
||||
|
||||
QFile();
|
||||
QFile(const QString &name);
|
||||
#ifndef QT_NO_QOBJECT
|
||||
@ -106,9 +73,6 @@ public:
|
||||
#endif
|
||||
~QFile();
|
||||
|
||||
FileError error() const;
|
||||
void unsetError();
|
||||
|
||||
QString fileName() const;
|
||||
void setFileName(const QString &name);
|
||||
|
||||
@ -141,18 +105,11 @@ public:
|
||||
bool copy(const QString &newName);
|
||||
static bool copy(const QString &fileName, const QString &newName);
|
||||
|
||||
bool isSequential() const;
|
||||
|
||||
bool open(OpenMode flags);
|
||||
bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
||||
bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
|
||||
virtual void close();
|
||||
|
||||
qint64 size() const;
|
||||
qint64 pos() const;
|
||||
bool seek(qint64 offset);
|
||||
bool atEnd() const;
|
||||
bool flush();
|
||||
|
||||
bool resize(qint64 sz);
|
||||
static bool resize(const QString &filename, qint64 sz);
|
||||
@ -162,15 +119,6 @@ public:
|
||||
bool setPermissions(Permissions permissionSpec);
|
||||
static bool setPermissions(const QString &filename, Permissions permissionSpec);
|
||||
|
||||
int handle() const;
|
||||
|
||||
enum MemoryMapFlags {
|
||||
NoOptions = 0
|
||||
};
|
||||
|
||||
uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
|
||||
bool unmap(uchar *address);
|
||||
|
||||
protected:
|
||||
#ifdef QT_NO_QOBJECT
|
||||
QFile(QFilePrivate &dd);
|
||||
@ -178,17 +126,11 @@ protected:
|
||||
QFile(QFilePrivate &dd, QObject *parent = 0);
|
||||
#endif
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
qint64 writeData(const char *data, qint64 len);
|
||||
qint64 readLineData(char *data, qint64 maxlen);
|
||||
|
||||
private:
|
||||
friend class QTemporaryFile;
|
||||
Q_DISABLE_COPY(QFile)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QFile::Permissions)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
@ -53,15 +53,13 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qabstractfileengine_p.h"
|
||||
#include "private/qiodevice_p.h"
|
||||
#include "private/qringbuffer_p.h"
|
||||
#include "private/qfiledevice_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTemporaryFile;
|
||||
|
||||
class QFilePrivate : public QIODevicePrivate
|
||||
class QFilePrivate : public QFileDevicePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QFile)
|
||||
friend class QTemporaryFile;
|
||||
@ -76,20 +74,6 @@ protected:
|
||||
virtual QAbstractFileEngine *engine() const;
|
||||
|
||||
QString fileName;
|
||||
mutable QAbstractFileEngine *fileEngine;
|
||||
|
||||
bool lastWasWrite;
|
||||
QRingBuffer writeBuffer;
|
||||
inline bool ensureFlushed() const;
|
||||
|
||||
bool putCharHelper(char c);
|
||||
|
||||
QFile::FileError error;
|
||||
void setError(QFile::FileError err);
|
||||
void setError(QFile::FileError err, const QString &errorString);
|
||||
void setError(QFile::FileError err, int errNum);
|
||||
|
||||
mutable qint64 cachedSize;
|
||||
|
||||
private:
|
||||
static QFile::EncoderFn encoder;
|
||||
|
736
src/corelib/io/qfiledevice.cpp
Normal file
736
src/corelib/io/qfiledevice.cpp
Normal file
@ -0,0 +1,736 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qplatformdefs.h"
|
||||
#include "qfiledevice.h"
|
||||
#include "qfiledevice_p.h"
|
||||
#include "qfsfileengine_p.h"
|
||||
|
||||
#ifdef QT_NO_QOBJECT
|
||||
#define tr(X) QString::fromLatin1(X)
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const int QFILE_WRITEBUFFER_SIZE = 16384;
|
||||
|
||||
QFileDevicePrivate::QFileDevicePrivate()
|
||||
: fileEngine(0), lastWasWrite(false),
|
||||
writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
|
||||
cachedSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
QFileDevicePrivate::~QFileDevicePrivate()
|
||||
{
|
||||
delete fileEngine;
|
||||
fileEngine = 0;
|
||||
}
|
||||
|
||||
QAbstractFileEngine * QFileDevicePrivate::engine() const
|
||||
{
|
||||
if (!fileEngine)
|
||||
fileEngine = new QFSFileEngine;
|
||||
return fileEngine;
|
||||
}
|
||||
|
||||
void QFileDevicePrivate::setError(QFileDevice::FileError err)
|
||||
{
|
||||
error = err;
|
||||
errorString.clear();
|
||||
}
|
||||
|
||||
void QFileDevicePrivate::setError(QFileDevice::FileError err, const QString &errStr)
|
||||
{
|
||||
error = err;
|
||||
errorString = errStr;
|
||||
}
|
||||
|
||||
void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
|
||||
{
|
||||
error = err;
|
||||
errorString = qt_error_string(errNum);
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::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 QFileDevice::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
|
||||
*/
|
||||
|
||||
//************* QFileDevice
|
||||
|
||||
/*!
|
||||
\class QFileDevice
|
||||
\since 5.0
|
||||
|
||||
\brief The QFileDevice class provides an interface for reading from and writing to open files.
|
||||
|
||||
\ingroup io
|
||||
|
||||
\reentrant
|
||||
|
||||
QFileDevice is the base class for I/O devices that can read and write text and binary files
|
||||
and \l{The Qt Resource System}{resources}. QFile offers the main functionality,
|
||||
QFileDevice serves as a base class for sharing functionality with other file devices such
|
||||
as QTemporaryFile, by providing all the operations that can be done on files that have
|
||||
been opened by QFile or QTemporaryFile.
|
||||
|
||||
\sa QFile, QTemporaryFile
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::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
|
||||
QFileDevice::QFileDevice()
|
||||
: QIODevice(*new QFileDevicePrivate)
|
||||
{
|
||||
}
|
||||
QFileDevice::QFileDevice(QFileDevicePrivate &dd)
|
||||
: QIODevice(dd)
|
||||
{
|
||||
}
|
||||
#else
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFileDevice::QFileDevice()
|
||||
: QIODevice(*new QFileDevicePrivate, 0)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFileDevice::QFileDevice(QObject *parent)
|
||||
: QIODevice(*new QFileDevicePrivate, parent)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFileDevice::QFileDevice(QFileDevicePrivate &dd, QObject *parent)
|
||||
: QIODevice(dd, parent)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Destroys the file device, closing it if necessary.
|
||||
*/
|
||||
QFileDevice::~QFileDevice()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
/*!
|
||||
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 QFileDevice::isSequential() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
return d->fileEngine && d->fileEngine->isSequential();
|
||||
}
|
||||
|
||||
/*!
|
||||
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 QFileDevice::handle() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
if (!isOpen() || !d->fileEngine)
|
||||
return -1;
|
||||
|
||||
return d->fileEngine->handle();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the name of the file.
|
||||
The default implementation in QFileDevice returns QString().
|
||||
*/
|
||||
QString QFileDevice::fileName() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
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 QFileDevice::flush()
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!d->fileEngine) {
|
||||
qWarning("QFileDevice::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) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d->fileEngine->flush()) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::WriteError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Calls QFileDevice::flush() and closes the file. Errors from flush are ignored.
|
||||
|
||||
\sa QIODevice::close()
|
||||
*/
|
||||
void QFileDevice::close()
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
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());
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFileDevice::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 QFileDevice::atEnd() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
|
||||
// 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 QFileDevice::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 QFileDevice::seek(qint64 off)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (!isOpen()) {
|
||||
qWarning("QFileDevice::seek: IODevice is not open");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!d->ensureFlushed())
|
||||
return false;
|
||||
|
||||
if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::PositionError;
|
||||
d->setError(err, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
unsetError();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
qint64 QFileDevice::readLineData(char *data, qint64 maxlen)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
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 QFileDevice::readData(char *data, qint64 len)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
unsetError();
|
||||
if (!d->ensureFlushed())
|
||||
return -1;
|
||||
|
||||
const qint64 read = d->fileEngine->read(data, len);
|
||||
if (read < 0) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::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 QFileDevicePrivate::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 QFileDevice::writeData(const char *data, qint64 len)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
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) {
|
||||
const qint64 ret = d->fileEngine->write(data, len);
|
||||
if (ret < 0) {
|
||||
QFileDevice::FileError err = d->fileEngine->error();
|
||||
if (err == QFileDevice::UnspecifiedError)
|
||||
err = QFileDevice::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()
|
||||
*/
|
||||
QFileDevice::FileError QFileDevice::error() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
return d->error;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the file's error to QFileDevice::NoError.
|
||||
|
||||
\sa error()
|
||||
*/
|
||||
void QFileDevice::unsetError()
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
d->setError(QFileDevice::NoError);
|
||||
}
|
||||
|
||||
/*!
|
||||
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 QFileDevice::size() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
if (!d->ensureFlushed())
|
||||
return 0;
|
||||
d->cachedSize = d->engine()->size();
|
||||
return d->cachedSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
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()
|
||||
*/
|
||||
bool QFileDevice::resize(qint64 sz)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
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;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the complete OR-ed together combination of
|
||||
QFile::Permission for the file.
|
||||
|
||||
\sa setPermissions()
|
||||
*/
|
||||
QFile::Permissions QFileDevice::permissions() const
|
||||
{
|
||||
Q_D(const QFileDevice);
|
||||
QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
|
||||
return QFile::Permissions((int)perms); //ewww
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the permissions for the file to the \a permissions specified.
|
||||
Returns true if successful, or false if the permissions cannot be
|
||||
modified.
|
||||
|
||||
\sa permissions()
|
||||
*/
|
||||
bool QFileDevice::setPermissions(Permissions permissions)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
if (d->engine()->setPermissions(permissions)) {
|
||||
unsetError();
|
||||
return true;
|
||||
}
|
||||
d->setError(QFile::PermissionsError, d->fileEngine->errorString());
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QFileDevice::MemoryMapFlags
|
||||
\since 4.4
|
||||
|
||||
This enum describes special options that may be used by the map()
|
||||
function.
|
||||
|
||||
\value NoOptions No options.
|
||||
*/
|
||||
|
||||
/*!
|
||||
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 *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
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;
|
||||
}
|
||||
|
||||
/*!
|
||||
Unmaps the memory \a address.
|
||||
|
||||
Returns true if the unmap succeeds; false otherwise.
|
||||
|
||||
\sa map()
|
||||
*/
|
||||
bool QFileDevice::unmap(uchar *address)
|
||||
{
|
||||
Q_D(QFileDevice);
|
||||
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;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
147
src/corelib/io/qfiledevice.h
Normal file
147
src/corelib/io/qfiledevice.h
Normal file
@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QFILEDEVICE_H
|
||||
#define QFILEDEVICE_H
|
||||
|
||||
#include <QtCore/qiodevice.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QFileDevicePrivate;
|
||||
|
||||
class Q_CORE_EXPORT QFileDevice : public QIODevice
|
||||
{
|
||||
#ifndef QT_NO_QOBJECT
|
||||
Q_OBJECT
|
||||
#endif
|
||||
Q_DECLARE_PRIVATE(QFileDevice)
|
||||
|
||||
public:
|
||||
enum FileError {
|
||||
NoError = 0,
|
||||
ReadError = 1,
|
||||
WriteError = 2,
|
||||
FatalError = 3,
|
||||
ResourceError = 4,
|
||||
OpenError = 5,
|
||||
AbortError = 6,
|
||||
TimeOutError = 7,
|
||||
UnspecifiedError = 8,
|
||||
RemoveError = 9,
|
||||
RenameError = 10,
|
||||
PositionError = 11,
|
||||
ResizeError = 12,
|
||||
PermissionsError = 13,
|
||||
CopyError = 14
|
||||
};
|
||||
|
||||
enum Permission {
|
||||
ReadOwner = 0x4000, WriteOwner = 0x2000, ExeOwner = 0x1000,
|
||||
ReadUser = 0x0400, WriteUser = 0x0200, ExeUser = 0x0100,
|
||||
ReadGroup = 0x0040, WriteGroup = 0x0020, ExeGroup = 0x0010,
|
||||
ReadOther = 0x0004, WriteOther = 0x0002, ExeOther = 0x0001
|
||||
};
|
||||
Q_DECLARE_FLAGS(Permissions, Permission)
|
||||
|
||||
enum FileHandleFlag {
|
||||
AutoCloseHandle = 0x0001,
|
||||
DontCloseHandle = 0
|
||||
};
|
||||
Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)
|
||||
|
||||
~QFileDevice();
|
||||
|
||||
FileError error() const;
|
||||
void unsetError();
|
||||
|
||||
virtual void close();
|
||||
|
||||
bool isSequential() const;
|
||||
|
||||
int handle() const;
|
||||
virtual QString fileName() const;
|
||||
|
||||
qint64 pos() const;
|
||||
bool seek(qint64 offset);
|
||||
bool atEnd() const;
|
||||
bool flush();
|
||||
|
||||
qint64 size() const;
|
||||
|
||||
virtual bool resize(qint64 sz);
|
||||
virtual Permissions permissions() const;
|
||||
virtual bool setPermissions(Permissions permissionSpec);
|
||||
|
||||
enum MemoryMapFlags {
|
||||
NoOptions = 0
|
||||
};
|
||||
|
||||
uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
|
||||
bool unmap(uchar *address);
|
||||
|
||||
protected:
|
||||
QFileDevice();
|
||||
#ifdef QT_NO_QOBJECT
|
||||
QFileDevice(QFileDevicePrivate &dd);
|
||||
#else
|
||||
explicit QFileDevice(QObject *parent);
|
||||
QFileDevice(QFileDevicePrivate &dd, QObject *parent = 0);
|
||||
#endif
|
||||
|
||||
qint64 readData(char *data, qint64 maxlen);
|
||||
qint64 writeData(const char *data, qint64 len);
|
||||
qint64 readLineData(char *data, qint64 maxlen);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QFileDevice)
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QFileDevice::Permissions)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QFILEDEVICE_H
|
104
src/corelib/io/qfiledevice_p.h
Normal file
104
src/corelib/io/qfiledevice_p.h
Normal file
@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QFILEDEVICE_P_H
|
||||
#define QFILEDEVICE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qiodevice_p.h"
|
||||
#include "private/qringbuffer_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAbstractFileEngine;
|
||||
class QFSFileEngine;
|
||||
|
||||
class QFileDevicePrivate : public QIODevicePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QFileDevice)
|
||||
protected:
|
||||
QFileDevicePrivate();
|
||||
~QFileDevicePrivate();
|
||||
|
||||
virtual QAbstractFileEngine *engine() const;
|
||||
|
||||
QFileDevice::FileHandleFlags handleFlags;
|
||||
|
||||
mutable QAbstractFileEngine *fileEngine;
|
||||
bool lastWasWrite;
|
||||
QRingBuffer writeBuffer;
|
||||
inline bool ensureFlushed() const;
|
||||
|
||||
bool putCharHelper(char c);
|
||||
|
||||
QFileDevice::FileError error;
|
||||
void setError(QFileDevice::FileError err);
|
||||
void setError(QFileDevice::FileError err, const QString &errorString);
|
||||
void setError(QFileDevice::FileError err, int errNum);
|
||||
|
||||
mutable qint64 cachedSize;
|
||||
};
|
||||
|
||||
inline bool QFileDevicePrivate::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<QFileDevicePrivate *>(this)->lastWasWrite = false;
|
||||
if (!const_cast<QFileDevice *>(q_func())->flush())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QFILEDEVICE_P_H
|
@ -67,6 +67,7 @@ SOURCES += \
|
||||
../../corelib/io/qfsfileengine.cpp \
|
||||
../../corelib/io/qfsfileengine_iterator.cpp \
|
||||
../../corelib/io/qiodevice.cpp \
|
||||
../../corelib/io/qfiledevice.cpp \
|
||||
../../corelib/io/qtemporaryfile.cpp \
|
||||
../../corelib/io/qtextstream.cpp \
|
||||
../../corelib/io/qurl.cpp \
|
||||
|
@ -36,6 +36,7 @@ OBJECTS = \
|
||||
qdatastream.o \
|
||||
qdir.o \
|
||||
qdiriterator.o \
|
||||
qfiledevice.o \
|
||||
qfile.o \
|
||||
qfileinfo.o \
|
||||
qabstractfileengine.o \
|
||||
|
@ -34,6 +34,7 @@ OBJECTS = \
|
||||
qdatastream.obj \
|
||||
qdir.obj \
|
||||
qdiriterator.obj \
|
||||
qfiledevice.obj \
|
||||
qfile.obj \
|
||||
qfileinfo.obj \
|
||||
qabstractfileengine.obj \
|
||||
@ -103,6 +104,7 @@ qbuffer.obj: $(CORESRC)\io\qbuffer.cpp $(PCH)
|
||||
qdatastream.obj: $(CORESRC)\io\qdatastream.cpp $(PCH)
|
||||
qdir.obj: $(CORESRC)\io\qdir.cpp $(PCH)
|
||||
qdiriterator.obj: $(CORESRC)\io\qdiriterator.cpp $(PCH)
|
||||
qfiledevice.obj: $(CORESRC)\io\qfiledevice.cpp $(PCH)
|
||||
qfile.obj: $(CORESRC)\io\qfile.cpp $(PCH)
|
||||
qfileinfo.obj: $(CORESRC)\io\qfileinfo.cpp $(PCH)
|
||||
qabstractfileengine.obj: $(CORESRC)\io\qabstractfileengine.cpp $(PCH)
|
||||
|
@ -48,6 +48,7 @@ HEADERS = configureapp.h environment.h tools.h\
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qdatastream.h \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qdir.h \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qdiriterator.h \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfiledevice.h \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfile.h \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfileinfo.h \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfilesystementry_p.h \
|
||||
@ -92,6 +93,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qdatastream.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qdir.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qdiriterator.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfiledevice.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfile.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qfileinfo.cpp \
|
||||
$$QT_SOURCE_TREE/src/corelib/io/qabstractfileengine.cpp \
|
||||
|
Loading…
Reference in New Issue
Block a user