diff --git a/backends/fs/amigaos/amigaos-fs.cpp b/backends/fs/amigaos/amigaos-fs.cpp index 5f1ed71da09..3f8f205c285 100644 --- a/backends/fs/amigaos/amigaos-fs.cpp +++ b/backends/fs/amigaos/amigaos-fs.cpp @@ -27,20 +27,19 @@ #include "common/debug.h" #include "common/util.h" -#define ENTER() /* debug(6, "Enter") */ -#define LEAVE() /* debug(6, "Leave") */ - /** - * Returns the last component of a given path. + * Returns the last component of a given path * - * @param str Common::String containing the path. - * @return Pointer to the first char of the last component inside str. + * @param str Common::String containing the path + * @return Pointer to the first char of the last component inside str */ + const char *lastPathComponent(const Common::String &str) { + int offset = str.size(); if (offset <= 0) { - debug(6, "Bad offset!"); + debug(6, "lastPathComponent() failed -> Bad offset!"); return 0; } @@ -56,23 +55,22 @@ const char *lastPathComponent(const Common::String &str) { } AmigaOSFilesystemNode::AmigaOSFilesystemNode() { - ENTER(); + _sDisplayName = "Available HDDs/Partitions"; _bIsValid = true; _bIsDirectory = true; _sPath = ""; _pFileLock = 0; - _nProt = 0; // Protection is ignored for the root volume. - LEAVE(); + // Protection is ignored for the root volume + _nProt = 0; } AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) { - ENTER(); int offset = p.size(); if (offset <= 0) { - debug(6, "Bad offset!"); + debug(6, "AmigaOSFileSystemNode() failed -> Bad offset!"); return; } @@ -82,56 +80,40 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) { _bIsDirectory = false; _bIsValid = false; - // WORKAROUND: - // This is a workaround for a bug present in AmigaOS - // newlib.library 53.30 and lower. - // It will be removed once a fixed version of said library is - // available to the public. - // DESCRIPTION: - // We need to explicitly open dos.library and it's IDOS interface. - // Otherwise it will hit a NULL pointer with a shared binary build. - // The hit will happen on loading a game from any engine, if - // more than one engine (shared) plugin is available. - DOSBase = IExec->OpenLibrary("dos.library", 0); - IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL); - - // Check whether the node exists and if it's a directory. + // Check whether the node exists and if it's a directory struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_StringNameInput,_sPath.c_str(),TAG_END); + if (pExd) { + _nProt = pExd->Protection; + if (EXD_IS_DIRECTORY(pExd)) { + _bIsDirectory = true; _pFileLock = IDOS->Lock((CONST_STRPTR)_sPath.c_str(), SHARED_LOCK); _bIsValid = (_pFileLock != 0); - - // Add a trailing slash, if needed. + // Add a trailing slash, if needed const char c = _sPath.lastChar(); if (c != '/' && c != ':') _sPath += '/'; } else { - //_bIsDirectory = false; + _bIsDirectory = false; _bIsValid = true; } IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); } - - // WORKAROUND: - // Close dos.library and its IDOS interface again. - IExec->DropInterface((struct Interface *)IDOS); - IExec->CloseLibrary(DOSBase); - - LEAVE(); } AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName) { - ENTER(); + int bufSize = MAXPATHLEN; _pFileLock = 0; while (true) { char *n = new char[bufSize]; if (IDOS->NameFromLock(pLock, (STRPTR)n, bufSize) != DOSFALSE) { + _sPath = n; _sDisplayName = pDisplayName ? pDisplayName : IDOS->FilePart((STRPTR)n); delete[] n; @@ -139,9 +121,9 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam } if (IDOS->IoErr() != ERROR_LINE_TOO_LONG) { + _bIsValid = false; - debug(6, "IDOS->IoErr() failed - ERROR_LINE_TOO_LONG not matched!"); - LEAVE(); + debug(6, "IDOS->IoErr() failed -> ERROR_LINE_TOO_LONG not matched!"); delete[] n; return; } @@ -153,90 +135,73 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam _bIsDirectory = false; _bIsValid = false; - // Check whether the node exists and if it's a directory. + // Check whether the node exists and if it's a directory struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_FileLockInput,pLock,TAG_END); + if (pExd) { + _nProt = pExd->Protection; + if (EXD_IS_DIRECTORY(pExd)) { + _bIsDirectory = true; _pFileLock = IDOS->DupLock(pLock); _bIsValid = _pFileLock != 0; - // Add a trailing slash, if needed. + // Add a trailing slash, if needed const char c = _sPath.lastChar(); if (c != '/' && c != ':') _sPath += '/'; } else { - //_bIsDirectory = false; _bIsValid = true; } - IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); - } else { - debug(6, "IDOS->ExamineData() failed - ExamineDosObject returned NULL!"); - } + IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); - LEAVE(); + } else { + + debug(6, "IDOS->ExamineObjectTags() failed -> ExamineDosObject returned NULL!"); + } } -// We need the custom copy constructor because of DupLock(). +// We need the custom copy constructor because of DupLock() AmigaOSFilesystemNode::AmigaOSFilesystemNode(const AmigaOSFilesystemNode& node) : AbstractFSNode() { - ENTER(); + _sDisplayName = node._sDisplayName; _bIsValid = node._bIsValid; _bIsDirectory = node._bIsDirectory; _sPath = node._sPath; _pFileLock = IDOS->DupLock(node._pFileLock); _nProt = node._nProt; - LEAVE(); } AmigaOSFilesystemNode::~AmigaOSFilesystemNode() { - ENTER(); + if (_pFileLock) IDOS->UnLock(_pFileLock); - LEAVE(); } bool AmigaOSFilesystemNode::exists() const { - ENTER(); + if (_sPath.empty()) return false; bool nodeExists = false; - // Previously we were trying to examine the node in order - // to determine if the node exists or not. - // I don't see the point : once you have been granted a - // lock on it, it means it exists... - // - // ============================= Old code - // BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); - // if (pLock) - // { - // if (IDOS->Examine(pLock, fib) != DOSFALSE) - // nodeExists = true; - // IDOS->UnLock(pLock); - // } - // - // IDOS->FreeDosObject(DOS_FIB, fib); - // - // ============================= New code BPTR pLock = IDOS->Lock(_sPath.c_str(), SHARED_LOCK); if (pLock) { nodeExists = true; IDOS->UnLock(pLock); } - LEAVE(); return nodeExists; } AbstractFSNode *AmigaOSFilesystemNode::getChild(const Common::String &n) const { - ENTER(); + if (!_bIsDirectory) { - debug(6, "Not a directory!"); + debug(6, "AmigaOSFileSystemNode::getChild() failed -> Not a directory!"); return 0; } @@ -246,52 +211,50 @@ AbstractFSNode *AmigaOSFilesystemNode::getChild(const Common::String &n) const { newPath += '/'; newPath += n; - - LEAVE(); return new AmigaOSFilesystemNode(newPath); } bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { - ENTER(); - bool ret = false; if (!_bIsValid) { - debug(6, "Invalid node!"); - LEAVE(); - return false; // Empty list + debug(6, "AmigaOSFileSystemNode::getChildren() failed -> Invalid node (Empty list)!"); + return false; } if (!_bIsDirectory) { - debug(6, "Not a directory!"); - LEAVE(); - return false; // Empty list + debug(6, "AmigaOSFileSystemNode::getChildren() failed -> Invalid node (Not a directory)!"); + return false; } if (isRootNode()) { - debug(6, "Root node!"); - LEAVE(); + debug(6, "AmigaOSFileSystemNode::getChildren() -> Root node obtained!"); myList = listVolumes(); return true; } - APTR context = IDOS->ObtainDirContextTags( EX_FileLockInput, _pFileLock, - EX_DoCurrentDir, TRUE, /* for softlinks */ - EX_DataFields, (EXF_NAME|EXF_LINK|EXF_TYPE), + APTR context = IDOS->ObtainDirContextTags( EX_FileLockInput, _pFileLock, + EX_DoCurrentDir, TRUE, /* for softlinks */ + EX_DataFields, (EXF_NAME|EXF_LINK|EXF_TYPE), TAG_END); + if (context) { - // No need to free the value after usage, everything will be dealt with by the DirContext release. + + // No need to free the value after usage, everything will be dealt with by the + // DirContext release struct ExamineData * pExd = NULL; AmigaOSFilesystemNode *entry; - while ( (pExd = IDOS->ExamineDir(context)) ) { - if ( (EXD_IS_FILE(pExd) && ( Common::FSNode::kListFilesOnly == mode )) - || (EXD_IS_DIRECTORY(pExd) && ( Common::FSNode::kListDirectoriesOnly == mode )) - || Common::FSNode::kListAll == mode - ) + + while ((pExd = IDOS->ExamineDir(context))) { + if ((EXD_IS_FILE(pExd) && (Common::FSNode::kListFilesOnly == mode)) + || (EXD_IS_DIRECTORY(pExd) && (Common::FSNode::kListDirectoriesOnly == mode)) + || Common::FSNode::kListAll == mode) { BPTR pLock = IDOS->Lock( pExd->Name, SHARED_LOCK ); + if (pLock) { entry = new AmigaOSFilesystemNode( pLock, pExd->Name ); + if (entry) { myList.push_back(entry); } @@ -302,30 +265,23 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b } if (ERROR_NO_MORE_ENTRIES != IDOS->IoErr() ) { - debug(6, "IDOS->IoErr() failed - ERROR_NO_MORE_ENTRIES!"); - ret = false; - } else { - ret = true; + debug(6, "IDOS->IoErr() failed -> ERROR_NO_MORE_ENTRIES not matched!"); + return false; } - IDOS->ReleaseDirContext(context); + return true; + } else { debug(6, "IDOS->ObtainDirContext() failed!"); - ret = false; + return false; } - - LEAVE(); - - return ret; } AbstractFSNode *AmigaOSFilesystemNode::getParent() const { - ENTER(); if (isRootNode()) { - debug(6, "Root node!"); - LEAVE(); + debug(6, "AmigaOSFileSystemNode::getParent() -> Root node obtained!"); return new AmigaOSFilesystemNode(*this); } @@ -340,6 +296,7 @@ AbstractFSNode *AmigaOSFilesystemNode::getParent() const { AmigaOSFilesystemNode *node; BPTR parentDir = IDOS->ParentDir( pLock ); + if (parentDir) { node = new AmigaOSFilesystemNode(parentDir); IDOS->UnLock(parentDir); @@ -350,91 +307,72 @@ AbstractFSNode *AmigaOSFilesystemNode::getParent() const { IDOS->UnLock(pLock); } - LEAVE(); - return node; + } bool AmigaOSFilesystemNode::isReadable() const { + if (!_bIsValid) return false; // Regular RWED protection flags are low-active or inverted, // thus the negation. Moreover, a pseudo root filesystem is - // readable whatever the protection says. + // always readable, whatever the protection says bool readable = !(_nProt & EXDF_OTR_READ) || isRootNode(); - return readable; } bool AmigaOSFilesystemNode::isWritable() const { + if (!_bIsValid) return false; // Regular RWED protection flags are low-active or inverted, // thus the negation. Moreover, a pseudo root filesystem is - // never writable whatever the protection says. - // (Because of it's pseudo nature). + // never writable (due of it's pseudo nature), whatever the protection says bool writable = !(_nProt & EXDF_OTR_WRITE) && !isRootNode(); - return writable; } AbstractFSList AmigaOSFilesystemNode::listVolumes() const { - ENTER(); AbstractFSList myList; - const uint32 kLockFlags = LDF_READ | LDF_VOLUMES; char buffer[MAXPATHLEN]; struct DosList *dosList = IDOS->LockDosList(kLockFlags); + if (!dosList) { debug(6, "IDOS->LockDOSList() failed!"); - LEAVE(); return myList; } dosList = IDOS->NextDosEntry(dosList, LDF_VOLUMES); + while (dosList) { if (dosList->dol_Type == DLT_VOLUME && dosList->dol_Name && dosList->dol_Port) { - // The original line was - // - // if (dosList->dol_Type == DLT_VOLUME && - // dosList->dol_Name && - // dosList->dol_Task) { - // - // which errored using SDK 53.24 with a - // 'struct dosList' has no member called 'dol_Task' - // The reason for that was, that - // 1) dol_Task wasn't a task pointer, it was a message port instead. - // 2) it was redefined to be dol_Port in dos/obsolete.h in aforementioned SDK. - - // Copy name to buffer. + // Copy name to buffer IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN); - // Volume name + '\0'. + // Volume name + '\0' char *volName = new char [strlen(buffer) + 1]; strcpy(volName, buffer); - strcat(buffer, ":"); BPTR volumeLock = IDOS->Lock((STRPTR)buffer, SHARED_LOCK); - if (volumeLock) { + if (volumeLock) { char *devName = new char [MAXPATHLEN]; - // Find device name. + // Find device name IDOS->DevNameFromLock(volumeLock, devName, MAXPATHLEN, DN_DEVICEONLY); - snprintf(buffer, MAXPATHLEN, "%s (%s)", volName, devName); - delete[] devName; - AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(volumeLock, buffer); if (entry) { myList.push_back(entry); @@ -442,7 +380,6 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { IDOS->UnLock(volumeLock); } - delete[] volName; } dosList = IDOS->NextDosEntry(dosList, LDF_VOLUMES); @@ -450,34 +387,20 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { IDOS->UnLockDosList(kLockFlags); - LEAVE(); - return myList; } Common::SeekableReadStream *AmigaOSFilesystemNode::createReadStream() { - StdioStream *readStream = StdioStream::makeFromPath(getPath(), false); - - // - // Work around for possibility that someone uses AmigaOS "newlib" build - // with SmartFileSystem (blocksize 512 bytes), leading to buffer size - // being only 512 bytes. "Clib2" sets the buffer size to 8KB, resulting - // smooth movie playback. This forces the buffer to be enough also when - // using "newlib" compile on SFS. - // - if (readStream) { - readStream->setBufferSize(8192); - } - - return readStream; + return StdioStream::makeFromPath(getPath(), false); } + Common::WriteStream *AmigaOSFilesystemNode::createWriteStream() { return StdioStream::makeFromPath(getPath(), true); } bool AmigaOSFilesystemNode::createDirectory() { - warning("AmigaOSFilesystemNode::createDirectory(): Not supported"); + warning("AmigaOSFilesystemNode::createDirectory() -> Not supported"); return _bIsValid && _bIsDirectory; }