Commit d2350c23 authored by Eike Ziller's avatar Eike Ziller

FileSearch: Fixes for making FileIterator actual ForwardIterator

Give iterators 'a' and 'b', if a == b, either both are non-dereference
or *a and *b are references bound to the same object.
Also add missing default constructor, copy constructor and copy
assignment operator.

Change-Id: I53fd30a620155b9faa9850b2ffcf546376b14cff
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent dcf09b00
......@@ -494,14 +494,8 @@ void FileIterator::advance(FileIterator::const_iterator *it) const
return;
++it->m_index;
const_cast<FileIterator *>(this)->update(it->m_index);
if (it->m_index < currentFileCount()) {
it->m_item.filePath = fileAt(it->m_index);
it->m_item.encoding = codecAt(it->m_index);
} else {
if (it->m_index >= currentFileCount())
it->m_index = -1; // == end
it->m_item.filePath.clear();
it->m_item.encoding = 0;
}
}
FileIterator::const_iterator FileIterator::begin() const
......@@ -509,25 +503,30 @@ FileIterator::const_iterator FileIterator::begin() const
const_cast<FileIterator *>(this)->update(0);
if (currentFileCount() == 0)
return end();
return FileIterator::const_iterator(this,
FileIterator::Item(fileAt(0), codecAt(0)),
0/*index*/);
return FileIterator::const_iterator(this, 0/*index*/);
}
FileIterator::const_iterator FileIterator::end() const
{
return FileIterator::const_iterator(this, FileIterator::Item(QString(), 0),
-1/*end*/);
return FileIterator::const_iterator(this, -1/*end*/);
}
// #pragma mark -- FileListIterator
QTextCodec *encodingAt(const QList<QTextCodec *> encodings, int index)
{
if (index >= 0 && index < encodings.size())
return encodings.at(index);
return QTextCodec::codecForLocale();
}
FileListIterator::FileListIterator(const QStringList &fileList,
const QList<QTextCodec *> encodings)
: m_files(fileList),
m_encodings(encodings),
m_maxIndex(-1)
: m_maxIndex(-1)
{
m_items.reserve(fileList.size());
for (int i = 0; i < fileList.size(); ++i)
m_items.append(Item(fileList.at(i), encodingAt(encodings, i)));
}
void FileListIterator::update(int requestedIndex)
......@@ -538,22 +537,17 @@ void FileListIterator::update(int requestedIndex)
int FileListIterator::currentFileCount() const
{
return m_files.size();
return m_items.size();
}
QString FileListIterator::fileAt(int index) const
const FileIterator::Item &FileListIterator::itemAt(int index) const
{
return m_files.at(index);
}
QTextCodec *FileListIterator::codecAt(int index) const
{
return m_encodings.at(index);
return m_items.at(index);
}
int FileListIterator::maxProgress() const
{
return m_files.size();
return m_items.size();
}
int FileListIterator::currentProgress() const
......@@ -561,13 +555,6 @@ int FileListIterator::currentProgress() const
return m_maxIndex + 1;
}
QTextCodec *FileListIterator::encodingAt(int index) const
{
if (index >= 0 && index < m_encodings.size())
return m_encodings.at(index);
return QTextCodec::codecForLocale();
}
// #pragma mark -- SubDirFileIterator
namespace {
......@@ -589,12 +576,17 @@ SubDirFileIterator::SubDirFileIterator(const QStringList &directories, const QSt
}
}
SubDirFileIterator::~SubDirFileIterator()
{
qDeleteAll(m_items);
}
void SubDirFileIterator::update(int index)
{
if (index < m_files.size())
if (index < m_items.size())
return;
// collect files from the directories until we have enough for the given index
while (!m_dirs.isEmpty() && index >= m_files.size()) {
while (!m_dirs.isEmpty() && index >= m_items.size()) {
QDir dir = m_dirs.pop();
const qreal dirProgressMax = m_progressValues.pop();
const bool processed = m_processedValues.pop();
......@@ -607,9 +599,10 @@ void SubDirFileIterator::update(int index)
QDir::Files|QDir::Hidden);
QStringListIterator it(fileEntries);
it.toBack();
m_items.reserve(m_items.size() + fileEntries.size());
while (it.hasPrevious()) {
const QString &file = it.previous();
m_files.append(dir.path()+ QLatin1Char('/') +file);
m_items.append(new Item(dir.path()+ QLatin1Char('/') + file, m_encoding));
}
m_progress += dirProgressMax;
} else {
......@@ -630,24 +623,18 @@ void SubDirFileIterator::update(int index)
m_progress += dirProgressMax;
}
}
if (index >= m_files.size())
if (index >= m_items.size())
m_progress = MAX_PROGRESS;
}
int SubDirFileIterator::currentFileCount() const
{
return m_files.size();
}
QString SubDirFileIterator::fileAt(int index) const
{
return m_files.at(index);
return m_items.size();
}
QTextCodec *SubDirFileIterator::codecAt(int index) const
const FileIterator::Item &SubDirFileIterator::itemAt(int index) const
{
Q_UNUSED(index)
return m_encoding;
return *m_items.at(index);
}
int SubDirFileIterator::maxProgress() const
......
......@@ -28,10 +28,10 @@
#include "utils_global.h"
#include <QDir>
#include <QFuture>
#include <QMap>
#include <QStack>
#include <QDir>
#include <QTextDocument>
QT_FORWARD_DECLARE_CLASS(QTextCodec)
......@@ -44,6 +44,7 @@ public:
class Item
{
public:
Item() : encoding(nullptr) { }
Item(const QString &path, QTextCodec *codec)
: filePath(path), encoding(codec)
{}
......@@ -62,11 +63,15 @@ public:
typedef const value_type *pointer;
typedef const value_type &reference;
const_iterator(const FileIterator *parent, Item item, int id)
: m_parent(parent), m_item(item), m_index(id)
const_iterator() : m_parent(nullptr), m_index(-1) { }
const_iterator(const FileIterator *parent, int id)
: m_parent(parent), m_index(id)
{}
const Item operator*() const { return m_item; }
const Item *operator->() const { return &m_item; }
const_iterator(const const_iterator &) = default;
const_iterator &operator=(const const_iterator &) = default;
reference operator*() const { return m_parent->itemAt(m_index); }
pointer operator->() const { return &m_parent->itemAt(m_index); }
void operator++() { m_parent->advance(this); }
bool operator==(const const_iterator &other) const
{
......@@ -75,23 +80,22 @@ public:
bool operator!=(const const_iterator &other) const { return !operator==(other); }
const FileIterator *m_parent;
Item m_item;
int m_index; // -1 == end
};
virtual ~FileIterator() {}
void advance(const_iterator *it) const;
const_iterator begin() const;
const_iterator end() const;
virtual int maxProgress() const = 0;
virtual int currentProgress() const = 0;
void advance(const_iterator *it) const;
virtual const Item &itemAt(int index) const = 0;
protected:
virtual void update(int requestedIndex) = 0;
virtual int currentFileCount() const = 0;
virtual QString fileAt(int index) const = 0;
virtual QTextCodec *codecAt(int index) const = 0;
};
class QTCREATOR_UTILS_EXPORT FileListIterator : public FileIterator
......@@ -106,13 +110,10 @@ public:
protected:
void update(int requestedIndex) override;
int currentFileCount() const override;
QString fileAt(int index) const override;
QTextCodec *codecAt(int index) const override;
const Item &itemAt(int index) const override;
private:
QTextCodec *encodingAt(int index) const;
QStringList m_files;
QList<QTextCodec *> m_encodings;
QVector<Item> m_items;
int m_maxIndex;
};
......@@ -121,6 +122,7 @@ class QTCREATOR_UTILS_EXPORT SubDirFileIterator : public FileIterator
public:
SubDirFileIterator(const QStringList &directories, const QStringList &filters,
QTextCodec *encoding = 0);
~SubDirFileIterator();
int maxProgress() const override;
int currentProgress() const override;
......@@ -128,8 +130,7 @@ public:
protected:
void update(int requestedIndex) override;
int currentFileCount() const override;
QString fileAt(int index) const override;
QTextCodec *codecAt(int index) const override;
const Item &itemAt(int index) const override;
private:
QStringList m_filters;
......@@ -138,7 +139,8 @@ private:
QStack<qreal> m_progressValues;
QStack<bool> m_processedValues;
qreal m_progress;
QStringList m_files;
// Use heap allocated objects directly because we want references to stay valid even after resize
QList<Item *> m_items;
};
class QTCREATOR_UTILS_EXPORT FileSearchResult
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment