mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-12 11:43:00 +00:00
Patch #1768757: Merge fsnode-gsoc into trunk (MAJOR change, will break compilation on some ports)
svn-id: r28944
This commit is contained in:
commit
c3d3aebe87
73
backends/fs/abstract-fs-factory.h
Normal file
73
backends/fs/abstract-fs-factory.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* 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 ABSTRACT_FILESYSTEM_FACTORY_H
|
||||||
|
#define ABSTRACT_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates concrete FilesystemNode objects depending on the current architecture.
|
||||||
|
*/
|
||||||
|
class AbstractFilesystemFactory {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
virtual ~AbstractFilesystemFactory() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a node representing the "current directory".
|
||||||
|
* If your system does not support this concept, you can either try to
|
||||||
|
* emulate it or simply return some "sensible" default directory node,
|
||||||
|
* e.g. the same value as getRoot() returns.
|
||||||
|
*/
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a node based on a path; the path is in the same format as it
|
||||||
|
* would be for calls to fopen().
|
||||||
|
*
|
||||||
|
* Furthermore getNodeForPath(oldNode.path()) should create a new node
|
||||||
|
* identical to oldNode. Hence, we can use the "path" value for persistent
|
||||||
|
* storage e.g. in the config file.
|
||||||
|
*
|
||||||
|
* @param path The path string to create a FilesystemNode for.
|
||||||
|
*/
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a special node representing the filesystem root.
|
||||||
|
* The starting point for any file system browsing.
|
||||||
|
*
|
||||||
|
* On Unix, this will be simply the node for / (the root directory).
|
||||||
|
* On Windows, it will be a special node which "contains" all drives (C:, D:, E:).
|
||||||
|
*/
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*ABSTRACT_FILESYSTEM_FACTORY_H*/
|
@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
|
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
|
|
||||||
class AbstractFilesystemNode;
|
class AbstractFilesystemNode;
|
||||||
@ -47,88 +46,106 @@ protected:
|
|||||||
friend class FilesystemNode;
|
friend class FilesystemNode;
|
||||||
typedef Common::String String;
|
typedef Common::String String;
|
||||||
typedef FilesystemNode::ListMode ListMode;
|
typedef 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.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parent node of this directory.
|
* The parent node of this directory.
|
||||||
* The parent of the root is the root itself.
|
* The parent of the root is the root itself.
|
||||||
*/
|
*/
|
||||||
virtual AbstractFilesystemNode *parent() const = 0;
|
virtual AbstractFilesystemNode *getParent() const = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @note Handling calls on non-dir nodes gracefully makes it possible to
|
|
||||||
* switch to a lazy type detection scheme in the future.
|
|
||||||
*/
|
|
||||||
virtual AbstractFilesystemNode *child(const String &name) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a special node representing the FS root. The starting point for
|
|
||||||
* any file system browsing.
|
|
||||||
* On Unix, this will be simply the node for / (the root directory).
|
|
||||||
* On Windows, it will be a special node which "contains" all drives (C:, D:, E:).
|
|
||||||
*/
|
|
||||||
static AbstractFilesystemNode *getRoot();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a node representing the "current directory". If your system does
|
|
||||||
* not support this concept, you can either try to emulate it or
|
|
||||||
* simply return some "sensible" default directory node, e.g. the same
|
|
||||||
* value as getRoot() returns.
|
|
||||||
*/
|
|
||||||
static AbstractFilesystemNode *getCurrentDirectory();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a node based on a path; the path is in the same format as it
|
|
||||||
* would be for calls to fopen().
|
|
||||||
*
|
|
||||||
* Furthermore getNodeForPath(oldNode.path()) should create a new node
|
|
||||||
* identical to oldNode. Hence, we can use the "path" value for persistent
|
|
||||||
* storage e.g. in the config file.
|
|
||||||
*
|
|
||||||
* @todo: This is of course a place where non-portable code easily will sneak
|
|
||||||
* in, because the format of the path used here is not well-defined.
|
|
||||||
* So we really should reconsider this API and try to come up with
|
|
||||||
* something which is more portable but still flexible enough for our
|
|
||||||
* purposes.
|
|
||||||
*/
|
|
||||||
static AbstractFilesystemNode *getNodeForPath(const String &path);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
virtual ~AbstractFilesystemNode() {}
|
virtual ~AbstractFilesystemNode() {}
|
||||||
|
|
||||||
virtual String name() const = 0;
|
|
||||||
|
|
||||||
// By default, we use the actual file name as 'display name'.
|
/*
|
||||||
virtual String displayName() const { return name(); }
|
* Indicates whether the object referred by this path exists in the filesystem or not.
|
||||||
|
*/
|
||||||
|
virtual bool exists() const = 0;
|
||||||
|
|
||||||
virtual bool isValid() const = 0;
|
/**
|
||||||
|
* Return a list of child nodes of this directory node. If called on a node
|
||||||
|
* that does not represent a directory, false is returned.
|
||||||
|
*
|
||||||
|
* @param list List to put the contents of the directory in.
|
||||||
|
* @param mode Mode to use while listing the directory.
|
||||||
|
* @param hidden Whether to include hidden files or not in the results.
|
||||||
|
*
|
||||||
|
* @return true if succesful, false otherwise (e.g. when the directory does not exist).
|
||||||
|
*/
|
||||||
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a human readable path string.
|
||||||
|
*
|
||||||
|
* @note By default, this method returns the value of getName().
|
||||||
|
*/
|
||||||
|
virtual String getDisplayName() const { return getName(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string with an architecture dependent path description.
|
||||||
|
*/
|
||||||
|
virtual String getName() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the 'path' of the current node, usable in fopen().
|
||||||
|
*/
|
||||||
|
virtual String getPath() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this path refers to a directory or not.
|
||||||
|
*/
|
||||||
virtual bool isDirectory() const = 0;
|
virtual bool isDirectory() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the 'path' of the current node, usable in fopen(). See also
|
* Indicates whether the object referred by this path can be read from or not.
|
||||||
* the static getNodeForPath() method.
|
*
|
||||||
|
* If the path refers to a directory, readability implies being able to read
|
||||||
|
* and list the directory entries.
|
||||||
|
*
|
||||||
|
* If the path refers to a file, readability implies being able to read the
|
||||||
|
* contents of the file.
|
||||||
|
*
|
||||||
|
* @return bool true if the object can be read, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual String path() const = 0;
|
virtual bool isReadable() const = 0;
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const = 0;
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the object referred by this path can be written to or not.
|
||||||
|
*
|
||||||
|
* If the path refers to a directory, writability implies being able to modify
|
||||||
|
* the directory entry (i.e. rename the directory, remove it or write files inside of it).
|
||||||
|
*
|
||||||
|
* If the path refers to a file, writability implies being able to write data
|
||||||
|
* to the file.
|
||||||
|
*
|
||||||
|
* @return bool true if the object can be written to, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool isWritable() const = 0;
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
bool exists();
|
|
||||||
|
|
||||||
bool isDirectory();
|
|
||||||
bool isFile();
|
bool isFile();
|
||||||
|
|
||||||
bool isReadable();
|
|
||||||
bool isWriteable();
|
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif //BACKENDS_ABSTRACT_FS_H
|
||||||
#endif
|
|
||||||
|
40
backends/fs/amigaos4/amigaos4-fs-factory.cpp
Normal file
40
backends/fs/amigaos4/amigaos4-fs-factory.cpp
Normal file
@ -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/amigaos4/amigaos4-fs-factory.h"
|
||||||
|
#include "backends/fs/amigaos4/amigaos4-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(AmigaOSFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *AmigaOSFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new AmigaOSFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *AmigaOSFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new AmigaOSFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *AmigaOSFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new AmigaOSFilesystemNode(path);
|
||||||
|
}
|
51
backends/fs/amigaos4/amigaos4-fs-factory.h
Normal file
51
backends/fs/amigaos4/amigaos4-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 AMIGAOS_FILESYSTEM_FACTORY_H
|
||||||
|
#define AMIGAOS_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates AmigaOSFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class AmigaOSFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<AmigaOSFilesystemFactory> {
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*AMIGAOS_FILESYSTEM_FACTORY_H*/
|
@ -38,58 +38,76 @@
|
|||||||
#include <common/stdafx.h>
|
#include <common/stdafx.h>
|
||||||
|
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
#include "engines/engine.h"
|
#include "engines/engine.h"
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
#define ENTER() /* debug(6, "Enter") */
|
#define ENTER() /* debug(6, "Enter") */
|
||||||
#define LEAVE() /* debug(6, "Leave") */
|
#define LEAVE() /* debug(6, "Leave") */
|
||||||
|
|
||||||
|
|
||||||
const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure?
|
const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the ScummVM file system API.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
|
*/
|
||||||
class AmigaOSFilesystemNode : public AbstractFilesystemNode {
|
class AmigaOSFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
BPTR _pFileLock;
|
BPTR _pFileLock;
|
||||||
String _sDisplayName;
|
String _sDisplayName;
|
||||||
bool _bIsDirectory;
|
String _sPath;
|
||||||
bool _bIsValid;
|
bool _bIsDirectory;
|
||||||
String _sPath;
|
bool _bIsValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AmigaOSFilesystemNode();
|
/**
|
||||||
AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0);
|
* Creates a AmigaOSFilesystemNode with the root node as path.
|
||||||
AmigaOSFilesystemNode(const String &p);
|
*/
|
||||||
|
AmigaOSFilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a AmigaOSFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
|
AmigaOSFilesystemNode(const String &p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: document this constructor.
|
||||||
|
*/
|
||||||
|
AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0);
|
||||||
|
|
||||||
// Note: Copy constructor is needed because it duplicates the file lock
|
/**
|
||||||
AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node);
|
* Copy constructor.
|
||||||
|
*
|
||||||
virtual ~AmigaOSFilesystemNode();
|
* @note Needed because it duplicates the file lock
|
||||||
|
*/
|
||||||
|
AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
virtual ~AmigaOSFilesystemNode();
|
||||||
|
|
||||||
virtual String displayName() const { return _sDisplayName; };
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _sDisplayName; };
|
virtual String getDisplayName() const { return _sDisplayName; };
|
||||||
virtual bool isValid() const { return _bIsValid; };
|
virtual String getName() const { return _sDisplayName; };
|
||||||
virtual bool isDirectory() const { return _bIsDirectory; };
|
virtual String getPath() const { return _sPath; };
|
||||||
virtual String path() const { return _sPath; };
|
virtual bool isDirectory() const { return _bIsDirectory; };
|
||||||
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual bool isValid() const { return _bIsValid; };
|
||||||
virtual AbstractFSList listVolumes() const;
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
|
||||||
virtual AbstractFilesystemNode *child(const String &n) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a list with all the volumes present in the root node.
|
||||||
|
*/
|
||||||
|
virtual AbstractFSList listVolumes() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
return AbstractFilesystemNode::getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
|
||||||
return new AmigaOSFilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new AmigaOSFilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
AmigaOSFilesystemNode::AmigaOSFilesystemNode() {
|
AmigaOSFilesystemNode::AmigaOSFilesystemNode() {
|
||||||
ENTER();
|
ENTER();
|
||||||
_sDisplayName = "Available Disks";
|
_sDisplayName = "Available Disks";
|
||||||
@ -100,7 +118,6 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode() {
|
|||||||
LEAVE();
|
LEAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) {
|
AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
@ -150,7 +167,6 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) {
|
|||||||
const char c = _sPath.lastChar();
|
const char c = _sPath.lastChar();
|
||||||
if (c != '/' && c != ':')
|
if (c != '/' && c != ':')
|
||||||
_sPath += '/';
|
_sPath += '/';
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//_bIsDirectory = false;
|
//_bIsDirectory = false;
|
||||||
@ -170,7 +186,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam
|
|||||||
int bufSize = MAXPATHLEN;
|
int bufSize = MAXPATHLEN;
|
||||||
_pFileLock = 0;
|
_pFileLock = 0;
|
||||||
|
|
||||||
while (1) {
|
while (true) {
|
||||||
char *n = new char[bufSize];
|
char *n = new char[bufSize];
|
||||||
if (IDOS->NameFromLock(pLock, (STRPTR)n, bufSize) != DOSFALSE) {
|
if (IDOS->NameFromLock(pLock, (STRPTR)n, bufSize) != DOSFALSE) {
|
||||||
_sPath = n;
|
_sPath = n;
|
||||||
@ -186,6 +202,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam
|
|||||||
delete [] n;
|
delete [] n;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufSize *= 2;
|
bufSize *= 2;
|
||||||
delete [] n;
|
delete [] n;
|
||||||
}
|
}
|
||||||
@ -238,9 +255,35 @@ AmigaOSFilesystemNode::~AmigaOSFilesystemNode() {
|
|||||||
LEAVE();
|
LEAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AmigaOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
AbstractFilesystemNode *AmigaOSFilesystemNode::getChild(const String &n) const {
|
||||||
|
if (!_bIsDirectory) {
|
||||||
|
debug(6, "Not a directory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
String newPath(_sPath);
|
||||||
|
|
||||||
|
if (_sPath.lastChar() != '/')
|
||||||
|
newPath += '/';
|
||||||
|
|
||||||
|
newPath += n;
|
||||||
|
BPTR lock = IDOS->Lock(newPath.c_str(), SHARED_LOCK);
|
||||||
|
|
||||||
|
if (!lock) {
|
||||||
|
debug(6, "Bad path");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDOS->UnLock(lock);
|
||||||
|
|
||||||
|
return new AmigaOSFilesystemNode(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
if (!_bIsValid) {
|
if (!_bIsValid) {
|
||||||
debug(6, "Invalid node");
|
debug(6, "Invalid node");
|
||||||
LEAVE();
|
LEAVE();
|
||||||
@ -308,10 +351,11 @@ bool AmigaOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
LEAVE();
|
LEAVE();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AmigaOSFilesystemNode::parent() const {
|
AbstractFilesystemNode *AmigaOSFilesystemNode::getParent() const {
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
if (!_bIsDirectory) {
|
if (!_bIsDirectory) {
|
||||||
@ -337,33 +381,8 @@ AbstractFilesystemNode *AmigaOSFilesystemNode::parent() const {
|
|||||||
node = new AmigaOSFilesystemNode();
|
node = new AmigaOSFilesystemNode();
|
||||||
|
|
||||||
LEAVE();
|
LEAVE();
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AmigaOSFilesystemNode::child(const String &n) const {
|
|
||||||
|
|
||||||
if (!_bIsDirectory) {
|
return node;
|
||||||
debug(6, "Not a directory");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
String newPath(_sPath);
|
|
||||||
|
|
||||||
if (_sPath.lastChar() != '/')
|
|
||||||
newPath += '/';
|
|
||||||
|
|
||||||
newPath += n;
|
|
||||||
|
|
||||||
BPTR lock = IDOS->Lock(newPath.c_str(), SHARED_LOCK);
|
|
||||||
|
|
||||||
if (!lock) {
|
|
||||||
debug(6, "Bad path");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDOS->UnLock(lock);
|
|
||||||
|
|
||||||
return new AmigaOSFilesystemNode(newPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
|
AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
|
||||||
@ -431,7 +450,8 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
|
|||||||
IDOS->UnLockDosList(kLockFlags);
|
IDOS->UnLockDosList(kLockFlags);
|
||||||
|
|
||||||
LEAVE();
|
LEAVE();
|
||||||
|
|
||||||
return myList;
|
return myList;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif //defined(__amigaos4__)
|
||||||
|
@ -25,40 +25,62 @@
|
|||||||
#if defined(__DC__)
|
#if defined(__DC__)
|
||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
|
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
#include <ronin/cdfs.h>
|
#include <ronin/cdfs.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of the ScummVM file system API based on ronin.
|
* Implementation of the ScummVM file system API based on Ronin.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RoninCDFilesystemNode : public AbstractFilesystemNode {
|
class RoninCDFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
String _path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a RoninCDFilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
RoninCDFilesystemNode();
|
RoninCDFilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a RoninCDFilesystemNode 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.
|
||||||
|
*/
|
||||||
RoninCDFilesystemNode(const String &path, bool verify);
|
RoninCDFilesystemNode(const String &path, bool verify);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return _isValid; }
|
virtual String getName() const { return _displayName; }
|
||||||
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return _isValid; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
virtual AbstractFilesystemNode *child(const String &n) 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.
|
||||||
|
*/
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
static const char *lastPathComponent(const Common::String &str) {
|
||||||
const char *start = str.c_str();
|
const char *start = str.c_str();
|
||||||
const char *cur = start + str.size() - 2;
|
const char *cur = start + str.size() - 2;
|
||||||
@ -70,22 +92,6 @@ static const char *lastPathComponent(const Common::String &str) {
|
|||||||
return cur + 1;
|
return cur + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
// Since there is no way to _set_ the current directory,
|
|
||||||
// it will always be /...
|
|
||||||
|
|
||||||
return getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
|
||||||
return new RoninCDFilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new RoninCDFilesystemNode(path, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
RoninCDFilesystemNode::RoninCDFilesystemNode() {
|
RoninCDFilesystemNode::RoninCDFilesystemNode() {
|
||||||
// The root dir.
|
// The root dir.
|
||||||
_path = "/";
|
_path = "/";
|
||||||
@ -118,10 +124,25 @@ RoninCDFilesystemNode::RoninCDFilesystemNode(const String &p, bool verify) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RoninCDFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
AbstractFilesystemNode *RoninCDFilesystemNode::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.
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
DIR *dirp = opendir(_path.c_str());
|
|
||||||
|
String newPath(_path);
|
||||||
|
if (_path.lastChar() != '/')
|
||||||
|
newPath += '/';
|
||||||
|
newPath += n;
|
||||||
|
|
||||||
|
return new RoninCDFilesystemNode(newPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RoninCDFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
|
DIR *dirp = opendir(_path.c_str());
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
|
|
||||||
if (dirp == NULL)
|
if (dirp == NULL)
|
||||||
@ -150,35 +171,22 @@ bool RoninCDFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
|
|
||||||
if (entry._isDirectory)
|
if (entry._isDirectory)
|
||||||
entry._path += "/";
|
entry._path += "/";
|
||||||
|
|
||||||
myList.push_back(new RoninCDFilesystemNode(entry));
|
myList.push_back(new RoninCDFilesystemNode(entry));
|
||||||
}
|
}
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *RoninCDFilesystemNode::parent() const {
|
AbstractFilesystemNode *RoninCDFilesystemNode::getParent() const {
|
||||||
if (_path == "/")
|
if (_path == "/")
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const char *start = _path.c_str();
|
const char *start = _path.c_str();
|
||||||
const char *end = lastPathComponent(_path);
|
const char *end = lastPathComponent(_path);
|
||||||
|
|
||||||
RoninCDFilesystemNode *p = new RoninCDFilesystemNode(String(start, end - start), false);
|
return new RoninCDFilesystemNode(String(start, end - start), false);
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *RoninCDFilesystemNode::child(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.
|
|
||||||
assert(_isDirectory);
|
|
||||||
String newPath(_path);
|
|
||||||
if (_path.lastChar() != '/')
|
|
||||||
newPath += '/';
|
|
||||||
newPath += n;
|
|
||||||
RoninCDFilesystemNode *p = new RoninCDFilesystemNode(newPath, true);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(__DC__)
|
#endif // defined(__DC__)
|
||||||
|
40
backends/fs/dc/ronincd-fs-factory.cpp
Normal file
40
backends/fs/dc/ronincd-fs-factory.cpp
Normal file
@ -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/dc/ronincd-fs-factory.h"
|
||||||
|
#include "backends/fs/dc/dc-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(RoninCDFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *RoninCDFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new RoninCDFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *RoninCDFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new RoninCDFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *RoninCDFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new RoninCDFilesystemNode(path, true);
|
||||||
|
}
|
51
backends/fs/dc/ronincd-fs-factory.h
Normal file
51
backends/fs/dc/ronincd-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 RONINCD_FILESYSTEM_FACTORY_H
|
||||||
|
#define RONINCD_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates RoninCDFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class RoninCDFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<RoninCDFilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RoninCDFilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*RONINCD_FILESYSTEM_FACTORY_H*/
|
53
backends/fs/ds/ds-fs-factory.cpp
Normal file
53
backends/fs/ds/ds-fs-factory.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* 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/ds/ds-fs-factory.h"
|
||||||
|
#include "backends/fs/ds/ds-fs.cpp"
|
||||||
|
#include "dsmain.h" //for the isGBAMPAvailable() function
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(DSFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *DSFilesystemFactory::makeRootFileNode() const {
|
||||||
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
return new DS::GBAMPFileSystemNode();
|
||||||
|
} else {
|
||||||
|
return new DS::DSFileSystemNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *DSFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
return new DS::GBAMPFileSystemNode();
|
||||||
|
} else {
|
||||||
|
return new DS::DSFileSystemNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *DSFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
return new DS::GBAMPFileSystemNode(path);
|
||||||
|
} else {
|
||||||
|
return new DS::DSFileSystemNode(path);
|
||||||
|
}
|
||||||
|
}
|
51
backends/fs/ds/ds-fs-factory.h
Normal file
51
backends/fs/ds/ds-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 DS_FILESYSTEM_FACTORY_H
|
||||||
|
#define DS_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates DSFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class DSFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<DSFilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DSFilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*DS_FILESYSTEM_FACTORY_H*/
|
@ -20,24 +20,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "fs.h"
|
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
//#include <NDS/ARM9/console.h> //basic print funcionality
|
//#include <NDS/ARM9/console.h> //basic print funcionality
|
||||||
#include "ds-fs.h"
|
#include "ds-fs.h"
|
||||||
#include "dsmain.h"
|
#include "dsmain.h"
|
||||||
#include "gba_nds_fat.h"
|
#include "gba_nds_fat.h"
|
||||||
|
|
||||||
|
|
||||||
namespace DS {
|
namespace DS {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// DSFileSystemNode - Flash ROM file system using Zip files
|
// DSFileSystemNode - Flash ROM file system using Zip files //
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ZipFile* DSFileSystemNode::_zipFile = NULL;
|
ZipFile* DSFileSystemNode::_zipFile = NULL;
|
||||||
@ -66,7 +60,6 @@ DSFileSystemNode::DSFileSystemNode(const String& path) {
|
|||||||
char disp[128];
|
char disp[128];
|
||||||
char* pathStr = (char *) path.c_str();
|
char* pathStr = (char *) path.c_str();
|
||||||
|
|
||||||
|
|
||||||
int lastSlash = 3;
|
int lastSlash = 3;
|
||||||
for (int r = 0; r < (int) strlen(pathStr) - 1; r++) {
|
for (int r = 0; r < (int) strlen(pathStr) - 1; r++) {
|
||||||
if (path[r] == '\\') {
|
if (path[r] == '\\') {
|
||||||
@ -81,13 +74,10 @@ DSFileSystemNode::DSFileSystemNode(const String& path) {
|
|||||||
// _isValid = true;
|
// _isValid = true;
|
||||||
// _isDirectory = false;
|
// _isDirectory = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!strncmp(pathStr, "ds:/", 4)) {
|
if (!strncmp(pathStr, "ds:/", 4)) {
|
||||||
pathStr += 4;
|
pathStr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (*pathStr == '\0') {
|
if (*pathStr == '\0') {
|
||||||
_isValid = true;
|
_isValid = true;
|
||||||
_isDirectory = true;
|
_isDirectory = true;
|
||||||
@ -130,35 +120,10 @@ DSFileSystemNode::DSFileSystemNode(const String& path, bool isDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DSFileSystemNode::DSFileSystemNode(const DSFileSystemNode* node) {
|
DSFileSystemNode::DSFileSystemNode(const DSFileSystemNode* node) {
|
||||||
|
//TODO: not implemented?
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode* DSFileSystemNode::parent() const {
|
AbstractFilesystemNode *DSFileSystemNode::getChild(const Common::String& n) const {
|
||||||
// consolePrintf("parent\n");
|
|
||||||
DSFileSystemNode *p;
|
|
||||||
|
|
||||||
if (_path != "ds:/") {
|
|
||||||
char *path = (char *) _path.c_str();
|
|
||||||
int lastSlash = 4;
|
|
||||||
|
|
||||||
for (int r = 4; r < (int) strlen((char *) path); r++) {
|
|
||||||
if (path[r] == '\\') {
|
|
||||||
lastSlash = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p = new DSFileSystemNode(String(path, lastSlash));
|
|
||||||
((DSFileSystemNode *) (p))->_isDirectory = true;
|
|
||||||
} else {
|
|
||||||
p = new DSFileSystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AbstractFilesystemNode *DSFileSystemNode::child(const Common::String& n) const {
|
|
||||||
if (_path.lastChar() == '\\') {
|
if (_path.lastChar() == '\\') {
|
||||||
return new DSFileSystemNode(_path + n);
|
return new DSFileSystemNode(_path + n);
|
||||||
} else {
|
} else {
|
||||||
@ -168,14 +133,12 @@ AbstractFilesystemNode *DSFileSystemNode::child(const Common::String& n) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DSFileSystemNode::getChildren(AbstractFSList &dirList, ListMode mode, bool hidden) const {
|
||||||
bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const {
|
|
||||||
// consolePrintf("Listdir\n");
|
// consolePrintf("Listdir\n");
|
||||||
|
|
||||||
|
|
||||||
// consolePrintf("Directory\n");
|
// consolePrintf("Directory\n");
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
char temp[128];
|
char temp[128];
|
||||||
strcpy(temp, _path.c_str());
|
strcpy(temp, _path.c_str());
|
||||||
|
|
||||||
@ -190,14 +153,13 @@ bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const {
|
|||||||
/* // This is the root dir, so add the RAM folder
|
/* // This is the root dir, so add the RAM folder
|
||||||
DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/ram");
|
DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/ram");
|
||||||
dsfsn->_isDirectory = true;
|
dsfsn->_isDirectory = true;
|
||||||
dirList->push_back(wrap(dsfsn));*/
|
dirList->push_back(wrap(dsfsn));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_zipFile->changeDirectory(temp);
|
_zipFile->changeDirectory(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (_zipFile->restartFile()) {
|
if (_zipFile->restartFile()) {
|
||||||
do {
|
do {
|
||||||
char n[128];
|
char n[128];
|
||||||
@ -218,12 +180,32 @@ bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode* DSFileSystemNode::getParent() const {
|
||||||
|
// consolePrintf("parent\n");
|
||||||
|
DSFileSystemNode *p;
|
||||||
|
|
||||||
|
if (_path != "ds:/") {
|
||||||
|
char *path = (char *) _path.c_str();
|
||||||
|
int lastSlash = 4;
|
||||||
|
|
||||||
|
for (int r = 4; r < (int) strlen((char *) path); r++) {
|
||||||
|
if (path[r] == '\\') {
|
||||||
|
lastSlash = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = new DSFileSystemNode(String(path, lastSlash));
|
||||||
|
((DSFileSystemNode *) (p))->_isDirectory = true;
|
||||||
|
} else {
|
||||||
|
p = new DSFileSystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
return p;
|
||||||
// GBAMPFileSystemNode - File system using GBA Movie Player and CF card
|
}
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// GBAMPFileSystemNode - File system using GBA Movie Player and CF card //
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
GBAMPFileSystemNode::GBAMPFileSystemNode() {
|
GBAMPFileSystemNode::GBAMPFileSystemNode() {
|
||||||
_displayName = "mp:/";
|
_displayName = "mp:/";
|
||||||
@ -290,35 +272,10 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path, bool isDirectory) {
|
|||||||
|
|
||||||
|
|
||||||
GBAMPFileSystemNode::GBAMPFileSystemNode(const GBAMPFileSystemNode* node) {
|
GBAMPFileSystemNode::GBAMPFileSystemNode(const GBAMPFileSystemNode* node) {
|
||||||
|
//TODO: not implemented?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *GBAMPFileSystemNode::getChild(const Common::String& n) const {
|
||||||
AbstractFilesystemNode* GBAMPFileSystemNode::parent() const {
|
|
||||||
// consolePrintf("parent\n");
|
|
||||||
GBAMPFileSystemNode *p;
|
|
||||||
|
|
||||||
if (_path != "mp:/") {
|
|
||||||
char *path = (char *) _path.c_str();
|
|
||||||
int lastSlash = 4;
|
|
||||||
|
|
||||||
for (int r = 4; r < (int) strlen((char *) path); r++) {
|
|
||||||
if (path[r] == '/') {
|
|
||||||
lastSlash = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p = new GBAMPFileSystemNode(String(path, lastSlash));
|
|
||||||
p->_isDirectory = true;
|
|
||||||
} else {
|
|
||||||
p = new GBAMPFileSystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *GBAMPFileSystemNode::child(const Common::String& n) const {
|
|
||||||
if (_path.lastChar() == '\\') {
|
if (_path.lastChar() == '\\') {
|
||||||
return new DSFileSystemNode(_path + n);
|
return new DSFileSystemNode(_path + n);
|
||||||
} else {
|
} else {
|
||||||
@ -328,9 +285,11 @@ AbstractFilesystemNode *GBAMPFileSystemNode::child(const Common::String& n) cons
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const {
|
bool GBAMPFileSystemNode::getChildren(AbstractFSList& dirList, ListMode mode, bool hidden) const {
|
||||||
// consolePrintf("Listdir\n");
|
// consolePrintf("Listdir\n");
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
enum { TYPE_NO_MORE = 0, TYPE_FILE = 1, TYPE_DIR = 2 };
|
enum { TYPE_NO_MORE = 0, TYPE_FILE = 1, TYPE_DIR = 2 };
|
||||||
|
|
||||||
char temp[128], fname[128], *path, *pathTemp;
|
char temp[128], fname[128], *path, *pathTemp;
|
||||||
@ -346,7 +305,6 @@ bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const
|
|||||||
pathTemp++;
|
pathTemp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// consolePrintf("This dir: %s\n", path);
|
// consolePrintf("This dir: %s\n", path);
|
||||||
FAT_chdir(path);
|
FAT_chdir(path);
|
||||||
|
|
||||||
@ -369,8 +327,6 @@ bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const
|
|||||||
// dsfsn->_isDirectory = entryType == DIR;
|
// dsfsn->_isDirectory = entryType == DIR;
|
||||||
dirList.push_back((dsfsn));
|
dirList.push_back((dsfsn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// consolePrintf("Skipping %s\n", fname);
|
// consolePrintf("Skipping %s\n", fname);
|
||||||
}
|
}
|
||||||
@ -385,6 +341,28 @@ bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode* GBAMPFileSystemNode::getParent() const {
|
||||||
|
// consolePrintf("parent\n");
|
||||||
|
GBAMPFileSystemNode *p;
|
||||||
|
|
||||||
|
if (_path != "mp:/") {
|
||||||
|
char *path = (char *) _path.c_str();
|
||||||
|
int lastSlash = 4;
|
||||||
|
|
||||||
|
for (int r = 4; r < (int) strlen((char *) path); r++) {
|
||||||
|
if (path[r] == '/') {
|
||||||
|
lastSlash = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = new GBAMPFileSystemNode(String(path, lastSlash));
|
||||||
|
p->_isDirectory = true;
|
||||||
|
} else {
|
||||||
|
p = new GBAMPFileSystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
// Stdio replacements
|
// Stdio replacements
|
||||||
#define MAX_FILE_HANDLES 32
|
#define MAX_FILE_HANDLES 32
|
||||||
@ -393,9 +371,6 @@ bool inited = false;
|
|||||||
DS::fileHandle handle[MAX_FILE_HANDLES];
|
DS::fileHandle handle[MAX_FILE_HANDLES];
|
||||||
|
|
||||||
FILE* std_fopen(const char* name, const char* mode) {
|
FILE* std_fopen(const char* name, const char* mode) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
for (int r = 0; r < MAX_FILE_HANDLES; r++) {
|
for (int r = 0; r < MAX_FILE_HANDLES; r++) {
|
||||||
handle[r].used = false;
|
handle[r].used = false;
|
||||||
@ -403,9 +378,6 @@ FILE* std_fopen(const char* name, const char* mode) {
|
|||||||
inited = true;
|
inited = true;
|
||||||
currentDir[0] = '\0';
|
currentDir[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* realName = (char *) name;
|
char* realName = (char *) name;
|
||||||
|
|
||||||
@ -413,7 +385,7 @@ FILE* std_fopen(const char* name, const char* mode) {
|
|||||||
if ((name[0] == 'd') && (name[1] == 's') && (name[2] == ':') && (name[3] == '/')) {
|
if ((name[0] == 'd') && (name[1] == 's') && (name[2] == ':') && (name[3] == '/')) {
|
||||||
realName += 4;
|
realName += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) {
|
if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) {
|
||||||
realName += 4;
|
realName += 4;
|
||||||
}
|
}
|
||||||
@ -421,7 +393,6 @@ FILE* std_fopen(const char* name, const char* mode) {
|
|||||||
// consolePrintf("Open file:");
|
// consolePrintf("Open file:");
|
||||||
// consolePrintf("'%s', [%s]", realName, mode);
|
// consolePrintf("'%s', [%s]", realName, mode);
|
||||||
|
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
FAT_chdir("/");
|
FAT_chdir("/");
|
||||||
|
|
||||||
@ -443,10 +414,9 @@ FILE* std_fopen(const char* name, const char* mode) {
|
|||||||
|
|
||||||
return (FILE *) result;
|
return (FILE *) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fail to open file for writing. It's in ROM!
|
// Fail to open file for writing. It's in ROM!
|
||||||
|
|
||||||
// Allocate a file handle
|
// Allocate a file handle
|
||||||
int r = 0;
|
int r = 0;
|
||||||
while (handle[r].used) r++;
|
while (handle[r].used) r++;
|
||||||
@ -459,7 +429,6 @@ FILE* std_fopen(const char* name, const char* mode) {
|
|||||||
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, false);
|
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (handle[r].sramFile) {
|
if (handle[r].sramFile) {
|
||||||
handle[r].used = true;
|
handle[r].used = true;
|
||||||
handle[r].pos = 0;
|
handle[r].pos = 0;
|
||||||
@ -513,6 +482,7 @@ FILE* std_fopen(const char* name, const char* mode) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void std_fclose(FILE* handle) {
|
void std_fclose(FILE* handle) {
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
@ -528,14 +498,9 @@ void std_fclose(FILE* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
||||||
|
|
||||||
// consolePrintf("fread %d,%d %d ", size, numItems, ptr);
|
// consolePrintf("fread %d,%d %d ", size, numItems, ptr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
|
||||||
|
|
||||||
int bytes = FAT_fread((void *) ptr, size, numItems, (FAT_FILE *) handle);
|
int bytes = FAT_fread((void *) ptr, size, numItems, (FAT_FILE *) handle);
|
||||||
if (!std_feof(handle)) {
|
if (!std_feof(handle)) {
|
||||||
return numItems;
|
return numItems;
|
||||||
@ -560,27 +525,24 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;*/
|
return item;
|
||||||
|
*/
|
||||||
|
|
||||||
int items = 0;
|
int items = 0;
|
||||||
|
|
||||||
//for (int r = 0; r < numItems; r++) {
|
//for (int r = 0; r < numItems; r++) {
|
||||||
if (!std_feof(handle)) {
|
if (!std_feof(handle)) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* for (int t = 0; t < size; t++) {
|
/* for (int t = 0; t < size; t++) {
|
||||||
if (feof(handle)) eof = true;
|
if (feof(handle)) eof = true;
|
||||||
*(((char *) (ptr)) + r * size + t) = getc(handle);
|
*(((char *) (ptr)) + r * size + t) = getc(handle);
|
||||||
}*/
|
}*/
|
||||||
int left = size * numItems;
|
int left = size * numItems;
|
||||||
int bytesRead = -1;
|
int bytesRead = -1;
|
||||||
|
|
||||||
while ((left > 0) && (!FAT_feof((FAT_FILE *) handle))) {
|
while ((left > 0) && (!FAT_feof((FAT_FILE *) handle))) {
|
||||||
int amount = left > 8192? 8192: left;
|
int amount = left > 8192? 8192: left;
|
||||||
// do {
|
// do {
|
||||||
bytesRead = FAT_fread((void *) ptr, 1, amount, (FAT_FILE *) handle);
|
bytesRead = FAT_fread((void *) ptr, 1, amount, (FAT_FILE *) handle);
|
||||||
/* if (bytesRead == 0) {
|
/* if (bytesRead == 0) {
|
||||||
consolePrintf("Pos:%d items:%d num:%d amount:%d read:%d\n", ftell(handle), items, numItems, amount, bytesRead);
|
consolePrintf("Pos:%d items:%d num:%d amount:%d read:%d\n", ftell(handle), items, numItems, amount, bytesRead);
|
||||||
left++;
|
left++;
|
||||||
|
|
||||||
@ -592,27 +554,24 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|||||||
fread(ptr, 1024, 1, handle);
|
fread(ptr, 1024, 1, handle);
|
||||||
swiWaitForVBlank();
|
swiWaitForVBlank();
|
||||||
//while (true);
|
//while (true);
|
||||||
}*/
|
}
|
||||||
//} while (bytesRead == 0);
|
|
||||||
|
} while (bytesRead == 0);
|
||||||
|
*/
|
||||||
left -= bytesRead;
|
left -= bytesRead;
|
||||||
ptr = ((char *) (ptr)) + bytesRead;
|
ptr = ((char *) (ptr)) + bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
items = numItems - (left / size);
|
items = numItems - (left / size);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// FAT_fread((void *) ptr, size, 1, ((int) (handle)) - 1);
|
// FAT_fread((void *) ptr, size, 1, ((int) (handle)) - 1);
|
||||||
// ptr = ((char *) (ptr)) + size;
|
// ptr = ((char *) (ptr)) + size;
|
||||||
|
|
||||||
}
|
}
|
||||||
//}
|
// }
|
||||||
|
|
||||||
// consolePrintf("...done %d \n", items)
|
// consolePrintf("...done %d \n", items)
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->sramFile) {
|
if (handle->sramFile) {
|
||||||
@ -630,7 +589,6 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|||||||
return bytes / size;
|
return bytes / size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (handle->pos + size * numItems > handle->size) {
|
if (handle->pos + size * numItems > handle->size) {
|
||||||
numItems = (handle->size - handle->pos) / size;
|
numItems = (handle->size - handle->pos) / size;
|
||||||
if (numItems < 0) numItems = 0;
|
if (numItems < 0) numItems = 0;
|
||||||
@ -639,10 +597,8 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|||||||
// consolePrintf("read %d ", size * numItems);
|
// consolePrintf("read %d ", size * numItems);
|
||||||
|
|
||||||
memcpy((void *) ptr, handle->data + handle->pos, size * numItems);
|
memcpy((void *) ptr, handle->data + handle->pos, size * numItems);
|
||||||
|
|
||||||
handle->pos += size * numItems;
|
handle->pos += size * numItems;
|
||||||
|
|
||||||
|
|
||||||
return numItems;
|
return numItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +613,6 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|||||||
//consolePrintf("fwrite size=%d\n", size * numItems);
|
//consolePrintf("fwrite size=%d\n", size * numItems);
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
|
||||||
FAT_fwrite(((char *) (ptr)), size, numItems, (FAT_FILE *) handle);
|
FAT_fwrite(((char *) (ptr)), size, numItems, (FAT_FILE *) handle);
|
||||||
return numItems;
|
return numItems;
|
||||||
|
|
||||||
@ -675,7 +630,6 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|||||||
return numItems;
|
return numItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (handle->sramFile) {
|
if (handle->sramFile) {
|
||||||
handle->sramFile->write(ptr, size);
|
handle->sramFile->write(ptr, size);
|
||||||
return size;
|
return size;
|
||||||
@ -704,6 +658,7 @@ bool std_feof(FILE* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void std_fflush(FILE* handle) {
|
void std_fflush(FILE* handle) {
|
||||||
|
//FIXME: not implemented?
|
||||||
// consolePrintf("fflush ");
|
// consolePrintf("fflush ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,7 +666,6 @@ char* std_fgets(char* str, int size, FILE* file) {
|
|||||||
// consolePrintf("fgets file=%d ", file);
|
// consolePrintf("fgets file=%d ", file);
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
|
||||||
char* s = str;
|
char* s = str;
|
||||||
while ((*s++ = std_getc(file)) >= 32) {
|
while ((*s++ = std_getc(file)) >= 32) {
|
||||||
// consolePrintf("%d ", *s);
|
// consolePrintf("%d ", *s);
|
||||||
@ -723,7 +677,6 @@ char* std_fgets(char* str, int size, FILE* file) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (file->sramFile) {
|
if (file->sramFile) {
|
||||||
file->pos--;
|
file->pos--;
|
||||||
int p = -1;
|
int p = -1;
|
||||||
@ -743,7 +696,6 @@ char* std_fgets(char* str, int size, FILE* file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long int std_ftell(FILE* handle) {
|
long int std_ftell(FILE* handle) {
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
return FAT_ftell((FAT_FILE *) handle);
|
return FAT_ftell((FAT_FILE *) handle);
|
||||||
}
|
}
|
||||||
@ -758,39 +710,30 @@ int std_fseek(FILE* handle, long int offset, int whence) {
|
|||||||
return FAT_fseek((FAT_FILE *) handle, offset, whence);
|
return FAT_fseek((FAT_FILE *) handle, offset, whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (whence) {
|
switch (whence) {
|
||||||
case SEEK_CUR: {
|
case SEEK_CUR:
|
||||||
handle->pos += offset;
|
handle->pos += offset;
|
||||||
break;
|
break;
|
||||||
}
|
case SEEK_SET:
|
||||||
|
|
||||||
case SEEK_SET: {
|
|
||||||
handle->pos = offset;
|
handle->pos = offset;
|
||||||
break;
|
break;
|
||||||
}
|
case SEEK_END:
|
||||||
|
|
||||||
case SEEK_END: {
|
|
||||||
handle->pos = handle->size + offset;
|
handle->pos = handle->size + offset;
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
|
||||||
default: {
|
|
||||||
handle->pos = offset;
|
handle->pos = offset;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void std_clearerr(FILE* handle) {
|
void std_clearerr(FILE* handle) {
|
||||||
|
//FIXME: not implemented?
|
||||||
// consolePrintf("clearerr ");
|
// consolePrintf("clearerr ");
|
||||||
}
|
}
|
||||||
|
|
||||||
int std_getc(FILE* handle) {
|
int std_getc(FILE* handle) {
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
char c;
|
char c;
|
||||||
FAT_fread(&c, 1, 1, (FAT_FILE *) handle);
|
FAT_fread(&c, 1, 1, (FAT_FILE *) handle);
|
||||||
@ -852,24 +795,3 @@ int std_ferror(FILE* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace DS
|
} // namespace DS
|
||||||
|
|
||||||
// These functions are added to AbstractFileSystemNode and are therefore outside
|
|
||||||
// the DS namespace.
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
// consolePrintf("New node");
|
|
||||||
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
|
||||||
return new DS::GBAMPFileSystemNode();
|
|
||||||
} else {
|
|
||||||
return new DS::DSFileSystemNode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode* AbstractFilesystemNode::getNodeForPath(const String& path) {
|
|
||||||
if (DS::isGBAMPAvailable()) {
|
|
||||||
return new DS::GBAMPFileSystemNode(path);
|
|
||||||
} else {
|
|
||||||
return new DS::DSFileSystemNode(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
#ifndef _DS_FS_H
|
#ifndef _DS_FS_H
|
||||||
#define _DS_FS_H
|
#define _DS_FS_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#include <NDS/ARM9/console.h>
|
//#include <NDS/ARM9/console.h>
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "zipreader.h"
|
#include "zipreader.h"
|
||||||
@ -32,81 +30,137 @@
|
|||||||
#include "scummconsole.h"
|
#include "scummconsole.h"
|
||||||
#include "gba_nds_fat.h"
|
#include "gba_nds_fat.h"
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
//#include "backends/fs/fs.h"
|
|
||||||
|
|
||||||
namespace DS {
|
namespace DS {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Implementation of the ScummVM file system API.
|
||||||
* This class is used when a Flash cart is in use.
|
* This class is used when a Flash cart is in use.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
class DSFileSystemNode : public AbstractFilesystemNode {
|
class DSFileSystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
static ZipFile* _zipFile;
|
|
||||||
|
|
||||||
typedef class Common::String String;
|
typedef class Common::String String;
|
||||||
|
|
||||||
|
static ZipFile* _zipFile;
|
||||||
|
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
String _path;
|
|
||||||
int _refCountVal;
|
int _refCountVal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a DSFilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
DSFileSystemNode();
|
DSFileSystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DSFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
DSFileSystemNode(const String &path);
|
DSFileSystemNode(const String &path);
|
||||||
DSFileSystemNode(const DSFileSystemNode *node);
|
|
||||||
|
/**
|
||||||
|
* Creates a DSFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @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 String& path, bool isDir);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
/**
|
||||||
virtual String name() const { return _displayName; }
|
* Copy constructor.
|
||||||
virtual bool isValid() const { return _isValid; }
|
*/
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
DSFileSystemNode(const DSFileSystemNode *node);
|
||||||
virtual String path() const { return _path; }
|
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly) const;
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
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 true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return _isValid; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of this node.
|
||||||
|
*/
|
||||||
virtual AbstractFilesystemNode *clone() const { return new DSFileSystemNode(this); }
|
virtual AbstractFilesystemNode *clone() const { return new DSFileSystemNode(this); }
|
||||||
virtual AbstractFilesystemNode *child(const Common::String& name) const;
|
virtual AbstractFilesystemNode *getChild(const Common::String& name) const;
|
||||||
|
virtual bool getChildren(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly, bool hidden) const;
|
||||||
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the zip file this node points to.
|
||||||
|
* TODO: check this documentation.
|
||||||
|
*/
|
||||||
static ZipFile* getZip() { return _zipFile; }
|
static ZipFile* getZip() { return _zipFile; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* Implementation of the ScummVM file system API.
|
||||||
* This class is used when the GBAMP (GBA Movie Player) is used with a CompactFlash card.
|
* This class is used when the GBAMP (GBA Movie Player) is used with a CompactFlash card.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
class GBAMPFileSystemNode : public AbstractFilesystemNode {
|
class GBAMPFileSystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
typedef class Common::String String;
|
typedef class Common::String String;
|
||||||
|
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
String _path;
|
|
||||||
|
|
||||||
int _refCountVal;
|
int _refCountVal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a GBAMPFilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
GBAMPFileSystemNode();
|
GBAMPFileSystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a GBAMPFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
GBAMPFileSystemNode(const String &path);
|
GBAMPFileSystemNode(const String &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DSFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @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 String &path, bool isDirectory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
GBAMPFileSystemNode(const GBAMPFileSystemNode *node);
|
GBAMPFileSystemNode(const GBAMPFileSystemNode *node);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
|
virtual String getName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return _isValid; }
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly) const;
|
virtual bool isValid() const { return _isValid; }
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
virtual AbstractFilesystemNode *clone() const { return new GBAMPFileSystemNode(this); }
|
|
||||||
virtual AbstractFilesystemNode *child(const Common::String& name) const;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of this node.
|
||||||
|
*/
|
||||||
|
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) const;
|
||||||
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct fileHandle {
|
struct fileHandle {
|
||||||
int pos;
|
int pos;
|
||||||
bool used;
|
bool used;
|
||||||
@ -116,7 +170,6 @@ struct fileHandle {
|
|||||||
DSSaveFile* sramFile;
|
DSSaveFile* sramFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#undef stderr
|
#undef stderr
|
||||||
#undef stdout
|
#undef stdout
|
||||||
#undef stdin
|
#undef stdin
|
||||||
@ -140,6 +193,6 @@ void std_clearerr(FILE* handle);
|
|||||||
void std_cwd(char* dir);
|
void std_cwd(char* dir);
|
||||||
void std_fflush(FILE* handle);
|
void std_fflush(FILE* handle);
|
||||||
|
|
||||||
}
|
} //namespace DS
|
||||||
|
|
||||||
#endif
|
#endif //_DS_FS_H
|
||||||
|
87
backends/fs/fs-factory-maker.cpp
Normal file
87
backends/fs/fs-factory-maker.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* 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-factory.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the following includes choose, at compile time, which specific backend will be used
|
||||||
|
* during the execution of the ScummVM.
|
||||||
|
*
|
||||||
|
* It has to be done this way because not all the necessary libraries will be available in
|
||||||
|
* all build environments. Additionally, this results in smaller binaries.
|
||||||
|
*/
|
||||||
|
#if defined(__amigaos4__)
|
||||||
|
#include "backends/fs/amigaos4/amigaos4-fs-factory.cpp"
|
||||||
|
#elif defined(__DC__)
|
||||||
|
#include "backends/fs/dc/ronincd-fs-factory.cpp"
|
||||||
|
#elif defined(__DS__)
|
||||||
|
#include "backends/fs/ds/ds-fs-factory.cpp"
|
||||||
|
#elif defined(__GP32__)
|
||||||
|
#include "backends/fs/gp32/gp32-fs-factory.cpp"
|
||||||
|
#elif defined(__MORPHOS__)
|
||||||
|
#include "backends/fs/morphos/abox-fs-factory.cpp"
|
||||||
|
#elif defined(PALMOS_MODE)
|
||||||
|
#include "backends/fs/palmos/palmos-fs-factory.cpp"
|
||||||
|
#elif defined(__PLAYSTATION2__)
|
||||||
|
#include "backends/fs/ps2/ps2-fs-factory.cpp"
|
||||||
|
#elif defined(__PSP__)
|
||||||
|
#include "backends/fs/psp/psp-fs-factory.cpp"
|
||||||
|
#elif defined(__SYMBIAN32__)
|
||||||
|
#include "backends/fs/symbian/symbian-fs-factory.cpp"
|
||||||
|
#elif defined(UNIX)
|
||||||
|
#include "backends/fs/posix/posix-fs-factory.cpp"
|
||||||
|
#elif defined(WIN32)
|
||||||
|
#include "backends/fs/windows/windows-fs-factory.cpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates concrete FilesystemFactory objects depending on the current architecture.
|
||||||
|
*
|
||||||
|
* @return AbstractFilesystemFactory* The specific factory for the current architecture.
|
||||||
|
*/
|
||||||
|
static AbstractFilesystemFactory *makeFSFactory() {
|
||||||
|
#if defined(__amigaos4__)
|
||||||
|
return &AmigaOSFilesystemFactory::instance();
|
||||||
|
#elif defined(__DC__)
|
||||||
|
return &RoninCDFilesystemFactory::instance();
|
||||||
|
#elif defined(__DS__)
|
||||||
|
return &DSFilesystemFactory::instance();
|
||||||
|
#elif defined(__GP32__)
|
||||||
|
return &GP32FilesystemFactory::instance();
|
||||||
|
#elif defined(__MORPHOS__)
|
||||||
|
return &ABoxFilesystemFactory::instance();
|
||||||
|
#elif defined(PALMOS_MODE)
|
||||||
|
return &PalmOSFilesystemFactory::instance();
|
||||||
|
#elif defined(__PLAYSTATION2__)
|
||||||
|
return &Ps2FilesystemFactory::instance();
|
||||||
|
#elif defined(__PSP__)
|
||||||
|
return &PSPFilesystemFactory::instance();
|
||||||
|
#elif defined(__SYMBIAN32__)
|
||||||
|
return &SymbianFilesystemFactory::instance();
|
||||||
|
#elif defined(UNIX)
|
||||||
|
return &POSIXFilesystemFactory::instance();
|
||||||
|
#elif defined(WIN32)
|
||||||
|
return &WindowsFilesystemFactory::instance();
|
||||||
|
#endif
|
||||||
|
}
|
40
backends/fs/gp32/gp32-fs-factory.cpp
Normal file
40
backends/fs/gp32/gp32-fs-factory.cpp
Normal file
@ -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/gp32/gp32-fs-factory.h"
|
||||||
|
#include "backends/fs/gp32/gp32-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(GP32FilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *GP32FilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new GP32FilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *GP32FilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new GP32FilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *GP32FilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new GP32FilesystemNode(path);
|
||||||
|
}
|
51
backends/fs/gp32/gp32-fs-factory.h
Normal file
51
backends/fs/gp32/gp32-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 GP32_FILESYSTEM_FACTORY_H
|
||||||
|
#define GP32_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates GP32FilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class GP32FilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<GP32FilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GP32FilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*GP32_FILESYSTEM_FACTORY_H*/
|
@ -24,38 +24,81 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
|
#define MAX_PATH_SIZE 256
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the ScummVM file system API.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
|
*/
|
||||||
class GP32FilesystemNode : public AbstractFilesystemNode {
|
class GP32FilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isRoot;
|
bool _isRoot;
|
||||||
String _path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a GP32FilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
GP32FilesystemNode();
|
GP32FilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a GP32FilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
GP32FilesystemNode(const String &path);
|
GP32FilesystemNode(const String &path);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
// FIXME: isValid should return false if this Node can't be used!
|
virtual String getName() const { return _displayName; }
|
||||||
// client code can rely on the return value.
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isValid() const { return true; }
|
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
// FIXME: isValid should return false if this Node can't be used!
|
||||||
|
// so client code can rely on the return value.
|
||||||
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return true; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
virtual AbstractFilesystemNode *child(const String &n) const;
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_PATH_SIZE 256
|
|
||||||
|
|
||||||
const char gpRootPath[] = "gp:\\";
|
const char gpRootPath[] = "gp:\\";
|
||||||
//char gpCurrentPath[MAX_PATH_SIZE] = "gp:\\"; // must end with '\'
|
//char gpCurrentPath[MAX_PATH_SIZE] = "gp:\\"; // must end with '\'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last component of a given path.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* gp:\foo\bar.txt would return "\bar.txt"
|
||||||
|
* gp:\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.
|
||||||
|
*/
|
||||||
|
static 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: document this function.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* @param convPath
|
||||||
|
*/
|
||||||
int gpMakePath(const char *path, char *convPath) {
|
int gpMakePath(const char *path, char *convPath) {
|
||||||
// copy root or current directory
|
// copy root or current directory
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -106,18 +149,6 @@ int gpMakePath(const char *path, char *convPath) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
return AbstractFilesystemNode::getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
|
||||||
return new GP32FilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new GP32FilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
GP32FilesystemNode::GP32FilesystemNode() {
|
GP32FilesystemNode::GP32FilesystemNode() {
|
||||||
_isDirectory = true;
|
_isDirectory = true;
|
||||||
_isRoot = true;
|
_isRoot = true;
|
||||||
@ -132,8 +163,8 @@ GP32FilesystemNode::GP32FilesystemNode(const String &path) {
|
|||||||
gpMakePath(path.c_str(), convPath);
|
gpMakePath(path.c_str(), convPath);
|
||||||
|
|
||||||
_path = convPath;
|
_path = convPath;
|
||||||
|
|
||||||
pos = convPath;
|
pos = convPath;
|
||||||
|
|
||||||
while (*pos)
|
while (*pos)
|
||||||
if (*pos++ == '\\')
|
if (*pos++ == '\\')
|
||||||
dsplName = pos;
|
dsplName = pos;
|
||||||
@ -150,14 +181,27 @@ GP32FilesystemNode::GP32FilesystemNode(const String &path) {
|
|||||||
_isDirectory = true;
|
_isDirectory = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GP32FilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
AbstractFilesystemNode *GP32FilesystemNode::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.
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
String newPath(_path);
|
||||||
|
if (_path.lastChar() != '\\')
|
||||||
|
newPath += '\\';
|
||||||
|
newPath += n;
|
||||||
|
|
||||||
|
return new GP32FilesystemNode(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GP32FilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
GPDIRENTRY dirEntry;
|
GPDIRENTRY dirEntry;
|
||||||
GPFILEATTR attr;
|
GPFILEATTR attr;
|
||||||
|
|
||||||
GP32FilesystemNode entry;
|
GP32FilesystemNode entry;
|
||||||
|
|
||||||
uint32 read;
|
uint32 read;
|
||||||
|
|
||||||
if (mode == FilesystemNode::kListAll)
|
if (mode == FilesystemNode::kListAll)
|
||||||
@ -168,9 +212,11 @@ bool GP32FilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
|||||||
int startIdx = 0; // current file
|
int startIdx = 0; // current file
|
||||||
String listDir(_path);
|
String listDir(_path);
|
||||||
//listDir += "/";
|
//listDir += "/";
|
||||||
|
|
||||||
while (GpDirEnumList(listDir.c_str(), startIdx++, 1, &dirEntry, &read) == SM_OK) {
|
while (GpDirEnumList(listDir.c_str(), startIdx++, 1, &dirEntry, &read) == SM_OK) {
|
||||||
if (dirEntry.name[0] == '.')
|
if (dirEntry.name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
entry._displayName = dirEntry.name;
|
entry._displayName = dirEntry.name;
|
||||||
entry._path = _path;
|
entry._path = _path;
|
||||||
entry._path += dirEntry.name;
|
entry._path += dirEntry.name;
|
||||||
@ -194,18 +240,7 @@ bool GP32FilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
AbstractFilesystemNode *GP32FilesystemNode::getParent() const {
|
||||||
const char *start = str.c_str();
|
|
||||||
const char *cur = start + str.size() - 2;
|
|
||||||
|
|
||||||
while (cur >= start && *cur != '\\') {
|
|
||||||
--cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cur + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *GP32FilesystemNode::parent() const {
|
|
||||||
if(_isRoot)
|
if(_isRoot)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -218,16 +253,3 @@ AbstractFilesystemNode *GP32FilesystemNode::parent() const {
|
|||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *GP32FilesystemNode::child(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.
|
|
||||||
assert(_isDirectory);
|
|
||||||
String newPath(_path);
|
|
||||||
if (_path.lastChar() != '\\')
|
|
||||||
newPath += '\\';
|
|
||||||
newPath += n;
|
|
||||||
GP32FilesystemNode *p = new GP32FilesystemNode(newPath);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
40
backends/fs/morphos/abox-fs-factory.cpp
Normal file
40
backends/fs/morphos/abox-fs-factory.cpp
Normal file
@ -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/morphos/abox-fs-factory.h"
|
||||||
|
#include "backends/fs/morphos/abox-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(ABoxFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *ABoxFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new ABoxFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *ABoxFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new ABoxFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *ABoxFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new ABoxFilesystemNode(path);
|
||||||
|
}
|
51
backends/fs/morphos/abox-fs-factory.h
Normal file
51
backends/fs/morphos/abox-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 ABOX_FILESYSTEM_FACTORY_H
|
||||||
|
#define ABOX_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates ABoxFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class ABoxFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<ABoxFilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ABoxFilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*ABOX_FILESYSTEM_FACTORY_H*/
|
@ -35,52 +35,66 @@
|
|||||||
#include "base/engine.h"
|
#include "base/engine.h"
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of the ScummVM file system API based on the MorphOS A-Box API.
|
* Implementation of the ScummVM file system API based on the MorphOS A-Box API.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ABoxFilesystemNode : public AbstractFilesystemNode {
|
class ABoxFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
BPTR _lock;
|
BPTR _lock;
|
||||||
String _displayName;
|
String _displayName;
|
||||||
bool _isDirectory;
|
String _path;
|
||||||
bool _isValid;
|
bool _isDirectory;
|
||||||
String _path;
|
bool _isValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ABoxFilesystemNode();
|
/**
|
||||||
ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL);
|
* Creates a ABoxFilesystemNode with the root node as path.
|
||||||
ABoxFilesystemNode(const String &p);
|
*/
|
||||||
ABoxFilesystemNode(const ABoxFilesystemNode &node);
|
ABoxFilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ABoxFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
|
ABoxFilesystemNode(const String &p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: document this constructor.
|
||||||
|
*/
|
||||||
|
ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
|
ABoxFilesystemNode(const ABoxFilesystemNode &node);
|
||||||
|
|
||||||
~ABoxFilesystemNode();
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
~ABoxFilesystemNode();
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; };
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return _isValid; }
|
virtual String getName() const { return _displayName; };
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual String getPath() const { return _path; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual bool isValid() const { return _isValid; }
|
||||||
static AbstractFSList listRoot();
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
|
||||||
virtual AbstractFilesystemNode *child(const String &name) const;
|
virtual AbstractFilesystemNode *getChild(const String &name) const;
|
||||||
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of child nodes for the root node.
|
||||||
|
*/
|
||||||
|
static AbstractFSList getRootChildren();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
return AbstractFilesystemNode::getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new ABoxFilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot()
|
|
||||||
{
|
|
||||||
return new ABoxFilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
ABoxFilesystemNode::ABoxFilesystemNode()
|
ABoxFilesystemNode::ABoxFilesystemNode()
|
||||||
{
|
{
|
||||||
_displayName = "Mounted Volumes";
|
_displayName = "Mounted Volumes";
|
||||||
@ -90,6 +104,62 @@ ABoxFilesystemNode::ABoxFilesystemNode()
|
|||||||
_lock = NULL;
|
_lock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ABoxFilesystemNode::ABoxFilesystemNode(const String &p) {
|
||||||
|
int len = 0, offset = p.size();
|
||||||
|
|
||||||
|
assert(offset > 0);
|
||||||
|
|
||||||
|
_path = p;
|
||||||
|
|
||||||
|
// Extract last component from path
|
||||||
|
const char *str = p.c_str();
|
||||||
|
while (offset > 0 && (str[offset-1] == '/' || str[offset-1] == ':') )
|
||||||
|
offset--;
|
||||||
|
while (offset > 0 && (str[offset-1] != '/' && str[offset-1] != ':')) {
|
||||||
|
len++;
|
||||||
|
offset--;
|
||||||
|
}
|
||||||
|
_displayName = String(str + offset, len);
|
||||||
|
_lock = NULL;
|
||||||
|
_isDirectory = false;
|
||||||
|
|
||||||
|
struct FileInfoBlock *fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL);
|
||||||
|
if (!fib)
|
||||||
|
{
|
||||||
|
debug(6, "FileInfoBlock is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the node exists and if it is a directory
|
||||||
|
BPTR pLock = Lock((STRPTR)_path.c_str(), SHARED_LOCK);
|
||||||
|
if (pLock)
|
||||||
|
{
|
||||||
|
if (Examine(pLock, fib) != DOSFALSE) {
|
||||||
|
if (fib->fib_EntryType > 0)
|
||||||
|
{
|
||||||
|
_isDirectory = true;
|
||||||
|
_lock = DupLock(pLock);
|
||||||
|
_isValid = (_lock != 0);
|
||||||
|
|
||||||
|
// Add a trailing slash if it is needed
|
||||||
|
const char c = _path.lastChar();
|
||||||
|
if (c != '/' && c != ':')
|
||||||
|
_path += '/';
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_isDirectory = false;
|
||||||
|
_isValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnLock(pLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeDosObject(DOS_FIB, fib);
|
||||||
|
}
|
||||||
|
|
||||||
ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
|
ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
|
||||||
{
|
{
|
||||||
int bufsize = 256;
|
int bufsize = 256;
|
||||||
@ -138,63 +208,7 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
|
|||||||
_isValid = true;
|
_isValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FreeDosObject(DOS_FIB, fib);
|
|
||||||
}
|
|
||||||
|
|
||||||
ABoxFilesystemNode::ABoxFilesystemNode(const String &p) {
|
|
||||||
int len = 0, offset = p.size();
|
|
||||||
|
|
||||||
assert(offset > 0);
|
|
||||||
|
|
||||||
_path = p;
|
|
||||||
|
|
||||||
// Extract last component from path
|
|
||||||
const char *str = p.c_str();
|
|
||||||
while (offset > 0 && (str[offset-1] == '/' || str[offset-1] == ':') )
|
|
||||||
offset--;
|
|
||||||
while (offset > 0 && (str[offset-1] != '/' && str[offset-1] != ':')) {
|
|
||||||
len++;
|
|
||||||
offset--;
|
|
||||||
}
|
|
||||||
_displayName = String(str + offset, len);
|
|
||||||
_lock = NULL;
|
|
||||||
_isDirectory = false;
|
|
||||||
|
|
||||||
struct FileInfoBlock *fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL);
|
|
||||||
if (!fib)
|
|
||||||
{
|
|
||||||
debug(6, "FileInfoBlock is NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the node exists and if it is a directory
|
|
||||||
|
|
||||||
BPTR pLock = Lock((STRPTR)_path.c_str(), SHARED_LOCK);
|
|
||||||
if (pLock)
|
|
||||||
{
|
|
||||||
if (Examine(pLock, fib) != DOSFALSE) {
|
|
||||||
if (fib->fib_EntryType > 0)
|
|
||||||
{
|
|
||||||
_isDirectory = true;
|
|
||||||
_lock = DupLock(pLock);
|
|
||||||
_isValid = (_lock != 0);
|
|
||||||
|
|
||||||
// Add a trailing slash if it is needed
|
|
||||||
const char c = _path.lastChar();
|
|
||||||
if (c != '/' && c != ':')
|
|
||||||
_path += '/';
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_isDirectory = false;
|
|
||||||
_isValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UnLock(pLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeDosObject(DOS_FIB, fib);
|
FreeDosObject(DOS_FIB, fib);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +230,30 @@ ABoxFilesystemNode::~ABoxFilesystemNode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
AbstractFilesystemNode *ABoxFilesystemNode::getChild(const String &name) const {
|
||||||
|
assert(_isDirectory);
|
||||||
|
String newPath(_path);
|
||||||
|
|
||||||
|
if (_path.lastChar() != '/')
|
||||||
|
newPath += '/';
|
||||||
|
newPath += name;
|
||||||
|
|
||||||
|
BPTR lock = Lock(newPath.c_str(), SHARED_LOCK);
|
||||||
|
|
||||||
|
if (!lock)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnLock(lock);
|
||||||
|
|
||||||
|
return new ABoxFilesystemNode(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ABoxFilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const
|
||||||
{
|
{
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
if (!_isValid)
|
if (!_isValid)
|
||||||
{
|
{
|
||||||
debug(6, "listDir() called on invalid node");
|
debug(6, "listDir() called on invalid node");
|
||||||
@ -232,7 +268,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
if (_lock == NULL)
|
if (_lock == NULL)
|
||||||
{
|
{
|
||||||
/* This is the root node */
|
/* This is the root node */
|
||||||
myList = listRoot();
|
list = getRootChildren();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +302,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (entry->isValid())
|
if (entry->isValid())
|
||||||
myList.push_back(entry);
|
list.push_back(entry);
|
||||||
else
|
else
|
||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
@ -284,7 +320,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *ABoxFilesystemNode::parent() const
|
AbstractFilesystemNode *ABoxFilesystemNode::getParent() const
|
||||||
{
|
{
|
||||||
AbstractFilesystemNode *node = NULL;
|
AbstractFilesystemNode *node = NULL;
|
||||||
|
|
||||||
@ -309,29 +345,9 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *ABoxFilesystemNode::child(const String &name) const {
|
AbstractFSList ABoxFilesystemNode::getRootChildren()
|
||||||
assert(_isDirectory);
|
|
||||||
String newPath(_path);
|
|
||||||
|
|
||||||
if (_path.lastChar() != '/')
|
|
||||||
newPath += '/';
|
|
||||||
newPath += name;
|
|
||||||
|
|
||||||
BPTR lock = Lock(newPath.c_str(), SHARED_LOCK);
|
|
||||||
|
|
||||||
if (!lock)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UnLock(lock);
|
|
||||||
|
|
||||||
return new ABoxFilesystemNode(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFSList ABoxFilesystemNode::listRoot()
|
|
||||||
{
|
{
|
||||||
AbstractFSList myList;
|
AbstractFSList list;
|
||||||
DosList *dosList;
|
DosList *dosList;
|
||||||
CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
|
CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
|
||||||
char name[256];
|
char name[256];
|
||||||
@ -339,15 +355,15 @@ AbstractFSList ABoxFilesystemNode::listRoot()
|
|||||||
dosList = LockDosList(lockDosListFlags);
|
dosList = LockDosList(lockDosListFlags);
|
||||||
if (dosList == NULL)
|
if (dosList == NULL)
|
||||||
{
|
{
|
||||||
return myList;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
dosList = NextDosEntry(dosList, LDF_VOLUMES);
|
dosList = NextDosEntry(dosList, LDF_VOLUMES);
|
||||||
while (dosList)
|
while (dosList)
|
||||||
{
|
{
|
||||||
if (dosList->dol_Type == DLT_VOLUME && // Should always be true, but ...
|
if (dosList->dol_Type == DLT_VOLUME && // Should always be true, but ...
|
||||||
dosList->dol_Name && // Same here
|
dosList->dol_Name && // Same here
|
||||||
dosList->dol_Task // Will be NULL if volume is removed from drive but still in use by some program
|
dosList->dol_Task // Will be NULL if volume is removed from drive but still in use by some program
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ABoxFilesystemNode *entry;
|
ABoxFilesystemNode *entry;
|
||||||
@ -365,7 +381,7 @@ AbstractFSList ABoxFilesystemNode::listRoot()
|
|||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
if (entry->isValid())
|
if (entry->isValid())
|
||||||
myList.push_back(entry);
|
list.push_back(entry);
|
||||||
else
|
else
|
||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
@ -377,9 +393,7 @@ AbstractFSList ABoxFilesystemNode::listRoot()
|
|||||||
|
|
||||||
UnLockDosList(lockDosListFlags);
|
UnLockDosList(lockDosListFlags);
|
||||||
|
|
||||||
return myList;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(__MORPHOS__)
|
#endif // defined(__MORPHOS__)
|
||||||
|
|
||||||
|
|
||||||
|
40
backends/fs/palmos/palmos-fs-factory.cpp
Normal file
40
backends/fs/palmos/palmos-fs-factory.cpp
Normal file
@ -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/palmos/palmos-fs-factory.h"
|
||||||
|
#include "backends/fs/palmos/palmos-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(PalmOSFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PalmOSFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new PalmOSFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PalmOSFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new PalmOSFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PalmOSFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new PalmOSFilesystemNode(path);
|
||||||
|
}
|
51
backends/fs/palmos/palmos-fs-factory.h
Normal file
51
backends/fs/palmos/palmos-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 PALMOS_FILESYSTEM_FACTORY_H
|
||||||
|
#define PALMOS_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates PalmOSFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class PalmOSFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<PalmOSFilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PalmOSFilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*PALMOS_FILESYSTEM_FACTORY_H*/
|
@ -30,36 +30,68 @@
|
|||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of the ScummVM file system API based on PalmOS VFS API.
|
* Implementation of the ScummVM file system API based on PalmOS VFS API.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PalmOSFilesystemNode : public AbstractFilesystemNode {
|
class PalmOSFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
bool _isPseudoRoot;
|
bool _isPseudoRoot;
|
||||||
String _path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a PalmOSFilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
PalmOSFilesystemNode();
|
PalmOSFilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a POSIXFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
PalmOSFilesystemNode(const String &p);
|
PalmOSFilesystemNode(const String &p);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return _isValid; }
|
virtual String getName() const { return _displayName; }
|
||||||
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return _isValid; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
virtual AbstractFilesystemNode *child(const String &n) const;
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void addFile (AbstractFSList &list, ListMode mode, const Char *base, FileInfoType* find_data);
|
/**
|
||||||
|
* Adds a single WindowsFilesystemNode to a given list.
|
||||||
|
* This method is used by getChildren() to populate the directory entries list.
|
||||||
|
*
|
||||||
|
* @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 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.
|
||||||
|
*/
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
static const char *lastPathComponent(const Common::String &str) {
|
||||||
const char *start = str.c_str();
|
const char *start = str.c_str();
|
||||||
const char *cur = start + str.size() - 2;
|
const char *cur = start + str.size() - 2;
|
||||||
@ -95,19 +127,6 @@ void PalmOSFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const ch
|
|||||||
list.push_back(new PalmOSFilesystemNode(entry));
|
list.push_back(new PalmOSFilesystemNode(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
return AbstractFilesystemNode::getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
|
||||||
return new PalmOSFilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new PalmOSFilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PalmOSFilesystemNode::PalmOSFilesystemNode() {
|
PalmOSFilesystemNode::PalmOSFilesystemNode() {
|
||||||
_isDirectory = true;
|
_isDirectory = true;
|
||||||
_displayName = "Root";
|
_displayName = "Root";
|
||||||
@ -122,13 +141,13 @@ PalmOSFilesystemNode::PalmOSFilesystemNode(const String &p) {
|
|||||||
|
|
||||||
UInt32 attr;
|
UInt32 attr;
|
||||||
FileRef handle;
|
FileRef handle;
|
||||||
Err e = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle);
|
Err error = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle);
|
||||||
if (!e) {
|
if (!error) {
|
||||||
e = VFSFileGetAttributes(handle, &attr);
|
error = VFSFileGetAttributes(handle, &attr);
|
||||||
VFSFileClose(handle);
|
VFSFileClose(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e) {
|
if (error) {
|
||||||
_isValid = false;
|
_isValid = false;
|
||||||
_isDirectory = false;
|
_isDirectory = false;
|
||||||
|
|
||||||
@ -139,8 +158,33 @@ PalmOSFilesystemNode::PalmOSFilesystemNode(const String &p) {
|
|||||||
_isPseudoRoot = false;
|
_isPseudoRoot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PalmOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
AbstractFilesystemNode *PalmOSFilesystemNode::getChild(const String &n) const {
|
||||||
Err e;
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
String newPath(_path);
|
||||||
|
if (_path.lastChar() != '/')
|
||||||
|
newPath += '/';
|
||||||
|
newPath += n;
|
||||||
|
|
||||||
|
FileRef handle;
|
||||||
|
UInt32 attr;
|
||||||
|
Err error = VFSFileOpen(gVars->VFS.volRefNum, newPath.c_str(), vfsModeRead, &handle);
|
||||||
|
if (error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error = VFSFileGetAttributes(handle, &attr);
|
||||||
|
VFSFileClose(handle);
|
||||||
|
|
||||||
|
if (error || !(attr & vfsFileAttrDirectory))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return new PalmOSFilesystemNode(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PalmOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
|
Err error;
|
||||||
Char nameP[256];
|
Char nameP[256];
|
||||||
FileInfoType desc;
|
FileInfoType desc;
|
||||||
FileRef handle;
|
FileRef handle;
|
||||||
@ -148,14 +192,14 @@ bool PalmOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
|
|
||||||
desc.nameP = nameP;
|
desc.nameP = nameP;
|
||||||
desc.nameBufLen = 256;
|
desc.nameBufLen = 256;
|
||||||
e = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle);
|
error = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle);
|
||||||
|
|
||||||
if (e)
|
if (error)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while(dirIterator != expIteratorStop) {
|
while(dirIterator != expIteratorStop) {
|
||||||
e = VFSDirEntryEnumerate(handle, &dirIterator, &desc);
|
error = VFSDirEntryEnumerate(handle, &dirIterator, &desc);
|
||||||
if (!e) {
|
if (!error) {
|
||||||
addFile(myList, mode, _path.c_str(), &desc);
|
addFile(myList, mode, _path.c_str(), &desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,8 +209,7 @@ bool PalmOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PalmOSFilesystemNode::getParent() const {
|
||||||
AbstractFilesystemNode *PalmOSFilesystemNode::parent() const {
|
|
||||||
PalmOSFilesystemNode *p = 0;
|
PalmOSFilesystemNode *p = 0;
|
||||||
|
|
||||||
if (!_isPseudoRoot) {
|
if (!_isPseudoRoot) {
|
||||||
@ -180,31 +223,7 @@ AbstractFilesystemNode *PalmOSFilesystemNode::parent() const {
|
|||||||
p->_displayName = lastPathComponent(p->_path);
|
p->_displayName = lastPathComponent(p->_path);
|
||||||
p->_isPseudoRoot =(p->_path == "/");
|
p->_isPseudoRoot =(p->_path == "/");
|
||||||
}
|
}
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AbstractFilesystemNode *PalmOSFilesystemNode::child(const String &n) const {
|
|
||||||
assert(_isDirectory);
|
|
||||||
String newPath(_path);
|
|
||||||
|
|
||||||
if (_path.lastChar() != '/')
|
|
||||||
newPath += '/';
|
|
||||||
newPath += n;
|
|
||||||
|
|
||||||
FileRef handle;
|
|
||||||
UInt32 attr;
|
|
||||||
Err e = VFSFileOpen(gVars->VFS.volRefNum, newPath.c_str(), vfsModeRead, &handle);
|
|
||||||
if (e)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
e = VFSFileGetAttributes(handle, &attr);
|
|
||||||
VFSFileClose(handle);
|
|
||||||
|
|
||||||
if (e || !(attr & vfsFileAttrDirectory))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
PalmOSFilesystemNode *p = new PalmOSFilesystemNode(newPath);
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
backends/fs/posix/posix-fs-factory.cpp
Normal file
42
backends/fs/posix/posix-fs-factory.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* 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/posix/posix-fs-factory.h"
|
||||||
|
#include "backends/fs/posix/posix-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(POSIXFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *POSIXFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new POSIXFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *POSIXFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
getcwd(buf, MAXPATHLEN);
|
||||||
|
return new POSIXFilesystemNode(buf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *POSIXFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new POSIXFilesystemNode(path, true);
|
||||||
|
}
|
51
backends/fs/posix/posix-fs-factory.h
Normal file
51
backends/fs/posix/posix-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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_FACTORY_H
|
||||||
|
#define POSIX_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates POSIXFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class POSIXFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<POSIXFilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
POSIXFilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*POSIX_FILESYSTEM_FACTORY_H*/
|
@ -25,7 +25,6 @@
|
|||||||
#if defined(UNIX)
|
#if defined(UNIX)
|
||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
|
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
#ifdef MACOSX
|
#ifdef MACOSX
|
||||||
@ -37,33 +36,61 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of the ScummVM file system API based on POSIX.
|
* 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 {
|
class POSIXFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
String _path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a POSIXFilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
POSIXFilesystemNode();
|
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);
|
POSIXFilesystemNode(const String &path, bool verify);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return _isValid; }
|
virtual String getName() const { return _displayName; }
|
||||||
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
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 bool listDir(AbstractFSList &list, ListMode mode) const;
|
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *child(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.
|
||||||
|
*/
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
static const char *lastPathComponent(const Common::String &str) {
|
||||||
const char *start = str.c_str();
|
const char *start = str.c_str();
|
||||||
const char *cur = start + str.size() - 2;
|
const char *cur = start + str.size() - 2;
|
||||||
@ -75,18 +102,11 @@ static const char *lastPathComponent(const Common::String &str) {
|
|||||||
return cur + 1;
|
return cur + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
void POSIXFilesystemNode::setFlags() {
|
||||||
char buf[MAXPATHLEN];
|
struct stat st;
|
||||||
getcwd(buf, MAXPATHLEN);
|
|
||||||
return new POSIXFilesystemNode(buf, true);
|
_isValid = (0 == stat(_path.c_str(), &st));
|
||||||
}
|
_isDirectory = _isValid ? S_ISDIR(st.st_mode) : false;
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
|
||||||
return new POSIXFilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new POSIXFilesystemNode(path, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
POSIXFilesystemNode::POSIXFilesystemNode() {
|
POSIXFilesystemNode::POSIXFilesystemNode() {
|
||||||
@ -123,30 +143,44 @@ POSIXFilesystemNode::POSIXFilesystemNode(const String &p, bool verify) {
|
|||||||
|
|
||||||
_path = p;
|
_path = p;
|
||||||
_displayName = lastPathComponent(_path);
|
_displayName = lastPathComponent(_path);
|
||||||
_isValid = true;
|
|
||||||
_isDirectory = true;
|
|
||||||
|
|
||||||
if (verify) {
|
if (verify) {
|
||||||
struct stat st;
|
setFlags();
|
||||||
_isValid = (0 == stat(_path.c_str(), &st));
|
|
||||||
_isDirectory = _isValid ? S_ISDIR(st.st_mode) : false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
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.
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
DIR *dirp = opendir(_path.c_str());
|
|
||||||
|
String newPath(_path);
|
||||||
|
if (_path.lastChar() != '/')
|
||||||
|
newPath += '/';
|
||||||
|
newPath += n;
|
||||||
|
|
||||||
|
return new POSIXFilesystemNode(newPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
DIR *dirp = opendir(_path.c_str());
|
||||||
struct dirent *dp;
|
struct dirent *dp;
|
||||||
|
|
||||||
if (dirp == NULL)
|
if (dirp == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// ... loop over dir entries using readdir
|
// loop over dir entries using readdir
|
||||||
while ((dp = readdir(dirp)) != NULL) {
|
while ((dp = readdir(dirp)) != NULL) {
|
||||||
// Skip 'invisible' files
|
// Skip 'invisible' files if necessary
|
||||||
if (dp->d_name[0] == '.')
|
if (dp->d_name[0] == '.' && !hidden) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
// Skip '.' and '..' to avoid cycles
|
||||||
|
if((dp->d_name[0] == '.' && dp->d_name[1] == 0) || (dp->d_name[0] == '.' && dp->d_name[1] == '.')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String newPath(_path);
|
String newPath(_path);
|
||||||
if (newPath.lastChar() != '/')
|
if (newPath.lastChar() != '/')
|
||||||
@ -156,18 +190,18 @@ bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
|||||||
POSIXFilesystemNode entry(newPath, false);
|
POSIXFilesystemNode entry(newPath, false);
|
||||||
|
|
||||||
#if defined(SYSTEM_NOT_SUPPORTING_D_TYPE)
|
#if defined(SYSTEM_NOT_SUPPORTING_D_TYPE)
|
||||||
// TODO: d_type is not part of POSIX, so it might not be supported
|
/* TODO: d_type is not part of POSIX, so it might not be supported
|
||||||
// on some of our targets. For those systems where it isn't supported,
|
* on some of our targets. For those systems where it isn't supported,
|
||||||
// add this #elif case, which tries to use stat() instead.
|
* add this #elif case, which tries to use stat() instead.
|
||||||
struct stat st;
|
*
|
||||||
entry._isValid = (0 == stat(entry._path.c_str(), &st));
|
* The d_type method is used to avoid costly recurrent stat() calls in big
|
||||||
entry._isDirectory = entry._isValid ? S_ISDIR(st.st_mode) : false;
|
* directories.
|
||||||
|
*/
|
||||||
|
entry.setFlags();
|
||||||
#else
|
#else
|
||||||
if (dp->d_type == DT_UNKNOWN) {
|
if (dp->d_type == DT_UNKNOWN) {
|
||||||
// Fall back to stat()
|
// Fall back to stat()
|
||||||
struct stat st;
|
entry.setFlags();
|
||||||
entry._isValid = (0 == stat(entry._path.c_str(), &st));
|
|
||||||
entry._isDirectory = entry._isValid ? S_ISDIR(st.st_mode) : false;
|
|
||||||
} else {
|
} else {
|
||||||
entry._isValid = (dp->d_type == DT_DIR) || (dp->d_type == DT_REG) || (dp->d_type == DT_LNK);
|
entry._isValid = (dp->d_type == DT_DIR) || (dp->d_type == DT_REG) || (dp->d_type == DT_LNK);
|
||||||
if (dp->d_type == DT_LNK) {
|
if (dp->d_type == DT_LNK) {
|
||||||
@ -194,35 +228,22 @@ bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
|||||||
|
|
||||||
if (entry._isDirectory)
|
if (entry._isDirectory)
|
||||||
entry._path += "/";
|
entry._path += "/";
|
||||||
|
|
||||||
myList.push_back(new POSIXFilesystemNode(entry));
|
myList.push_back(new POSIXFilesystemNode(entry));
|
||||||
}
|
}
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *POSIXFilesystemNode::parent() const {
|
AbstractFilesystemNode *POSIXFilesystemNode::getParent() const {
|
||||||
if (_path == "/")
|
if (_path == "/")
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const char *start = _path.c_str();
|
const char *start = _path.c_str();
|
||||||
const char *end = lastPathComponent(_path);
|
const char *end = lastPathComponent(_path);
|
||||||
|
|
||||||
POSIXFilesystemNode *p = new POSIXFilesystemNode(String(start, end - start), false);
|
return new POSIXFilesystemNode(String(start, end - start), true);
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *POSIXFilesystemNode::child(const String &n) const {
|
#endif //#if defined(UNIX)
|
||||||
// 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);
|
|
||||||
if (_path.lastChar() != '/')
|
|
||||||
newPath += '/';
|
|
||||||
newPath += n;
|
|
||||||
POSIXFilesystemNode *p = new POSIXFilesystemNode(newPath, true);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // defined(UNIX)
|
|
||||||
|
40
backends/fs/ps2/ps2-fs-factory.cpp
Normal file
40
backends/fs/ps2/ps2-fs-factory.cpp
Normal file
@ -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/ps2/ps2-fs-factory.h"
|
||||||
|
#include "backends/fs/ps2/ps2-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(Ps2FilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *Ps2FilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new Ps2FilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *Ps2FilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new Ps2FilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *Ps2FilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new Ps2FilesystemNode(path);
|
||||||
|
}
|
51
backends/fs/ps2/ps2-fs-factory.h
Normal file
51
backends/fs/ps2/ps2-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 PS2_FILESYSTEM_FACTORY_H
|
||||||
|
#define PS2_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates PS2FilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class Ps2FilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<Ps2FilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Ps2FilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*PS2_FILESYSTEM_FACTORY_H*/
|
@ -32,44 +32,52 @@
|
|||||||
extern AsyncFio fio;
|
extern AsyncFio fio;
|
||||||
extern OSystem_PS2 *g_systemPs2;
|
extern OSystem_PS2 *g_systemPs2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the ScummVM file system API based on the Ps2SDK.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
|
*/
|
||||||
class Ps2FilesystemNode : public AbstractFilesystemNode {
|
class Ps2FilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isRoot;
|
bool _isRoot;
|
||||||
String _path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ps2FilesystemNode(void);
|
/**
|
||||||
Ps2FilesystemNode(const Ps2FilesystemNode *node);
|
* Creates a PS2FilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
|
Ps2FilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a PS2FilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
Ps2FilesystemNode(const String &path);
|
Ps2FilesystemNode(const String &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
|
Ps2FilesystemNode(const Ps2FilesystemNode *node);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return !_isRoot; }
|
virtual String getName() const { return _displayName; }
|
||||||
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return !_isRoot; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
//virtual FSList listDir(ListMode) const;
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
|
||||||
virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); }
|
virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); }
|
||||||
virtual AbstractFilesystemNode *child(const String &n) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
Ps2FilesystemNode::Ps2FilesystemNode() {
|
||||||
return AbstractFilesystemNode::getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot(void) {
|
|
||||||
return new Ps2FilesystemNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new Ps2FilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ps2FilesystemNode::Ps2FilesystemNode(void) {
|
|
||||||
_isDirectory = true;
|
_isDirectory = true;
|
||||||
_isRoot = true;
|
_isRoot = true;
|
||||||
_displayName = "PlayStation 2";
|
_displayName = "PlayStation 2";
|
||||||
@ -108,7 +116,43 @@ Ps2FilesystemNode::Ps2FilesystemNode(const Ps2FilesystemNode *node) {
|
|||||||
_isRoot = node->_isRoot;
|
_isRoot = node->_isRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ps2FilesystemNode::listDir(AbstractFSList &list, ListMode mode) const {
|
AbstractFilesystemNode *Ps2FilesystemNode::getChild(const String &n) const {
|
||||||
|
if (!_isDirectory)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char listDir[256];
|
||||||
|
sprintf(listDir, "%s/", _path.c_str());
|
||||||
|
int fd = fio.dopen(listDir);
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
iox_dirent_t dirent;
|
||||||
|
|
||||||
|
while (fio.dread(fd, &dirent) > 0) {
|
||||||
|
if (strcmp(n.c_str(), dirent.name) == 0) {
|
||||||
|
Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode();
|
||||||
|
|
||||||
|
dirEntry->_isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR);
|
||||||
|
dirEntry->_isRoot = false;
|
||||||
|
|
||||||
|
dirEntry->_path = _path;
|
||||||
|
dirEntry->_path += "/";
|
||||||
|
dirEntry->_path += dirent.name;
|
||||||
|
|
||||||
|
dirEntry->_displayName = dirent.name;
|
||||||
|
|
||||||
|
fio.dclose(fd);
|
||||||
|
return dirEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fio.dclose(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const {
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
if (!_isDirectory)
|
if (!_isDirectory)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -135,6 +179,7 @@ bool Ps2FilesystemNode::listDir(AbstractFSList &list, ListMode mode) const {
|
|||||||
} else {
|
} else {
|
||||||
char listDir[256];
|
char listDir[256];
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (_path.lastChar() == '/')
|
if (_path.lastChar() == '/')
|
||||||
fd = fio.dopen(_path.c_str());
|
fd = fio.dopen(_path.c_str());
|
||||||
else {
|
else {
|
||||||
@ -173,7 +218,7 @@ bool Ps2FilesystemNode::listDir(AbstractFSList &list, ListMode mode) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *Ps2FilesystemNode::parent() const {
|
AbstractFilesystemNode *Ps2FilesystemNode::getParent() const {
|
||||||
if (_isRoot)
|
if (_isRoot)
|
||||||
return new Ps2FilesystemNode(this);
|
return new Ps2FilesystemNode(this);
|
||||||
|
|
||||||
@ -191,36 +236,3 @@ AbstractFilesystemNode *Ps2FilesystemNode::parent() const {
|
|||||||
else
|
else
|
||||||
return new Ps2FilesystemNode();
|
return new Ps2FilesystemNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *Ps2FilesystemNode::child(const String &n) const {
|
|
||||||
if (!_isDirectory)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
char listDir[256];
|
|
||||||
sprintf(listDir, "%s/", _path.c_str());
|
|
||||||
int fd = fio.dopen(listDir);
|
|
||||||
|
|
||||||
if (fd >= 0) {
|
|
||||||
iox_dirent_t dirent;
|
|
||||||
|
|
||||||
while (fio.dread(fd, &dirent) > 0) {
|
|
||||||
if (strcmp(n.c_str(), dirent.name) == 0) {
|
|
||||||
Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode();
|
|
||||||
|
|
||||||
dirEntry->_isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR);
|
|
||||||
dirEntry->_isRoot = false;
|
|
||||||
|
|
||||||
dirEntry->_path = _path;
|
|
||||||
dirEntry->_path += "/";
|
|
||||||
dirEntry->_path += dirent.name;
|
|
||||||
|
|
||||||
dirEntry->_displayName = dirent.name;
|
|
||||||
|
|
||||||
fio.dclose(fd);
|
|
||||||
return dirEntry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fio.dclose(fd);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
40
backends/fs/psp/psp-fs-factory.cpp
Normal file
40
backends/fs/psp/psp-fs-factory.cpp
Normal file
@ -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/psp/psp-fs-factory.h"
|
||||||
|
#include "backends/fs/psp/psp_fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(PSPFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PSPFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new PSPFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new PSPFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *PSPFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new PSPFilesystemNode(path, true);
|
||||||
|
}
|
51
backends/fs/psp/psp-fs-factory.h
Normal file
51
backends/fs/psp/psp-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 PSP_FILESYSTEM_FACTORY_H
|
||||||
|
#define PSP_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates PSPFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class PSPFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<PSPFilesystemFactory> {
|
||||||
|
public:
|
||||||
|
typedef Common::String String;
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode *makeRootFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const;
|
||||||
|
virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PSPFilesystemFactory() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*PSP_FILESYSTEM_FACTORY_H*/
|
@ -23,8 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __PSP__
|
#ifdef __PSP__
|
||||||
#include "engines/engine.h"
|
|
||||||
|
|
||||||
|
#include "engines/engine.h"
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -32,39 +32,65 @@
|
|||||||
|
|
||||||
#define ROOT_PATH "ms0:/"
|
#define ROOT_PATH "ms0:/"
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* Implementation of the ScummVM file system API based on PSPSDK API.
|
* Implementation of the ScummVM file system API based on PSPSDK API.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PSPFilesystemNode : public AbstractFilesystemNode {
|
class PSPFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
String _path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a PSPFilesystemNode with the root node as path.
|
||||||
|
*/
|
||||||
PSPFilesystemNode();
|
PSPFilesystemNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a PSPFilesystemNode 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.
|
||||||
|
*/
|
||||||
PSPFilesystemNode(const Common::String &p, bool verify);
|
PSPFilesystemNode(const Common::String &p, bool verify);
|
||||||
|
|
||||||
virtual String displayName() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual String name() const { return _displayName; }
|
virtual String getDisplayName() const { return _displayName; }
|
||||||
virtual bool isValid() const { return _isValid; }
|
virtual String getName() const { return _displayName; }
|
||||||
|
virtual String getPath() const { return _path; }
|
||||||
virtual bool isDirectory() const { return _isDirectory; }
|
virtual bool isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return _isValid; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
virtual AbstractFilesystemNode *child(const String &n) const;
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
/**
|
||||||
return AbstractFilesystemNode::getRoot();
|
* 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.
|
||||||
|
*/
|
||||||
|
static const char *lastPathComponent(const Common::String &str) {
|
||||||
|
const char *start = str.c_str();
|
||||||
|
const char *cur = start + str.size() - 2;
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
while (cur >= start && *cur != '/') {
|
||||||
return new PSPFilesystemNode();
|
--cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PSPFilesystemNode::PSPFilesystemNode() {
|
PSPFilesystemNode::PSPFilesystemNode() {
|
||||||
@ -89,14 +115,24 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
AbstractFilesystemNode *PSPFilesystemNode::getChild(const String &n) const {
|
||||||
return new PSPFilesystemNode(path, true);
|
// 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);
|
||||||
|
if (_path.lastChar() != '/')
|
||||||
|
newPath += '/';
|
||||||
|
newPath += n;
|
||||||
|
|
||||||
|
return new PSPFilesystemNode(newPath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
bool PSPFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
int dfd = sceIoDopen(_path.c_str());
|
int dfd = sceIoDopen(_path.c_str());
|
||||||
if (dfd > 0) {
|
if (dfd > 0) {
|
||||||
SceIoDirent dir;
|
SceIoDirent dir;
|
||||||
@ -133,18 +169,7 @@ bool PSPFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
AbstractFilesystemNode *PSPFilesystemNode::getParent() const {
|
||||||
const char *start = str.c_str();
|
|
||||||
const char *cur = start + str.size() - 2;
|
|
||||||
|
|
||||||
while (cur >= start && *cur != '/') {
|
|
||||||
--cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cur + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *PSPFilesystemNode::parent() const {
|
|
||||||
assert(_isValid);
|
assert(_isValid);
|
||||||
|
|
||||||
if (_path == ROOT_PATH)
|
if (_path == ROOT_PATH)
|
||||||
@ -153,22 +178,7 @@ AbstractFilesystemNode *PSPFilesystemNode::parent() const {
|
|||||||
const char *start = _path.c_str();
|
const char *start = _path.c_str();
|
||||||
const char *end = lastPathComponent(_path);
|
const char *end = lastPathComponent(_path);
|
||||||
|
|
||||||
PSPFilesystemNode *p = new PSPFilesystemNode(String(start, end - start), false);
|
return new PSPFilesystemNode(String(start, end - start), false);
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *PSPFilesystemNode::child(const String &n) const {
|
#endif //#ifdef __PSP__
|
||||||
// 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);
|
|
||||||
if (_path.lastChar() != '/')
|
|
||||||
newPath += '/';
|
|
||||||
newPath += n;
|
|
||||||
PSPFilesystemNode *p = new PSPFilesystemNode(newPath, true);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PSP
|
|
||||||
|
42
backends/fs/symbian/symbian-fs-factory.cpp
Normal file
42
backends/fs/symbian/symbian-fs-factory.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* 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/symbian/symbian-fs-factory.h"
|
||||||
|
#include "backends/fs/symbian/symbian-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(SymbianFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *SymbianFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new SymbianFilesystemNode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *SymbianFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
char path[MAXPATHLEN];
|
||||||
|
getcwd(path, MAXPATHLEN);
|
||||||
|
return new SymbianFilesystemNode(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *SymbianFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new SymbianFilesystemNode(path);
|
||||||
|
}
|
51
backends/fs/symbian/symbian-fs-factory.h
Normal file
51
backends/fs/symbian/symbian-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 SYMBIAN_FILESYSTEM_FACTORY_H
|
||||||
|
#define SYMBIAN_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates SymbianFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class SymbianFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<SymbianFilesystemFactory> {
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*SYMBIAN_FILESYSTEM_FACTORY_H*/
|
@ -31,33 +31,58 @@
|
|||||||
#include <f32file.h>
|
#include <f32file.h>
|
||||||
#include <bautils.h>
|
#include <bautils.h>
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of the ScummVM file system API based on POSIX.
|
* Implementation of the ScummVM file system API based on POSIX.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SymbianFilesystemNode : public AbstractFilesystemNode {
|
class SymbianFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
|
String _path;
|
||||||
bool _isDirectory;
|
bool _isDirectory;
|
||||||
bool _isValid;
|
bool _isValid;
|
||||||
String _path;
|
|
||||||
bool _isPseudoRoot;
|
bool _isPseudoRoot;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a SymbianFilesystemNode with the root node as path.
|
||||||
|
*
|
||||||
|
* @param aIsRoot true if the node will be a pseudo root, false otherwise.
|
||||||
|
*/
|
||||||
SymbianFilesystemNode(bool aIsRoot);
|
SymbianFilesystemNode(bool aIsRoot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SymbianFilesystemNode for a given path.
|
||||||
|
*
|
||||||
|
* @param path String with the path the new node should point to.
|
||||||
|
*/
|
||||||
SymbianFilesystemNode(const String &path);
|
SymbianFilesystemNode(const String &path);
|
||||||
virtual String displayName() const { return _displayName; }
|
|
||||||
virtual String name() const { return _displayName; }
|
virtual bool exists() const { return true; } //FIXME: this is just a stub
|
||||||
virtual bool isValid() const { return _isValid; }
|
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 isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return true; } //FIXME: this is just a stub
|
||||||
|
virtual bool isValid() const { return _isValid; }
|
||||||
|
virtual bool isWritable() const { return true; } //FIXME: this is just a stub
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
virtual AbstractFilesystemNode *child(const String &n) 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.
|
||||||
|
*/
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
static const char *lastPathComponent(const Common::String &str) {
|
||||||
const char *start = str.c_str();
|
const char *start = str.c_str();
|
||||||
const char *cur = start + str.size() - 2;
|
const char *cur = start + str.size() - 2;
|
||||||
@ -69,6 +94,11 @@ static const char *lastPathComponent(const Common::String &str) {
|
|||||||
return cur + 1;
|
return cur + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fixes the path by changing all slashes to backslashes.
|
||||||
|
*
|
||||||
|
* @param path String with the path to be fixed.
|
||||||
|
*/
|
||||||
static void fixFilePath(Common::String& path) {
|
static void fixFilePath(Common::String& path) {
|
||||||
TInt len = path.size();
|
TInt len = path.size();
|
||||||
|
|
||||||
@ -79,20 +109,6 @@ static void fixFilePath(Common::String& path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
||||||
char path[MAXPATHLEN];
|
|
||||||
getcwd(path, MAXPATHLEN);
|
|
||||||
return new SymbianFilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
|
||||||
return new SymbianFilesystemNode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
|
||||||
return new SymbianFilesystemNode(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbianFilesystemNode::SymbianFilesystemNode(bool aIsRoot) {
|
SymbianFilesystemNode::SymbianFilesystemNode(bool aIsRoot) {
|
||||||
_path = "";
|
_path = "";
|
||||||
_isValid = true;
|
_isValid = true;
|
||||||
@ -128,8 +144,29 @@ SymbianFilesystemNode::SymbianFilesystemNode(const String &path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SymbianFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
AbstractFilesystemNode *SymbianFilesystemNode::getChild(const String &n) const {
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
|
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;
|
||||||
|
|
||||||
|
return new SymbianFilesystemNode(newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
if (_isPseudoRoot) {
|
if (_isPseudoRoot) {
|
||||||
// Drives enumeration
|
// Drives enumeration
|
||||||
@ -199,18 +236,18 @@ bool SymbianFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
}
|
}
|
||||||
CleanupStack::PopAndDestroy(dirPtr);
|
CleanupStack::PopAndDestroy(dirPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *SymbianFilesystemNode::parent() const {
|
AbstractFilesystemNode *SymbianFilesystemNode::getParent() const {
|
||||||
SymbianFilesystemNode *p =NULL;
|
SymbianFilesystemNode *p =NULL;
|
||||||
|
|
||||||
// Root node is its own parent. Still we can't just return this
|
// Root node is its own parent. Still we can't just return this
|
||||||
// as the GUI code will call delete on the old node.
|
// as the GUI code will call delete on the old node.
|
||||||
if (!_isPseudoRoot && _path.size() > 3) {
|
if (!_isPseudoRoot && _path.size() > 3) {
|
||||||
p=new SymbianFilesystemNode(false);
|
p = new SymbianFilesystemNode(false);
|
||||||
const char *start = _path.c_str();
|
const char *start = _path.c_str();
|
||||||
const char *end = lastPathComponent(_path);
|
const char *end = lastPathComponent(_path);
|
||||||
|
|
||||||
@ -221,29 +258,10 @@ AbstractFilesystemNode *SymbianFilesystemNode::parent() const {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p=new SymbianFilesystemNode(true);
|
p = new SymbianFilesystemNode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *SymbianFilesystemNode::child(const String &n) const {
|
#endif //#if defined (__SYMBIAN32__)
|
||||||
assert(_isDirectory);
|
|
||||||
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;
|
|
||||||
|
|
||||||
SymbianFilesystemNode *p = new SymbianFilesystemNode(newPath);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // defined(__SYMBIAN32__)
|
|
||||||
|
40
backends/fs/windows/windows-fs-factory.cpp
Normal file
40
backends/fs/windows/windows-fs-factory.cpp
Normal file
@ -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/windows/windows-fs-factory.h"
|
||||||
|
#include "backends/fs/windows/windows-fs.cpp"
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(WindowsFilesystemFactory);
|
||||||
|
|
||||||
|
AbstractFilesystemNode *WindowsFilesystemFactory::makeRootFileNode() const {
|
||||||
|
return new WindowsFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *WindowsFilesystemFactory::makeCurrentDirectoryFileNode() const {
|
||||||
|
return new WindowsFilesystemNode("", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFilesystemNode *WindowsFilesystemFactory::makeFileNodePath(const String &path) const {
|
||||||
|
return new WindowsFilesystemNode(path, false);
|
||||||
|
}
|
51
backends/fs/windows/windows-fs-factory.h
Normal file
51
backends/fs/windows/windows-fs-factory.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* 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 WINDOWS_FILESYSTEM_FACTORY_H
|
||||||
|
#define WINDOWS_FILESYSTEM_FACTORY_H
|
||||||
|
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "backends/fs/abstract-fs-factory.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates WindowsFilesystemNode objects.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemFactory.
|
||||||
|
*/
|
||||||
|
class WindowsFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<WindowsFilesystemFactory> {
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*WINDOWS_FILESYSTEM_FACTORY_H*/
|
@ -29,6 +29,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
#include "backends/fs/abstract-fs.h"
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
#include <io.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifndef _WIN32_WCE
|
#ifndef _WIN32_WCE
|
||||||
@ -36,39 +37,93 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of the ScummVM file system API based on Windows API.
|
* Implementation of the ScummVM file system API based on Windows API.
|
||||||
|
*
|
||||||
|
* Parts of this class are documented in the base interface class, AbstractFilesystemNode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class WindowsFilesystemNode : public AbstractFilesystemNode {
|
class WindowsFilesystemNode : public AbstractFilesystemNode {
|
||||||
protected:
|
protected:
|
||||||
String _displayName;
|
String _displayName;
|
||||||
bool _isDirectory;
|
|
||||||
bool _isValid;
|
|
||||||
bool _isPseudoRoot;
|
|
||||||
String _path;
|
String _path;
|
||||||
|
bool _isDirectory;
|
||||||
|
bool _isPseudoRoot;
|
||||||
|
bool _isValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a WindowsFilesystemNode with the root node as path.
|
||||||
|
*
|
||||||
|
* In regular windows systems, a virtual root path is used "".
|
||||||
|
* In windows CE, the "\" root is used instead.
|
||||||
|
*/
|
||||||
WindowsFilesystemNode();
|
WindowsFilesystemNode();
|
||||||
WindowsFilesystemNode(const String &path);
|
|
||||||
|
/**
|
||||||
virtual String displayName() const { return _displayName; }
|
* Creates a WindowsFilesystemNode for a given path.
|
||||||
virtual String name() const { return _displayName; }
|
*
|
||||||
virtual bool isValid() const { return _isValid; }
|
* Examples:
|
||||||
|
* path=c:\foo\bar.txt, currentDir=false -> c:\foo\bar.txt
|
||||||
|
* 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 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);
|
||||||
|
|
||||||
|
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 isDirectory() const { return _isDirectory; }
|
||||||
virtual String path() const { return _path; }
|
virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; }
|
||||||
|
virtual bool isValid() const { return _isValid; }
|
||||||
|
virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; }
|
||||||
|
|
||||||
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
|
virtual AbstractFilesystemNode *getChild(const String &n) const;
|
||||||
virtual AbstractFilesystemNode *parent() const;
|
virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
|
||||||
virtual AbstractFilesystemNode *child(const String &n) const;
|
virtual AbstractFilesystemNode *getParent() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static char *toAscii(TCHAR *x);
|
/**
|
||||||
static const TCHAR* toUnicode(const char *x);
|
* Adds a single WindowsFilesystemNode to a given list.
|
||||||
static void addFile (AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data);
|
* This method is used by getChildren() to populate the directory entries list.
|
||||||
|
*
|
||||||
|
* @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 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a Unicode string to Ascii format.
|
||||||
|
*
|
||||||
|
* @param str String to convert from Unicode to Ascii.
|
||||||
|
* @return str in Ascii format.
|
||||||
|
*/
|
||||||
|
static char *toAscii(TCHAR *str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an Ascii string to Unicode format.
|
||||||
|
*
|
||||||
|
* @param str 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.
|
||||||
|
*/
|
||||||
static const char *lastPathComponent(const Common::String &str) {
|
static const char *lastPathComponent(const Common::String &str) {
|
||||||
const char *start = str.c_str();
|
const char *start = str.c_str();
|
||||||
const char *cur = start + str.size() - 2;
|
const char *cur = start + str.size() - 2;
|
||||||
@ -80,27 +135,6 @@ static const char *lastPathComponent(const Common::String &str) {
|
|||||||
return cur + 1;
|
return cur + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* WindowsFilesystemNode::toAscii(TCHAR *x) {
|
|
||||||
|
|
||||||
#ifndef UNICODE
|
|
||||||
return (char*)x;
|
|
||||||
#else
|
|
||||||
static char asciiString[MAX_PATH];
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, x, _tcslen(x) + 1, asciiString, sizeof(asciiString), NULL, NULL);
|
|
||||||
return asciiString;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
const TCHAR* WindowsFilesystemNode::toUnicode(const char *x) {
|
|
||||||
#ifndef UNICODE
|
|
||||||
return (const TCHAR *)x;
|
|
||||||
#else
|
|
||||||
static TCHAR unicodeString[MAX_PATH];
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, x, strlen(x) + 1, unicodeString, sizeof(unicodeString) / sizeof(TCHAR));
|
|
||||||
return unicodeString;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data) {
|
void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data) {
|
||||||
WindowsFilesystemNode entry;
|
WindowsFilesystemNode entry;
|
||||||
char *asciiName = toAscii(find_data->cFileName);
|
char *asciiName = toAscii(find_data->cFileName);
|
||||||
@ -128,25 +162,24 @@ void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const c
|
|||||||
list.push_back(new WindowsFilesystemNode(entry));
|
list.push_back(new WindowsFilesystemNode(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
char* WindowsFilesystemNode::toAscii(TCHAR *str) {
|
||||||
char path[MAX_PATH];
|
#ifndef UNICODE
|
||||||
GetCurrentDirectory(MAX_PATH, path);
|
return (char*)str;
|
||||||
|
#else
|
||||||
// Add a trailing slash, if necessary.
|
static char asciiString[MAX_PATH];
|
||||||
if (path[0] != 0) {
|
WideCharToMultiByte(CP_ACP, 0, str, _tcslen(str) + 1, asciiString, sizeof(asciiString), NULL, NULL);
|
||||||
if (path[strlen(path) - 1] != '\\')
|
return asciiString;
|
||||||
strcat(path, "\\");
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return new WindowsFilesystemNode(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
|
const TCHAR* WindowsFilesystemNode::toUnicode(const char *str) {
|
||||||
return new WindowsFilesystemNode();
|
#ifndef UNICODE
|
||||||
}
|
return (const TCHAR *)str;
|
||||||
|
#else
|
||||||
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
|
static TCHAR unicodeString[MAX_PATH];
|
||||||
return new WindowsFilesystemNode(path);
|
MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, unicodeString, sizeof(unicodeString) / sizeof(TCHAR));
|
||||||
|
return unicodeString;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowsFilesystemNode::WindowsFilesystemNode() {
|
WindowsFilesystemNode::WindowsFilesystemNode() {
|
||||||
@ -165,27 +198,58 @@ WindowsFilesystemNode::WindowsFilesystemNode() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowsFilesystemNode::WindowsFilesystemNode(const String &p) {
|
WindowsFilesystemNode::WindowsFilesystemNode(const String &p, const bool currentDir) {
|
||||||
assert(p.size() > 0);
|
if (currentDir) {
|
||||||
|
char path[MAX_PATH];
|
||||||
|
GetCurrentDirectory(MAX_PATH, path);
|
||||||
|
|
||||||
_path = p;
|
// Add a trailing slash, if necessary.
|
||||||
|
if (path[0] != 0) {
|
||||||
|
if (path[strlen(path) - 1] != '\\')
|
||||||
|
strcat(path, "\\");
|
||||||
|
}
|
||||||
|
_path = path;
|
||||||
|
}
|
||||||
|
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
|
// Check whether it is a directory, and whether the file actually exists
|
||||||
DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));
|
DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str()));
|
||||||
|
|
||||||
if (fileAttribs == INVALID_FILE_ATTRIBUTES) {
|
if (fileAttribs == INVALID_FILE_ATTRIBUTES) {
|
||||||
_isValid = false;
|
|
||||||
_isDirectory = false;
|
_isDirectory = false;
|
||||||
|
_isValid = false;
|
||||||
} else {
|
} else {
|
||||||
_isValid = true;
|
|
||||||
_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
|
||||||
|
_isValid = true;
|
||||||
}
|
}
|
||||||
_isPseudoRoot = false;
|
_isPseudoRoot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
|
AbstractFilesystemNode *WindowsFilesystemNode::getChild(const String &n) const {
|
||||||
assert(_isDirectory);
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowsFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
|
||||||
|
assert(_isDirectory);
|
||||||
|
|
||||||
|
//TODO: honor the hidden flag
|
||||||
|
|
||||||
if (_isPseudoRoot) {
|
if (_isPseudoRoot) {
|
||||||
#ifndef _WIN32_WCE
|
#ifndef _WIN32_WCE
|
||||||
@ -218,9 +282,12 @@ bool WindowsFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
sprintf(searchPath, "%s*", _path.c_str());
|
sprintf(searchPath, "%s*", _path.c_str());
|
||||||
|
|
||||||
handle = FindFirstFile(toUnicode(searchPath), &desc);
|
handle = FindFirstFile(toUnicode(searchPath), &desc);
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
addFile(myList, mode, _path.c_str(), &desc);
|
addFile(myList, mode, _path.c_str(), &desc);
|
||||||
|
|
||||||
while (FindNextFile(handle, &desc))
|
while (FindNextFile(handle, &desc))
|
||||||
addFile(myList, mode, _path.c_str(), &desc);
|
addFile(myList, mode, _path.c_str(), &desc);
|
||||||
|
|
||||||
@ -230,10 +297,12 @@ bool WindowsFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *WindowsFilesystemNode::parent() const {
|
AbstractFilesystemNode *WindowsFilesystemNode::getParent() const {
|
||||||
assert(_isValid || _isPseudoRoot);
|
assert(_isValid || _isPseudoRoot);
|
||||||
|
|
||||||
if (_isPseudoRoot)
|
if (_isPseudoRoot)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
WindowsFilesystemNode *p = new WindowsFilesystemNode();
|
WindowsFilesystemNode *p = new WindowsFilesystemNode();
|
||||||
if (_path.size() > 3) {
|
if (_path.size() > 3) {
|
||||||
const char *start = _path.c_str();
|
const char *start = _path.c_str();
|
||||||
@ -246,23 +315,8 @@ AbstractFilesystemNode *WindowsFilesystemNode::parent() const {
|
|||||||
p->_displayName = lastPathComponent(p->_path);
|
p->_displayName = lastPathComponent(p->_path);
|
||||||
p->_isPseudoRoot = false;
|
p->_isPseudoRoot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFilesystemNode *WindowsFilesystemNode::child(const String &n) const {
|
#endif //#ifdef WIN32
|
||||||
assert(_isDirectory);
|
|
||||||
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;
|
|
||||||
|
|
||||||
WindowsFilesystemNode *p = new WindowsFilesystemNode(newPath);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // WIN32
|
|
||||||
|
@ -114,14 +114,14 @@ PluginList DCPluginProvider::getPlugins() {
|
|||||||
// Scan for all plugins in this directory
|
// Scan for all plugins in this directory
|
||||||
FilesystemNode dir(PLUGIN_DIRECTORY);
|
FilesystemNode dir(PLUGIN_DIRECTORY);
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
|
||||||
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
||||||
Common::String name(i->name());
|
Common::String name(i->getName());
|
||||||
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
||||||
pl.push_back(new DCPlugin(i->path()));
|
pl.push_back(new DCPlugin(i->getPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,14 +107,14 @@ PluginList POSIXPluginProvider::getPlugins() {
|
|||||||
// Scan for all plugins in this directory
|
// Scan for all plugins in this directory
|
||||||
FilesystemNode dir(PLUGIN_DIRECTORY);
|
FilesystemNode dir(PLUGIN_DIRECTORY);
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
|
||||||
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
||||||
Common::String name(i->name());
|
Common::String name(i->getName());
|
||||||
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
||||||
pl.push_back(new POSIXPlugin(i->path()));
|
pl.push_back(new POSIXPlugin(i->getPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,14 +107,14 @@ PluginList SDLPluginProvider::getPlugins() {
|
|||||||
// Scan for all plugins in this directory
|
// Scan for all plugins in this directory
|
||||||
FilesystemNode dir(PLUGIN_DIRECTORY);
|
FilesystemNode dir(PLUGIN_DIRECTORY);
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
|
||||||
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
||||||
Common::String name(i->name());
|
Common::String name(i->getName());
|
||||||
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
||||||
pl.push_back(new SDLPlugin(i->path()));
|
pl.push_back(new SDLPlugin(i->getPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,14 +110,14 @@ PluginList Win32PluginProvider::getPlugins() {
|
|||||||
// Scan for all plugins in this directory
|
// Scan for all plugins in this directory
|
||||||
FilesystemNode dir(PLUGIN_DIRECTORY);
|
FilesystemNode dir(PLUGIN_DIRECTORY);
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) {
|
||||||
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) {
|
||||||
Common::String name(i->name());
|
Common::String name(i->getName());
|
||||||
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) {
|
||||||
pl.push_back(new Win32Plugin(i->path()));
|
pl.push_back(new Win32Plugin(i->getPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
#include "common/fs.h"
|
||||||
|
#include "common/file.h"
|
||||||
#include "backends/saves/default/default-saves.h"
|
#include "backends/saves/default/default-saves.h"
|
||||||
#include "backends/saves/compressed/compressed-saves.h"
|
#include "backends/saves/compressed/compressed-saves.h"
|
||||||
|
|
||||||
@ -86,7 +88,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void join_paths(const char *filename, const char *directory,
|
static void join_paths(const char *filename, const char *directory,
|
||||||
char *buf, int bufsize) {
|
char *buf, int bufsize) {
|
||||||
buf[bufsize-1] = '\0';
|
buf[bufsize-1] = '\0';
|
||||||
@ -113,57 +114,19 @@ static void join_paths(const char *filename, const char *directory,
|
|||||||
strncat(buf, filename, bufsize-1);
|
strncat(buf, filename, bufsize-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const char *filename) {
|
Common::StringList DefaultSaveFileManager::listSavefiles(const char *regex) {
|
||||||
char buf[256];
|
FilesystemNode savePath(getSavePath());
|
||||||
|
FSList savefiles;
|
||||||
// Ensure that the savepath exists and is writeable. If not, generate
|
Common::StringList results;
|
||||||
// an appropriate error
|
Common::String search(regex);
|
||||||
const char *savePath = getSavePath();
|
|
||||||
#if defined(UNIX) || defined(__SYMBIAN32__)
|
|
||||||
struct stat sb;
|
|
||||||
|
|
||||||
// Check whether the dir exists
|
if (savePath.lookupFile(savefiles, savePath, search, false, true)) {
|
||||||
if (stat(savePath, &sb) == -1) {
|
for (FSList::const_iterator file = savefiles.begin(); file != savefiles.end(); file++) {
|
||||||
// The dir does not exist, or stat failed for some other reason.
|
results.push_back(file->getPath());
|
||||||
// If the problem was that the path pointed to nothing, try
|
|
||||||
// to create the dir.
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
if (mkdir(savePath, 0755) != 0) {
|
|
||||||
// mkdir could fail for various reasons: The parent dir doesn't exist,
|
|
||||||
// or is not writeable, the path could be completly bogus, etc.
|
|
||||||
warning("mkdir for '%s' failed!", savePath);
|
|
||||||
perror("mkdir");
|
|
||||||
// TODO: Specify an error code here so that callers can
|
|
||||||
// determine what exactly went wrong.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Unknown error, abort.
|
|
||||||
// TODO: Specify an error code here so that callers can
|
|
||||||
// determine what exactly went wrong.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// So stat() succeeded. But is the path actually pointing to a
|
|
||||||
// directory?
|
|
||||||
if (!S_ISDIR(sb.st_mode)) {
|
|
||||||
// TODO: Specify an error code here so that callers can
|
|
||||||
// determine what exactly went wrong.
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
return results;
|
||||||
|
|
||||||
join_paths(filename, savePath, buf, sizeof(buf));
|
|
||||||
|
|
||||||
StdioSaveFile *sf = new StdioSaveFile(buf, true);
|
|
||||||
|
|
||||||
if (!sf->isOpen()) {
|
|
||||||
delete sf;
|
|
||||||
sf = 0;
|
|
||||||
}
|
|
||||||
return wrapOutSaveFile(sf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename) {
|
Common::InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename) {
|
||||||
@ -179,11 +142,97 @@ Common::InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename)
|
|||||||
return wrapInSaveFile(sf);
|
return wrapInSaveFile(sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultSaveFileManager::listSavefiles(const char * /* prefix */, bool *marks, int num) {
|
Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const char *filename) {
|
||||||
// TODO: Implement this properly, at least on systems that support
|
char buf[256];
|
||||||
// opendir/readdir.
|
|
||||||
// Even better, replace this with a better design...
|
// Ensure that the savepath exists and is writeable. If not, generate
|
||||||
memset(marks, true, num * sizeof(bool));
|
// an appropriate error
|
||||||
|
const char *savePath = getSavePath();
|
||||||
|
|
||||||
|
#if defined(UNIX) || defined(__SYMBIAN32__)
|
||||||
|
struct stat sb;
|
||||||
|
clearError();
|
||||||
|
|
||||||
|
// Check whether the dir exists
|
||||||
|
if (stat(savePath, &sb) == -1) {
|
||||||
|
// The dir does not exist, or stat failed for some other reason.
|
||||||
|
// If the problem was that the path pointed to nothing, try
|
||||||
|
// to create the dir (ENOENT case).
|
||||||
|
switch (errno) {
|
||||||
|
case EACCES:
|
||||||
|
setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied"));
|
||||||
|
break;
|
||||||
|
case ELOOP:
|
||||||
|
setError(SFM_DIR_LOOP, Common::String("Too many symbolic links encountered while traversing the path"));
|
||||||
|
break;
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
setError(SFM_DIR_NAMETOOLONG, Common::String("The path name is too long"));
|
||||||
|
break;
|
||||||
|
case ENOENT:
|
||||||
|
if (mkdir(savePath, 0755) != 0) {
|
||||||
|
// mkdir could fail for various reasons: The parent dir doesn't exist,
|
||||||
|
// or is not writeable, the path could be completly bogus, etc.
|
||||||
|
warning("mkdir for '%s' failed!", savePath);
|
||||||
|
perror("mkdir");
|
||||||
|
|
||||||
|
switch (errno) {
|
||||||
|
case EACCES:
|
||||||
|
setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied"));
|
||||||
|
break;
|
||||||
|
case EMLINK:
|
||||||
|
setError(SFM_DIR_LINKMAX, Common::String("The link count of the parent directory would exceed {LINK_MAX}"));
|
||||||
|
break;
|
||||||
|
case ELOOP:
|
||||||
|
setError(SFM_DIR_LOOP, Common::String("Too many symbolic links encountered while traversing the path"));
|
||||||
|
break;
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
setError(SFM_DIR_NAMETOOLONG, Common::String("The path name is too long"));
|
||||||
|
break;
|
||||||
|
case ENOENT:
|
||||||
|
setError(SFM_DIR_NOENT, Common::String("A component of the path path does not exist, or the path is an empty string"));
|
||||||
|
break;
|
||||||
|
case ENOTDIR:
|
||||||
|
setError(SFM_DIR_NOTDIR, Common::String("A component of the path prefix is not a directory"));
|
||||||
|
break;
|
||||||
|
case EROFS:
|
||||||
|
setError(SFM_DIR_ROFS, Common::String("The parent directory resides on a read-only file system"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ENOTDIR:
|
||||||
|
setError(SFM_DIR_NOTDIR, Common::String("A component of the path prefix is not a directory"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// So stat() succeeded. But is the path actually pointing to a directory?
|
||||||
|
if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
setError(SFM_DIR_NOTDIR, Common::String("The given savepath is not a directory"));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
join_paths(filename, savePath, buf, sizeof(buf));
|
||||||
|
|
||||||
|
StdioSaveFile *sf = new StdioSaveFile(buf, true);
|
||||||
|
|
||||||
|
if (!sf->isOpen()) {
|
||||||
|
delete sf;
|
||||||
|
sf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapOutSaveFile(sf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DefaultSaveFileManager::removeSavefile(const char *filename) {
|
||||||
|
Common::File file;
|
||||||
|
FilesystemNode savePath(filename);
|
||||||
|
return file.remove(savePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
|
#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
|
||||||
|
@ -28,12 +28,14 @@
|
|||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
|
||||||
class DefaultSaveFileManager : public Common::SaveFileManager {
|
class DefaultSaveFileManager : public Common::SaveFileManager {
|
||||||
public:
|
public:
|
||||||
virtual Common::OutSaveFile *openForSaving(const char *filename);
|
virtual Common::StringList listSavefiles(const char *regex);
|
||||||
virtual Common::InSaveFile *openForLoading(const char *filename);
|
virtual Common::InSaveFile *openForLoading(const char *filename);
|
||||||
virtual void listSavefiles(const char * /* prefix */, bool *marks, int num);
|
virtual Common::OutSaveFile *openForSaving(const char *filename);
|
||||||
|
virtual bool removeSavefile(const char *filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
#include "common/fs.h"
|
||||||
|
|
||||||
#include "sound/mididrv.h"
|
#include "sound/mididrv.h"
|
||||||
#include "sound/mixer.h"
|
#include "sound/mixer.h"
|
||||||
@ -48,10 +49,6 @@
|
|||||||
|
|
||||||
#define DETECTOR_TESTING_HACK
|
#define DETECTOR_TESTING_HACK
|
||||||
|
|
||||||
#ifdef DETECTOR_TESTING_HACK
|
|
||||||
#include "common/fs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Base {
|
namespace Base {
|
||||||
|
|
||||||
static const char USAGE_STRING[] =
|
static const char USAGE_STRING[] =
|
||||||
@ -313,7 +310,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
|
|||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
s = argv[i];
|
s = argv[i];
|
||||||
s2 = (i < argc-1) ? argv[i+1] : 0;
|
s2 = (i < argc-1) ? argv[i+1] : 0;
|
||||||
|
|
||||||
if (s[0] != '-') {
|
if (s[0] != '-') {
|
||||||
// The argument doesn't start with a dash, so it's not an option.
|
// The argument doesn't start with a dash, so it's not an option.
|
||||||
// Hence it must be the target name. We currently enforce that
|
// Hence it must be the target name. We currently enforce that
|
||||||
@ -390,7 +387,12 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
|
|||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_OPTION('p', "path")
|
DO_OPTION('p', "path")
|
||||||
// TODO: Verify whether the path is valid
|
FilesystemNode path(option);
|
||||||
|
if(!path.exists()) {
|
||||||
|
usage("Non-existent game path '%s'", option);
|
||||||
|
} else if(!path.isReadable()) {
|
||||||
|
usage("Non-readable game path '%s'", option);
|
||||||
|
}
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_OPTION('q', "language")
|
DO_OPTION('q', "language")
|
||||||
@ -428,7 +430,12 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
|
|||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION("soundfont")
|
DO_LONG_OPTION("soundfont")
|
||||||
// TODO: Verify whether the path is valid
|
FilesystemNode path(option);
|
||||||
|
if(!path.exists()) {
|
||||||
|
usage("Non-existent soundfont path '%s'", option);
|
||||||
|
} else if(!path.isReadable()) {
|
||||||
|
usage("Non-readable soundfont path '%s'", option);
|
||||||
|
}
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION_BOOL("disable-sdl-parachute")
|
DO_LONG_OPTION_BOOL("disable-sdl-parachute")
|
||||||
@ -453,7 +460,12 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
|
|||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION("savepath")
|
DO_LONG_OPTION("savepath")
|
||||||
// TODO: Verify whether the path is valid
|
FilesystemNode path(option);
|
||||||
|
if(!path.exists()) {
|
||||||
|
usage("Non-existent savegames path '%s'", option);
|
||||||
|
} else if(!path.isWritable()) {
|
||||||
|
usage("Non-writable savegames path '%s'", option);
|
||||||
|
}
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION_INT("talkspeed")
|
DO_LONG_OPTION_INT("talkspeed")
|
||||||
@ -466,7 +478,12 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, char **ar
|
|||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION("themepath")
|
DO_LONG_OPTION("themepath")
|
||||||
// TODO: Verify whether the path is valid
|
FilesystemNode path(option);
|
||||||
|
if(!path.exists()) {
|
||||||
|
usage("Non-existent theme path '%s'", option);
|
||||||
|
} else if(!path.isReadable()) {
|
||||||
|
usage("Non-readable theme path '%s'", option);
|
||||||
|
}
|
||||||
END_OPTION
|
END_OPTION
|
||||||
|
|
||||||
DO_LONG_OPTION("target-md5")
|
DO_LONG_OPTION("target-md5")
|
||||||
@ -562,7 +579,7 @@ static void runDetectorTest() {
|
|||||||
|
|
||||||
FilesystemNode dir(path);
|
FilesystemNode dir(path);
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListAll)) {
|
if (!dir.getChildren(files, FilesystemNode::kListAll)) {
|
||||||
printf(" ... invalid path, skipping\n");
|
printf(" ... invalid path, skipping\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -673,13 +690,18 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
|
|||||||
if (!settings.contains("savepath")) {
|
if (!settings.contains("savepath")) {
|
||||||
const char *dir = getenv("SCUMMVM_SAVEPATH");
|
const char *dir = getenv("SCUMMVM_SAVEPATH");
|
||||||
if (dir && *dir && strlen(dir) < MAXPATHLEN) {
|
if (dir && *dir && strlen(dir) < MAXPATHLEN) {
|
||||||
// TODO: Verify whether the path is valid
|
FilesystemNode saveDir(dir);
|
||||||
settings["savepath"] = dir;
|
if(!saveDir.exists()) {
|
||||||
|
warning("Non-existent SCUMMVM_SAVEPATH save path. It will be ignored.");
|
||||||
|
} else if(!saveDir.isWritable()) {
|
||||||
|
warning("Non-writable SCUMMVM_SAVEPATH save path. It will be ignored.");
|
||||||
|
} else {
|
||||||
|
settings["savepath"] = dir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Finally, store the command line settings into the config manager.
|
// Finally, store the command line settings into the config manager.
|
||||||
for (Common::StringMap::const_iterator x = settings.begin(); x != settings.end(); ++x) {
|
for (Common::StringMap::const_iterator x = settings.begin(); x != settings.end(); ++x) {
|
||||||
Common::String key(x->_key);
|
Common::String key(x->_key);
|
||||||
|
@ -276,7 +276,7 @@ PluginError detectGameForEngineCreation(
|
|||||||
|
|
||||||
FSList fslist;
|
FSList fslist;
|
||||||
FilesystemNode dir(ConfMan.get("path"));
|
FilesystemNode dir(ConfMan.get("path"));
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(fslist, FilesystemNode::kListFilesOnly)) {
|
||||||
return kInvalidPathError;
|
return kInvalidPathError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +345,7 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p
|
|||||||
// Get the information of the existing files
|
// Get the information of the existing files
|
||||||
for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) {
|
for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) {
|
||||||
if (file->isDirectory()) continue;
|
if (file->isDirectory()) continue;
|
||||||
tstr = file->name();
|
tstr = file->getName();
|
||||||
tstr.toLowercase();
|
tstr.toLowercase();
|
||||||
|
|
||||||
// Strip any trailing dot
|
// Strip any trailing dot
|
||||||
@ -364,7 +364,7 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p
|
|||||||
|
|
||||||
debug(3, "> %s: %s", tstr.c_str(), md5str);
|
debug(3, "> %s: %s", tstr.c_str(), md5str);
|
||||||
|
|
||||||
if (testFile.open(file->path())) {
|
if (testFile.open(file->getPath())) {
|
||||||
filesSize[tstr] = (int32)testFile.size();
|
filesSize[tstr] = (int32)testFile.size();
|
||||||
testFile.close();
|
testFile.close();
|
||||||
}
|
}
|
||||||
|
47
common/error.h
Normal file
47
common/error.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* 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 COMMON_ERROR_H
|
||||||
|
#define COMMON_ERROR_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains enums with error codes commonly used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Errors used in the SaveFileManager class.
|
||||||
|
*/
|
||||||
|
enum SFMError {
|
||||||
|
SFM_NO_ERROR, //Default state, indicates no error has been recorded
|
||||||
|
SFM_DIR_ACCESS, //stat(), mkdir()::EACCES: Search or write permission denied
|
||||||
|
SFM_DIR_LINKMAX, //mkdir()::EMLINK: The link count of the parent directory would exceed {LINK_MAX}
|
||||||
|
SFM_DIR_LOOP, //stat(), mkdir()::ELOOP: Too many symbolic links encountered while traversing the path
|
||||||
|
SFM_DIR_NAMETOOLONG, //stat(), mkdir()::ENAMETOOLONG: The path name is too long
|
||||||
|
SFM_DIR_NOENT, //stat(), mkdir()::ENOENT: A component of the path path does not exist, or the path is an empty string
|
||||||
|
SFM_DIR_NOTDIR, //stat(), mkdir()::ENOTDIR: A component of the path prefix is not a directory
|
||||||
|
SFM_DIR_ROFS //mkdir()::EROFS: The parent directory resides on a read-only file system
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //COMMON_ERROR_H
|
@ -28,6 +28,7 @@
|
|||||||
#include "common/hashmap.h"
|
#include "common/hashmap.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include "common/hash-str.h"
|
#include "common/hash-str.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef MACOSX
|
#ifdef MACOSX
|
||||||
#include "CoreFoundation/CoreFoundation.h"
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
@ -226,7 +227,7 @@ void File::addDefaultDirectoryRecursive(const FilesystemNode &dir, int level, co
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
FSList fslist;
|
FSList fslist;
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListAll)) {
|
if (!dir.getChildren(fslist, FilesystemNode::kListAll)) {
|
||||||
// Failed listing the contents of this node, so it is either not a
|
// Failed listing the contents of this node, so it is either not a
|
||||||
// directory, or just doesn't exist at all.
|
// directory, or just doesn't exist at all.
|
||||||
return;
|
return;
|
||||||
@ -237,7 +238,7 @@ void File::addDefaultDirectoryRecursive(const FilesystemNode &dir, int level, co
|
|||||||
|
|
||||||
// Do not add directories multiple times, unless this time they are added
|
// Do not add directories multiple times, unless this time they are added
|
||||||
// with a bigger depth.
|
// with a bigger depth.
|
||||||
const String &directory(dir.path());
|
const String &directory(dir.getPath());
|
||||||
if (_defaultDirectories->contains(directory) && (*_defaultDirectories)[directory] >= level)
|
if (_defaultDirectories->contains(directory) && (*_defaultDirectories)[directory] >= level)
|
||||||
return;
|
return;
|
||||||
(*_defaultDirectories)[directory] = level;
|
(*_defaultDirectories)[directory] = level;
|
||||||
@ -247,13 +248,13 @@ void File::addDefaultDirectoryRecursive(const FilesystemNode &dir, int level, co
|
|||||||
|
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (file->isDirectory()) {
|
if (file->isDirectory()) {
|
||||||
addDefaultDirectoryRecursive(file->path(), level - 1, prefix + file->name() + "/");
|
addDefaultDirectoryRecursive(file->getPath(), level - 1, prefix + file->getName() + "/");
|
||||||
} else {
|
} else {
|
||||||
String lfn(prefix);
|
String lfn(prefix);
|
||||||
lfn += file->name();
|
lfn += file->getName();
|
||||||
lfn.toLowercase();
|
lfn.toLowercase();
|
||||||
if (!_filesMap->contains(lfn)) {
|
if (!_filesMap->contains(lfn)) {
|
||||||
(*_filesMap)[lfn] = file->path();
|
(*_filesMap)[lfn] = file->getPath();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,15 +365,21 @@ bool File::open(const String &filename, AccessMode mode) {
|
|||||||
bool File::open(const FilesystemNode &node, AccessMode mode) {
|
bool File::open(const FilesystemNode &node, AccessMode mode) {
|
||||||
assert(mode == kFileReadMode || mode == kFileWriteMode);
|
assert(mode == kFileReadMode || mode == kFileWriteMode);
|
||||||
|
|
||||||
if (!node.isValid()) {
|
if (!node.exists()) {
|
||||||
warning("File::open: Trying to open an invalid FilesystemNode object");
|
warning("File::open: Trying to open a FilesystemNode which does not exist");
|
||||||
return false;
|
return false;
|
||||||
} else if (node.isDirectory()) {
|
} else if (node.isDirectory()) {
|
||||||
warning("File::open: Trying to open a FilesystemNode which is a directory");
|
warning("File::open: Trying to open a FilesystemNode which is a directory");
|
||||||
return false;
|
return false;
|
||||||
}
|
} /*else if (!node.isReadable() && mode == kFileReadMode) {
|
||||||
|
warning("File::open: Trying to open an unreadable FilesystemNode object for reading");
|
||||||
|
return false;
|
||||||
|
} else if (!node.isWritable() && mode == kFileWriteMode) {
|
||||||
|
warning("File::open: Trying to open an unwritable FilesystemNode object for writing");
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
String filename(node.name());
|
String filename(node.getName());
|
||||||
|
|
||||||
if (_handle) {
|
if (_handle) {
|
||||||
error("File::open: This file object already is opened (%s), won't open '%s'", _name.c_str(), filename.c_str());
|
error("File::open: This file object already is opened (%s), won't open '%s'", _name.c_str(), filename.c_str());
|
||||||
@ -383,7 +390,7 @@ bool File::open(const FilesystemNode &node, AccessMode mode) {
|
|||||||
|
|
||||||
const char *modeStr = (mode == kFileReadMode) ? "rb" : "wb";
|
const char *modeStr = (mode == kFileReadMode) ? "rb" : "wb";
|
||||||
|
|
||||||
_handle = fopen(node.path().c_str(), modeStr);
|
_handle = fopen(node.getPath().c_str(), modeStr);
|
||||||
|
|
||||||
if (_handle == NULL) {
|
if (_handle == NULL) {
|
||||||
if (mode == kFileReadMode)
|
if (mode == kFileReadMode)
|
||||||
@ -402,16 +409,40 @@ bool File::open(const FilesystemNode &node, AccessMode mode) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool File::remove(const String &filename){
|
||||||
|
if (remove(filename.c_str()) != 0) {
|
||||||
|
if(errno == EACCES)
|
||||||
|
;//TODO: read-only file
|
||||||
|
if(errno == ENOENT)
|
||||||
|
;//TODO: non-existent file
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool File::remove(const FilesystemNode &node){
|
||||||
|
if (remove(node.getPath()) != 0) {
|
||||||
|
if(errno == EACCES)
|
||||||
|
;//TODO: read-only file
|
||||||
|
if(errno == ENOENT)
|
||||||
|
;//TODO: non-existent file
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool File::exists(const String &filename) {
|
bool File::exists(const String &filename) {
|
||||||
// First try to find the file it via a FilesystemNode (in case an absolute
|
// First try to find the file it via a FilesystemNode (in case an absolute
|
||||||
// path was passed). But we only use this to filter out directories.
|
// path was passed). But we only use this to filter out directories.
|
||||||
FilesystemNode file(filename);
|
FilesystemNode file(filename);
|
||||||
// FIXME: can't use isValid() here since at the time of writing
|
|
||||||
// FilesystemNode is to be unable to find for example files
|
return (!file.isDirectory() && file.exists());
|
||||||
// added in extrapath
|
|
||||||
if (file.isDirectory())
|
//***DEPRECATED COMMENTS BELOW, LEFT FOR DISCUSSION***
|
||||||
return false;
|
|
||||||
|
|
||||||
// Next, try to locate the file by *opening* it in read mode. This has
|
// Next, try to locate the file by *opening* it in read mode. This has
|
||||||
// multiple effects:
|
// multiple effects:
|
||||||
// 1) It takes _filesMap and _defaultDirectories into consideration -> good
|
// 1) It takes _filesMap and _defaultDirectories into consideration -> good
|
||||||
|
@ -52,7 +52,7 @@ private:
|
|||||||
// code that accidentally copied File objects tended to break in strange
|
// code that accidentally copied File objects tended to break in strange
|
||||||
// ways.
|
// ways.
|
||||||
File(const File &f);
|
File(const File &f);
|
||||||
File &operator =(const File &f);
|
File &operator =(const File &f);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum AccessMode {
|
enum AccessMode {
|
||||||
@ -86,6 +86,9 @@ public:
|
|||||||
|
|
||||||
virtual void close();
|
virtual void close();
|
||||||
|
|
||||||
|
virtual bool remove(const String &filename);
|
||||||
|
virtual bool remove(const FilesystemNode &node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the object opened a file successfully.
|
* Checks if the object opened a file successfully.
|
||||||
*
|
*
|
||||||
|
228
common/fs.cpp
228
common/fs.cpp
@ -23,14 +23,45 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/stdafx.h"
|
#include "common/stdafx.h"
|
||||||
|
|
||||||
#include "backends/fs/abstract-fs.h"
|
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
#include "backends/fs/abstract-fs.h"
|
||||||
|
#include "backends/fs/fs-factory-maker.cpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple DOS-style pattern matching function (understands * and ? like used in DOS).
|
||||||
|
* Taken from exult/files/listfiles.cc
|
||||||
|
*/
|
||||||
|
static bool matchString(const char *str, const char *pat) {
|
||||||
|
const char *p = 0;
|
||||||
|
const char *q = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
switch (*pat) {
|
||||||
|
case '*':
|
||||||
|
p = ++pat;
|
||||||
|
q = str;
|
||||||
|
break;
|
||||||
|
|
||||||
FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) {
|
default:
|
||||||
_realNode = realNode;
|
if (*pat != *str) {
|
||||||
_refCount = new int(1);
|
if (p) {
|
||||||
|
pat = p;
|
||||||
|
str = ++q;
|
||||||
|
if(!*str)
|
||||||
|
return !*pat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// fallthrough
|
||||||
|
case '?':
|
||||||
|
if(!*str)
|
||||||
|
return !*pat;
|
||||||
|
pat++;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilesystemNode::FilesystemNode() {
|
FilesystemNode::FilesystemNode() {
|
||||||
@ -38,6 +69,11 @@ FilesystemNode::FilesystemNode() {
|
|||||||
_refCount = 0;
|
_refCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) {
|
||||||
|
_realNode = realNode;
|
||||||
|
_refCount = new int(1);
|
||||||
|
}
|
||||||
|
|
||||||
FilesystemNode::FilesystemNode(const FilesystemNode &node) {
|
FilesystemNode::FilesystemNode(const FilesystemNode &node) {
|
||||||
_realNode = node._realNode;
|
_realNode = node._realNode;
|
||||||
_refCount = node._refCount;
|
_refCount = node._refCount;
|
||||||
@ -46,10 +82,12 @@ FilesystemNode::FilesystemNode(const FilesystemNode &node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FilesystemNode::FilesystemNode(const Common::String &p) {
|
FilesystemNode::FilesystemNode(const Common::String &p) {
|
||||||
|
AbstractFilesystemFactory *factory = makeFSFactory();
|
||||||
|
|
||||||
if (p.empty() || p == ".")
|
if (p.empty() || p == ".")
|
||||||
_realNode = AbstractFilesystemNode::getCurrentDirectory();
|
_realNode = factory->makeCurrentDirectoryFileNode();
|
||||||
else
|
else
|
||||||
_realNode = AbstractFilesystemNode::getNodeForPath(p);
|
_realNode = factory->makeFileNodePath(p);
|
||||||
_refCount = new int(1);
|
_refCount = new int(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +95,28 @@ FilesystemNode::~FilesystemNode() {
|
|||||||
decRefCount();
|
decRefCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilesystemNode &FilesystemNode::operator= (const FilesystemNode &node) {
|
||||||
|
if (node._refCount)
|
||||||
|
++(*node._refCount);
|
||||||
|
|
||||||
|
decRefCount();
|
||||||
|
|
||||||
|
_realNode = node._realNode;
|
||||||
|
_refCount = node._refCount;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilesystemNode::operator<(const FilesystemNode& node) const
|
||||||
|
{
|
||||||
|
if (isDirectory() && !node.isDirectory())
|
||||||
|
return true;
|
||||||
|
if (!isDirectory() && node.isDirectory())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return scumm_stricmp(getDisplayName().c_str(), node.getDisplayName().c_str()) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
void FilesystemNode::decRefCount() {
|
void FilesystemNode::decRefCount() {
|
||||||
if (_refCount) {
|
if (_refCount) {
|
||||||
assert(*_refCount > 0);
|
assert(*_refCount > 0);
|
||||||
@ -68,34 +128,11 @@ void FilesystemNode::decRefCount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilesystemNode &FilesystemNode::operator =(const FilesystemNode &node) {
|
bool FilesystemNode::exists() const {
|
||||||
if (node._refCount)
|
|
||||||
++(*node._refCount);
|
|
||||||
|
|
||||||
decRefCount();
|
|
||||||
|
|
||||||
_realNode = node._realNode;
|
|
||||||
_refCount = node._refCount;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilesystemNode::isValid() const {
|
|
||||||
if (_realNode == 0)
|
if (_realNode == 0)
|
||||||
return false;
|
return false;
|
||||||
return _realNode->isValid();
|
|
||||||
}
|
return _realNode->exists();
|
||||||
|
|
||||||
FilesystemNode FilesystemNode::getParent() const {
|
|
||||||
if (_realNode == 0)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
AbstractFilesystemNode *node = _realNode->parent();
|
|
||||||
if (node == 0) {
|
|
||||||
return *this;
|
|
||||||
} else {
|
|
||||||
return FilesystemNode(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FilesystemNode FilesystemNode::getChild(const Common::String &n) const {
|
FilesystemNode FilesystemNode::getChild(const Common::String &n) const {
|
||||||
@ -103,17 +140,17 @@ FilesystemNode FilesystemNode::getChild(const Common::String &n) const {
|
|||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
assert(_realNode->isDirectory());
|
assert(_realNode->isDirectory());
|
||||||
AbstractFilesystemNode *node = _realNode->child(n);
|
AbstractFilesystemNode *node = _realNode->getChild(n);
|
||||||
return FilesystemNode(node);
|
return FilesystemNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilesystemNode::listDir(FSList &fslist, ListMode mode) const {
|
bool FilesystemNode::getChildren(FSList &fslist, ListMode mode, bool hidden) const {
|
||||||
if (!_realNode || !_realNode->isDirectory())
|
if (!_realNode || !_realNode->isDirectory())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AbstractFSList tmp;
|
AbstractFSList tmp;
|
||||||
|
|
||||||
if (!_realNode->listDir(tmp, mode))
|
if (!_realNode->getChildren(tmp, mode, hidden))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fslist.clear();
|
fslist.clear();
|
||||||
@ -124,33 +161,108 @@ bool FilesystemNode::listDir(FSList &fslist, ListMode mode) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::String FilesystemNode::getDisplayName() const {
|
||||||
|
assert(_realNode);
|
||||||
|
return _realNode->getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String FilesystemNode::getName() const {
|
||||||
|
assert(_realNode);
|
||||||
|
return _realNode->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilesystemNode FilesystemNode::getParent() const {
|
||||||
|
if (_realNode == 0)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
AbstractFilesystemNode *node = _realNode->getParent();
|
||||||
|
if (node == 0) {
|
||||||
|
return *this;
|
||||||
|
} else {
|
||||||
|
return FilesystemNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String FilesystemNode::getPath() const {
|
||||||
|
assert(_realNode);
|
||||||
|
return _realNode->getPath();
|
||||||
|
}
|
||||||
|
|
||||||
bool FilesystemNode::isDirectory() const {
|
bool FilesystemNode::isDirectory() const {
|
||||||
if (_realNode == 0)
|
if (_realNode == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return _realNode->isDirectory();
|
return _realNode->isDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::String FilesystemNode::displayName() const {
|
bool FilesystemNode::isReadable() const {
|
||||||
assert(_realNode);
|
if (_realNode == 0)
|
||||||
return _realNode->displayName();
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::String FilesystemNode::name() const {
|
|
||||||
assert(_realNode);
|
|
||||||
return _realNode->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::String FilesystemNode::path() const {
|
|
||||||
assert(_realNode);
|
|
||||||
return _realNode->path();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool FilesystemNode::operator< (const FilesystemNode& node) const
|
|
||||||
{
|
|
||||||
if (isDirectory() && !node.isDirectory())
|
|
||||||
return true;
|
|
||||||
if (!isDirectory() && node.isDirectory())
|
|
||||||
return false;
|
return false;
|
||||||
return scumm_stricmp(displayName().c_str(), node.displayName().c_str()) < 0;
|
|
||||||
|
return _realNode->isReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilesystemNode::isWritable() const {
|
||||||
|
if (_realNode == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _realNode->isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilesystemNode::lookupFile(FSList &results, FSList &fslist, Common::String &filename, bool hidden, bool exhaustive) const
|
||||||
|
{
|
||||||
|
int matches = 0;
|
||||||
|
|
||||||
|
for (FSList::iterator entry = fslist.begin(); entry != fslist.end(); ++entry) {
|
||||||
|
if (entry->isDirectory()) {
|
||||||
|
matches += lookupFileRec(results, *entry, filename, hidden, exhaustive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((matches > 0) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilesystemNode::lookupFile(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const
|
||||||
|
{
|
||||||
|
int matches;
|
||||||
|
|
||||||
|
if (!dir.isDirectory())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
matches = lookupFileRec(results, dir, filename, hidden, exhaustive);
|
||||||
|
|
||||||
|
return ((matches > 0) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilesystemNode::lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const
|
||||||
|
{
|
||||||
|
FSList entries;
|
||||||
|
FSList children;
|
||||||
|
int matches = 0;
|
||||||
|
dir.getChildren(entries, FilesystemNode::kListAll, hidden);
|
||||||
|
|
||||||
|
//Breadth search (entries in the same level)
|
||||||
|
for (FSList::iterator entry = entries.begin(); entry != entries.end(); ++entry) {
|
||||||
|
if (entry->isDirectory()) {
|
||||||
|
children.push_back(*entry);
|
||||||
|
} else {
|
||||||
|
//TODO: here we assume all backends implement the lastPathComponent method. It is currently static,
|
||||||
|
// so it might be a good idea to include it inside the backend class. This would enforce its
|
||||||
|
// implementation by all ports.
|
||||||
|
if (matchString(lastPathComponent(entry->getPath()), filename.c_str())) {
|
||||||
|
results.push_back(*entry);
|
||||||
|
matches++;
|
||||||
|
|
||||||
|
if (!exhaustive)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Depth search (entries in lower levels)
|
||||||
|
for (FSList::iterator child = children.begin(); child != children.end(); ++child) {
|
||||||
|
matches += lookupFileRec(results, *child, filename, hidden, exhaustive);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches;
|
||||||
}
|
}
|
||||||
|
159
common/fs.h
159
common/fs.h
@ -33,7 +33,6 @@
|
|||||||
class FilesystemNode;
|
class FilesystemNode;
|
||||||
class AbstractFilesystemNode;
|
class AbstractFilesystemNode;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of multiple file system nodes. E.g. the contents of a given directory.
|
* List of multiple file system nodes. E.g. the contents of a given directory.
|
||||||
* This is subclass instead of just a typedef so that we can use forward
|
* This is subclass instead of just a typedef so that we can use forward
|
||||||
@ -41,9 +40,8 @@ class AbstractFilesystemNode;
|
|||||||
*/
|
*/
|
||||||
class FSList : public Common::Array<FilesystemNode> {};
|
class FSList : public Common::Array<FilesystemNode> {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FilesystemNode provides an abstraction for file pathes, allowing for portable
|
* FilesystemNode provides an abstraction for file paths, allowing for portable
|
||||||
* file system browsing. To this ends, multiple or single roots have to be supported
|
* file system browsing. To this ends, multiple or single roots have to be supported
|
||||||
* (compare Unix with a single root, Windows with multiple roots C:, D:, ...).
|
* (compare Unix with a single root, Windows with multiple roots C:, D:, ...).
|
||||||
*
|
*
|
||||||
@ -64,12 +62,13 @@ class FSList : public Common::Array<FilesystemNode> {};
|
|||||||
* paths (MacOS 9 doesn't even have the notion of a "current directory").
|
* paths (MacOS 9 doesn't even have the notion of a "current directory").
|
||||||
* And if we ever want to support devices with no FS in the classical sense (Palm...),
|
* And if we ever want to support devices with no FS in the classical sense (Palm...),
|
||||||
* we can build upon this.
|
* we can build upon this.
|
||||||
|
*
|
||||||
|
* This class acts as a wrapper around the AbstractFilesystemNode class defined in backends/fs.
|
||||||
*/
|
*/
|
||||||
class FilesystemNode {
|
class FilesystemNode {
|
||||||
private:
|
private:
|
||||||
AbstractFilesystemNode *_realNode;
|
|
||||||
int *_refCount;
|
int *_refCount;
|
||||||
|
AbstractFilesystemNode *_realNode;
|
||||||
FilesystemNode(AbstractFilesystemNode *realNode);
|
FilesystemNode(AbstractFilesystemNode *realNode);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -83,9 +82,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new invalid FilesystemNode. In other words, isValid() for that
|
* Create a new pathless FilesystemNode. Since there's no path associated
|
||||||
* node returns false, and if you try to get it's path, an assert is
|
* with this node, path-related operations (i.e. exists(), isDirectory(),
|
||||||
* triggered.
|
* getPath()) will always return false or raise an assertion.
|
||||||
*/
|
*/
|
||||||
FilesystemNode();
|
FilesystemNode();
|
||||||
|
|
||||||
@ -113,51 +112,44 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Copy operator.
|
* Copy operator.
|
||||||
*/
|
*/
|
||||||
FilesystemNode &operator =(const FilesystemNode &node);
|
FilesystemNode &operator= (const FilesystemNode &node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the name of this node to the name of another. Directories
|
||||||
|
* go before normal files.
|
||||||
|
*/
|
||||||
|
bool operator<(const FilesystemNode& node) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the FilesystemNode is valid for any usage
|
* Indicates whether the object referred by this path exists in the filesystem or not.
|
||||||
|
*
|
||||||
|
* @return bool true if the path exists, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool isValid() const;
|
virtual bool exists() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the parent node of this node. If this node has no parent node,
|
|
||||||
* then it returns a duplicate of this node.
|
|
||||||
*/
|
|
||||||
FilesystemNode getParent() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a child node of this node, with the given name. Only valid for
|
* Fetch a child node of this node, with the given name. Only valid for
|
||||||
* directory nodes (an assertion is triggered otherwise). If no no child
|
* directory nodes (an assertion is triggered otherwise).
|
||||||
* node with the given name exists, an invalid node is returned.
|
* If no child node with the given name exists, an invalid node is returned.
|
||||||
*/
|
*/
|
||||||
FilesystemNode getChild(const Common::String &name) const;
|
FilesystemNode getChild(const Common::String &name) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of child nodes of this directory node. If called on a node
|
* Return a list of child nodes of this directory node. If called on a node
|
||||||
* that does not represent a directory, false is returned.
|
* that does not represent a directory, false is returned.
|
||||||
|
*
|
||||||
* @return true if succesful, false otherwise (e.g. when the directory does not exist).
|
* @return true if succesful, false otherwise (e.g. when the directory does not exist).
|
||||||
* @todo Rename this to listChildren or getChildren.
|
|
||||||
*/
|
*/
|
||||||
virtual bool listDir(FSList &fslist, ListMode mode = kListDirectoriesOnly) const;
|
virtual bool getChildren(FSList &fslist, ListMode mode = kListDirectoriesOnly, bool hidden = false) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this node pointing to a directory?
|
|
||||||
* @todo Currently we assume that a valid node that is not a directory
|
|
||||||
* automatically is a file (ignoring things like symlinks). That might
|
|
||||||
* actually be OK... but we could still add an isFile method. Or even replace
|
|
||||||
* isValid and isDirectory by a getType() method that can return values like
|
|
||||||
* kDirNodeType, kFileNodeType, kInvalidNodeType.
|
|
||||||
*/
|
|
||||||
virtual bool isDirectory() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a human readable string for this node, usable for display (e.g.
|
* Return a human readable string for this node, usable for display (e.g.
|
||||||
* in the GUI code). Do *not* rely on it being usable for anything else,
|
* in the GUI code). Do *not* rely on it being usable for anything else,
|
||||||
* like constructing paths!
|
* like constructing paths!
|
||||||
|
*
|
||||||
* @return the display name
|
* @return the display name
|
||||||
*/
|
*/
|
||||||
virtual Common::String displayName() const;
|
virtual Common::String getDisplayName() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a string representation of the name of the file. This is can be
|
* Return a string representation of the name of the file. This is can be
|
||||||
@ -167,7 +159,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return the file name
|
* @return the file name
|
||||||
*/
|
*/
|
||||||
virtual Common::String name() const;
|
virtual Common::String getName() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a string representation of the file which can be passed to fopen(),
|
* Return a string representation of the file which can be passed to fopen(),
|
||||||
@ -180,18 +172,107 @@ public:
|
|||||||
*
|
*
|
||||||
* @return the 'path' represented by this filesystem node
|
* @return the 'path' represented by this filesystem node
|
||||||
*/
|
*/
|
||||||
virtual Common::String path() const;
|
virtual Common::String getPath() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parent node of this node. If this node has no parent node,
|
||||||
|
* then it returns a duplicate of this node.
|
||||||
|
*/
|
||||||
|
FilesystemNode getParent() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare the name of this node to the name of another. Directories
|
* Indicates whether the path refers to a directory or not.
|
||||||
* go before normal files.
|
*
|
||||||
|
* @todo Currently we assume that a node that is not a directory
|
||||||
|
* automatically is a file (ignoring things like symlinks or pipes).
|
||||||
|
* That might actually be OK... but we could still add an isFile method.
|
||||||
|
* Or even replace isDirectory by a getType() method that can return values like
|
||||||
|
* kDirNodeType, kFileNodeType, kInvalidNodeType.
|
||||||
*/
|
*/
|
||||||
bool operator< (const FilesystemNode& node) const;
|
virtual bool isDirectory() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the object referred by this path can be read from or not.
|
||||||
|
*
|
||||||
|
* If the path refers to a directory, readability implies being able to read
|
||||||
|
* and list the directory entries.
|
||||||
|
*
|
||||||
|
* If the path refers to a file, readability implies being able to read the
|
||||||
|
* contents of the file.
|
||||||
|
*
|
||||||
|
* @return bool true if the object can be read, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool isReadable() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the object referred by this path can be written to or not.
|
||||||
|
*
|
||||||
|
* If the path refers to a directory, writability implies being able to modify
|
||||||
|
* the directory entry (i.e. rename the directory, remove it or write files inside of it).
|
||||||
|
*
|
||||||
|
* If the path refers to a file, writability implies being able to write data
|
||||||
|
* to the file.
|
||||||
|
*
|
||||||
|
* @return bool true if the object can be written to, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool isWritable() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches recursively for a filename inside the given directories.
|
||||||
|
*
|
||||||
|
* For each directory in the directory list a breadth-first search is performed,
|
||||||
|
* that is, the current directory entries are scanned before going into subdirectories.
|
||||||
|
*
|
||||||
|
* @param results List to put the matches in.
|
||||||
|
* @param fslist List of directories to search within.
|
||||||
|
* @param filename Name of the file to look for.
|
||||||
|
* @param hidden Whether to search hidden files or not.
|
||||||
|
* @param exhaustive Whether to continue searching after one match has been found.
|
||||||
|
*
|
||||||
|
* @return true if matches could be found, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool lookupFile(FSList &results, FSList &fslist, Common::String &filename, bool hidden, bool exhaustive) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches recursively for a filename inside the given directory.
|
||||||
|
*
|
||||||
|
* The search is performed breadth-first, that is, the current directory entries
|
||||||
|
* are scanned before going into subdirectories.
|
||||||
|
*
|
||||||
|
* @param results List to put the matches in.
|
||||||
|
* @param FilesystemNode Directory to search within.
|
||||||
|
* @param filename Name of the file to look for.
|
||||||
|
* @param hidden Whether to search hidden files or not.
|
||||||
|
* @param exhaustive Whether to continue searching after one match has been found.
|
||||||
|
*
|
||||||
|
* @return true if matches could be found, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool lookupFile(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Decreases the reference count to the FilesystemNode, and if necessary,
|
||||||
|
* deletes the corresponding underlying references.
|
||||||
|
*/
|
||||||
void decRefCount();
|
void decRefCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches recursively for a filename inside the given directory.
|
||||||
|
*
|
||||||
|
* The search is performed breadth-first, that is, the current directory entries
|
||||||
|
* are scanned before going into subdirectories.
|
||||||
|
*
|
||||||
|
* @param results List to put the matches in.
|
||||||
|
* @param FilesystemNode Directory to search within.
|
||||||
|
* @param filename Name of the file to look for.
|
||||||
|
* @param hidden Whether to search hidden files or not.
|
||||||
|
* @param exhaustive Whether to continue searching after one match has been found.
|
||||||
|
*
|
||||||
|
* @return The number of matches found.
|
||||||
|
*/
|
||||||
|
int lookupFileRec(FSList &results, FilesystemNode &dir, Common::String &filename, bool hidden, bool exhaustive) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//} // End of namespace Common
|
//} // End of namespace Common
|
||||||
|
|
||||||
#endif
|
#endif //COMMON_FS_H
|
||||||
|
@ -246,15 +246,18 @@ void md5_finish(md5_context *ctx, uint8 digest[16]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool md5_file(const FilesystemNode &file, uint8 digest[16], uint32 length) {
|
bool md5_file(const FilesystemNode &file, uint8 digest[16], uint32 length) {
|
||||||
if (!file.isValid()) {
|
if(!file.exists()) {
|
||||||
warning("md5_file: using an invalid FilesystemNode");
|
warning("md5_file: using an inexistent FilesystemNode");
|
||||||
|
return false;
|
||||||
|
} else if (!file.isReadable()) {
|
||||||
|
warning("md5_file: using an unreadable FilesystemNode");
|
||||||
return false;
|
return false;
|
||||||
} else if (file.isDirectory()) {
|
} else if (file.isDirectory()) {
|
||||||
warning("md5_file: using a diretory FilesystemNode");
|
warning("md5_file: using a directory FilesystemNode");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return md5_file(file.path().c_str(), digest, length);
|
return md5_file(file.getPath().c_str(), digest, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool md5_file(const char *name, uint8 digest[16], uint32 length) {
|
bool md5_file(const char *name, uint8 digest[16], uint32 length) {
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "common/noncopyable.h"
|
#include "common/noncopyable.h"
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
#include "common/stream.h"
|
#include "common/stream.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "common/error.h"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
@ -75,10 +77,40 @@ public:
|
|||||||
* returning the single SaveFileManager instances to be used.
|
* returning the single SaveFileManager instances to be used.
|
||||||
*/
|
*/
|
||||||
class SaveFileManager : NonCopyable {
|
class SaveFileManager : NonCopyable {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SFMError _error;
|
||||||
|
String _errorDesc;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~SaveFileManager() {}
|
virtual ~SaveFileManager() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the last set error code and string.
|
||||||
|
*/
|
||||||
|
virtual void clearError() { _error = SFM_NO_ERROR; _errorDesc = ""; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last ocurred error code. If none ocurred, returns SFM_NO_ERROR.
|
||||||
|
*
|
||||||
|
* @return A SFMError indicating the type of the last error.
|
||||||
|
*/
|
||||||
|
virtual SFMError getError() { return _error; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last ocurred error description. If none ocurred, returns 0.
|
||||||
|
*
|
||||||
|
* @return A string describing the last error.
|
||||||
|
*/
|
||||||
|
virtual String getErrorDesc() { return _errorDesc; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the last ocurred error.
|
||||||
|
* @param error Code identifying the last error.
|
||||||
|
* @param errorDesc String describing the last error.
|
||||||
|
*/
|
||||||
|
virtual void setError(SFMError error, String errorDesc) { _error = error; _errorDesc = errorDesc; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the file with name filename in the given directory for saving.
|
* Open the file with name filename in the given directory for saving.
|
||||||
* @param filename the filename
|
* @param filename the filename
|
||||||
@ -94,12 +126,18 @@ public:
|
|||||||
virtual InSaveFile *openForLoading(const char *filename) = 0;
|
virtual InSaveFile *openForLoading(const char *filename) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request a list of available savegames with a given prefix.
|
* Removes the given savefile from the filesystem.
|
||||||
* TODO: Document this better!
|
* @param filename Filename path pointing to the savefile.
|
||||||
* TODO: Or even replace it with a better API. For example, one that
|
* @return true if no error ocurred. false otherwise.
|
||||||
* returns a list of strings for all present file names.
|
|
||||||
*/
|
*/
|
||||||
virtual void listSavefiles(const char * /* prefix */, bool *marks, int num) = 0;
|
virtual bool removeSavefile(const char *filename) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a list of available savegames with a given regex.
|
||||||
|
* @param regex Regular expression to match. Wildcards like * or ? are available.
|
||||||
|
* returns a list of strings for all present file names.
|
||||||
|
*/
|
||||||
|
virtual Common::StringList listSavefiles(const char *regex) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path to the save game directory.
|
* Get the path to the save game directory.
|
||||||
|
@ -1930,7 +1930,7 @@ Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
|||||||
path = ".";
|
path = ".";
|
||||||
|
|
||||||
FilesystemNode fsCurrentDir(path);
|
FilesystemNode fsCurrentDir(path);
|
||||||
fsCurrentDir.listDir(fslistCurrentDir, FilesystemNode::kListFilesOnly);
|
fsCurrentDir.getChildren(fslistCurrentDir, FilesystemNode::kListFilesOnly);
|
||||||
fslist = &fslistCurrentDir;
|
fslist = &fslistCurrentDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1947,13 +1947,13 @@ Common::EncapsulatedADGameDesc fallbackDetector(const FSList *fslist) {
|
|||||||
// First grab all filenames and at the same time count the number of *.wag files
|
// First grab all filenames and at the same time count the number of *.wag files
|
||||||
for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) {
|
for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) {
|
||||||
if (file->isDirectory()) continue;
|
if (file->isDirectory()) continue;
|
||||||
Common::String filename = file->name();
|
Common::String filename = file->getName();
|
||||||
filename.toLowercase();
|
filename.toLowercase();
|
||||||
allFiles[filename] = true; // Save the filename in a hash table
|
allFiles[filename] = true; // Save the filename in a hash table
|
||||||
|
|
||||||
if (filename.hasSuffix(".wag")) {
|
if (filename.hasSuffix(".wag")) {
|
||||||
// Save latest found *.wag file's path (Can be used to open the file, the name can't)
|
// Save latest found *.wag file's path (Can be used to open the file, the name can't)
|
||||||
wagFilePath = file->path();
|
wagFilePath = file->getPath();
|
||||||
wagFileCount++; // Count found *.wag files
|
wagFileCount++; // Count found *.wag files
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,14 +52,14 @@ int AgiLoader_v3::detectGame() {
|
|||||||
FSList fslist;
|
FSList fslist;
|
||||||
FilesystemNode dir(ConfMan.get("path"));
|
FilesystemNode dir(ConfMan.get("path"));
|
||||||
|
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(fslist, FilesystemNode::kListFilesOnly)) {
|
||||||
warning("AgiEngine: invalid game path '%s'", dir.path().c_str());
|
warning("AgiEngine: invalid game path '%s'", dir.getPath().c_str());
|
||||||
return errInvalidAGIFile;
|
return errInvalidAGIFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (FSList::const_iterator file = fslist.begin();
|
for (FSList::const_iterator file = fslist.begin();
|
||||||
file != fslist.end() && !found; ++file) {
|
file != fslist.end() && !found; ++file) {
|
||||||
Common::String f = file->name();
|
Common::String f = file->getName();
|
||||||
f.toLowercase();
|
f.toLowercase();
|
||||||
|
|
||||||
if (f.hasSuffix("vol.0")) {
|
if (f.hasSuffix("vol.0")) {
|
||||||
|
@ -989,7 +989,7 @@ struct fsnodeNameEqualsIgnoreCase : public Common::UnaryFunction<const Filesyste
|
|||||||
fsnodeNameEqualsIgnoreCase(const Common::String str) { _str.push_back(str); }
|
fsnodeNameEqualsIgnoreCase(const Common::String str) { _str.push_back(str); }
|
||||||
bool operator()(const FilesystemNode ¶m) const {
|
bool operator()(const FilesystemNode ¶m) const {
|
||||||
for (Common::StringList::const_iterator iter = _str.begin(); iter != _str.end(); iter++)
|
for (Common::StringList::const_iterator iter = _str.begin(); iter != _str.end(); iter++)
|
||||||
if (param.name().equalsIgnoreCase(*iter))
|
if (param.getName().equalsIgnoreCase(*iter))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1014,8 +1014,8 @@ bool SoundMgr::loadInstruments() {
|
|||||||
// List files in the game path
|
// List files in the game path
|
||||||
FSList fslist;
|
FSList fslist;
|
||||||
FilesystemNode dir(ConfMan.get("path"));
|
FilesystemNode dir(ConfMan.get("path"));
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(fslist, FilesystemNode::kListFilesOnly)) {
|
||||||
warning("Invalid game path (\"%s\"), not loading Apple IIGS instruments", dir.path().c_str());
|
warning("Invalid game path (\"%s\"), not loading Apple IIGS instruments", dir.getPath().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,12 +1050,12 @@ bool SoundMgr::loadInstruments() {
|
|||||||
// Finally fix the instruments' lengths using the wave file data
|
// Finally fix the instruments' lengths using the wave file data
|
||||||
// (A zero in the wave file data can end the sample prematurely)
|
// (A zero in the wave file data can end the sample prematurely)
|
||||||
// and convert the wave file from 8-bit unsigned to 16-bit signed format.
|
// and convert the wave file from 8-bit unsigned to 16-bit signed format.
|
||||||
Common::MemoryReadStream *uint8Wave = loadWaveFile(waveFsnode->path(), *exeInfo);
|
Common::MemoryReadStream *uint8Wave = loadWaveFile(waveFsnode->getPath(), *exeInfo);
|
||||||
// Seek the wave to its
|
// Seek the wave to its
|
||||||
if (uint8Wave != NULL)
|
if (uint8Wave != NULL)
|
||||||
uint8Wave->seek(0);
|
uint8Wave->seek(0);
|
||||||
|
|
||||||
bool result = uint8Wave != NULL && loadInstrumentHeaders(exeFsnode->path(), *exeInfo) &&
|
bool result = uint8Wave != NULL && loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo) &&
|
||||||
finalizeInstruments(*uint8Wave) && convertWave(*uint8Wave, g_wave, uint8Wave->size());
|
finalizeInstruments(*uint8Wave) && convertWave(*uint8Wave, g_wave, uint8Wave->size());
|
||||||
|
|
||||||
delete uint8Wave; // Free the 8-bit unsigned wave file buffer
|
delete uint8Wave; // Free the 8-bit unsigned wave file buffer
|
||||||
|
@ -38,13 +38,29 @@ namespace AGOS {
|
|||||||
|
|
||||||
int AGOSEngine::countSaveGames() {
|
int AGOSEngine::countSaveGames() {
|
||||||
Common::InSaveFile *f;
|
Common::InSaveFile *f;
|
||||||
|
Common::StringList filenames;
|
||||||
uint i = 1;
|
uint i = 1;
|
||||||
|
char slot[3];
|
||||||
|
int slotNum;
|
||||||
bool marks[256];
|
bool marks[256];
|
||||||
|
|
||||||
char *prefix = genSaveName(998);
|
char *prefix = genSaveName(998);
|
||||||
prefix[strlen(prefix)-3] = '\0';
|
prefix[strlen(prefix)-3] = '*';
|
||||||
_saveFileMan->listSavefiles(prefix, marks, 256);
|
prefix[strlen(prefix)-2] = '\0';
|
||||||
|
memset(marks, false, 256 * sizeof(bool)); //assume no savegames for this title
|
||||||
|
filenames = _saveFileMan->listSavefiles(prefix);
|
||||||
|
|
||||||
|
for(Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++){
|
||||||
|
//Obtain the last 3 digits of the filename, since they correspond to the save slot
|
||||||
|
slot[0] = file->c_str()[file->size()-3];
|
||||||
|
slot[1] = file->c_str()[file->size()-2];
|
||||||
|
slot[2] = file->c_str()[file->size()-1];
|
||||||
|
|
||||||
|
slotNum = atoi(slot);
|
||||||
|
if(slotNum >= 0 && slotNum < 256)
|
||||||
|
marks[slotNum] = true; //mark this slot as valid
|
||||||
|
}
|
||||||
|
|
||||||
while (i < 256) {
|
while (i < 256) {
|
||||||
if (marks[i] &&
|
if (marks[i] &&
|
||||||
(f = _saveFileMan->openForLoading(genSaveName(i)))) {
|
(f = _saveFileMan->openForLoading(genSaveName(i)))) {
|
||||||
@ -53,6 +69,7 @@ int AGOSEngine::countSaveGames() {
|
|||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +82,8 @@ Resource::Resource(KyraEngine *vm) {
|
|||||||
FSList fslist;
|
FSList fslist;
|
||||||
FilesystemNode dir(ConfMan.get("path"));
|
FilesystemNode dir(ConfMan.get("path"));
|
||||||
|
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly))
|
if (!dir.getChildren(fslist, FilesystemNode::kListFilesOnly))
|
||||||
error("invalid game path '%s'", dir.path().c_str());
|
error("invalid game path '%s'", dir.getPath().c_str());
|
||||||
|
|
||||||
if (_vm->game() == GI_KYRA1 && _vm->gameFlags().isTalkie) {
|
if (_vm->game() == GI_KYRA1 && _vm->gameFlags().isTalkie) {
|
||||||
static const char *list[] = {
|
static const char *list[] = {
|
||||||
@ -96,7 +96,7 @@ Resource::Resource(KyraEngine *vm) {
|
|||||||
Common::for_each(_pakfiles.begin(), _pakfiles.end(), Common::bind2nd(Common::mem_fun(&ResourceFile::protect), true));
|
Common::for_each(_pakfiles.begin(), _pakfiles.end(), Common::bind2nd(Common::mem_fun(&ResourceFile::protect), true));
|
||||||
} else {
|
} else {
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
Common::String filename = file->name();
|
Common::String filename = file->getName();
|
||||||
filename.toUppercase();
|
filename.toUppercase();
|
||||||
|
|
||||||
// No real PAK file!
|
// No real PAK file!
|
||||||
@ -104,8 +104,8 @@ Resource::Resource(KyraEngine *vm) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (filename.hasSuffix("PAK") || filename.hasSuffix("APK")) {
|
if (filename.hasSuffix("PAK") || filename.hasSuffix("APK")) {
|
||||||
if (!loadPakFile(file->name()))
|
if (!loadPakFile(file->getName()))
|
||||||
error("couldn't open pakfile '%s'", file->name().c_str());
|
error("couldn't open pakfile '%s'", file->getName().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ GameList Engine_LURE_detectGames(const FSList &fslist) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (g = lure_games; g->gameid; g++) {
|
for (g = lure_games; g->gameid; g++) {
|
||||||
if (scumm_stricmp(file->name().c_str(), g->checkFile) == 0)
|
if (scumm_stricmp(file->getName().c_str(), g->checkFile) == 0)
|
||||||
isFound = true;
|
isFound = true;
|
||||||
}
|
}
|
||||||
if (isFound)
|
if (isFound)
|
||||||
|
@ -73,7 +73,7 @@ GameList Engine_QUEEN_detectGames(const FSList &fslist) {
|
|||||||
if (file->isDirectory()) {
|
if (file->isDirectory()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (file->name().equalsIgnoreCase("queen.1") || file->name().equalsIgnoreCase("queen.1c")) {
|
if (file->getName().equalsIgnoreCase("queen.1") || file->getName().equalsIgnoreCase("queen.1c")) {
|
||||||
Common::File dataFile;
|
Common::File dataFile;
|
||||||
if (!dataFile.open(*file)) {
|
if (!dataFile.open(*file)) {
|
||||||
continue;
|
continue;
|
||||||
@ -317,11 +317,28 @@ void QueenEngine::makeGameStateName(uint16 slot, char *buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QueenEngine::findGameStateDescriptions(char descriptions[100][32]) {
|
void QueenEngine::findGameStateDescriptions(char descriptions[100][32]) {
|
||||||
char filename[20];
|
char prefix[20];
|
||||||
makeGameStateName(0, filename);
|
makeGameStateName(0, prefix);
|
||||||
filename[strlen(filename) - 2] = 0;
|
prefix[strlen(prefix) - 2] = '*';
|
||||||
|
prefix[strlen(prefix) - 1] = 0;
|
||||||
bool marks[SAVESTATE_MAX_NUM];
|
bool marks[SAVESTATE_MAX_NUM];
|
||||||
_saveFileMan->listSavefiles(filename, marks, SAVESTATE_MAX_NUM);
|
char slot[2];
|
||||||
|
int slotNum;
|
||||||
|
Common::StringList filenames;
|
||||||
|
|
||||||
|
memset(marks, false, SAVESTATE_MAX_NUM * sizeof(bool)); //assume no savegames for this title
|
||||||
|
filenames = _saveFileMan->listSavefiles(prefix);
|
||||||
|
|
||||||
|
for(Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++){
|
||||||
|
//Obtain the last 2 digits of the filename, since they correspond to the save slot
|
||||||
|
slot[0] = file->c_str()[file->size()-2];
|
||||||
|
slot[1] = file->c_str()[file->size()-1];
|
||||||
|
|
||||||
|
slotNum = atoi(slot);
|
||||||
|
if(slotNum >= 0 && slotNum < SAVESTATE_MAX_NUM)
|
||||||
|
marks[slotNum] = true; //mark this slot as valid
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < SAVESTATE_MAX_NUM; ++i) {
|
for (int i = 0; i < SAVESTATE_MAX_NUM; ++i) {
|
||||||
if (marks[i]) {
|
if (marks[i]) {
|
||||||
GameStateHeader header;
|
GameStateHeader header;
|
||||||
|
@ -112,14 +112,32 @@ uint SagaEngine::getNewSaveSlotNumber() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SagaEngine::fillSaveList() {
|
void SagaEngine::fillSaveList() {
|
||||||
|
assert(_saveMarks);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
Common::InSaveFile *in;
|
Common::InSaveFile *in;
|
||||||
|
Common::StringList filenames;
|
||||||
|
char slot[2];
|
||||||
|
int slotNum;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = calcSaveFileName(MAX_SAVES);
|
name = calcSaveFileName(MAX_SAVES);
|
||||||
name[strlen(name) - 2] = 0;
|
name[strlen(name) - 2] = '*';
|
||||||
_saveFileMan->listSavefiles(name, _saveMarks, MAX_SAVES);
|
name[strlen(name) - 1] = 0;
|
||||||
|
|
||||||
|
memset(_saveMarks, false, MAX_SAVES * sizeof(bool)); //assume no savegames for this title
|
||||||
|
filenames = _saveFileMan->listSavefiles(name);
|
||||||
|
|
||||||
|
for(Common::StringList::iterator file = filenames.begin(); file != filenames.end(); file++){
|
||||||
|
//Obtain the last 2 digits of the filename, since they correspond to the save slot
|
||||||
|
slot[0] = file->c_str()[file->size()-2];
|
||||||
|
slot[1] = file->c_str()[file->size()-1];
|
||||||
|
|
||||||
|
slotNum = atoi(slot);
|
||||||
|
if(slotNum >= 0 && slotNum < MAX_SAVES)
|
||||||
|
_saveMarks[slotNum] = true; //mark this slot as valid
|
||||||
|
}
|
||||||
|
|
||||||
_saveFilesMaxCount = 0;
|
_saveFilesMaxCount = 0;
|
||||||
for (i = 0; i < MAX_SAVES; i++) {
|
for (i = 0; i < MAX_SAVES; i++) {
|
||||||
if (_saveMarks[i]) {
|
if (_saveMarks[i]) {
|
||||||
|
@ -190,7 +190,7 @@ static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Com
|
|||||||
// the first match is used.
|
// the first match is used.
|
||||||
static bool searchFSNode(const FSList &fslist, const Common::String &name, FilesystemNode &result) {
|
static bool searchFSNode(const FSList &fslist, const Common::String &name, FilesystemNode &result) {
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (!scumm_stricmp(file->name().c_str(), name.c_str())) {
|
if (!scumm_stricmp(file->getName().c_str(), name.c_str())) {
|
||||||
result = *file;
|
result = *file;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ static Common::Language detectLanguage(const FSList &fslist, byte id) {
|
|||||||
FSList tmpList;
|
FSList tmpList;
|
||||||
if (searchFSNode(fslist, "RESOURCE", resDir)
|
if (searchFSNode(fslist, "RESOURCE", resDir)
|
||||||
&& resDir.isDirectory()
|
&& resDir.isDirectory()
|
||||||
&& resDir.listDir(tmpList, FilesystemNode::kListFilesOnly)
|
&& resDir.getChildren(tmpList, FilesystemNode::kListFilesOnly)
|
||||||
&& searchFSNode(tmpList, filename, langFile)) {
|
&& searchFSNode(tmpList, filename, langFile)) {
|
||||||
tmp.open(langFile);
|
tmp.open(langFile);
|
||||||
}
|
}
|
||||||
@ -320,7 +320,7 @@ static void detectGames(const FSList &fslist, Common::List<DetectorResult> &resu
|
|||||||
DetectorDesc d;
|
DetectorDesc d;
|
||||||
d.node = *file;
|
d.node = *file;
|
||||||
d.md5Entry = 0;
|
d.md5Entry = 0;
|
||||||
fileMD5Map[file->name()] = d;
|
fileMD5Map[file->getName()] = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +447,7 @@ static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Com
|
|||||||
|
|
||||||
Common::File tmp;
|
Common::File tmp;
|
||||||
if (!tmp.open(d.node)) {
|
if (!tmp.open(d.node)) {
|
||||||
warning("SCUMM detectGames: failed to open '%s' for read access", d.node.path().c_str());
|
warning("SCUMM detectGames: failed to open '%s' for read access", d.node.getPath().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +751,7 @@ PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) {
|
|||||||
// Fetch the list of files in the current directory
|
// Fetch the list of files in the current directory
|
||||||
FSList fslist;
|
FSList fslist;
|
||||||
FilesystemNode dir(ConfMan.get("path"));
|
FilesystemNode dir(ConfMan.get("path"));
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) {
|
if (!dir.getChildren(fslist, FilesystemNode::kListFilesOnly)) {
|
||||||
return kInvalidPathError;
|
return kInvalidPathError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,10 +421,10 @@ void SaveLoadChooser::updateInfos() {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
|
Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
|
||||||
// Get savegame names
|
// Get savegame descriptions
|
||||||
Common::StringList l;
|
Common::StringList descriptions;
|
||||||
char name[32];
|
char name[32];
|
||||||
uint i = saveMode ? 1 : 0;
|
uint i = saveMode ? 1 : 0; //the autosave is on slot #0
|
||||||
bool avail_saves[81];
|
bool avail_saves[81];
|
||||||
|
|
||||||
scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves));
|
scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves));
|
||||||
@ -433,10 +433,10 @@ Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) {
|
|||||||
scumm->getSavegameName(i, name);
|
scumm->getSavegameName(i, name);
|
||||||
else
|
else
|
||||||
name[0] = 0;
|
name[0] = 0;
|
||||||
l.push_back(name);
|
descriptions.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return descriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
|
MainMenuDialog::MainMenuDialog(ScummEngine *scumm)
|
||||||
|
@ -384,10 +384,28 @@ void ScummEngine::makeSavegameName(char *out, int slot, bool temporary) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ScummEngine::listSavegames(bool *marks, int num) {
|
void ScummEngine::listSavegames(bool *marks, int num) {
|
||||||
|
assert(marks);
|
||||||
|
|
||||||
char prefix[256];
|
char prefix[256];
|
||||||
|
char slot[2];
|
||||||
|
int slotNum;
|
||||||
|
Common::StringList filenames;
|
||||||
|
|
||||||
makeSavegameName(prefix, 99, false);
|
makeSavegameName(prefix, 99, false);
|
||||||
prefix[strlen(prefix)-2] = 0;
|
prefix[strlen(prefix)-2] = '*';
|
||||||
_saveFileMan->listSavefiles(prefix, marks, num);
|
prefix[strlen(prefix)-1] = 0;
|
||||||
|
memset(marks, false, num * sizeof(bool)); //assume no savegames for this title
|
||||||
|
filenames = _saveFileMan->listSavefiles(prefix);
|
||||||
|
|
||||||
|
for(Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++){
|
||||||
|
//Obtain the last 2 digits of the filename, since they correspond to the save slot
|
||||||
|
slot[0] = file->c_str()[file->size()-2];
|
||||||
|
slot[1] = file->c_str()[file->size()-1];
|
||||||
|
|
||||||
|
slotNum = atoi(slot);
|
||||||
|
if(slotNum >= 0 && slotNum < num)
|
||||||
|
marks[slotNum] = true; //mark this slot as valid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScummEngine::getSavegameName(int slot, char *desc) {
|
bool ScummEngine::getSavegameName(int slot, char *desc) {
|
||||||
|
@ -124,11 +124,11 @@ GameList Engine_SKY_detectGames(const FSList &fslist) {
|
|||||||
// Iterate over all files in the given directory
|
// Iterate over all files in the given directory
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (!file->isDirectory()) {
|
if (!file->isDirectory()) {
|
||||||
const char *fileName = file->name().c_str();
|
const char *fileName = file->getName().c_str();
|
||||||
|
|
||||||
if (0 == scumm_stricmp("sky.dsk", fileName)) {
|
if (0 == scumm_stricmp("sky.dsk", fileName)) {
|
||||||
Common::File dataDisk;
|
Common::File dataDisk;
|
||||||
if (dataDisk.open(file->path())) {
|
if (dataDisk.open(file->getPath())) {
|
||||||
hasSkyDsk = true;
|
hasSkyDsk = true;
|
||||||
dataDiskSize = dataDisk.size();
|
dataDiskSize = dataDisk.size();
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ GameList Engine_SKY_detectGames(const FSList &fslist) {
|
|||||||
|
|
||||||
if (0 == scumm_stricmp("sky.dnr", fileName)) {
|
if (0 == scumm_stricmp("sky.dnr", fileName)) {
|
||||||
Common::File dinner;
|
Common::File dinner;
|
||||||
if (dinner.open(file->path())) {
|
if (dinner.open(file->getPath())) {
|
||||||
hasSkyDnr = true;
|
hasSkyDnr = true;
|
||||||
dinnerTableEntries = dinner.readUint32LE();
|
dinnerTableEntries = dinner.readUint32LE();
|
||||||
}
|
}
|
||||||
|
@ -107,15 +107,15 @@ GameDescriptor Engine_SWORD1_findGameID(const char *gameid) {
|
|||||||
void Sword1CheckDirectory(const FSList &fslist, bool *filesFound) {
|
void Sword1CheckDirectory(const FSList &fslist, bool *filesFound) {
|
||||||
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (!file->isDirectory()) {
|
if (!file->isDirectory()) {
|
||||||
const char *fileName = file->name().c_str();
|
const char *fileName = file->getName().c_str();
|
||||||
for (int cnt = 0; cnt < NUM_FILES_TO_CHECK; cnt++)
|
for (int cnt = 0; cnt < NUM_FILES_TO_CHECK; cnt++)
|
||||||
if (scumm_stricmp(fileName, g_filesToCheck[cnt]) == 0)
|
if (scumm_stricmp(fileName, g_filesToCheck[cnt]) == 0)
|
||||||
filesFound[cnt] = true;
|
filesFound[cnt] = true;
|
||||||
} else {
|
} else {
|
||||||
for (int cnt = 0; cnt < ARRAYSIZE(g_dirNames); cnt++)
|
for (int cnt = 0; cnt < ARRAYSIZE(g_dirNames); cnt++)
|
||||||
if (scumm_stricmp(file->name().c_str(), g_dirNames[cnt]) == 0) {
|
if (scumm_stricmp(file->getName().c_str(), g_dirNames[cnt]) == 0) {
|
||||||
FSList fslist2;
|
FSList fslist2;
|
||||||
if (file->listDir(fslist2, FilesystemNode::kListFilesOnly))
|
if (file->getChildren(fslist2, FilesystemNode::kListFilesOnly))
|
||||||
Sword1CheckDirectory(fslist2, filesFound);
|
Sword1CheckDirectory(fslist2, filesFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ GameList Engine_SWORD2_detectGames(const FSList &fslist) {
|
|||||||
// Iterate over all files in the given directory
|
// Iterate over all files in the given directory
|
||||||
for (file = fslist.begin(); file != fslist.end(); ++file) {
|
for (file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (!file->isDirectory()) {
|
if (!file->isDirectory()) {
|
||||||
const char *fileName = file->name().c_str();
|
const char *fileName = file->getName().c_str();
|
||||||
|
|
||||||
if (0 == scumm_stricmp(g->detectname, fileName)) {
|
if (0 == scumm_stricmp(g->detectname, fileName)) {
|
||||||
// Match found, add to list of candidates, then abort inner loop.
|
// Match found, add to list of candidates, then abort inner loop.
|
||||||
@ -118,11 +118,11 @@ GameList Engine_SWORD2_detectGames(const FSList &fslist) {
|
|||||||
// present e.g. if the user copied the data straight from CD.
|
// present e.g. if the user copied the data straight from CD.
|
||||||
for (file = fslist.begin(); file != fslist.end(); ++file) {
|
for (file = fslist.begin(); file != fslist.end(); ++file) {
|
||||||
if (file->isDirectory()) {
|
if (file->isDirectory()) {
|
||||||
const char *fileName = file->name().c_str();
|
const char *fileName = file->getName().c_str();
|
||||||
|
|
||||||
if (0 == scumm_stricmp("clusters", fileName)) {
|
if (0 == scumm_stricmp("clusters", fileName)) {
|
||||||
FSList recList;
|
FSList recList;
|
||||||
if (file->listDir(recList, FilesystemNode::kListAll)) {
|
if (file->getChildren(recList, FilesystemNode::kListAll)) {
|
||||||
GameList recGames(Engine_SWORD2_detectGames(recList));
|
GameList recGames(Engine_SWORD2_detectGames(recList));
|
||||||
if (!recGames.empty()) {
|
if (!recGames.empty()) {
|
||||||
detectedGames.push_back(recGames);
|
detectedGames.push_back(recGames);
|
||||||
@ -144,7 +144,7 @@ PluginError Engine_SWORD2_create(OSystem *syst, Engine **engine) {
|
|||||||
|
|
||||||
FSList fslist;
|
FSList fslist;
|
||||||
FilesystemNode dir(ConfMan.get("path"));
|
FilesystemNode dir(ConfMan.get("path"));
|
||||||
if (!dir.listDir(fslist, FilesystemNode::kListAll)) {
|
if (!dir.getChildren(fslist, FilesystemNode::kListAll)) {
|
||||||
return kInvalidPathError;
|
return kInvalidPathError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ void ToucheEngine::readGameStateDescription(int num, char *description, int len)
|
|||||||
|
|
||||||
void ToucheEngine::generateGameStateFileName(int num, char *dst, int len, bool prefixOnly) const {
|
void ToucheEngine::generateGameStateFileName(int num, char *dst, int len, bool prefixOnly) const {
|
||||||
if (prefixOnly) {
|
if (prefixOnly) {
|
||||||
snprintf(dst, len, "%s.", _targetName.c_str());
|
snprintf(dst, len, "%s.*", _targetName.c_str());
|
||||||
} else {
|
} else {
|
||||||
snprintf(dst, len, "%s.%d", _targetName.c_str(), num);
|
snprintf(dst, len, "%s.%d", _targetName.c_str(), num);
|
||||||
}
|
}
|
||||||
|
@ -370,9 +370,33 @@ void ToucheEngine::handleOptions(int forceDisplay) {
|
|||||||
setupMenu(menuData.mode, &menuData);
|
setupMenu(menuData.mode, &menuData);
|
||||||
curMode = menuData.mode;
|
curMode = menuData.mode;
|
||||||
if (menuData.mode == kMenuLoadStateMode || menuData.mode == kMenuSaveStateMode) {
|
if (menuData.mode == kMenuLoadStateMode || menuData.mode == kMenuSaveStateMode) {
|
||||||
|
assert(menuData.saveLoadMarks);
|
||||||
|
|
||||||
char gameStateFileName[16];
|
char gameStateFileName[16];
|
||||||
generateGameStateFileName(999, gameStateFileName, 15, true);
|
generateGameStateFileName(999, gameStateFileName, 15, true);
|
||||||
_saveFileMan->listSavefiles(gameStateFileName, menuData.saveLoadMarks, 100);
|
char slot[2];
|
||||||
|
int slotNum;
|
||||||
|
Common::StringList filenames;
|
||||||
|
|
||||||
|
memset(menuData.saveLoadMarks, false, 100 * sizeof(bool)); //assume no savegames for this title
|
||||||
|
filenames = _saveFileMan->listSavefiles(gameStateFileName);
|
||||||
|
|
||||||
|
for(Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++){
|
||||||
|
//Obtain the last 1 or 2 digits of the filename, since they correspond to the save slot
|
||||||
|
//This engine can save games either with one or two digits, hence the additional if statement
|
||||||
|
slot[0] = file->c_str()[file->size()-2];
|
||||||
|
slot[1] = file->c_str()[file->size()-1];
|
||||||
|
|
||||||
|
if(!atoi(&slot[0])){
|
||||||
|
slotNum = atoi(&slot[1]);
|
||||||
|
} else {
|
||||||
|
slotNum = atoi(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(slotNum >= 0 && slotNum < 100)
|
||||||
|
menuData.saveLoadMarks[slotNum] = true; //mark this slot as valid
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 100; ++i) {
|
for (int i = 0; i < 100; ++i) {
|
||||||
menuData.saveLoadDescriptionsTable[i][0] = 0;
|
menuData.saveLoadDescriptionsTable[i][0] = 0;
|
||||||
if (menuData.saveLoadMarks[i]) {
|
if (menuData.saveLoadMarks[i]) {
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "gui/ListWidget.h"
|
#include "gui/ListWidget.h"
|
||||||
|
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
#include "common/fs.h"
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "common/algorithm.h"
|
#include "common/algorithm.h"
|
||||||
|
|
||||||
@ -223,15 +222,15 @@ void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
|
|||||||
|
|
||||||
void BrowserDialog::updateListing() {
|
void BrowserDialog::updateListing() {
|
||||||
// Update the path display
|
// Update the path display
|
||||||
_currentPath->setLabel(_node.path());
|
_currentPath->setLabel(_node.getPath());
|
||||||
|
|
||||||
// We memorize the last visited path.
|
// We memorize the last visited path.
|
||||||
ConfMan.set("browser_lastpath", _node.path());
|
ConfMan.set("browser_lastpath", _node.getPath());
|
||||||
|
|
||||||
// Read in the data from the file system
|
// Read in the data from the file system
|
||||||
FilesystemNode::ListMode listMode = _isDirBrowser ? FilesystemNode::kListDirectoriesOnly
|
FilesystemNode::ListMode listMode = _isDirBrowser ? FilesystemNode::kListDirectoriesOnly
|
||||||
: FilesystemNode::kListAll;
|
: FilesystemNode::kListAll;
|
||||||
if (!_node.listDir(_nodeContent, listMode)) {
|
if (!_node.getChildren(_nodeContent, listMode)) {
|
||||||
_nodeContent.clear();
|
_nodeContent.clear();
|
||||||
} else {
|
} else {
|
||||||
Common::sort(_nodeContent.begin(), _nodeContent.end());
|
Common::sort(_nodeContent.begin(), _nodeContent.end());
|
||||||
@ -241,9 +240,9 @@ void BrowserDialog::updateListing() {
|
|||||||
Common::StringList list;
|
Common::StringList list;
|
||||||
for (FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
|
for (FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
|
||||||
if (!_isDirBrowser && i->isDirectory())
|
if (!_isDirBrowser && i->isDirectory())
|
||||||
list.push_back(i->displayName() + "/");
|
list.push_back(i->getDisplayName() + "/");
|
||||||
else
|
else
|
||||||
list.push_back(i->displayName());
|
list.push_back(i->getDisplayName());
|
||||||
}
|
}
|
||||||
_fileList->setList(list);
|
_fileList->setList(list);
|
||||||
_fileList->scrollTo(0);
|
_fileList->scrollTo(0);
|
||||||
|
@ -394,9 +394,9 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made this choice...
|
// User made this choice...
|
||||||
FilesystemNode file(browser.getResult());
|
FilesystemNode file(browser.getResult());
|
||||||
_soundFont->setLabel(file.path());
|
_soundFont->setLabel(file.getPath());
|
||||||
|
|
||||||
if (!file.path().empty() && (file.path() != "None"))
|
if (!file.getPath().empty() && (file.getPath() != "None"))
|
||||||
_soundFontClearButton->setEnabled(true);
|
_soundFontClearButton->setEnabled(true);
|
||||||
else
|
else
|
||||||
_soundFontClearButton->setEnabled(false);
|
_soundFontClearButton->setEnabled(false);
|
||||||
@ -417,7 +417,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
|||||||
// done with optional specific gameid to pluginmgr detectgames?
|
// done with optional specific gameid to pluginmgr detectgames?
|
||||||
// FSList files = dir.listDir(FilesystemNode::kListFilesOnly);
|
// FSList files = dir.listDir(FilesystemNode::kListFilesOnly);
|
||||||
|
|
||||||
_gamePathWidget->setLabel(dir.path());
|
_gamePathWidget->setLabel(dir.getPath());
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
draw();
|
draw();
|
||||||
@ -430,7 +430,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode dir(browser.getResult());
|
FilesystemNode dir(browser.getResult());
|
||||||
_extraPathWidget->setLabel(dir.path());
|
_extraPathWidget->setLabel(dir.getPath());
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
draw();
|
draw();
|
||||||
@ -442,7 +442,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode dir(browser.getResult());
|
FilesystemNode dir(browser.getResult());
|
||||||
_savePathWidget->setLabel(dir.path());
|
_savePathWidget->setLabel(dir.getPath());
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
draw();
|
draw();
|
||||||
@ -654,9 +654,9 @@ void LauncherDialog::addGame() {
|
|||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode dir(_browser->getResult());
|
FilesystemNode dir(_browser->getResult());
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListAll)) {
|
if (!dir.getChildren(files, FilesystemNode::kListAll)) {
|
||||||
error("browser returned a node that is not a directory: '%s'",
|
error("browser returned a node that is not a directory: '%s'",
|
||||||
dir.path().c_str());
|
dir.getPath().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...so let's determine a list of candidates, games that
|
// ...so let's determine a list of candidates, games that
|
||||||
@ -686,7 +686,7 @@ void LauncherDialog::addGame() {
|
|||||||
GameDescriptor result = candidates[idx];
|
GameDescriptor result = candidates[idx];
|
||||||
|
|
||||||
// TODO: Change the detectors to set "path" !
|
// TODO: Change the detectors to set "path" !
|
||||||
result["path"] = dir.path();
|
result["path"] = dir.getPath();
|
||||||
|
|
||||||
Common::String domain = addGameToConf(result);
|
Common::String domain = addGameToConf(result);
|
||||||
|
|
||||||
|
@ -128,9 +128,9 @@ void MassAddDialog::handleTickle() {
|
|||||||
FilesystemNode dir = _scanStack.pop();
|
FilesystemNode dir = _scanStack.pop();
|
||||||
|
|
||||||
FSList files;
|
FSList files;
|
||||||
if (!dir.listDir(files, FilesystemNode::kListAll)) {
|
if (!dir.getChildren(files, FilesystemNode::kListAll)) {
|
||||||
error("browser returned a node that is not a directory: '%s'",
|
error("browser returned a node that is not a directory: '%s'",
|
||||||
dir.path().c_str());
|
dir.getPath().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the detector on the dir
|
// Run the detector on the dir
|
||||||
@ -142,7 +142,7 @@ void MassAddDialog::handleTickle() {
|
|||||||
// e.g. ask the user which one to pick (make sure to display the
|
// e.g. ask the user which one to pick (make sure to display the
|
||||||
// path, too).
|
// path, too).
|
||||||
GameDescriptor result = candidates[0];
|
GameDescriptor result = candidates[0];
|
||||||
result["path"] = dir.path();
|
result["path"] = dir.getPath();
|
||||||
|
|
||||||
_games.push_back(result);
|
_games.push_back(result);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "gui/themebrowser.h"
|
#include "gui/themebrowser.h"
|
||||||
#include "gui/chooser.h"
|
#include "gui/chooser.h"
|
||||||
#include "gui/eval.h"
|
#include "gui/eval.h"
|
||||||
|
#include "gui/message.h"
|
||||||
#include "gui/newgui.h"
|
#include "gui/newgui.h"
|
||||||
#include "gui/options.h"
|
#include "gui/options.h"
|
||||||
#include "gui/PopUpWidget.h"
|
#include "gui/PopUpWidget.h"
|
||||||
@ -813,9 +814,14 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode dir(browser.getResult());
|
FilesystemNode dir(browser.getResult());
|
||||||
_savePath->setLabel(dir.path());
|
if(dir.isWritable()) {
|
||||||
|
_savePath->setLabel(dir.getPath());
|
||||||
|
} else {
|
||||||
|
MessageDialog error("The chosen directory cannot be written to. Please select another one.");
|
||||||
|
error.runModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
draw();
|
draw();
|
||||||
// TODO - we should check if the directory is writeable before accepting it
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -824,7 +830,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode dir(browser.getResult());
|
FilesystemNode dir(browser.getResult());
|
||||||
_themePath->setLabel(dir.path());
|
_themePath->setLabel(dir.getPath());
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -834,7 +840,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode dir(browser.getResult());
|
FilesystemNode dir(browser.getResult());
|
||||||
_extraPath->setLabel(dir.path());
|
_extraPath->setLabel(dir.getPath());
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -844,9 +850,9 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
|
|||||||
if (browser.runModal() > 0) {
|
if (browser.runModal() > 0) {
|
||||||
// User made his choice...
|
// User made his choice...
|
||||||
FilesystemNode file(browser.getResult());
|
FilesystemNode file(browser.getResult());
|
||||||
_soundFont->setLabel(file.path());
|
_soundFont->setLabel(file.getPath());
|
||||||
|
|
||||||
if (!file.path().empty() && (file.path() != "None"))
|
if (!file.getPath().empty() && (file.getPath() != "None"))
|
||||||
_soundFontClearButton->setEnabled(true);
|
_soundFontClearButton->setEnabled(true);
|
||||||
else
|
else
|
||||||
_soundFontClearButton->setEnabled(false);
|
_soundFontClearButton->setEnabled(false);
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "gui/ListWidget.h"
|
#include "gui/ListWidget.h"
|
||||||
#include "gui/widget.h"
|
#include "gui/widget.h"
|
||||||
#include "gui/theme.h"
|
#include "gui/theme.h"
|
||||||
#include "common/fs.h"
|
|
||||||
|
|
||||||
#ifdef MACOSX
|
#ifdef MACOSX
|
||||||
#include "CoreFoundation/CoreFoundation.h"
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
@ -145,16 +144,16 @@ void ThemeBrowser::addDir(ThList &list, const Common::String &dir, int level) {
|
|||||||
|
|
||||||
FilesystemNode node(dir);
|
FilesystemNode node(dir);
|
||||||
|
|
||||||
if (!node.isValid())
|
if (!node.exists() || !node.isReadable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FSList fslist;
|
FSList fslist;
|
||||||
if (!node.listDir(fslist, FilesystemNode::kListAll))
|
if (!node.getChildren(fslist, FilesystemNode::kListAll))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) {
|
for (FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) {
|
||||||
if (i->isDirectory()) {
|
if (i->isDirectory()) {
|
||||||
addDir(list, i->path(), level-1);
|
addDir(list, i->getPath(), level-1);
|
||||||
} else {
|
} else {
|
||||||
Entry th;
|
Entry th;
|
||||||
if (isTheme(*i, th)) {
|
if (isTheme(*i, th)) {
|
||||||
@ -177,7 +176,7 @@ bool ThemeBrowser::isTheme(const FilesystemNode &node, Entry &out) {
|
|||||||
Common::ConfigFile cfg;
|
Common::ConfigFile cfg;
|
||||||
Common::String type;
|
Common::String type;
|
||||||
|
|
||||||
out.file = node.name();
|
out.file = node.getName();
|
||||||
for (int i = out.file.size()-1; out.file[i] != '.' && i > 0; --i) {
|
for (int i = out.file.size()-1; out.file[i] != '.' && i > 0; --i) {
|
||||||
out.file.deleteLastChar();
|
out.file.deleteLastChar();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user