Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/directory.hpp
2 views
1
#ifndef NALL_DIRECTORY_HPP
2
#define NALL_DIRECTORY_HPP
3
4
#include <nall/intrinsics.hpp>
5
#include <nall/sort.hpp>
6
#include <nall/string.hpp>
7
#include <nall/vector.hpp>
8
9
#if defined(PLATFORM_WINDOWS)
10
#include <nall/windows/utf8.hpp>
11
#else
12
#include <dirent.h>
13
#include <stdio.h>
14
#include <sys/types.h>
15
#endif
16
17
namespace nall {
18
19
struct directory {
20
static bool exists(const string &pathname);
21
static lstring folders(const string &pathname, const string &pattern = "*");
22
static lstring files(const string &pathname, const string &pattern = "*");
23
static lstring contents(const string &pathname, const string &pattern = "*");
24
};
25
26
#if defined(PLATFORM_WINDOWS)
27
inline bool directory::exists(const string &pathname) {
28
DWORD result = GetFileAttributes(utf16_t(pathname));
29
if(result == INVALID_FILE_ATTRIBUTES) return false;
30
return (result & FILE_ATTRIBUTE_DIRECTORY);
31
}
32
33
inline lstring directory::folders(const string &pathname, const string &pattern) {
34
lstring list;
35
string path = pathname;
36
path.transform("/", "\\");
37
if(!strend(path, "\\")) path.append("\\");
38
path.append("*");
39
HANDLE handle;
40
WIN32_FIND_DATA data;
41
handle = FindFirstFile(utf16_t(path), &data);
42
if(handle != INVALID_HANDLE_VALUE) {
43
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
44
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
45
string name = (const char*)utf8_t(data.cFileName);
46
if(wildcard(name, pattern)) list.append(name);
47
}
48
}
49
while(FindNextFile(handle, &data) != false) {
50
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
51
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
52
string name = (const char*)utf8_t(data.cFileName);
53
if(wildcard(name, pattern)) list.append(name);
54
}
55
}
56
}
57
FindClose(handle);
58
}
59
if(list.size() > 0) list.sort();
60
for(auto &name : list) name.append("/"); //must append after sorting
61
return list;
62
}
63
64
inline lstring directory::files(const string &pathname, const string &pattern) {
65
lstring list;
66
string path = pathname;
67
path.transform("/", "\\");
68
if(!strend(path, "\\")) path.append("\\");
69
path.append("*");
70
HANDLE handle;
71
WIN32_FIND_DATA data;
72
handle = FindFirstFile(utf16_t(path), &data);
73
if(handle != INVALID_HANDLE_VALUE) {
74
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
75
string name = (const char*)utf8_t(data.cFileName);
76
if(wildcard(name, pattern)) list.append(name);
77
}
78
while(FindNextFile(handle, &data) != false) {
79
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
80
string name = (const char*)utf8_t(data.cFileName);
81
if(wildcard(name, pattern)) list.append(name);
82
}
83
}
84
FindClose(handle);
85
}
86
if(list.size() > 0) list.sort();
87
return list;
88
}
89
90
inline lstring directory::contents(const string &pathname, const string &pattern) {
91
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
92
lstring files = directory::files(pathname, pattern);
93
for(auto &file : files) folders.append(file);
94
return folders;
95
}
96
#else
97
inline bool directory::exists(const string &pathname) {
98
DIR *dp = opendir(pathname);
99
if(!dp) return false;
100
closedir(dp);
101
return true;
102
}
103
104
inline lstring directory::folders(const string &pathname, const string &pattern) {
105
lstring list;
106
DIR *dp;
107
struct dirent *ep;
108
dp = opendir(pathname);
109
if(dp) {
110
while(ep = readdir(dp)) {
111
if(!strcmp(ep->d_name, ".")) continue;
112
if(!strcmp(ep->d_name, "..")) continue;
113
if(ep->d_type & DT_DIR) {
114
if(wildcard(ep->d_name, pattern)) list.append(ep->d_name);
115
}
116
}
117
closedir(dp);
118
}
119
if(list.size() > 0) list.sort();
120
for(auto &name : list) name.append("/"); //must append after sorting
121
return list;
122
}
123
124
inline lstring directory::files(const string &pathname, const string &pattern) {
125
lstring list;
126
DIR *dp;
127
struct dirent *ep;
128
dp = opendir(pathname);
129
if(dp) {
130
while(ep = readdir(dp)) {
131
if(!strcmp(ep->d_name, ".")) continue;
132
if(!strcmp(ep->d_name, "..")) continue;
133
if((ep->d_type & DT_DIR) == 0) {
134
if(wildcard(ep->d_name, pattern)) list.append(ep->d_name);
135
}
136
}
137
closedir(dp);
138
}
139
if(list.size() > 0) list.sort();
140
return list;
141
}
142
143
inline lstring directory::contents(const string &pathname, const string &pattern) {
144
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
145
lstring files = directory::files(pathname, pattern);
146
for(auto &file : files) folders.append(file);
147
return folders;
148
}
149
#endif
150
151
}
152
153
#endif
154
155