From 8100d28f827b8cdf9fb3179501c5420f129e251d Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Thu, 9 Oct 2003 13:50:27 +0000 Subject: [PATCH] Enabled multiple FindFirst/Next Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1304 --- include/dos_system.h | 9 ++--- src/dos/drive_cache.cpp | 76 +++++++++++++++++++++++++++++------------ src/dos/drive_local.cpp | 8 ++--- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/include/dos_system.h b/include/dos_system.h index 02ce52c2..32212304 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_system.h,v 1.15 2003-09-22 12:22:25 finsterr Exp $ */ +/* $Id: dos_system.h,v 1.16 2003-10-09 13:50:27 finsterr Exp $ */ #ifndef DOSSYSTEM_H_ #define DOSSYSTEM_H_ @@ -104,8 +104,8 @@ public: char* GetExpandName (const char* path); bool GetShortName (const char* fullname, char* shortname); - bool FindFirst (char* path, Bit16u& id); - bool FindNext (Bit16u& id, char* &result); + bool FindFirst (char* path, Bitu dtaAddress, Bitu& id); + bool FindNext (Bitu id, char* &result); void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path, bool checkExist = false); @@ -121,6 +121,7 @@ public: for (Bit32u i=0; inextEntry = 0; + if (!OpenDir(path,dirID)) return false; + // Seacrh if dta was already used before + for (Bitu n=0; ncompareCount == dtaAddress) { + // Reuse old dta + dirFindFirstID = n; break; + } + } else if (dirFindFirstID==0xffff) { + dirFindFirstID = n; + } + } + if (dirFindFirstID==0xffff) { + // no free slot found... + LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : All slots full."); + // always use first then + dirFindFirstID = 0; + } + // Clear and reuse slot + delete dirFindFirst[dirFindFirstID]; + dirFindFirst[dirFindFirstID] = new CFileInfo(); + dirFindFirst[dirFindFirstID]-> nextEntry = 0; + dirFindFirst[dirFindFirstID]-> compareCount = dtaAddress; +// strcpy(dirFindFirst[dirFindFirstID]->orgname,path); + // Copy entries to use with FindNext - for (Bitu i=0; ifileList.size(); i++) { - CreateEntry(dirFindFirst,dirSearch[id]->fileList[i]->orgname); + for (Bitu i=0; ifileList.size(); i++) { + CreateEntry(dirFindFirst[dirFindFirstID],dirSearch[dirID]->fileList[i]->orgname); // Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names) - std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByName); + std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); }; // Now re-sort the fileList accordingly to output switch (sortDirType) { - case ALPHABETICAL : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByName); break; - case DIRALPHABETICAL : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByDirName); break; - case ALPHABETICALREV : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByNameRev); break; - case DIRALPHABETICALREV : std::sort(dirFindFirst->fileList.begin(), dirFindFirst->fileList.end(), SortByDirNameRev); break; + case ALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByName); break; + case DIRALPHABETICAL : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirName); break; + case ALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByNameRev); break; + case DIRALPHABETICALREV : std::sort(dirFindFirst[dirFindFirstID]->fileList.begin(), dirFindFirst[dirFindFirstID]->fileList.end(), SortByDirNameRev); break; case NOSORT : break; }; + +// LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst : %s (ID:%02X)",path,dirFindFirstID); + id = dirFindFirstID; return true; }; -bool DOS_Drive_Cache::FindNext(Bit16u& id, char* &result) +bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) { - return SetResult(dirFindFirst, result, dirFindFirst->nextEntry); + // out of range ? + if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) { + LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id); + return false; + } + if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) { + // free slot + delete dirFindFirst[id]; dirFindFirst[id] = 0; + return false; + } + return true; }; // **************************************************************************** diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index f10fbed7..509d083f 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -109,9 +109,8 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) { char end[2]={CROSS_FILESPLIT,0}; if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); - Bit16u id; -// if (!dirCache.OpenDir(tempDir,id)) - if (!dirCache.FindFirst(tempDir,id)) + Bitu id; + if (!dirCache.FindFirst(tempDir,(Bitu)dos.dta,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; @@ -143,10 +142,9 @@ bool localDrive::FindNext(DOS_DTA & dta) { dta.GetSearchParams(srch_attr,srch_pattern); - Bit16u id = dta.GetDirID(); + Bitu id = dta.GetDirID(); again: -// if (!dirCache.ReadDir(id,dir_ent)) { if (!dirCache.FindNext(id,dir_ent)) { DOS_SetError(DOSERR_NO_MORE_FILES); return false;