From 0ac96302fe9c04df79cb01a77d19535b45fe2db0 Mon Sep 17 00:00:00 2001 From: David Corrales Date: Wed, 20 Jun 2007 00:28:04 +0000 Subject: Initial implementation of the lookupFile() function. It's meant to search recursively for given filename within a set of directories. svn-id: r27551 --- common/fs.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/fs.h | 37 +++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) (limited to 'common') diff --git a/common/fs.cpp b/common/fs.cpp index 6eaa35e67f..28f3e11f0b 100644 --- a/common/fs.cpp +++ b/common/fs.cpp @@ -27,6 +27,43 @@ #include "backends/fs/abstract-fs.h" #include "backends/fs/fs-factory-maker.cpp" +/* + * Simple DOS-style pattern matching function (understands * and ? like used in DOS). + * Taken from exult/files/listfiles.cc + */ +static bool matchString(const char *str, const char *pat) { + const char *p = 0; + const char *q = 0; + + for (;;) { + switch (*pat) { + case '*': + p = ++pat; + q = str; + break; + + default: + if (*pat != *str) { + if (p) { + pat = p; + str = ++q; + if(!*str) + return !*pat; + break; + } + else + return false; + } + // fallthrough + case '?': + if(!*str) + return !*pat; + pat++; + str++; + } + } +} + FilesystemNode::FilesystemNode() { _realNode = 0; _refCount = 0; @@ -166,3 +203,48 @@ bool FilesystemNode::isWritable() const { return false; return _realNode->isWritable(); } + +bool FilesystemNode::lookupFile(FSList &results, FSList &fslist, Common::String &filename, bool hidden, bool exhaustive) const +{ + for(FSList::iterator entry = fslist.begin(); entry != fslist.end(); ++entry) + { + if(entry->isDirectory()) { + lookupFileRec(results, *entry, filename, hidden, exhaustive); + } + } + + //TODO: we would return true even if no matches were found, if the initial results list isn't empty + return ((results.size() > 0) ? true : false); +} + +bool FilesystemNode::lookupFile(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const +{ + lookupFileRec(results, dir, filename, hidden, exhaustive); + + //TODO: we would return true even if no matches were found, if the initial results list isn't empty + return ((results.size() > 0) ? true : false); +} + +void FilesystemNode::lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const +{ + FSList entries; + dir.getChildren(entries, FilesystemNode::kListAll, hidden); + + for(FSList::iterator entry = entries.begin(); entry != entries.end(); ++entry) + { + if(entry->isDirectory()) { + lookupFileRec(results, *entry, filename, hidden, exhaustive); + } else { + //TODO: here we assume all backends implement the lastPathComponent method. It is currently static, + // so it might be a good idea to include it inside the backend class. This would enforce its + // implementation by all ports. + if(matchString(lastPathComponent(entry->getPath()), filename.c_str())) { + results.push_back(*entry); + + if(!exhaustive) { + break; + } + } + } + } +} diff --git a/common/fs.h b/common/fs.h index 7291fb75fc..6a2f049be1 100644 --- a/common/fs.h +++ b/common/fs.h @@ -196,6 +196,32 @@ public: * Indicates whether this path can be written to or not. */ virtual bool isWritable() const; + + /** + * Searches recursively for a filename inside the given directories. + * + * @param results List to put the matches in. + * @param fslist List of directories to search within. + * @param filename Name of the file to look for. + * @param hidden Whether to search hidden files or not. Default: false + * @param exhaustive Whether to continue searching after one match has been found. Default: false + * + * @return true if matches could be found, false otherwise. + */ + virtual bool lookupFile(FSList &results, FSList &fslist, Common::String &filename, bool hidden, bool exhaustive) const; + + /** + * Searches recursively for a filename inside the given directory. + * + * @param results List to put the matches in. + * @param FilesystemNode Directory to search within. + * @param filename Name of the file to look for. + * @param hidden Whether to search hidden files or not. Default: false + * @param exhaustive Whether to continue searching after one match has been found. Default: false + * + * @return true if matches could be found, false otherwise. + */ + virtual bool lookupFile(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const; protected: /** @@ -203,6 +229,17 @@ protected: * deletes the corresponding underlying references. */ void decRefCount(); + + /** + * Searches recursively for a filename inside the given directory. + * + * @param results List to put the matches in. + * @param FilesystemNode Directory to search within. + * @param filename Name of the file to look for. + * @param hidden Whether to search hidden files or not. + * @param exhaustive Whether to continue searching after one match has been found. + */ + void lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const; }; //} // End of namespace Common -- cgit v1.2.3