Patch #1594533: morphos fs backend

svn-id: r24690
This commit is contained in:
Max Horn 2006-11-12 11:43:46 +00:00
parent b648aaf64b
commit fb795dabd0

View File

@ -24,8 +24,12 @@
#include <proto/dos.h>
#include <stdio.h>
#include <sys/stat.h>
#include "engines/engine.h"
#include <common/stdafx.h>
#include "common/util.h"
#include "base/engine.h"
#include "backends/fs/abstract-fs.h"
/*
@ -43,10 +47,13 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
public:
ABoxFilesystemNode();
ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL);
ABoxFilesystemNode(const String &p);
ABoxFilesystemNode(const ABoxFilesystemNode &node);
~ABoxFilesystemNode();
virtual String displayName() const { return _displayName; }
virtual String name() const { return _displayName; }
virtual String name() const { return _displayName; };
virtual bool isValid() const { return _isValid; }
virtual bool isDirectory() const { return _isDirectory; }
virtual String path() const { return _path; }
@ -54,7 +61,7 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
static AbstractFSList listRoot();
virtual AbstractFilesystemNode *parent() const;
virtual AbstractFilesystemNode *child(const String &n) const;
virtual AbstractFilesystemNode *child(const String &name) const;
};
@ -62,6 +69,10 @@ AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
return new ABoxFilesystemNode(path);
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot()
{
return new ABoxFilesystemNode();
@ -83,28 +94,29 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
_lock = NULL;
for (;;)
{
char n[bufsize];
if (NameFromLock(lock, n, bufsize) != DOSFALSE)
char name[bufsize];
if (NameFromLock(lock, name, bufsize) != DOSFALSE)
{
_path = n;
_displayName = display_name ? display_name : FilePart(n);
_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());
debug(6, "Error while retrieving path name: %ld", IoErr());
return;
}
bufsize *= 2;
}
_isDirectory = false;
_isValid = false;
FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL);
if (fib == NULL)
{
warning("Failed to allocate memory for FileInfoBlock");
debug(6, "Failed to allocate memory for FileInfoBlock");
return;
}
@ -119,11 +131,79 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
_isValid = (_lock != NULL);
}
else
{
_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);
}
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)
@ -136,10 +216,15 @@ ABoxFilesystemNode::~ABoxFilesystemNode()
bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
{
if (!_isValid)
error("listDir() called on invalid node");
{
debug(6, "listDir() called on invalid node");
return false;
}
if (!_isDirectory)
error("listDir() called on file node");
{
debug(6, "listDir() called on file node");
return false;
}
if (_lock == NULL)
{
@ -153,7 +238,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
if (fib == NULL)
{
warning("Failed to allocate memory for FileInfoBlock");
debug(6, "Failed to allocate memory for FileInfoBlock");
return false;
}
@ -165,7 +250,8 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
String full_path;
BPTR lock;
if ((fib->fib_EntryType > 0 && (mode & FilesystemNode::kListDirectoriesOnly)) ||
if ((mode == FilesystemNode::kListAll) ||
(fib->fib_EntryType > 0 && (mode & FilesystemNode::kListDirectoriesOnly)) ||
(fib->fib_EntryType < 0 && (mode & FilesystemNode::kListFilesOnly)))
{
full_path = _path;
@ -173,7 +259,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
lock = Lock(full_path.c_str(), SHARED_LOCK);
if (lock)
{
entry = new ABoxFilesystemNode(lock);
entry = new ABoxFilesystemNode(lock, fib->fib_FileName);
if (entry)
{
if (entry->isValid())
@ -187,12 +273,12 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
}
if (IoErr() != ERROR_NO_MORE_ENTRIES)
warning("Error while reading directory: %d", IoErr());
debug(6, "Error while reading directory: %ld", IoErr());
}
FreeDosObject(DOS_FIB, fib);
return tree;
return true;
}
AbstractFilesystemNode *ABoxFilesystemNode::parent() const
@ -200,11 +286,14 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
AbstractFilesystemNode *node = NULL;
if (!_isDirectory)
error("parent() called on file node");
{
debug(6, "parent() called on file node");
return NULL;
}
if (_lock == NULL) {
/* Parent of the root is the root itself */
node = 0;
return new ABoxFilesystemNode(*this);
} else {
BPTR parent_lock = ParentDir(_lock);
if (parent_lock) {
@ -217,8 +306,24 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
return node;
}
AbstractFilesystemNode *ABoxFilesystemNode::child(const String &n) const {
TODO
AbstractFilesystemNode *ABoxFilesystemNode::child(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);
}
AbstractFSList ABoxFilesystemNode::listRoot()
@ -226,12 +331,11 @@ AbstractFSList ABoxFilesystemNode::listRoot()
AbstractFSList myList;
DosList *dosList;
CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
char n[256];
char name[256];
dosList = LockDosList(lockDosListFlags);
if (dosList == NULL)
{
warning("Could not lock dos list");
return myList;
}
@ -248,13 +352,13 @@ AbstractFSList ABoxFilesystemNode::listRoot()
CONST_STRPTR device_name = (CONST_STRPTR)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;
BPTR volume_lock;
strcpy(n, volume_name);
strcat(n, ":");
volume_lock = Lock(n, SHARED_LOCK);
strcpy(name, volume_name);
strcat(name, ":");
volume_lock = Lock(name, SHARED_LOCK);
if (volume_lock)
{
sprintf(n, "%s (%s)", volume_name, device_name);
entry = new ABoxFilesystemNode(volume_lock, n);
sprintf(name, "%s (%s)", volume_name, device_name);
entry = new ABoxFilesystemNode(volume_lock, name);
if (entry)
{
if (entry->isValid())