emsApplication/3rdPartner/libhv/cpputil/hdir.cpp

89 lines
2.7 KiB
C++

#include "hdir.h"
#include "hplatform.h"
#ifdef OS_WIN
//FILETIME starts from 1601-01-01 UTC, epoch from 1970-01-01 UTC
//FILETIME unit (100ns)
#define FILETIME_EPOCH_DIFF 11644473600 // s
time_t FileTime2Epoch(FILETIME filetime) {
uint64_t ll = (((uint64_t)filetime.dwHighDateTime) << 32) | filetime.dwLowDateTime;
ll /= 1e7; // s
return ll - FILETIME_EPOCH_DIFF;
}
#endif
static bool less(const hdir_t& lhs, const hdir_t& rhs) {
return stricmp(lhs.name, rhs.name) < 0;
}
int listdir(const char* dir, std::list<hdir_t>& dirs) {
int dirlen = strlen(dir);
if (dirlen > 256) {
return -1;
}
char path[512];
strcpy(path, dir);
if (dir[dirlen-1] != '/') {
strcat(path, "/");
++dirlen;
}
dirs.clear();
#ifdef OS_UNIX
// opendir -> readdir -> closedir
DIR* dp = opendir(dir);
if (dp == NULL) return -1;
struct dirent* result = NULL;
struct stat st;
hdir_t tmp;
while ((result = readdir(dp))) {
memset(&tmp, 0, sizeof(hdir_t));
strncpy(tmp.name, result->d_name, sizeof(tmp.name));
strncpy(path+dirlen, result->d_name, sizeof(path)-dirlen);
if (lstat(path, &st) == 0) {
if (S_ISREG(st.st_mode)) tmp.type = 'f';
else if (S_ISDIR(st.st_mode)) tmp.type = 'd';
else if (S_ISLNK(st.st_mode)) tmp.type = 'l';
else if (S_ISBLK(st.st_mode)) tmp.type = 'b';
else if (S_ISCHR(st.st_mode)) tmp.type = 'c';
else if (S_ISSOCK(st.st_mode)) tmp.type = 's';
else if (S_ISFIFO(st.st_mode)) tmp.type = 'p';
else tmp.type = '-';
tmp.mode = st.st_mode & 0777;
tmp.size = st.st_size;
tmp.atime = st.st_atime;
tmp.mtime = st.st_mtime;
tmp.ctime = st.st_ctime;
}
dirs.push_back(tmp);
}
closedir(dp);
#elif defined(OS_WIN)
// FindFirstFile -> FindNextFile -> FindClose
strcat(path, "*");
WIN32_FIND_DATAA data;
HANDLE h = FindFirstFileA(path, &data);
if (h == NULL) {
return -1;
}
hdir_t tmp;
do {
memset(&tmp, 0, sizeof(hdir_t));
strncpy(tmp.name, data.cFileName, sizeof(tmp.name));
tmp.type = 'f';
if (data.dwFileAttributes & _A_SUBDIR) {
tmp.type = 'd';
}
tmp.mode = 0777;
tmp.size = (((uint64_t)data.nFileSizeHigh) << 32) | data.nFileSizeLow;
tmp.atime = FileTime2Epoch(data.ftLastAccessTime);
tmp.mtime = FileTime2Epoch(data.ftLastWriteTime);
tmp.ctime = FileTime2Epoch(data.ftCreationTime);
dirs.push_back(tmp);
} while (FindNextFileA(h, &data));
FindClose(h);
#endif
dirs.sort(less);
return dirs.size();
}