mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 03:40:14 +00:00
Use a pair of iterator to represents a range for directory listing
This commit is contained in:
parent
baa33799de
commit
b676d93e03
@ -105,8 +105,23 @@ namespace VFS
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveDirectoryIterator Manager::getRecursiveDirectoryIterator(const std::string& path) const
|
namespace
|
||||||
{
|
{
|
||||||
return RecursiveDirectoryIterator(mIndex, normalizeFilename(path));
|
bool startsWith(std::string_view text, std::string_view start)
|
||||||
|
{
|
||||||
|
return text.rfind(start, 0) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator(const std::string& path) const
|
||||||
|
{
|
||||||
|
if (path.empty())
|
||||||
|
return { mIndex.begin(), mIndex.end() };
|
||||||
|
auto normalized = normalizeFilename(path);
|
||||||
|
const auto it = mIndex.lower_bound(normalized);
|
||||||
|
if (it == mIndex.end() || !startsWith(it->first, normalized))
|
||||||
|
return { it, it };
|
||||||
|
++normalized.back();
|
||||||
|
return { it, mIndex.lower_bound(normalized) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,51 +12,19 @@ namespace VFS
|
|||||||
class Archive;
|
class Archive;
|
||||||
class File;
|
class File;
|
||||||
|
|
||||||
class RecursiveDirectoryIterator;
|
template <typename Iterator>
|
||||||
RecursiveDirectoryIterator end(const RecursiveDirectoryIterator& iter);
|
class IteratorPair
|
||||||
|
|
||||||
class RecursiveDirectoryIterator
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RecursiveDirectoryIterator(const std::map<std::string, File*>& index, const std::string& path)
|
IteratorPair(Iterator first, Iterator last) : mFirst(first), mLast(last) {}
|
||||||
: mPath(path)
|
Iterator begin() const { return mFirst; }
|
||||||
, mIndex(&index)
|
Iterator end() const { return mLast; }
|
||||||
, mIt(index.lower_bound(path))
|
|
||||||
{}
|
|
||||||
|
|
||||||
RecursiveDirectoryIterator(const RecursiveDirectoryIterator&) = default;
|
|
||||||
|
|
||||||
const std::string& operator*() const { return mIt->first; }
|
|
||||||
const std::string* operator->() const { return &mIt->first; }
|
|
||||||
|
|
||||||
bool operator!=(const RecursiveDirectoryIterator& other) { return mPath != other.mPath || mIt != other.mIt; }
|
|
||||||
|
|
||||||
RecursiveDirectoryIterator& operator++()
|
|
||||||
{
|
|
||||||
if (++mIt == mIndex->end() || !starts_with(mIt->first, mPath))
|
|
||||||
*this = end(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend RecursiveDirectoryIterator end(const RecursiveDirectoryIterator& iter);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool starts_with(const std::string& text, const std::string& start) { return text.rfind(start, 0) == 0; }
|
Iterator mFirst;
|
||||||
|
Iterator mLast;
|
||||||
std::string mPath;
|
|
||||||
const std::map<std::string, File*>* mIndex;
|
|
||||||
std::map<std::string, File*>::const_iterator mIt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RecursiveDirectoryIterator begin(RecursiveDirectoryIterator iter) { return iter; }
|
|
||||||
|
|
||||||
inline RecursiveDirectoryIterator end(const RecursiveDirectoryIterator& iter)
|
|
||||||
{
|
|
||||||
RecursiveDirectoryIterator result(iter);
|
|
||||||
result.mIt = result.mIndex->end();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief The main class responsible for loading files from a virtual file system.
|
/// @brief The main class responsible for loading files from a virtual file system.
|
||||||
/// @par Various archive types (e.g. directories on the filesystem, or compressed archives)
|
/// @par Various archive types (e.g. directories on the filesystem, or compressed archives)
|
||||||
/// can be registered, and will be merged into a single file tree. If the same filename is
|
/// can be registered, and will be merged into a single file tree. If the same filename is
|
||||||
@ -64,6 +32,21 @@ namespace VFS
|
|||||||
/// @par Most of the methods in this class are considered thread-safe, see each method documentation for details.
|
/// @par Most of the methods in this class are considered thread-safe, see each method documentation for details.
|
||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
|
class RecursiveDirectoryIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RecursiveDirectoryIterator(std::map<std::string, File*>::const_iterator it) : mIt(it) {}
|
||||||
|
const std::string& operator*() const { return mIt->first; }
|
||||||
|
const std::string* operator->() const { return &mIt->first; }
|
||||||
|
bool operator!=(const RecursiveDirectoryIterator& other) { return mIt != other.mIt; }
|
||||||
|
RecursiveDirectoryIterator& operator++() { ++mIt; return *this; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, File*>::const_iterator mIt;
|
||||||
|
};
|
||||||
|
|
||||||
|
using RecursiveDirectoryRange = IteratorPair<RecursiveDirectoryIterator>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @param strict Use strict path handling? If enabled, no case folding will
|
/// @param strict Use strict path handling? If enabled, no case folding will
|
||||||
/// be done, but slash/backslash conversions are always done.
|
/// be done, but slash/backslash conversions are always done.
|
||||||
@ -105,7 +88,7 @@ namespace VFS
|
|||||||
/// In practice it return all files of the VFS starting with the given path
|
/// In practice it return all files of the VFS starting with the given path
|
||||||
/// @note the path is normalized
|
/// @note the path is normalized
|
||||||
/// @note May be called from any thread once the index has been built.
|
/// @note May be called from any thread once the index has been built.
|
||||||
RecursiveDirectoryIterator getRecursiveDirectoryIterator(const std::string& path) const;
|
RecursiveDirectoryRange getRecursiveDirectoryIterator(const std::string& path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mStrict;
|
bool mStrict;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user