aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2009-06-01 00:01:32 +0000
committerWillem Jan Palenstijn2009-06-01 00:01:32 +0000
commit6e382592702534bb530f5610f19f694d3b4e5429 (patch)
tree2ab7746b3970483790cb6ceca634427a3c6720cc
parent9c8c1cb080a72fd143ef6db50f1ab2fd27a6d009 (diff)
downloadscummvm-rg350-6e382592702534bb530f5610f19f694d3b4e5429.tar.gz
scummvm-rg350-6e382592702534bb530f5610f19f694d3b4e5429.tar.bz2
scummvm-rg350-6e382592702534bb530f5610f19f694d3b4e5429.zip
Add a 'flat' option to FSDirectory to allow searching recursively for files in subdirectories
svn-id: r41090
-rw-r--r--common/archive.cpp8
-rw-r--r--common/archive.h4
-rw-r--r--common/fs.cpp31
-rw-r--r--common/fs.h24
4 files changed, 39 insertions, 28 deletions
diff --git a/common/archive.cpp b/common/archive.cpp
index a39d78dd9e..86ae5b6795 100644
--- a/common/archive.cpp
+++ b/common/archive.cpp
@@ -111,16 +111,16 @@ void SearchSet::add(const String &name, Archive *archive, int priority, bool aut
}
-void SearchSet::addDirectory(const String &name, const String &directory, int priority, int depth) {
+void SearchSet::addDirectory(const String &name, const String &directory, int priority, int depth, bool flat) {
FSNode dir(directory);
- addDirectory(name, dir, priority, depth);
+ addDirectory(name, dir, priority, depth, flat);
}
-void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority, int depth) {
+void SearchSet::addDirectory(const String &name, const FSNode &dir, int priority, int depth, bool flat) {
if (!dir.exists() || !dir.isDirectory())
return;
- add(name, new FSDirectory(dir, depth), priority);
+ add(name, new FSDirectory(dir, depth, flat), priority);
}
diff --git a/common/archive.h b/common/archive.h
index 69e29a73f2..aa13d26d16 100644
--- a/common/archive.h
+++ b/common/archive.h
@@ -161,12 +161,12 @@ public:
/**
* Create and add a FSDirectory by name
*/
- void addDirectory(const String &name, const String &directory, int priority = 0, int depth = 1);
+ void addDirectory(const String &name, const String &directory, int priority = 0, int depth = 1, bool flat = false);
/**
* Create and add a FSDirectory by FSNode
*/
- void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1);
+ void addDirectory(const String &name, const FSNode &directory, int priority = 0, int depth = 1, bool flat = false);
/**
* Remove an archive from the searchable set.
diff --git a/common/fs.cpp b/common/fs.cpp
index 2f1347226f..742177ea4a 100644
--- a/common/fs.cpp
+++ b/common/fs.cpp
@@ -163,22 +163,22 @@ Common::WriteStream *FSNode::createWriteStream() const {
return _realNode->createWriteStream();
}
-FSDirectory::FSDirectory(const FSNode &node, int depth)
- : _node(node), _cached(false), _depth(depth) {
+FSDirectory::FSDirectory(const FSNode &node, int depth, bool flat)
+ : _node(node), _cached(false), _depth(depth), _flat(flat) {
}
-FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth)
- : _node(node), _cached(false), _depth(depth) {
+FSDirectory::FSDirectory(const String &prefix, const FSNode &node, int depth, bool flat)
+ : _node(node), _cached(false), _depth(depth), _flat(flat) {
setPrefix(prefix);
}
-FSDirectory::FSDirectory(const String &name, int depth)
- : _node(name), _cached(false), _depth(depth) {
+FSDirectory::FSDirectory(const String &name, int depth, bool flat)
+ : _node(name), _cached(false), _depth(depth), _flat(flat) {
}
-FSDirectory::FSDirectory(const String &prefix, const String &name, int depth)
- : _node(name), _cached(false), _depth(depth) {
+FSDirectory::FSDirectory(const String &prefix, const String &name, int depth, bool flat)
+ : _node(name), _cached(false), _depth(depth), _flat(flat) {
setPrefix(prefix);
}
@@ -248,11 +248,11 @@ SeekableReadStream *FSDirectory::createReadStreamForMember(const String &name) c
return stream;
}
-FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth) {
- return getSubDirectory(String::emptyString, name, depth);
+FSDirectory *FSDirectory::getSubDirectory(const String &name, int depth, bool flat) {
+ return getSubDirectory(String::emptyString, name, depth, flat);
}
-FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth) {
+FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &name, int depth, bool flat) {
if (name.empty() || !_node.isDirectory())
return 0;
@@ -260,7 +260,7 @@ FSDirectory *FSDirectory::getSubDirectory(const String &prefix, const String &na
if (!node)
return 0;
- return new FSDirectory(prefix, *node, depth);
+ return new FSDirectory(prefix, *node, depth, flat);
}
void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String& prefix) const {
@@ -280,10 +280,13 @@ void FSDirectory::cacheDirectoryRecursive(FSNode node, int depth, const String&
// since the hashmap is case insensitive, we need to check for clashes when caching
if (it->isDirectory()) {
- if (_subDirCache.contains(lowercaseName)) {
+ if (!_flat && _subDirCache.contains(lowercaseName)) {
warning("FSDirectory::cacheDirectory: name clash when building cache, ignoring sub-directory '%s'", name.c_str());
} else {
- cacheDirectoryRecursive(*it, depth - 1, lowercaseName + "/");
+ if (_subDirCache.contains(lowercaseName)) {
+ warning("FSDirectory::cacheDirectory: name clash when building subDirCache with subdirectory '%s'", name.c_str());
+ }
+ cacheDirectoryRecursive(*it, depth - 1, _flat ? prefix : lowercaseName + "/");
_subDirCache[lowercaseName] = *it;
}
} else {
diff --git a/common/fs.h b/common/fs.h
index 1dcd07b1cf..d0e3c23558 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -232,8 +232,8 @@ public:
*
* FSDirectory can represent a single directory, or a tree with specified depth,
* depending on the value passed to the 'depth' parameter in the constructors.
- * Filenames are cached with their relative path, with elements separated by
- * slashes, e.g.:
+ * In the default mode, filenames are cached with their relative path,
+ * with elements separated by slashes, e.g.:
*
* c:\my\data\file.ext
*
@@ -247,11 +247,16 @@ public:
* hasFile(), listMatchingMembers() and listMembers(). Please see the function
* specific comments for more information.
*
+ * If the 'flat' argument to the constructor is true, files in subdirectories
+ * are cached without the relative path, so in the example above
+ * c:\my\data\file.ext would be cached as file.ext.
+ *
* Client code can customize cache by using the constructors with the 'prefix'
* parameter. In this case, the prefix is prepended to each entry in the cache,
* and effectively treated as a 'virtual' parent subdirectory. FSDirectory adds
* a trailing slash to prefix if needed. Following on with the previous example
* and using 'your' as prefix, the cache entry would have been 'your/data/file.ext'.
+ * This is done both in non-flat and flat mode.
*
*/
class FSDirectory : public Archive {
@@ -266,6 +271,7 @@ class FSDirectory : public Archive {
mutable NodeCache _fileCache, _subDirCache;
mutable bool _cached;
mutable int _depth;
+ mutable bool _flat;
// look for a match
FSNode *lookupCache(NodeCache &cache, const String &name) const;
@@ -282,15 +288,17 @@ public:
* unbound FSDirectory if name is not found on the filesystem or if the node is not a
* valid directory.
*/
- FSDirectory(const String &name, int depth = 1);
- FSDirectory(const FSNode &node, int depth = 1);
+ FSDirectory(const String &name, int depth = 1, bool flat = false);
+ FSDirectory(const FSNode &node, int depth = 1, bool flat = false);
/**
* Create a FSDirectory representing a tree with the specified depth. The parameter
* prefix is prepended to the keys in the cache. See class comment.
*/
- FSDirectory(const String &prefix, const String &name, int depth = 1);
- FSDirectory(const String &prefix, const FSNode &node, int depth = 1);
+ FSDirectory(const String &prefix, const String &name, int depth = 1,
+ bool flat = false);
+ FSDirectory(const String &prefix, const FSNode &node, int depth = 1,
+ bool flat = false);
virtual ~FSDirectory();
@@ -304,8 +312,8 @@ public:
* for an explanation of the prefix parameter.
* @return a new FSDirectory instance
*/
- FSDirectory *getSubDirectory(const String &name, int depth = 1);
- FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1);
+ FSDirectory *getSubDirectory(const String &name, int depth = 1, bool flat = false);
+ FSDirectory *getSubDirectory(const String &prefix, const String &name, int depth = 1, bool flat = false);
/**
* Checks for existence in the cache. A full match of relative path and filename is needed