1
0
Fork 0

Enabled multiple FindFirst/Next

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1304
This commit is contained in:
Ulf Wohlers 2003-10-09 13:50:27 +00:00
parent 4fae68a7b6
commit 8100d28f82
3 changed files with 63 additions and 30 deletions

View file

@ -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; i<fileList.size(); i++) delete fileList[i];
fileList.clear();
longNameList.clear();
compareCount = 0;
};
char orgname [CROSS_LEN];
char shortname [DOS_NAMELENGTH_ASCII];
@ -161,7 +162,7 @@ private:
CFileInfo* dirSearch [MAX_OPENDIRS];
char dirSearchName [MAX_OPENDIRS];
bool free [MAX_OPENDIRS];
CFileInfo* dirFindFirst;
CFileInfo* dirFindFirst [MAX_OPENDIRS];
char label [CROSS_LEN];
};

View file

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_cache.cpp,v 1.26 2003-09-22 12:21:53 finsterr Exp $ */
/* $Id: drive_cache.cpp,v 1.27 2003-10-09 13:49:48 finsterr Exp $ */
#include "drives.h"
#include "dos_inc.h"
@ -65,8 +65,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void)
save_dir = 0;
srchNr = 0;
label[0] = 0;
dirFindFirst= 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; };
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; dirFindFirst[i] = 0; };
SetDirSort(DIRALPHABETICAL);
};
@ -76,8 +75,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path)
save_dir = 0;
srchNr = 0;
label[0] = 0;
dirFindFirst= 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; };
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; dirFindFirst[i] = 0; };
SetDirSort(DIRALPHABETICAL);
SetBaseDir(path);
};
@ -85,7 +83,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path)
DOS_Drive_Cache::~DOS_Drive_Cache(void)
{
Clear();
delete dirFindFirst; dirFindFirst = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { delete dirFindFirst[i]; dirFindFirst[i]=0; };
};
void DOS_Drive_Cache::Clear(void)
@ -614,34 +612,70 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr)
};
// FindFirst / FindNext
bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id)
bool DOS_Drive_Cache::FindFirst(char* path, Bitu dtaAddress, Bitu& id)
{
Bit16u dirID;
Bitu dirFindFirstID = 0xffff;
// Cache directory in
if (!OpenDir(path,id)) return false;
// Find Free ID for directory copy
if (dirFindFirst) delete dirFindFirst;
dirFindFirst = new CFileInfo();
dirFindFirst->nextEntry = 0;
if (!OpenDir(path,dirID)) return false;
// Seacrh if dta was already used before
for (Bitu n=0; n<MAX_OPENDIRS; n++) {
if (dirFindFirst[n]) {
if (dirFindFirst[n]->compareCount == 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; i<dirSearch[id]->fileList.size(); i++) {
CreateEntry(dirFindFirst,dirSearch[id]->fileList[i]->orgname);
for (Bitu i=0; i<dirSearch[dirID]->fileList.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;
};
// ****************************************************************************

View file

@ -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;