mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Merge branch 'vfs_normalized_path_1' into 'master'
Use normalized path for VFS manager and RecursiveDirectoryIterator See merge request OpenMW/openmw!3806
This commit is contained in:
commit
7450b11402
8 changed files with 34 additions and 23 deletions
|
@ -116,9 +116,9 @@ void readVFS(std::unique_ptr<VFS::Archive>&& archive, const std::filesystem::pat
|
|||
|
||||
for (const auto& name : vfs.getRecursiveDirectoryIterator(""))
|
||||
{
|
||||
if (isNIF(name))
|
||||
if (isNIF(name.value()))
|
||||
{
|
||||
readNIF(archivePath, name, &vfs, quiet);
|
||||
readNIF(archivePath, name.value(), &vfs, quiet);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,18 +30,18 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char* const* e
|
|||
|
||||
for (const auto& filepath : vfs->getRecursiveDirectoryIterator(""))
|
||||
{
|
||||
if (filepath.size() < baseSize + 1 || filepath.substr(0, baseSize) != mBaseDirectory
|
||||
|| (filepath[baseSize] != '/' && filepath[baseSize] != '\\'))
|
||||
const std::string_view view = filepath.view();
|
||||
if (view.size() < baseSize + 1 || !view.starts_with(mBaseDirectory) || view[baseSize] != '/')
|
||||
continue;
|
||||
|
||||
if (extensions)
|
||||
{
|
||||
std::string::size_type extensionIndex = filepath.find_last_of('.');
|
||||
const auto extensionIndex = view.find_last_of('.');
|
||||
|
||||
if (extensionIndex == std::string::npos)
|
||||
if (extensionIndex == std::string_view::npos)
|
||||
continue;
|
||||
|
||||
std::string extension = filepath.substr(extensionIndex + 1);
|
||||
std::string_view extension = view.substr(extensionIndex + 1);
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -53,10 +53,9 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char* const* e
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string file = filepath.substr(baseSize + 1);
|
||||
std::string file(view.substr(baseSize + 1));
|
||||
mFiles.push_back(file);
|
||||
std::replace(file.begin(), file.end(), '\\', '/');
|
||||
mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(file), static_cast<int>(mFiles.size()) - 1));
|
||||
mIndex.emplace(std::move(file), static_cast<int>(mFiles.size()) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <components/files/conversion.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
|
||||
#include "grouptype.hpp"
|
||||
|
||||
|
|
|
@ -36,13 +36,17 @@
|
|||
|
||||
#include <components/esm/formid.hpp>
|
||||
#include <components/files/istreamptr.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
|
||||
namespace ToUTF8
|
||||
{
|
||||
class StatelessUtf8Encoder;
|
||||
}
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace ESM4
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "manager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/files/conversion.hpp>
|
||||
|
@ -37,30 +38,30 @@ namespace VFS
|
|||
archive->listResources(mIndex);
|
||||
}
|
||||
|
||||
Files::IStreamPtr Manager::get(std::string_view name) const
|
||||
Files::IStreamPtr Manager::get(const Path::Normalized& name) const
|
||||
{
|
||||
return getNormalized(Path::normalizeFilename(name));
|
||||
return getNormalized(name);
|
||||
}
|
||||
|
||||
Files::IStreamPtr Manager::getNormalized(std::string_view normalizedName) const
|
||||
{
|
||||
assert(Path::isNormalized(normalizedName));
|
||||
const auto found = mIndex.find(normalizedName);
|
||||
if (found == mIndex.end())
|
||||
throw std::runtime_error("Resource '" + std::string(normalizedName) + "' not found");
|
||||
return found->second->open();
|
||||
}
|
||||
|
||||
bool Manager::exists(std::string_view name) const
|
||||
bool Manager::exists(const Path::Normalized& name) const
|
||||
{
|
||||
return mIndex.find(Path::normalizeFilename(name)) != mIndex.end();
|
||||
return mIndex.find(name) != mIndex.end();
|
||||
}
|
||||
|
||||
std::string Manager::getArchive(std::string_view name) const
|
||||
std::string Manager::getArchive(const Path::Normalized& name) const
|
||||
{
|
||||
std::string normalized = Path::normalizeFilename(name);
|
||||
for (auto it = mArchives.rbegin(); it != mArchives.rend(); ++it)
|
||||
{
|
||||
if ((*it)->contains(normalized))
|
||||
if ((*it)->contains(name))
|
||||
return (*it)->getDescription();
|
||||
}
|
||||
return {};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "filemap.hpp"
|
||||
#include "pathutil.hpp"
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
|
@ -40,19 +41,19 @@ namespace VFS
|
|||
|
||||
/// Does a file with this name exist?
|
||||
/// @note May be called from any thread once the index has been built.
|
||||
bool exists(std::string_view name) const;
|
||||
bool exists(const Path::Normalized& name) const;
|
||||
|
||||
/// Retrieve a file by name.
|
||||
/// @note Throws an exception if the file can not be found.
|
||||
/// @note May be called from any thread once the index has been built.
|
||||
Files::IStreamPtr get(std::string_view name) const;
|
||||
Files::IStreamPtr get(const Path::Normalized& name) const;
|
||||
|
||||
/// Retrieve a file by name (name is already normalized).
|
||||
/// @note Throws an exception if the file can not be found.
|
||||
/// @note May be called from any thread once the index has been built.
|
||||
Files::IStreamPtr getNormalized(std::string_view normalizedName) const;
|
||||
|
||||
std::string getArchive(std::string_view name) const;
|
||||
std::string getArchive(const Path::Normalized& name) const;
|
||||
|
||||
/// Recursively iterate over the elements of the given path
|
||||
/// In practice it return all files of the VFS starting with the given path
|
||||
|
|
|
@ -15,6 +15,11 @@ namespace VFS::Path
|
|||
return c == '\\' ? '/' : Misc::StringUtils::toLower(c);
|
||||
}
|
||||
|
||||
inline constexpr bool isNormalized(std::string_view name)
|
||||
{
|
||||
return std::all_of(name.begin(), name.end(), [](char v) { return v == normalize(v); });
|
||||
}
|
||||
|
||||
inline void normalizeFilenameInPlace(std::string& name)
|
||||
{
|
||||
std::transform(name.begin(), name.end(), name.begin(), normalize);
|
||||
|
|
|
@ -16,9 +16,9 @@ namespace VFS
|
|||
{
|
||||
}
|
||||
|
||||
const std::string& operator*() const { return mIt->first.value(); }
|
||||
const Path::Normalized& operator*() const { return mIt->first; }
|
||||
|
||||
const std::string* operator->() const { return &mIt->first.value(); }
|
||||
const Path::Normalized* operator->() const { return &mIt->first; }
|
||||
|
||||
RecursiveDirectoryIterator& operator++()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue