Add an function to return directory list of files and basic properties.

This commit is contained in:
baldurk
2016-08-05 14:45:17 +02:00
parent 5dc70c2a72
commit 593e2c5903
3 changed files with 162 additions and 0 deletions
+21
View File
@@ -264,6 +264,27 @@ uint64_t GetModifiedTimestamp(const string &filename);
void Copy(const char *from, const char *to, bool allowOverwrite);
void Delete(const char *path);
enum
{
eFileProp_Directory = 0x1,
eFileProp_Hidden = 0x2,
eFileProp_Executable = 0x4,
eFileProp_ErrorUnknown = 0x2000,
eFileProp_ErrorAccessDenied = 0x4000,
eFileProp_ErrorInvalidPath = 0x8000,
};
struct FoundFile
{
FoundFile() : flags(0) {}
FoundFile(string fn, uint32_t f) : filename(fn), flags(f) {}
string filename;
uint32_t flags;
};
vector<FoundFile> GetFilesInDirectory(const char *path);
FILE *fopen(const char *filename, const char *mode);
size_t fread(void *buf, size_t elementSize, size_t count, FILE *f);
+65
View File
@@ -22,6 +22,7 @@
* THE SOFTWARE.
******************************************************************************/
#include <dirent.h>
#include <dlfcn.h> // for dladdr
#include <errno.h>
#include <limits.h>
@@ -234,6 +235,70 @@ void Delete(const char *path)
unlink(path);
}
vector<FoundFile> GetFilesInDirectory(const char *path)
{
vector<FoundFile> ret;
DIR *d = opendir(path);
if(d == NULL)
{
uint32_t flags = eFileProp_ErrorUnknown;
if(errno == ENOENT)
flags = eFileProp_ErrorInvalidPath;
else if(errno == EACCES)
flags = eFileProp_ErrorAccessDenied;
ret.push_back(FoundFile(path, flags));
return ret;
}
dirent *ent = NULL;
for(;;)
{
ent = readdir(d);
if(!ent)
break;
// skip "." and ".."
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
continue;
string fullpath = path;
fullpath += '/';
fullpath += ent->d_name;
struct ::stat st;
int res = stat(fullpath.c_str(), &st);
// invalid/bad file - skip it
if(res != 0)
continue;
uint32_t flags = 0;
// make directory/executable mutually exclusive for clarity's sake
if(S_ISDIR(st.st_mode))
flags |= eFileProp_Directory;
else if(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
flags |= eFileProp_Executable;
if(ent->d_name[0] == '.')
flags |= eFileProp_Hidden;
ret.push_back(FoundFile(ent->d_name, flags));
}
// don't care if we hit an error or enumerated all files, just finish
closedir(d);
return ret;
}
FILE *fopen(const char *filename, const char *mode)
{
return ::fopen(filename, mode);
+76
View File
@@ -333,6 +333,82 @@ void Delete(const char *path)
::DeleteFileW(wpath.c_str());
}
vector<FoundFile> GetFilesInDirectory(const char *path)
{
vector<FoundFile> ret;
string pathstr = path;
// normalise path to windows style
for(size_t i = 0; i < pathstr.size(); i++)
if(pathstr[i] == '/')
pathstr[i] = '\\';
// remove any trailing slash
if(pathstr[pathstr.size() - 1] == '\\')
pathstr.resize(pathstr.size() - 1);
// append '\*' to do the search we want
pathstr += "\\*";
wstring wpath = StringFormat::UTF82Wide(pathstr);
WIN32_FIND_DATAW findData = {};
HANDLE find = FindFirstFileW(wpath.c_str(), &findData);
if(find == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError();
uint32_t flags = eFileProp_ErrorUnknown;
if(err == ERROR_FILE_NOT_FOUND)
flags = eFileProp_ErrorInvalidPath;
else if(err == ERROR_ACCESS_DENIED)
flags = eFileProp_ErrorAccessDenied;
ret.push_back(FoundFile(path, flags));
return ret;
}
do
{
if(findData.cFileName[0] == L'.' && findData.cFileName[1] == 0)
{
// skip "."
}
else if(findData.cFileName[0] == L'.' && findData.cFileName[1] == L'.' &&
findData.cFileName[2] == 0)
{
// skip ".."
}
else
{
uint32_t flags = 0;
if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
flags |= eFileProp_Directory;
if(findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
flags |= eFileProp_Hidden;
if(wcsstr(findData.cFileName, L".EXE") || wcsstr(findData.cFileName, L".exe") ||
wcsstr(findData.cFileName, L".Exe"))
{
flags |= eFileProp_Executable;
}
ret.push_back(FoundFile(StringFormat::Wide2UTF8(findData.cFileName), flags));
}
} while(FindNextFile(find, &findData) != FALSE);
// don't care if we hit an error or enumerated all files, just finish
FindClose(find);
return ret;
}
FILE *fopen(const char *filename, const char *mode)
{
wstring wfn = StringFormat::UTF82Wide(string(filename));