diff options
author | João Abecasis <joao.abecasis@nokia.com> | 2010-09-10 15:25:14 (GMT) |
---|---|---|
committer | João Abecasis <joao.abecasis@nokia.com> | 2010-09-10 17:12:49 (GMT) |
commit | 8f40161a7932e901a9f6fe59b5b3d2666c5482c5 (patch) | |
tree | 459955fe34ff30159d60169d3d88edb20e616e4c | |
parent | cc23ac99d68af5c9bf537e5451b7ee7c7698e954 (diff) | |
download | Qt-8f40161a7932e901a9f6fe59b5b3d2666c5482c5.zip Qt-8f40161a7932e901a9f6fe59b5b3d2666c5482c5.tar.gz Qt-8f40161a7932e901a9f6fe59b5b3d2666c5482c5.tar.bz2 |
QDirIterator: Use new native iterators when possible
Native iterators interface allows propagation of meta data gathered
during directory traversal.
Reviewed-by: Shane Kearns
-rw-r--r-- | src/corelib/io/qdiriterator.cpp | 99 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 7 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo_p.h | 14 |
4 files changed, 100 insertions, 24 deletions
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 3544d87..2e67bfd 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -97,9 +97,17 @@ #include <QtCore/qstack.h> #include <QtCore/qvariant.h> +#include <QtCore/private/qfilesystemiterator_p.h> +#include <QtCore/private/qfilesystementry_p.h> +#include <QtCore/private/qfilesystemmetadata_p.h> +#include <QtCore/private/qfilesystemengine_p.h> +#include <QtCore/qfsfileengine.h> +#include <QtCore/private/qfileinfo_p.h> + QT_BEGIN_NAMESPACE -class QDirIteratorPrivateIteratorStack : public QStack<QAbstractFileEngineIterator *> +template <class Iterator> +class QDirIteratorPrivateIteratorStack : public QStack<Iterator *> { public: ~QDirIteratorPrivateIteratorStack() @@ -116,6 +124,7 @@ public: void advance(); + bool entryMatches(const QString & fileName, const QFileInfo &fileInfo); void pushDirectory(const QFileInfo &fileInfo); void checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; @@ -131,7 +140,9 @@ public: QVector<QRegExp> nameRegExps; #endif - QDirIteratorPrivateIteratorStack fileEngineIterators; + QDirIteratorPrivateIteratorStack<QAbstractFileEngineIterator> fileEngineIterators; + QDirIteratorPrivateIteratorStack<QFileSystemIterator> nativeIterators; + QFileInfo currentFileInfo; QFileInfo nextFileInfo; @@ -144,8 +155,7 @@ public: */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) - : engine(QAbstractFileEngine::create(path)) - , path(path) + : path(path) , nameFilters(nameFilters.contains(QLatin1String("*")) ? QStringList() : nameFilters) , filters(QDir::NoFilter == filters ? QDir::AllEntries : filters) , iteratorFlags(flags) @@ -159,8 +169,19 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList QRegExp::Wildcard)); #endif +#ifdef Q_OS_UNIX + QFileSystemEntry fileEntry(path); + QFileSystemMetaData metaData; + + engine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)); + QFileInfo fileInfo(new QFileInfoPrivate(fileEntry, metaData)); +#else + engine.reset(QAbstractFileEngine::create(path)); + QFileInfo fileInfo(path); +#endif + // Populate fields for hasNext() and next() - pushDirectory(QFileInfo(path)); + pushDirectory(fileInfo); advance(); } @@ -188,34 +209,63 @@ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) } else { // No iterator; no entry list. } + } else { + QFileSystemIterator *it = new QFileSystemIterator(fileInfo.d_ptr->fileEntry, + filters, nameFilters, iteratorFlags); + nativeIterators << it; } } -/*! - \internal -*/ -void QDirIteratorPrivate::advance() +inline bool QDirIteratorPrivate::entryMatches(const QString & fileName, const QFileInfo &fileInfo) { - while (!fileEngineIterators.isEmpty()) { + checkAndPushDirectory(fileInfo); - // Find the next valid iterator that matches the filters. - while (fileEngineIterators.top()->hasNext()) { - QAbstractFileEngineIterator *it = fileEngineIterators.top(); - it->next(); + if (matchesFilters(fileName, fileInfo)) { + currentFileInfo = nextFileInfo; + nextFileInfo = fileInfo; - const QFileInfo info = it->currentFileInfo(); - checkAndPushDirectory(it->currentFileInfo()); + //We found a matching entry. + return true; + } - if (matchesFilters(it->currentFileName(), info)) { - currentFileInfo = nextFileInfo; - nextFileInfo = info; + return false; +} - //We found a matching entry. - return; +/*! + \internal +*/ +void QDirIteratorPrivate::advance() +{ + if (engine) { + while (!fileEngineIterators.isEmpty()) { + // Find the next valid iterator that matches the filters. + QAbstractFileEngineIterator *it; + while (it = fileEngineIterators.top(), it->hasNext()) { + it->next(); + if (entryMatches(it->currentFileName(), it->currentFileInfo())) + return; } + + fileEngineIterators.pop(); + delete it; } + } else { + QFileSystemEntry nextEntry; + QFileSystemMetaData nextMetaData; + + while (!nativeIterators.isEmpty()) { + // Find the next valid iterator that matches the filters. + QFileSystemIterator *it; + while (it = nativeIterators.top(), it->advance(nextEntry, nextMetaData)) { + QFileInfo info(new QFileInfoPrivate(nextEntry, nextMetaData)); + + if (entryMatches(nextEntry.fileName(), info)) + return; + } - delete fileEngineIterators.pop(); + nativeIterators.pop(); + delete it; + } } currentFileInfo = nextFileInfo; @@ -455,7 +505,10 @@ QString QDirIterator::next() */ bool QDirIterator::hasNext() const { - return !d->fileEngineIterators.isEmpty(); + if (d->engine) + return !d->fileEngineIterators.isEmpty(); + else + return !d->nativeIterators.isEmpty(); } /*! diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index d49ee74..83df26d 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -291,6 +291,13 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) */ /*! + \internal +*/ +QFileInfo::QFileInfo(QFileInfoPrivate *p) : d_ptr(p) +{ +} + +/*! Constructs an empty QFileInfo object. Note that an empty QFileInfo object contain no file reference. diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index f0128b1..273a5f7 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -53,11 +53,15 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) class QDir; +class QDirIteratorPrivate; class QDateTime; class QFileInfoPrivate; class Q_CORE_EXPORT QFileInfo { + friend class QDirIteratorPrivate; + explicit QFileInfo(QFileInfoPrivate *d); + public: QFileInfo(); QFileInfo(const QString &file); diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 6db84c4..869a7a6 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -58,9 +58,11 @@ #include "qdatetime.h" #include "qatomic.h" #include "qshareddata.h" -#include "qfilesystementry_p.h" #include "qfilesystemengine_p.h" +#include <QtCore/private/qfilesystementry_p.h> +#include <QtCore/private/qfilesystemmetadata_p.h> + QT_BEGIN_NAMESPACE class QFileInfoPrivate : public QSharedData @@ -102,6 +104,16 @@ public: { } + inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data) + : QSharedData(), + fileEntry(file), + metaData(data), + cachedFlags(0), + isDefaultConstructed(false), + cache_enabled(true), fileFlags(0), fileSize(0) + { + } + inline void clearFlags() const { fileFlags = 0; cachedFlags = 0; |