summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2010-08-30 10:02:39 (GMT)
committerJoão Abecasis <joao.abecasis@nokia.com>2010-08-30 12:00:21 (GMT)
commit1d52b8a0643dca077de432d841df5f49f472352a (patch)
treeabdab952ae27d3a64873b576b467b1d9c029f49c
parent5dfcf2c6778e6852b3d1a2f9c6cc4c9e7c8a5d3b (diff)
downloadQt-1d52b8a0643dca077de432d841df5f49f472352a.zip
Qt-1d52b8a0643dca077de432d841df5f49f472352a.tar.gz
Qt-1d52b8a0643dca077de432d841df5f49f472352a.tar.bz2
Removed native file path handling from QFSFileEngine
Moved it into QFileSystemEntry, instead. For the time being, QFileSystemEntry may look like an unnecessary extra layer of indirection. For the time being, this allows us to do some code cleanup and de-duplication. It is also a stepping stone to becoming completely independent of the current file engine abstraction. Changes to QFileSystemEntry: - native file path on Windows is now a QString, instead of a QByteArray. Accordingly, constructors taking a QByteArray were removed for these platforms. - Encoding/decoding of file names uses QFile::encode/decodeName API, instead of assuming local 8 bit. On Windows, UTF-16 is used for native, as was being done in QFSFileEngine. - new functions isRoot(), isDriveRoot() [Windows/Symbian], and path() - convenience functions clear() and isEmpty() added to facilitate porting. Changes to QFSFileEngine (Windows): - removed QFSFileEnginePrivate::sizeFdFh(): the function was broken and never used, so might as well not get compiled in. - repeated pattern for use of FindFirstFile/FindClose hidden away in a static inline function. - repeated and inconsistent conversions from QString to native file paths reduced through the use of QFileSystemEntry. Done-with: Prasanth Ullattil Done-with: Thomas Zander
-rw-r--r--src/corelib/io/qfilesystementry.cpp107
-rw-r--r--src/corelib/io/qfilesystementry_p.h23
-rw-r--r--src/corelib/io/qfsfileengine.cpp23
-rw-r--r--src/corelib/io/qfsfileengine_p.h7
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp158
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp283
-rw-r--r--src/corelib/io/qtemporaryfile.cpp19
7 files changed, 302 insertions, 318 deletions
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 04ad388..a32e22f 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -42,9 +42,38 @@
#include "qfilesystementry_p.h"
#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+#include <QtCore/private/qfsfileengine_p.h>
+#ifdef Q_OS_WIN
+#include <QtCore/qstringbuilder.h>
+#endif
QT_BEGIN_NAMESPACE
+#ifdef Q_OS_WIN
+static bool isUncRoot(const QString &server)
+{
+ QString localPath = QDir::toNativeSeparators(server);
+ if (!localPath.startsWith(QLatin1String("\\\\")))
+ return false;
+
+ int idx = localPath.indexOf(QLatin1Char('\\'), 2);
+ if (idx == -1 || idx + 1 == localPath.length())
+ return true;
+
+ localPath = localPath.right(localPath.length() - idx - 1).trimmed();
+ return localPath.isEmpty();
+}
+
+static inline QString fixIfRelativeUncPath(const QString &path)
+{
+ QString currentPath = QDir::currentPath();
+ if (currentPath.startsWith(QLatin1String("//")))
+ return currentPath % QChar(QLatin1Char('/')) % path;
+ return path;
+}
+#endif
+
QFileSystemEntry::QFileSystemEntry()
: m_lastSeparator(0),
m_firstDotInFileName(0),
@@ -60,6 +89,7 @@ QFileSystemEntry::QFileSystemEntry(const QString &filePath)
{
}
+#ifndef Q_OS_WIN
QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath)
: m_nativeFilePath(nativeFilePath),
m_lastSeparator(-2),
@@ -76,6 +106,7 @@ QFileSystemEntry::QFileSystemEntry(const QByteArray &nativeFilePath, const QStri
m_lastDotInFileName(0)
{
}
+#endif
QString QFileSystemEntry::filePath() const
{
@@ -83,7 +114,11 @@ QString QFileSystemEntry::filePath() const
return m_filePath;
}
+#ifndef Q_OS_WIN
QByteArray QFileSystemEntry::nativeFilePath() const
+#else
+QString QFileSystemEntry::nativeFilePath() const
+#endif
{
resolveNativeFilePath();
return m_nativeFilePath;
@@ -92,23 +127,59 @@ QByteArray QFileSystemEntry::nativeFilePath() const
void QFileSystemEntry::resolveFilePath() const
{
if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) {
- m_filePath = QDir::fromNativeSeparators(QString::fromLocal8Bit(m_nativeFilePath));
+#ifdef Q_OS_WIN
+ m_filePath = QDir::fromNativeSeparators(m_nativeFilePath);
+#else
+ m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath));
+#endif
}
}
void QFileSystemEntry::resolveNativeFilePath() const
{
if (!m_filePath.isEmpty() && m_nativeFilePath.isEmpty()) {
- m_nativeFilePath = QDir::toNativeSeparators(m_filePath).toLocal8Bit();
+#ifdef Q_OS_WIN
+ QString filePath = m_filePath;
+ if (isRelative())
+ filePath = fixIfRelativeUncPath(m_filePath);
+ m_nativeFilePath = QFSFileEnginePrivate::longFileName(QDir::toNativeSeparators(filePath));
+#else
+ m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath));
+#endif
}
}
QString QFileSystemEntry::fileName() const
{
findLastSeparator();
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ if (m_lastSeparator == -1) {
+ if (m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':'))
+ return m_filePath.mid(2);
+ }
+#endif
return m_filePath.mid(m_lastSeparator + 1);
}
+QString QFileSystemEntry::path() const
+{
+ findLastSeparator();
+ if (m_lastSeparator == -1) {
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ if (m_filePath.length() >= 2 && m_filePath.at(1) == QLatin1Char(':'))
+ return m_filePath.left(2);
+#endif
+ return QString(QLatin1Char('.'));
+ }
+ if (m_lastSeparator == 0)
+ return QString(QLatin1Char('/'));
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ if (m_lastSeparator == 2 && m_filePath.at(1) == QLatin1Char(':'))
+ return m_filePath.left(m_lastSeparator + 1);
+#endif
+ return m_filePath.left(m_lastSeparator);
+}
+
QString QFileSystemEntry::suffix() const
{
findFileNameSeparators();
@@ -141,6 +212,38 @@ bool QFileSystemEntry::isAbsolute() const
}
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+bool QFileSystemEntry::isDriveRoot() const
+{
+ resolveFilePath();
+ return (m_filePath.length() == 3
+ && m_filePath.at(0).isLetter() && m_filePath.at(1) == QLatin1Char(':')
+ && m_filePath.at(2) == QLatin1Char('/'));
+}
+#endif
+
+bool QFileSystemEntry::isRoot() const
+{
+ resolveFilePath();
+ if (m_filePath == QLatin1String("/")
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ || isDriveRoot()
+#if defined(Q_OS_WIN)
+ || isUncRoot(m_filePath)
+#endif
+#endif
+ )
+ return true;
+
+ return false;
+}
+
+bool QFileSystemEntry::isEmpty() const
+{
+ resolveNativeFilePath();
+ return m_nativeFilePath.isEmpty();
+}
+
// private methods
void QFileSystemEntry::findLastSeparator() const
diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h
index ae2071a..3e49f2c 100644
--- a/src/corelib/io/qfilesystementry_p.h
+++ b/src/corelib/io/qfilesystementry_p.h
@@ -63,12 +63,19 @@ class QFileSystemEntry
public:
QFileSystemEntry();
explicit QFileSystemEntry(const QString &filePath);
+#ifndef Q_OS_WIN
explicit QFileSystemEntry(const QByteArray &nativeFilePath);
QFileSystemEntry(const QByteArray &nativeFilePath, const QString &filePath);
+#endif
QString filePath() const;
QString fileName() const;
+ QString path() const;
+#ifndef Q_OS_WIN
QByteArray nativeFilePath() const;
+#else
+ QString nativeFilePath() const;
+#endif
QString suffix() const;
QString completeSuffix() const;
bool isAbsolute() const;
@@ -76,6 +83,17 @@ public:
return !isAbsolute();
}
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ bool isDriveRoot() const;
+#endif
+ bool isRoot() const;
+
+ bool isEmpty() const;
+ void clear()
+ {
+ *this = QFileSystemEntry();
+ }
+
private:
// creates the QString version out of the bytearray version
void resolveFilePath() const;
@@ -87,7 +105,12 @@ private:
void findFileNameSeparators() const;
mutable QString m_filePath; // always has slashes as separator
+
+#ifdef Q_OS_WIN
+ mutable QString m_nativeFilePath; // native encoding and separators
+#else
mutable QByteArray m_nativeFilePath; // native encoding and separators
+#endif
mutable qint16 m_lastSeparator; // index in m_filePath of last separator
mutable qint16 m_firstDotInFileName; // index after m_filePath for first dot (.)
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 511a1a6..75f82a6 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -239,11 +239,11 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path)
/*!
Constructs a QFSFileEngine for the file name \a file.
*/
-QFSFileEngine::QFSFileEngine(const QString &file) : QAbstractFileEngine(*new QFSFileEnginePrivate)
+QFSFileEngine::QFSFileEngine(const QString &file)
+ : QAbstractFileEngine(*new QFSFileEnginePrivate)
{
Q_D(QFSFileEngine);
- d->filePath = QDir::fromNativeSeparators(file);
- d->nativeInitFileName();
+ d->fileEntry = QFileSystemEntry(QDir::fromNativeSeparators(file));
}
/*!
@@ -292,8 +292,7 @@ void QFSFileEngine::setFileName(const QString &file)
{
Q_D(QFSFileEngine);
d->init();
- d->filePath = QDir::fromNativeSeparators(file);
- d->nativeInitFileName();
+ d->fileEntry = QFileSystemEntry(QDir::fromNativeSeparators(file));
}
/*!
@@ -302,7 +301,7 @@ void QFSFileEngine::setFileName(const QString &file)
bool QFSFileEngine::open(QIODevice::OpenMode openMode)
{
Q_D(QFSFileEngine);
- if (d->filePath.isEmpty()) {
+ if (d->fileEntry.isEmpty()) {
qWarning("QFSFileEngine::open: No file name specified");
setError(QFile::OpenError, QLatin1String("No file name specified"));
return false;
@@ -344,8 +343,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh)
d->openMode = openMode;
d->lastFlushFailed = false;
d->closeFileHandle = false;
- d->nativeFilePath.clear();
- d->filePath.clear();
+ d->fileEntry.clear();
d->tried_stat = 0;
d->fd = -1;
@@ -401,8 +399,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd)
d->openMode = openMode;
d->lastFlushFailed = false;
d->closeFileHandle = false;
- d->nativeFilePath.clear();
- d->filePath.clear();
+ d->fileEntry.clear();
d->fh = 0;
d->fd = -1;
d->tried_stat = 0;
@@ -549,6 +546,7 @@ qint64 QFSFileEngine::size() const
/*!
\internal
*/
+#ifndef Q_OS_WIN
qint64 QFSFileEnginePrivate::sizeFdFh() const
{
Q_Q(const QFSFileEngine);
@@ -556,13 +554,13 @@ qint64 QFSFileEnginePrivate::sizeFdFh() const
QT_STATBUF st;
int ret = 0;
const_cast<QFSFileEngine *>(q)->flush();
- if (fh && nativeFilePath.isEmpty()) {
+ if (fh && fileEntry.isEmpty()) {
// Buffered stdlib mode.
// ### This should really be an ftell
ret = QT_FSTAT(QT_FILENO(fh), &st);
} else if (fd == -1) {
// Stateless stat.
- ret = QT_STAT(nativeFilePath.constData(), &st);
+ ret = QT_STAT(fileEntry.nativeFilePath().constData(), &st);
} else {
// Unbuffered stdio mode.
ret = QT_FSTAT(fd, &st);
@@ -571,6 +569,7 @@ qint64 QFSFileEnginePrivate::sizeFdFh() const
return 0;
return st.st_size;
}
+#endif
/*!
\reimp
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index e9e55f3..74cbca3 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -56,6 +56,7 @@
#include "qplatformdefs.h"
#include "QtCore/qfsfileengine.h"
#include "private/qabstractfileengine_p.h"
+#include "private/qfilesystementry_p.h"
#include <qhash.h>
#ifndef QT_NO_FSFILEENGINE
@@ -76,11 +77,9 @@ public:
#endif
static QString canonicalized(const QString &path);
- QString filePath;
- QByteArray nativeFilePath;
+ QFileSystemEntry fileEntry;
QIODevice::OpenMode openMode;
- void nativeInitFileName();
bool nativeOpen(QIODevice::OpenMode openMode);
bool openFh(QIODevice::OpenMode flags, FILE *fh);
bool openFd(QIODevice::OpenMode flags, int fd);
@@ -89,7 +88,9 @@ public:
bool nativeFlush();
bool flushFh();
qint64 nativeSize() const;
+#ifndef Q_OS_WIN
qint64 sizeFdFh() const;
+#endif
qint64 nativePos() const;
qint64 posFdFh() const;
bool nativeSeek(qint64);
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 5fecb5d..3daf7f6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -200,14 +200,6 @@ static inline bool setCloseOnExec(int fd)
/*!
\internal
*/
-void QFSFileEnginePrivate::nativeInitFileName()
-{
- nativeFilePath = QFile::encodeName(filePath);
-}
-
-/*!
- \internal
-*/
bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
{
Q_Q(QFSFileEngine);
@@ -217,7 +209,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
// Try to open the file in unbuffered mode.
do {
- fd = QT_OPEN(nativeFilePath.constData(), flags, 0666);
+ fd = QT_OPEN(fileEntry.nativeFilePath().constData(), flags, 0666);
} while (fd == -1 && errno == EINTR);
// On failure, return and report the error.
@@ -256,11 +248,11 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
fh = 0;
} else {
- QByteArray fopenMode = openModeToFopenMode(openMode, nativeFilePath.constData());
+ QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry.nativeFilePath().constData());
// Try to open the file in buffered mode.
do {
- fh = QT_FOPEN(nativeFilePath.constData(), fopenMode.constData());
+ fh = QT_FOPEN(fileEntry.nativeFilePath().constData(), fopenMode.constData());
} while (!fh && errno == EINTR);
// On failure, return and report the error.
@@ -435,7 +427,7 @@ bool QFSFileEnginePrivate::nativeIsSequential() const
bool QFSFileEngine::remove()
{
Q_D(QFSFileEngine);
- bool ret = unlink(d->nativeFilePath.constData()) == 0;
+ bool ret = unlink(d->fileEntry.nativeFilePath().constData()) == 0;
if (!ret)
setError(QFile::RemoveError, qt_error_string(errno));
return ret;
@@ -447,7 +439,7 @@ bool QFSFileEngine::copy(const QString &newName)
Q_D(QFSFileEngine);
RFs rfs = qt_s60GetRFs();
CFileMan* fm = NULL;
- QString oldNative(QDir::toNativeSeparators(d->filePath));
+ QString oldNative(QDir::toNativeSeparators(d->fileEntry.filePath()));
TPtrC oldPtr(qt_QString2TPtrC(oldNative));
QFileInfo fi(newName);
QString absoluteNewName = fi.absoluteFilePath();
@@ -478,7 +470,7 @@ bool QFSFileEngine::copy(const QString &newName)
bool QFSFileEngine::rename(const QString &newName)
{
Q_D(QFSFileEngine);
- bool ret = ::rename(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0;
+ bool ret = ::rename(d->fileEntry.nativeFilePath().constData(), QFile::encodeName(newName).constData()) == 0;
if (!ret)
setError(QFile::RenameError, qt_error_string(errno));
return ret;
@@ -487,7 +479,7 @@ bool QFSFileEngine::rename(const QString &newName)
bool QFSFileEngine::link(const QString &newName)
{
Q_D(QFSFileEngine);
- bool ret = ::symlink(d->nativeFilePath.constData(), QFile::encodeName(newName).constData()) == 0;
+ bool ret = ::symlink(d->fileEntry.nativeFilePath().constData(), QFile::encodeName(newName).constData()) == 0;
if (!ret)
setError(QFile::RenameError, qt_error_string(errno));
return ret;
@@ -691,7 +683,7 @@ bool QFSFileEnginePrivate::doStat() const
tried_stat = true;
could_stat = false;
- if (fh && nativeFilePath.isEmpty()) {
+ if (fh && fileEntry.isEmpty()) {
// ### actually covers two cases: d->fh and when the file is not open
could_stat = (QT_FSTAT(QT_FILENO(fh), &st) == 0);
} else if (fd == -1) {
@@ -701,12 +693,12 @@ bool QFSFileEnginePrivate::doStat() const
// When the filename is not a link, lstat will return the same info as stat, but this also removes
// any need for a further call to lstat to check if the file is a link.
need_lstat = false;
- could_stat = (QT_LSTAT(nativeFilePath.constData(), &st) == 0);
+ could_stat = (QT_LSTAT(fileEntry.nativeFilePath().constData(), &st) == 0);
is_link = could_stat ? S_ISLNK(st.st_mode) : false;
// if it turns out this was a link, we can call stat too.
if (is_link)
#endif
- could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0);
+ could_stat = (QT_STAT(fileEntry.nativeFilePath().constData(), &st) == 0);
} else {
could_stat = (QT_FSTAT(fd, &st) == 0);
}
@@ -720,7 +712,7 @@ bool QFSFileEnginePrivate::isSymlink() const
need_lstat = false;
QT_STATBUF st; // don't clobber our main one
- is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false;
+ is_link = (QT_LSTAT(fileEntry.nativeFilePath().constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false;
}
return is_link;
}
@@ -789,15 +781,15 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil
// calculate user permissions
if (type & QAbstractFileEngine::ReadUserPerm) {
- if (QT_ACCESS(nativeFilePath.constData(), R_OK) == 0)
+ if (QT_ACCESS(fileEntry.nativeFilePath().constData(), R_OK) == 0)
ret |= QAbstractFileEngine::ReadUserPerm;
}
if (type & QAbstractFileEngine::WriteUserPerm) {
- if (QT_ACCESS(nativeFilePath.constData(), W_OK) == 0)
+ if (QT_ACCESS(fileEntry.nativeFilePath().constData(), W_OK) == 0)
ret |= QAbstractFileEngine::WriteUserPerm;
}
if (type & QAbstractFileEngine::ExeUserPerm) {
- if (QT_ACCESS(nativeFilePath.constData(), X_OK) == 0)
+ if (QT_ACCESS(fileEntry.nativeFilePath().constData(), X_OK) == 0)
ret |= QAbstractFileEngine::ExeUserPerm;
}
@@ -830,7 +822,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
bool foundAlias = false;
{
FSRef fref;
- if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(),
+ if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(),
&fref, NULL) == noErr) {
Boolean isAlias, isFolder;
if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr && isAlias) {
@@ -850,7 +842,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
ret |= DirectoryType;
#if !defined(QWS) && defined(Q_OS_MAC)
if ((ret & DirectoryType) && (type & BundleType)) {
- QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath),
+ QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->fileEntry.filePath()),
kCFURLPOSIXPathStyle, true);
UInt32 type, creator;
if (CFBundleGetPackageInfoInDirectory(url, &type, &creator))
@@ -862,35 +854,29 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
if (type & FlagsMask) {
if (exists)
ret |= ExistsFlag;
-#if defined(Q_OS_SYMBIAN)
- if (d->filePath == QLatin1String("/")
- || (d->filePath.length() == 3 && d->filePath.at(0).isLetter()
- && d->filePath.at(1) == QLatin1Char(':') && d->filePath.at(2) == QLatin1Char('/'))) {
+ if (d->fileEntry.isRoot()) {
ret |= RootFlag;
} else {
+#if defined(Q_OS_SYMBIAN)
// In Symbian, all symlinks have hidden attribute for some reason;
// lets make them visible for better compatibility with other platforms.
// If somebody actually wants a hidden link, then they are out of luck.
- if (!d->isSymlink() && _q_isSymbianHidden(d->filePath, ret & DirectoryType))
+ if (!d->isSymlink() && _q_isSymbianHidden(d->fileEntry.filePath(), ret & DirectoryType))
ret |= HiddenFlag;
- }
#else
- if (d->filePath == QLatin1String("/")) {
- ret |= RootFlag;
- } else {
QString baseName = fileName(BaseName);
if ((baseName.size() > 0 && baseName.at(0) == QLatin1Char('.'))
# if !defined(QWS) && defined(Q_OS_MAC)
- || _q_isMacHidden(d->filePath)
+ || _q_isMacHidden(d->fileEntry.filePath())
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- || d->st.st_flags & UF_HIDDEN
+ || d->st.st_flags & UF_HIDDEN
# endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
# endif
) {
ret |= HiddenFlag;
}
- }
#endif
+ }
}
return ret;
}
@@ -901,50 +887,50 @@ QString QFSFileEngine::fileName(FileName file) const
Q_D(const QFSFileEngine);
const QLatin1Char slashChar('/');
if(file == BaseName) {
- int slash = d->filePath.lastIndexOf(slashChar);
+ int slash = d->fileEntry.filePath().lastIndexOf(slashChar);
if(slash == -1) {
- int colon = d->filePath.lastIndexOf(QLatin1Char(':'));
+ int colon = d->fileEntry.filePath().lastIndexOf(QLatin1Char(':'));
if(colon != -1)
- return d->filePath.mid(colon + 1);
- return d->filePath;
+ return d->fileEntry.filePath().mid(colon + 1);
+ return d->fileEntry.filePath();
}
- return d->filePath.mid(slash + 1);
+ return d->fileEntry.filePath().mid(slash + 1);
} else if(file == PathName) {
- if(!d->filePath.size())
- return d->filePath;
+ if(!d->fileEntry.filePath().size())
+ return d->fileEntry.filePath();
- int slash = d->filePath.lastIndexOf(slashChar);
+ int slash = d->fileEntry.filePath().lastIndexOf(slashChar);
if(slash == -1) {
- if(d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
- return d->filePath.left(2);
+ if(d->fileEntry.filePath().length() >= 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':'))
+ return d->fileEntry.filePath().left(2);
return QLatin1String(".");
} else {
if(!slash)
return QLatin1String("/");
- if(slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
+ if(slash == 2 && d->fileEntry.filePath().length() >= 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':'))
slash++;
- return d->filePath.left(slash);
+ return d->fileEntry.filePath().left(slash);
}
} else if(file == AbsoluteName || file == AbsolutePathName) {
QString ret;
- if (!isRelativePathSymbian(d->filePath)) {
- if (d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':')
- && d->filePath.at(2) != slashChar){
+ if (!isRelativePathSymbian(d->fileEntry.filePath())) {
+ if (d->fileEntry.filePath().size() > 2 && d->fileEntry.filePath().at(1) == QLatin1Char(':')
+ && d->fileEntry.filePath().at(2) != slashChar){
// It's a drive-relative path, so C:a.txt -> C:/currentpath/a.txt,
// or if it's different drive than current, Z:a.txt -> Z:/a.txt
QString currentPath = QDir::currentPath();
- if (0 == currentPath.left(1).compare(d->filePath.left(1), Qt::CaseInsensitive))
- ret = currentPath + slashChar + d->filePath.mid(2);
+ if (0 == currentPath.left(1).compare(d->fileEntry.filePath().left(1), Qt::CaseInsensitive))
+ ret = currentPath + slashChar + d->fileEntry.filePath().mid(2);
else
- ret = d->filePath.left(2) + slashChar + d->filePath.mid(2);
- } else if (d->filePath.startsWith(slashChar)) {
+ ret = d->fileEntry.filePath().left(2) + slashChar + d->fileEntry.filePath().mid(2);
+ } else if (d->fileEntry.filePath().startsWith(slashChar)) {
// It's a absolute path to the current drive, so /a.txt -> C:/a.txt
- ret = QDir::currentPath().left(2) + d->filePath;
+ ret = QDir::currentPath().left(2) + d->fileEntry.filePath();
} else {
- ret = d->filePath;
+ ret = d->fileEntry.filePath();
}
} else {
- ret = QDir::currentPath() + slashChar + d->filePath;
+ ret = QDir::currentPath() + slashChar + d->fileEntry.filePath();
}
// The path should be absolute at this point.
@@ -993,14 +979,14 @@ QString QFSFileEngine::fileName(FileName file) const
} else if(file == LinkName) {
if (d->isSymlink()) {
char s[PATH_MAX+1];
- int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX);
+ int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX);
if (len > 0) {
s[len] = '\0';
QString ret = QFile::decodeName(QByteArray(s));
if (isRelativePathSymbian(ret)) {
- if (!isRelativePathSymbian(d->filePath)) {
- ret.prepend(d->filePath.left(d->filePath.lastIndexOf(slashChar))
+ if (!isRelativePathSymbian(d->fileEntry.filePath())) {
+ ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(slashChar))
+ slashChar);
} else {
ret.prepend(QDir::currentPath() + slashChar);
@@ -1016,7 +1002,7 @@ QString QFSFileEngine::fileName(FileName file) const
} else if(file == BundleName) {
return QString();
}
- return d->filePath;
+ return d->fileEntry.filePath();
}
#else
@@ -1026,7 +1012,7 @@ QString QFSFileEngine::fileName(FileName file) const
Q_D(const QFSFileEngine);
if (file == BundleName) {
#if !defined(QWS) && defined(Q_OS_MAC)
- QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->filePath),
+ QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, QCFString(d->fileEntry.filePath()),
kCFURLPOSIXPathStyle, true);
if (QCFType<CFDictionaryRef> dict = CFBundleCopyInfoDictionaryForURL(url)) {
if (CFTypeRef name = (CFTypeRef)CFDictionaryGetValue(dict, kCFBundleNameKey)) {
@@ -1037,29 +1023,15 @@ QString QFSFileEngine::fileName(FileName file) const
#endif
return QString();
} else if (file == BaseName) {
- int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
- if (slash != -1)
- return d->filePath.mid(slash + 1);
+ return d->fileEntry.fileName();
} else if (file == PathName) {
- int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
- if (slash == -1)
- return QLatin1String(".");
- else if (!slash)
- return QLatin1String("/");
- return d->filePath.left(slash);
+ return d->fileEntry.path();
} else if (file == AbsoluteName || file == AbsolutePathName) {
- QFileSystemEntry entry(d->filePath);
- entry = QFileSystemEngine::absoluteName(entry);
- QString ret = entry.filePath();
+ QFileSystemEntry entry = QFileSystemEngine::absoluteName(d->fileEntry);
if (file == AbsolutePathName) {
- int slash = ret.lastIndexOf(QLatin1Char('/'));
- if (slash == -1)
- return QDir::currentPath();
- else if (!slash)
- return QLatin1String("/");
- return ret.left(slash);
+ return entry.path();
}
- return ret;
+ return entry.filePath();
} else if (file == CanonicalName || file == CanonicalPathName) {
if (!(fileFlags(ExistsFlag) & ExistsFlag))
return QString();
@@ -1085,7 +1057,7 @@ QString QFSFileEngine::fileName(FileName file) const
while (1) {
s = (char *) ::realloc(s, size);
Q_CHECK_PTR(s);
- len = ::readlink(d->nativeFilePath.constData(), s, size);
+ len = ::readlink(d->fileEntry.nativeFilePath().constData(), s, size);
if (len < 0) {
::free(s);
break;
@@ -1097,12 +1069,12 @@ QString QFSFileEngine::fileName(FileName file) const
}
#else
char s[PATH_MAX+1];
- int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX);
+ int len = readlink(d->fileEntry.nativeFilePath().constData(), s, PATH_MAX);
#endif
if (len > 0) {
QString ret;
if (d->doStat() && S_ISDIR(d->st.st_mode) && s[0] != '/') {
- QDir parent(d->filePath);
+ QDir parent(d->fileEntry.filePath());
parent.cdUp();
ret = parent.path();
if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
@@ -1115,8 +1087,8 @@ QString QFSFileEngine::fileName(FileName file) const
#endif
if (!ret.startsWith(QLatin1Char('/'))) {
- if (d->filePath.startsWith(QLatin1Char('/'))) {
- ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/')))
+ if (d->fileEntry.filePath().startsWith(QLatin1Char('/'))) {
+ ret.prepend(d->fileEntry.filePath().left(d->fileEntry.filePath().lastIndexOf(QLatin1Char('/')))
+ QLatin1Char('/'));
} else {
ret.prepend(QDir::currentPath() + QLatin1Char('/'));
@@ -1131,7 +1103,7 @@ QString QFSFileEngine::fileName(FileName file) const
#if !defined(QWS) && defined(Q_OS_MAC)
{
FSRef fref;
- if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->filePath)).data(), &fref, 0) == noErr) {
+ if (FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->fileEntry.filePath())).data(), &fref, 0) == noErr) {
Boolean isAlias, isFolder;
if (FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) {
AliasHandle alias;
@@ -1146,7 +1118,7 @@ QString QFSFileEngine::fileName(FileName file) const
#endif
return QString();
}
- return d->filePath;
+ return d->fileEntry.filePath();
}
#endif // Q_OS_SYMBIAN
@@ -1154,9 +1126,9 @@ bool QFSFileEngine::isRelativePath() const
{
Q_D(const QFSFileEngine);
#if defined(Q_OS_SYMBIAN)
- return isRelativePathSymbian(d->filePath);
+ return isRelativePathSymbian(d->fileEntry.filePath());
#else
- return d->filePath.length() ? d->filePath[0] != QLatin1Char('/') : true;
+ return d->fileEntry.filePath().length() ? d->fileEntry.filePath()[0] != QLatin1Char('/') : true;
#endif
}
@@ -1253,7 +1225,7 @@ bool QFSFileEngine::setPermissions(uint perms)
if (d->fd != -1)
ret = fchmod(d->fd, mode) == 0;
else
- ret = ::chmod(d->nativeFilePath.constData(), mode) == 0;
+ ret = ::chmod(d->fileEntry.nativeFilePath().constData(), mode) == 0;
if (!ret)
setError(QFile::PermissionsError, qt_error_string(errno));
return ret;
@@ -1268,7 +1240,7 @@ bool QFSFileEngine::setSize(qint64 size)
else if (d->fh)
ret = QT_FTRUNCATE(QT_FILENO(d->fh), size) == 0;
else
- ret = QT_TRUNCATE(d->nativeFilePath.constData(), size) == 0;
+ ret = QT_TRUNCATE(d->fileEntry.nativeFilePath().constData(), size) == 0;
if (!ret)
setError(QFile::ResizeError, qt_error_string(errno));
return ret;
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 84120b4..6f81652 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -128,7 +128,7 @@ typedef struct _REPARSE_DATA_BUFFER {
QT_BEGIN_NAMESPACE
-static QString readLink(const QString &link);
+static QString readLink(const QFileSystemEntry &link);
Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
@@ -279,20 +279,6 @@ bool QFSFileEnginePrivate::uncListSharesOnServer(const QString &server, QStringL
return false;
}
-static bool isUncRoot(const QString &server)
-{
- QString localPath = QDir::toNativeSeparators(server);
- if (!localPath.startsWith(QLatin1String("\\\\")))
- return false;
-
- int idx = localPath.indexOf(QLatin1Char('\\'), 2);
- if (idx == -1 || idx + 1 == localPath.length())
- return true;
-
- localPath = localPath.right(localPath.length() - idx - 1).trimmed();
- return localPath.isEmpty();
-}
-
#if !defined(Q_OS_WINCE)
static inline bool isUncPath(const QString &path)
{
@@ -302,25 +288,6 @@ static inline bool isUncPath(const QString &path)
}
#endif
-static inline bool isRelativePath(const QString &path)
-{
- // drive, e.g. "a:", or UNC root, e.q. "//"
- return !(path.startsWith(QLatin1Char('/'))
- || (path.length() >= 2
- && ((path.at(0).isLetter() && path.at(1) == QLatin1Char(':'))
- || (path.at(0) == QLatin1Char('/') && path.at(1) == QLatin1Char('/')))));
-}
-
-static QString fixIfRelativeUncPath(const QString &path)
-{
- if (isRelativePath(path)) {
- QString currentPath = QDir::currentPath() + QLatin1Char('/');
- if (currentPath.startsWith(QLatin1String("//")))
- return QString(path).prepend(currentPath);
- }
- return path;
-}
-
// can be //server or //server/share
static bool uncShareExists(const QString &server)
{
@@ -333,13 +300,6 @@ static bool uncShareExists(const QString &server)
return false;
}
-static inline bool isDriveRoot(const QString &path)
-{
- return (path.length() == 3
- && path.at(0).isLetter() && path.at(1) == QLatin1Char(':')
- && path.at(2) == QLatin1Char('/'));
-}
-
static QString nativeAbsoluteFilePath(const QString &path)
{
QString absPath;
@@ -390,13 +350,22 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
#endif
}
-/*
- \internal
-*/
-void QFSFileEnginePrivate::nativeInitFileName()
+static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
{
- QString path = longFileName(QDir::toNativeSeparators(fixIfRelativeUncPath(filePath)));
- nativeFilePath = QByteArray((const char *)path.utf16(), path.size() * 2 + 1);
+ // path should not end with a trailing slash
+ while (path.endsWith(QLatin1Char('\\')))
+ path.chop(1);
+
+ // can't handle drives
+ if (!path.endsWith(QLatin1Char(':'))) {
+ HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ ::FindClose(hFind);
+ return true;
+ }
+ }
+
+ return false;
}
/*
@@ -421,7 +390,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING;
// Create the file handle.
- fileHandle = CreateFile((const wchar_t*)nativeFilePath.constData(),
+ fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
accessRights,
shareMode,
&securityAtts,
@@ -538,31 +507,18 @@ qint64 QFSFileEnginePrivate::nativeSize() const
// Not-open mode, where the file name is known: We'll check the
// file system directly.
- if (openMode == QIODevice::NotOpen && !nativeFilePath.isEmpty()) {
+ if (openMode == QIODevice::NotOpen && !fileEntry.isEmpty()) {
WIN32_FILE_ATTRIBUTE_DATA attribData;
- bool ok = ::GetFileAttributesEx((const wchar_t*)nativeFilePath.constData(),
+ bool ok = ::GetFileAttributesEx((const wchar_t*)fileEntry.nativeFilePath().utf16(),
GetFileExInfoStandard, &attribData);
if (!ok) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
- QByteArray path = nativeFilePath;
- // path for the FindFirstFile should not end with a trailing slash
- while (!path.isEmpty() && reinterpret_cast<const wchar_t *>(
- path.constData() + path.length())[-1] == '\\')
- path.chop(2);
-
- // FindFirstFile can not handle drives
- if (!path.isEmpty() && reinterpret_cast<const wchar_t *>(
- path.constData() + path.length())[-1] != ':') {
- WIN32_FIND_DATA findData;
- HANDLE hFind = ::FindFirstFile((const wchar_t*)path.constData(),
- &findData);
- if (hFind != INVALID_HANDLE_VALUE) {
- ::FindClose(hFind);
- ok = true;
- attribData.nFileSizeHigh = findData.nFileSizeHigh;
- attribData.nFileSizeLow = findData.nFileSizeLow;
- }
+ WIN32_FIND_DATA findData;
+ if (getFindData(fileEntry.nativeFilePath(), findData)) {
+ ok = true;
+ attribData.nFileSizeHigh = findData.nFileSizeHigh;
+ attribData.nFileSizeLow = findData.nFileSizeLow;
}
}
}
@@ -831,7 +787,7 @@ bool QFSFileEnginePrivate::nativeIsSequential() const
bool QFSFileEngine::remove()
{
Q_D(QFSFileEngine);
- bool ret = ::DeleteFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16()) != 0;
+ bool ret = ::DeleteFile((wchar_t*)d->fileEntry.nativeFilePath().utf16()) != 0;
if (!ret)
setError(QFile::RemoveError, qt_error_string());
return ret;
@@ -840,8 +796,10 @@ bool QFSFileEngine::remove()
bool QFSFileEngine::copy(const QString &copyName)
{
Q_D(QFSFileEngine);
- bool ret = ::CopyFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(),
- (wchar_t*)QFSFileEnginePrivate::longFileName(copyName).utf16(), true) != 0;
+
+ QFileSystemEntry target(copyName);
+ bool ret = ::CopyFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(),
+ (wchar_t*)target.nativeFilePath().utf16(), true) != 0;
if (!ret)
setError(QFile::CopyError, qt_error_string());
return ret;
@@ -850,8 +808,9 @@ bool QFSFileEngine::copy(const QString &copyName)
bool QFSFileEngine::rename(const QString &newName)
{
Q_D(QFSFileEngine);
- bool ret = ::MoveFile((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(),
- (wchar_t*)QFSFileEnginePrivate::longFileName(newName).utf16()) != 0;
+ QFileSystemEntry target(newName);
+ bool ret = ::MoveFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(),
+ (wchar_t*)target.nativeFilePath().utf16()) != 0;
if (!ret)
setError(QFile::RenameError, qt_error_string());
return ret;
@@ -896,20 +855,9 @@ static bool isDirPath(const QString &dirPath, bool *existed)
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
- // path for the FindFirstFile should not end with a trailing slash
- while (path.endsWith(QLatin1Char('\\')))
- path.chop(1);
-
- // FindFirstFile can not handle drives
- if (!path.endsWith(QLatin1Char(':'))) {
- WIN32_FIND_DATA findData;
- HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
- &findData);
- if (hFind != INVALID_HANDLE_VALUE) {
- ::FindClose(hFind);
- fileAttrib = findData.dwFileAttributes;
- }
- }
+ WIN32_FIND_DATA findData;
+ if (getFindData(QFSFileEnginePrivate::longFileName(path), findData))
+ fileAttrib = findData.dwFileAttributes;
}
}
@@ -1164,19 +1112,17 @@ bool QFSFileEnginePrivate::doStat() const
tried_stat = true;
could_stat = false;
- if (filePath.isEmpty())
+ if (fileEntry.isEmpty())
return could_stat;
- QString fname;
- if(filePath.endsWith(QLatin1String(".lnk"))) {
- fname = readLink(filePath);
+ QFileSystemEntry fname;
+ if(fileEntry.filePath().endsWith(QLatin1String(".lnk"))) {
+ fname = QFileSystemEntry(readLink(fileEntry));
if(fname.isEmpty())
return could_stat;
}
else
- fname = filePath;
-
- fname = fixIfRelativeUncPath(fname);
+ fname = fileEntry;
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
@@ -1191,48 +1137,37 @@ bool QFSFileEnginePrivate::doStat() const
}
}
#else
- DWORD tmpAttributes = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16());
+ DWORD tmpAttributes = GetFileAttributes((wchar_t*)fname.nativeFilePath().utf16());
if (tmpAttributes != -1) {
fileAttrib = tmpAttributes;
could_stat = true;
}
#endif
} else {
- fileAttrib = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16());
+ fileAttrib = GetFileAttributes((wchar_t*)fname.nativeFilePath().utf16());
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
- QString path = QDir::toNativeSeparators(fname);
- // path for the FindFirstFile should not end with a trailing slash
- while (path.endsWith(QLatin1Char('\\')))
- path.chop(1);
-
- // FindFirstFile can not handle drives
- if (!path.endsWith(QLatin1Char(':'))) {
- WIN32_FIND_DATA findData;
- HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
- &findData);
- if (hFind != INVALID_HANDLE_VALUE) {
- ::FindClose(hFind);
- fileAttrib = findData.dwFileAttributes;
- }
+ WIN32_FIND_DATA findData;
+ if (getFindData(fname.nativeFilePath(), findData)) {
+ fileAttrib = findData.dwFileAttributes;
}
}
}
could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES;
if (!could_stat) {
#if !defined(Q_OS_WINCE)
- if (isDriveRoot(fname)) {
+ if (fname.isDriveRoot()) {
// a valid drive ??
DWORD drivesBitmask = ::GetLogicalDrives();
- int drivebit = 1 << (fname.at(0).toUpper().unicode() - QLatin1Char('A').unicode());
+ int drivebit = 1 << (fname.filePath().at(0).toUpper().unicode() - QLatin1Char('A').unicode());
if (drivesBitmask & drivebit) {
fileAttrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM;
could_stat = true;
}
} else {
#endif
- QString path = QDir::toNativeSeparators(fname);
+ const QString &path = fname.nativeFilePath();
bool is_dir = false;
if (path.startsWith(QLatin1String("\\\\"))) {
// UNC - stat doesn't work for all cases (Windows bug)
@@ -1274,11 +1209,11 @@ bool QFSFileEnginePrivate::doStat() const
}
-static QString readSymLink(const QString &link)
+static QString readSymLink(const QFileSystemEntry &link)
{
QString result;
#if !defined(Q_OS_WINCE)
- HANDLE handle = CreateFile((wchar_t*)QFSFileEnginePrivate::longFileName(link).utf16(),
+ HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(),
FILE_READ_EA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
@@ -1328,7 +1263,7 @@ static QString readSymLink(const QString &link)
return result;
}
-static QString readLink(const QString &link)
+static QString readLink(const QFileSystemEntry &link)
{
#if !defined(Q_OS_WINCE)
#if !defined(QT_NO_LIBRARY) && !defined(Q_CC_MWERKS)
@@ -1352,7 +1287,7 @@ static QString readLink(const QString &link)
IPersistFile *ppf;
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
if (SUCCEEDED(hres)) {
- hres = ppf->Load((LPOLESTR)link.utf16(), STGM_READ);
+ hres = ppf->Load((LPOLESTR)link.nativeFilePath().utf16(), STGM_READ);
//The original path of the link is retrieved. If the file/folder
//was moved, the return value still have the old path.
if (SUCCEEDED(hres)) {
@@ -1374,7 +1309,7 @@ static QString readLink(const QString &link)
#else
wchar_t target[MAX_PATH];
QString result;
- if (SHGetShortcutTarget((wchar_t*)QFileInfo(link).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) {
+ if (SHGetShortcutTarget((wchar_t*)QFileInfo(link.filePath()).absoluteFilePath().replace(QLatin1Char('/'),QLatin1Char('\\')).utf16(), target, MAX_PATH)) {
result = QString::fromWCharArray(target);
if (result.startsWith(QLatin1Char('"')))
result.remove(0,1);
@@ -1458,7 +1393,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil
if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) {
enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 };
- QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath;
+ QString fname = fileEntry.filePath().endsWith(QLatin1String(".lnk")) ? readLink(fileEntry) : fileEntry.filePath();
PSID pOwner = 0;
PSID pGroup = 0;
PACL pDacl;
@@ -1528,7 +1463,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFil
| QAbstractFileEngine::WriteOtherPerm;
}
- QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath;
+ QString fname = fileEntry.filePath().endsWith(QLatin1String(".lnk")) ? readLink(fileEntry) : fileEntry.filePath();
QString ext = fname.right(4).toLower();
if ((fileAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") ||
@@ -1561,16 +1496,8 @@ bool QFSFileEnginePrivate::isSymlink() const
is_link = false;
if (fileAttrib & FILE_ATTRIBUTE_REPARSE_POINT) {
- QString path = QDir::toNativeSeparators(filePath);
- // path for the FindFirstFile should not end with a trailing slash
- while (path.endsWith(QLatin1Char('\\')))
- path.chop(1);
-
WIN32_FIND_DATA findData;
- HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
- &findData);
- if (hFind != INVALID_HANDLE_VALUE) {
- ::FindClose(hFind);
+ if (getFindData(fileEntry.nativeFilePath(), findData)) {
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
&& (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
is_link = true;
@@ -1606,9 +1533,9 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
}
}
if (type & TypesMask) {
- if (d->filePath.endsWith(QLatin1String(".lnk"))) {
+ if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk"))) {
ret |= LinkType;
- QString l = readLink(d->filePath);
+ QString l = readLink(d->fileEntry);
if (!l.isEmpty()) {
bool existed = false;
if (isDirPath(l, &existed) && existed)
@@ -1630,7 +1557,7 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
ret |= LocalDiskFlag;
if (d->doStat()) {
ret |= ExistsFlag;
- if (d->filePath == QLatin1String("/") || isDriveRoot(d->filePath) || isUncRoot(d->filePath))
+ if (d->fileEntry.isRoot())
ret |= RootFlag;
else if (d->fileAttrib & FILE_ATTRIBUTE_HIDDEN)
ret |= HiddenFlag;
@@ -1643,50 +1570,26 @@ QString QFSFileEngine::fileName(FileName file) const
{
Q_D(const QFSFileEngine);
if (file == BaseName) {
- int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
- if (slash == -1) {
- int colon = d->filePath.lastIndexOf(QLatin1Char(':'));
- if (colon != -1)
- return d->filePath.mid(colon + 1);
- return d->filePath;
- }
- return d->filePath.mid(slash + 1);
+ return d->fileEntry.fileName();
} else if (file == PathName) {
- if (!d->filePath.size())
- return d->filePath;
-
- int slash = d->filePath.lastIndexOf(QLatin1Char('/'));
- if (slash == -1) {
- if (d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
- return d->filePath.left(2);
- return QString(QLatin1Char('.'));
- } else {
- if (!slash)
- return QString(QLatin1Char('/'));
- if (slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':'))
- slash++;
- return d->filePath.left(slash);
- }
+ return d->fileEntry.path();
} else if (file == AbsoluteName || file == AbsolutePathName) {
QString ret;
if (!isRelativePath()) {
#if !defined(Q_OS_WINCE)
- if (d->filePath.startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt
- d->filePath.size() == 2 || // It's a drive letter that needs to get a working dir appended
- (d->filePath.size() > 2 && d->filePath.at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
- d->filePath.contains(QLatin1String("/../")) || d->filePath.contains(QLatin1String("/./")) ||
- d->filePath.endsWith(QLatin1String("/..")) || d->filePath.endsWith(QLatin1String("/.")))
+ if (d->fileEntry.filePath().startsWith(QLatin1Char('/')) || // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt
+ d->fileEntry.filePath().size() == 2 || // It's a drive letter that needs to get a working dir appended
+ (d->fileEntry.filePath().size() > 2 && d->fileEntry.filePath().at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
+ d->fileEntry.filePath().contains(QLatin1String("/../")) || d->fileEntry.filePath().contains(QLatin1String("/./")) ||
+ d->fileEntry.filePath().endsWith(QLatin1String("/..")) || d->fileEntry.filePath().endsWith(QLatin1String("/.")))
{
- ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->filePath));
- } else {
- ret = d->filePath;
+ ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->fileEntry.filePath()));
}
-#else
- ret = d->filePath;
#endif
+ ret = d->fileEntry.filePath();
} else {
- ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->filePath);
+ ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->fileEntry.filePath());
}
// The path should be absolute at this point.
@@ -1728,25 +1631,22 @@ QString QFSFileEngine::fileName(FileName file) const
return ret;
} else if (file == LinkName) {
QString ret;
- if (d->filePath.endsWith(QLatin1String(".lnk")))
- ret = readLink(d->filePath);
+ if (d->fileEntry.filePath().endsWith(QLatin1String(".lnk")))
+ ret = readLink(d->fileEntry);
else if (d->doStat() && d->isSymlink())
- ret = readSymLink(d->filePath);
+ ret = readSymLink(d->fileEntry);
return QDir::fromNativeSeparators(ret);
} else if (file == BundleName) {
return QString();
}
- return d->filePath;
+ return d->fileEntry.filePath();
}
bool QFSFileEngine::isRelativePath() const
{
Q_D(const QFSFileEngine);
// drive, e.g. "a:", or UNC root, e.q. "//"
- return !(d->filePath.startsWith(QLatin1Char('/'))
- || (d->filePath.length() >= 2
- && ((d->filePath.at(0).isLetter() && d->filePath.at(1) == QLatin1Char(':'))
- || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == QLatin1Char('/')))));
+ return d->fileEntry.isRelative();
}
uint QFSFileEngine::ownerId(FileOwner /*own*/) const
@@ -1765,7 +1665,7 @@ QString QFSFileEngine::owner(FileOwner own) const
if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) {
PSID pOwner = 0;
PSECURITY_DESCRIPTOR pSD;
- if (ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT,
+ if (ptrGetNamedSecurityInfoW((wchar_t*)d->fileEntry.nativeFilePath().utf16(), SE_FILE_OBJECT,
own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION,
own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0,
0, 0, &pSD) == ERROR_SUCCESS) {
@@ -1817,7 +1717,7 @@ bool QFSFileEngine::setPermissions(uint perms)
if (mode == 0) // not supported
return false;
- ret = ::_wchmod((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), mode) == 0;
+ ret = ::_wchmod((wchar_t*)d->fileEntry.nativeFilePath().utf16(), mode) == 0;
if (!ret)
setError(QFile::PermissionsError, qt_error_string(errno));
return ret;
@@ -1847,9 +1747,9 @@ bool QFSFileEngine::setSize(qint64 size)
return false;
}
- if (!d->nativeFilePath.isEmpty()) {
+ if (!d->fileEntry.isEmpty()) {
// resize file on disk
- QFile file(d->filePath);
+ QFile file(d->fileEntry.filePath());
if (file.open(QFile::ReadWrite)) {
bool ret = file.resize(size);
if (!ret)
@@ -1915,27 +1815,16 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
#endif
} else {
WIN32_FILE_ATTRIBUTE_DATA attribData;
- bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), GetFileExInfoStandard, &attribData);
+ bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->fileEntry.filePath()).utf16(), GetFileExInfoStandard, &attribData);
if (!ok) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
- QString path = QDir::toNativeSeparators(d->filePath);
- // path for the FindFirstFile should not end with a trailing slash
- while (path.endsWith(QLatin1Char('\\')))
- path.chop(1);
-
- // FindFirstFile can not handle drives
- if (!path.endsWith(QLatin1Char(':'))) {
- WIN32_FIND_DATA findData;
- HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
- &findData);
- if (hFind != INVALID_HANDLE_VALUE) {
- ::FindClose(hFind);
- ok = true;
- attribData.ftCreationTime = findData.ftCreationTime;
- attribData.ftLastWriteTime = findData.ftLastWriteTime;
- attribData.ftLastAccessTime = findData.ftLastAccessTime;
- }
+ WIN32_FIND_DATA findData;
+ if (getFindData(d->fileEntry.nativeFilePath(), findData)) {
+ ok = true;
+ attribData.ftCreationTime = findData.ftCreationTime;
+ attribData.ftLastWriteTime = findData.ftLastWriteTime;
+ attribData.ftLastAccessTime = findData.ftLastAccessTime;
}
}
}
@@ -1977,7 +1866,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
#ifdef Q_USE_DEPRECATED_MAP_API
nativeClose();
// handle automatically closed by kernel with mapHandle (below).
- handle = ::CreateFileForMapping((const wchar_t*)nativeFilePath.constData(),
+ handle = ::CreateFileForMapping((const wchar_t*)fileEntry.nativeFilePath().utf16(),
GENERIC_READ | (openMode & QIODevice::WriteOnly ? GENERIC_WRITE : 0),
0,
NULL,
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index c34c4a4..a0d3176 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -295,7 +295,7 @@ public:
: QFSFileEngine(), filePathIsTemplate(fileIsTemplate)
{
Q_D(QFSFileEngine);
- d->filePath = file;
+ d->fileEntry = QFileSystemEntry(file);
if (!filePathIsTemplate)
QFSFileEngine::setFileName(file);
@@ -346,7 +346,7 @@ void QTemporaryFileEngine::setFileTemplate(const QString &fileTemplate)
{
Q_D(QFSFileEngine);
if (filePathIsTemplate)
- d->filePath = fileTemplate;
+ d->fileEntry = QFileSystemEntry(fileTemplate);
}
bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
@@ -359,7 +359,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
if (!filePathIsTemplate)
return QFSFileEngine::open(openMode);
- QString qfilename = d->filePath;
+ QString qfilename = d->fileEntry.filePath();
if(!qfilename.contains(QLatin1String("XXXXXX")))
qfilename += QLatin1String(".XXXXXX");
@@ -377,9 +377,8 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
d->closeFileHandle = true;
// Restore the file names (open() resets them).
- d->filePath = QString::fromLocal8Bit(filename); //changed now!
+ d->fileEntry = QFileSystemEntry(QByteArray(filename)); //changed now!
filePathIsTemplate = false;
- d->nativeInitFileName();
delete [] filename;
return true;
}
@@ -395,9 +394,8 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
return false;
}
- QString template_ = d->filePath;
- d->filePath = QString::fromLocal8Bit(filename);
- d->nativeInitFileName();
+ QString template_ = d->fileEntry.filePath();
+ d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(filename));
delete [] filename;
if (QFSFileEngine::open(openMode)) {
@@ -405,8 +403,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
return true;
}
- d->filePath = template_;
- d->nativeFilePath.clear();
+ d->fileEntry = QFileSystemEntry(template_);
return false;
#endif
}
@@ -418,7 +415,7 @@ bool QTemporaryFileEngine::remove()
// we must explicitly call QFSFileEngine::close() before we remove it.
QFSFileEngine::close();
if (QFSFileEngine::remove()) {
- d->filePath.clear();
+ d->fileEntry.clear();
return true;
}
return false;