QDirIterator: manage fs/file iterators with unique_ptr
Use std::stack/std::vector, since QList doesn't work with move only types. Change-Id: If0009c8127d56f85bb6b4b7bd40251cdc6b7950d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
1a3753fc78
commit
3d3eb7e402
@ -72,21 +72,13 @@
|
|||||||
#include <QtCore/private/qduplicatetracker_p.h>
|
#include <QtCore/private/qduplicatetracker_p.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stack>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
class QDirIteratorPrivateIteratorStack : public QStack<Iterator *>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~QDirIteratorPrivateIteratorStack()
|
|
||||||
{
|
|
||||||
qDeleteAll(*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class QDirIteratorPrivate
|
class QDirIteratorPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -109,9 +101,11 @@ public:
|
|||||||
QList<QRegularExpression> nameRegExps;
|
QList<QRegularExpression> nameRegExps;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QDirIteratorPrivateIteratorStack<QAbstractFileEngineIterator> fileEngineIterators;
|
using FEngineIteratorPtr = std::unique_ptr<QAbstractFileEngineIterator>;
|
||||||
|
std::stack<FEngineIteratorPtr, std::vector<FEngineIteratorPtr>> fileEngineIterators;
|
||||||
#ifndef QT_NO_FILESYSTEMITERATOR
|
#ifndef QT_NO_FILESYSTEMITERATOR
|
||||||
QDirIteratorPrivateIteratorStack<QFileSystemIterator> nativeIterators;
|
using FsIteratorPtr = std::unique_ptr<QFileSystemIterator>;
|
||||||
|
std::stack<FsIteratorPtr, std::vector<FsIteratorPtr>> nativeIterators;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QFileInfo currentFileInfo;
|
QFileInfo currentFileInfo;
|
||||||
@ -170,15 +164,14 @@ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo)
|
|||||||
QAbstractFileEngineIterator *it = engine->beginEntryList(filters, nameFilters);
|
QAbstractFileEngineIterator *it = engine->beginEntryList(filters, nameFilters);
|
||||||
if (it) {
|
if (it) {
|
||||||
it->setPath(path);
|
it->setPath(path);
|
||||||
fileEngineIterators << it;
|
fileEngineIterators.emplace(FEngineIteratorPtr(it));
|
||||||
} else {
|
} else {
|
||||||
// No iterator; no entry list.
|
// No iterator; no entry list.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifndef QT_NO_FILESYSTEMITERATOR
|
#ifndef QT_NO_FILESYSTEMITERATOR
|
||||||
QFileSystemIterator *it = new QFileSystemIterator(fileInfo.d_ptr->fileEntry,
|
nativeIterators.emplace(std::make_unique<QFileSystemIterator>(
|
||||||
filters, nameFilters, iteratorFlags);
|
fileInfo.d_ptr->fileEntry, filters, nameFilters, iteratorFlags));
|
||||||
nativeIterators << it;
|
|
||||||
#else
|
#else
|
||||||
qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
|
qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
|
||||||
#endif
|
#endif
|
||||||
@ -202,31 +195,46 @@ inline bool QDirIteratorPrivate::entryMatches(const QString & fileName, const QF
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
|
||||||
|
Advances the internal iterator, either a QAbstractFileEngineIterator (e.g.
|
||||||
|
QResourceFileEngineIterator) or a QFileSystemIterator (which uses low-level
|
||||||
|
system methods, e.g. readdir() on Unix).
|
||||||
|
|
||||||
|
An iterator stack is used for holding the iterators.
|
||||||
|
|
||||||
|
A typical example of doing recursive iteration:
|
||||||
|
- while iterating directory A we find a sub-dir B
|
||||||
|
- an iterator for B is added to the iterator stack
|
||||||
|
- B's iterator is processed (the top() of the stack) first; then loop
|
||||||
|
goes back to processing A's iterator
|
||||||
*/
|
*/
|
||||||
void QDirIteratorPrivate::advance()
|
void QDirIteratorPrivate::advance()
|
||||||
{
|
{
|
||||||
|
// Use get() in both code paths below because the iterator returned by top()
|
||||||
|
// may be invalidated due to reallocation when appending new iterators in
|
||||||
|
// pushDirectory().
|
||||||
|
|
||||||
if (engine) {
|
if (engine) {
|
||||||
while (!fileEngineIterators.isEmpty()) {
|
while (!fileEngineIterators.empty()) {
|
||||||
// Find the next valid iterator that matches the filters.
|
// Find the next valid iterator that matches the filters.
|
||||||
QAbstractFileEngineIterator *it;
|
QAbstractFileEngineIterator *it;
|
||||||
while (it = fileEngineIterators.top(), it->hasNext()) {
|
while (it = fileEngineIterators.top().get(), it->hasNext()) {
|
||||||
it->next();
|
it->next();
|
||||||
if (entryMatches(it->currentFileName(), it->currentFileInfo()))
|
if (entryMatches(it->currentFileName(), it->currentFileInfo()))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileEngineIterators.pop();
|
fileEngineIterators.pop();
|
||||||
delete it;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifndef QT_NO_FILESYSTEMITERATOR
|
#ifndef QT_NO_FILESYSTEMITERATOR
|
||||||
QFileSystemEntry nextEntry;
|
QFileSystemEntry nextEntry;
|
||||||
QFileSystemMetaData nextMetaData;
|
QFileSystemMetaData nextMetaData;
|
||||||
|
|
||||||
while (!nativeIterators.isEmpty()) {
|
while (!nativeIterators.empty()) {
|
||||||
// Find the next valid iterator that matches the filters.
|
// Find the next valid iterator that matches the filters.
|
||||||
QFileSystemIterator *it;
|
QFileSystemIterator *it;
|
||||||
while (it = nativeIterators.top(), it->advance(nextEntry, nextMetaData)) {
|
while (it = nativeIterators.top().get(), it->advance(nextEntry, nextMetaData)) {
|
||||||
QFileInfo info(new QFileInfoPrivate(nextEntry, nextMetaData));
|
QFileInfo info(new QFileInfoPrivate(nextEntry, nextMetaData));
|
||||||
|
|
||||||
if (entryMatches(nextEntry.fileName(), info))
|
if (entryMatches(nextEntry.fileName(), info))
|
||||||
@ -235,7 +243,6 @@ void QDirIteratorPrivate::advance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nativeIterators.pop();
|
nativeIterators.pop();
|
||||||
delete it;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -513,10 +520,10 @@ QFileInfo QDirIterator::nextFileInfo()
|
|||||||
bool QDirIterator::hasNext() const
|
bool QDirIterator::hasNext() const
|
||||||
{
|
{
|
||||||
if (d->engine)
|
if (d->engine)
|
||||||
return !d->fileEngineIterators.isEmpty();
|
return !d->fileEngineIterators.empty();
|
||||||
else
|
else
|
||||||
#ifndef QT_NO_FILESYSTEMITERATOR
|
#ifndef QT_NO_FILESYSTEMITERATOR
|
||||||
return !d->nativeIterators.isEmpty();
|
return !d->nativeIterators.empty();
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user