mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-15 00:05:02 +02:00
VCMIDirs update #5
- Minor fixes - string based paths -> boost::filesystem::path paths (I hope it's final) - New user data path on windows - New moving dir method on windows.
This commit is contained in:
@ -4,9 +4,11 @@
|
||||
#include "CFileInfo.h"
|
||||
#include "CFileInputStream.h"
|
||||
|
||||
CFilesystemLoader::CFilesystemLoader(const std::string &mountPoint, const std::string & baseDirectory, size_t depth, bool initial):
|
||||
baseDirectory(baseDirectory),
|
||||
mountPoint(mountPoint),
|
||||
namespace bfs = boost::filesystem;
|
||||
|
||||
CFilesystemLoader::CFilesystemLoader(std::string _mountPoint, bfs::path baseDirectory, size_t depth, bool initial):
|
||||
baseDirectory(std::move(baseDirectory)),
|
||||
mountPoint(std::move(_mountPoint)),
|
||||
fileList(listFiles(mountPoint, depth, initial))
|
||||
{
|
||||
logGlobal->traceStream() << "Filesystem loaded, " << fileList.size() << " files found";
|
||||
@ -16,7 +18,7 @@ std::unique_ptr<CInputStream> CFilesystemLoader::load(const ResourceID & resourc
|
||||
{
|
||||
assert(fileList.count(resourceName));
|
||||
|
||||
std::unique_ptr<CInputStream> stream(new CFileInputStream(baseDirectory + '/' + fileList.at(resourceName)));
|
||||
std::unique_ptr<CInputStream> stream(new CFileInputStream(baseDirectory / fileList.at(resourceName)));
|
||||
return stream;
|
||||
}
|
||||
|
||||
@ -34,7 +36,7 @@ boost::optional<std::string> CFilesystemLoader::getResourceName(const ResourceID
|
||||
{
|
||||
assert(existsResource(resourceName));
|
||||
|
||||
return baseDirectory + '/' + fileList.at(resourceName);
|
||||
return (baseDirectory / fileList.at(resourceName)).string();
|
||||
}
|
||||
|
||||
std::unordered_set<ResourceID> CFilesystemLoader::getFilteredFiles(std::function<bool(const ResourceID &)> filter) const
|
||||
@ -45,7 +47,8 @@ std::unordered_set<ResourceID> CFilesystemLoader::getFilteredFiles(std::function
|
||||
{
|
||||
if (filter(file.first))
|
||||
foundID.insert(file.first);
|
||||
} return foundID;
|
||||
}
|
||||
return foundID;
|
||||
}
|
||||
|
||||
bool CFilesystemLoader::createResource(std::string filename, bool update)
|
||||
@ -65,7 +68,7 @@ bool CFilesystemLoader::createResource(std::string filename, bool update)
|
||||
|
||||
if (!update)
|
||||
{
|
||||
std::ofstream newfile (baseDirectory + "/" + filename);
|
||||
bfs::ofstream newfile(baseDirectory / filename);
|
||||
if (!newfile.good())
|
||||
return false;
|
||||
}
|
||||
@ -73,49 +76,72 @@ bool CFilesystemLoader::createResource(std::string filename, bool update)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unordered_map<ResourceID, std::string> CFilesystemLoader::listFiles(const std::string &mountPoint, size_t depth, bool initial) const
|
||||
std::unordered_map<ResourceID, bfs::path> CFilesystemLoader::listFiles(const std::string &mountPoint, size_t depth, bool initial) const
|
||||
{
|
||||
std::set<EResType::Type> initialTypes;
|
||||
initialTypes.insert(EResType::DIRECTORY);
|
||||
initialTypes.insert(EResType::TEXT);
|
||||
initialTypes.insert(EResType::ARCHIVE_LOD);
|
||||
initialTypes.insert(EResType::ARCHIVE_VID);
|
||||
initialTypes.insert(EResType::ARCHIVE_SND);
|
||||
initialTypes.insert(EResType::ARCHIVE_ZIP);
|
||||
static const EResType::Type initArray[] = {
|
||||
EResType::DIRECTORY,
|
||||
EResType::TEXT,
|
||||
EResType::ARCHIVE_LOD,
|
||||
EResType::ARCHIVE_VID,
|
||||
EResType::ARCHIVE_SND,
|
||||
EResType::ARCHIVE_ZIP };
|
||||
static const std::set<EResType::Type> initialTypes(initArray, initArray + ARRAY_COUNT(initArray));
|
||||
|
||||
assert(boost::filesystem::is_directory(baseDirectory));
|
||||
std::unordered_map<ResourceID, std::string> fileList;
|
||||
assert(bfs::is_directory(baseDirectory));
|
||||
std::unordered_map<ResourceID, bfs::path> fileList;
|
||||
|
||||
std::vector<std::string> path;//vector holding relative path to our file
|
||||
std::vector<bfs::path> path; //vector holding relative path to our file
|
||||
|
||||
boost::filesystem::recursive_directory_iterator enddir;
|
||||
boost::filesystem::recursive_directory_iterator it(baseDirectory, boost::filesystem::symlink_option::recurse);
|
||||
bfs::recursive_directory_iterator enddir;
|
||||
bfs::recursive_directory_iterator it(baseDirectory, bfs::symlink_option::recurse);
|
||||
|
||||
for(; it != enddir; ++it)
|
||||
{
|
||||
EResType::Type type;
|
||||
|
||||
if (boost::filesystem::is_directory(it->status()))
|
||||
if (bfs::is_directory(it->status()))
|
||||
{
|
||||
path.resize(it.level()+1);
|
||||
path.back() = it->path().leaf().string();
|
||||
path.resize(it.level() + 1);
|
||||
path.back() = it->path().filename();
|
||||
// don't iterate into directory if depth limit reached
|
||||
it.no_push(depth <= it.level());
|
||||
|
||||
type = EResType::DIRECTORY;
|
||||
}
|
||||
else
|
||||
type = EResTypeHelper::getTypeFromExtension(boost::filesystem::extension(*it));
|
||||
type = EResTypeHelper::getTypeFromExtension(it->path().extension().string());
|
||||
|
||||
if (!initial || vstd::contains(initialTypes, type))
|
||||
{
|
||||
//reconstruct relative filename (not possible via boost AFAIK)
|
||||
std::string filename;
|
||||
for (size_t i=0; i<it.level() && i<path.size(); i++)
|
||||
filename += path[i] + '/';
|
||||
filename += it->path().leaf().string();
|
||||
bfs::path filename;
|
||||
const size_t iterations = std::min((size_t)it.level(), path.size());
|
||||
if (iterations)
|
||||
{
|
||||
filename = path.front();
|
||||
for (size_t i = 1; i < iterations; ++i)
|
||||
filename /= path[i];
|
||||
filename /= it->path().filename();
|
||||
}
|
||||
else
|
||||
filename = it->path().filename();
|
||||
|
||||
fileList[ResourceID(mountPoint + filename, type)] = filename;
|
||||
std::string resName;
|
||||
if (bfs::path::preferred_separator != '/')
|
||||
{
|
||||
// resource names are using UNIX slashes (/)
|
||||
resName.reserve(resName.size() + filename.native().size());
|
||||
resName = mountPoint;
|
||||
for (const char c : filename.string())
|
||||
if (c != bfs::path::preferred_separator)
|
||||
resName.push_back(c);
|
||||
else
|
||||
resName.push_back('/');
|
||||
}
|
||||
else
|
||||
resName = mountPoint + filename.string();
|
||||
|
||||
fileList[ResourceID(resName, type)] = std::move(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user