recursive search for Windows - untested
This commit is contained in:
parent
aabe2f58f5
commit
6b59dcf380
1 changed files with 123 additions and 41 deletions
|
|
@ -93,6 +93,57 @@ void FurnaceFilePicker::completeStat() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
FurnaceFilePicker::FileEntry* FurnaceFilePicker::makeEntry(void* _entry, const char* prefix) {
|
||||||
|
WIN32_FIND_DATAW* entry=(WIN32_FIND_DATAW*)_entry;
|
||||||
|
SYSTEMTIME tempTM;
|
||||||
|
|
||||||
|
FileEntry* newEntry=new FileEntry;
|
||||||
|
|
||||||
|
if (prefix!=NULL) {
|
||||||
|
if (prefix[0]=='\\') {
|
||||||
|
newEntry->name=String(&prefix[1])+"\\"+utf16To8(entry->cFileName);
|
||||||
|
} else {
|
||||||
|
newEntry->name=utf16To8(entry->cFileName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newEntry->name=utf16To8(entry->cFileName);
|
||||||
|
}
|
||||||
|
newEntry->nameLower=newEntry->name;
|
||||||
|
for (char& i: newEntry->nameLower) {
|
||||||
|
if (i>='A' && i<='Z') i+='a'-'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
newEntry->isDir=entry->dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
newEntry->isHidden=(entry->dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) || (entry->dwFileAttributes&FILE_ATTRIBUTE_SYSTEM);
|
||||||
|
newEntry->type=newEntry->isDir?FP_TYPE_DIR:FP_TYPE_NORMAL;
|
||||||
|
|
||||||
|
if (!newEntry->isDir) {
|
||||||
|
size_t extPos=newEntry->name.rfind('.');
|
||||||
|
if (extPos!=String::npos) {
|
||||||
|
newEntry->ext=newEntry->name.substr(extPos);
|
||||||
|
for (char& i: newEntry->ext) {
|
||||||
|
if (i>='A' && i<='Z') i+='a'-'A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newEntry->size=((uint64_t)entry->nFileSizeHigh<<32)|(uint64_t)entry->nFileSizeLow;
|
||||||
|
newEntry->hasSize=true;
|
||||||
|
|
||||||
|
if (FileTimeToSystemTime(&entry->ftLastWriteTime,&tempTM)) {
|
||||||
|
// we only use these
|
||||||
|
newEntry->time.tm_year=tempTM.wYear-1900;
|
||||||
|
newEntry->time.tm_mon=tempTM.wMonth-1;
|
||||||
|
newEntry->time.tm_mday=tempTM.wDay;
|
||||||
|
newEntry->time.tm_hour=tempTM.wHour;
|
||||||
|
newEntry->time.tm_min=tempTM.wMinute;
|
||||||
|
newEntry->time.tm_sec=tempTM.wSecond;
|
||||||
|
|
||||||
|
newEntry->hasTime=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newEntry;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
FurnaceFilePicker::FileEntry* FurnaceFilePicker::makeEntry(void* _entry, const char* prefix) {
|
FurnaceFilePicker::FileEntry* FurnaceFilePicker::makeEntry(void* _entry, const char* prefix) {
|
||||||
struct dirent* entry=(struct dirent*)_entry;
|
struct dirent* entry=(struct dirent*)_entry;
|
||||||
|
|
@ -224,7 +275,6 @@ void FurnaceFilePicker::readDirectorySub() {
|
||||||
WString pathW=utf8To16(path.c_str());
|
WString pathW=utf8To16(path.c_str());
|
||||||
pathW+=L"\\*";
|
pathW+=L"\\*";
|
||||||
WIN32_FIND_DATAW entry;
|
WIN32_FIND_DATAW entry;
|
||||||
SYSTEMTIME tempTM;
|
|
||||||
HANDLE dir=FindFirstFileW(pathW.c_str(),&entry);
|
HANDLE dir=FindFirstFileW(pathW.c_str(),&entry);
|
||||||
if (dir==INVALID_HANDLE_VALUE) {
|
if (dir==INVALID_HANDLE_VALUE) {
|
||||||
wchar_t* errorStr=NULL;
|
wchar_t* errorStr=NULL;
|
||||||
|
|
@ -247,42 +297,7 @@ void FurnaceFilePicker::readDirectorySub() {
|
||||||
if (wcscmp(entry.cFileName,L".")==0) continue;
|
if (wcscmp(entry.cFileName,L".")==0) continue;
|
||||||
if (wcscmp(entry.cFileName,L"..")==0) continue;
|
if (wcscmp(entry.cFileName,L"..")==0) continue;
|
||||||
|
|
||||||
FileEntry* newEntry=new FileEntry;
|
FileEntry* newEntry=makeEntry(&entry,NULL);
|
||||||
|
|
||||||
newEntry->name=utf16To8(entry.cFileName);
|
|
||||||
newEntry->nameLower=newEntry->name;
|
|
||||||
for (char& i: newEntry->nameLower) {
|
|
||||||
if (i>='A' && i<='Z') i+='a'-'A';
|
|
||||||
}
|
|
||||||
|
|
||||||
newEntry->isDir=entry.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
newEntry->isHidden=(entry.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN) || (entry.dwFileAttributes&FILE_ATTRIBUTE_SYSTEM);
|
|
||||||
newEntry->type=newEntry->isDir?FP_TYPE_DIR:FP_TYPE_NORMAL;
|
|
||||||
|
|
||||||
if (!newEntry->isDir) {
|
|
||||||
size_t extPos=newEntry->name.rfind('.');
|
|
||||||
if (extPos!=String::npos) {
|
|
||||||
newEntry->ext=newEntry->name.substr(extPos);
|
|
||||||
for (char& i: newEntry->ext) {
|
|
||||||
if (i>='A' && i<='Z') i+='a'-'A';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newEntry->size=((uint64_t)entry.nFileSizeHigh<<32)|(uint64_t)entry.nFileSizeLow;
|
|
||||||
newEntry->hasSize=true;
|
|
||||||
|
|
||||||
if (FileTimeToSystemTime(&entry.ftLastWriteTime,&tempTM)) {
|
|
||||||
// we only use these
|
|
||||||
newEntry->time.tm_year=tempTM.wYear-1900;
|
|
||||||
newEntry->time.tm_mon=tempTM.wMonth-1;
|
|
||||||
newEntry->time.tm_mday=tempTM.wDay;
|
|
||||||
newEntry->time.tm_hour=tempTM.wHour;
|
|
||||||
newEntry->time.tm_min=tempTM.wMinute;
|
|
||||||
newEntry->time.tm_sec=tempTM.wSecond;
|
|
||||||
|
|
||||||
newEntry->hasTime=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
entryLock.lock();
|
entryLock.lock();
|
||||||
entries.push_back(newEntry);
|
entries.push_back(newEntry);
|
||||||
|
|
@ -343,6 +358,73 @@ void FurnaceFilePicker::readDirectorySub() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Windows implementation
|
// Windows implementation
|
||||||
void FurnaceFilePicker::searchSub(String subPath, int depth) {
|
void FurnaceFilePicker::searchSub(String subPath, int depth) {
|
||||||
|
/// refuse to if we're on the drive list
|
||||||
|
if (path=="") {
|
||||||
|
failMessage="Select a drive!";
|
||||||
|
haveFiles=true;
|
||||||
|
haveStat=true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WString searchQueryW=utf8To16(searchQuery);
|
||||||
|
|
||||||
|
if (depth>15) logW("searchSub(%s,%d)",subPath,depth);
|
||||||
|
|
||||||
|
/// STAGE 1: get file list
|
||||||
|
String actualPath=path+subPath;
|
||||||
|
WString pathW=utf8To16(actualPath.c_str());
|
||||||
|
pathW+=L"\\*";
|
||||||
|
WIN32_FIND_DATAW entry;
|
||||||
|
HANDLE dir=FindFirstFileW(pathW.c_str(),&entry);
|
||||||
|
if (dir==INVALID_HANDLE_VALUE) {
|
||||||
|
if (depth==0) {
|
||||||
|
wchar_t* errorStr=NULL;
|
||||||
|
int errorSize=FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(wchar_t*)&errorStr,0,NULL);
|
||||||
|
if (errorSize==0) {
|
||||||
|
failMessage="Unknown error!";
|
||||||
|
} else {
|
||||||
|
failMessage=utf16To8(errorStr);
|
||||||
|
// remove trailing new-line
|
||||||
|
if (failMessage.size()>=2) failMessage.resize(failMessage.size()-2);
|
||||||
|
}
|
||||||
|
LocalFree(errorStr);
|
||||||
|
|
||||||
|
haveFiles=true;
|
||||||
|
haveStat=true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (stopReading) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wcscmp(entry.cFileName,L".")==0) continue;
|
||||||
|
if (wcscmp(entry.cFileName,L"..")==0) continue;
|
||||||
|
|
||||||
|
WString lower=entry.cFileName;
|
||||||
|
for (auto& i: lower) {
|
||||||
|
if (i>='A' && i<='Z') i+='a'-'A';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lower.find(searchQueryW)!=WString::npos) {
|
||||||
|
FileEntry* newEntry=makeEntry(&entry,NULL);
|
||||||
|
entryLock.lock();
|
||||||
|
entries.push_back(newEntry);
|
||||||
|
entryLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
searchSub(subPath+String("\\")+utf16To8(entry.cFileName),depth+1);
|
||||||
|
}
|
||||||
|
} while (FindNextFileW(dir,&entry)!=0);
|
||||||
|
FindClose(dir);
|
||||||
|
|
||||||
|
if (depth==0) {
|
||||||
|
haveFiles=true;
|
||||||
|
haveStat=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Linux/Unix implementation
|
// Linux/Unix implementation
|
||||||
|
|
@ -363,6 +445,10 @@ void FurnaceFilePicker::searchSub(String subPath, int depth) {
|
||||||
|
|
||||||
struct dirent* entry=NULL;
|
struct dirent* entry=NULL;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (stopReading) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
entry=readdir(dir);
|
entry=readdir(dir);
|
||||||
if (entry==NULL) break;
|
if (entry==NULL) break;
|
||||||
if (strcmp(entry->d_name,".")==0) continue;
|
if (strcmp(entry->d_name,".")==0) continue;
|
||||||
|
|
@ -383,10 +469,6 @@ void FurnaceFilePicker::searchSub(String subPath, int depth) {
|
||||||
if (entry->d_type==DT_DIR) {
|
if (entry->d_type==DT_DIR) {
|
||||||
searchSub(subPath+String("/")+entry->d_name,depth+1);
|
searchSub(subPath+String("/")+entry->d_name,depth+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopReading) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (closedir(dir)!=0) {
|
if (closedir(dir)!=0) {
|
||||||
// ?!
|
// ?!
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue