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