2014-07-04 10:46:57 +00:00
|
|
|
#include "resources.hpp"
|
|
|
|
|
2014-12-03 14:31:00 +00:00
|
|
|
#include <algorithm>
|
2014-07-04 10:46:57 +00:00
|
|
|
#include <sstream>
|
2022-10-19 17:02:00 +00:00
|
|
|
#include <stddef.h>
|
2014-07-04 10:46:57 +00:00
|
|
|
#include <stdexcept>
|
2021-09-04 16:07:23 +00:00
|
|
|
#include <string_view>
|
2022-10-19 17:02:00 +00:00
|
|
|
#include <utility>
|
2014-07-04 10:46:57 +00:00
|
|
|
|
2022-10-19 17:02:00 +00:00
|
|
|
#include <apps/opencs/model/world/universalid.hpp>
|
2015-03-19 16:49:41 +00:00
|
|
|
|
2022-08-02 22:00:54 +00:00
|
|
|
#include <components/misc/strings/lower.hpp>
|
2022-10-19 17:02:00 +00:00
|
|
|
#include <components/vfs/manager.hpp>
|
2024-01-15 23:30:41 +00:00
|
|
|
#include <components/vfs/recursivedirectoryiterator.hpp>
|
2014-07-04 10:46:57 +00:00
|
|
|
|
2015-03-19 16:49:41 +00:00
|
|
|
CSMWorld::Resources::Resources(
|
|
|
|
const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, const char* const* extensions)
|
2014-07-07 13:20:05 +00:00
|
|
|
: mBaseDirectory(baseDirectory)
|
|
|
|
, mType(type)
|
2014-07-04 10:46:57 +00:00
|
|
|
{
|
2017-08-19 07:43:31 +00:00
|
|
|
recreate(vfs, extensions);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char* const* extensions)
|
|
|
|
{
|
|
|
|
mFiles.clear();
|
|
|
|
mIndex.clear();
|
|
|
|
|
2021-05-02 06:43:44 +00:00
|
|
|
size_t baseSize = mBaseDirectory.size();
|
2014-07-04 10:46:57 +00:00
|
|
|
|
2024-03-11 23:40:03 +00:00
|
|
|
for (const auto& filepath : vfs->getRecursiveDirectoryIterator())
|
2014-07-04 10:46:57 +00:00
|
|
|
{
|
2024-01-17 22:32:15 +00:00
|
|
|
const std::string_view view = filepath.view();
|
|
|
|
if (view.size() < baseSize + 1 || !view.starts_with(mBaseDirectory) || view[baseSize] != '/')
|
2014-07-04 10:46:57 +00:00
|
|
|
continue;
|
|
|
|
|
2015-03-19 16:49:41 +00:00
|
|
|
if (extensions)
|
2014-07-04 10:46:57 +00:00
|
|
|
{
|
2024-01-17 22:32:15 +00:00
|
|
|
const auto extensionIndex = view.find_last_of('.');
|
2014-07-07 09:34:24 +00:00
|
|
|
|
2024-01-17 22:32:15 +00:00
|
|
|
if (extensionIndex == std::string_view::npos)
|
2015-03-19 16:49:41 +00:00
|
|
|
continue;
|
2014-07-07 09:34:24 +00:00
|
|
|
|
2024-01-17 22:32:15 +00:00
|
|
|
std::string_view extension = view.substr(extensionIndex + 1);
|
2014-07-07 09:34:24 +00:00
|
|
|
|
2015-03-19 16:49:41 +00:00
|
|
|
int i = 0;
|
2014-07-07 09:34:24 +00:00
|
|
|
|
2015-03-19 16:49:41 +00:00
|
|
|
for (; extensions[i]; ++i)
|
|
|
|
if (extensions[i] == extension)
|
|
|
|
break;
|
2014-07-07 09:34:24 +00:00
|
|
|
|
2015-03-19 16:49:41 +00:00
|
|
|
if (!extensions[i])
|
|
|
|
continue;
|
2014-07-04 10:46:57 +00:00
|
|
|
}
|
2015-03-19 16:49:41 +00:00
|
|
|
|
2024-01-17 22:32:15 +00:00
|
|
|
std::string file(view.substr(baseSize + 1));
|
2015-03-19 16:49:41 +00:00
|
|
|
mFiles.push_back(file);
|
2024-01-17 22:32:15 +00:00
|
|
|
mIndex.emplace(std::move(file), static_cast<int>(mFiles.size()) - 1);
|
2014-07-04 10:46:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSMWorld::Resources::getSize() const
|
|
|
|
{
|
2021-05-02 06:43:44 +00:00
|
|
|
return static_cast<int>(mFiles.size());
|
2014-07-04 10:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CSMWorld::Resources::getId(int index) const
|
|
|
|
{
|
|
|
|
return mFiles.at(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CSMWorld::Resources::getIndex(const std::string& id) const
|
|
|
|
{
|
|
|
|
int index = searchId(id);
|
|
|
|
|
|
|
|
if (index == -1)
|
|
|
|
{
|
|
|
|
std::ostringstream stream;
|
|
|
|
stream << "Invalid resource: " << mBaseDirectory << '/' << id;
|
|
|
|
|
2019-01-07 13:47:39 +00:00
|
|
|
throw std::runtime_error(stream.str());
|
2014-07-04 10:46:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2021-09-04 16:07:23 +00:00
|
|
|
int CSMWorld::Resources::searchId(std::string_view id) const
|
2014-07-04 10:46:57 +00:00
|
|
|
{
|
|
|
|
std::string id2 = Misc::StringUtils::lowerCase(id);
|
|
|
|
|
2014-12-03 14:31:00 +00:00
|
|
|
std::replace(id2.begin(), id2.end(), '\\', '/');
|
|
|
|
|
2014-07-04 10:46:57 +00:00
|
|
|
std::map<std::string, int>::const_iterator iter = mIndex.find(id2);
|
|
|
|
|
|
|
|
if (iter == mIndex.end())
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return iter->second;
|
2014-07-07 13:20:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSMWorld::UniversalId::Type CSMWorld::Resources::getType() const
|
|
|
|
{
|
|
|
|
return mType;
|
2015-03-19 16:21:15 +00:00
|
|
|
}
|