diff options
author | Max Horn | 2009-09-25 09:57:38 +0000 |
---|---|---|
committer | Max Horn | 2009-09-25 09:57:38 +0000 |
commit | 3c8500c14966d8e1b49918056ff1fc9128ae4ea9 (patch) | |
tree | b2735c8166e0c2b28b8dc1a76d1edfd653db5b5c /backends/fs | |
parent | e296cef9becef7e890cd1ce33d1b0ae23007a784 (diff) | |
download | scummvm-rg350-3c8500c14966d8e1b49918056ff1fc9128ae4ea9.tar.gz scummvm-rg350-3c8500c14966d8e1b49918056ff1fc9128ae4ea9.tar.bz2 scummvm-rg350-3c8500c14966d8e1b49918056ff1fc9128ae4ea9.zip |
Patch #2856708: AMIGAOS4: FS updated to new SDK
svn-id: r44338
Diffstat (limited to 'backends/fs')
-rw-r--r-- | backends/fs/amigaos4/amigaos4-fs.cpp | 285 |
1 files changed, 112 insertions, 173 deletions
diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp index 7f1e01dcb9..183558409e 100644 --- a/backends/fs/amigaos4/amigaos4-fs.cpp +++ b/backends/fs/amigaos4/amigaos4-fs.cpp @@ -43,8 +43,6 @@ #define ENTER() /* debug(6, "Enter") */ #define LEAVE() /* debug(6, "Leave") */ -const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure? - /** * Implementation of the ScummVM file system API. * @@ -57,38 +55,41 @@ protected: Common::String _sPath; bool _bIsDirectory; bool _bIsValid; + uint32 _nProt; /** - * Obtain the FileInfoBlock protection value for this FSNode, - * as defined in the <proto/dos.h> header. - * - * @return -1 if there were errors, 0 or a positive integer otherwise. + * Creates a list with all the volumes present in the root node. */ - virtual int getFibProtection() const; + virtual AbstractFSList listVolumes() const; public: /** - * Creates a AmigaOSFilesystemNode with the root node as path. + * Creates an AmigaOSFilesystemNode with the root node as path. */ AmigaOSFilesystemNode(); /** - * Creates a AmigaOSFilesystemNode for a given path. + * Creates an AmigaOSFilesystemNode for a given path. * * @param path Common::String with the path the new node should point to. */ AmigaOSFilesystemNode(const Common::String &p); /** - * FIXME: document this constructor. + * Creates an AmigaOSFilesystemNode given its lock and display name + * + * @param pLock BPTR to the lock. + * @param pDisplayName name to be used for display, in case not supplied the FilePart() of the filename will be used. + * + * @note This shouldn't even be public as it's only internally, at best it should have been protected if not private */ AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0); - /** - * Copy constructor. - * - * @note Needed because it duplicates the file lock - */ + /** + * Copy constructor. + * + * @note Needed because it duplicates the file lock + */ AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node); /** @@ -110,11 +111,6 @@ public: virtual Common::SeekableReadStream *createReadStream(); virtual Common::WriteStream *createWriteStream(); - - /** - * Creates a list with all the volumes present in the root node. - */ - virtual AbstractFSList listVolumes() const; }; /** @@ -149,6 +145,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode() { _bIsDirectory = true; _sPath = ""; _pFileLock = 0; + _nProt = 0; // protection is ignored for the root volume LEAVE(); } @@ -169,37 +166,28 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const Common::String &p) { _pFileLock = 0; _bIsDirectory = false; - struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); - if (!fib) { - debug(6, "FileInfoBlock is NULL"); - LEAVE(); - return; - } - // Check whether the node exists and if it is a directory - BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); - if (pLock) { - if (IDOS->Examine(pLock, fib) != DOSFALSE) { - if (FIB_IS_DRAWER(fib)) { - _bIsDirectory = true; - _pFileLock = IDOS->DupLock(pLock); - _bIsValid = (_pFileLock != 0); - - // Add a trailing slash if it is needed - const char c = _sPath.lastChar(); - if (c != '/' && c != ':') - _sPath += '/'; - } - else { - //_bIsDirectory = false; - _bIsValid = true; - } + 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 it is needed + const char c = _sPath.lastChar(); + if (c != '/' && c != ':') + _sPath += '/'; + } + else { + //_bIsDirectory = false; + _bIsValid = true; } - IDOS->UnLock(pLock); + IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); } - IDOS->FreeDosObject(DOS_FIB, fib); LEAVE(); } @@ -232,15 +220,10 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam _bIsValid = false; _bIsDirectory = false; - struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); - if (!fib) { - debug(6, "FileInfoBlock is NULL"); - LEAVE(); - return; - } - - if (IDOS->Examine(pLock, fib) != DOSFALSE) { - if (FIB_IS_DRAWER(fib)) { + 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; @@ -253,20 +236,26 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam //_bIsDirectory = false; _bIsValid = true; } + + IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd); } + else { + debug(6, "ExamineObject() returned NULL"); + } - IDOS->FreeDosObject(DOS_FIB, fib); LEAVE(); } // We need the custom copy constructor because of DupLock() -AmigaOSFilesystemNode::AmigaOSFilesystemNode(const AmigaOSFilesystemNode& node) { +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(); } @@ -284,21 +273,29 @@ bool AmigaOSFilesystemNode::exists() const { bool nodeExists = false; - struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); - if (!fib) { - debug(6, "FileInfoBlock is NULL"); - LEAVE(); - return false; - } - - BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); + // 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 then 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) { - if (IDOS->Examine(pLock, fib) != DOSFALSE) - nodeExists = true; + nodeExists = true; IDOS->UnLock(pLock); } - IDOS->FreeDosObject(DOS_FIB, fib); LEAVE(); return nodeExists; } @@ -323,8 +320,10 @@ AbstractFSNode *AmigaOSFilesystemNode::getChild(const Common::String &n) const { bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { ENTER(); + bool ret = false; //TODO: honor the hidden flag + // There is nothing like a hidden flag under AmigaOS... if (!_bIsValid) { debug(6, "Invalid node"); @@ -345,85 +344,50 @@ bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, b return true; } - struct ExAllControl *eac = (struct ExAllControl *)IDOS->AllocDosObject(DOS_EXALLCONTROL, 0); - if (eac) { - struct ExAllData *data = (struct ExAllData *)IExec->AllocVec(kExAllBufferSize, MEMF_ANY); - if (data) { - BOOL bExMore; - eac->eac_LastKey = 0; - do { - // Examine directory - bExMore = IDOS->ExAll(_pFileLock, data, kExAllBufferSize, ED_TYPE, eac); - - LONG error = IDOS->IoErr(); - if (!bExMore && error != ERROR_NO_MORE_ENTRIES) - break; // Abnormal failure - - if (eac->eac_Entries == 0) - continue; // Normal failure, no entries - - struct ExAllData *ead = data; - do { - if ((mode == Common::FSNode::kListAll) || - (EAD_IS_DRAWER(ead) && (mode == Common::FSNode::kListDirectoriesOnly)) || - (EAD_IS_FILE(ead) && (mode == Common::FSNode::kListFilesOnly))) { - Common::String full_path = _sPath; - full_path += (char*)ead->ed_Name; - - BPTR lock = IDOS->Lock((STRPTR)full_path.c_str(), SHARED_LOCK); - if (lock) { - AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(lock, (char *)ead->ed_Name); - if (entry) { - //FIXME: since the isValid() function is no longer part of the AbstractFSNode - // specification, the following call had to be changed: - // if (entry->isValid()) - // Please verify that the logic of the code remains coherent. Also, remember - // that the isReadable() and isWritable() methods are available. - if (entry->exists()) - myList.push_back(entry); - else - delete entry; - } - IDOS->UnLock(lock); - } + APTR context = IDOS->ObtainDirContextTags( EX_FileLockInput, _pFileLock, + EX_DoCurrentDir, TRUE, /* for softlinks */ + EX_DataFields, (EXF_NAME|EXF_LINK|EXF_TYPE), + TAG_END); + if (context) { + struct ExamineData * pExd = NULL; // NB: no need to free value after usage, all is dealt by the DirContext release + + 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 + ) + { + BPTR pLock = IDOS->Lock( pExd->Name, SHARED_LOCK ); + if( pLock ) { + entry = new AmigaOSFilesystemNode( pLock, pExd->Name ); + if( entry ) { + myList.push_back(entry); } - ead = ead->ed_Next; - } while (ead); - } while (bExMore); - IExec->FreeVec(data); + IDOS->UnLock(pLock); + } + } + } + if( ERROR_NO_MORE_ENTRIES != IDOS->IoErr() ) { + debug(6, "An error occured during ExamineDir"); + ret = false; + } + else { + ret = true; } - IDOS->FreeDosObject(DOS_EXALLCONTROL, eac); - } - - LEAVE(); - - return true; -} - -int AmigaOSFilesystemNode::getFibProtection() const { - ENTER(); - int fibProt = -1; - struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL); - if (!fib) { - debug(6, "FileInfoBlock is NULL"); - LEAVE(); - return fibProt; + IDOS->ReleaseDirContext(context); } - - BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK); - if (pLock) { - if (IDOS->Examine(pLock, fib) != DOSFALSE) { - fibProt = fib->fib_Protection; - } - IDOS->UnLock(pLock); + else { + debug(6, "Unable to ObtainDirContext"); + ret = false; } - IDOS->FreeDosObject(DOS_FIB, fib); LEAVE(); - return fibProt; + + return ret; } AbstractFSNode *AmigaOSFilesystemNode::getParent() const { @@ -457,38 +421,24 @@ AbstractFSNode *AmigaOSFilesystemNode::getParent() const { } bool AmigaOSFilesystemNode::isReadable() const { - bool readable = false; - int fibProt = getFibProtection(); - - if (fibProt >= 0) { - /* The fib_Protection flag is low-active or inverted, thus the negation. - * - * For more information, consult the compiler/include/dos/dos.h - * file from the AROS source (http://aros.sourceforge.net/). - */ - readable = !(fibProt & FIBF_READ); - } + // Regular RWED protection flags are low-active or inverted, thus the negation. + // moreover pseudo root filesystem (null _pFileLock) is readable whatever the + // protection says + bool readable = !(_nProt & EXDF_READ) || _pFileLock == 0; return readable; } bool AmigaOSFilesystemNode::isWritable() const { - bool writable = false; - int fibProt = getFibProtection(); - - if (fibProt >= 0) { - /* The fib_Protection flag is low-active or inverted, thus the negation. - * - * For more information, consult the compiler/include/dos/dos.h - * file from the AROS source (http://aros.sourceforge.net/). - */ - writable = !(fibProt & FIBF_WRITE); - } + // Regular RWED protection flags are low-active or inverted, thus the negation. + // moreover pseudo root filesystem (null _pFileLock) is never writable whatever + // the protection says (because of the pseudo nature) + bool writable = !(_nProt & EXDF_WRITE) && _pFileLock !=0; return writable; } -AbstractFSList AmigaOSFilesystemNode::listVolumes() const { +AbstractFSList AmigaOSFilesystemNode::listVolumes() const { ENTER(); AbstractFSList myList; @@ -508,13 +458,10 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { if (dosList->dol_Type == DLT_VOLUME && dosList->dol_Name && dosList->dol_Task) { - //const char *volName = (const char *)BADDR(dosList->dol_Name)+1; // Copy name to buffer IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN); - //const char *devName = (const char *)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name; - // Volume name + '\0' char *volName = new char [strlen(buffer) + 1]; @@ -536,15 +483,7 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(volumeLock, buffer); if (entry) { - //FIXME: since the isValid() function is no longer part of the AbstractFSNode - // specification, the following call had to be changed: - // if (entry->isValid()) - // Please verify that the logic of the code remains coherent. Also, remember - // that the isReadable() and isWritable() methods are available. - if(entry->exists()) - myList.push_back(entry); - else - delete entry; + myList.push_back(entry); } IDOS->UnLock(volumeLock); |