diff options
author | Ruediger Hanke | 2002-11-15 15:12:30 +0000 |
---|---|---|
committer | Ruediger Hanke | 2002-11-15 15:12:30 +0000 |
commit | 1d17168202da7f16d71de4fc05b798a145731036 (patch) | |
tree | 66f15870a559e8771322e571f6b3ccd4a07e7aaf /backends/fs/morphos | |
parent | 18bb6f73048b2ef29e783cf31f849f448bbe8716 (diff) | |
download | scummvm-rg350-1d17168202da7f16d71de4fc05b798a145731036.tar.gz scummvm-rg350-1d17168202da7f16d71de4fc05b798a145731036.tar.bz2 scummvm-rg350-1d17168202da7f16d71de4fc05b798a145731036.zip |
FS backend for MorphOS
svn-id: r5566
Diffstat (limited to 'backends/fs/morphos')
-rw-r--r-- | backends/fs/morphos/abox-fs.cpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp new file mode 100644 index 0000000000..054c5d86b1 --- /dev/null +++ b/backends/fs/morphos/abox-fs.cpp @@ -0,0 +1,259 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + */ + +#if defined(__MORPHOS__) + +#include <proto/dos.h> + +#include <stdio.h> + +#include "common/engine.h" +#include "../fs.h" + +/* + * Implementation of the ScummVM file system API based on the MorphOS A-Box API. + */ + +class ABoxFilesystemNode : public FilesystemNode { + protected: + BPTR _lock; + String _displayName; + bool _isDirectory; + bool _isValid; + String _path; + + public: + ABoxFilesystemNode(); + ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL); + ABoxFilesystemNode(const ABoxFilesystemNode *node); + ~ABoxFilesystemNode(); + + virtual String displayName() const { return _displayName; } + virtual bool isValid() const { return _isValid; } + virtual bool isDirectory() const { return _isDirectory; } + virtual String path() const { return _path; } + + virtual FSList *listDir() const; + static FSList *listRoot(); + virtual FilesystemNode *parent() const; + virtual FilesystemNode *clone() const { return new ABoxFilesystemNode(this); } +}; + + +FilesystemNode *FilesystemNode::getRoot() +{ + return new ABoxFilesystemNode(); +} + +ABoxFilesystemNode::ABoxFilesystemNode() +{ + _displayName = "All Drives"; + _isValid = true; + _isDirectory = true; + _path = ""; + _lock = NULL; +} + +ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name) +{ + int bufsize = 256; + + _lock = NULL; + for (;;) + { + char name[bufsize]; + if (NameFromLock(lock, name, bufsize) != DOSFALSE) + { + _path = name; + _displayName = display_name ? display_name : FilePart(name); + break; + } + if (IoErr() != ERROR_LINE_TOO_LONG) + { + _isValid = false; + warning("Error while retrieving path name: %d", IoErr()); + return; + } + bufsize *= 2; + } + + _isValid = false; + + FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); + if (fib == NULL) + { + warning("Failed to allocate memory for FileInfoBlock"); + return; + } + + if (Examine(lock, fib) != DOSFALSE) + { + _isDirectory = fib->fib_EntryType > 0; + if (_isDirectory) + { + _lock = DupLock(lock); + _isValid = (_lock != NULL); + } + else + _isValid = true; + } + FreeDosObject(DOS_FIB, fib); +} + +ABoxFilesystemNode::ABoxFilesystemNode(const ABoxFilesystemNode *node) +{ + _displayName = node->_displayName; + _isValid = node->_isValid; + _isDirectory = node->_isDirectory; + _path = node->_path; + _lock = DupLock(node->_lock); +} + +ABoxFilesystemNode::~ABoxFilesystemNode() +{ + if (_lock) + { + UnLock(_lock); + _lock = NULL; + } +} + +FSList *ABoxFilesystemNode::listDir() const +{ + FSList *myList = new FSList(); + + if (!_isValid) + error("listDir() called on invalid node"); + + if (!_isDirectory) + error("listDir() called on file node"); + + if (_lock == NULL) + { + /* This is the root node */ + return listRoot(); + } + + /* "Normal" file system directory */ + FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); + + if (fib == NULL) + { + warning("Failed to allocate memory for FileInfoBlock"); + return myList; + } + + if (Examine(_lock, fib) != DOSFALSE) + { + while (ExNext(_lock, fib) != DOSFALSE) + { + ABoxFilesystemNode entry; + entry._displayName = fib->fib_FileName; + entry._isDirectory = fib->fib_EntryType > 0; + entry._path = _path; + entry._path += fib->fib_FileName; + if (entry._isDirectory) + entry._path += "/"; + myList->push_back(entry); + } + + if (IoErr() != ERROR_NO_MORE_ENTRIES) + warning("Error while reading directory: %d", IoErr()); + } + + FreeDosObject(DOS_FIB, fib); + + return myList; +} + +FilesystemNode *ABoxFilesystemNode::parent() const +{ + FilesystemNode *node = NULL; + + if (!_isDirectory) + error("parent() called on file node"); + + if (_lock == NULL) + /* Parent of the root is the root itself */ + node = const_cast<ABoxFilesystemNode*>(this); + else + { + BPTR parent_lock = ParentDir(_lock); + if (parent_lock) + { + node = new ABoxFilesystemNode(parent_lock); + UnLock(parent_lock); + } + else + node = new ABoxFilesystemNode(); + } + + return node; +} + +FSList *ABoxFilesystemNode::listRoot() +{ + FSList *myList = new FSList(); + DosList *dosList; + CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES; + char name[256]; + + dosList = LockDosList(lockDosListFlags); + if (dosList == NULL) + { + warning("Could not lock dos list"); + return myList; + } + + dosList = NextDosEntry(dosList, LDF_VOLUMES); + while (dosList) + { + if (dosList->dol_Type == DLT_VOLUME && // Should always be true, but ... + dosList->dol_Name && // Same here + dosList->dol_Task // Will be NULL if volume is removed from drive but still in use by some program + ) + { + ABoxFilesystemNode *entry; + CONST_STRPTR volume_name = (CONST_STRPTR)BADDR(dosList->dol_Name)+1; + CONST_STRPTR device_name = (CONST_STRPTR)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name; + BPTR volume_lock; + + strcpy(name, volume_name); + strcat(name, ":"); + volume_lock = Lock(name, SHARED_LOCK); + if (volume_lock) + { + sprintf(name, "%s (%s)", volume_name, device_name); + entry = new ABoxFilesystemNode(volume_lock, name); + if (entry->isValid()) + myList->push_back(*entry); + UnLock(volume_lock); + } + } + dosList = NextDosEntry(dosList, LDF_VOLUMES); + } + + UnLockDosList(lockDosListFlags); + + return myList; +} + +#endif // defined(__MORPHOS__) + |