void Directory::VisitSpecificFiles(Path path, const TCHAR* filter, File::Visitor &visitor, bool recursive) { ScanDirectories(visitor, recursive, path, filter); }
static bool ScanDirectories(File::Visitor &visitor, bool recursive, Path sPath, const TCHAR* filter = _T("*")) { #ifdef HAVE_POSIX DIR *dir = opendir(sPath.c_str()); if (dir == nullptr) return false; TCHAR FileName[MAX_PATH]; _tcscpy(FileName, sPath.c_str()); size_t FileNameLength = _tcslen(FileName); FileName[FileNameLength++] = '/'; struct dirent *ent; while ((ent = readdir(dir)) != nullptr) { // omit '.', '..' and any other files/directories starting with '.' if (*ent->d_name == _T('.')) continue; _tcscpy(FileName + FileNameLength, ent->d_name); struct stat st; if (stat(FileName, &st) < 0) continue; if (S_ISDIR(st.st_mode) && recursive) ScanDirectories(visitor, true, Path(FileName), filter); else { int flags = 0; #ifdef FNM_CASEFOLD flags = FNM_CASEFOLD; #endif if (S_ISREG(st.st_mode) && fnmatch(filter, ent->d_name, flags) == 0) visitor.Visit(Path(FileName), Path(ent->d_name)); } } closedir(dir); #else /* !HAVE_POSIX */ TCHAR DirPath[MAX_PATH]; TCHAR FileName[MAX_PATH]; if (sPath != nullptr) { // e.g. "/test/data/something" _tcscpy(DirPath, sPath.c_str()); _tcscpy(FileName, sPath.c_str()); } else { DirPath[0] = 0; FileName[0] = 0; } // Scan for files in "/test/data/something" ScanFiles(visitor, Path(FileName), filter); // If we are not scanning recursive we are done now if (!recursive) return true; // "test/data/something/" _tcscat(DirPath, _T(DIR_SEPARATOR_S)); // "test/data/something/*" _tcscat(FileName, _T(DIR_SEPARATOR_S "*")); // Find the first file WIN32_FIND_DATA FindFileData; HANDLE hFind = FindFirstFile(FileName, &FindFileData); // If no file found -> return false if (hFind == INVALID_HANDLE_VALUE) return false; // Loop through remaining files while (true) { if (!IsDots(FindFileData.cFileName) && (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // "test/data/something/" _tcscpy(FileName, DirPath); // "test/data/something/SUBFOLDER" _tcscat(FileName, FindFileData.cFileName); // Scan subfolder for matching files too ScanDirectories(visitor, true, Path(FileName), filter); } // Look for next file/folder if (!FindNextFile(hFind, &FindFileData)) { if (GetLastError() == ERROR_NO_MORE_FILES) // No more files/folders // -> Jump out of the loop break; else { // Some error occured // -> Close the handle and return false FindClose(hFind); return false; } } } // Close the file handle FindClose(hFind); #endif /* !HAVE_POSIX */ return true; }
void Directory::VisitFiles(Path path, File::Visitor &visitor, bool recursive) { ScanDirectories(visitor, recursive, path); }
void Directory::VisitFiles(const TCHAR* path, File::Visitor &visitor, bool recursive) { ScanDirectories(visitor, recursive, path); }