1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 15:59:54 +00:00
openmw/components/vfs/manager.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

133 lines
3.8 KiB
C++
Raw Normal View History

#include "manager.hpp"
2024-01-16 22:53:55 +00:00
#include <cassert>
#include <stdexcept>
#include <components/files/conversion.hpp>
#include <components/misc/strings/lower.hpp>
#include <components/vfs/recursivedirectoryiterator.hpp>
#include "archive.hpp"
#include "file.hpp"
2023-05-31 21:11:03 +00:00
#include "pathutil.hpp"
#include "recursivedirectoryiterator.hpp"
namespace VFS
{
Manager::Manager() = default;
Manager::~Manager() = default;
void Manager::reset()
{
mIndex.clear();
mArchives.clear();
}
void Manager::addArchive(std::unique_ptr<Archive>&& archive)
{
mArchives.push_back(std::move(archive));
}
void Manager::buildIndex()
{
mIndex.clear();
for (const auto& archive : mArchives)
2023-05-31 21:11:03 +00:00
archive->listResources(mIndex);
}
2024-05-02 23:07:47 +00:00
Files::IStreamPtr Manager::find(Path::NormalizedView name) const
{
return findNormalized(name.value());
}
Files::IStreamPtr Manager::get(const Path::Normalized& name) const
{
return getNormalized(name);
2015-03-26 17:02:51 +00:00
}
Files::IStreamPtr Manager::get(Path::NormalizedView name) const
{
return getNormalized(name.value());
}
2023-12-17 14:20:48 +00:00
Files::IStreamPtr Manager::getNormalized(std::string_view normalizedName) const
2015-03-26 17:02:51 +00:00
{
2024-01-16 22:53:55 +00:00
assert(Path::isNormalized(normalizedName));
2024-05-02 23:07:47 +00:00
auto ptr = findNormalized(normalizedName);
if (ptr == nullptr)
throw std::runtime_error("Resource '" + std::string(normalizedName) + "' not found");
return ptr;
}
bool Manager::exists(const Path::Normalized& name) const
{
return mIndex.find(name) != mIndex.end();
2015-03-26 17:02:51 +00:00
}
bool Manager::exists(Path::NormalizedView name) const
{
return mIndex.find(name) != mIndex.end();
}
std::string Manager::getArchive(const Path::Normalized& name) const
2020-12-29 20:45:59 +00:00
{
2020-12-30 09:35:51 +00:00
for (auto it = mArchives.rbegin(); it != mArchives.rend(); ++it)
2020-12-29 20:45:59 +00:00
{
if ((*it)->contains(name))
2020-12-30 09:35:51 +00:00
return (*it)->getDescription();
2020-12-29 20:45:59 +00:00
}
return {};
}
std::filesystem::path Manager::getAbsoluteFileName(const std::filesystem::path& name) const
2022-05-14 01:58:00 +00:00
{
std::string normalized = Files::pathToUnicodeString(name);
2023-05-31 21:11:03 +00:00
Path::normalizeFilenameInPlace(normalized);
2022-05-14 01:58:00 +00:00
const auto found = mIndex.find(normalized);
2022-05-14 01:58:00 +00:00
if (found == mIndex.end())
2024-05-01 23:55:36 +00:00
throw std::runtime_error("Resource '" + normalized + "' is not found");
return found->second->getPath();
2022-05-14 01:58:00 +00:00
}
RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator(std::string_view path) const
{
if (path.empty())
return { mIndex.begin(), mIndex.end() };
2023-05-31 21:11:03 +00:00
std::string normalized = Path::normalizeFilename(path);
const auto it = mIndex.lower_bound(normalized);
if (it == mIndex.end() || !it->first.view().starts_with(normalized))
return { it, it };
++normalized.back();
return { it, mIndex.lower_bound(normalized) };
}
RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator(VFS::Path::NormalizedView path) const
{
if (path.value().empty())
return { mIndex.begin(), mIndex.end() };
const auto it = mIndex.lower_bound(path);
if (it == mIndex.end() || !it->first.view().starts_with(path.value()))
return { it, it };
std::string copy(path.value());
++copy.back();
return { it, mIndex.lower_bound(copy) };
}
RecursiveDirectoryRange Manager::getRecursiveDirectoryIterator() const
{
return { mIndex.begin(), mIndex.end() };
}
2024-05-02 23:07:47 +00:00
Files::IStreamPtr Manager::findNormalized(std::string_view normalizedPath) const
{
assert(Path::isNormalized(normalizedPath));
const auto it = mIndex.find(normalizedPath);
if (it == mIndex.end())
return nullptr;
return it->second->open();
}
}