From fb795dabd04392fe87a24da6bb5fb28ab4fc6c2c Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 12 Nov 2006 11:43:46 +0000 Subject: Patch #1594533: morphos fs backend svn-id: r24690 --- backends/fs/morphos/abox-fs.cpp | 160 +++++++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 28 deletions(-) (limited to 'backends') diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp index 17b6879f5e..e88eb19c00 100644 --- a/backends/fs/morphos/abox-fs.cpp +++ b/backends/fs/morphos/abox-fs.cpp @@ -24,8 +24,12 @@ #include #include +#include -#include "engines/engine.h" +#include + +#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()) -- cgit v1.2.3