diff options
author | Max Horn | 2008-12-27 18:03:27 +0000 |
---|---|---|
committer | Max Horn | 2008-12-27 18:03:27 +0000 |
commit | 87a27477441ac9812406eb441465a5b9fddae85d (patch) | |
tree | 71d07df9a18ab186c8628e26136a723c983b222c /common/fs.h | |
parent | db1a4b478940677c5a8d9128a283b74ad1c49104 (diff) | |
download | scummvm-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.h | 136 |
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 |