// usage: makeRelativePath("/path/to/my/thing.sfc", "/path/to") -> "./my/thing.sfc" // usage: makeRelativePath("/home/pi/my/thing.sfc", "/path/to", true) -> "~/my/thing.sfc" fs::path makeRelativePath(const fs::path& path, const fs::path& relativeTo, bool allowHome) { bool contains = false; fs::path ret = removeCommonPath(path, relativeTo, contains); if(contains) { // success ret = "." / ret; return ret; } if(allowHome) { contains = false; std::string homePath = getHomePath(); ret = removeCommonPath(path, homePath, contains); if(contains) { // success ret = "~" / ret; return ret; } } // nothing could be resolved return path; }
FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type, bool trustGamelist) { // first, verify that path is within the system's root folder FileData* root = system->getRootFolder(); fs::path relative; bool contains = false; if (trustGamelist) { relative = removeCommonPathUsingStrings(path, root->getPath(), contains); } else { relative = removeCommonPath(path, root->getPath(), contains); } if(!contains) { LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\""; return NULL; } auto path_it = relative.begin(); FileData* treeNode = root; bool found = false; while(path_it != relative.end()) { const std::unordered_map<std::string, FileData*>& children = treeNode->getChildrenByFilename(); std::string key = path_it->string(); found = children.find(key) != children.end(); if (found) { treeNode = children.at(key); } // this is the end if(path_it == --relative.end()) { if(found) return treeNode; if(type == FOLDER) { LOG(LogWarning) << "gameList: folder doesn't already exist, won't create"; return NULL; } FileData* file = new FileData(type, path, system); treeNode->addChild(file); return file; } if(!found) { // don't create folders unless it's leading up to a game // if type is a folder it's gonna be empty, so don't bother if(type == FOLDER) { LOG(LogWarning) << "gameList: folder doesn't already exist, won't create"; return NULL; } // create missing folder FileData* folder = new FileData(FOLDER, treeNode->getPath().stem() / *path_it, system); treeNode->addChild(folder); treeNode = folder; } path_it++; } return NULL; }
FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type) { // first, verify that path is within the system's root folder FileData* root = system->getRootFolder(); bool contains = false; fs::path relative = removeCommonPath(path, root->getPath(), contains); if(!contains) { LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\""; return NULL; } auto path_it = relative.begin(); FileData* treeNode = root; bool found = false; while(path_it != relative.end()) { const std::vector<FileData*>& children = treeNode->getChildren(); found = false; for(auto child_it = children.begin(); child_it != children.end(); child_it++) { if((*child_it)->getPath().filename() == *path_it) { treeNode = *child_it; found = true; break; } } // this is the end if(path_it == --relative.end()) { if(found) return treeNode; if(type == FOLDER) { LOG(LogWarning) << "gameList: folder doesn't already exist, won't create"; return NULL; } //LOG(LogInfo) << "File type" << type << " File path \"" << path << "System " << system; FileData* file = new FileData(type, path, system); treeNode->addChild(file); return file; } if(!found) { // don't create folders unless it's leading up to a game // if type is a folder it's gonna be empty, so don't bother if(type == FOLDER) { LOG(LogWarning) << "gameList: folder doesn't already exist, won't create"; return NULL; } // create missing folder FileData* folder = new FileData(FOLDER, treeNode->getPath().stem() / *path_it, system); treeNode->addChild(folder); treeNode = folder; } path_it++; } return NULL; }