1
0
Fork 0

Added support for multiple findfirst/findnext at the same time.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@664
This commit is contained in:
Ulf Wohlers 2003-02-13 23:33:43 +00:00
parent 50385d3c05
commit e727664414
3 changed files with 139 additions and 68 deletions

View file

@ -55,16 +55,19 @@ bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFi
DOS_Drive_Cache::DOS_Drive_Cache(void)
{
dirBase = new CFileInfo;
dirSearch = 0;
save_dir = 0;
srchNr = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; };
SetDirSort(DIRALPHABETICAL);
};
DOS_Drive_Cache::DOS_Drive_Cache(const char* path)
{
dirBase = new CFileInfo;
dirSearch = 0;
save_dir = 0;
srchNr = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; };
SetDirSort(DIRALPHABETICAL);
SetBaseDir(path);
};
@ -72,14 +75,23 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path)
DOS_Drive_Cache::~DOS_Drive_Cache(void)
{
delete dirBase; dirBase = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) dirSearch[i] = 0;
};
Bit16u DOS_Drive_Cache::GetFreeID(void)
{
for (Bit32u i=0; i<MAX_OPENDIRS; i++) if (free[i]) return i;
LOG_ERROR("DIRCACHE: Too many open directorys!");
return 0;
};
void DOS_Drive_Cache::SetBaseDir(const char* baseDir)
{
Bit16u id;
strcpy(basePath,baseDir);
if (OpenDir(baseDir)) {
if (OpenDir(baseDir,id)) {
struct dirent* result;
ReadDir(result);
ReadDir(id,result);
};
};
@ -110,9 +122,8 @@ char* DOS_Drive_Cache::GetExpandName(const char* path)
return work;
};
void DOS_Drive_Cache::AddEntry(const char* path)
void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists)
{
// FIXME: Code doesnt seem to work with arena ??? Why is that ?
// Get Last part...
char file [CROSS_LEN];
char expand [CROSS_LEN];
@ -122,7 +133,9 @@ void DOS_Drive_Cache::AddEntry(const char* path)
if (pos) {
strcpy(file,pos+1);
// Check if file already exists, then dont add new entry...
if (checkExists && (GetLongName(dir,file)>=0)) return;
CreateEntry(dir,file);
// Sort Lists - filelist has to be alphabetically sorted
std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName);
@ -142,7 +155,7 @@ void DOS_Drive_Cache::AddEntry(const char* path)
void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir)
{
CacheOut(path,ignoreLastDir);
if (nextEntry>0) nextEntry--;
if (dirSearch[srchNr]->nextEntry>0) dirSearch[srchNr]->nextEntry--;
};
void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir)
@ -180,6 +193,31 @@ bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir)
return (curDir->fileList.size()>0);
};
bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname)
{
// Get Dir Info
char expand[CROSS_LEN] = {0};
CFileInfo* curDir = FindDirInfo(fullname,expand);
Bit16s foundNr = 0;
Bit16s low = 0;
Bit16s high = curDir->longNameList.size()-1;
Bit16s mid, res;
while (low<=high) {
mid = (low+high)/2;
res = strcmp(fullname,curDir->longNameList[mid]->orgname);
if (res>0) low = mid+1; else
if (res<0) high = mid-1;
else {
strcpy(shortname,curDir->longNameList[mid]->shortname);
return true;
};
}
return false;
};
Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name)
{
Bit16s foundNr = 0;
@ -319,6 +357,7 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
char* start = (char*)path;
char* pos;
CFileInfo* curDir = dirBase;
Bit16u id;
if (save_dir && (strcmp(path,save_path)==0)) {
strcpy(expandedPath,save_expanded);
@ -327,22 +366,23 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
// LOG_DEBUG("DIR: Find %s",path);
// hehe, baseDir should be cached in...
if (!IsCachedIn(curDir)) {
strcpy(work,basePath);
if (OpenDir(curDir,work)) {
char buffer[CROSS_LEN];
struct dirent* result;
strcpy(buffer,dirPath);
ReadDir(result);
strcpy(dirPath,buffer);
};
};
// Remove base dir path
start += strlen(basePath);
strcpy(expandedPath,basePath);
// hehe, baseDir should be cached in...
if (!IsCachedIn(curDir)) {
strcpy(work,basePath);
if (OpenDir(curDir,work,id)) {
char buffer[CROSS_LEN];
struct dirent* result;
strcpy(buffer,dirPath);
ReadDir(id,result);
strcpy(dirPath,buffer);
free[id] = true;
};
};
do {
// bool errorcheck = false;
pos = strchr(start,CROSS_FILESPLIT);
@ -366,12 +406,13 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
// Cut Directory, if its only part of whole path
if (pos) work[(Bit32u)pos-(Bit32u)path] = 0;
if (!IsCachedIn(curDir)) {
if (OpenDir(curDir,work)) {
if (OpenDir(curDir,work,id)) {
char buffer[CROSS_LEN];
struct dirent* result;
strcpy(buffer,dirPath);
ReadDir(result);
ReadDir(id,result);
strcpy(dirPath,buffer);
free[id] = true;
};
}
};
@ -389,31 +430,33 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
return curDir;
};
bool DOS_Drive_Cache::OpenDir(const char* path)
bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id)
{
char expand[CROSS_LEN] = {0};
CFileInfo* dir = FindDirInfo(path,expand);
if (OpenDir(dir,expand)) {
nextEntry = 0;
if (OpenDir(dir,expand,id)) {
dirSearch[id]->nextEntry = 0;
return true;
}
return false;
};
bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand)
bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand, Bit16u& id)
{
dirSearch = dir;
id = GetFreeID();
dirSearch[id] = dir;
// Add "/"
char end[2]={CROSS_FILESPLIT,0};
if (expand[strlen(expand)-1]!=CROSS_FILESPLIT) strcat(expand,end);
// open dir
if (dirSearch) {
if (dirSearch[id]) {
// open dir
DIR* dirp = opendir(expand);
if (dirp) {
// Reset it..
closedir(dirp);
strcpy(dirPath,expand);
free[id] = false;
return true;
}
};
@ -439,27 +482,31 @@ void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name)
dir->outputList.push_back(info);
};
bool DOS_Drive_Cache::ReadDir(struct dirent* &result)
bool DOS_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result)
{
if (!IsCachedIn(dirSearch)) {
// shouldnt happen...
if (id>MAX_OPENDIRS) return false;
if (!IsCachedIn(dirSearch[id])) {
// Try to open directory
DIR* dirp = opendir(dirPath);
if (!dirp) return false;
// Read complete directory
struct dirent* tmpres;
while (tmpres = readdir(dirp)) {
CreateEntry(dirSearch,tmpres->d_name);
CreateEntry(dirSearch[id],tmpres->d_name);
// Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names)
// hmpf.. bit slow probably...
std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName);
std::sort(dirSearch[id]->fileList.begin(), dirSearch[id]->fileList.end(), SortByName);
}
// close dir
closedir(dirp);
// Output list - user defined
switch (sortDirType) {
case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break;
case DIRALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirName); break;
case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break;
case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break;
case ALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByName); break;
case DIRALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirName); break;
case ALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByNameRev); break;
case DIRALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirNameRev); break;
};
// Info
/* if (!dirp) {
@ -467,11 +514,13 @@ bool DOS_Drive_Cache::ReadDir(struct dirent* &result)
return false;
} else {
char buffer[128];
sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch->fileList.size());
sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch[srchNr]->fileList.size());
LOG_DEBUG(buffer);
};*/
};
return SetResult(dirSearch, result, nextEntry);
if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true;
free[id] = true;
return false;
};
bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* &result, Bit16u entryNr)
@ -484,7 +533,7 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* &result, Bit16u e
// copy filename, short version
strcpy(result->d_name,info->shortname);
// Set to next Entry
nextEntry = entryNr+1;
dir->nextEntry = entryNr+1;
return true;
};
@ -502,19 +551,21 @@ void DOS_No_Drive_Cache::SetBaseDir(const char* path)
strcpy(basePath,path);
}
bool DOS_No_Drive_Cache::OpenDir(const char* path)
bool DOS_No_Drive_Cache::OpenDir(const char* path, Bit16u& id)
{
id = 0;
strcpy(dirPath,path);
if((srch_opendir=opendir(dirPath))==NULL) return false;
return true;
};
bool DOS_No_Drive_Cache::ReadDir(struct dirent* &result)
bool DOS_No_Drive_Cache::ReadDir(Bit16u id, struct dirent* &result)
{
if((result=readdir(srch_opendir))==NULL) {
if (!srch_opendir) return false;
if ((result=readdir(srch_opendir))==NULL) {
closedir(srch_opendir);
srch_opendir=NULL;
return false;
}
return true;
};
};

