summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fios.cpp110
-rw-r--r--src/fios.h2
2 files changed, 72 insertions, 40 deletions
diff --git a/src/fios.cpp b/src/fios.cpp
index cdab45635..548efbfec 100644
--- a/src/fios.cpp
+++ b/src/fios.cpp
@@ -129,11 +129,7 @@ const char *FiosBrowseTo(const FiosItem *item)
case FIOS_TYPE_OLD_SCENARIO:
case FIOS_TYPE_PNG:
case FIOS_TYPE_BMP:
- {
- static char str_buffr[512];
- snprintf(str_buffr, lengthof(str_buffr), "%s%s", path, item->name);
- return str_buffr;
- }
+ return item->name;
}
return NULL;
@@ -192,11 +188,76 @@ bool FileExists(const char *filename)
typedef FiosType fios_getlist_callback_proc(SaveLoadDialogMode mode, const char *filename, const char *ext, char *title, const char *last);
-/** Create a list of the files in a directory, according to some arbitrary rule.
+/**
+ * Scanner to scan for a particular type of FIOS file.
+ */
+class FiosFileScanner : public FileScanner {
+ SaveLoadDialogMode mode; ///< The mode we want to search for
+ fios_getlist_callback_proc *callback_proc; ///< Callback to check whether the file may be added
+public:
+ /**
+ * Create the scanner
+ * @param mode The mode we are in. Some modes don't allow 'parent'.
+ * @param callback_proc The function that is called where you need to do the filtering.
+ */
+ FiosFileScanner(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc) :
+ mode(mode),
+ callback_proc(callback_proc)
+ {}
+
+ /* virtual */ bool AddFile(const char *filename, size_t basepath_length);
+};
+
+/**
+ * Try to add a fios item set with the given filename.
+ * @param filename the full path to the file to read
+ * @param basepath_length amount of characters to chop of before to get a relative filename
+ * @return true if the file is added.
+ */
+bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length)
+{
+ const char *ext = strrchr(filename, '.');
+ if (ext == NULL) return false;
+
+ char fios_title[64];
+ fios_title[0] = '\0'; // reset the title;
+
+ FiosType type = this->callback_proc(this->mode, filename, ext, fios_title, lastof(fios_title));
+ if (type == FIOS_TYPE_INVALID) return false;
+
+ for (const FiosItem *fios = _fios_items.Begin(); fios != _fios_items.End(); fios++) {
+ if (strcmp(fios->name, filename) == 0) return false;
+ }
+
+ FiosItem *fios = _fios_items.Append();
+ struct stat sb;
+ if (stat(filename, &sb) == 0) {
+ fios->mtime = sb.st_mtime;
+ } else {
+ fios->mtime = 0;
+ }
+
+ fios->type = type;
+ strecpy(fios->name, filename, lastof(fios->name));
+
+ /* If the file doesn't have a title, use it's filename */
+ const char *t = fios_title;
+ if (StrEmpty(fios_title)) {
+ t = strrchr(filename, PATHSEPCHAR);
+ t = (t == NULL) ? filename : (t + 1);
+ }
+ strecpy(fios->title, t, lastof(fios->title));
+ str_validate(fios->title);
+
+ return true;
+}
+
+
+/** Fill the list of the files in a directory, according to some arbitrary rule.
* @param mode The mode we are in. Some modes don't allow 'parent'.
* @param callback_proc The function that is called where you need to do the filtering.
- * @return Return the list of files. */
-static FiosItem *FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc)
+ */
+static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc)
{
struct stat sb;
struct dirent *dirent;
@@ -248,35 +309,8 @@ static FiosItem *FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_
sort_start = _fios_items.Length();
/* Show files */
- dir = ttd_opendir(_fios_path);
- if (dir != NULL) {
- while ((dirent = readdir(dir)) != NULL) {
- char fios_title[64];
- char *t;
- strecpy(d_name, FS2OTTD(dirent->d_name), lastof(d_name));
-
- if (!FiosIsValidFile(_fios_path, dirent, &sb) || !S_ISREG(sb.st_mode) || FiosIsHiddenFile(dirent)) continue;
-
- /* File has no extension, skip it */
- if ((t = strrchr(d_name, '.')) == NULL) continue;
- fios_title[0] = '\0'; // reset the title;
-
- FiosType type = callback_proc(mode, d_name, t, fios_title, lastof(fios_title));
- if (type != FIOS_TYPE_INVALID) {
- fios = _fios_items.Append();
- fios->mtime = sb.st_mtime;
- fios->type = type;
- strecpy(fios->name, d_name, lastof(fios->name));
-
- /* Some callbacks want to lookup the title of the file. Allow that.
- * If we just copy the title from the filename, strip the extension */
- t = (fios_title[0] == '\0') ? *t = '\0', d_name : fios_title;
- strecpy(fios->title, t, lastof(fios->title));
- str_validate(fios->title);
- }
- }
- closedir(dir);
- }
+ FiosFileScanner scanner(mode, callback_proc);
+ scanner.Scan(NULL, _fios_path, false);
qsort(_fios_items.Get(sort_start), _fios_items.Length() - sort_start, sizeof(FiosItem), compare_FiosItems);
@@ -284,8 +318,6 @@ static FiosItem *FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_
if (mode != SLD_NEW_GAME) FiosGetDrives();
_fios_items.Compact();
-
- return _fios_items.Begin();
}
/**
diff --git a/src/fios.h b/src/fios.h
index f119dd75c..4f6f98c58 100644
--- a/src/fios.h
+++ b/src/fios.h
@@ -62,7 +62,7 @@ struct FiosItem {
FiosType type;
uint64 mtime;
char title[64];
- char name[256 - 12 - 64];
+ char name[MAX_PATH];
};
/* Deals with the type of the savegame, independent of extension */