aboutsummaryrefslogtreecommitdiff
path: root/backends/fs
diff options
context:
space:
mode:
authorStephen Kennedy2008-09-26 21:53:08 +0000
committerStephen Kennedy2008-09-26 21:53:08 +0000
commita7bb113e83c88fad3a23d408caa99f918fdb610a (patch)
tree698dd9d85abaa6a20957bfb9c0e006e9dd1dc8b3 /backends/fs
parent11c0a3bdedcdf5eb2618b9db67b559663fb93320 (diff)
parentc1385076cbc57f1a4a52946a46b3ea06ecf37f37 (diff)
downloadscummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.gz
scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.tar.bz2
scummvm-rg350-a7bb113e83c88fad3a23d408caa99f918fdb610a.zip
Merged revisions 33452-33453,33455-33459,33463-33464,33466-33471,33473-33474,33478,33490,33492,33495-33496,33509-33512,33518-33519,33522-33527,33529-33530,33537,33541,33544,33546,33550,33552-33554,33556,33558,33561-33562,33565,33568,33570,33574,33576,33578-33581,33584-33587,33590,33596,33604-33611,33614-33615,33617-33618,33620-33621,33623,33626-33627,33632-33633,33635,33637,33639-33640,33642-33645,33648,33654-33655,33664,33667-33670,33673-33674,33678,33682,33686-33691,33693,33696,33698,33700,33703,33708,33710,33712-33714,33716,33719,33721-33723,33725-33727,33729-33730,33733,33736,33742,33754,33756,33758,33761,33763,33766,33777,33781-33788,33790,33792-33793,33795,33797,33805,33807-33812,33815-33817,33819,33822,33826,33829,33837,33839,33844,33847,33858-33861,33864,33871-33873,33875,33877-33879,33886,33889-33892,33894,33896,33900,33902-33903,33919,33928,33930,33932-33936,33938-33940,33942-33943,33948,33950,33953,33967,33973,33976,33978,33980,33985,33991,33993,33999-34000,34006,34009,34011,34013,34015,34019,34021-34023,34025,34027-34028,34030,34032-34034,34036,34038-34039,34041,34046-34048,34050-34055,34057,34059-34065,34067,34072,34074,34076,34078-34081,34084,34086-34087,34089-34090,34093,34096-34102,34104,34107,34113,34116,34119,34122,34124,34126,34128,34131-34132,34135,34138,34141,34144,34146,34149,34152-34154,34156-34157,34160,34163-34164,34169,34173,34179-34194,34196-34198,34200-34201,34205-34206,34208-34217,34219-34225,34227-34228,34234-34237,34239-34249,34251-34279,34281-34284,34286-34288,34290-34320,34323-34324,34326,34328-34329,34332,34334,34336,34338-34340,34343-34353,34356-34357,34359-34371,34373,34375,34378,34381-34382,34384-34385,34389-34391,34393-34394,34396-34397,34399-34405,34407-34409,34411,34413,34415,34417-34420,34423-34426,34428-34438,34440-34454,34456-34458,34460,34462-34469,34472,34474,34479-34481,34483-34498,34501-34505,34508,34511-34518,34520-34524,34526-34563,34566-34569,34571-34590,34592,34595-34599,34602-34603,34605,34613-34615,34617,34619-34624,34627-34628,34630-34639,34642-34649 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk svn-id: r34654
Diffstat (limited to 'backends/fs')
-rw-r--r--backends/fs/abstract-fs.cpp40
-rw-r--r--backends/fs/abstract-fs.h61
-rw-r--r--backends/fs/amigaos4/amigaos4-fs-factory.cpp4
-rw-r--r--backends/fs/amigaos4/amigaos4-fs-factory.h13
-rw-r--r--backends/fs/amigaos4/amigaos4-fs.cpp49
-rw-r--r--backends/fs/ds/ds-fs-factory.cpp2
-rw-r--r--backends/fs/ds/ds-fs-factory.h4
-rw-r--r--backends/fs/ds/ds-fs.cpp250
-rw-r--r--backends/fs/ds/ds-fs.h47
-rw-r--r--backends/fs/palmos/palmos-fs-factory.cpp2
-rw-r--r--backends/fs/palmos/palmos-fs-factory.h4
-rw-r--r--backends/fs/palmos/palmos-fs.cpp72
-rw-r--r--backends/fs/posix/posix-fs-factory.cpp11
-rw-r--r--backends/fs/posix/posix-fs-factory.h14
-rw-r--r--backends/fs/posix/posix-fs.cpp216
-rw-r--r--backends/fs/posix/posix-fs.h86
-rw-r--r--backends/fs/ps2/ps2-fs-factory.cpp2
-rw-r--r--backends/fs/ps2/ps2-fs-factory.h4
-rw-r--r--backends/fs/ps2/ps2-fs.cpp73
-rw-r--r--backends/fs/psp/psp-fs-factory.cpp2
-rw-r--r--backends/fs/psp/psp-fs-factory.h4
-rw-r--r--backends/fs/psp/psp-fs.cpp64
-rw-r--r--backends/fs/stdiostream.cpp161
-rw-r--r--backends/fs/stdiostream.h62
-rw-r--r--backends/fs/symbian/symbian-fs-factory.cpp4
-rw-r--r--backends/fs/symbian/symbian-fs-factory.h13
-rw-r--r--backends/fs/symbian/symbian-fs.cpp162
-rw-r--r--backends/fs/symbian/symbianstream.cpp274
-rw-r--r--backends/fs/symbian/symbianstream.h62
-rw-r--r--backends/fs/wii/wii-fs-factory.cpp2
-rw-r--r--backends/fs/wii/wii-fs-factory.h4
-rw-r--r--backends/fs/wii/wii-fs.cpp70
-rw-r--r--backends/fs/windows/windows-fs-factory.cpp4
-rw-r--r--backends/fs/windows/windows-fs-factory.h13
-rw-r--r--backends/fs/windows/windows-fs.cpp94
35 files changed, 1198 insertions, 751 deletions
diff --git a/backends/fs/abstract-fs.cpp b/backends/fs/abstract-fs.cpp
new file mode 100644
index 0000000000..6daad7152a
--- /dev/null
+++ b/backends/fs/abstract-fs.cpp
@@ -0,0 +1,40 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 "backends/fs/abstract-fs.h"
+
+const char *AbstractFilesystemNode::lastPathComponent(const Common::String &str, const char sep) {
+ // TODO: Get rid of this eventually! Use Common::lastPathComponent instead
+ if(str.empty())
+ return "";
+
+ const char *start = str.c_str();
+ const char *cur = start + str.size() - 2;
+
+ while (cur >= start && *cur != sep) {
+ --cur;
+ }
+
+ return cur + 1;
+}
diff --git a/backends/fs/abstract-fs.h b/backends/fs/abstract-fs.h
index 8125ad7d95..b3a652f2ae 100644
--- a/backends/fs/abstract-fs.h
+++ b/backends/fs/abstract-fs.h
@@ -43,28 +43,27 @@ typedef Common::Array<AbstractFilesystemNode *> AbstractFSList;
*/
class AbstractFilesystemNode {
protected:
- friend class FilesystemNode;
- typedef Common::String String;
- typedef FilesystemNode::ListMode ListMode;
+ friend class Common::FilesystemNode;
+ typedef Common::FilesystemNode::ListMode ListMode;
/**
- * Returns the child node with the given name. If no child with this name
- * exists, returns 0. When called on a non-directory node, it should
- * handle this gracefully by returning 0.
+ * Returns the child node with the given name. When called on a non-directory
+ * node, it should handle this gracefully by returning 0.
+ * When called with a name not matching any of the files/dirs contained in this
+ * directory, a valid node shold be returned, which returns 'false' upon calling
+ * the exists() method. The idea is that this node can then still can be used to
+ * create a new file via the openForWriting() method.
*
* Example:
* Calling getChild() for a node with path "/foo/bar" using name="file.txt",
* would produce a new node with "/foo/bar/file.txt" as path.
*
- * @note This function will append a separator char (\ or /) to the end of the
- * path if needed.
- *
* @note Handling calls on non-dir nodes gracefully makes it possible to
* switch to a lazy type detection scheme in the future.
*
* @param name String containing the name of the child to create a new node.
*/
- virtual AbstractFilesystemNode *getChild(const String &name) const = 0;
+ virtual AbstractFilesystemNode *getChild(const Common::String &name) const = 0;
/**
* The parent node of this directory.
@@ -72,6 +71,19 @@ protected:
*/
virtual AbstractFilesystemNode *getParent() const = 0;
+ /**
+ * Returns the last component of a given path.
+ *
+ * Examples:
+ * /foo/bar.txt would return /bar.txt
+ * /foo/bar/ would return /bar/
+ *
+ * @param str String containing the path.
+ * @param sep character used to separate path components
+ * @return Pointer to the first char of the last component inside str.
+ */
+ static const char *lastPathComponent(const Common::String &str, const char sep);
+
public:
/**
* Destructor.
@@ -100,7 +112,7 @@ public:
*
* @note By default, this method returns the value of getName().
*/
- virtual String getDisplayName() const { return getName(); }
+ virtual Common::String getDisplayName() const { return getName(); }
/**
* Returns the last component of the path pointed by this FilesystemNode.
@@ -111,12 +123,12 @@ public:
*
* @note This method is very architecture dependent, please check the concrete implementation for more information.
*/
- virtual String getName() const = 0;
+ virtual Common::String getName() const = 0;
/**
* Returns the 'path' of the current node, usable in fopen().
*/
- virtual String getPath() const = 0;
+ virtual Common::String getPath() const = 0;
/**
* Indicates whether this path refers to a directory or not.
@@ -149,9 +161,26 @@ public:
*/
virtual bool isWritable() const = 0;
- /* TODO:
- bool isFile();
- */
+
+ /**
+ * Creates a SeekableReadStream instance corresponding to the file
+ * referred by this node. This assumes that the node actually refers
+ * to a readable file. If this is not the case, 0 is returned.
+ *
+ * @return pointer to the stream object, 0 in case of a failure
+ */
+ virtual Common::SeekableReadStream *openForReading() = 0;
+
+ /**
+ * Creates a WriteStream instance corresponding to the file
+ * referred by this node. This assumes that the node actually refers
+ * to a readable file. If this is not the case, 0 is returned.
+ *
+ * @return pointer to the stream object, 0 in case of a failure
+ */
+ virtual Common::WriteStream *openForWriting() = 0;
};
+
+
#endif //BACKENDS_ABSTRACT_FS_H
diff --git a/backends/fs/amigaos4/amigaos4-fs-factory.cpp b/backends/fs/amigaos4/amigaos4-fs-factory.cpp
index af843b7c78..2b0b2f1908 100644
--- a/backends/fs/amigaos4/amigaos4-fs-factory.cpp
+++ b/backends/fs/amigaos4/amigaos4-fs-factory.cpp
@@ -26,8 +26,6 @@
#include "backends/fs/amigaos4/amigaos4-fs-factory.h"
#include "backends/fs/amigaos4/amigaos4-fs.cpp"
-DECLARE_SINGLETON(AmigaOSFilesystemFactory);
-
AbstractFilesystemNode *AmigaOSFilesystemFactory::makeRootFileNode() const {
return new AmigaOSFilesystemNode();
}
@@ -36,7 +34,7 @@ AbstractFilesystemNode *AmigaOSFilesystemFactory::makeCurrentDirectoryFileNode()
return new AmigaOSFilesystemNode();
}
-AbstractFilesystemNode *AmigaOSFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *AmigaOSFilesystemFactory::makeFileNodePath(const Common::String &path) const {
return new AmigaOSFilesystemNode(path);
}
#endif
diff --git a/backends/fs/amigaos4/amigaos4-fs-factory.h b/backends/fs/amigaos4/amigaos4-fs-factory.h
index 58a7dcd372..03af6e95b9 100644
--- a/backends/fs/amigaos4/amigaos4-fs-factory.h
+++ b/backends/fs/amigaos4/amigaos4-fs-factory.h
@@ -25,7 +25,6 @@
#ifndef AMIGAOS_FILESYSTEM_FACTORY_H
#define AMIGAOS_FILESYSTEM_FACTORY_H
-#include "common/singleton.h"
#include "backends/fs/fs-factory.h"
/**
@@ -33,19 +32,11 @@
*
* Parts of this class are documented in the base interface class, FilesystemFactory.
*/
-class AmigaOSFilesystemFactory : public FilesystemFactory, public Common::Singleton<AmigaOSFilesystemFactory> {
+class AmigaOSFilesystemFactory : public FilesystemFactory {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
-
-protected:
- AmigaOSFilesystemFactory() {};
-
-private:
- friend class Common::Singleton<SingletonBaseType>;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
};
#endif /*AMIGAOS_FILESYSTEM_FACTORY_H*/
diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp
index 5bf57ddf34..d517121dc0 100644
--- a/backends/fs/amigaos4/amigaos4-fs.cpp
+++ b/backends/fs/amigaos4/amigaos4-fs.cpp
@@ -36,8 +36,8 @@
#endif
#include "common/util.h"
-#include "engines/engine.h"
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/stdiostream.h"
#define ENTER() /* debug(6, "Enter") */
#define LEAVE() /* debug(6, "Leave") */
@@ -52,8 +52,8 @@ const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure?
class AmigaOSFilesystemNode : public AbstractFilesystemNode {
protected:
BPTR _pFileLock;
- String _sDisplayName;
- String _sPath;
+ Common::String _sDisplayName;
+ Common::String _sPath;
bool _bIsDirectory;
bool _bIsValid;
@@ -74,9 +74,9 @@ public:
/**
* Creates a AmigaOSFilesystemNode for a given path.
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
*/
- AmigaOSFilesystemNode(const String &p);
+ AmigaOSFilesystemNode(const Common::String &p);
/**
* FIXME: document this constructor.
@@ -96,17 +96,20 @@ public:
virtual ~AmigaOSFilesystemNode();
virtual bool exists() const;
- virtual String getDisplayName() const { return _sDisplayName; };
- virtual String getName() const { return _sDisplayName; };
- virtual String getPath() const { return _sPath; };
+ virtual Common::String getDisplayName() const { return _sDisplayName; };
+ virtual Common::String getName() const { return _sDisplayName; };
+ virtual Common::String getPath() const { return _sPath; };
virtual bool isDirectory() const { return _bIsDirectory; };
virtual bool isReadable() const;
virtual bool isWritable() const;
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+
/**
* Creates a list with all the volumes present in the root node.
*/
@@ -116,7 +119,7 @@ public:
/**
* Returns the last component of a given path.
*
- * @param str String containing the path.
+ * @param str Common::String containing the path.
* @return Pointer to the first char of the last component inside str.
*/
const char *lastPathComponent(const Common::String &str) {
@@ -148,10 +151,10 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode() {
LEAVE();
}
-AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) {
+AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) {
ENTER();
- int len = 0, offset = p.size();
+ int offset = p.size();
//assert(offset > 0);
@@ -161,7 +164,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) {
}
_sPath = p;
- _sDisplayName = lastPathComponent(_sPath);
+ _sDisplayName = ::lastPathComponent(_sPath);
_pFileLock = 0;
_bIsDirectory = false;
@@ -299,14 +302,14 @@ bool AmigaOSFilesystemNode::exists() const {
return nodeExists;
}
-AbstractFilesystemNode *AmigaOSFilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *AmigaOSFilesystemNode::getChild(const Common::String &n) const {
ENTER();
if (!_bIsDirectory) {
debug(6, "Not a directory");
return 0;
}
- String newPath(_sPath);
+ Common::String newPath(_sPath);
if (_sPath.lastChar() != '/')
newPath += '/';
@@ -368,10 +371,10 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
struct ExAllData *ead = data;
do {
- if ((mode == FilesystemNode::kListAll) ||
- (EAD_IS_DRAWER(ead) && (mode == FilesystemNode::kListDirectoriesOnly)) ||
- (EAD_IS_FILE(ead) && (mode == FilesystemNode::kListFilesOnly))) {
- String full_path = _sPath;
+ if ((mode == Common::FilesystemNode::kListAll) ||
+ (EAD_IS_DRAWER(ead) && (mode == Common::FilesystemNode::kListDirectoriesOnly)) ||
+ (EAD_IS_FILE(ead) && (mode == Common::FilesystemNode::kListFilesOnly))) {
+ Common::String full_path = _sPath;
full_path += (char*)ead->ed_Name;
BPTR lock = IDOS->Lock((STRPTR)full_path.c_str(), SHARED_LOCK);
@@ -566,4 +569,12 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
return myList;
}
+Common::SeekableReadStream *AmigaOSFilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *AmigaOSFilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
+}
+
#endif //defined(__amigaos4__)
diff --git a/backends/fs/ds/ds-fs-factory.cpp b/backends/fs/ds/ds-fs-factory.cpp
index 2eae2f2403..5c8c3f45f8 100644
--- a/backends/fs/ds/ds-fs-factory.cpp
+++ b/backends/fs/ds/ds-fs-factory.cpp
@@ -45,7 +45,7 @@ AbstractFilesystemNode *DSFilesystemFactory::makeCurrentDirectoryFileNode() cons
}
}
-AbstractFilesystemNode *DSFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *DSFilesystemFactory::makeFileNodePath(const Common::String &path) const {
if (DS::isGBAMPAvailable()) {
return new DS::GBAMPFileSystemNode(path);
} else {
diff --git a/backends/fs/ds/ds-fs-factory.h b/backends/fs/ds/ds-fs-factory.h
index bff21a309d..67e0076b78 100644
--- a/backends/fs/ds/ds-fs-factory.h
+++ b/backends/fs/ds/ds-fs-factory.h
@@ -35,11 +35,9 @@
*/
class DSFilesystemFactory : public FilesystemFactory, public Common::Singleton<DSFilesystemFactory> {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
protected:
DSFilesystemFactory() {};
diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp
index cffe4c118d..911702316d 100644
--- a/backends/fs/ds/ds-fs.cpp
+++ b/backends/fs/ds/ds-fs.cpp
@@ -24,6 +24,7 @@
#include "common/util.h"
//#include <NDS/ARM9/console.h> //basic print funcionality
#include "backends/fs/ds/ds-fs.h"
+#include "backends/fs/stdiostream.h"
#include "dsmain.h"
#include "fat/gba_nds_fat.h"
@@ -55,7 +56,7 @@ DSFileSystemNode::DSFileSystemNode() {
}
}
-DSFileSystemNode::DSFileSystemNode(const String& path) {
+DSFileSystemNode::DSFileSystemNode(const Common::String& path) {
// consolePrintf("--%s ",path.c_str());
char disp[128];
@@ -70,7 +71,7 @@ DSFileSystemNode::DSFileSystemNode(const String& path) {
strcpy(disp, pathStr + lastSlash + 1);
- _displayName = String(disp);
+ _displayName = Common::String(disp);
_path = path;
// _isValid = true;
// _isDirectory = false;
@@ -98,7 +99,7 @@ DSFileSystemNode::DSFileSystemNode(const String& path) {
// consolePrintf("%s - Found: %d, Dir: %d\n", pathStr, _isValid, _isDirectory);
}
-DSFileSystemNode::DSFileSystemNode(const String& path, bool isDir) {
+DSFileSystemNode::DSFileSystemNode(const Common::String& path, bool isDir) {
// consolePrintf("--%s ",path.c_str());
char disp[128];
@@ -112,7 +113,7 @@ DSFileSystemNode::DSFileSystemNode(const String& path, bool isDir) {
strcpy(disp, pathStr + lastSlash + 1);
- _displayName = String(disp);
+ _displayName = Common::String(disp);
_path = path;
_isValid = true;
_isDirectory = isDir;
@@ -167,10 +168,10 @@ bool DSFileSystemNode::getChildren(AbstractFSList &dirList, ListMode mode, bool
_zipFile->getFileName(n);
// consolePrintf("file: %s\n", n);
- if ( (_zipFile->isDirectory() && ((mode == FilesystemNode::kListDirectoriesOnly) || (mode == FilesystemNode::kListAll)) )
- || (!_zipFile->isDirectory() && ((mode == FilesystemNode::kListFilesOnly) || (mode == FilesystemNode::kListAll)) ) )
+ if ( (_zipFile->isDirectory() && ((mode == Common::FilesystemNode::kListDirectoriesOnly) || (mode == Common::FilesystemNode::kListAll)) )
+ || (!_zipFile->isDirectory() && ((mode == Common::FilesystemNode::kListFilesOnly) || (mode == Common::FilesystemNode::kListAll)) ) )
{
- DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/" + String(n), _zipFile->isDirectory());
+ DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/" + Common::String(n), _zipFile->isDirectory());
dsfsn->_isDirectory = _zipFile->isDirectory();
dirList.push_back((dsfsn));
}
@@ -195,7 +196,7 @@ AbstractFilesystemNode* DSFileSystemNode::getParent() const {
}
}
- p = new DSFileSystemNode(String(path, lastSlash));
+ p = new DSFileSystemNode(Common::String(path, lastSlash));
((DSFileSystemNode *) (p))->_isDirectory = true;
} else {
p = new DSFileSystemNode();
@@ -204,6 +205,14 @@ AbstractFilesystemNode* DSFileSystemNode::getParent() const {
return p;
}
+Common::SeekableReadStream *DSFileSystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *DSFileSystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
+}
+
//////////////////////////////////////////////////////////////////////////
// GBAMPFileSystemNode - File system using GBA Movie Player and CF card //
//////////////////////////////////////////////////////////////////////////
@@ -216,7 +225,7 @@ GBAMPFileSystemNode::GBAMPFileSystemNode() {
_path = "mp:/";
}
-GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path) {
+GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path) {
// consolePrintf("'%s'",path.c_str());
char disp[128];
@@ -245,13 +254,13 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path) {
}
// consolePrintf("Path: %s (%d)\n", check, success);
- _displayName = String(disp);
+ _displayName = Common::String(disp);
_path = path;
_isValid = success == FT_FILE;
_isDirectory = success == FT_DIR;
}
-GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path, bool isDirectory) {
+GBAMPFileSystemNode::GBAMPFileSystemNode(const Common::String& path, bool isDirectory) {
// consolePrintf("'%s'",path.c_str());
char disp[128];
@@ -265,7 +274,7 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path, bool isDirectory) {
strcpy(disp, pathStr + lastSlash + 1);
- _displayName = String(disp);
+ _displayName = Common::String(disp);
_path = path;
_isValid = true;
_isDirectory = isDirectory;
@@ -313,8 +322,8 @@ bool GBAMPFileSystemNode::getChildren(AbstractFSList& dirList, ListMode mode, bo
while (entryType != TYPE_NO_MORE) {
- if ( ((entryType == TYPE_DIR) && ((mode == FilesystemNode::kListDirectoriesOnly) || (mode == FilesystemNode::kListAll)))
- || ((entryType == TYPE_FILE) && ((mode == FilesystemNode::kListFilesOnly) || (mode == FilesystemNode::kListAll))) ) {
+ if ( ((entryType == TYPE_DIR) && ((mode == Common::FilesystemNode::kListDirectoriesOnly) || (mode == Common::FilesystemNode::kListAll)))
+ || ((entryType == TYPE_FILE) && ((mode == Common::FilesystemNode::kListFilesOnly) || (mode == Common::FilesystemNode::kListAll))) ) {
GBAMPFileSystemNode* dsfsn;
consolePrintf("Fname: %s\n", fname);
@@ -322,9 +331,9 @@ bool GBAMPFileSystemNode::getChildren(AbstractFSList& dirList, ListMode mode, bo
if (strcmp(fname, ".") && strcmp(fname, "..")) {
if (!strcmp(path, "/")) {
- dsfsn = new GBAMPFileSystemNode("mp:" + String(path) + String(fname), entryType == TYPE_DIR);
+ dsfsn = new GBAMPFileSystemNode("mp:" + Common::String(path) + Common::String(fname), entryType == TYPE_DIR);
} else {
- dsfsn = new GBAMPFileSystemNode("mp:" + String(path) + String("/") + String(fname), entryType == TYPE_DIR);
+ dsfsn = new GBAMPFileSystemNode("mp:" + Common::String(path) + Common::String("/") + Common::String(fname), entryType == TYPE_DIR);
}
// dsfsn->_isDirectory = entryType == DIR;
@@ -358,7 +367,7 @@ AbstractFilesystemNode* GBAMPFileSystemNode::getParent() const {
}
}
- p = new GBAMPFileSystemNode(String(path, lastSlash));
+ p = new GBAMPFileSystemNode(Common::String(path, lastSlash));
p->_isDirectory = true;
} else {
p = new GBAMPFileSystemNode();
@@ -367,6 +376,14 @@ AbstractFilesystemNode* GBAMPFileSystemNode::getParent() const {
return p;
}
+Common::SeekableReadStream *GBAMPFileSystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *GBAMPFileSystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
+}
+
// Stdio replacements
#define MAX_FILE_HANDLES 32
@@ -399,6 +416,7 @@ FILE* std_fopen(const char* name, const char* mode) {
if (DS::isGBAMPAvailable()) {
FAT_chdir("/");
+ // Turn all back slashes into forward slashes for gba_nds_fat
char* p = realName;
while (*p) {
if (*p == '\\') *p = '/';
@@ -422,8 +440,12 @@ FILE* std_fopen(const char* name, const char* mode) {
// Allocate a file handle
int r = 0;
- while (handle[r].used) r++;
+ while (handle[r].used) {
+ r++;
+ assert(r < MAX_FILE_HANDLES);
+ }
+#ifdef GBA_SRAM_SAVE
if (strchr(mode, 'w')) {
// consolePrintf("Writing %s\n", realName);
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, true);
@@ -431,6 +453,7 @@ FILE* std_fopen(const char* name, const char* mode) {
// consolePrintf("Reading %s\n", realName);
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, false);
}
+#endif
if (handle[r].sramFile) {
handle[r].used = true;
@@ -512,69 +535,6 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
return bytes / size;
}
return numItems;
-
-/* int item = 0;
- u8* data = (u8 *) ptr;
- while ((item < numItems) && (!FAT_feof((FAT_FILE *) handle))) {
-
-
- int bytes = 0;
- while ((bytes < size) && (!FAT_feof((FAT_FILE *) handle))) {
- *data++ = FAT_fgetc((FAT_FILE *) handle);
- bytes++;
- }
-
- item++;
-
- }
-
- return item;
-*/
- int items = 0;
-
- //for (int r = 0; r < numItems; r++) {
- if (!std_feof(handle)) {
-/* for (int t = 0; t < size; t++) {
- if (feof(handle)) eof = true;
- *(((char *) (ptr)) + r * size + t) = getc(handle);
- }*/
- int left = size * numItems;
- int bytesRead = -1;
-
- while ((left > 0) && (!FAT_feof((FAT_FILE *) handle))) {
- int amount = left > 8192? 8192: left;
-// do {
- bytesRead = FAT_fread((void *) ptr, 1, amount, (FAT_FILE *) handle);
-/* if (bytesRead == 0) {
- consolePrintf("Pos:%d items:%d num:%d amount:%d read:%d\n", ftell(handle), items, numItems, amount, bytesRead);
- left++;
-
- int pos = ftell(handle);
-
- fseek(handle, 0, SEEK_SET);
- int c = getc(handle);
- fseek(handle, pos - 1024, SEEK_SET);
- fread(ptr, 1024, 1, handle);
- swiWaitForVBlank();
- //while (true);
- }
-
- } while (bytesRead == 0);
-*/
- left -= bytesRead;
- ptr = ((char *) (ptr)) + bytesRead;
- }
-
- items = numItems - (left / size);
-
-// FAT_fread((void *) ptr, size, 1, ((int) (handle)) - 1);
-// ptr = ((char *) (ptr)) + size;
- }
-// }
-
-// consolePrintf("...done %d \n", items)
-
- return items;
}
if (handle->sramFile) {
@@ -641,10 +601,6 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
}
}
-void std_fprintf(FILE* handle, const char* fmt, ...) {
- consolePrintf(fmt);
-}
-
bool std_feof(FILE* handle) {
// consolePrintf("feof ");
@@ -660,42 +616,10 @@ bool std_feof(FILE* handle) {
return handle->pos >= handle->size;
}
-void std_fflush(FILE* handle) {
+int std_fflush(FILE* handle) {
//FIXME: not implemented?
// consolePrintf("fflush ");
-}
-
-char* std_fgets(char* str, int size, FILE* file) {
-// consolePrintf("fgets file=%d ", file);
-
- if (DS::isGBAMPAvailable()) {
- char* s = str;
- while ((*s++ = std_getc(file)) >= 32) {
-// consolePrintf("%d ", *s);
- }
- *s = 0;
-
-// consolePrintf("Read:%s\n", str);
-
- return str;
- }
-
- if (file->sramFile) {
- file->pos--;
- int p = -1;
- do {
- file->pos++;
- p++;
- file->sramFile->read((char *) &str[p], 1);
-// consolePrintf("%d,", str[p]);
- } while ((str[p] >= 32) && (!std_feof(file)) && (p < size));
- str[p + 1] = 0;
- file->pos++;
-// consolePrintf("Read:%s\n", str);
- return str;
- }
-
- return NULL;
+ return 0;
}
long int std_ftell(FILE* handle) {
@@ -731,92 +655,20 @@ int std_fseek(FILE* handle, long int offset, int whence) {
return 0;
}
-void std_clearerr(FILE* handle) {
+int std_ferror(FILE* handle) {
//FIXME: not implemented?
-// consolePrintf("clearerr ");
-}
-
-int std_getc(FILE* handle) {
- if (DS::isGBAMPAvailable()) {
- char c;
- FAT_fread(&c, 1, 1, (FAT_FILE *) handle);
-
- return c;
- }
-
-// consolePrintf("fgetc ");
- return 0; // Not supported yet
+// consolePrintf("ferror ");
+ return 0;
}
-char* std_getcwd(char* dir, int dunno) {
-// consolePrintf("getcwd ");
- dir[0] = '\0';
- return dir; // Not supported yet
+void std_clearerr(FILE* handle) {
+ //FIXME: not implemented?
+// consolePrintf("clearerr ");
}
-void std_cwd(char* dir) {
- char buffer[128];
- strcpy(buffer, dir);
- char* realName = buffer;
-
- if (DS::isGBAMPAvailable()) {
- if ((strlen(dir) >= 4) && (dir[0] == 'm') && (dir[1] == 'p') && (dir[2] == ':') && (dir[3] == '/')) {
- realName += 4;
- }
-
- // consolePrintf("Real cwd:%d\n", realName);
-
- char* p = realName;
- while (*p) {
- if (*p == '\\') *p = '/';
- p++;
- }
-
- // consolePrintf("Real cwd:%d\n", realName);
- FAT_chdir(realName);
- } else {
- if ((strlen(dir) >= 4) && (dir[0] == 'd') && (dir[1] == 's') && (dir[2] == ':') && (dir[3] == '/')) {
- realName += 4;
- }
-
- char* p = realName;
- while (*p) {
- if (*p == '\\') *p = '/';
- p++;
- }
-
- strcpy(currentDir, realName);
- if (*(currentDir + strlen(currentDir) - 1) == '/') {
- *(currentDir + strlen(currentDir) - 1) = '\0';
- }
-// consolePrintf("CWD: %s\n", currentDir);
- }
+void std_fprintf(FILE* handle, const char* fmt, ...) {
+ consolePrintf(fmt);
}
-int std_ferror(FILE* handle) {
- return 0;
-}
} // namespace DS
-
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * /foo/bar.txt would return /bar.txt
- * /foo/bar/ would return /bar/
- *
- * @param str String containing the path.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '/' && *cur != '\\') {
- --cur;
- }
-
- return cur + 1;
-}
-
diff --git a/backends/fs/ds/ds-fs.h b/backends/fs/ds/ds-fs.h
index 9ac453aca9..36e7bc9824 100644
--- a/backends/fs/ds/ds-fs.h
+++ b/backends/fs/ds/ds-fs.h
@@ -41,12 +41,10 @@ namespace DS {
*/
class DSFileSystemNode : public AbstractFilesystemNode {
protected:
- typedef class Common::String String;
-
static ZipFile* _zipFile;
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory;
bool _isValid;
@@ -61,7 +59,7 @@ public:
*
* @param path String with the path the new node should point to.
*/
- DSFileSystemNode(const String &path);
+ DSFileSystemNode(const Common::String &path);
/**
* Creates a DSFilesystemNode for a given path.
@@ -69,7 +67,7 @@ public:
* @param path String with the path the new node should point to.
* @param path true if path is a directory, false otherwise.
*/
- DSFileSystemNode(const String& path, bool isDir);
+ DSFileSystemNode(const Common::String& path, bool isDir);
/**
* Copy constructor.
@@ -77,9 +75,9 @@ public:
DSFileSystemNode(const DSFileSystemNode *node);
virtual bool exists() const { return true; } //FIXME: this is just a stub
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
@@ -89,9 +87,12 @@ public:
*/
virtual AbstractFilesystemNode *clone() const { return new DSFileSystemNode(this); }
virtual AbstractFilesystemNode *getChild(const Common::String& name) const;
- virtual bool getChildren(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly, bool hidden = false) const;
+ virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+
/**
* Returns the zip file this node points to.
* TODO: check this documentation.
@@ -107,10 +108,8 @@ public:
*/
class GBAMPFileSystemNode : public AbstractFilesystemNode {
protected:
- typedef class Common::String String;
-
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory;
bool _isValid;
@@ -125,7 +124,7 @@ public:
*
* @param path String with the path the new node should point to.
*/
- GBAMPFileSystemNode(const String &path);
+ GBAMPFileSystemNode(const Common::String &path);
/**
* Creates a DSFilesystemNode for a given path.
@@ -133,7 +132,7 @@ public:
* @param path String with the path the new node should point to.
* @param path true if path is a directory, false otherwise.
*/
- GBAMPFileSystemNode(const String &path, bool isDirectory);
+ GBAMPFileSystemNode(const Common::String &path, bool isDirectory);
/**
* Copy constructor.
@@ -141,9 +140,9 @@ public:
GBAMPFileSystemNode(const GBAMPFileSystemNode *node);
virtual bool exists() const { return _isValid || _isDirectory; }
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
@@ -153,8 +152,11 @@ public:
*/
virtual AbstractFilesystemNode *clone() const { return new GBAMPFileSystemNode(this); }
virtual AbstractFilesystemNode *getChild(const Common::String& name) const;
- virtual bool getChildren(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly, bool hidden = false) const;
+ virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
+
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
};
struct fileHandle {
@@ -179,15 +181,14 @@ struct fileHandle {
// Please do not remove any of these prototypes that appear not to be required.
FILE* std_fopen(const char* name, const char* mode);
void std_fclose(FILE* handle);
-int std_getc(FILE* handle);
size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle);
size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle);
bool std_feof(FILE* handle);
long int std_ftell(FILE* handle);
int std_fseek(FILE* handle, long int offset, int whence);
void std_clearerr(FILE* handle);
-void std_cwd(char* dir);
-void std_fflush(FILE* handle);
+int std_fflush(FILE* handle);
+int std_ferror(FILE* handle);
} //namespace DS
diff --git a/backends/fs/palmos/palmos-fs-factory.cpp b/backends/fs/palmos/palmos-fs-factory.cpp
index 8699a9788b..bbc1639897 100644
--- a/backends/fs/palmos/palmos-fs-factory.cpp
+++ b/backends/fs/palmos/palmos-fs-factory.cpp
@@ -36,7 +36,7 @@ AbstractFilesystemNode *PalmOSFilesystemFactory::makeCurrentDirectoryFileNode()
return new PalmOSFilesystemNode();
}
-AbstractFilesystemNode *PalmOSFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *PalmOSFilesystemFactory::makeFileNodePath(const Common::String &path) const {
return new PalmOSFilesystemNode(path);
}
#endif
diff --git a/backends/fs/palmos/palmos-fs-factory.h b/backends/fs/palmos/palmos-fs-factory.h
index 3ea8b5fe47..f778aa89ef 100644
--- a/backends/fs/palmos/palmos-fs-factory.h
+++ b/backends/fs/palmos/palmos-fs-factory.h
@@ -35,11 +35,9 @@
*/
class PalmOSFilesystemFactory : public FilesystemFactory, public Common::Singleton<PalmOSFilesystemFactory> {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
protected:
PalmOSFilesystemFactory() {};
diff --git a/backends/fs/palmos/palmos-fs.cpp b/backends/fs/palmos/palmos-fs.cpp
index 5edb6c2d26..7c415aa320 100644
--- a/backends/fs/palmos/palmos-fs.cpp
+++ b/backends/fs/palmos/palmos-fs.cpp
@@ -28,6 +28,7 @@
#include "globals.h"
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/stdiostream.h"
/**
* Implementation of the ScummVM file system API based on PalmOS VFS API.
@@ -36,8 +37,8 @@
*/
class PalmOSFilesystemNode : public AbstractFilesystemNode {
protected:
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory;
bool _isValid;
bool _isPseudoRoot;
@@ -51,22 +52,25 @@ public:
/**
* Creates a POSIXFilesystemNode for a given path.
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
*/
- PalmOSFilesystemNode(const String &p);
+ PalmOSFilesystemNode(const Common::String &p);
virtual bool exists() const { return _isValid; }
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+
private:
/**
* Adds a single WindowsFilesystemNode to a given list.
@@ -74,44 +78,20 @@ private:
*
* @param list List to put the file entry node in.
* @param mode Mode to use while adding the file entry to the list.
- * @param base String with the directory being listed.
+ * @param base Common::String with the directory being listed.
* @param find_data Describes a file that the FindFirstFile, FindFirstFileEx, or FindNextFile functions find.
*/
static void addFile(AbstractFSList &list, ListMode mode, const Char *base, FileInfoType* find_data);
};
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * /foo/bar.txt would return /bar.txt
- * /foo/bar/ would return /bar/
- *
- * @param str String containing the path.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if(str.empty())
- return "";
-
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '/') {
- --cur;
- }
-
- return cur + 1;
-}
-
void PalmOSFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, FileInfoType* find_data) {
PalmOSFilesystemNode entry;
bool isDir;
isDir = (find_data->attributes & vfsFileAttrDirectory);
- if ((!isDir && mode == FilesystemNode::kListDirectoriesOnly) ||
- (isDir && mode == FilesystemNode::kListFilesOnly))
+ if ((!isDir && mode == Common::FilesystemNode::kListDirectoriesOnly) ||
+ (isDir && mode == Common::FilesystemNode::kListFilesOnly))
return;
entry._isDirectory = isDir;
@@ -136,9 +116,9 @@ PalmOSFilesystemNode::PalmOSFilesystemNode() {
_isPseudoRoot = false;
}
-PalmOSFilesystemNode::PalmOSFilesystemNode(const String &p) {
+PalmOSFilesystemNode::PalmOSFilesystemNode(const Common::String &p) {
_path = p;
- _displayName = lastPathComponent(_path);
+ _displayName = lastPathComponent(_path, '/');
UInt32 attr;
FileRef handle;
@@ -159,10 +139,10 @@ PalmOSFilesystemNode::PalmOSFilesystemNode(const String &p) {
_isPseudoRoot = false;
}
-AbstractFilesystemNode *PalmOSFilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *PalmOSFilesystemNode::getChild(const Common::String &n) const {
assert(_isDirectory);
- String newPath(_path);
+ Common::String newPath(_path);
if (_path.lastChar() != '/')
newPath += '/';
newPath += n;
@@ -215,17 +195,25 @@ AbstractFilesystemNode *PalmOSFilesystemNode::getParent() const {
if (!_isPseudoRoot) {
const char *start = _path.c_str();
- const char *end = lastPathComponent(_path);
+ const char *end = lastPathComponent(_path, '/');
p = new PalmOSFilesystemNode();
- p->_path = String(start, end - start);
+ p->_path = Common::String(start, end - start);
p->_isValid = true;
p->_isDirectory = true;
- p->_displayName = lastPathComponent(p->_path);
+ p->_displayName = lastPathComponent(p->_path, '/');
p->_isPseudoRoot =(p->_path == "/");
}
return p;
}
+Common::SeekableReadStream *PalmOSFilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *PalmOSFilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
+}
+
#endif // PALMOS_MODE
diff --git a/backends/fs/posix/posix-fs-factory.cpp b/backends/fs/posix/posix-fs-factory.cpp
index 0a1160ff8f..cbfb69b76a 100644
--- a/backends/fs/posix/posix-fs-factory.cpp
+++ b/backends/fs/posix/posix-fs-factory.cpp
@@ -26,19 +26,18 @@
#include "backends/fs/posix/posix-fs-factory.h"
#include "backends/fs/posix/posix-fs.cpp"
-DECLARE_SINGLETON(POSIXFilesystemFactory);
-
AbstractFilesystemNode *POSIXFilesystemFactory::makeRootFileNode() const {
- return new POSIXFilesystemNode();
+ return new POSIXFilesystemNode("/");
}
AbstractFilesystemNode *POSIXFilesystemFactory::makeCurrentDirectoryFileNode() const {
char buf[MAXPATHLEN];
getcwd(buf, MAXPATHLEN);
- return new POSIXFilesystemNode(buf, true);
+ return new POSIXFilesystemNode(buf);
}
-AbstractFilesystemNode *POSIXFilesystemFactory::makeFileNodePath(const String &path) const {
- return new POSIXFilesystemNode(path, true);
+AbstractFilesystemNode *POSIXFilesystemFactory::makeFileNodePath(const Common::String &path) const {
+ assert(!path.empty());
+ return new POSIXFilesystemNode(path);
}
#endif
diff --git a/backends/fs/posix/posix-fs-factory.h b/backends/fs/posix/posix-fs-factory.h
index d8eecda6ef..c697679814 100644
--- a/backends/fs/posix/posix-fs-factory.h
+++ b/backends/fs/posix/posix-fs-factory.h
@@ -25,7 +25,6 @@
#ifndef POSIX_FILESYSTEM_FACTORY_H
#define POSIX_FILESYSTEM_FACTORY_H
-#include "common/singleton.h"
#include "backends/fs/fs-factory.h"
/**
@@ -33,19 +32,10 @@
*
* Parts of this class are documented in the base interface class, FilesystemFactory.
*/
-class POSIXFilesystemFactory : public FilesystemFactory, public Common::Singleton<POSIXFilesystemFactory> {
-public:
- typedef Common::String String;
-
+class POSIXFilesystemFactory : public FilesystemFactory {
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
-
-protected:
- POSIXFilesystemFactory() {};
-
-private:
- friend class Common::Singleton<SingletonBaseType>;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
};
#endif /*POSIX_FILESYSTEM_FACTORY_H*/
diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp
index 5cde32c851..8dca78d82a 100644
--- a/backends/fs/posix/posix-fs.cpp
+++ b/backends/fs/posix/posix-fs.cpp
@@ -24,85 +24,20 @@
#if defined(UNIX)
-#include "backends/fs/abstract-fs.h"
+#include "backends/fs/posix/posix-fs.h"
+#include "backends/fs/stdiostream.h"
+#include "common/algorithm.h"
-#ifdef MACOSX
-#include <sys/types.h>
-#endif
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
-#include <unistd.h>
-/**
- * Implementation of the ScummVM file system API based on POSIX.
- *
- * Parts of this class are documented in the base interface class, AbstractFilesystemNode.
- */
-class POSIXFilesystemNode : public AbstractFilesystemNode {
-protected:
- String _displayName;
- String _path;
- bool _isDirectory;
- bool _isValid;
-
-public:
- /**
- * Creates a POSIXFilesystemNode with the root node as path.
- */
- POSIXFilesystemNode();
-
- /**
- * Creates a POSIXFilesystemNode for a given path.
- *
- * @param path String with the path the new node should point to.
- * @param verify true if the isValid and isDirectory flags should be verified during the construction.
- */
- POSIXFilesystemNode(const String &path, bool verify);
-
- virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
- virtual bool isDirectory() const { return _isDirectory; }
- virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
- virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
-
- virtual AbstractFilesystemNode *getChild(const String &n) const;
- virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
- virtual AbstractFilesystemNode *getParent() const;
-
-private:
- /**
- * Tests and sets the _isValid and _isDirectory flags, using the stat() function.
- */
- virtual void setFlags();
-};
-
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * /foo/bar.txt would return /bar.txt
- * /foo/bar/ would return /bar/
- *
- * @param str String containing the path.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if(str.empty())
- return "";
-
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '/') {
- --cur;
- }
+#ifdef __OS2__
+#define INCL_DOS
+#include <os2.h>
+#endif
- return cur + 1;
-}
void POSIXFilesystemNode::setFlags() {
struct stat st;
@@ -111,15 +46,7 @@ void POSIXFilesystemNode::setFlags() {
_isDirectory = _isValid ? S_ISDIR(st.st_mode) : false;
}
-POSIXFilesystemNode::POSIXFilesystemNode() {
- // The root dir.
- _path = "/";
- _displayName = _path;
- _isValid = true;
- _isDirectory = true;
-}
-
-POSIXFilesystemNode::POSIXFilesystemNode(const String &p, bool verify) {
+POSIXFilesystemNode::POSIXFilesystemNode(const Common::String &p) {
assert(p.size() > 0);
// Expand "~/" to the value of the HOME env variable
@@ -134,30 +61,85 @@ POSIXFilesystemNode::POSIXFilesystemNode(const String &p, bool verify) {
} else {
_path = p;
}
-
- _displayName = lastPathComponent(_path);
-
- if (verify) {
- setFlags();
+
+#ifdef __OS2__
+ // On OS/2, 'X:/' is a root of drive X, so we should not remove that last
+ // slash.
+ if (!(_path.size() == 3 && _path.hasSuffix(":/")))
+#endif
+ // Normalize the path (that is, remove unneeded slashes etc.)
+ _path = Common::normalizePath(_path, '/');
+ _displayName = Common::lastPathComponent(_path, '/');
+
+ // TODO: should we turn relative paths into absolute ones?
+ // Pro: Ensures the "getParent" works correctly even for relative dirs.
+ // Contra: The user may wish to use (and keep!) relative paths in his
+ // config file, and converting relative to absolute paths may hurt him...
+ //
+ // An alternative approach would be to change getParent() to work correctly
+ // if "_path" is the empty string.
+#if 0
+ if (!_path.hasPrefix("/")) {
+ char buf[MAXPATHLEN+1];
+ getcwd(buf, MAXPATHLEN);
+ strcat(buf, "/");
+ _path = buf + _path;
}
+#endif
+ // TODO: Should we enforce that the path is absolute at this point?
+ //assert(_path.hasPrefix("/"));
+
+ setFlags();
}
-AbstractFilesystemNode *POSIXFilesystemNode::getChild(const String &n) const {
- // FIXME: Pretty lame implementation! We do no error checking to speak
- // of, do not check if this is a special node, etc.
+AbstractFilesystemNode *POSIXFilesystemNode::getChild(const Common::String &n) const {
+ assert(!_path.empty());
assert(_isDirectory);
+
+ // Make sure the string contains no slashes
+ assert(!n.contains('/'));
- String newPath(_path);
+ // We assume here that _path is already normalized (hence don't bother to call
+ // Common::normalizePath on the final path).
+ Common::String newPath(_path);
if (_path.lastChar() != '/')
newPath += '/';
newPath += n;
- return new POSIXFilesystemNode(newPath, true);
+ return makeNode(newPath);
}
bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
assert(_isDirectory);
+#ifdef __OS2__
+ if (_path == "/") {
+ // Special case for the root dir: List all DOS drives
+ ULONG ulDrvNum;
+ ULONG ulDrvMap;
+
+ DosQueryCurrentDisk(&ulDrvNum, &ulDrvMap);
+
+ for (int i = 0; i < 26; i++) {
+ if (ulDrvMap & 1) {
+ char drive_root[] = "A:/";
+ drive_root[0] += i;
+
+ POSIXFilesystemNode *entry = new POSIXFilesystemNode();
+ entry->_isDirectory = true;
+ entry->_isValid = true;
+ entry->_path = drive_root;
+ entry->_displayName = "[" + Common::String(drive_root, 2) + "]";
+ myList.push_back(entry);
+ }
+
+ ulDrvMap >>= 1;
+ }
+
+ return true;
+ }
+#endif
+
DIR *dirp = opendir(_path.c_str());
struct dirent *dp;
@@ -175,12 +157,12 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo
continue;
}
- String newPath(_path);
- if (newPath.lastChar() != '/')
- newPath += '/';
- newPath += dp->d_name;
-
- POSIXFilesystemNode entry(newPath, false);
+ // Start with a clone of this node, with the correct path set
+ POSIXFilesystemNode entry(*this);
+ entry._displayName = dp->d_name;
+ if (_path.lastChar() != '/')
+ entry._path += '/';
+ entry._path += entry._displayName;
#if defined(SYSTEM_NOT_SUPPORTING_D_TYPE)
/* TODO: d_type is not part of POSIX, so it might not be supported
@@ -215,13 +197,10 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo
continue;
// Honor the chosen mode
- if ((mode == FilesystemNode::kListFilesOnly && entry._isDirectory) ||
- (mode == FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
+ if ((mode == Common::FilesystemNode::kListFilesOnly && entry._isDirectory) ||
+ (mode == Common::FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
continue;
- if (entry._isDirectory)
- entry._path += "/";
-
myList.push_back(new POSIXFilesystemNode(entry));
}
closedir(dirp);
@@ -231,12 +210,39 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, boo
AbstractFilesystemNode *POSIXFilesystemNode::getParent() const {
if (_path == "/")
- return 0;
+ return 0; // The filesystem root has no parent
+
+#ifdef __OS2__
+ if (_path.size() == 3 && _path.hasSuffix(":/"))
+ // This is a root directory of a drive
+ return makeNode("/"); // return a virtual root for a list of drives
+#endif
const char *start = _path.c_str();
- const char *end = lastPathComponent(_path);
+ const char *end = start + _path.size();
+
+ // Strip of the last component. We make use of the fact that at this
+ // point, _path is guaranteed to be normalized
+ while (end > start && *(end-1) != '/')
+ end--;
+
+ if (end == start) {
+ // This only happens if we were called with a relative path, for which
+ // there simply is no parent.
+ // TODO: We could also resolve this by assuming that the parent is the
+ // current working directory, and returning a node referring to that.
+ return 0;
+ }
+
+ return makeNode(Common::String(start, end));
+}
+
+Common::SeekableReadStream *POSIXFilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
- return new POSIXFilesystemNode(String(start, end - start), true);
+Common::WriteStream *POSIXFilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
}
#endif //#if defined(UNIX)
diff --git a/backends/fs/posix/posix-fs.h b/backends/fs/posix/posix-fs.h
new file mode 100644
index 0000000000..e09e433e05
--- /dev/null
+++ b/backends/fs/posix/posix-fs.h
@@ -0,0 +1,86 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 POSIX_FILESYSTEM_H
+#define POSIX_FILESYSTEM_H
+
+#include "backends/fs/abstract-fs.h"
+
+#ifdef MACOSX
+#include <sys/types.h>
+#endif
+#include <unistd.h>
+
+/**
+ * Implementation of the ScummVM file system API based on POSIX.
+ *
+ * Parts of this class are documented in the base interface class, AbstractFilesystemNode.
+ */
+class POSIXFilesystemNode : public AbstractFilesystemNode {
+protected:
+ Common::String _displayName;
+ Common::String _path;
+ bool _isDirectory;
+ bool _isValid;
+
+ virtual AbstractFilesystemNode *makeNode(const Common::String &path) const {
+ return new POSIXFilesystemNode(path);
+ }
+
+ /**
+ * Plain constructor, for internal use only (hence protected).
+ */
+ POSIXFilesystemNode() : _isDirectory(false), _isValid(false) {}
+
+public:
+ /**
+ * Creates a POSIXFilesystemNode for a given path.
+ *
+ * @param path the path the new node should point to.
+ */
+ POSIXFilesystemNode(const Common::String &path);
+
+ virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
+ virtual bool isDirectory() const { return _isDirectory; }
+ virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
+ virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
+
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
+ virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
+ virtual AbstractFilesystemNode *getParent() const;
+
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+
+private:
+ /**
+ * Tests and sets the _isValid and _isDirectory flags, using the stat() function.
+ */
+ virtual void setFlags();
+};
+
+#endif /*POSIX_FILESYSTEM_H*/
diff --git a/backends/fs/ps2/ps2-fs-factory.cpp b/backends/fs/ps2/ps2-fs-factory.cpp
index ce3b4a5eaf..e96671ee0a 100644
--- a/backends/fs/ps2/ps2-fs-factory.cpp
+++ b/backends/fs/ps2/ps2-fs-factory.cpp
@@ -36,7 +36,7 @@ AbstractFilesystemNode *Ps2FilesystemFactory::makeCurrentDirectoryFileNode() con
return new Ps2FilesystemNode();
}
-AbstractFilesystemNode *Ps2FilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *Ps2FilesystemFactory::makeFileNodePath(const Common::String &path) const {
// return new Ps2FilesystemNode(path);
Ps2FilesystemNode *nf = new Ps2FilesystemNode(path, true);
diff --git a/backends/fs/ps2/ps2-fs-factory.h b/backends/fs/ps2/ps2-fs-factory.h
index 416024c905..432cf467c3 100644
--- a/backends/fs/ps2/ps2-fs-factory.h
+++ b/backends/fs/ps2/ps2-fs-factory.h
@@ -35,11 +35,9 @@
*/
class Ps2FilesystemFactory : public FilesystemFactory, public Common::Singleton<Ps2FilesystemFactory> {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
protected:
Ps2FilesystemFactory() {};
diff --git a/backends/fs/ps2/ps2-fs.cpp b/backends/fs/ps2/ps2-fs.cpp
index 782e97b959..3d7656e9f0 100644
--- a/backends/fs/ps2/ps2-fs.cpp
+++ b/backends/fs/ps2/ps2-fs.cpp
@@ -23,6 +23,7 @@
*/
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/stdiostream.h"
#include <kernel.h>
#include <stdio.h>
#include <stdlib.h>
@@ -47,8 +48,8 @@ class Ps2FilesystemNode : public AbstractFilesystemNode {
friend class Ps2FilesystemFactory;
protected:
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory;
bool _isRoot;
@@ -65,10 +66,10 @@ public:
/**
* Creates a PS2FilesystemNode for a given path.
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
*/
- Ps2FilesystemNode(const String &path);
- Ps2FilesystemNode(const String &path, bool verify);
+ Ps2FilesystemNode(const Common::String &path);
+ Ps2FilesystemNode(const Common::String &path, bool verify);
/**
* Copy constructor.
@@ -77,9 +78,9 @@ public:
virtual bool exists(void) const;
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const {
return _isDirectory;
@@ -95,32 +96,13 @@ public:
}
virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); }
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
-};
-
-/**
- * Returns the last component of a given path.
- *
- * @param str String containing the path.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if (str.empty())
- return "";
-
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '/' && *cur != ':') {
- --cur;
- }
-
- printf("romeo : lastPathComponent = %s\n", cur + 1);
- return cur + 1;
-}
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+};
Ps2FilesystemNode::Ps2FilesystemNode() {
_isDirectory = true;
@@ -129,12 +111,12 @@ Ps2FilesystemNode::Ps2FilesystemNode() {
_path = "";
}
-Ps2FilesystemNode::Ps2FilesystemNode(const String &path) {
+Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path) {
_path = path;
_isDirectory = true;
if (strcmp(path.c_str(), "") == 0) {
_isRoot = true;
- _displayName = String("PlayStation 2");
+ _displayName = Common::String("PlayStation 2");
} else {
_isRoot = false;
const char *dsplName = NULL, *pos = path.c_str();
@@ -142,18 +124,18 @@ Ps2FilesystemNode::Ps2FilesystemNode(const String &path) {
if (*pos++ == '/')
dsplName = pos;
if (dsplName)
- _displayName = String(dsplName);
+ _displayName = Common::String(dsplName);
else
_displayName = getDeviceDescription(path.c_str());
}
}
-Ps2FilesystemNode::Ps2FilesystemNode(const String &path, bool verify) {
+Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path, bool verify) {
_path = path;
if (strcmp(path.c_str(), "") == 0) {
_isRoot = true; /* root is always a dir*/
- _displayName = String("PlayStation 2");
+ _displayName = Common::String("PlayStation 2");
_isDirectory = true;
} else {
_isRoot = false;
@@ -163,7 +145,7 @@ Ps2FilesystemNode::Ps2FilesystemNode(const String &path, bool verify) {
dsplName = pos;
if (dsplName) {
- _displayName = String(dsplName);
+ _displayName = Common::String(dsplName);
if (verify)
_isDirectory = getDirectoryFlag(path.c_str());
else
@@ -228,7 +210,7 @@ bool Ps2FilesystemNode::getDirectoryFlag(const char *path) {
return false;
}
-AbstractFilesystemNode *Ps2FilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *Ps2FilesystemNode::getChild(const Common::String &n) const {
if (!_isDirectory)
return NULL;
@@ -306,9 +288,9 @@ bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hi
while ((dreadRes = fio.dread(fd, &dirent)) > 0) {
if (dirent.name[0] == '.')
continue; // ignore '.' and '..'
- if (((mode == FilesystemNode::kListDirectoriesOnly) && (dirent.stat.mode & FIO_S_IFDIR)) ||
- ((mode == FilesystemNode::kListFilesOnly) && !(dirent.stat.mode & FIO_S_IFDIR)) ||
- (mode == FilesystemNode::kListAll)) {
+ if (((mode == Common::FilesystemNode::kListDirectoriesOnly) && (dirent.stat.mode & FIO_S_IFDIR)) ||
+ ((mode == Common::FilesystemNode::kListFilesOnly) && !(dirent.stat.mode & FIO_S_IFDIR)) ||
+ (mode == Common::FilesystemNode::kListAll)) {
dirEntry._isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR);
dirEntry._isRoot = false;
@@ -344,7 +326,7 @@ AbstractFilesystemNode *Ps2FilesystemNode::getParent() const {
}
if (slash)
- return new Ps2FilesystemNode(String(_path.c_str(), slash - _path.c_str()));
+ return new Ps2FilesystemNode(Common::String(_path.c_str(), slash - _path.c_str()));
else
return new Ps2FilesystemNode();
}
@@ -359,3 +341,10 @@ char *Ps2FilesystemNode::getDeviceDescription(const char *path) const {
return "Harddisk";
}
+Common::SeekableReadStream *Ps2FilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *Ps2FilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
+}
diff --git a/backends/fs/psp/psp-fs-factory.cpp b/backends/fs/psp/psp-fs-factory.cpp
index 87f0e0f587..a38462f02a 100644
--- a/backends/fs/psp/psp-fs-factory.cpp
+++ b/backends/fs/psp/psp-fs-factory.cpp
@@ -36,7 +36,7 @@ AbstractFilesystemNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() con
return new PSPFilesystemNode();
}
-AbstractFilesystemNode *PSPFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *PSPFilesystemFactory::makeFileNodePath(const Common::String &path) const {
return new PSPFilesystemNode(path, true);
}
#endif
diff --git a/backends/fs/psp/psp-fs-factory.h b/backends/fs/psp/psp-fs-factory.h
index ffa934755f..abf03d288e 100644
--- a/backends/fs/psp/psp-fs-factory.h
+++ b/backends/fs/psp/psp-fs-factory.h
@@ -35,11 +35,9 @@
*/
class PSPFilesystemFactory : public FilesystemFactory, public Common::Singleton<PSPFilesystemFactory> {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
protected:
PSPFilesystemFactory() {};
diff --git a/backends/fs/psp/psp-fs.cpp b/backends/fs/psp/psp-fs.cpp
index 3fe6060928..13cd63903b 100644
--- a/backends/fs/psp/psp-fs.cpp
+++ b/backends/fs/psp/psp-fs.cpp
@@ -26,6 +26,7 @@
#include "engines/engine.h"
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/stdiostream.h"
#include <sys/stat.h>
#include <unistd.h>
@@ -39,8 +40,8 @@
*/
class PSPFilesystemNode : public AbstractFilesystemNode {
protected:
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory;
bool _isValid;
@@ -53,47 +54,26 @@ public:
/**
* Creates a PSPFilesystemNode for a given path.
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
* @param verify true if the isValid and isDirectory flags should be verified during the construction.
*/
PSPFilesystemNode(const Common::String &p, bool verify);
virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
-};
-
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * /foo/bar.txt would return /bar.txt
- * /foo/bar/ would return /bar/
- *
- * @param str String containing the path.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if(str.empty())
- return "";
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '/') {
- --cur;
- }
-
- return cur + 1;
-}
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+};
PSPFilesystemNode::PSPFilesystemNode() {
_isDirectory = true;
@@ -106,7 +86,7 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
assert(p.size() > 0);
_path = p;
- _displayName = lastPathComponent(_path);
+ _displayName = lastPathComponent(_path, '/');
_isValid = true;
_isDirectory = true;
@@ -117,12 +97,12 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
}
}
-AbstractFilesystemNode *PSPFilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *PSPFilesystemNode::getChild(const Common::String &n) const {
// FIXME: Pretty lame implementation! We do no error checking to speak
// of, do not check if this is a special node, etc.
assert(_isDirectory);
- String newPath(_path);
+ Common::String newPath(_path);
if (_path.lastChar() != '/')
newPath += '/';
newPath += n;
@@ -157,8 +137,8 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
entry._path += "/";
// Honor the chosen mode
- if ((mode == FilesystemNode::kListFilesOnly && entry._isDirectory) ||
- (mode == FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
+ if ((mode == Common::FilesystemNode::kListFilesOnly && entry._isDirectory) ||
+ (mode == Common::FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
continue;
myList.push_back(new PSPFilesystemNode(entry));
@@ -176,9 +156,17 @@ AbstractFilesystemNode *PSPFilesystemNode::getParent() const {
return 0;
const char *start = _path.c_str();
- const char *end = lastPathComponent(_path);
+ const char *end = lastPathComponent(_path, '/');
+
+ return new PSPFilesystemNode(Common::String(start, end - start), false);
+}
+
+Common::SeekableReadStream *PSPFilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
- return new PSPFilesystemNode(String(start, end - start), false);
+Common::WriteStream *PSPFilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
}
#endif //#ifdef __PSP__
diff --git a/backends/fs/stdiostream.cpp b/backends/fs/stdiostream.cpp
new file mode 100644
index 0000000000..3b0de253ab
--- /dev/null
+++ b/backends/fs/stdiostream.cpp
@@ -0,0 +1,161 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 "backends/fs/stdiostream.h"
+
+#include <errno.h>
+
+#if defined(MACOSX) || defined(IPHONE)
+#include "CoreFoundation/CoreFoundation.h"
+#endif
+
+
+#ifdef __PLAYSTATION2__
+ // for those replaced fopen/fread/etc functions
+ typedef unsigned long uint64;
+ typedef signed long int64;
+ #include "backends/platform/ps2/fileio.h"
+
+ #define fopen(a, b) ps2_fopen(a, b)
+ #define fclose(a) ps2_fclose(a)
+ #define fseek(a, b, c) ps2_fseek(a, b, c)
+ #define ftell(a) ps2_ftell(a)
+ #define feof(a) ps2_feof(a)
+ #define fread(a, b, c, d) ps2_fread(a, b, c, d)
+ #define fwrite(a, b, c, d) ps2_fwrite(a, b, c, d)
+
+ //#define fprintf ps2_fprintf // used in common/util.cpp
+ //#define fflush(a) ps2_fflush(a) // used in common/util.cpp
+
+ //#define fgetc(a) ps2_fgetc(a) // not used
+ //#define fgets(a, b, c) ps2_fgets(a, b, c) // not used
+ //#define fputc(a, b) ps2_fputc(a, b) // not used
+ //#define fputs(a, b) ps2_fputs(a, b) // not used
+
+ //#define fsize(a) ps2_fsize(a) // not used -- and it is not a standard function either
+#endif
+
+#ifdef __DS__
+
+ // These functions replace the standard library functions of the same name.
+ // As this header is included after the standard one, I have the chance to #define
+ // all of these to my own code.
+ //
+ // A #define is the only way, as redefinig the functions would cause linker errors.
+
+ // These functions need to be #undef'ed, as their original definition
+ // in devkitarm is done with #includes (ugh!)
+ #undef feof
+ #undef clearerr
+ //#undef getc
+ //#undef ferror
+
+ #include "backends/fs/ds/ds-fs.h"
+
+
+ // Only functions used in the ScummVM source have been defined here!
+ #define fopen(name, mode) DS::std_fopen(name, mode)
+ #define fclose(handle) DS::std_fclose(handle)
+ #define fread(ptr, size, items, file) DS::std_fread(ptr, size, items, file)
+ #define fwrite(ptr, size, items, file) DS::std_fwrite(ptr, size, items, file)
+ #define feof(handle) DS::std_feof(handle)
+ #define ftell(handle) DS::std_ftell(handle)
+ #define fseek(handle, offset, whence) DS::std_fseek(handle, offset, whence)
+ #define clearerr(handle) DS::std_clearerr(handle)
+ #define fflush(file) DS::std_fflush(file)
+ #define ferror(handle) DS::std_ferror(handle)
+
+#endif
+
+StdioStream::StdioStream(void *handle) : _handle(handle) {
+ assert(handle);
+}
+
+StdioStream::~StdioStream() {
+ fclose((FILE *)_handle);
+}
+
+bool StdioStream::err() const {
+ return ferror((FILE *)_handle) != 0;
+}
+
+void StdioStream::clearErr() {
+ clearerr((FILE *)_handle);
+}
+
+bool StdioStream::eos() const {
+ return feof((FILE *)_handle) != 0;
+}
+
+int32 StdioStream::pos() const {
+ return ftell((FILE *)_handle);
+}
+
+int32 StdioStream::size() const {
+ int32 oldPos = ftell((FILE *)_handle);
+ fseek((FILE *)_handle, 0, SEEK_END);
+ int32 length = ftell((FILE *)_handle);
+ fseek((FILE *)_handle, oldPos, SEEK_SET);
+
+ return length;
+}
+
+bool StdioStream::seek(int32 offs, int whence) {
+ return fseek((FILE *)_handle, offs, whence) == 0;
+}
+
+uint32 StdioStream::read(void *ptr, uint32 len) {
+ return fread((byte *)ptr, 1, len, (FILE *)_handle);
+}
+
+uint32 StdioStream::write(const void *ptr, uint32 len) {
+ return fwrite(ptr, 1, len, (FILE *)_handle);
+}
+
+bool StdioStream::flush() {
+ return fflush((FILE *)_handle) == 0;
+}
+
+StdioStream *StdioStream::makeFromPath(const Common::String &path, bool writeMode) {
+ FILE *handle = fopen(path.c_str(), writeMode ? "wb" : "rb");
+
+#ifdef __amigaos4__
+ //
+ // Work around for possibility that someone uses AmigaOS "newlib" build
+ // with SmartFileSystem (blocksize 512 bytes), leading to buffer size
+ // being only 512 bytes. "Clib2" sets the buffer size to 8KB, resulting
+ // smooth movie playback. This forces the buffer to be enough also when
+ // using "newlib" compile on SFS.
+ //
+ if (handle && !writeMode) {
+ setvbuf(handle, NULL, _IOFBF, 8192);
+ }
+#endif
+
+
+ if (handle)
+ return new StdioStream(handle);
+ return 0;
+}
diff --git a/backends/fs/stdiostream.h b/backends/fs/stdiostream.h
new file mode 100644
index 0000000000..3d44062d7f
--- /dev/null
+++ b/backends/fs/stdiostream.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 BACKENDS_FS_STDIOSTREAM_H
+#define BACKENDS_FS_STDIOSTREAM_H
+
+#include "common/scummsys.h"
+#include "common/noncopyable.h"
+#include "common/stream.h"
+#include "common/str.h"
+
+class StdioStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable {
+protected:
+ /** File handle to the actual file. */
+ void *_handle;
+
+public:
+ /**
+ * Given a path, invokes fopen on that path and wrap the result in a
+ * StdioStream instance.
+ */
+ static StdioStream *makeFromPath(const Common::String &path, bool writeMode);
+
+ StdioStream(void *handle);
+ virtual ~StdioStream();
+
+ bool err() const;
+ void clearErr();
+ bool eos() const;
+
+ virtual uint32 write(const void *dataPtr, uint32 dataSize);
+ virtual bool flush();
+
+ virtual int32 pos() const;
+ virtual int32 size() const;
+ bool seek(int32 offs, int whence = SEEK_SET);
+ uint32 read(void *dataPtr, uint32 dataSize);
+};
+
+#endif
diff --git a/backends/fs/symbian/symbian-fs-factory.cpp b/backends/fs/symbian/symbian-fs-factory.cpp
index 0a1bd62134..c31dfb594a 100644
--- a/backends/fs/symbian/symbian-fs-factory.cpp
+++ b/backends/fs/symbian/symbian-fs-factory.cpp
@@ -26,8 +26,6 @@
#include "backends/fs/symbian/symbian-fs-factory.h"
#include "backends/fs/symbian/symbian-fs.cpp"
-DECLARE_SINGLETON(SymbianFilesystemFactory);
-
AbstractFilesystemNode *SymbianFilesystemFactory::makeRootFileNode() const {
return new SymbianFilesystemNode(true);
}
@@ -38,7 +36,7 @@ AbstractFilesystemNode *SymbianFilesystemFactory::makeCurrentDirectoryFileNode()
return new SymbianFilesystemNode(path);
}
-AbstractFilesystemNode *SymbianFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *SymbianFilesystemFactory::makeFileNodePath(const Common::String &path) const {
return new SymbianFilesystemNode(path);
}
#endif
diff --git a/backends/fs/symbian/symbian-fs-factory.h b/backends/fs/symbian/symbian-fs-factory.h
index 502fba2930..ef5a231e72 100644
--- a/backends/fs/symbian/symbian-fs-factory.h
+++ b/backends/fs/symbian/symbian-fs-factory.h
@@ -25,7 +25,6 @@
#ifndef SYMBIAN_FILESYSTEM_FACTORY_H
#define SYMBIAN_FILESYSTEM_FACTORY_H
-#include "common/singleton.h"
#include "backends/fs/fs-factory.h"
/**
@@ -33,19 +32,11 @@
*
* Parts of this class are documented in the base interface class, FilesystemFactory.
*/
-class SymbianFilesystemFactory : public FilesystemFactory, public Common::Singleton<SymbianFilesystemFactory> {
+class SymbianFilesystemFactory : public FilesystemFactory {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
-
-protected:
- SymbianFilesystemFactory() {};
-
-private:
- friend class Common::Singleton<SingletonBaseType>;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
};
#endif /*SYMBIAN_FILESYSTEM_FACTORY_H*/
diff --git a/backends/fs/symbian/symbian-fs.cpp b/backends/fs/symbian/symbian-fs.cpp
index 85fc58179a..1c6d8435a9 100644
--- a/backends/fs/symbian/symbian-fs.cpp
+++ b/backends/fs/symbian/symbian-fs.cpp
@@ -24,12 +24,16 @@
#if defined (__SYMBIAN32__)
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/symbian/symbianstream.h"
+#include "backends/platform/symbian/src/symbianos.h"
#include <dirent.h>
#include <eikenv.h>
#include <f32file.h>
#include <bautils.h>
+#define KDriveLabelSize 30
+
/**
* Implementation of the ScummVM file system API based on POSIX.
*
@@ -37,12 +41,11 @@
*/
class SymbianFilesystemNode : public AbstractFilesystemNode {
protected:
- String _displayName;
- String _path;
- bool _isDirectory;
- bool _isValid;
- bool _isPseudoRoot;
-
+ Common::String _displayName;
+ Common::String _path;
+ TBool _isDirectory;
+ TBool _isValid;
+ TBool _isPseudoRoot;
public:
/**
* Creates a SymbianFilesystemNode with the root node as path.
@@ -54,57 +57,36 @@ public:
/**
* Creates a SymbianFilesystemNode for a given path.
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
*/
- SymbianFilesystemNode(const String &path);
+ SymbianFilesystemNode(const Common::String &path);
virtual bool exists() const {
TFileName fname;
- TPtrC8 ptr((const unsigned char*)_path.c_str(),_path.size());
+ TPtrC8 ptr((const unsigned char*) _path.c_str(), _path.size());
fname.Copy(ptr);
- TBool fileExists = BaflUtils::FileExists(CEikonEnv::Static()->FsSession(), fname);
+ TBool fileExists = BaflUtils::FileExists(static_cast<OSystem_SDL_Symbian*> (g_system)->FsSession(), fname);
return fileExists;
}
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } //FIXME: this is just a stub
virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } //FIXME: this is just a stub
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
-};
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * c:\foo\bar.txt would return "\bar.txt"
- * c:\foo\bar\ would return "\bar\"
- *
- * @param str Path to obtain the last component from.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if(str.empty())
- return "";
-
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '\\') {
- --cur;
- }
-
- return cur + 1;
-}
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+};
/**
* Fixes the path by changing all slashes to backslashes.
*
- * @param path String with the path to be fixed.
+ * @param path Common::String with the path to be fixed.
*/
static void fixFilePath(Common::String& aPath){
TInt len = aPath.size();
@@ -118,54 +100,47 @@ static void fixFilePath(Common::String& aPath){
SymbianFilesystemNode::SymbianFilesystemNode(bool aIsRoot) {
_path = "";
- _isValid = true;
- _isDirectory = true;
+ _isValid = ETrue;
+ _isDirectory = ETrue;
_isPseudoRoot = aIsRoot;
_displayName = "Root";
}
-SymbianFilesystemNode::SymbianFilesystemNode(const String &path) {
+SymbianFilesystemNode::SymbianFilesystemNode(const Common::String &path) {
if (path.size() == 0)
- _isPseudoRoot = true;
+ _isPseudoRoot = ETrue;
else
- _isPseudoRoot = false;
+ _isPseudoRoot = EFalse;
_path = path;
fixFilePath(_path);
- _displayName = lastPathComponent(_path);
+ _displayName = lastPathComponent(_path, '\\');
TEntry fileAttribs;
TFileName fname;
TPtrC8 ptr((const unsigned char*)_path.c_str(),_path.size());
fname.Copy(ptr);
- if (CEikonEnv::Static()->FsSession().Entry(fname, fileAttribs) == KErrNone) {
- _isValid = true;
+ if (static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession().Entry(fname, fileAttribs) == KErrNone) {
+ _isValid = ETrue;
_isDirectory = fileAttribs.IsDir();
} else {
- _isValid = false;
- _isDirectory = false;
+ _isValid = ETrue;
+ _isDirectory = EFalse;
}
}
-AbstractFilesystemNode *SymbianFilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *SymbianFilesystemNode::getChild(const Common::String &n) const {
assert(_isDirectory);
- String newPath(_path);
+ Common::String newPath(_path);
if (_path.lastChar() != '\\')
newPath += '\\';
- newPath += n;
- TPtrC8 ptr((const unsigned char*) newPath.c_str(), newPath.size());
- TFileName fname;
- fname.Copy(ptr);
- TBool isFolder = EFalse;
- BaflUtils::IsFolder(CEikonEnv::Static()->FsSession(), fname, isFolder);
- if (!isFolder)
- return 0;
+ newPath += n;
return new SymbianFilesystemNode(newPath);
}
@@ -177,19 +152,19 @@ bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
if (_isPseudoRoot) {
// Drives enumeration
- RFs fs = CEikonEnv::Static()->FsSession();
+ RFs& fs = static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession();
TInt driveNumber;
TChar driveLetter;
TUint driveLetterValue;
TVolumeInfo volumeInfo;
- TBuf8<30> driveLabel8;
- TBuf8<30> driveString8;
+ TBuf8<KDriveLabelSize> driveLabel8;
+ TBuf8<KDriveLabelSize> driveString8;
for (driveNumber=EDriveA; driveNumber<=EDriveZ; driveNumber++) {
TInt err = fs.Volume(volumeInfo, driveNumber);
if (err != KErrNone)
continue;
- if (fs.DriveToChar(driveNumber,driveLetter) != KErrNone)
+ if (fs.DriveToChar(driveNumber, driveLetter) != KErrNone)
continue;
driveLetterValue = driveLetter;
@@ -205,40 +180,46 @@ bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b
sprintf(path,"%c:\\", driveNumber+'A');
SymbianFilesystemNode entry(false);
- entry._displayName = (char*)driveString8.PtrZ(); // drive_name
- entry._isDirectory = true;
- entry._isValid = true;
- entry._isPseudoRoot = false;
+ entry._displayName = (char*) driveString8.PtrZ(); // drive_name
+ entry._isDirectory = ETrue;
+ entry._isValid = ETrue;
+ entry._isPseudoRoot = EFalse;
entry._path = path;
myList.push_back(new SymbianFilesystemNode(entry));
}
} else {
- TPtrC8 ptr((const unsigned char*)_path.c_str(),_path.size());
+ TPtrC8 ptr((const unsigned char*) _path.c_str(), _path.size());
TFileName fname;
- fname.Copy(ptr);
TBuf8<256>nameBuf;
CDir* dirPtr;
- if (CEikonEnv::Static()->FsSession().GetDir(fname,KEntryAttNormal|KEntryAttDir,0,dirPtr)==KErrNone) {
+ fname.Copy(ptr);
+
+ if (_path.lastChar() != '\\')
+ fname.Append('\\');
+
+ if (static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession().GetDir(fname, KEntryAttNormal|KEntryAttDir, 0, dirPtr) == KErrNone) {
CleanupStack::PushL(dirPtr);
TInt cnt=dirPtr->Count();
for (TInt loop=0;loop<cnt;loop++) {
TEntry fileentry=(*dirPtr)[loop];
nameBuf.Copy(fileentry.iName);
- SymbianFilesystemNode entry(false);
- entry._isPseudoRoot = false;
+ SymbianFilesystemNode entry(EFalse);
+ entry._isPseudoRoot = EFalse;
- entry._displayName =(char*)nameBuf.PtrZ();
+ entry._displayName =(char*) nameBuf.PtrZ();
entry._path = _path;
- entry._path +=(char*)nameBuf.PtrZ();
+
+ if (entry._path.lastChar() != '\\')
+ entry._path+= '\\';
+
+ entry._path +=(char*) nameBuf.PtrZ();
entry._isDirectory = fileentry.IsDir();
// Honor the chosen mode
- if ((mode == FilesystemNode::kListFilesOnly && entry._isDirectory) ||
- (mode == FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
+ if ((mode == Common::FilesystemNode::kListFilesOnly && entry._isDirectory) ||
+ (mode == Common::FilesystemNode::kListDirectoriesOnly && !entry._isDirectory))
continue;
-
- if (entry._isDirectory)
- entry._path += "\\";
+
myList.push_back(new SymbianFilesystemNode(entry));
}
CleanupStack::PopAndDestroy(dirPtr);
@@ -254,21 +235,30 @@ AbstractFilesystemNode *SymbianFilesystemNode::getParent() const {
// Root node is its own parent. Still we can't just return this
// as the GUI code will call delete on the old node.
if (!_isPseudoRoot && _path.size() > 3) {
- p = new SymbianFilesystemNode(false);
+ p = new SymbianFilesystemNode(EFalse);
const char *start = _path.c_str();
- const char *end = lastPathComponent(_path);
+ const char *end = lastPathComponent(_path, '\\');
- p->_path = String(start, end - start);
- p->_isValid = true;
- p->_isDirectory = true;
- p->_displayName = lastPathComponent(p->_path);
+ p->_path = Common::String(start, end - start);
+ p->_isValid = ETrue;
+ p->_isDirectory = ETrue;
+ p->_displayName = lastPathComponent(p->_path, '\\');
}
else
{
- p = new SymbianFilesystemNode(true);
+ p = new SymbianFilesystemNode(ETrue);
}
return p;
}
+Common::SeekableReadStream *SymbianFilesystemNode::openForReading() {
+ return SymbianStdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *SymbianFilesystemNode::openForWriting() {
+ return SymbianStdioStream::makeFromPath(getPath().c_str(), true);
+}
#endif //#if defined (__SYMBIAN32__)
+
+
diff --git a/backends/fs/symbian/symbianstream.cpp b/backends/fs/symbian/symbianstream.cpp
new file mode 100644
index 0000000000..5944cab892
--- /dev/null
+++ b/backends/fs/symbian/symbianstream.cpp
@@ -0,0 +1,274 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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/scummsys.h"
+#include "backends/fs/symbian/symbianstream.h"
+#include "common/system.h"
+#include "backends/platform/symbian/src/symbianos.h"
+
+#include <f32file.h>
+
+#define KInputBufferLength 128
+
+// Symbian libc file functionality in order to provide shared file handles
+class TSymbianFileEntry {
+public:
+ RFile _fileHandle;
+ char _inputBuffer[KInputBufferLength];
+ TInt _inputBufferLen;
+ TInt _inputPos;
+ TInt _lastError;
+ TBool _eofReached;
+};
+
+TSymbianFileEntry* CreateSymbianFileEntry(const char* name, const char* mode) {
+ TSymbianFileEntry* fileEntry = new TSymbianFileEntry;
+ fileEntry->_inputPos = KErrNotFound;
+ fileEntry->_lastError = 0;
+ fileEntry->_eofReached = EFalse;
+
+ if (fileEntry != NULL) {
+ TInt modeLen = strlen(mode);
+
+ TPtrC8 namePtr((unsigned char*) name, strlen(name));
+ TFileName tempFileName;
+ tempFileName.Copy(namePtr);
+
+ TInt fileMode = EFileRead;
+
+ if (mode[0] == 'a')
+ fileMode = EFileWrite;
+
+ if (!((modeLen > 1 && mode[1] == 'b') || (modeLen > 2 && mode[2] == 'b'))) {
+ fileMode |= EFileStreamText;
+ }
+
+ if ((modeLen > 1 && mode[1] == '+') || (modeLen > 2 && mode[2] == '+')) {
+ fileMode = fileMode| EFileWrite;
+ }
+
+ fileMode = fileMode| EFileShareAny;
+
+ switch(mode[0]) {
+ case 'a':
+ if (fileEntry->_fileHandle.Open(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ if (fileEntry->_fileHandle.Create(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ delete fileEntry;
+ fileEntry = NULL;
+ }
+ }
+ break;
+ case 'r':
+ if (fileEntry->_fileHandle.Open(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ delete fileEntry;
+ fileEntry = NULL;
+ }
+ break;
+
+ case 'w':
+ if (fileEntry->_fileHandle.Replace(static_cast<OSystem_SDL_Symbian*>(g_system)->FsSession(), tempFileName, fileMode) != KErrNone) {
+ delete fileEntry;
+ fileEntry = NULL;
+ }
+ break;
+ }
+ }
+ return fileEntry;
+}
+
+size_t ReadData(const void* ptr, size_t size, size_t numItems, TSymbianFileEntry* handle) {
+ TSymbianFileEntry* entry = ((TSymbianFileEntry*)(handle));
+ TUint32 totsize = size*numItems;
+ TPtr8 pointer ( (unsigned char*) ptr, totsize);
+
+ // Nothing cached and we want to load at least KInputBufferLength bytes
+ if (totsize >= KInputBufferLength) {
+ TUint32 totLength = 0;
+ if (entry->_inputPos != KErrNotFound) {
+ TPtr8 cacheBuffer( (unsigned char*) entry->_inputBuffer+entry->_inputPos, entry->_inputBufferLen - entry->_inputPos, KInputBufferLength);
+ pointer.Append(cacheBuffer);
+ entry->_inputPos = KErrNotFound;
+ totLength+=pointer.Length();
+ pointer.Set(totLength+(unsigned char*) ptr, 0, totsize-totLength);
+ }
+
+ entry->_lastError = entry->_fileHandle.Read(pointer);
+
+ totLength+=pointer.Length();
+
+ pointer.Set((unsigned char*) ptr, totLength, totsize);
+
+ } else {
+ // Nothing in buffer
+ if (entry->_inputPos == KErrNotFound) {
+ TPtr8 cacheBuffer( (unsigned char*) entry->_inputBuffer, KInputBufferLength);
+ entry->_lastError = entry->_fileHandle.Read(cacheBuffer);
+
+ if (cacheBuffer.Length() >= totsize) {
+ pointer.Copy(cacheBuffer.Left(totsize));
+ entry->_inputPos = totsize;
+ entry->_inputBufferLen = cacheBuffer.Length();
+ } else {
+ pointer.Copy(cacheBuffer);
+ entry->_inputPos = KErrNotFound;
+ }
+
+ } else {
+ TPtr8 cacheBuffer( (unsigned char*) entry->_inputBuffer, entry->_inputBufferLen, KInputBufferLength);
+
+ if (entry->_inputPos+totsize < entry->_inputBufferLen) {
+ pointer.Copy(cacheBuffer.Mid(entry->_inputPos, totsize));
+ entry->_inputPos+=totsize;
+ } else {
+
+ pointer.Copy(cacheBuffer.Mid(entry->_inputPos, entry->_inputBufferLen-entry->_inputPos));
+ cacheBuffer.SetLength(0);
+ entry->_lastError = entry->_fileHandle.Read(cacheBuffer);
+
+ if (cacheBuffer.Length() >= totsize-pointer.Length()) {
+ TUint32 restSize = totsize-pointer.Length();
+ pointer.Append(cacheBuffer.Left(restSize));
+ entry->_inputPos = restSize;
+ entry->_inputBufferLen = cacheBuffer.Length();
+ } else {
+ pointer.Append(cacheBuffer);
+ entry->_inputPos = KErrNotFound;
+ }
+ }
+ }
+ }
+
+ if((numItems * size) != pointer.Length() && entry->_lastError == KErrNone) {
+ entry->_eofReached = ETrue;
+ }
+
+ return pointer.Length() / size;
+}
+
+SymbianStdioStream::SymbianStdioStream(void *handle) : _handle(handle) {
+ assert(handle);
+}
+
+SymbianStdioStream::~SymbianStdioStream() {
+ ((TSymbianFileEntry*)(_handle))->_fileHandle.Close();
+
+ delete (TSymbianFileEntry*)(_handle);
+}
+
+bool SymbianStdioStream::err() const {
+ return ((TSymbianFileEntry*)(_handle))->_lastError != 0;
+}
+
+void SymbianStdioStream::clearErr() {
+ ((TSymbianFileEntry*)(_handle))->_lastError = 0;
+ ((TSymbianFileEntry*)(_handle))->_eofReached = 0;
+}
+
+bool SymbianStdioStream::eos() const {
+ TSymbianFileEntry* entry = ((TSymbianFileEntry*)(_handle));
+
+ return entry->_eofReached != 0;
+}
+
+int32 SymbianStdioStream::pos() const {
+ TInt pos = 0;
+ TSymbianFileEntry* entry = ((TSymbianFileEntry*)(_handle));
+
+ entry->_lastError = entry->_fileHandle.Seek(ESeekCurrent, pos);
+ if (entry->_lastError == KErrNone && entry->_inputPos != KErrNotFound) {
+ pos += (entry->_inputPos - entry->_inputBufferLen);
+ }
+
+ return pos;
+}
+
+int32 SymbianStdioStream::size() const {
+
+ TInt length = 0;
+ ((TSymbianFileEntry*)(_handle))->_fileHandle.Size(length);
+
+ return length;
+}
+
+bool SymbianStdioStream::seek(int32 offs, int whence) {
+ assert(_handle);
+
+ TSeek seekMode = ESeekStart;
+ TInt pos = offs;
+ TSymbianFileEntry* entry = ((TSymbianFileEntry*)(_handle));
+
+ switch (whence) {
+ case SEEK_SET:
+ seekMode = ESeekStart;
+ break;
+ case SEEK_CUR:
+ seekMode = ESeekCurrent;
+ if (entry->_inputPos != KErrNotFound) {
+ pos += (entry->_inputPos - entry->_inputBufferLen);
+ }
+ break;
+ case SEEK_END:
+ seekMode = ESeekEnd;
+ break;
+
+ }
+
+ entry->_inputPos = KErrNotFound;
+ entry->_eofReached = EFalse;
+ entry->_fileHandle.Seek(seekMode, pos);
+
+ return true; // FIXME: Probably should return a value based on what _fileHandle.Seek returns
+}
+
+uint32 SymbianStdioStream::read(void *ptr, uint32 len) {
+ return (uint32)ReadData((byte *)ptr, 1, len, (TSymbianFileEntry *)_handle);
+}
+
+uint32 SymbianStdioStream::write(const void *ptr, uint32 len) {
+ TPtrC8 pointer( (unsigned char*) ptr, len);
+
+ ((TSymbianFileEntry*)(_handle))->_inputPos = KErrNotFound;
+ ((TSymbianFileEntry*)(_handle))->_lastError = ((TSymbianFileEntry*)(_handle))->_fileHandle.Write(pointer);
+ ((TSymbianFileEntry*)(_handle))->_eofReached = EFalse;
+
+ if (((TSymbianFileEntry*)(_handle))->_lastError == KErrNone) {
+ return len;
+ }
+
+ return 0;
+}
+
+bool SymbianStdioStream::flush() {
+ ((TSymbianFileEntry*)(_handle))->_fileHandle.Flush();
+ return true;
+}
+
+SymbianStdioStream *SymbianStdioStream::makeFromPath(const Common::String &path, bool writeMode) {
+ void *handle = CreateSymbianFileEntry(path.c_str(), writeMode ? "wb" : "rb");
+ if (handle)
+ return new SymbianStdioStream(handle);
+ return 0;
+}
+
diff --git a/backends/fs/symbian/symbianstream.h b/backends/fs/symbian/symbianstream.h
new file mode 100644
index 0000000000..d783856687
--- /dev/null
+++ b/backends/fs/symbian/symbianstream.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 BACKENDS_FS_SYMBIANSTDIOSTREAM_H
+#define BACKENDS_FS_SYMBIANSTDIOSTREAM_H
+
+#include "common/scummsys.h"
+#include "common/noncopyable.h"
+#include "common/stream.h"
+#include "common/str.h"
+
+class SymbianStdioStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable {
+protected:
+ /** File handle to the actual file. */
+ void *_handle;
+
+public:
+ /**
+ * Given a path, invokes fopen on that path and wrap the result in a
+ * StdioStream instance.
+ */
+ static SymbianStdioStream *makeFromPath(const Common::String &path, bool writeMode);
+
+ SymbianStdioStream(void *handle);
+ virtual ~SymbianStdioStream();
+
+ bool err() const;
+ void clearErr();
+ bool eos() const;
+
+ virtual uint32 write(const void *dataPtr, uint32 dataSize);
+ virtual bool flush();
+
+ virtual int32 pos() const;
+ virtual int32 size() const;
+ bool seek(int32 offs, int whence = SEEK_SET);
+ uint32 read(void *dataPtr, uint32 dataSize);
+};
+
+#endif
diff --git a/backends/fs/wii/wii-fs-factory.cpp b/backends/fs/wii/wii-fs-factory.cpp
index 9839858dd5..69086a95f1 100644
--- a/backends/fs/wii/wii-fs-factory.cpp
+++ b/backends/fs/wii/wii-fs-factory.cpp
@@ -42,7 +42,7 @@ AbstractFilesystemNode *WiiFilesystemFactory::makeCurrentDirectoryFileNode() con
return new WiiFilesystemNode();
}
-AbstractFilesystemNode *WiiFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *WiiFilesystemFactory::makeFileNodePath(const Common::String &path) const {
return new WiiFilesystemNode(path, true);
}
#endif
diff --git a/backends/fs/wii/wii-fs-factory.h b/backends/fs/wii/wii-fs-factory.h
index 24badee330..36867a392c 100644
--- a/backends/fs/wii/wii-fs-factory.h
+++ b/backends/fs/wii/wii-fs-factory.h
@@ -33,11 +33,9 @@
*/
class WiiFilesystemFactory : public FilesystemFactory, public Common::Singleton<WiiFilesystemFactory> {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
protected:
WiiFilesystemFactory() {};
diff --git a/backends/fs/wii/wii-fs.cpp b/backends/fs/wii/wii-fs.cpp
index e6d0cf4c7e..a620df5471 100644
--- a/backends/fs/wii/wii-fs.cpp
+++ b/backends/fs/wii/wii-fs.cpp
@@ -23,6 +23,7 @@
#if defined(__WII__)
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/stdiostream.h"
#include <sys/dir.h>
@@ -37,8 +38,8 @@
*/
class WiiFilesystemNode : public AbstractFilesystemNode {
protected:
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory, _isReadable, _isWritable;
public:
@@ -50,51 +51,30 @@ public:
/**
* Creates a WiiFilesystemNode for a given path.
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
* @param verify true if the isValid and isDirectory flags should be verified during the construction.
*/
- WiiFilesystemNode(const String &path, bool verify);
+ WiiFilesystemNode(const Common::String &path, bool verify);
virtual bool exists() const;
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return _isReadable; }
virtual bool isWritable() const { return _isWritable; }
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+
private:
virtual void setFlags();
};
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * /foo/bar.txt would return /bar.txt
- * /foo/bar/ would return /bar/
- *
- * @param str String containing the path.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if(str.empty())
- return "";
-
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '/') {
- --cur;
- }
-
- return cur + 1;
-}
-
void WiiFilesystemNode::setFlags() {
struct stat st;
@@ -118,12 +98,12 @@ WiiFilesystemNode::WiiFilesystemNode() {
setFlags();
}
-WiiFilesystemNode::WiiFilesystemNode(const String &p, bool verify) {
+WiiFilesystemNode::WiiFilesystemNode(const Common::String &p, bool verify) {
assert(p.size() > 0);
_path = p;
- _displayName = lastPathComponent(_path);
+ _displayName = lastPathComponent(_path, '/');
if (verify)
setFlags();
@@ -134,10 +114,10 @@ bool WiiFilesystemNode::exists() const {
return stat(_path.c_str (), &st) == 0;
}
-AbstractFilesystemNode *WiiFilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *WiiFilesystemNode::getChild(const Common::String &n) const {
assert(_isDirectory);
- String newPath(_path);
+ Common::String newPath(_path);
if (newPath.lastChar() != '/')
newPath += '/';
newPath += n;
@@ -160,15 +140,15 @@ bool WiiFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool
if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
continue;
- String newPath(_path);
+ Common::String newPath(_path);
if (newPath.lastChar() != '/')
newPath += '/';
newPath += filename;
bool isDir = S_ISDIR(st.st_mode);
- if ((mode == FilesystemNode::kListFilesOnly && isDir) ||
- (mode == FilesystemNode::kListDirectoriesOnly && !isDir))
+ if ((mode == Common::FilesystemNode::kListFilesOnly && isDir) ||
+ (mode == Common::FilesystemNode::kListDirectoriesOnly && !isDir))
continue;
if (isDir)
@@ -187,9 +167,17 @@ AbstractFilesystemNode *WiiFilesystemNode::getParent() const {
return 0;
const char *start = _path.c_str();
- const char *end = lastPathComponent(_path);
+ const char *end = lastPathComponent(_path, '/');
+
+ return new WiiFilesystemNode(Common::String(start, end - start), true);
+}
+
+Common::SeekableReadStream *WiiFilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
- return new WiiFilesystemNode(String(start, end - start), true);
+Common::WriteStream *WiiFilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
}
#endif //#if defined(__WII__)
diff --git a/backends/fs/windows/windows-fs-factory.cpp b/backends/fs/windows/windows-fs-factory.cpp
index 7fbf4f7fff..ed273bb746 100644
--- a/backends/fs/windows/windows-fs-factory.cpp
+++ b/backends/fs/windows/windows-fs-factory.cpp
@@ -26,8 +26,6 @@
#include "backends/fs/windows/windows-fs-factory.h"
#include "backends/fs/windows/windows-fs.cpp"
-DECLARE_SINGLETON(WindowsFilesystemFactory);
-
AbstractFilesystemNode *WindowsFilesystemFactory::makeRootFileNode() const {
return new WindowsFilesystemNode();
}
@@ -36,7 +34,7 @@ AbstractFilesystemNode *WindowsFilesystemFactory::makeCurrentDirectoryFileNode()
return new WindowsFilesystemNode("", true);
}
-AbstractFilesystemNode *WindowsFilesystemFactory::makeFileNodePath(const String &path) const {
+AbstractFilesystemNode *WindowsFilesystemFactory::makeFileNodePath(const Common::String &path) const {
return new WindowsFilesystemNode(path, false);
}
#endif
diff --git a/backends/fs/windows/windows-fs-factory.h b/backends/fs/windows/windows-fs-factory.h
index 0745b286a8..3c7b80942d 100644
--- a/backends/fs/windows/windows-fs-factory.h
+++ b/backends/fs/windows/windows-fs-factory.h
@@ -25,7 +25,6 @@
#ifndef WINDOWS_FILESYSTEM_FACTORY_H
#define WINDOWS_FILESYSTEM_FACTORY_H
-#include "common/singleton.h"
#include "backends/fs/fs-factory.h"
/**
@@ -33,19 +32,11 @@
*
* Parts of this class are documented in the base interface class, FilesystemFactory.
*/
-class WindowsFilesystemFactory : public FilesystemFactory, public Common::Singleton<WindowsFilesystemFactory> {
+class WindowsFilesystemFactory : public FilesystemFactory {
public:
- typedef Common::String String;
-
virtual AbstractFilesystemNode *makeRootFileNode() const;
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
- virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
-
-protected:
- WindowsFilesystemFactory() {};
-
-private:
- friend class Common::Singleton<SingletonBaseType>;
+ virtual AbstractFilesystemNode *makeFileNodePath(const Common::String &path) const;
};
#endif /*WINDOWS_FILESYSTEM_FACTORY_H*/
diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp
index ac2f521e21..c59c7dbe71 100644
--- a/backends/fs/windows/windows-fs.cpp
+++ b/backends/fs/windows/windows-fs.cpp
@@ -24,24 +24,17 @@
#ifdef WIN32
-#ifdef ARRAYSIZE
-#undef ARRAYSIZE
-#endif
-#ifdef _WIN32_WCE
#include <windows.h>
// winnt.h defines ARRAYSIZE, but we want our own one...
#undef ARRAYSIZE
+#ifdef _WIN32_WCE
#undef GetCurrentDirectory
#endif
#include "backends/fs/abstract-fs.h"
+#include "backends/fs/stdiostream.h"
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
-#ifndef _WIN32_WCE
-#include <windows.h>
-// winnt.h defines ARRAYSIZE, but we want our own one...
-#undef ARRAYSIZE
-#endif
#include <tchar.h>
// F_OK, R_OK and W_OK are not defined under MSVC, so we define them here
@@ -66,8 +59,8 @@
*/
class WindowsFilesystemNode : public AbstractFilesystemNode {
protected:
- String _displayName;
- String _path;
+ Common::String _displayName;
+ Common::String _path;
bool _isDirectory;
bool _isPseudoRoot;
bool _isValid;
@@ -89,23 +82,26 @@ public:
* path=c:\foo\bar.txt, currentDir=true -> current directory
* path=NULL, currentDir=true -> current directory
*
- * @param path String with the path the new node should point to.
+ * @param path Common::String with the path the new node should point to.
* @param currentDir if true, the path parameter will be ignored and the resulting node will point to the current directory.
*/
- WindowsFilesystemNode(const String &path, const bool currentDir);
+ WindowsFilesystemNode(const Common::String &path, const bool currentDir);
virtual bool exists() const { return _access(_path.c_str(), F_OK) == 0; }
- virtual String getDisplayName() const { return _displayName; }
- virtual String getName() const { return _displayName; }
- virtual String getPath() const { return _path; }
+ virtual Common::String getDisplayName() const { return _displayName; }
+ virtual Common::String getName() const { return _displayName; }
+ virtual Common::String getPath() const { return _path; }
virtual bool isDirectory() const { return _isDirectory; }
virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; }
virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; }
- virtual AbstractFilesystemNode *getChild(const String &n) const;
+ virtual AbstractFilesystemNode *getChild(const Common::String &n) const;
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode *getParent() const;
+ virtual Common::SeekableReadStream *openForReading();
+ virtual Common::WriteStream *openForWriting();
+
private:
/**
* Adds a single WindowsFilesystemNode to a given list.
@@ -113,7 +109,7 @@ private:
*
* @param list List to put the file entry node in.
* @param mode Mode to use while adding the file entry to the list.
- * @param base String with the directory being listed.
+ * @param base Common::String with the directory being listed.
* @param find_data Describes a file that the FindFirstFile, FindFirstFileEx, or FindNextFile functions find.
*/
static void addFile(AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data);
@@ -121,7 +117,7 @@ private:
/**
* Converts a Unicode string to Ascii format.
*
- * @param str String to convert from Unicode to Ascii.
+ * @param str Common::String to convert from Unicode to Ascii.
* @return str in Ascii format.
*/
static char *toAscii(TCHAR *str);
@@ -129,36 +125,12 @@ private:
/**
* Converts an Ascii string to Unicode format.
*
- * @param str String to convert from Ascii to Unicode.
+ * @param str Common::String to convert from Ascii to Unicode.
* @return str in Unicode format.
*/
static const TCHAR* toUnicode(const char *str);
};
-/**
- * Returns the last component of a given path.
- *
- * Examples:
- * c:\foo\bar.txt would return "\bar.txt"
- * c:\foo\bar\ would return "\bar\"
- *
- * @param str Path to obtain the last component from.
- * @return Pointer to the first char of the last component inside str.
- */
-const char *lastPathComponent(const Common::String &str) {
- if(str.empty())
- return "";
-
- const char *start = str.c_str();
- const char *cur = start + str.size() - 2;
-
- while (cur >= start && *cur != '\\') {
- --cur;
- }
-
- return cur + 1;
-}
-
void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data) {
WindowsFilesystemNode entry;
char *asciiName = toAscii(find_data->cFileName);
@@ -170,8 +142,8 @@ void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const c
isDirectory = (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? true : false);
- if ((!isDirectory && mode == FilesystemNode::kListDirectoriesOnly) ||
- (isDirectory && mode == FilesystemNode::kListFilesOnly))
+ if ((!isDirectory && mode == Common::FilesystemNode::kListDirectoriesOnly) ||
+ (isDirectory && mode == Common::FilesystemNode::kListFilesOnly))
return;
entry._isDirectory = isDirectory;
@@ -222,18 +194,17 @@ WindowsFilesystemNode::WindowsFilesystemNode() {
#endif
}
-WindowsFilesystemNode::WindowsFilesystemNode(const String &p, const bool currentDir) {
+WindowsFilesystemNode::WindowsFilesystemNode(const Common::String &p, const bool currentDir) {
if (currentDir) {
char path[MAX_PATH];
GetCurrentDirectory(MAX_PATH, path);
_path = path;
- }
- else {
+ } else {
assert(p.size() > 0);
_path = p;
}
- _displayName = lastPathComponent(_path);
+ _displayName = lastPathComponent(_path, '\\');
// Check whether it is a directory, and whether the file actually exists
DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));
@@ -252,19 +223,14 @@ WindowsFilesystemNode::WindowsFilesystemNode(const String &p, const bool current
_isPseudoRoot = false;
}
-AbstractFilesystemNode *WindowsFilesystemNode::getChild(const String &n) const {
+AbstractFilesystemNode *WindowsFilesystemNode::getChild(const Common::String &n) const {
assert(_isDirectory);
- String newPath(_path);
+ Common::String newPath(_path);
if (_path.lastChar() != '\\')
newPath += '\\';
newPath += n;
- // Check whether the directory actually exists
- DWORD fileAttribs = GetFileAttributes(toUnicode(newPath.c_str()));
- if (fileAttribs == INVALID_FILE_ATTRIBUTES)
- return 0;
-
return new WindowsFilesystemNode(newPath, false);
}
@@ -328,17 +294,25 @@ AbstractFilesystemNode *WindowsFilesystemNode::getParent() const {
WindowsFilesystemNode *p = new WindowsFilesystemNode();
if (_path.size() > 3) {
const char *start = _path.c_str();
- const char *end = lastPathComponent(_path);
+ const char *end = lastPathComponent(_path, '\\');
p = new WindowsFilesystemNode();
- p->_path = String(start, end - start);
+ p->_path = Common::String(start, end - start);
p->_isValid = true;
p->_isDirectory = true;
- p->_displayName = lastPathComponent(p->_path);
+ p->_displayName = lastPathComponent(p->_path, '\\');
p->_isPseudoRoot = false;
}
return p;
}
+Common::SeekableReadStream *WindowsFilesystemNode::openForReading() {
+ return StdioStream::makeFromPath(getPath().c_str(), false);
+}
+
+Common::WriteStream *WindowsFilesystemNode::openForWriting() {
+ return StdioStream::makeFromPath(getPath().c_str(), true);
+}
+
#endif //#ifdef WIN32