-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathd_fs.h
175 lines (155 loc) · 3.72 KB
/
d_fs.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#ifndef D_FS_H
#define D_FS_H
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
char* d_read_text(char* path, size_t* osize);
uint8_t* d_read_bytes(char* path, size_t* osize);
bool d_write_bytes(char* path, uint8_t* data, size_t size);
bool d_write_text(char* path, char* text, size_t size);
void d_free_dir(char** list);
bool d_is_file(char* path);
bool d_is_dir(char* path);
char* d_extname(char* path);
char* d_basename(char* path);
char* d_res_dir(void);
char* d_res_path(char* path);
char* d_data_dir(void);
#endif
#ifdef D_IMPL
#define D_FS_IMPL
#endif
#ifdef D_FS_IMPL
#ifndef D_FS_IMPL_ONCE
#define D_FS_IMPL_ONCE
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#if defined(__APPLE__)
#import <Foundation/Foundation.h>
#endif
char* d_read_text(char* path, size_t* osize) {
FILE* file = fopen(path, "r");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = malloc(size + 1);
fread(buffer, 1, size, file);
buffer[size] = '\0';
fclose(file);
if (osize) *osize = size;
return buffer;
}
uint8_t* d_read_bytes(char* path, size_t* osize) {
FILE* file = fopen(path, "rb");
if (!file) return NULL;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fseek(file, 0, SEEK_SET);
uint8_t* buffer = malloc(size);
fread(buffer, 1, size, file);
fclose(file);
if (osize) *osize = size;
return buffer;
}
bool d_write_text(char* path, char* text, size_t size) {
FILE* file = fopen(path, "w");
if (!file) return false;
fwrite(text, 1, size ? size : strlen(text), file);
fclose(file);
return true;
}
bool d_write_bytes(char* path, uint8_t* data, size_t size) {
FILE* file = fopen(path, "wb");
if (!file) return false;
fwrite(data, 1, size, file);
fclose(file);
return true;
}
bool d_is_file(char* path) {
struct stat sb;
return stat(path, &sb) == 0 && S_ISREG(sb.st_mode);
}
bool d_is_dir(char* path) {
struct stat sb;
return stat(path, &sb) == 0 && S_ISDIR(sb.st_mode);
}
char* d_extname(char* path) {
char* dot = strrchr(path, '.');
if (!dot) {
return NULL;
}
char* buf = malloc(strlen(dot + 1) + 1);
strcpy(buf, dot + 1);
return buf;
}
char* d_basename(char* path) {
char* dot = strrchr(path, '.');
char* slash = strrchr(path, '/');
dot = dot ? dot : path + strlen(path);
slash = slash ? slash + 1 : path;
int len = dot - slash;
char* buf = malloc(len + 1);
strncpy(buf, slash, len);
buf[len] = '\0';
return buf;
}
char* d_fmt(char* fmt, ...) {
va_list args;
va_start(args, fmt);
size_t size = vsnprintf(NULL, 0, fmt, args);
va_end(args);
char* buf = malloc(size + 1);
va_start(args, fmt);
vsnprintf(buf, size + 1, fmt, args);
va_end(args);
return buf;
}
char* d_res_dir(void) {
#if defined(__APPLE__)
@autoreleasepool {
return d_fmt("%s", [[[NSBundle mainBundle] resourcePath] UTF8String]);
}
#endif
return NULL;
}
char* d_res_path(char* path) {
char* res_dir = d_res_dir();
char* rpath;
if (res_dir == NULL) {
rpath = d_fmt("%s", path);
} else {
rpath = d_fmt("%s/%s", res_dir, path);
}
free(res_dir);
return rpath;
}
char* d_data_dir(void) {
#if defined(__APPLE__)
const char* home = getenv("HOME");
if (home) {
return d_fmt("%s/Library/Application Support", home);
} else {
return d_fmt("~/Library/Application Support");
}
#elif defined(__linux__) || defined(__unix__)
char* home = getenv("HOME");
char* xdg_home = getenv("XDG_DATA_HOME");
if (xdg_home) {
return d_fmt("%s", xdg_home);
} else if (home) {
return d_fmt("%s/.local/share", home);
} else {
return d_fmt("~/.local/share");
}
#elif defined(_WIN32) || defined(_WIN64)
// TODO
return d_fmt("");
#endif
return d_fmt("");
}
#endif
#endif