aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorMax Horn2006-06-24 08:07:48 +0000
committerMax Horn2006-06-24 08:07:48 +0000
commitd210b19aec69d34711e5d473e6e4e5081955b02e (patch)
tree3346e4ab55138bffc74c614faf862bcff10b896c /common
parent72a4747dd64461e4bca819f5a246c84518b7ff8d (diff)
downloadscummvm-rg350-d210b19aec69d34711e5d473e6e4e5081955b02e.tar.gz
scummvm-rg350-d210b19aec69d34711e5d473e6e4e5081955b02e.tar.bz2
scummvm-rg350-d210b19aec69d34711e5d473e6e4e5081955b02e.zip
Move backends/fs/fs.h and .cpp to common/fs/fs.h and .cpp
Rationale: backend implementations belong to backends/, but portable APIs meant to be used by high level code is for common / sound / graphics / ... (compare also with backends/midi vs. sound/mididrv.h) svn-id: r23274
Diffstat (limited to 'common')
-rw-r--r--common/file.cpp2
-rw-r--r--common/fs.cpp142
-rw-r--r--common/fs.h175
-rw-r--r--common/module.mk1
4 files changed, 319 insertions, 1 deletions
diff --git a/common/file.cpp b/common/file.cpp
index 075c821886..c71121b241 100644
--- a/common/file.cpp
+++ b/common/file.cpp
@@ -21,9 +21,9 @@
*/
#include "common/file.h"
+#include "common/fs.h"
#include "common/hashmap.h"
#include "common/util.h"
-#include "backends/fs/fs.h"
#ifdef MACOSX
#include "CoreFoundation/CoreFoundation.h"
diff --git a/common/fs.cpp b/common/fs.cpp
new file mode 100644
index 0000000000..3836dfc212
--- /dev/null
+++ b/common/fs.cpp
@@ -0,0 +1,142 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "common/stdafx.h"
+
+#include "backends/fs/abstract-fs.h"
+#include "common/util.h"
+
+
+FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) {
+ _realNode = realNode;
+ _refCount = new int(1);
+}
+
+FilesystemNode::FilesystemNode() {
+ _realNode = 0;
+ _refCount = 0;
+}
+
+FilesystemNode::FilesystemNode(const FilesystemNode &node) {
+ _realNode = node._realNode;
+ _refCount = node._refCount;
+ if (_refCount)
+ ++(*_refCount);
+}
+
+FilesystemNode::FilesystemNode(const Common::String &p) {
+ if (p.empty() || p == ".")
+ _realNode = AbstractFilesystemNode::getCurrentDirectory();
+ else
+ _realNode = AbstractFilesystemNode::getNodeForPath(p);
+ _refCount = new int(1);
+}
+
+FilesystemNode::~FilesystemNode() {
+ decRefCount();
+}
+
+void FilesystemNode::decRefCount() {
+ if (_refCount) {
+ assert(*_refCount > 0);
+ --(*_refCount);
+ if (*_refCount == 0) {
+ delete _refCount;
+ delete _realNode;
+ }
+ }
+}
+
+FilesystemNode &FilesystemNode::operator =(const FilesystemNode &node) {
+ if (node._refCount)
+ ++(*node._refCount);
+
+ decRefCount();
+
+ _realNode = node._realNode;
+ _refCount = node._refCount;
+
+ return *this;
+}
+
+FilesystemNode FilesystemNode::getParent() const {
+ if (_realNode == 0)
+ return *this;
+
+ AbstractFilesystemNode *node = _realNode->parent();
+ if (node == 0) {
+ return *this;
+ } else {
+ return FilesystemNode(node);
+ }
+}
+
+FilesystemNode FilesystemNode::getChild(const String &name) const {
+ if (_realNode == 0)
+ return *this;
+
+ assert(_realNode->isDirectory());
+ AbstractFilesystemNode *node = _realNode->child(name);
+ return FilesystemNode(node);
+}
+
+bool FilesystemNode::listDir(FSList &fslist, ListMode mode) const {
+ if (!_realNode || !_realNode->isDirectory())
+ return false;
+
+ AbstractFSList tmp;
+
+ if (!_realNode->listDir(tmp, mode))
+ return false;
+
+ fslist.clear();
+ for (AbstractFSList::iterator i = tmp.begin(); i != tmp.end(); ++i) {
+ fslist.push_back(FilesystemNode(*i));
+ }
+
+ return true;
+}
+
+Common::String FilesystemNode::displayName() const {
+ assert(_realNode);
+ return _realNode->displayName();
+}
+
+bool FilesystemNode::isDirectory() const {
+ if (_realNode == 0)
+ return false;
+ return _realNode->isDirectory();
+}
+
+Common::String FilesystemNode::path() const {
+ assert(_realNode);
+ return _realNode->path();
+}
+
+
+bool FilesystemNode::operator< (const FilesystemNode& node) const
+{
+ if (isDirectory() && !node.isDirectory())
+ return true;
+ if (!isDirectory() && node.isDirectory())
+ return false;
+ return scumm_stricmp(displayName().c_str(), node.displayName().c_str()) < 0;
+}
diff --git a/common/fs.h b/common/fs.h
new file mode 100644
index 0000000000..a79d710024
--- /dev/null
+++ b/common/fs.h
@@ -0,0 +1,175 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef COMMON_FS_H
+#define COMMON_FS_H
+
+#include "common/array.h"
+#include "common/str.h"
+
+//namespace Common {
+
+class FilesystemNode;
+class AbstractFilesystemNode;
+
+
+/**
+ * List of multiple file system nodes. E.g. the contents of a given directory.
+ * 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<FilesystemNode> {};
+
+
+/*
+ * FilesystemNode provides an abstraction for file pathes, allowing for portable
+ * file system browsing. To this ends, multiple or single roots have to be supported
+ * (compare Unix with a single root, Windows with multiple roots C:, D:, ...).
+ *
+ * To this end, we abstract away from paths; implementations can be based on
+ * 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.
+ *
+ * NOTE: Backends still have to provide a way to extract a path from a FSIntern
+ *
+ * You may ask now: "isn't this cheating? Why do we go through all this when we use
+ * a path in the end anyway?!?".
+ * Well, for once as long as we don't provide our own file open/read/write API, we
+ * still have to use fopen(). Since all our targets already support fopen(), it should
+ * be possible to get a fopen() compatible string for any file system node.
+ *
+ * Secondly, with this abstraction layer, we still avoid a lot of complications based on
+ * differences in FS roots, different path separators, or even systems with no real
+ * 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.
+ */
+class FilesystemNode {
+ typedef Common::String String;
+private:
+ AbstractFilesystemNode *_realNode;
+ int *_refCount;
+
+ FilesystemNode(AbstractFilesystemNode *realNode);
+
+public:
+ /**
+ * Flag to tell listDir() which kind of files to list.
+ */
+ enum ListMode {
+ kListFilesOnly = 1,
+ kListDirectoriesOnly = 2,
+ kListAll = 3
+ };
+
+ /**
+ * 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.
+ */
+ FilesystemNode();
+
+ /**
+ * Create a new FilesystemNode referring to the specified path. This is
+ * the counterpart to the path() method.
+ *
+ * If path is empty or equals ".", then a node representing the "current
+ * directory" will be created. If that is not possible (since e.g. the
+ * operating system doesn't support the concept), some other directory is
+ * used (usually the root directory).
+ */
+ FilesystemNode(const String &path);
+
+ /**
+ * Copy constructor.
+ */
+ FilesystemNode(const FilesystemNode &node);
+
+ /**
+ * Destructor.
+ */
+ virtual ~FilesystemNode();
+
+ /**
+ * Copy operator.
+ */
+ FilesystemNode &operator =(const FilesystemNode &node);
+
+ /**
+ * Get the parent node of this node. If this node has no parent node,
+ * then it returns a duplicate of this node.
+ */
+ FilesystemNode getParent() const;
+
+ /**
+ * Fetch a child node of this node, with the given name. Only valid for
+ * directory nodes (an assertion is triggered otherwise). If no no child
+ * node with the given name exists, an invalid node is returned.
+ */
+ FilesystemNode getChild(const String &name) const;
+
+ /**
+ * Return a list of child nodes of this directory node. If called on a node
+ * that does not represent a directory, false is returned.
+ * @return true if succesful, false otherwise (e.g. when the directory does not exist).
+ * @todo Rename this to listChildren or getChildren.
+ */
+ virtual bool listDir(FSList &fslist, ListMode mode = kListDirectoriesOnly) const;
+
+ /**
+ * Return a human readable string for this node, usable for display (e.g.
+ * in the GUI code). Do *not* rely on it being usable for anything else,
+ * like constructing paths!
+ * @return the display name
+ */
+ virtual String displayName() const;
+
+ /**
+ * Is this node pointing to a directory?
+ * @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
+ * kDirNodeType, kFileNodeType, kInvalidNodeType.
+ */
+ virtual bool isDirectory() const;
+
+ /**
+ * Return a string representation of the file which can be passed to fopen(),
+ * and is suitable for archiving (i.e. writing to the config file).
+ * This will usually be a 'path' (hence the name of the method), but can
+ * be anything that fulfilly the above criterions.
+ */
+ virtual String path() const;
+
+ /**
+ * Compare the name of this node to the name of another. Directories
+ * go before normal files.
+ */
+ bool operator< (const FilesystemNode& node) const;
+
+protected:
+ void decRefCount();
+};
+
+//} // End of namespace Common
+
+#endif
diff --git a/common/module.mk b/common/module.mk
index dc8048db64..9d1908f925 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
config-file.o \
config-manager.o \
file.o \
+ fs.o \
hashmap.o \
md5.o \
mutex.o \