Merge branch 'vfs_normalized_path' into 'master'

Add type for normalized VFS path and use for VFS::Manager file map key

See merge request OpenMW/openmw!3781
ini_importer_tests
jvoisin 11 months ago
commit ec6ac8058b

@ -17,6 +17,7 @@
#include <components/vfs/bsaarchive.hpp>
#include <components/vfs/filesystemarchive.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include <boost/program_options.hpp>

@ -11,6 +11,7 @@
#include <components/misc/strings/lower.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
CSMWorld::Resources::Resources(
const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, const char* const* extensions)

@ -18,6 +18,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/settings/values.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp"

@ -29,6 +29,7 @@
#include <components/sceneutil/lightmanager.hpp>
#include <components/settings/values.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include <components/widgets/sharedstatebutton.hpp>
#include "../mwbase/environment.hpp"

@ -5,6 +5,7 @@
#include <components/settings/values.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/pathutil.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include "../mwbase/environment.hpp"

@ -33,6 +33,7 @@
#include <components/sceneutil/keyframe.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/sceneutil/lightutil.hpp>

@ -23,6 +23,7 @@
#include <components/stereo/multiview.hpp>
#include <components/stereo/stereomanager.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"

@ -13,6 +13,7 @@
#include <components/settings/values.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/pathutil.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"

@ -6,6 +6,7 @@
#include <components/misc/strings/conversion.hpp>
#include <components/vfs/archive.hpp>
#include <components/vfs/file.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/pathutil.hpp>
@ -60,7 +61,7 @@ namespace TestingOpenMW
void listResources(VFS::FileMap& out) override
{
for (const auto& [key, value] : mFiles)
out.emplace(VFS::Path::normalizeFilename(key), value);
out.emplace(key, value);
}
bool contains(std::string_view file) const override { return mFiles.contains(file); }