View file

@ -51,7 +51,7 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
CROSS_FILENAME(newname);
FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+");
if (!hand) return false;
dirCache.AddEntry(newname);
dirCache.AddEntry(newname, true);
/* Make the 16 bit device information */
*file=new localFile(hand,0x202);
return true;
@ -98,18 +98,21 @@ bool localDrive::FileUnlink(char * name) {
bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) {
strcpy(srch_dir,basedir);
strcat(srch_dir,_dir);
CROSS_FILENAME(srch_dir);
char tempDir[CROSS_LEN];
strcpy(tempDir,basedir);
strcat(tempDir,_dir);
CROSS_FILENAME(tempDir);
char end[2]={CROSS_FILESPLIT,0};
if (srch_dir[strlen(srch_dir)-1]!=CROSS_FILESPLIT) strcat(srch_dir,end);
if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end);
if (!dirCache.OpenDir(srch_dir)) return false;
Bit16u id;
if (!dirCache.OpenDir(tempDir,id)) return false;
strcpy(srchInfo[id].srch_dir,tempDir);
dta.SetDirID(id);
return FindNext(dta);
}
bool localDrive::FindNext(DOS_DTA & dta) {
struct dirent* dir_ent;
@ -121,12 +124,16 @@ bool localDrive::FindNext(DOS_DTA & dta) {
dta.GetSearchParams(srch_attr,srch_pattern);
Bit16u id = dta.GetDirID();
again:
if (!dirCache.ReadDir(dir_ent)) return false;
if (!dirCache.ReadDir(id,dir_ent)) {
return false;
}
if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again;
strcpy(full_name,srch_dir);
strcpy(full_name,srchInfo[id].srch_dir);
strcat(full_name,dir_ent->d_name);
if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) {
goto again;
@ -287,7 +294,6 @@ Bit8u localDrive::GetMediaByte(void) {
localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) {
strcpy(basedir,startdir);
sprintf(info,"local directory %s",startdir);
srch_opendir=NULL;
allocation.bytes_sector=_bytes_sector;
allocation.sectors_cluster=_sectors_cluster;
allocation.total_clusters=_total_clusters;

View file

@ -24,7 +24,8 @@
#include <vector>
#include "dos_system.h"
#include "cross.h"
#define MAX_OPENDIRS 16
bool WildFileCmp(const char * file, const char * wild);
@ -38,14 +39,15 @@ public:
void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) { sortDirType = sort; };
bool OpenDir (const char* path);
bool ReadDir (struct dirent* &result);
bool OpenDir (const char* path, Bit16u& id);
bool ReadDir (Bit16u id, struct dirent* &result);
void ExpandName (char* path);
char* GetExpandName (const char* path);
bool GetShortName (const char* fullname, char* shortname);
void CacheOut (const char* path, bool ignoreLastDir = false);
void AddEntry (const char* path);
void AddEntry (const char* path, bool checkExist = false);
void DeleteEntry (const char* path, bool ignoreLastDir = false);
class CFileInfo {
@ -56,10 +58,10 @@ public:
longNameList.clear();
outputList.clear();
};
char fullname [CROSS_LEN];
char orgname [CROSS_LEN];
char shortname [DOS_NAMELENGTH_ASCII];
bool isDir;
Bit16u nextEntry;
Bit16u shortNr;
Bit16u compareCount;
// contents
@ -77,12 +79,11 @@ private:
bool IsCachedIn (CFileInfo* dir);
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
bool RemoveSpaces (char* str);
bool OpenDir (CFileInfo* dir, char* path);
bool OpenDir (CFileInfo* dir, char* path, Bit16u& id);
void CreateEntry (CFileInfo* dir, const char* name);
Bit16u GetFreeID (void);
Bit32u nextEntry;
CFileInfo* dirBase;
CFileInfo* dirSearch;
char dirPath [CROSS_LEN];
char basePath [CROSS_LEN];
bool dirFirstTime;
@ -91,6 +92,11 @@ private:
char save_path [CROSS_LEN];
char save_expanded [CROSS_LEN];
Bit16u srchNr;
CFileInfo* dirSearch [MAX_OPENDIRS];
char dirSearchName [MAX_OPENDIRS];
bool free [MAX_OPENDIRS];
};
class DOS_No_Drive_Cache {
@ -103,15 +109,19 @@ public:
void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) {};
bool OpenDir (const char* path);
bool ReadDir (struct dirent* &result);
bool OpenDir (const char* path, Bit16u& id);
bool ReadDir (Bit16u id, struct dirent* &result);
void ExpandName (char* path) {};
char* GetExpandName (const char* path) { return (char*)path; };
bool GetShortName (const char* fullname, char* shortname) { return false; };
void CacheOut (const char* path, bool ignoreLastDir = false) {};
void AddEntry (const char* path) {};
void DeleteEntry (const char* path, bool ignoreLastDir = false);
void AddEntry (const char* path, bool checkExists = false) {};
void DeleteEntry (const char* path, bool ignoreLastDir = false) {};
void SetCurrentEntry (Bit16u entry) {};
Bit16u GetCurrentEntry (void) { return 0; };
public:
char basePath [CROSS_LEN];
@ -136,10 +146,14 @@ public:
bool FileExists(const char* name);
bool FileStat(const char* name, FileStat_Block * const stat_block);
Bit8u GetMediaByte(void);
bool GetShortName(const char* fullname, char* shortname) { return dirCache.GetShortName(fullname, shortname); };
private:
char basedir[CROSS_LEN];
char srch_dir[CROSS_LEN];
DIR * srch_opendir;
struct {
char srch_dir[CROSS_LEN];
} srchInfo[MAX_OPENDIRS];
struct {
Bit16u bytes_sector;
Bit8u sectors_cluster;
@ -147,7 +161,7 @@ private:
Bit16u free_clusters;
Bit8u mediaid;
} allocation;
DOS_Drive_Cache dirCache;
DOS_Drive_Cache dirCache;
};
struct VFILE_Block;