From 3623a94927a3d01b6df5c75f42af13a348327c2a Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 12 May 2006 21:41:54 +0000 Subject: Added the new AbstractFilesystemNode::getCurrentDirectory() method. Also changed the semantics of the FilesystemNode constructors (see also the relevant doxygen comments for explanations). This also fixes bug #1485941. svn-id: r22424 --- backends/fs/abstract-fs.h | 14 ++++++++++++++ backends/fs/amigaos4/amigaos4-fs.cpp | 8 ++++++-- backends/fs/fs.cpp | 36 +++++++++++++++++------------------- backends/fs/fs.h | 23 +++++++++++++++++++++-- backends/fs/morphos/abox-fs.cpp | 4 ++++ backends/fs/palmos/palmos-fs.cpp | 4 ++++ backends/fs/posix/posix-fs.cpp | 12 +++++++++--- backends/fs/ps2/ps2-fs.cpp | 10 +++++++--- backends/fs/symbian/symbian-fs.cpp | 4 ++++ backends/fs/windows/windows-fs.cpp | 4 ++++ backends/gp32/gp-fs.cpp | 12 ++++++++---- backends/psp/psp_fs.cpp | 8 ++++++-- 12 files changed, 104 insertions(+), 35 deletions(-) (limited to 'backends') diff --git a/backends/fs/abstract-fs.h b/backends/fs/abstract-fs.h index 8f6405763b..fb4f83216b 100644 --- a/backends/fs/abstract-fs.h +++ b/backends/fs/abstract-fs.h @@ -70,6 +70,15 @@ protected: */ static AbstractFilesystemNode *getRoot(); + /** + * Returns a node representing the "current directory". If your system does + * not support this concept, you can either try to emulate it or + * simply return some "sensible" default directory node, e.g. the same + * value as getRoot() returns. + */ + static AbstractFilesystemNode *getCurrentDirectory(); + + /** * Construct a node based on a path; the path is in the same format as it * would be for calls to fopen(). @@ -92,6 +101,11 @@ public: virtual String displayName() const = 0; virtual bool isDirectory() const = 0; + + /** + * Return the 'path' of the current node, usable in fopen(). See also + * the static getNodeForPath() method. + */ virtual String path() const = 0; virtual bool listDir(AbstractFSList &list, ListMode mode) const = 0; diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp index cc7220c9b1..e4eca97713 100644 --- a/backends/fs/amigaos4/amigaos4-fs.cpp +++ b/backends/fs/amigaos4/amigaos4-fs.cpp @@ -70,11 +70,15 @@ class AmigaOSFilesystemNode : public AbstractFilesystemNode { virtual String path() const { return _sPath; }; virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFSList listVolumes(void) const; + virtual AbstractFSList listVolumes() const; virtual AbstractFilesystemNode *parent() const; virtual AbstractFilesystemNode *child(const String &name) const; }; +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new AmigaOSFilesystemNode(); } @@ -333,7 +337,7 @@ AbstractFilesystemNode *AmigaOSFilesystemNode::child(const String &name) const { return new AmigaOSFilesystemNode(newPath); } -AbstractFSList AmigaOSFilesystemNode::listVolumes(void) const { +AbstractFSList AmigaOSFilesystemNode::listVolumes() const { ENTER(); AbstractFSList myList; diff --git a/backends/fs/fs.cpp b/backends/fs/fs.cpp index ca0ac2d7d7..2daa362196 100644 --- a/backends/fs/fs.cpp +++ b/backends/fs/fs.cpp @@ -26,33 +26,28 @@ #include "common/util.h" -static AbstractFilesystemNode *_rootNode = 0; -static int *_rootRefCount = 0; - FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) { _realNode = realNode; _refCount = new int(1); } FilesystemNode::FilesystemNode() { - if (_rootNode == 0) { - _rootNode = AbstractFilesystemNode::getRoot(); - assert(_rootNode); - _rootRefCount = new int(1); - } - _realNode = _rootNode; - _refCount = _rootRefCount; - ++(*_refCount); + _realNode = 0; + _refCount = 0; } FilesystemNode::FilesystemNode(const FilesystemNode &node) { _realNode = node._realNode; _refCount = node._refCount; - ++(*_refCount); + if (_refCount) + ++(*_refCount); } FilesystemNode::FilesystemNode(const Common::String &p) { - _realNode = AbstractFilesystemNode::getNodeForPath(p); + if (p.empty() || p == ".") + _realNode = AbstractFilesystemNode::getCurrentDirectory(); + else + _realNode = AbstractFilesystemNode::getNodeForPath(p); _refCount = new int(1); } @@ -61,16 +56,19 @@ FilesystemNode::~FilesystemNode() { } void FilesystemNode::decRefCount() { - assert(*_refCount > 0); - --(*_refCount); - if (*_refCount == 0) { - delete _refCount; - delete _realNode; + if (_refCount) { + assert(*_refCount > 0); + --(*_refCount); + if (*_refCount == 0) { + delete _refCount; + delete _realNode; + } } } FilesystemNode &FilesystemNode::operator =(const FilesystemNode &node) { - ++(*node._refCount); + if (node._refCount) + ++(*node._refCount); decRefCount(); diff --git a/backends/fs/fs.h b/backends/fs/fs.h index f272cb2164..0e271b5fc9 100644 --- a/backends/fs/fs.h +++ b/backends/fs/fs.h @@ -78,18 +78,37 @@ public: 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); - - FilesystemNode(); + /** + * Copy constructor. + */ FilesystemNode(const FilesystemNode &node); + + /** + * Destructor. + */ virtual ~FilesystemNode(); + /** + * Copy operator. + */ FilesystemNode &operator =(const FilesystemNode &node); /** diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp index 38e84b2547..a51a683773 100644 --- a/backends/fs/morphos/abox-fs.cpp +++ b/backends/fs/morphos/abox-fs.cpp @@ -58,6 +58,10 @@ class ABoxFilesystemNode : public AbstractFilesystemNode { }; +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new ABoxFilesystemNode(); diff --git a/backends/fs/palmos/palmos-fs.cpp b/backends/fs/palmos/palmos-fs.cpp index 20480e9a14..709dddb7d0 100644 --- a/backends/fs/palmos/palmos-fs.cpp +++ b/backends/fs/palmos/palmos-fs.cpp @@ -78,6 +78,10 @@ void PalmOSFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const ch list.push_back(new PalmOSFilesystemNode(entry)); } +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new PalmOSFilesystemNode(); } diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index ea874c9d0e..c0914bdb43 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -50,7 +50,7 @@ protected: public: POSIXFilesystemNode(); - POSIXFilesystemNode(const String &path, bool verify = false); + POSIXFilesystemNode(const String &path, bool verify); virtual String displayName() const { return _displayName; } virtual bool isValid() const { return _isValid; } @@ -74,6 +74,12 @@ static const char *lastPathComponent(const Common::String &str) { return cur + 1; } +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + char buf[MAXPATHLEN]; + getcwd(buf, MAXPATHLEN); + return new POSIXFilesystemNode(buf, true); +} + AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new POSIXFilesystemNode(); } @@ -156,7 +162,7 @@ bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { newPath += '/'; newPath += dp->d_name; - POSIXFilesystemNode entry(newPath); + POSIXFilesystemNode entry(newPath, false); #ifdef __DC__ entry._isDirectory = dp->d_size < 0; @@ -212,7 +218,7 @@ AbstractFilesystemNode *POSIXFilesystemNode::parent() const { const char *start = _path.c_str(); const char *end = lastPathComponent(_path); - POSIXFilesystemNode *p = new POSIXFilesystemNode(String(start, end - start)); + POSIXFilesystemNode *p = new POSIXFilesystemNode(String(start, end - start), false); return p; } diff --git a/backends/fs/ps2/ps2-fs.cpp b/backends/fs/ps2/ps2-fs.cpp index 7370c3393e..0286a72831 100644 --- a/backends/fs/ps2/ps2-fs.cpp +++ b/backends/fs/ps2/ps2-fs.cpp @@ -37,7 +37,7 @@ protected: String _path; public: - Ps2FilesystemNode(void); + Ps2FilesystemNode(); Ps2FilesystemNode(const String &path); virtual String displayName() const { return _displayName; } @@ -52,7 +52,11 @@ public: virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); } }; -AbstractFilesystemNode *AbstractFilesystemNode::getRoot(void) { +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + +AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new Ps2FilesystemNode(); } @@ -60,7 +64,7 @@ AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &pat return new Ps2FilesystemNode(path); } -Ps2FilesystemNode::Ps2FilesystemNode(void) { +Ps2FilesystemNode::Ps2FilesystemNode() { _isDirectory = true; _isRoot = true; _displayName = "CD Root"; diff --git a/backends/fs/symbian/symbian-fs.cpp b/backends/fs/symbian/symbian-fs.cpp index e73c4d4489..6be8302f98 100644 --- a/backends/fs/symbian/symbian-fs.cpp +++ b/backends/fs/symbian/symbian-fs.cpp @@ -69,6 +69,10 @@ static const char *lastPathComponent(const Common::String &str) { return cur + 1; } +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new SymbianFilesystemNode(true); } diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp index 13ed68878c..2eebcee963 100644 --- a/backends/fs/windows/windows-fs.cpp +++ b/backends/fs/windows/windows-fs.cpp @@ -120,6 +120,10 @@ void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const c list.push_back(new WindowsFilesystemNode(entry)); } +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new WindowsFilesystemNode(); } diff --git a/backends/gp32/gp-fs.cpp b/backends/gp32/gp-fs.cpp index df056c570e..8dfa1e8c03 100644 --- a/backends/gp32/gp-fs.cpp +++ b/backends/gp32/gp-fs.cpp @@ -36,7 +36,7 @@ protected: String _path; public: - GP32FilesystemNode(void); + GP32FilesystemNode(); GP32FilesystemNode(const String &path); virtual String displayName() const { return _displayName; } @@ -48,15 +48,19 @@ public: virtual AbstractFilesystemNode *parent() const; }; -AbstractFilesystemNode *FilesystemNode::getRoot(void) { +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + +AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new GP32FilesystemNode(); } -AbstractFilesystemNode *FilesystemNode::getNodeForPath(const String &path) { +AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { return new GP32FilesystemNode(path); } -GP32FilesystemNode::GP32FilesystemNode(void) { +GP32FilesystemNode::GP32FilesystemNode() { _isDirectory = true; _isRoot = true; _displayName = "GP32 Root"; diff --git a/backends/psp/psp_fs.cpp b/backends/psp/psp_fs.cpp index 2d2a3078c2..702f18a30d 100644 --- a/backends/psp/psp_fs.cpp +++ b/backends/psp/psp_fs.cpp @@ -55,7 +55,11 @@ public: virtual AbstractFilesystemNode *parent() const; }; -AbstractFilesystemNode *FilesystemNode::getRoot() { +AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { + return AbstractFilesystemNode::getRoot(); +} + +AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { return new PSPFilesystemNode(); } @@ -76,7 +80,7 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p) } -AbstractFilesystemNode *FilesystemNode::getNodeForPath(const String &path) +AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { return new PSPFilesystemNode(path); } -- cgit v1.2.3