#include "StdInc.h" #include "CFilesystemLoader.h" #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), fileList(listFiles(mountPoint, depth, initial)) { logGlobal->traceStream() << "Filesystem loaded, " << fileList.size() << " files found"; } std::unique_ptr CFilesystemLoader::load(const ResourceID & resourceName) const { assert(fileList.count(resourceName)); std::unique_ptr stream(new CFileInputStream(baseDirectory + '/' + fileList.at(resourceName))); return stream; } bool CFilesystemLoader::existsResource(const ResourceID & resourceName) const { return fileList.count(resourceName); } std::string CFilesystemLoader::getMountPoint() const { return mountPoint; } boost::optional CFilesystemLoader::getResourceName(const ResourceID & resourceName) const { assert(existsResource(resourceName)); return baseDirectory + '/' + fileList.at(resourceName); } std::unordered_set CFilesystemLoader::getFilteredFiles(std::function filter) const { std::unordered_set foundID; for (auto & file : fileList) { if (filter(file.first)) foundID.insert(file.first); } return foundID; } bool CFilesystemLoader::createResource(std::string filename, bool update) { ResourceID resID(filename); if (fileList.find(resID) != fileList.end()) return true; if (!boost::iequals(mountPoint, filename.substr(0, mountPoint.size()))) { logGlobal->traceStream() << "Can't create file: wrong mount point: " << mountPoint; return false; } filename = filename.substr(mountPoint.size()); if (!update) { std::ofstream newfile (baseDirectory + "/" + filename); if (!newfile.good()) return false; } fileList[resID] = filename; return true; } std::unordered_map CFilesystemLoader::listFiles(const std::string &mountPoint, size_t depth, bool initial) const { std::set 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); assert(boost::filesystem::is_directory(baseDirectory)); std::unordered_map fileList; std::vector 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); for(; it != enddir; ++it) { EResType::Type type; if (boost::filesystem::is_directory(it->status())) { path.resize(it.level()+1); path.back() = it->path().leaf().string(); // 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)); if (!initial || vstd::contains(initialTypes, type)) { //reconstruct relative filename (not possible via boost AFAIK) std::string filename; for (size_t i=0; ipath().leaf().string(); fileList[ResourceID(mountPoint + filename, type)] = filename; } } return fileList; }