QAbstractFileEngineIterator: add bool advance() virtual method

And remove hasNext/next() methods. This remodels QAFEI to be like
QFileSystemIterator. This better fits the logic in the newly added
QDirListing class (which uses STL-style iterators).

QFSFileEngineIterator:
Initialize the internal nativeIterator in the constructor; also replace
the advance() private method with an override for the advance() method
inherited from the base class.

QResourceFileEngineIterator:
Override currentFileInfo(), with a QResouces the QFileInfo is created
on demand if/when this method is called.

This is the backend/private API, and QDirListing is the public API that
can be used in a ranged-for to iterate over directory entries.

Change-Id: I93eb7bdd64823ac01eea2dcaaa6bcc8ad868b2c4
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Ahmad Samir 2023-12-17 21:10:18 +02:00
parent cd5dd8b95b
commit ceeaf1b657
13 changed files with 88 additions and 128 deletions

View File

@ -59,17 +59,15 @@ public:
entries << "entry1" << "entry2" << "entry3";
}
bool hasNext() const override
bool advance() override
{
return index < entries.size() - 1;
}
QString next() override
{
if (!hasNext())
return QString();
++index;
return currentFilePath();
if (entries.isEmpty())
return false;
if (index < entries.size() - 1) {
++index;
return true;
}
return false;
}
QString currentFileName() override

View File

