diff --git a/src/common/FSNodeFactory.hxx b/src/common/FSNodeFactory.hxx new file mode 100644 index 000000000..c91fd0ccf --- /dev/null +++ b/src/common/FSNodeFactory.hxx @@ -0,0 +1,64 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +//============================================================================ + +#ifndef FSNODE_FACTORY_HXX +#define FSNODE_FACTORY_HXX + +class AbstractFSNode; +#if defined(UNIX) || defined(MAC_OSX) + #include "FSNodePOSIX.hxx" +#elif defined(WIN32) + #include "FSNodeWin32.hxx" +#else + #error Unsupported platform in FSNodeFactory! +#endif +#include "FSNodeZIP.hxx" + +/** + This class deals with creating the different FSNode implementations. + I think you can see why this mess was put into a factory class :) + + @author Stephen Anthony +*/ +class FilesystemNodeFactory +{ + public: + enum Type { SYSTEM, ZIP }; + + public: + static AbstractFSNode* create(const string& path, Type type) + { + switch(type) + { + case SYSTEM: + #if defined(UNIX) || defined(MAC_OSX) + return new FilesystemNodePOSIX(path); + #elif defined(WIN32) + return new FilesystemNodeWin32(path); + #endif + break; + case ZIP: + return new FilesystemNodeZIP(path); + break; + } + return 0; + } +}; + +#endif diff --git a/src/common/FSNodeZIP.cxx b/src/common/FSNodeZIP.cxx new file mode 100644 index 000000000..80cb6c0ac --- /dev/null +++ b/src/common/FSNodeZIP.cxx @@ -0,0 +1,108 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +// +// Based on code from ScummVM - Scumm Interpreter +// Copyright (C) 2002-2004 The ScummVM project +//============================================================================ + +#include "bspf.hxx" +#include "FSNodeFactory.hxx" +#include "FSNodeZIP.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FilesystemNodeZIP::FilesystemNodeZIP() +{ + // We need a name, else the node is invalid + _path = _shortPath = _virtualFile = ""; + _isValid = _isDirectory = _isFile = _isVirtual = false; + + AbstractFSNode* tmp = 0; + _realNode = Common::SharedPtr(tmp); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FilesystemNodeZIP::FilesystemNodeZIP(const string& p) +{ + // Extract ZIP file and virtual file (if specified) + size_t pos = BSPF_findIgnoreCase(p, ".zip"); + if(pos == string::npos) + { + // Not a ZIP file + _path = _shortPath = _virtualFile = ""; + _isValid = _isDirectory = _isFile = _isVirtual = false; + cerr << "Not a ZIP file\n"; + return; + } + + _zipFile = p.substr(0, pos+4); + + // A ZIP file is, behind the scenes, still a real file in the filesystem + // Hence, we need to create a real filesystem node for it + AbstractFSNode* tmp = FilesystemNodeFactory::create(_zipFile, + FilesystemNodeFactory::SYSTEM); + _realNode = Common::SharedPtr(tmp); + _path = _realNode->getPath(); + _shortPath = _realNode->getShortPath(); + + // Is a file component present? + if(pos+5 < p.length()) + { + _isVirtual = true; + _virtualFile = p.substr(pos+5); + _path += (BSPF_PATH_SEPARATOR + _virtualFile); + _shortPath += (BSPF_PATH_SEPARATOR + _virtualFile); + } + else + { + _isVirtual = false; + _virtualFile = ""; + } + +cerr << "FilesystemNodeZIP: " << p << endl + << "path: " << _path << endl + << "spath: " << getShortPath() << endl + << "zipFile: " << _zipFile << endl + << "virtualFile: " << _virtualFile << endl + << endl; + +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FilesystemNodeZIP::getChildren(AbstractFSList& myList, ListMode mode, + bool hidden) const +{ +cerr << "getChildren: " << _path << endl; + + // Files within ZIP archives don't contain children + if(_isVirtual) + return false; + + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool FilesystemNodeZIP::isAbsolute() const +{ + return false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +AbstractFSNode* FilesystemNodeZIP::getParent() const +{ + return _realNode ? _realNode->getParent() : 0; +} diff --git a/src/common/FSNodeZIP.hxx b/src/common/FSNodeZIP.hxx new file mode 100644 index 000000000..0c8195418 --- /dev/null +++ b/src/common/FSNodeZIP.hxx @@ -0,0 +1,80 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +// +// Based on code from ScummVM - Scumm Interpreter +// Copyright (C) 2002-2004 The ScummVM project +//============================================================================ + +#ifndef FS_NODE_ZIP_HXX +#define FS_NODE_ZIP_HXX + +#include "StringList.hxx" +#include "FSNode.hxx" + +/* + * Implementation of the Stella file system API based on ZIP archives. + * + * Parts of this class are documented in the base interface class, AbstractFSNode. + */ +class FilesystemNodeZIP : public AbstractFSNode +{ + public: + /** + * Creates a FilesystemNodeZIP with the root node as path. + */ + FilesystemNodeZIP(); + + /** + * Creates a FilesystemNodeZIP for a given path. + * + * @param path String with the path the new node should point to. + * @param verify true if the isValid and isDirectory/isFile flags should + * be verified during the construction. + */ + FilesystemNodeZIP(const string& path); + + bool exists() const { return false; } + const string& getName() const { return _virtualFile; } + const string& getPath() const { return _path; } + string getShortPath() const { return _shortPath; } + bool isDirectory() const { return _isDirectory; } + bool isFile() const { return _isFile; } + bool isReadable() const { return false; } + bool isWritable() const { return false; } + bool isAbsolute() const; + + ////////////////////////////////////////////////////////// + // For now, ZIP files cannot be modified in any way + bool makeDir() { return false; } + bool rename(const string& newfile) { return false; } + ////////////////////////////////////////////////////////// + + bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; + AbstractFSNode* getParent() const; + + protected: + Common::SharedPtr _realNode; + string _zipFile, _virtualFile; + string _path, _shortPath; + bool _isDirectory; + bool _isFile; + bool _isValid; + bool _isVirtual; +}; + +#endif diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 1a9f03217..3b606b6c2 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -174,6 +174,12 @@ inline bool BSPF_endsWithIgnoreCase(const string& s1, const string& s2) false; } +// Test whether the first string contains the second one (case insensitive) +inline bool BSPF_containsIgnoreCase(const string& s1, const string& s2) +{ + return BSPF_findIgnoreCase(s1, s2) != string::npos; +} + static const string EmptyString(""); #endif diff --git a/src/common/module.mk b/src/common/module.mk index 0c99bcf14..ecd4758e1 100644 --- a/src/common/module.mk +++ b/src/common/module.mk @@ -7,6 +7,7 @@ MODULE_OBJS := \ src/common/FrameBufferGL.o \ src/common/FBSurfaceGL.o \ src/common/FBSurfaceTIA.o \ + src/common/FSNodeZIP.o \ src/common/PNGLibrary.o \ src/common/MouseControl.o \ src/common/RectList.o diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index caea63a5e..e6244e68a 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -22,6 +22,7 @@ #include "bspf.hxx" #include "SharedPtr.hxx" +#include "FSNodeFactory.hxx" #include "FSNode.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -30,7 +31,7 @@ FilesystemNode::FilesystemNode() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) +FilesystemNode::FilesystemNode(AbstractFSNode *realNode) : _realNode(realNode) { } @@ -38,8 +39,15 @@ FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FilesystemNode::FilesystemNode(const string& p) { - AbstractFilesystemNode* tmp = AbstractFilesystemNode::makeFileNodePath(p); - _realNode = Common::SharedPtr(tmp); + AbstractFSNode* tmp = 0; + + // Is this potentially a ZIP archive? + if(BSPF_containsIgnoreCase(p, ".zip")) + tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::ZIP); + else + tmp = FilesystemNodeFactory::create(p, FilesystemNodeFactory::SYSTEM); + + _realNode = Common::SharedPtr(tmp); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -85,7 +93,7 @@ FilesystemNode FilesystemNode::getParent() const if (_realNode == 0) return *this; - AbstractFilesystemNode* node = _realNode->getParent(); + AbstractFSNode* node = _realNode->getParent(); if (node == 0) return *this; else @@ -95,14 +103,12 @@ FilesystemNode FilesystemNode::getParent() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const string& FilesystemNode::getPath() const { - assert(_realNode); return _realNode->getPath(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string FilesystemNode::getShortPath() const { - assert(_realNode); return _realNode->getShortPath(); } diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index 2828ae0d8..27a1753f2 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -51,7 +51,7 @@ #include "SharedPtr.hxx" class FilesystemNode; -class AbstractFilesystemNode; +class AbstractFSNode; /** * List of multiple file system nodes. E.g. the contents of a given directory. @@ -61,7 +61,7 @@ class AbstractFilesystemNode; class FSList : public Common::Array { }; /** - * This class acts as a wrapper around the AbstractFilesystemNode class defined + * This class acts as a wrapper around the AbstractFSNode class defined * in backends/fs. */ class FilesystemNode @@ -244,8 +244,8 @@ class FilesystemNode const string& ext); private: - Common::SharedPtr _realNode; - FilesystemNode(AbstractFilesystemNode* realNode); + Common::SharedPtr _realNode; + FilesystemNode(AbstractFSNode* realNode); }; @@ -258,9 +258,9 @@ class FilesystemNode * the semantics. */ -typedef Common::Array AbstractFSList; +typedef Common::Array AbstractFSList; -class AbstractFilesystemNode +class AbstractFSNode { protected: friend class FilesystemNode; @@ -270,7 +270,7 @@ class AbstractFilesystemNode /** * Destructor. */ - virtual ~AbstractFilesystemNode() {} + virtual ~AbstractFSNode() {} /* * Indicates whether the object referred by this path exists in the @@ -372,20 +372,11 @@ class AbstractFilesystemNode */ virtual bool rename(const string& newfile) = 0; - protected: /** * The parent node of this directory. * The parent of the root is the root itself. */ - virtual AbstractFilesystemNode* getParent() const = 0; - - /** - * Construct a node based on a path; the path is in the same format as it - * would be for calls to fopen(). - * - * @param path The path string to create a FilesystemNode for. - */ - static AbstractFilesystemNode* makeFileNodePath(const string& path); + virtual AbstractFSNode* getParent() const = 0; }; #endif diff --git a/src/emucore/MediaFactory.cxx b/src/emucore/MediaFactory.cxx deleted file mode 100644 index 0448e5347..000000000 --- a/src/emucore/MediaFactory.cxx +++ /dev/null @@ -1,80 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id$ -//============================================================================ - -//////////////////////////////////////////////////////////////////// -// I think you can see why this mess was put into a factory class :) -//////////////////////////////////////////////////////////////////// - -#include "MediaFactory.hxx" - -#include "OSystem.hxx" -#include "Settings.hxx" - -#include "FrameBuffer.hxx" -#include "FrameBufferSoft.hxx" -#ifdef DISPLAY_OPENGL - #include "FrameBufferGL.hxx" -#endif - -#include "Sound.hxx" -#ifdef SOUND_SUPPORT - #include "SoundSDL.hxx" -#else - #include "SoundNull.hxx" -#endif - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -FrameBuffer* MediaFactory::createVideo(OSystem* osystem) -{ - FrameBuffer* fb = (FrameBuffer*) NULL; - - // OpenGL mode *may* fail, so we check for it first -#ifdef DISPLAY_OPENGL - if(osystem->settings().getString("video") == "gl") - { - const string& gl_lib = osystem->settings().getString("gl_lib"); - if(FrameBufferGL::loadLibrary(gl_lib)) - fb = new FrameBufferGL(osystem); - } -#endif - - // If OpenGL failed, or if it wasn't requested, create the appropriate - // software framebuffer - if(!fb) - fb = new FrameBufferSoft(osystem); - - // This should never happen - assert(fb != NULL); - - return fb; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Sound* MediaFactory::createAudio(OSystem* osystem) -{ - Sound* sound = (Sound*) NULL; - -#ifdef SOUND_SUPPORT - sound = new SoundSDL(osystem); -#else - sound = new SoundNull(osystem); -#endif - - return sound; -} diff --git a/src/emucore/MediaFactory.hxx b/src/emucore/MediaFactory.hxx index f343c96c8..e948a25da 100644 --- a/src/emucore/MediaFactory.hxx +++ b/src/emucore/MediaFactory.hxx @@ -20,23 +20,72 @@ #ifndef MEDIA_FACTORY_HXX #define MEDIA_FACTORY_HXX -class FrameBuffer; -class Sound; -class OSystem; +#include "OSystem.hxx" +#include "Settings.hxx" + +#include "FrameBuffer.hxx" +#include "FrameBufferSoft.hxx" +#ifdef DISPLAY_OPENGL + #include "FrameBufferGL.hxx" +#endif + +#include "Sound.hxx" +#ifdef SOUND_SUPPORT + #include "SoundSDL.hxx" +#else + #include "SoundNull.hxx" +#endif /** This class deals with the different framebuffer/sound implementations for the various ports of Stella, and always returns a valid media object based on the specific port and restrictions on that port. + I think you can see why this mess was put into a factory class :) + @author Stephen Anthony @version $Id$ */ class MediaFactory { public: - static FrameBuffer* createVideo(OSystem* osystem); - static Sound* createAudio(OSystem* osystem); + static FrameBuffer* createVideo(OSystem* osystem) + { + FrameBuffer* fb = (FrameBuffer*) NULL; + + // OpenGL mode *may* fail, so we check for it first + #ifdef DISPLAY_OPENGL + if(osystem->settings().getString("video") == "gl") + { + const string& gl_lib = osystem->settings().getString("gl_lib"); + if(FrameBufferGL::loadLibrary(gl_lib)) + fb = new FrameBufferGL(osystem); + } + #endif + + // If OpenGL failed, or if it wasn't requested, create the appropriate + // software framebuffer + if(!fb) + fb = new FrameBufferSoft(osystem); + + // This should never happen + assert(fb != NULL); + + return fb; + } + + static Sound* createAudio(OSystem* osystem) + { + Sound* sound = (Sound*) NULL; + + #ifdef SOUND_SUPPORT + sound = new SoundSDL(osystem); + #else + sound = new SoundNull(osystem); + #endif + + return sound; + } }; #endif diff --git a/src/emucore/module.mk b/src/emucore/module.mk index c4d4bc60e..2433be693 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -67,7 +67,6 @@ MODULE_OBJS := \ src/emucore/TIATables.o \ src/emucore/TrackBall.o \ src/emucore/unzip.o \ - src/emucore/MediaFactory.o \ src/emucore/Thumbulator.o MODULE_DIRS += \ diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 5445f6d2f..4589278b5 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -373,11 +373,13 @@ void LauncherDialog::loadDirListing() if(strlen(filename) >= 4 && !BSPF_startsWithIgnoreCase(filename, "__MACOSX")) { +#if 0 // Grab 3-character extension const char* ext = filename + strlen(filename) - 4; if(BSPF_equalsIgnoreCase(ext, ".a26") || BSPF_equalsIgnoreCase(ext, ".bin") || BSPF_equalsIgnoreCase(ext, ".rom")) +#endif { FilesystemNode newFile(FilesystemNode::createAbsolutePath( filename, myCurrentNode.getPath(), "")); diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 428231c7e..ed05d8e75 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -20,79 +20,7 @@ // Copyright (C) 2002-2004 The ScummVM project //============================================================================ -#include "FSNode.hxx" - -#ifdef MACOSX - #include -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#ifndef MAXPATHLEN // No MAXPATHLEN, as happens on Hurd - #define MAXPATHLEN 1024 -#endif - -/* - * Implementation of the Stella file system API based on POSIX (for Linux and OSX) - * - * Parts of this class are documented in the base interface class, AbstractFilesystemNode. - */ -class POSIXFilesystemNode : public AbstractFilesystemNode -{ - public: - /** - * Creates a POSIXFilesystemNode with the root node as path. - */ - POSIXFilesystemNode(); - - /** - * Creates a POSIXFilesystemNode for a given path. - * - * @param path String with the path the new node should point to. - * @param verify true if the isValid and isDirectory/isFile flags should - * be verified during the construction. - */ - POSIXFilesystemNode(const string& path, bool verify = true); - - bool exists() const { return access(_path.c_str(), F_OK) == 0; } - const string& getName() const { return _displayName; } - const string& getPath() const { return _path; } - string getShortPath() const; - bool isDirectory() const { return _isDirectory; } - bool isFile() const { return _isFile; } - bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } - bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } - bool isAbsolute() const; - bool makeDir(); - bool rename(const string& newfile); - - bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; - AbstractFilesystemNode* getParent() const; - - protected: - string _displayName; - string _path; - bool _isDirectory; - bool _isFile; - bool _isValid; - - private: - /** - * Tests and sets the _isValid and _isDirectory/_isFile flags, - * using the stat() function. - */ - virtual void setFlags(); -}; +#include "FSNodePOSIX.hxx" /** * Returns the last component of a given path. @@ -120,7 +48,7 @@ const char* lastPathComponent(const string& str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void POSIXFilesystemNode::setFlags() +void FilesystemNodePOSIX::setFlags() { struct stat st; @@ -135,7 +63,7 @@ void POSIXFilesystemNode::setFlags() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -POSIXFilesystemNode::POSIXFilesystemNode() +FilesystemNodePOSIX::FilesystemNodePOSIX() { // The root dir. _path = "/"; @@ -146,7 +74,7 @@ POSIXFilesystemNode::POSIXFilesystemNode() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify) +FilesystemNodePOSIX::FilesystemNodePOSIX(const string& p, bool verify) { // Default to home directory _path = p.length() > 0 ? p : "~"; @@ -177,7 +105,7 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string POSIXFilesystemNode::getShortPath() const +string FilesystemNodePOSIX::getShortPath() const { // If the path starts with the home directory, replace it with '~' const char* home = getenv("HOME"); @@ -193,7 +121,7 @@ string POSIXFilesystemNode::getShortPath() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, +bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode, bool hidden) const { assert(_isDirectory); @@ -220,7 +148,7 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, newPath += '/'; newPath += dp->d_name; - POSIXFilesystemNode entry(newPath, false); + FilesystemNodePOSIX entry(newPath, false); #if defined(SYSTEM_NOT_SUPPORTING_D_TYPE) /* TODO: d_type is not part of POSIX, so it might not be supported @@ -272,7 +200,7 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, if (entry._isDirectory) entry._path += "/"; - myList.push_back(new POSIXFilesystemNode(entry)); + myList.push_back(new FilesystemNodePOSIX(entry)); } closedir(dirp); @@ -280,13 +208,13 @@ bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool POSIXFilesystemNode::isAbsolute() const +bool FilesystemNodePOSIX::isAbsolute() const { return _path.length() > 0 && (_path[0] == '~' || _path[0] == '/'); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool POSIXFilesystemNode::makeDir() +bool FilesystemNodePOSIX::makeDir() { if(mkdir(_path.c_str(), 0777) == 0) { @@ -309,7 +237,7 @@ bool POSIXFilesystemNode::makeDir() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool POSIXFilesystemNode::rename(const string& newfile) +bool FilesystemNodePOSIX::rename(const string& newfile) { if(std::rename(_path.c_str(), newfile.c_str()) == 0) { @@ -334,7 +262,7 @@ bool POSIXFilesystemNode::rename(const string& newfile) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AbstractFilesystemNode* POSIXFilesystemNode::getParent() const +AbstractFSNode* FilesystemNodePOSIX::getParent() const { if (_path == "/") return 0; @@ -342,11 +270,5 @@ AbstractFilesystemNode* POSIXFilesystemNode::getParent() const const char *start = _path.c_str(); const char *end = lastPathComponent(_path); - return new POSIXFilesystemNode(string(start, end - start)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AbstractFilesystemNode* AbstractFilesystemNode::makeFileNodePath(const string& path) -{ - return new POSIXFilesystemNode(path); + return new FilesystemNodePOSIX(string(start, end - start)); } diff --git a/src/unix/FSNodePOSIX.hxx b/src/unix/FSNodePOSIX.hxx new file mode 100644 index 000000000..898d8cf1e --- /dev/null +++ b/src/unix/FSNodePOSIX.hxx @@ -0,0 +1,100 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +// +// Based on code from ScummVM - Scumm Interpreter +// Copyright (C) 2002-2004 The ScummVM project +//============================================================================ + +#ifndef FS_NODE_POSIX_HXX +#define FS_NODE_POSIX_HXX + +#include "FSNode.hxx" + +#ifdef MACOSX + #include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifndef MAXPATHLEN // No MAXPATHLEN, as happens on Hurd + #define MAXPATHLEN 1024 +#endif + +/* + * Implementation of the Stella file system API based on POSIX (for Linux and OSX) + * + * Parts of this class are documented in the base interface class, AbstractFSNode. + */ +class FilesystemNodePOSIX : public AbstractFSNode +{ + public: + /** + * Creates a FilesystemNodePOSIX with the root node as path. + */ + FilesystemNodePOSIX(); + + /** + * Creates a FilesystemNodePOSIX for a given path. + * + * @param path String with the path the new node should point to. + * @param verify true if the isValid and isDirectory/isFile flags should + * be verified during the construction. + */ + FilesystemNodePOSIX(const string& path, bool verify = true); + + bool exists() const { return access(_path.c_str(), F_OK) == 0; } + const string& getName() const { return _displayName; } + const string& getPath() const { return _path; } + string getShortPath() const; + bool isDirectory() const { return _isDirectory; } + bool isFile() const { return _isFile; } + bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } + bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } + bool isAbsolute() const; + bool makeDir(); + bool rename(const string& newfile); + + bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; + AbstractFSNode* getParent() const; + + protected: + string _displayName; + string _path; + bool _isDirectory; + bool _isFile; + bool _isValid; + + private: + /** + * Tests and sets the _isValid and _isDirectory/_isFile flags, + * using the stat() function. + */ + virtual void setFlags(); +}; + +#endif diff --git a/src/win32/FSNodeWin32.cxx b/src/win32/FSNodeWin32.cxx index c811f3bea..5d91d8450 100644 --- a/src/win32/FSNodeWin32.cxx +++ b/src/win32/FSNodeWin32.cxx @@ -20,139 +20,6 @@ // Copyright (C) 2002-2004 The ScummVM project //============================================================================ -#include -#include - -#ifdef ARRAYSIZE - #undef ARRAYSIZE -#endif -#ifdef _WIN32_WCE - #include - // winnt.h defines ARRAYSIZE, but we want our own one... - #undef ARRAYSIZE - #undef GetCurrentDirectory -#endif - -#include -#include -#include -#ifndef _WIN32_WCE - #include - // winnt.h defines ARRAYSIZE, but we want our own one... - #undef ARRAYSIZE -#endif -#include - -// F_OK, R_OK and W_OK are not defined under MSVC, so we define them here -// For more information on the modes used by MSVC, check: -// http://msdn2.microsoft.com/en-us/library/1w06ktdy(VS.80).aspx -#ifndef F_OK - #define F_OK 0 -#endif - -#ifndef R_OK - #define R_OK 4 -#endif - -#ifndef W_OK - #define W_OK 2 -#endif - -#include "FSNode.hxx" -#include "HomeFinder.hxx" - -static HomeFinder myHomeFinder; - -// TODO - fix isFile() functionality so that it actually determines if something -// is a file; for now, it assumes a file if it isn't a directory - -/* - * Implementation of the Stella file system API based on Windows API. - * - * Parts of this class are documented in the base interface class, - * AbstractFilesystemNode. - */ -class WindowsFilesystemNode : public AbstractFilesystemNode -{ - 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(); - - /** - * Creates a WindowsFilesystemNode for a given path. - * - * 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. - */ - WindowsFilesystemNode(const string& path); - - bool exists() const { return _access(_path.c_str(), F_OK) == 0; } - const string& getName() const { return _displayName; } - const string& getPath() const { return _path; } - string getShortPath() const; - bool isDirectory() const { return _isDirectory; } - bool isFile() const { return _isFile; } - bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; } - bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; } - bool isAbsolute() const; - bool makeDir(); - bool rename(const string& newfile); - - bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; - AbstractFilesystemNode* getParent() const; - - protected: - string _displayName; - string _path; - bool _isDirectory; - bool _isFile; - bool _isPseudoRoot; - bool _isValid; - - private: - /** - * Tests and sets the _isValid and _isDirectory/_isFile flags, - * using the GetFileAttributes() function. - */ - virtual void setFlags(); - - /** - * 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, 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. * @@ -179,7 +46,7 @@ const char* lastPathComponent(const string& str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void WindowsFilesystemNode::setFlags() +void FilesystemNodeWin32::setFlags() { // Get absolute path TCHAR buf[4096]; @@ -209,10 +76,10 @@ void WindowsFilesystemNode::setFlags() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void WindowsFilesystemNode::addFile(AbstractFSList& list, ListMode mode, +void FilesystemNodeWin32::addFile(AbstractFSList& list, ListMode mode, const char* base, WIN32_FIND_DATA* find_data) { - WindowsFilesystemNode entry; + FilesystemNodeWin32 entry; char* asciiName = toAscii(find_data->cFileName); bool isDirectory, isFile; @@ -237,11 +104,11 @@ void WindowsFilesystemNode::addFile(AbstractFSList& list, ListMode mode, entry._isValid = true; entry._isPseudoRoot = false; - list.push_back(new WindowsFilesystemNode(entry)); + list.push_back(new FilesystemNodeWin32(entry)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -char* WindowsFilesystemNode::toAscii(TCHAR* str) +char* FilesystemNodeWin32::toAscii(TCHAR* str) { #ifndef UNICODE return (char*)str; @@ -253,7 +120,7 @@ char* WindowsFilesystemNode::toAscii(TCHAR* str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const TCHAR* WindowsFilesystemNode::toUnicode(const char* str) +const TCHAR* FilesystemNodeWin32::toUnicode(const char* str) { #ifndef UNICODE return (const TCHAR *)str; @@ -265,7 +132,7 @@ const TCHAR* WindowsFilesystemNode::toUnicode(const char* str) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -WindowsFilesystemNode::WindowsFilesystemNode() +FilesystemNodeWin32::FilesystemNodeWin32() { // Create a virtual root directory for standard Windows system _isDirectory = true; @@ -276,7 +143,7 @@ WindowsFilesystemNode::WindowsFilesystemNode() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -WindowsFilesystemNode::WindowsFilesystemNode(const string& p) +FilesystemNodeWin32::FilesystemNodeWin32(const string& p) { // Default to home directory _path = p.length() > 0 ? p : "~"; @@ -289,7 +156,7 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string WindowsFilesystemNode::getShortPath() const +string FilesystemNodeWin32::getShortPath() const { // If the path starts with the home directory, replace it with '~' const string& home = myHomeFinder.getHomePath(); @@ -305,7 +172,7 @@ string WindowsFilesystemNode::getShortPath() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool WindowsFilesystemNode:: +bool FilesystemNodeWin32:: getChildren(AbstractFSList& myList, ListMode mode, bool hidden) const { assert(_isDirectory); @@ -321,7 +188,7 @@ bool WindowsFilesystemNode:: for (TCHAR *current_drive = drive_buffer; *current_drive; current_drive += _tcslen(current_drive) + 1) { - WindowsFilesystemNode entry; + FilesystemNodeWin32 entry; char drive_name[2]; drive_name[0] = toAscii(current_drive)[0]; @@ -332,7 +199,7 @@ bool WindowsFilesystemNode:: entry._isValid = true; entry._isPseudoRoot = false; entry._path = toAscii(current_drive); - myList.push_back(new WindowsFilesystemNode(entry)); + myList.push_back(new FilesystemNodeWin32(entry)); } } else @@ -361,13 +228,13 @@ bool WindowsFilesystemNode:: } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool WindowsFilesystemNode::isAbsolute() const +bool FilesystemNodeWin32::isAbsolute() const { return _path.length() >= 2 && (_path[0] == '~' || _path[1] == ':'); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool WindowsFilesystemNode::makeDir() +bool FilesystemNodeWin32::makeDir() { if(!_isPseudoRoot && CreateDirectory(_path.c_str(), NULL) != 0) { @@ -379,7 +246,7 @@ bool WindowsFilesystemNode::makeDir() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool WindowsFilesystemNode::rename(const string& newfile) +bool FilesystemNodeWin32::rename(const string& newfile) { if(!_isPseudoRoot && MoveFile(_path.c_str(), newfile.c_str()) != 0) { @@ -391,12 +258,12 @@ bool WindowsFilesystemNode::rename(const string& newfile) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AbstractFilesystemNode* WindowsFilesystemNode::getParent() const +AbstractFSNode* FilesystemNodeWin32::getParent() const { if (!_isValid || _isPseudoRoot) return 0; - WindowsFilesystemNode* p = new WindowsFilesystemNode(); + FilesystemNodeWin32* p = new FilesystemNodeWin32(); if (_path.size() > 3) { const char *start = _path.c_str(); @@ -414,7 +281,7 @@ AbstractFilesystemNode* WindowsFilesystemNode::getParent() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -AbstractFilesystemNode* AbstractFilesystemNode::makeFileNodePath(const string& path) +AbstractFSNode* AbstractFSNode::makeFileNodePath(const string& path) { - return new WindowsFilesystemNode(path); + return new FilesystemNodeWin32(path); } diff --git a/src/win32/FSNodeWin32.hxx b/src/win32/FSNodeWin32.hxx new file mode 100644 index 000000000..af3f636cf --- /dev/null +++ b/src/win32/FSNodeWin32.hxx @@ -0,0 +1,159 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2013 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +// +// Based on code from ScummVM - Scumm Interpreter +// Copyright (C) 2002-2004 The ScummVM project +//============================================================================ + +#ifndef FS_NODE_WIN32_HXX +#define FS_NODE_WIN32_HXX + +#include +#include + +#ifdef ARRAYSIZE + #undef ARRAYSIZE +#endif +#ifdef _WIN32_WCE + #include + // winnt.h defines ARRAYSIZE, but we want our own one... + #undef ARRAYSIZE + #undef GetCurrentDirectory +#endif + +#include +#include +#include +#ifndef _WIN32_WCE + #include + // winnt.h defines ARRAYSIZE, but we want our own one... + #undef ARRAYSIZE +#endif +#include + +// F_OK, R_OK and W_OK are not defined under MSVC, so we define them here +// For more information on the modes used by MSVC, check: +// http://msdn2.microsoft.com/en-us/library/1w06ktdy(VS.80).aspx +#ifndef F_OK + #define F_OK 0 +#endif + +#ifndef R_OK + #define R_OK 4 +#endif + +#ifndef W_OK + #define W_OK 2 +#endif + +#include "FSNode.hxx" +#include "HomeFinder.hxx" + +static HomeFinder myHomeFinder; + +// TODO - fix isFile() functionality so that it actually determines if something +// is a file; for now, it assumes a file if it isn't a directory + +/* + * Implementation of the Stella file system API based on Windows API. + * + * Parts of this class are documented in the base interface class, + * AbstractFSNode. + */ +class FilesystemNodeWin32 : public AbstractFSNode +{ + public: + /** + * Creates a FilesystemNodeWin32 with the root node as path. + * + * In regular windows systems, a virtual root path is used "". + * In windows CE, the "\" root is used instead. + */ + FilesystemNodeWin32(); + + /** + * Creates a FilesystemNodeWin32 for a given path. + * + * 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. + */ + FilesystemNodeWin32(const string& path); + + bool exists() const { return _access(_path.c_str(), F_OK) == 0; } + const string& getName() const { return _displayName; } + const string& getPath() const { return _path; } + string getShortPath() const; + bool isDirectory() const { return _isDirectory; } + bool isFile() const { return _isFile; } + bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; } + bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; } + bool isAbsolute() const; + bool makeDir(); + bool rename(const string& newfile); + + bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; + AbstractFSNode* getParent() const; + + protected: + string _displayName; + string _path; + bool _isDirectory; + bool _isFile; + bool _isPseudoRoot; + bool _isValid; + + private: + /** + * Tests and sets the _isValid and _isDirectory/_isFile flags, + * using the GetFileAttributes() function. + */ + virtual void setFlags(); + + /** + * Adds a single FilesystemNodeWin32 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, 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); +}; + +#endif