Line |
Branch |
Exec |
Source |
1 |
|
|
#include <errno.h> |
2 |
|
|
#include "virtualfile.h" |
3 |
|
|
#include "platform/file-helpers.h" |
4 |
|
|
#include "warnings.h" |
5 |
|
|
|
6 |
|
|
class virtual_file |
7 |
|
|
{ |
8 |
|
|
public: |
9 |
|
962 |
virtual ~virtual_file() |
10 |
|
962 |
{ |
11 |
|
962 |
} |
12 |
|
|
|
13 |
|
|
virtual void close() = 0; |
14 |
|
|
|
15 |
|
|
virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes) = 0; |
16 |
|
|
|
17 |
|
|
virtual size_t get_size() = 0; |
18 |
|
|
}; |
19 |
|
|
|
20 |
|
|
class memory_file : public virtual_file |
21 |
|
|
{ |
22 |
|
|
public: |
23 |
|
52 |
memory_file(const void* data, size_t length) |
24 |
|
52 |
: m_data(data), m_length(length) |
25 |
|
|
{ |
26 |
|
52 |
} |
27 |
|
|
|
28 |
|
208 |
virtual ~memory_file() |
29 |
|
104 |
{ |
30 |
|
104 |
close(); |
31 |
|
208 |
} |
32 |
|
|
|
33 |
|
104 |
virtual void close() |
34 |
|
|
{ |
35 |
|
104 |
} |
36 |
|
|
|
37 |
|
52 |
virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes) |
38 |
|
|
{ |
39 |
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 52 times.
|
52 |
if(pos > m_length) return 0; |
40 |
|
|
|
41 |
|
52 |
int diff = (int)(pos + num_bytes) - (int)m_length; |
42 |
|
52 |
num_bytes -= diff < 0 ? 0 : (unsigned int)diff; |
43 |
|
|
|
44 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 52 times.
|
52 |
memcpy(out_buffer, (const char*)m_data + pos, num_bytes); |
45 |
|
52 |
return num_bytes; |
46 |
|
|
} |
47 |
|
|
|
48 |
|
52 |
virtual size_t get_size() |
49 |
|
|
{ |
50 |
|
52 |
return m_length; |
51 |
|
|
} |
52 |
|
|
|
53 |
|
|
private: |
54 |
|
|
const void* m_data; |
55 |
|
|
size_t m_length; |
56 |
|
|
}; |
57 |
|
|
|
58 |
|
|
class physical_file : public virtual_file |
59 |
|
|
{ |
60 |
|
|
public: |
61 |
|
569 |
physical_file() |
62 |
|
569 |
: m_file_handle(InvalidFileHandle) |
63 |
|
|
{ |
64 |
|
569 |
} |
65 |
|
|
|
66 |
|
2276 |
virtual ~physical_file() |
67 |
|
1138 |
{ |
68 |
|
1138 |
close(); |
69 |
|
2276 |
} |
70 |
|
|
|
71 |
|
569 |
virtual_file_error open(const string& path) |
72 |
|
|
{ |
73 |
1/2
✓ Branch 0 taken 569 times.
✗ Branch 1 not taken.
|
569 |
if (path != "") |
74 |
|
|
{ |
75 |
|
|
// randomdude999: checking this before file regularity to improve error messages |
76 |
5/5
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 289 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 280 times.
✓ Branch 4 taken 281 times.
|
569 |
if(!file_exists((const char*)path)) return vfe_doesnt_exist; |
77 |
5/5
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 272 times.
✓ Branch 4 taken 275 times.
|
553 |
if(!check_is_regular_file((const char*)path)) return vfe_not_regular_file; |
78 |
|
|
|
79 |
|
541 |
FileOpenError error = FileOpenError_None; |
80 |
|
|
|
81 |
2/4
✓ Branch 0 taken 266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
|
541 |
m_file_handle = open_file((const char*)path, FileOpenMode_Read, &error); |
82 |
|
|
|
83 |
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 266 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 275 times.
|
541 |
if (m_file_handle == InvalidFileHandle) |
84 |
|
|
{ |
85 |
|
✗ |
if (error == FileOpenError_NotFound) |
86 |
|
|
{ |
87 |
|
✗ |
return vfe_doesnt_exist; |
88 |
|
|
} |
89 |
|
✗ |
else if (error == FileOpenError_AccessDenied) |
90 |
|
|
{ |
91 |
|
✗ |
return vfe_access_denied; |
92 |
|
|
} |
93 |
|
|
else |
94 |
|
|
{ |
95 |
|
✗ |
return vfe_unknown; |
96 |
|
|
} |
97 |
|
|
} |
98 |
|
|
|
99 |
|
541 |
return vfe_none; |
100 |
|
|
} |
101 |
|
|
|
102 |
|
✗ |
return vfe_doesnt_exist; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
1110 |
virtual void close() |
106 |
|
|
{ |
107 |
4/4
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 275 times.
✓ Branch 3 taken 289 times.
|
1110 |
if (m_file_handle != InvalidFileHandle) |
108 |
|
|
{ |
109 |
|
541 |
close_file(m_file_handle); |
110 |
|
541 |
m_file_handle = InvalidFileHandle; |
111 |
|
|
} |
112 |
|
1110 |
} |
113 |
|
|
|
114 |
|
553 |
virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes) |
115 |
|
|
{ |
116 |
|
553 |
set_file_pos(m_file_handle, (uint64_t)pos); |
117 |
|
553 |
return (size_t)read_file(m_file_handle, out_buffer, (uint32_t)num_bytes); |
118 |
|
|
} |
119 |
|
|
|
120 |
|
541 |
virtual size_t get_size() |
121 |
|
|
{ |
122 |
|
541 |
return (size_t)get_file_size(m_file_handle); |
123 |
|
|
} |
124 |
|
|
|
125 |
|
|
private: |
126 |
|
|
friend class virtual_filesystem; |
127 |
|
|
|
128 |
|
|
FileHandleType m_file_handle; |
129 |
|
|
}; |
130 |
|
|
|
131 |
|
|
|
132 |
|
|
|
133 |
|
286 |
void virtual_filesystem::initialize(const char** include_paths, size_t num_include_paths) |
134 |
|
|
{ |
135 |
|
286 |
m_include_paths.reset(); |
136 |
|
|
|
137 |
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 286 times.
|
291 |
for (size_t i = 0; i < num_include_paths; ++i) |
138 |
|
|
{ |
139 |
|
5 |
m_include_paths[(int)i] = include_paths[i]; |
140 |
|
|
} |
141 |
|
|
|
142 |
|
286 |
m_last_error = vfe_none; |
143 |
|
286 |
m_memory_files.reset(); |
144 |
|
286 |
} |
145 |
|
|
|
146 |
|
286 |
void virtual_filesystem::destroy() |
147 |
|
|
{ |
148 |
|
286 |
m_include_paths.reset(); |
149 |
|
286 |
} |
150 |
|
|
|
151 |
|
|
|
152 |
|
621 |
virtual_file_handle virtual_filesystem::open_file(const char* path, const char* base_path) |
153 |
|
|
{ |
154 |
|
621 |
m_last_error = vfe_none; |
155 |
|
|
|
156 |
2/3
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 341 times.
✗ Branch 2 not taken.
|
621 |
string absolutepath = create_absolute_path(base_path, path); |
157 |
|
|
|
158 |
2/3
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 341 times.
✗ Branch 2 not taken.
|
621 |
virtual_file_type vft = get_file_type_from_path(absolutepath); |
159 |
|
|
|
160 |
2/2
✓ Branch 0 taken 569 times.
✓ Branch 1 taken 52 times.
|
621 |
if (vft != vft_memory_file) |
161 |
|
|
{ |
162 |
1/2
✓ Branch 0 taken 569 times.
✗ Branch 1 not taken.
|
569 |
throw_warning(0, warn_check_memory_file, path); |
163 |
|
|
} |
164 |
|
|
|
165 |
2/3
✓ Branch 0 taken 569 times.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
|
621 |
switch (vft) |
166 |
|
|
{ |
167 |
|
569 |
case vft_physical_file: |
168 |
|
|
{ |
169 |
1/2
✓ Branch 0 taken 569 times.
✗ Branch 1 not taken.
|
569 |
physical_file* new_file = new physical_file; |
170 |
|
|
|
171 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 569 times.
|
569 |
if (new_file == nullptr) |
172 |
|
|
{ |
173 |
|
✗ |
m_last_error = vfe_unknown; |
174 |
|
✗ |
return INVALID_VIRTUAL_FILE_HANDLE; |
175 |
|
|
} |
176 |
|
|
|
177 |
2/4
✓ Branch 0 taken 280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 289 times.
✗ Branch 3 not taken.
|
569 |
virtual_file_error error = new_file->open(absolutepath); |
178 |
|
|
|
179 |
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 541 times.
|
569 |
if (error != vfe_none) |
180 |
|
|
{ |
181 |
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 |
delete new_file; |
182 |
|
28 |
m_last_error = error; |
183 |
|
28 |
return INVALID_VIRTUAL_FILE_HANDLE; |
184 |
|
|
} |
185 |
|
|
|
186 |
|
541 |
return static_cast<virtual_file_handle>(new_file); |
187 |
|
|
} |
188 |
|
|
|
189 |
|
52 |
case vft_memory_file: |
190 |
|
|
{ |
191 |
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
✗ Branch 5 not taken.
|
52 |
if(m_memory_files.exists(absolutepath)) { |
192 |
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
|
52 |
memory_buffer mem_buf = m_memory_files.find(absolutepath); |
193 |
1/2
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
|
52 |
memory_file* new_file = new memory_file(mem_buf.data, mem_buf.length); |
194 |
|
52 |
return static_cast<virtual_file_handle>(new_file); |
195 |
|
|
} else { |
196 |
|
✗ |
m_last_error = vfe_doesnt_exist; |
197 |
|
✗ |
return INVALID_VIRTUAL_FILE_HANDLE; |
198 |
|
|
} |
199 |
|
|
} |
200 |
|
|
|
201 |
|
✗ |
default: |
202 |
|
|
// We should not get here |
203 |
|
✗ |
m_last_error = vfe_unknown; |
204 |
|
✗ |
return INVALID_VIRTUAL_FILE_HANDLE; |
205 |
|
|
} |
206 |
|
621 |
} |
207 |
|
|
|
208 |
|
593 |
void virtual_filesystem::close_file(virtual_file_handle file_handle) |
209 |
|
|
{ |
210 |
1/2
✓ Branch 0 taken 593 times.
✗ Branch 1 not taken.
|
593 |
if (file_handle != INVALID_VIRTUAL_FILE_HANDLE) |
211 |
|
|
{ |
212 |
|
593 |
virtual_file* file = static_cast<virtual_file*>(file_handle); |
213 |
|
|
|
214 |
|
593 |
file->close(); |
215 |
|
|
|
216 |
1/2
✓ Branch 0 taken 593 times.
✗ Branch 1 not taken.
|
593 |
delete file; |
217 |
|
|
} |
218 |
|
593 |
} |
219 |
|
|
|
220 |
|
|
|
221 |
|
|
|
222 |
|
605 |
size_t virtual_filesystem::read_file(virtual_file_handle file_handle, void* out_buffer, size_t pos, size_t num_bytes) |
223 |
|
|
{ |
224 |
1/2
✓ Branch 0 taken 605 times.
✗ Branch 1 not taken.
|
605 |
if (file_handle != INVALID_VIRTUAL_FILE_HANDLE) |
225 |
|
|
{ |
226 |
|
605 |
virtual_file* file = static_cast<virtual_file*>(file_handle); |
227 |
|
|
|
228 |
|
605 |
return file->read(out_buffer, pos, num_bytes); |
229 |
|
|
} |
230 |
|
|
|
231 |
|
✗ |
return 0u; |
232 |
|
|
} |
233 |
|
|
|
234 |
|
593 |
size_t virtual_filesystem::get_file_size(virtual_file_handle file_handle) |
235 |
|
|
{ |
236 |
1/2
✓ Branch 0 taken 593 times.
✗ Branch 1 not taken.
|
593 |
if (file_handle != INVALID_VIRTUAL_FILE_HANDLE) |
237 |
|
|
{ |
238 |
|
593 |
virtual_file* file = static_cast<virtual_file*>(file_handle); |
239 |
|
|
|
240 |
|
593 |
return file->get_size(); |
241 |
|
|
} |
242 |
|
|
|
243 |
|
✗ |
return 0u; |
244 |
|
|
} |
245 |
|
|
|
246 |
|
|
|
247 |
|
621 |
virtual_filesystem::virtual_file_type virtual_filesystem::get_file_type_from_path(const char* path) |
248 |
|
|
{ |
249 |
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 289 times.
|
621 |
if(m_memory_files.exists(path)) { |
250 |
|
52 |
return vft_memory_file; |
251 |
|
|
} else { |
252 |
|
569 |
return vft_physical_file; |
253 |
|
|
} |
254 |
|
|
} |
255 |
|
|
|
256 |
|
34 |
void virtual_filesystem::add_memory_file(const char* name, const void* buffer, size_t length) { |
257 |
|
34 |
memory_buffer mem_buf = { buffer, length }; |
258 |
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 |
string normalized_path = normalize_path(name); |
259 |
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
|
34 |
m_memory_files.remove(normalized_path); |
260 |
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
|
34 |
m_memory_files.create(normalized_path) = mem_buf; |
261 |
|
68 |
} |
262 |
|
|
|
263 |
|
5988 |
bool virtual_filesystem::is_path_absolute(const char* path) |
264 |
|
|
{ |
265 |
|
5988 |
return path_is_absolute(path); |
266 |
|
|
} |
267 |
|
|
|
268 |
|
5988 |
string virtual_filesystem::create_absolute_path(const char* base, const char* target) |
269 |
|
|
{ |
270 |
12/12
✓ Branch 0 taken 3383 times.
✓ Branch 1 taken 2605 times.
✓ Branch 2 taken 2403 times.
✓ Branch 3 taken 2360 times.
✓ Branch 4 taken 3628 times.
✓ Branch 5 taken 1374 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 2400 times.
✓ Branch 8 taken 988 times.
✓ Branch 9 taken 3769 times.
✓ Branch 10 taken 1236 times.
✓ Branch 11 taken 1369 times.
|
5988 |
if (is_path_absolute(target) || base == nullptr || base[0] == '\0') |
271 |
|
|
{ |
272 |
2/3
✓ Branch 0 taken 983 times.
✓ Branch 1 taken 1236 times.
✗ Branch 2 not taken.
|
2219 |
return normalize_path(target); |
273 |
|
|
} |
274 |
|
|
|
275 |
2/3
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 1369 times.
✗ Branch 2 not taken.
|
3769 |
string path_to_use = ""; |
276 |
2/3
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 1369 times.
✗ Branch 2 not taken.
|
3769 |
string test_path = ""; |
277 |
|
|
|
278 |
2/3
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 1369 times.
✗ Branch 2 not taken.
|
3769 |
test_path = normalize_path(target); |
279 |
|
|
|
280 |
|
|
// First check if path is absolute |
281 |
2/4
✓ Branch 0 taken 3769 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3769 times.
|
3769 |
if (path_is_absolute(test_path)) |
282 |
|
|
{ |
283 |
|
✗ |
if (m_memory_files.exists(test_path) || file_exists(test_path)) |
284 |
|
|
{ |
285 |
|
✗ |
path_to_use = test_path; |
286 |
|
|
} |
287 |
|
|
} |
288 |
|
|
else |
289 |
|
|
{ |
290 |
|
|
// Now check if path exists relative to the base path |
291 |
1/2
✓ Branch 0 taken 3769 times.
✗ Branch 1 not taken.
|
3769 |
if (base != nullptr) |
292 |
|
|
{ |
293 |
3/8
✓ Branch 0 taken 2400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3769 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1369 times.
✗ Branch 7 not taken.
|
3769 |
test_path = create_combined_path(dir(base), target); |
294 |
|
|
} |
295 |
|
|
|
296 |
13/16
✓ Branch 0 taken 3769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2400 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3769 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3766 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 2387 times.
✓ Branch 9 taken 13 times.
✓ Branch 10 taken 3753 times.
✓ Branch 11 taken 13 times.
✓ Branch 12 taken 1341 times.
✓ Branch 13 taken 25 times.
✓ Branch 14 taken 1344 times.
✓ Branch 15 taken 25 times.
|
3769 |
if (test_path != "" && (m_memory_files.exists(test_path) || file_exists(test_path))) |
297 |
|
|
{ |
298 |
1/2
✓ Branch 0 taken 3731 times.
✗ Branch 1 not taken.
|
3731 |
path_to_use = test_path; |
299 |
|
|
} |
300 |
|
|
else |
301 |
|
|
{ |
302 |
|
|
// Finally check if path exists relative to any include path |
303 |
|
38 |
bool found = false; |
304 |
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 13 times.
|
65 |
for (int i = 0; i < m_include_paths.count; ++i) |
305 |
|
|
{ |
306 |
2/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
✗ Branch 5 not taken.
|
39 |
test_path = create_combined_path(m_include_paths[i], target); |
307 |
|
|
|
308 |
7/14
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 27 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 27 times.
✓ Branch 12 taken 12 times.
✓ Branch 13 taken 27 times.
|
39 |
if (m_memory_files.exists(test_path) || file_exists(test_path)) |
309 |
|
|
{ |
310 |
|
12 |
found = true; |
311 |
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 |
path_to_use = test_path; |
312 |
|
12 |
break; |
313 |
|
|
} |
314 |
|
|
} |
315 |
|
|
|
316 |
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 12 times.
|
38 |
if (!found) |
317 |
|
|
{ |
318 |
|
|
// Reset our path so that we don't return an empty one |
319 |
|
|
// (that will do some weird shit and fuck up error messages) |
320 |
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
26 |
path_to_use = target; |
321 |
|
|
} |
322 |
|
|
} |
323 |
|
|
} |
324 |
|
|
|
325 |
|
3769 |
return path_to_use; |
326 |
|
3769 |
} |
327 |
|
|
|