Ticket #9081: AmigaOS4.diff

File AmigaOS4.diff, 12.6 KB (added by raziel-, 11 years ago)

New diff file respecting the coding conventions

  • backends/fs/amigaos4/amigaos4-fs.cpp

     
    4343#define ENTER() /* debug(6, "Enter") */
    4444#define LEAVE() /* debug(6, "Leave") */
    4545
    46 const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure?
    47 
    4846/**
    4947 * Implementation of the ScummVM file system API.
    5048 *
     
    5755        Common::String _sPath;
    5856        bool _bIsDirectory;
    5957        bool _bIsValid;
     58        uint32 _nProt;
    6059
    6160        /**
    62          * Obtain the FileInfoBlock protection value for this FSNode,
    63          * as defined in the <proto/dos.h> header.
    64          *
    65          * @return -1 if there were errors, 0 or a positive integer otherwise.
     61         * Creates a list with all the volumes present in the root node.
    6662         */
    67         virtual int getFibProtection() const;
     63        virtual AbstractFSList listVolumes() const;
    6864
    6965public:
    7066        /**
    71          * Creates a AmigaOSFilesystemNode with the root node as path.
     67         * Creates an AmigaOSFilesystemNode with the root node as path.
    7268         */
    7369        AmigaOSFilesystemNode();
    7470
    7571        /**
    76          * Creates a AmigaOSFilesystemNode for a given path.
     72         * Creates an AmigaOSFilesystemNode for a given path.
    7773         *
    7874         * @param path Common::String with the path the new node should point to.
    7975         */
    8076        AmigaOSFilesystemNode(const Common::String &p);
    8177
    8278        /**
    83          * FIXME: document this constructor.
     79         * Creates an AmigaOSFilesystemNode given its lock and display name
     80         *
     81         * @param pLock BPTR to the lock.
     82         * @param pDisplayName name to be used for display, in case not supplied the FilePart() of the filename will be used.
     83         *
     84         * @note This shouldn't even be public as it's only internally, at best it should have been protected if not private
    8485         */
    8586        AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0);
    8687
    87     /**
    88     * Copy constructor.
    89     *
    90     * @note Needed because it duplicates the file lock
    91     */
     88        /**
     89        * Copy constructor.
     90        *
     91        * @note Needed because it duplicates the file lock
     92        */
    9293        AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node);
    9394
    9495        /**
     
    110111
    111112        virtual Common::SeekableReadStream *createReadStream();
    112113        virtual Common::WriteStream *createWriteStream();
    113 
    114         /**
    115          * Creates a list with all the volumes present in the root node.
    116          */
    117         virtual AbstractFSList listVolumes() const;
    118114};
    119115
    120116/**
     
    149145        _bIsDirectory = true;
    150146        _sPath = "";
    151147        _pFileLock = 0;
     148        _nProt = 0; // protection is ignored for the root volume
    152149        LEAVE();
    153150}
    154151
     
    169166        _pFileLock = 0;
    170167        _bIsDirectory = false;
    171168
    172         struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL);
    173         if (!fib) {
    174                 debug(6, "FileInfoBlock is NULL");
    175                 LEAVE();
    176                 return;
    177         }
    178 
    179169        // Check whether the node exists and if it is a directory
    180         BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK);
    181         if (pLock) {
    182                 if (IDOS->Examine(pLock, fib) != DOSFALSE) {
    183                         if (FIB_IS_DRAWER(fib)) {
    184                                 _bIsDirectory = true;
    185                                 _pFileLock = IDOS->DupLock(pLock);
    186                                 _bIsValid = (_pFileLock != 0);
     170        struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_StringNameInput,_sPath.c_str(),TAG_END);
     171        if (pExd) {
     172                _nProt = pExd->Protection;
     173                if (EXD_IS_DIRECTORY(pExd)) {
     174                        _bIsDirectory = true;
     175                        _pFileLock = IDOS->Lock((CONST_STRPTR)_sPath.c_str(), SHARED_LOCK);;
     176                        _bIsValid = (_pFileLock != 0);
    187177
    188                                 // Add a trailing slash if it is needed
    189                                 const char c = _sPath.lastChar();
    190                                 if (c != '/' && c != ':')
    191                                         _sPath += '/';
    192                         }
    193                         else {
    194                                 //_bIsDirectory = false;
    195                                 _bIsValid = true;
    196                         }
     178                        // Add a trailing slash if it is needed
     179                        const char c = _sPath.lastChar();
     180                        if (c != '/' && c != ':')
     181                                _sPath += '/';
    197182                }
     183                else {
     184                        //_bIsDirectory = false;
     185                        _bIsValid = true;
     186                }
    198187
    199                 IDOS->UnLock(pLock);
     188                IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd);
    200189        }
    201190
    202         IDOS->FreeDosObject(DOS_FIB, fib);
    203191        LEAVE();
    204192}
    205193
     
    232220        _bIsValid =     false;
    233221        _bIsDirectory = false;
    234222
    235         struct FileInfoBlock *fib = (struct     FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL);
    236         if (!fib) {
    237                 debug(6, "FileInfoBlock is NULL");
    238                 LEAVE();
    239                 return;
    240         }
    241 
    242         if (IDOS->Examine(pLock, fib) != DOSFALSE) {
    243                 if (FIB_IS_DRAWER(fib)) {
     223        struct ExamineData * pExd = IDOS->ExamineObjectTags(EX_FileLockInput,pLock,TAG_END);
     224        if (pExd) {
     225                _nProt = pExd->Protection;
     226                if (EXD_IS_DIRECTORY(pExd)) {
    244227                        _bIsDirectory = true;
    245228                        _pFileLock = IDOS->DupLock(pLock);
    246229                        _bIsValid = _pFileLock != 0;
     
    253236                        //_bIsDirectory = false;
    254237                        _bIsValid = true;
    255238                }
     239
     240        IDOS->FreeDosObject(DOS_EXAMINEDATA, pExd);
    256241        }
     242        else {
     243                debug(6, "ExamineObject() returned NULL");
     244    }
    257245
    258         IDOS->FreeDosObject(DOS_FIB, fib);
    259246        LEAVE();
    260247}
    261248
    262249// We need the custom copy constructor because of DupLock()
    263 AmigaOSFilesystemNode::AmigaOSFilesystemNode(const AmigaOSFilesystemNode& node) {
     250AmigaOSFilesystemNode::AmigaOSFilesystemNode(const AmigaOSFilesystemNode& node)
     251: AbstractFSNode() {
    264252        ENTER();
    265253        _sDisplayName = node._sDisplayName;
    266254        _bIsValid = node._bIsValid;
    267255        _bIsDirectory = node._bIsDirectory;
    268256        _sPath = node._sPath;
    269257        _pFileLock = IDOS->DupLock(node._pFileLock);
     258        _nProt = node._nProt;
    270259        LEAVE();
    271260}
    272261
     
    284273
    285274        bool nodeExists = false;
    286275
    287         struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL);
    288         if (!fib) {
    289                 debug(6, "FileInfoBlock is NULL");
    290                 LEAVE();
    291                 return false;
    292         }
    293 
    294         BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK);
     276        // previously we were trying to examine the node in order
     277        // to determine if the node exists or not.
     278        // I don't see the point : once you have been granted a
     279        // lock on it then it means it exists...
     280        //
     281        // =============================  Old code
     282        // BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK);
     283        // if (pLock)
     284        // {
     285        //      if (IDOS->Examine(pLock, fib) != DOSFALSE)
     286        //              nodeExists = true;
     287        //      IDOS->UnLock(pLock);
     288        // }
     289        //
     290        // IDOS->FreeDosObject(DOS_FIB, fib);
     291        //
     292        // =============================  New code
     293        BPTR pLock = IDOS->Lock(_sPath.c_str(), SHARED_LOCK);
    295294        if (pLock) {
    296                 if (IDOS->Examine(pLock, fib) != DOSFALSE)
    297                         nodeExists = true;
     295                nodeExists = true;
    298296                IDOS->UnLock(pLock);
    299297        }
    300298
    301         IDOS->FreeDosObject(DOS_FIB, fib);
    302299        LEAVE();
    303300        return nodeExists;
    304301}
     
    323320
    324321bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
    325322        ENTER();
     323        bool ret = false;
    326324
    327325        //TODO: honor the hidden flag
     326        // There is nothing like a hidden flag under AmigaOS...
    328327
    329328        if (!_bIsValid) {
    330329                debug(6, "Invalid node");
     
    345344                return true;
    346345        }
    347346
    348         struct ExAllControl *eac = (struct ExAllControl *)IDOS->AllocDosObject(DOS_EXALLCONTROL, 0);
    349         if (eac) {
    350                 struct ExAllData *data = (struct ExAllData *)IExec->AllocVec(kExAllBufferSize, MEMF_ANY);
    351                 if (data) {
    352                         BOOL bExMore;
    353                         eac->eac_LastKey = 0;
    354                         do {
    355                                 // Examine directory
    356                                 bExMore = IDOS->ExAll(_pFileLock, data, kExAllBufferSize, ED_TYPE, eac);
     347        APTR context = IDOS->ObtainDirContextTags(  EX_FileLockInput,   _pFileLock,
     348                                                                                                EX_DoCurrentDir,        TRUE,  /* for softlinks */
     349                                                                                                EX_DataFields,          (EXF_NAME|EXF_LINK|EXF_TYPE),
     350                                                                                                TAG_END);
     351        if (context) {
     352                struct ExamineData * pExd = NULL; // NB: no need to free value after usage, all is dealt by the DirContext release
    357353
    358                                 LONG error = IDOS->IoErr();
    359                                 if (!bExMore && error != ERROR_NO_MORE_ENTRIES)
    360                                         break; // Abnormal failure
    361 
    362                                 if (eac->eac_Entries == 0)
    363                                         continue; // Normal failure, no entries
    364 
    365                                 struct ExAllData *ead = data;
    366                                 do {
    367                                         if ((mode == Common::FSNode::kListAll) ||
    368                                                 (EAD_IS_DRAWER(ead) && (mode == Common::FSNode::kListDirectoriesOnly)) ||
    369                                                 (EAD_IS_FILE(ead) && (mode == Common::FSNode::kListFilesOnly))) {
    370                                                 Common::String full_path = _sPath;
    371                                                 full_path += (char*)ead->ed_Name;
    372 
    373                                                 BPTR lock = IDOS->Lock((STRPTR)full_path.c_str(), SHARED_LOCK);
    374                                                 if (lock) {
    375                                                         AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(lock, (char *)ead->ed_Name);
    376                                                         if (entry) {
    377                                                                 //FIXME: since the isValid() function is no longer part of the AbstractFSNode
    378                                                                 //       specification, the following call had to be changed:
    379                                                                 //          if (entry->isValid())
    380                                                                 //               Please verify that the logic of the code remains coherent. Also, remember
    381                                                                 //               that the isReadable() and isWritable() methods are available.
    382                                                                 if (entry->exists())
    383                                                                     myList.push_back(entry);
    384                                                                 else
    385                                                                         delete entry;
    386                                                         }
    387                                                         IDOS->UnLock(lock);
    388                                                 }
     354                AmigaOSFilesystemNode *entry ;
     355                while( (pExd = IDOS->ExamineDir(context)) ) {
     356                        if(     (EXD_IS_FILE(pExd) && ( Common::FSNode::kListFilesOnly == mode ))
     357                                ||  (EXD_IS_DIRECTORY(pExd) && ( Common::FSNode::kListDirectoriesOnly == mode ))
     358                                ||  Common::FSNode::kListAll == mode
     359                                )
     360                        {
     361                                BPTR pLock = IDOS->Lock( pExd->Name, SHARED_LOCK );
     362                                if( pLock ) {
     363                                        entry = new AmigaOSFilesystemNode( pLock, pExd->Name );
     364                                        if( entry ) {
     365                                                myList.push_back(entry);
    389366                                        }
    390                                         ead = ead->ed_Next;
    391                                 } while (ead);
    392                         } while (bExMore);
    393367
    394                         IExec->FreeVec(data);
     368                                        IDOS->UnLock(pLock);
     369                                }
     370                        }
    395371                }
     372                if( ERROR_NO_MORE_ENTRIES != IDOS->IoErr() ) {
     373                        debug(6, "An error occured during ExamineDir");
     374                        ret = false;
     375                }
     376                else {
     377                        ret = true;
     378                }
    396379
    397                 IDOS->FreeDosObject(DOS_EXALLCONTROL, eac);
    398         }
    399380
    400         LEAVE();
    401 
    402         return true;
    403 }
    404 
    405 int AmigaOSFilesystemNode::getFibProtection() const {
    406         ENTER();
    407 
    408         int fibProt = -1;
    409         struct FileInfoBlock *fib = (struct FileInfoBlock *)IDOS->AllocDosObject(DOS_FIB, NULL);
    410         if (!fib) {
    411                 debug(6, "FileInfoBlock is NULL");
    412                 LEAVE();
    413                 return fibProt;
     381                IDOS->ReleaseDirContext(context);
    414382        }
    415 
    416         BPTR pLock = IDOS->Lock((STRPTR)_sPath.c_str(), SHARED_LOCK);
    417         if (pLock) {
    418                 if (IDOS->Examine(pLock, fib) != DOSFALSE) {
    419                         fibProt = fib->fib_Protection;
    420                 }
    421                 IDOS->UnLock(pLock);
     383        else {
     384                debug(6, "Unable to ObtainDirContext");
     385                ret = false;
    422386        }
    423387
    424         IDOS->FreeDosObject(DOS_FIB, fib);
    425388        LEAVE();
    426         return fibProt;
     389
     390        return ret;
    427391}
    428392
    429393AbstractFSNode *AmigaOSFilesystemNode::getParent() const {
     
    457421}
    458422
    459423bool AmigaOSFilesystemNode::isReadable() const {
    460         bool readable = false;
    461         int fibProt = getFibProtection();
     424        // Regular RWED protection flags are low-active or inverted, thus the negation.
     425        // moreover pseudo root filesystem (null _pFileLock) is readable whatever the
     426        // protection says
     427        bool readable = !(_nProt & EXDF_READ) || _pFileLock == 0;
    462428
    463         if (fibProt >= 0) {
    464                 /* The fib_Protection flag is low-active or inverted, thus the negation.
    465                  *
    466                  * For more information, consult the compiler/include/dos/dos.h
    467                  * file from the AROS source (http://aros.sourceforge.net/).
    468                  */
    469                 readable = !(fibProt & FIBF_READ);
    470         }
    471 
    472429        return readable;
    473430}
    474431
    475432bool AmigaOSFilesystemNode::isWritable() const {
    476         bool writable = false;
    477         int fibProt = getFibProtection();
     433        // Regular RWED protection flags are low-active or inverted, thus the negation.
     434        // moreover pseudo root filesystem (null _pFileLock) is never writable whatever
     435        // the protection says (because of the pseudo nature)
     436        bool writable = !(_nProt & EXDF_WRITE) && _pFileLock !=0;
    478437
    479         if (fibProt >= 0) {
    480                 /* The fib_Protection flag is low-active or inverted, thus the negation.
    481                  *
    482                  * For more information, consult the compiler/include/dos/dos.h
    483                  * file from the AROS source (http://aros.sourceforge.net/).
    484                  */
    485                 writable = !(fibProt & FIBF_WRITE);
    486         }
    487 
    488438        return writable;
    489439}
    490440
    491 AbstractFSList AmigaOSFilesystemNode::listVolumes()     const {
     441AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
    492442        ENTER();
    493443
    494444        AbstractFSList myList;
     
    508458                if (dosList->dol_Type == DLT_VOLUME &&
    509459                        dosList->dol_Name &&
    510460                        dosList->dol_Task) {
    511                         //const char *volName = (const char *)BADDR(dosList->dol_Name)+1;
    512461
    513462                        // Copy name to buffer
    514463                        IDOS->CopyStringBSTRToC(dosList->dol_Name, buffer, MAXPATHLEN);
    515464
    516                         //const char *devName = (const char *)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;
    517 
    518465                        // Volume name + '\0'
    519466                        char *volName = new char [strlen(buffer) + 1];
    520467
     
    536483
    537484                                AmigaOSFilesystemNode *entry = new AmigaOSFilesystemNode(volumeLock, buffer);
    538485                                if (entry) {
    539                                         //FIXME: since the isValid() function is no longer part of the AbstractFSNode
    540                                         //       specification, the following call had to be changed:
    541                                         //          if (entry->isValid())
    542                                         //               Please verify that the logic of the code remains coherent. Also, remember
    543                                         //               that the isReadable() and isWritable() methods are available.
    544                                         if(entry->exists())
    545                                                 myList.push_back(entry);
    546                                         else
    547                                                 delete entry;
     486                                        myList.push_back(entry);
    548487                                }
    549488
    550489                                IDOS->UnLock(volumeLock);