Codechange: Use directory_iterator in ScanPath.

Replaces use of custom ttd_opendir.
This commit is contained in:
Peter Nelson 2024-04-18 00:04:46 +01:00 committed by Peter Nelson
parent d7c547d0db
commit 42523379d9
3 changed files with 27 additions and 39 deletions

View File

@ -1134,12 +1134,13 @@ std::unique_ptr<char[]> ReadFileToMem(const std::string &filename, size_t &lenp,
* @param filename The filename to look in for the extension.
* @return True iff the extension is nullptr, or the filename ends with it.
*/
static bool MatchesExtension(const char *extension, const char *filename)
static bool MatchesExtension(std::string_view extension, const std::string &filename)
{
if (extension == nullptr) return true;
if (extension.empty()) return true;
if (filename.length() < extension.length()) return false;
const char *ext = strrchr(filename, extension[0]);
return ext != nullptr && StrEqualsIgnoreCase(ext, extension);
std::string_view filename_sv = filename; // String view to avoid making another copy of the substring.
return StrCompareIgnoreCase(extension, filename_sv.substr(filename_sv.length() - extension.length())) == 0;
}
/**
@ -1151,36 +1152,24 @@ static bool MatchesExtension(const char *extension, const char *filename)
* @param basepath_length from where in the path are we 'based' on the search path
* @param recursive whether to recursively search the sub directories
*/
static uint ScanPath(FileScanner *fs, const char *extension, const char *path, size_t basepath_length, bool recursive)
static uint ScanPath(FileScanner *fs, std::string_view extension, const std::filesystem::path &path, size_t basepath_length, bool recursive)
{
uint num = 0;
struct stat sb;
struct dirent *dirent;
DIR *dir;
if (path == nullptr || (dir = ttd_opendir(path)) == nullptr) return 0;
while ((dirent = readdir(dir)) != nullptr) {
std::string d_name = FS2OTTD(dirent->d_name);
if (!FiosIsValidFile(path, dirent, &sb)) continue;
std::string filename(path);
filename += d_name;
if (S_ISDIR(sb.st_mode)) {
/* Directory */
std::error_code error_code;
for (const auto &dir_entry : std::filesystem::directory_iterator(path, error_code)) {
if (dir_entry.is_directory()) {
if (!recursive) continue;
if (d_name == "." || d_name == "..") continue;
AppendPathSeparator(filename);
num += ScanPath(fs, extension, filename.c_str(), basepath_length, recursive);
} else if (S_ISREG(sb.st_mode)) {
/* File */
if (MatchesExtension(extension, filename.c_str()) && fs->AddFile(filename, basepath_length, {})) num++;
num += ScanPath(fs, extension, dir_entry.path(), basepath_length, recursive);
} else if (dir_entry.is_regular_file()) {
std::string file = FS2OTTD(dir_entry.path());
if (!MatchesExtension(extension, file)) continue;
if (fs->AddFile(file, basepath_length, {})) num++;
}
}
closedir(dir);
if (error_code) {
Debug(misc, 9, "Unable to read directory {}: {}", path.string(), error_code.message());
}
return num;
}
@ -1191,12 +1180,11 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s
* @param extension the extension of files to search for.
* @param tar the tar to search in.
*/
static uint ScanTar(FileScanner *fs, const char *extension, const TarFileList::value_type &tar)
static uint ScanTar(FileScanner *fs, std::string_view extension, const TarFileList::value_type &tar)
{
uint num = 0;
const auto &filename = tar.first;
if (MatchesExtension(extension, filename.c_str()) && fs->AddFile(filename, 0, tar.second.tar_filename)) num++;
if (MatchesExtension(extension, tar.first) && fs->AddFile(tar.first, 0, tar.second.tar_filename)) num++;
return num;
}
@ -1210,7 +1198,7 @@ static uint ScanTar(FileScanner *fs, const char *extension, const TarFileList::v
* @return the number of found files, i.e. the number of times that
* AddFile returned true.
*/
uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool recursive)
uint FileScanner::Scan(std::string_view extension, Subdirectory sd, bool tars, bool recursive)
{
this->subdir = sd;
@ -1221,7 +1209,7 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
std::string path = FioGetDirectory(sp, sd);
num += ScanPath(this, extension, path.c_str(), path.size(), recursive);
num += ScanPath(this, extension, OTTD2FS(path), path.size(), recursive);
}
if (tars && sd != NO_DIRECTORY) {
@ -1252,9 +1240,9 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
* @return the number of found files, i.e. the number of times that
* AddFile returned true.
*/
uint FileScanner::Scan(const char *extension, const std::string &directory, bool recursive)
uint FileScanner::Scan(const std::string_view extension, const std::string &directory, bool recursive)
{
std::string path(directory);
AppendPathSeparator(path);
return ScanPath(this, extension, path.c_str(), path.size(), recursive);
return ScanPath(this, extension, OTTD2FS(path), path.size(), recursive);
}

View File

@ -42,8 +42,8 @@ public:
/** Destruct the proper one... */
virtual ~FileScanner() = default;
uint Scan(const char *extension, Subdirectory sd, bool tars = true, bool recursive = true);
uint Scan(const char *extension, const std::string &directory, bool recursive = true);
uint Scan(std::string_view extension, Subdirectory sd, bool tars = true, bool recursive = true);
uint Scan(std::string_view extension, const std::string &directory, bool recursive = true);
/**
* Add a file with the given filename.

View File

@ -365,9 +365,9 @@ static void FiosGetFileList(SaveLoadOperation fop, bool show_dirs, FiosGetTypeAn
/* Show files */
FiosFileScanner scanner(fop, callback_proc, file_list);
if (subdir == NO_DIRECTORY) {
scanner.Scan(nullptr, *_fios_path, false);
scanner.Scan({}, *_fios_path, false);
} else {
scanner.Scan(nullptr, subdir, true, true);
scanner.Scan({}, subdir, true, true);
}
std::sort(file_list.begin() + sort_start, file_list.end());