-
Notifications
You must be signed in to change notification settings - Fork 190
/
filesystem_utils.h
159 lines (129 loc) · 3.15 KB
/
filesystem_utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#ifndef FILESYSTEM_UTILS_H
#define FILESYSTEM_UTILS_H
#include <stdio.h>
#include <vector>
#include <string>
#include <algorithm>
#if _WIN32
#include <windows.h>
#include "win32dirent.h"
#else // _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#endif // _WIN32
#if _WIN32
typedef std::wstring path_t;
#define PATHSTR(X) L##X
#else
typedef std::string path_t;
#define PATHSTR(X) X
#endif
#if _WIN32
static bool path_is_directory(const path_t& path)
{
DWORD attr = GetFileAttributesW(path.c_str());
return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
}
static int list_directory(const path_t& dirpath, std::vector<path_t>& imagepaths)
{
imagepaths.clear();
_WDIR* dir = _wopendir(dirpath.c_str());
if (!dir)
{
fwprintf(stderr, L"opendir failed %ls\n", dirpath.c_str());
return -1;
}
struct _wdirent* ent = 0;
while ((ent = _wreaddir(dir)))
{
if (ent->d_type != DT_REG)
continue;
imagepaths.push_back(path_t(ent->d_name));
}
_wclosedir(dir);
std::sort(imagepaths.begin(), imagepaths.end());
return 0;
}
#else // _WIN32
static bool path_is_directory(const path_t& path)
{
struct stat s;
if (stat(path.c_str(), &s) != 0)
return false;
return S_ISDIR(s.st_mode);
}
static int list_directory(const path_t& dirpath, std::vector<path_t>& imagepaths)
{
imagepaths.clear();
DIR* dir = opendir(dirpath.c_str());
if (!dir)
{
fprintf(stderr, "opendir failed %s\n", dirpath.c_str());
return -1;
}
struct dirent* ent = 0;
while ((ent = readdir(dir)))
{
if (ent->d_type != DT_REG)
continue;
imagepaths.push_back(path_t(ent->d_name));
}
closedir(dir);
std::sort(imagepaths.begin(), imagepaths.end());
return 0;
}
#endif // _WIN32
static path_t get_file_name_without_extension(const path_t& path)
{
size_t dot = path.rfind(PATHSTR('.'));
if (dot == path_t::npos)
return path;
return path.substr(0, dot);
}
static path_t get_file_extension(const path_t& path)
{
size_t dot = path.rfind(PATHSTR('.'));
if (dot == path_t::npos)
return path_t();
return path.substr(dot + 1);
}
#if _WIN32
static path_t get_executable_directory()
{
wchar_t filepath[256];
GetModuleFileNameW(NULL, filepath, 256);
wchar_t* backslash = wcsrchr(filepath, L'\\');
backslash[1] = L'\0';
return path_t(filepath);
}
#else // _WIN32
static path_t get_executable_directory()
{
char filepath[256];
readlink("/proc/self/exe", filepath, 256);
char* slash = strrchr(filepath, '/');
slash[1] = '\0';
return path_t(filepath);
}
#endif // _WIN32
static bool filepath_is_readable(const path_t& path)
{
#if _WIN32
FILE* fp = _wfopen(path.c_str(), L"rb");
#else // _WIN32
FILE* fp = fopen(path.c_str(), "rb");
#endif // _WIN32
if (!fp)
return false;
fclose(fp);
return true;
}
static path_t sanitize_filepath(const path_t& path)
{
if (filepath_is_readable(path))
return path;
return get_executable_directory() + path;
}
#endif // FILESYSTEM_UTILS_H