1
0
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:
Karol
2014-08-21 22:26:28 +02:00
parent 2da6d9e7dd
commit 958839668c
25 changed files with 359 additions and 191 deletions

View File

@ -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);
}
}