@ -862,10 +862,11 @@ bool QAbstractFileEngine::cloneTo(QAbstractFileEngine *target)
You can call dirName() to get the directory name, nameFilters() to get a
stringlist of name filters, and filters() to get the entry filters.
The pure virtual function hasNext() returns \c true if the current directory
has at least one more entry (i.e., the directory name is valid and
accessible, and we have not reached the end of the entry list), and false
otherwise. Reimplement next() to seek to the next entry.
The pure virtual function advance(), as its name implies, advances the
iterator to the next entry in the current directory; if the operation
was successful this method returns \c true, otherwise it returns \c
false. You have to reimplement this function in your sub-class to work
with your file engine implementation.
The pure virtual function currentFileName() returns the name of the
current entry without advancing the iterator. The currentFilePath()
@ -995,10 +996,11 @@ QFileInfo QAbstractFileEngineIterator::currentFileInfo() const
}
/*!
\fn virtual QString QAbstractFileEngineIterator::next() = 0
\fn virtual bool QAbstractFileEngineIterator::advance() = 0
This pure virtual function advances the iterator to the next directory
entry, and returns the file path to the current entry.
entry; if the operation was successful this method returns \c true,
otherwise it returs \c false.
This function can optionally make use of nameFilters() and filters() to
optimize its performance.
@ -1006,14 +1008,6 @@ QFileInfo QAbstractFileEngineIterator::currentFileInfo() const
Reimplement this function in a subclass to advance the iterator.
*/
/*!
\fn virtual bool QAbstractFileEngineIterator::hasNext() const = 0
This pure virtual function returns \c true if there is at least one more
entry in the current directory (i.e., the iterator path is valid and
accessible, and the iterator has not reached the end of the entry list).
*/
/*!
Returns a QAbstractFileEngine::IteratorUniquePtr, that can be used
to iterate over the entries in \a path, using \a filters for entry

View File

@ -202,8 +202,7 @@ public:
const QStringList &nameFilters);
virtual ~QAbstractFileEngineIterator();
virtual QString next() = 0;
virtual bool hasNext() const = 0;
virtual bool advance() = 0;
QString path() const;
QStringList nameFilters() const;

View File

@ -215,8 +215,7 @@ void QDirListingPrivate::advance()
while (!fileEngineIterators.empty()) {
// Find the next valid iterator that matches the filters.
QAbstractFileEngineIterator *it;
while (it = fileEngineIterators.top().get(), it->hasNext()) {
it->next();
while (it = fileEngineIterators.top().get(), it->advance()) {
QDirEntryInfo entryInfo;
entryInfo.fileInfoOpt = it->currentFileInfo();
if (entryMatches(entryInfo)) {

View File

@ -12,7 +12,7 @@ QT_BEGIN_NAMESPACE
QFSFileEngineIterator::QFSFileEngineIterator(const QString &path, QDir::Filters filters,
const QStringList &filterNames)
: QAbstractFileEngineIterator(path, filters, filterNames),
done(false)
nativeIterator(new QFileSystemIterator(QFileSystemEntry(path), filters))
{
}
@ -20,47 +20,30 @@ QFSFileEngineIterator::~QFSFileEngineIterator()
{
}
bool QFSFileEngineIterator::hasNext() const
bool QFSFileEngineIterator::advance()
{
if (!done && !nativeIterator) {
nativeIterator.reset(new QFileSystemIterator(QFileSystemEntry(path()), filters()));
advance();
}
return !done;
}
QString QFSFileEngineIterator::next()
{
if (!hasNext())
return QString();
advance();
return currentFilePath();
}
void QFSFileEngineIterator::advance() const
{
currentInfo = nextInfo;
if (!nativeIterator)
return false;
QFileSystemEntry entry;
QFileSystemMetaData data;
if (nativeIterator->advance(entry, data)) {
nextInfo = QFileInfo(new QFileInfoPrivate(entry, data));
m_fileInfo = QFileInfo(new QFileInfoPrivate(entry, data));
return true;
} else {
done = true;
nativeIterator.reset();
return false;
}
}
QString QFSFileEngineIterator::currentFileName() const
{
return currentInfo.fileName();
return m_fileInfo.fileName();
}
QFileInfo QFSFileEngineIterator::currentFileInfo() const
{
return currentInfo;
return m_fileInfo;
}
QT_END_NAMESPACE

View File

@ -29,18 +29,13 @@ public:
QFSFileEngineIterator(const QString &path, QDir::Filters filters, const QStringList &filterNames);
~QFSFileEngineIterator();
QString next() override;
bool hasNext() const override;
bool advance() override;
QString currentFileName() const override;
QFileInfo currentFileInfo() const override;
private:
void advance() const;
mutable QScopedPointer<QFileSystemIterator> nativeIterator;
mutable QFileInfo currentInfo;
mutable QFileInfo nextInfo;
mutable bool done;
};
QT_END_NAMESPACE

View File

@ -19,15 +19,7 @@ QResourceFileEngineIterator::~QResourceFileEngineIterator()
{
}
QString QResourceFileEngineIterator::next()
{
if (!hasNext())
return QString();
++index;
return currentFilePath();
}
bool QResourceFileEngineIterator::hasNext() const
bool QResourceFileEngineIterator::advance()
{
if (index == -1) {
// Lazy initialization of the iterator
@ -35,19 +27,34 @@ bool QResourceFileEngineIterator::hasNext() const
if (!resource.isValid())
return false;
// Initialize and move to the next entry.
// Initialize and move to the first entry.
entries = resource.children();
if (entries.isEmpty())
return false;
index = 0;
return true;
}
return index < entries.size();
if (index < entries.size() - 1) {
++index;
return true;
}
return false;
}
QString QResourceFileEngineIterator::currentFileName() const
{
if (index <= 0 || index > entries.size())
if (index < 0 || index > entries.size())
return QString();
return entries.at(index - 1);
return entries.at(index);
}
QFileInfo QResourceFileEngineIterator::currentFileInfo() const
{
m_fileInfo = QFileInfo(currentFilePath());
return m_fileInfo;
}
QT_END_NAMESPACE

View File

@ -28,10 +28,10 @@ public:
const QStringList &filterNames);
~QResourceFileEngineIterator();
QString next() override;
bool hasNext() const override;
bool advance() override;
QString currentFileName() const override;
QFileInfo currentFileInfo() const override;
private:
mutable QStringList entries;

View File

@ -276,15 +276,7 @@ AndroidContentFileEngineIterator::~AndroidContentFileEngineIterator()
{
}
QString AndroidContentFileEngineIterator::next()
{
if (!hasNext())
return QString();
++m_index;
return currentFilePath();
}
bool AndroidContentFileEngineIterator::hasNext() const
bool AndroidContentFileEngineIterator::advance()
{
if (m_index == -1 && m_files.isEmpty()) {
const auto currentPath = path();
@ -295,9 +287,18 @@ bool AndroidContentFileEngineIterator::hasNext() const
if (iterDoc->isDirectory())
for (const auto &doc : iterDoc->listFiles())
m_files.append(doc);
if (m_files.isEmpty())
return false;
m_index = 0;
return true;
}
return m_index < (m_files.size() - 1);
if (m_index < m_files.size() - 1) {
++m_index;
return true;
}
return false;
}
QString AndroidContentFileEngineIterator::currentFileName() const

View File

@ -55,8 +55,9 @@ public:
AndroidContentFileEngineIterator(const QString &path, QDir::Filters filters,
const QStringList &filterNames);
~AndroidContentFileEngineIterator();
QString next() override;
bool hasNext() const override;
bool advance() override;
QString currentFileName() const override;
QString currentFilePath() const override;
private:

View File

@ -142,17 +142,13 @@ public:
return m_path + at(m_index).name;
}
bool hasNext() const
bool advance()
{
return !empty() && m_index + 1 < size();
}
std::optional<std::pair<QString, AssetItem>> next()
{
if (!hasNext())
return {};
++m_index;
return std::pair<QString, AssetItem>(currentFileName(), at(m_index));
if (!empty() && m_index + 1 < size()) {
++m_index;
return true;
}
return false;
}
private:
@ -195,21 +191,9 @@ public:
return m_currentIterator->currentFilePath();
}
bool hasNext() const override
bool advance() override
{
if (!m_currentIterator)
return false;
return m_currentIterator->hasNext();
}
QString next() override
{
if (!m_currentIterator)
return {};
auto res = m_currentIterator->next();
if (!res)
return {};
return res->first;
return m_currentIterator ? m_currentIterator->advance() : false;
}
private:

View File

@ -270,8 +270,11 @@ public:
g_iteratorCurrentUrl.setLocalData(QString());
}
QString next() override
bool advance() override
{
if (!m_enumerator->hasNext())
return false;
// Cache the URL that we are about to return, since QDir will immediately create a
// new file engine on the file and ask if it exists. Unless we do this, we end up
// creating a new ALAsset just to verify its existence, which will be especially
@ -279,12 +282,7 @@ public:
ALAsset *asset = m_enumerator->next();
QString url = QUrl::fromNSURL([asset valueForProperty:ALAssetPropertyAssetURL]).toString();
g_iteratorCurrentUrl.setLocalData(url);
return url;
}
bool hasNext() const override
{
return m_enumerator->hasNext();
return true;
}
QString currentFileName() const override

View File

@ -439,18 +439,19 @@ public:
}
QString currentFileName() const override
{
return names.at(index);
if (!names.isEmpty() && index < names.size())
return names.at(index);
return {};
}
bool hasNext() const override
bool advance() override
{
return index < names.size() - 1;
}
QString next() override
{
if (!hasNext())
return QString();
++index;
return currentFilePath();
if (names.isEmpty())
return false;
if (index < names.size() - 1) {
++index;
return true;
}
return false;
}
QStringList names;
int index;