asar coverage - build #218


src/asar/
File: src/asar/virtualfile.cpp
Date: 2024-03-02 09:45:45
Lines:
98/144
68.1%
Functions:
19/27
70.4%
Branches:
75/147
51.0%

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