aboutsummaryrefslogtreecommitdiff
path: root/common/fs.h
diff options
context:
space:
mode:
authorMax Horn2008-12-27 18:03:27 +0000
committerMax Horn2008-12-27 18:03:27 +0000
commit87a27477441ac9812406eb441465a5b9fddae85d (patch)
tree71d07df9a18ab186c8628e26136a723c983b222c /common/fs.h
parentdb1a4b478940677c5a8d9128a283b74ad1c49104 (diff)
downloadscummvm-rg350-87a27477441ac9812406eb441465a5b9fddae85d.tar.gz
scummvm-rg350-87a27477441ac9812406eb441465a5b9fddae85d.tar.bz2
scummvm-rg350-87a27477441ac9812406eb441465a5b9fddae85d.zip
Turned FSNode into a ArchiveMember subclass; removed the now obsolete FSDirectoryMember; moved FSDirectory from common/archive.h to common/fs.h
svn-id: r35578
Diffstat (limited to 'common/fs.h')
-rw-r--r--common/fs.h136
1 files changed, 126 insertions, 10 deletions
diff --git a/common/fs.h b/common/fs.h
index 310d24c4c5..29d6f667ca 100644
--- a/common/fs.h
+++ b/common/fs.h
@@ -26,6 +26,7 @@
#define COMMON_FS_H
#include "common/array.h"
+#include "common/archive.h"
#include "common/ptr.h"
#include "common/str.h"
@@ -42,7 +43,7 @@ class WriteStream;
* This is subclass instead of just a typedef so that we can use forward
* declarations of it in other places.
*/
-class FSList : public Common::Array<FSNode> {};
+class FSList : public Array<FSNode> {};
/**
* FSNode, short for "File System Node", provides an abstraction for file
@@ -54,9 +55,9 @@ class FSList : public Common::Array<FSNode> {};
* paths (and it's left to them whether / or \ or : is the path separator :-);
* but it is also possible to use inodes or vrefs (MacOS 9) or anything else.
*/
-class FSNode {
+class FSNode : public ArchiveMember {
private:
- Common::SharedPtr<AbstractFSNode> _realNode;
+ SharedPtr<AbstractFSNode> _realNode;
FSNode(AbstractFSNode *realNode);
public:
@@ -85,7 +86,7 @@ public:
* operating system doesn't support the concept), some other directory is
* used (usually the root directory).
*/
- explicit FSNode(const Common::String &path);
+ explicit FSNode(const String &path);
virtual ~FSNode() {}
@@ -119,7 +120,7 @@ public:
* @param name the name of a child of this directory
* @return the node referring to the child with the given name
*/
- FSNode getChild(const Common::String &name) const;
+ FSNode getChild(const String &name) const;
/**
* Return a list of all child nodes of this directory node. If called on a node
@@ -136,7 +137,7 @@ public:
*
* @return the display name
*/
- virtual Common::String getDisplayName() const;
+ virtual String getDisplayName() const;
/**
* Return a string representation of the name of the file. This is can be
@@ -146,7 +147,7 @@ public:
*
* @return the file name
*/
- virtual Common::String getName() const;
+ virtual String getName() const;
/**
* Return a string representation of the file which is suitable for
@@ -160,7 +161,7 @@ public:
*
* @return the 'path' represented by this filesystem node
*/
- virtual Common::String getPath() const;
+ virtual String getPath() const;
/**
* Get the parent node of this node. If this node has no parent node,
@@ -212,7 +213,7 @@ public:
*
* @return pointer to the stream object, 0 in case of a failure
*/
- virtual Common::SeekableReadStream *openForReading() const;
+ virtual SeekableReadStream *openForReading() const;
/**
* Creates a WriteStream instance corresponding to the file
@@ -221,9 +222,124 @@ public:
*
* @return pointer to the stream object, 0 in case of a failure
*/
- virtual Common::WriteStream *openForWriting() const;
+ virtual WriteStream *openForWriting() const;
+
+ // Compatibility with ArchiveMember API.
+ SeekableReadStream *open() {
+ return openForReading();
+ }
};
+/**
+ * FSDirectory models a directory tree from the filesystem and allows users
+ * to access it through the Archive interface. Searching is case-insensitive,
+ * since the intended goal is supporting retrieval of game data.
+ *
+ * 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
+ * backslashes, e.g.:
+ *
+ * c:\my\data\file.ext
+ *
+ * would be cached as 'data/file.ext' if FSDirectory was created on 'c:/my' with
+ * depth > 1. If depth was 1, then the 'data' subdirectory would have been
+ * ignored, instead.
+ * Again, only BACKSLASHES are used as separators independently from the
+ * underlying file system.
+ *
+ * Relative paths can be specified when calling matching functions like openFile(),
+ * hasFile(), listMatchingMembers() and listMembers(). Please see the function
+ * specific comments for more information.
+ *
+ * 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 backslash 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'.
+ *
+ */
+class FSDirectory : public Archive {
+ FSNode _node;
+
+ // Caches are case insensitive, clashes are dealt with when creating
+ // Key is stored in lowercase.
+ typedef HashMap<String, FSNode, IgnoreCase_Hash, IgnoreCase_EqualTo> NodeCache;
+ NodeCache _fileCache, _subDirCache;
+ String _prefix; // string that is prepended to each cache item key
+ void setPrefix(const String &prefix);
+
+ // look for a match
+ FSNode lookupCache(NodeCache &cache, const String &name);
+
+ // cache management
+ void cacheDirectoryRecursive(FSNode node, int depth, const String& prefix);
+ // fill cache if not already cached
+ void ensureCached();
+ bool _cached;
+ int _depth;
+
+public:
+ /**
+ * Create a FSDirectory representing a tree with the specified depth. Will result in an
+ * 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);
+
+ /**
+ * 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);
+
+ virtual ~FSDirectory();
+
+ /**
+ * This return the underlying FSNode of the FSDirectory.
+ */
+ FSNode getFSNode() const;
+
+ /**
+ * Create a new FSDirectory pointing to a sub directory of the instance. See class comment
+ * 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);
+
+ /**
+ * Checks for existence in the cache. A full match of relative path and filename is needed
+ * for success.
+ */
+ virtual bool hasFile(const String &name);
+
+ /**
+ * Returns a list of matching file names. Pattern can use GLOB wildcards.
+ */
+ virtual int listMatchingMembers(ArchiveMemberList &list, const String &pattern);
+
+ /**
+ * Returns a list of all the files in the cache.
+ */
+ virtual int listMembers(ArchiveMemberList &list);
+
+ /**
+ * Get a ArchiveMember representation of the specified file. A full match of relative
+ * path and filename is needed for success.
+ */
+ virtual ArchiveMemberPtr getMember(const String &name);
+
+ /**
+ * Open the specified file. A full match of relative path and filename is needed
+ * for success.
+ */
+ virtual SeekableReadStream *openFile(const String &name);
+};
+
+
} // End of namespace Common
#endif //COMMON_FS_H