[Scummvm-cvs-logs] CVS: scummvm/backends/fs .cvsignore,NONE,1.1 fs.cpp,NONE,1.1 fs.h,1.21,1.22

Max Horn fingolfin at users.sourceforge.net
Sat Nov 20 13:36:17 CET 2004


Update of /cvsroot/scummvm/scummvm/backends/fs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32450/backends/fs

Modified Files:
	fs.h 
Added Files:
	.cvsignore fs.cpp 
Log Message:
Changed the FilesystemNode implementation to make it easier to use (client code doesn't have to worry about the memory managment anymore, it's all 'automatic' now). May have introduced a mem leak or two, please check :-)

--- NEW FILE: .cvsignore ---
.deps

--- NEW FILE: fs.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2002-2004 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/backends/fs/fs.cpp,v 1.1 2004/11/20 21:35:48 fingolfin Exp $
 */

#include "stdafx.h"

#include "fs.h"

FilesystemNode AbstractFilesystemNode::wrap(AbstractFilesystemNode *node) {
	FilesystemNode wrapper;
	wrapper._realNode = node;
	return wrapper;
}


FilesystemNode::FilesystemNode() {
	_realNode = getRoot();
	_refCount = new int(1);
}

FilesystemNode::FilesystemNode(const FilesystemNode &node)
	: AbstractFilesystemNode() {
	_realNode = node._realNode;
	_refCount = node._refCount;
	++(*_refCount);
}

#ifdef MACOSX
FilesystemNode::FilesystemNode(const String &p) {
	_realNode = getNodeForPath(p);
	_refCount = new int(1);
}
#endif

FilesystemNode::~FilesystemNode() {
	decRefCount();
}

void FilesystemNode::decRefCount() {
	--(*_refCount);
	if (*_refCount <= 0) {
		delete _refCount;
		delete _realNode;
	}
}

FilesystemNode &FilesystemNode::operator  =(const FilesystemNode &node) {
	++(*node._refCount);

	decRefCount();

	_realNode = node._realNode;
	_refCount = node._refCount;

	return *this;
}

FilesystemNode FilesystemNode::getParent() const {
	FilesystemNode wrapper;
	wrapper._realNode = _realNode->parent();
	return wrapper;
}

Index: fs.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/fs/fs.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- fs.h	21 Jul 2004 14:27:45 -0000	1.21
+++ fs.h	20 Nov 2004 21:35:48 -0000	1.22
@@ -58,15 +58,40 @@
 #include "common/array.h"
 #include "common/str.h"
 
-class FSList;
+class FilesystemNode;
+
+
+/**
+ * List of multiple file system nodes. E.g. the contents of a given directory.
+ */
+class FSList : public Common::Array<FilesystemNode> {
+};
+
 
 /**
  * File system node.
  */
