aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/file.cpp4
-rw-r--r--common/file.h5
-rw-r--r--common/fs.cpp57
-rw-r--r--common/fs.h65
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