diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/file.cpp | 4 | ||||
-rw-r--r-- | common/file.h | 5 | ||||
-rw-r--r-- | common/fs.cpp | 57 | ||||
-rw-r--r-- | common/fs.h | 65 |
4 files changed, 90 insertions, 41 deletions
diff --git a/common/file.cpp b/common/file.cpp index 30ac870f05..e70a9328cb 100644 --- a/common/file.cpp +++ b/common/file.cpp @@ -24,14 +24,10 @@ */ #include "common/file.h" -#include "common/fs.h" #include "common/hashmap.h" #include "common/util.h" #include "common/hash-str.h" - -#if defined(UNIX) || defined(__SYMBIAN32__) #include <errno.h> -#endif #ifdef MACOSX #include "CoreFoundation/CoreFoundation.h" diff --git a/common/file.h b/common/file.h index c18776a377..19b1d45144 100644 --- a/common/file.h +++ b/common/file.h @@ -30,6 +30,9 @@ #include "common/scummsys.h" #include "common/str.h" #include "common/stream.h" +#include "common/fs.h" +#include "backends/file/base-file.h" +//#include "backends/factories/fs-factory-maker.h" class FilesystemNode; @@ -38,7 +41,7 @@ namespace Common { class File : public SeekableReadStream, public WriteStream { protected: /** File handle to the actual file; 0 if no file is open. */ - //BaseFile *_test; + BaseFile *_test; /** File handle to the actual file; 0 if no file is open. */ void *_handle; diff --git a/common/fs.cpp b/common/fs.cpp index 40d9e4de14..442e3ed4d7 100644 --- a/common/fs.cpp +++ b/common/fs.cpp @@ -24,6 +24,7 @@ #include "common/stdafx.h" #include "common/util.h" +#include "common/fs.h" #include "backends/fs/abstract-fs.h" #include "backends/factories/fs-factory-maker.cpp" @@ -107,12 +108,13 @@ FilesystemNode &FilesystemNode::operator= (const FilesystemNode &node) { return *this; } -bool FilesystemNode::operator< (const FilesystemNode& node) const +bool FilesystemNode::operator<(const FilesystemNode& node) const { if (isDirectory() && !node.isDirectory()) return true; if (!isDirectory() && node.isDirectory()) return false; + return scumm_stricmp(getDisplayName().c_str(), node.getDisplayName().c_str()) < 0; } @@ -130,6 +132,7 @@ void FilesystemNode::decRefCount() { bool FilesystemNode::exists() const { if (_realNode == 0) return false; + return _realNode->exists(); } @@ -189,62 +192,78 @@ Common::String FilesystemNode::getPath() const { bool FilesystemNode::isDirectory() const { if (_realNode == 0) return false; + return _realNode->isDirectory(); } bool FilesystemNode::isReadable() const { if (_realNode == 0) return false; + return _realNode->isReadable(); } bool FilesystemNode::isWritable() const { if (_realNode == 0) 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); + int matches = 0; + + for (FSList::iterator entry = fslist.begin(); entry != fslist.end(); ++entry) { + if (entry->isDirectory()) { + matches += 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); + + return ((matches > 0) ? true : false); } bool FilesystemNode::lookupFile(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const { - lookupFileRec(results, dir, filename, hidden, exhaustive); + int matches; + + if (!dir.isDirectory()) + return false; + + matches = 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); + return ((matches > 0) ? true : false); } -void FilesystemNode::lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const +int FilesystemNode::lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const { FSList entries; + FSList children; + int matches = 0; 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); + //Breadth search (entries in the same level) + for (FSList::iterator entry = entries.begin(); entry != entries.end(); ++entry) { + if (entry->isDirectory()) { + children.push_back(*entry); } 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())) { + if(matchString(_realNode->getLastPathComponent(entry->getPath()), filename.c_str())) { results.push_back(*entry); + matches++; - if(!exhaustive) { + if (!exhaustive) break; - } } } } + + //Depth search (entries in lower levels) + for (FSList::iterator child = children.begin(); child != children.end(); ++child) { + matches += lookupFileRec(results, *child, filename, hidden, exhaustive); + } + + return matches; } diff --git a/common/fs.h b/common/fs.h index 6a2f049be1..7f634791d6 100644 --- a/common/fs.h +++ b/common/fs.h @@ -62,6 +62,8 @@ class FSList : public Common::Array<FilesystemNode> {}; * paths (MacOS 9 doesn't even have the notion of a "current directory"). * And if we ever want to support devices with no FS in the classical sense (Palm...), * we can build upon this. + * + * This class acts as a wrapper around the AbstractFilesystemNode class defined in backends/fs. */ class FilesystemNode { private: @@ -80,9 +82,9 @@ public: }; /** - * Create a new invalid FilesystemNode. In other words, isValid() for that - * node returns false, and if you try to get it's path, an assert is - * triggered. + * Create a new pathless FilesystemNode. Since there's no path associated + * with this node, path-related operations (i.e. exists(), isDirectory(), + * getPath()) will always return false or raise an assertion. */ FilesystemNode(); @@ -116,10 +118,12 @@ public: * Compare the name of this node to the name of another. Directories * go before normal files. */ - bool operator< (const FilesystemNode& node) const; + bool operator<(const FilesystemNode& node) const; /* - * Indicates whether the object refered by this path exists in the filesystem or not. + * Indicates whether the object referred by this path exists in the filesystem or not. + * + * @return bool true if the path exists, false otherwise. */ virtual bool exists() const; @@ -177,34 +181,53 @@ public: FilesystemNode getParent() const; /** - * Indicates whether this path refers to a directory or not. + * Indicates whether the path refers to a directory or not. * - * @todo Currently we assume that a valid node that is not a directory - * automatically is a file (ignoring things like symlinks). That might - * actually be OK... but we could still add an isFile method. Or even replace - * isValid and isDirectory by a getType() method that can return values like + * @todo Currently we assume that a node that is not a directory + * automatically is a file (ignoring things like symlinks or pipes). + * That might actually be OK... but we could still add an isFile method. + * Or even replace isDirectory by a getType() method that can return values like * kDirNodeType, kFileNodeType, kInvalidNodeType. */ virtual bool isDirectory() const; /** - * Indicates whether this path can be read from or not. + * Indicates whether the object referred by this path can be read from or not. + * + * If the path refers to a directory, readability implies being able to read + * and list the directory entries. + * + * If the path refers to a file, readability implies being able to read the + * contents of the file. + * + * @return bool true if the object can be read, false otherwise. */ virtual bool isReadable() const; /** - * Indicates whether this path can be written to or not. + * Indicates whether the object referred by this path can be written to or not. + * + * If the path refers to a directory, writability implies being able to modify + * the directory entry (i.e. rename the directory, remove it or write files inside of it). + * + * If the path refers to a file, writability implies being able to write data + * to the file. + * + * @return bool true if the object can be written to, false otherwise. */ virtual bool isWritable() const; /** * Searches recursively for a filename inside the given directories. * + * For each directory in the directory list a breadth-first search is performed, + * that is, the current directory entries are scanned before going into subdirectories. + * * @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 + * @param hidden Whether to search hidden files or not. + * @param exhaustive Whether to continue searching after one match has been found. * * @return true if matches could be found, false otherwise. */ @@ -213,11 +236,14 @@ public: /** * Searches recursively for a filename inside the given directory. * + * The search is performed breadth-first, that is, the current directory entries + * are scanned before going into subdirectories. + * * @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 + * @param hidden Whether to search hidden files or not. + * @param exhaustive Whether to continue searching after one match has been found. * * @return true if matches could be found, false otherwise. */ @@ -233,13 +259,18 @@ protected: /** * Searches recursively for a filename inside the given directory. * + * The search is performed breadth-first, that is, the current directory entries + * are scanned before going into subdirectories. + * * @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. + * + * @return The number of matches found. */ - void lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const; + int lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const; }; //} // End of namespace Common |