-class FilesystemNode {
+class AbstractFilesystemNode {
 protected:
+	friend class FilesystemNode;
 	typedef Common::String String;
 
+	/**
+	 * The parent node of this directory.
+	 * The parent of the root is the root itself.
+	 */
+	virtual AbstractFilesystemNode *parent() const = 0;
+
+	/**
+	 * This method is a rather ugly hack which is used internally by the 
+	 * actual node implementions to wrap up raw nodes inside FilesystemNode
+	 * objects. We probably want to get rid of this eventually and replace it
+	 * with a cleaner / more elegant solution, but for now it works.
+	 * @note This takes over ownership of node. Do not delete it yourself,
+	 *       else you'll get ugly crashes. You've been warned!
+	 */
+	static FilesystemNode wrap(AbstractFilesystemNode *node);
+
 public:
 
 	/**
@@ -78,25 +103,7 @@
 		kListAll = 3
 	} ListMode;
 
-	/**
-	 * Returns a special node representing the FS root. The starting point for
-	 * any file system browsing.
-	 * On Unix, this will be simply the node for / (the root directory).
-	 * On Windows, it will be a special node which "contains" all drives (C:, D:, E:).
-	 */
-	static FilesystemNode *getRoot();
-
-#ifdef MACOSX
-	/*
-	 * Construct a node based on a path; the path is in the same format as it
-	 * would be for calls to fopen().
-	 *
-	 * I.e. getNodeForPath(oldNode.path()) should create a new node identical to oldNode.
-	 */
-	static FilesystemNode *getNodeForPath(const String &path);
-#endif
-
-	virtual ~FilesystemNode() {}
+	virtual ~AbstractFilesystemNode() {}
 
 	/**
 	 * Return display name, used by e.g. the GUI to present the file in the file browser.
@@ -123,78 +130,69 @@
 	 * List the content of this directory node.
 	 * If this node is not a directory, throw an exception or call error().
 	 */
-	virtual FSList *listDir(ListMode mode = kListDirectoriesOnly) const = 0;
-
-	/**
-	 * The parent node of this directory.
-	 * The parent of the root is the root itself
-	 */
-	virtual FilesystemNode *parent() const = 0;
+	virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const = 0;
 
 	/**
-	 * Return a clone of this node allocated with new().
-	 */
-	virtual FilesystemNode *clone() const = 0;
-	
-	/**
 	 * Compare the name of this node to the name of another.
 	 */
-	virtual bool operator< (const FilesystemNode& node) const
+	virtual bool operator< (const AbstractFilesystemNode& node) const
 	{
 		return scumm_stricmp(displayName().c_str(), node.displayName().c_str()) < 0;
 	}
 };
 
+class FilesystemNode : public AbstractFilesystemNode {
+	friend class AbstractFilesystemNode;
+
+	typedef Common::String String;
+private:
+	AbstractFilesystemNode *_realNode;
+	int *_refCount;
+
+	/**
+	 * Returns a special node representing the FS root. The starting point for
+	 * any file system browsing.
+	 * On Unix, this will be simply the node for / (the root directory).
+	 * On Windows, it will be a special node which "contains" all drives (C:, D:, E:).
+	 */
+	static AbstractFilesystemNode *getRoot();
+
+#ifdef MACOSX
+	/*
+	 * Construct a node based on a path; the path is in the same format as it
+	 * would be for calls to fopen().
+	 *
+	 * I.e. getNodeForPath(oldNode.path()) should create a new node identical to oldNode.
+	 */
+	static AbstractFilesystemNode *getNodeForPath(const String &path);
+#endif
+
 
-/**
- * Sorted list of multiple file system nodes. E.g. the contents of a given directory.
- */
-class FSList : private Common::Array<FilesystemNode *> {
 public:
-	class const_iterator {
-		friend class FSList;
-		FilesystemNode **_data;
-		const_iterator(FilesystemNode **data) : _data(data) { }
-	public:
-		const FilesystemNode &operator *() const { return **_data; }
-		const FilesystemNode *operator->() const { return *_data; }
-		bool operator !=(const const_iterator &iter) const { return _data != iter._data; }
-		void operator ++() { ++_data; }
-	};
+	FilesystemNode();
+	FilesystemNode(const FilesystemNode &node);
+#ifdef MACOSX
+	FilesystemNode(const String &path);
+#endif
+	~FilesystemNode();
 
-	~FSList() {
-		for (int i = 0; i < _size; i++)
-			delete _data[i];
-	}
+	FilesystemNode &operator  =(const FilesystemNode &node);
 
-	void push_back(const FilesystemNode &element) {
-		ensureCapacity(_size + 1);
-		// Determine where to insert the item.
-		// TODO this is inefficient, should use binary search instead
-		int i = 0;
-		while (i < _size && *_data[i] < element)
-			i++;
-		if (i < _size)
-			memmove(&_data[i + 1], &_data[i], (_size - i) * sizeof(FilesystemNode *));
-		_data[i] = element.clone();
-		_size++;
-	}
+	FilesystemNode getParent() const;
 
-	const FilesystemNode& operator [](int idx) const {
-		assert(idx >= 0 && idx < _size);
-		return *_data[idx];
-	}
 
-	int size() const	{ return _size; }
+	virtual String displayName() const { return _realNode->displayName(); }
+	virtual bool isValid() const { return _realNode->isValid(); }
+	virtual bool isDirectory() const { return _realNode->isDirectory(); }
+	virtual String path() const { return _realNode->path(); }
 
-	const_iterator	begin() const {
-		return const_iterator(_data);
-	}
+	virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const { return _realNode->listDir(mode); }
 
-	const_iterator	end() const {
-		return const_iterator(_data + _size);
-	}
+protected:
+	void decRefCount();
 
+	virtual AbstractFilesystemNode *parent() const { return 0; }
 };
 
+
 #endif





More information about the Scummvm-git-logs mailing list