@ -1,27 +1,13 @@
#ifndef OPENMW_COMPONENTS_RESOURCE_ARCHIVE_H
#define OPENMW_COMPONENTS_RESOURCE_ARCHIVE_H
#ifndef OPENMW_COMPONENTS_VFS_ARCHIVE_H
#define OPENMW_COMPONENTS_VFS_ARCHIVE_H
#include <filesystem>
#include <map>
#include <string>
#include <string_view>
#include <components/files/istreamptr.hpp>
#include "filemap.hpp"
namespace VFS
{
class File
{
public:
virtual ~File() = default;
virtual Files::IStreamPtr open() = 0;
virtual std::filesystem::path getPath() = 0;
};
using FileMap = std::map<std::string, File*, std::less<>>;
class Archive
{
public:

@ -2,6 +2,7 @@
#define VFS_BSAARCHIVE_HPP_
#include "archive.hpp"
#include "file.hpp"
#include "pathutil.hpp"
#include <components/bsa/ba2dx10file.hpp>

@ -0,0 +1,21 @@
#ifndef OPENMW_COMPONENTS_VFS_FILE_H
#define OPENMW_COMPONENTS_VFS_FILE_H
#include <filesystem>
#include <components/files/istreamptr.hpp>
namespace VFS
{
class File
{
public:
virtual ~File() = default;
virtual Files::IStreamPtr open() = 0;
virtual std::filesystem::path getPath() = 0;
};
}
#endif

@ -0,0 +1,19 @@
#ifndef OPENMW_COMPONENTS_VFS_FILEMAP_H
#define OPENMW_COMPONENTS_VFS_FILEMAP_H
#include <map>
#include <string>
namespace VFS
{
class File;
namespace Path
{
class Normalized;
}
using FileMap = std::map<Path::Normalized, File*, std::less<>>;
}
#endif

@ -2,8 +2,9 @@
#define OPENMW_COMPONENTS_RESOURCE_FILESYSTEMARCHIVE_H
#include "archive.hpp"
#include <filesystem>
#include "file.hpp"
#include <filesystem>
#include <string>
namespace VFS

@ -5,12 +5,19 @@
#include <components/files/conversion.hpp>
#include <components/misc/strings/lower.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include "archive.hpp"
#include "file.hpp"
#include "pathutil.hpp"
#include "recursivedirectoryiterator.hpp"
namespace VFS
{
Manager::Manager() = default;
Manager::~Manager() = default;
void Manager::reset()
{
mIndex.clear();
@ -70,13 +77,13 @@ namespace VFS
return found->second->getPath();
}
Manager::RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator(std::string_view path) const
RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator(std::string_view path) const
{
if (path.empty())
return { mIndex.begin(), mIndex.end() };
std::string normalized = Path::normalizeFilename(path);
const auto it = mIndex.lower_bound(normalized);
if (it == mIndex.end() || !it->first.starts_with(normalized))
if (it == mIndex.end() || !it->first.view().starts_with(normalized))
return { it, it };
++normalized.back();
return { it, mIndex.lower_bound(normalized) };

@ -4,32 +4,17 @@
#include <components/files/istreamptr.hpp>
#include <filesystem>
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include "archive.hpp"
#include "filemap.hpp"
namespace VFS
{
template <typename Iterator>
class IteratorPair
{
public:
IteratorPair(Iterator first, Iterator last)
: mFirst(first)
, mLast(last)
{
}
Iterator begin() const { return mFirst; }
Iterator end() const { return mLast; }
private:
Iterator mFirst;
Iterator mLast;
};
class Archive;
class RecursiveDirectoryRange;
/// @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)
@ -38,29 +23,11 @@ namespace VFS
/// @par Most of the methods in this class are considered thread-safe, see each method documentation for details.
class Manager
{
class RecursiveDirectoryIterator
{
public:
RecursiveDirectoryIterator(FileMap::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:
FileMap::const_iterator mIt;
};
using RecursiveDirectoryRange = IteratorPair<RecursiveDirectoryIterator>;
public:
Manager();
~Manager();
// Empty the file index and unregister archives.
void reset();

@ -4,6 +4,7 @@
#include <components/misc/strings/lower.hpp>
#include <algorithm>
#include <ostream>
#include <string>
#include <string_view>
@ -51,6 +52,73 @@ namespace VFS::Path
bool operator()(std::string_view left, std::string_view right) const { return pathLess(left, right); }
};
class Normalized
{
public:
Normalized() = default;
Normalized(std::string_view value)
: mValue(normalizeFilename(value))
{
}
Normalized(const char* value)
: Normalized(std::string_view(value))
{
}
Normalized(const std::string& value)
: Normalized(std::string_view(value))
{
}
explicit Normalized(std::string&& value)
: mValue(std::move(value))
{
normalizeFilenameInPlace(mValue);
}
const std::string& value() const& { return mValue; }
std::string value() && { return std::move(mValue); }
std::string_view view() const { return mValue; }
operator std::string_view() const { return mValue; }
operator const std::string&() const { return mValue; }
friend bool operator==(const Normalized& lhs, const Normalized& rhs) = default;
template <class T>
friend bool operator==(const Normalized& lhs, const T& rhs)
{
return lhs.mValue == rhs;
}
friend bool operator<(const Normalized& lhs, const Normalized& rhs) { return lhs.mValue < rhs.mValue; }
template <class T>
friend bool operator<(const Normalized& lhs, const T& rhs)
{
return lhs.mValue < rhs;
}
template <class T>
friend bool operator<(const T& lhs, const Normalized& rhs)
{
return lhs < rhs.mValue;
}
friend std::ostream& operator<<(std::ostream& stream, const Normalized& value)
{
return stream << value.mValue;
}
private:
std::string mValue;
};
}
#endif

@ -0,0 +1,54 @@
#ifndef OPENMW_COMPONENTS_VFS_RECURSIVEDIRECTORYITERATOR_H
#define OPENMW_COMPONENTS_VFS_RECURSIVEDIRECTORYITERATOR_H
#include <string>
#include "filemap.hpp"
#include "pathutil.hpp"
namespace VFS
{
class RecursiveDirectoryIterator
{
public:
RecursiveDirectoryIterator(FileMap::const_iterator it)
: mIt(it)
{
}
const std::string& operator*() const { return mIt->first.value(); }
const std::string* operator->() const { return &mIt->first.value(); }
RecursiveDirectoryIterator& operator++()
{
++mIt;
return *this;
}
friend bool operator==(const RecursiveDirectoryIterator& lhs, const RecursiveDirectoryIterator& rhs) = default;
private:
FileMap::const_iterator mIt;
};
class RecursiveDirectoryRange
{
public:
RecursiveDirectoryRange(RecursiveDirectoryIterator first, RecursiveDirectoryIterator last)
: mBegin(first)
, mEnd(last)
{
}
RecursiveDirectoryIterator begin() const { return mBegin; }
RecursiveDirectoryIterator end() const { return mEnd; }
private:
RecursiveDirectoryIterator mBegin;
RecursiveDirectoryIterator mEnd;
};
}
#endif
Loading…
Cancel
Save