Status DeleteDirectory(const OsPath& path) { // note: we have to recursively empty the directory before it can // be deleted (required by Windows and POSIX rmdir()). CFileInfos files; DirectoryNames subdirectoryNames; RETURN_STATUS_IF_ERR(GetDirectoryEntries(path, &files, &subdirectoryNames)); // delete files for(size_t i = 0; i < files.size(); i++) { const OsPath pathname = path / files[i].Name(); errno = 0; if(wunlink(pathname) != 0) WARN_RETURN(StatusFromErrno()); } // recurse over subdirectoryNames for(size_t i = 0; i < subdirectoryNames.size(); i++) RETURN_STATUS_IF_ERR(DeleteDirectory(path / subdirectoryNames[i])); errno = 0; if(wrmdir(path) != 0) WARN_RETURN(StatusFromErrno()); return INFO::OK; }
void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const VfsPath& path) { //LOGMESSAGE("CTextureManager::RecurseDirectory(%s)", path.string8()); CTerrainPropertiesPtr props; // Load terrains.xml first, if it exists VfsPath pathname = path / "terrains.xml"; if (VfsFileExists(pathname)) props = GetPropertiesFromFile(parentProps, pathname); // No terrains.xml, or read failures -> use parent props (i.e. if (!props) { LOGMESSAGE("CTerrainTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", path.string8()); props = parentProps; } // Recurse once for each subdirectory DirectoryNames subdirectoryNames; (void)g_VFS->GetDirectoryEntries(path, 0, &subdirectoryNames); for (size_t i=0;i<subdirectoryNames.size();i++) { VfsPath subdirectoryPath = path / subdirectoryNames[i] / ""; RecurseDirectory(props, subdirectoryPath); } LoadTextures(props, path); }
/////////////////////////////////////////////////////////////////// // Generate list of available skies std::vector<CStrW> SkyManager::GetSkySets() const { std::vector<CStrW> skies; // Find all subdirectories in art/textures/skies const VfsPath path(L"art/textures/skies/"); DirectoryNames subdirectories; if(g_VFS->GetDirectoryEntries(path, 0, &subdirectories) < 0) { LOGERROR(L"Error opening directory '%ls'", path.string().c_str()); return std::vector<CStrW>(1, GetSkySet()); // just return what we currently have } for(size_t i = 0; i < subdirectories.size(); i++) skies.push_back(subdirectories[i].string()); sort(skies.begin(), skies.end()); return skies; }
Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags) { // (declare here to avoid reallocations) CFileInfos files; DirectoryNames subdirectoryNames; // (a FIFO queue is more efficient than recursion because it uses less // stack space and avoids seeks due to breadth-first traversal.) std::queue<VfsPath> pendingDirectories; pendingDirectories.push(startPath/""); while(!pendingDirectories.empty()) { const VfsPath& path = pendingDirectories.front(); RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, &subdirectoryNames)); for(size_t i = 0; i < files.size(); i++) { const CFileInfo fileInfo = files[i]; if(!match_wildcard(fileInfo.Name().string().c_str(), pattern)) continue; const VfsPath pathname(path / fileInfo.Name()); // (CFileInfo only stores the name) RETURN_STATUS_IF_ERR(cb(pathname, fileInfo, cbData)); } if(!(flags & DIR_RECURSIVE)) break; for(size_t i = 0; i < subdirectoryNames.size(); i++) pendingDirectories.push(path / subdirectoryNames[i]/""); pendingDirectories.pop(); } return INFO::OK; }