void GetFileListRecursive(std::string dir, StringList& files, bool withQueriedDir /* = false */) { std::stack<std::string> stk; if(withQueriedDir) { stk.push(dir); while(stk.size()) { dir = stk.top(); stk.pop(); MakeSlashTerminated(dir); StringList li; GetFileList(dir.c_str(), li); for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it) files.push_back(dir + *it); li.clear(); GetDirList(dir.c_str(), li, true); for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it) stk.push(dir + *it); } } else { std::string topdir = dir; MakeSlashTerminated(topdir); stk.push(""); while(stk.size()) { dir = stk.top(); stk.pop(); MakeSlashTerminated(dir); StringList li; dir = topdir + dir; GetFileList(dir.c_str(), li); for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it) files.push_back(dir + *it); li.clear(); GetDirList(dir.c_str(), li, true); for(std::deque<std::string>::iterator it = li.begin(); it != li.end(); ++it) stk.push(dir + *it); } } }
void forEachDirectory(const char* basedir, const FileNameCallback& callback, std::size_t depth) { GSList* list = GetDirList(basedir, depth); for(GSList* i = list; i != 0; i = g_slist_next(i)) { callback(reinterpret_cast<const char*>((*i).data)); } ClearFileDirList(&list); }
void DiskDir::load() { _files.clear(); _subdirs.clear(); // TODO: cache existing files and keep them unless they do no longer exist StringList li; GetFileList(fullname(), li); for(StringList::iterator it = li.begin(); it != li.end(); ++it) { DiskFile *f = new DiskFile(joinPath(fullname(), it->c_str()).c_str()); _files[f->name()] = f; } li.clear(); GetDirList(fullname(), li, 0); for(StringList::iterator it = li.begin(); it != li.end(); ++it) { // GetDirList() returns relative paths, so need to join Dir *d = createNew(joinPath(fullname(), it->c_str()).c_str()); _subdirs[d->name()] = d; } }
// returns a list of directory names in the given directory, *without* the source dir. // if getting the dir list recursively, all paths are added, except *again* the top source dir beeing queried. void GetDirList(const char *path, StringList &dirs, bool recursive /* = false */) { #if !_WIN32 DIR * dirp; struct dirent * dp; dirp = opendir(path); if(dirp) { while((dp = readdir(dirp))) // assignment is intentional { if (_IsDir(path, dp)) // only add if it is a directory { if(strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) { dirs.push_back(dp->d_name); if (recursive) // needing a better way to do that { std::deque<std::string> newdirs; GetDirList(dp->d_name, newdirs, true); std::string d(dp->d_name); for(std::deque<std::string>::iterator it = newdirs.begin(); it != newdirs.end(); ++it) dirs.push_back(d + *it); } } } } closedir(dirp); } #else std::string search(path); MakeSlashTerminated(search); search += "*"; WIN32_FIND_DATA fil; HANDLE hFil = FindFirstFile(search.c_str(),&fil); if(hFil != INVALID_HANDLE_VALUE) { do { if( fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { if (!strcmp(fil.cFileName, ".") || !strcmp(fil.cFileName, "..")) continue; std::string d(fil.cFileName); dirs.push_back(d); if (recursive) // need a better way to do that { StringList newdirs; GetDirList(d.c_str(), newdirs, true); for(std::deque<std::string>::iterator it = newdirs.begin(); it != newdirs.end(); ++it) dirs.push_back(d + *it); } } } while(FindNextFile(hFil, &fil)); FindClose(hFil); } #endif }
GSList* getDirList(const char *basedir) { return GetDirList(basedir, 1); }