GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* The ManaPlus Client |
||
3 |
* Copyright (C) 2013-2019 The ManaPlus Developers |
||
4 |
* Copyright (C) 2019-2021 Andrei Karas |
||
5 |
* |
||
6 |
* This file is part of The ManaPlus Client. |
||
7 |
* |
||
8 |
* This program is free software; you can redistribute it and/or modify |
||
9 |
* it under the terms of the GNU General Public License as published by |
||
10 |
* the Free Software Foundation; either version 2 of the License, or |
||
11 |
* any later version. |
||
12 |
* |
||
13 |
* This program is distributed in the hope that it will be useful, |
||
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 |
* GNU General Public License for more details. |
||
17 |
* |
||
18 |
* You should have received a copy of the GNU General Public License |
||
19 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
20 |
*/ |
||
21 |
|||
22 |
#include "fs/virtfs/fs.h" |
||
23 |
|||
24 |
#include "fs/files.h" |
||
25 |
#include "fs/paths.h" |
||
26 |
|||
27 |
#include "fs/virtfs/direntry.h" |
||
28 |
#include "fs/virtfs/file.h" |
||
29 |
#include "fs/virtfs/fsdir.h" |
||
30 |
#include "fs/virtfs/fsfuncs.h" |
||
31 |
#include "fs/virtfs/fszip.h" |
||
32 |
#include "fs/virtfs/list.h" |
||
33 |
#include "fs/virtfs/zipentry.h" |
||
34 |
#include "fs/virtfs/zipreader.h" |
||
35 |
|||
36 |
#include "utils/checkutils.h" |
||
37 |
#include "utils/foreach.h" |
||
38 |
#include "utils/stdmove.h" |
||
39 |
#include "utils/stringutils.h" |
||
40 |
|||
41 |
#include "debug.h" |
||
42 |
|||
43 |
const char *dirSeparator = nullptr; |
||
44 |
|||
45 |
#ifdef UNITTESTS |
||
46 |
#define reportNonTests(a, b) logger->log(a, b); |
||
47 |
#else // UNITTESTS |
||
48 |
#define reportNonTests(a, b) reportAlways(a, b) |
||
49 |
#endif // UNITTESTS |
||
50 |
|||
51 |
namespace VirtFs |
||
52 |
{ |
||
53 |
namespace |
||
54 |
{ |
||
55 |
1 |
STD_VECTOR<FsEntry*> mEntries; |
|
56 |
} // namespace |
||
57 |
|||
58 |
120 |
void init(const std::string &restrict name) |
|
59 |
{ |
||
60 |
updateDirSeparator(); |
||
61 |
120 |
FsDir::init(name); |
|
62 |
120 |
FsZip::init(); |
|
63 |
120 |
} |
|
64 |
|||
65 |
1 |
void updateDirSeparator() |
|
66 |
{ |
||
67 |
#ifdef WIN32 |
||
68 |
dirSeparator = "\\"; |
||
69 |
#else // WIN32 |
||
70 |
121 |
dirSeparator = "/"; |
|
71 |
#endif // WIN32 |
||
72 |
1 |
} |
|
73 |
|||
74 |
2 |
const char *getDirSeparator() |
|
75 |
{ |
||
76 |
2 |
return dirSeparator; |
|
77 |
} |
||
78 |
|||
79 |
293 |
const char *getBaseDir() |
|
80 |
{ |
||
81 |
293 |
return FsDir::getBaseDir(); |
|
82 |
} |
||
83 |
|||
84 |
583 |
const char *getUserDir() |
|
85 |
{ |
||
86 |
583 |
return FsDir::getUserDir(); |
|
87 |
} |
||
88 |
|||
89 |
353 |
STD_VECTOR<FsEntry*> &getEntries() |
|
90 |
{ |
||
91 |
353 |
return mEntries; |
|
92 |
} |
||
93 |
|||
94 |
706 |
FsEntry *searchByRootInternal(const std::string &restrict root, |
|
95 |
const std::string &restrict subDir) |
||
96 |
{ |
||
97 |
✓✓ | 3852 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
98 |
{ |
||
99 |
391 |
const FsEntry *const entry = *it; |
|
100 |
✓✓✓✓ ✓✓ |
472 |
if (entry->root == root && |
101 |
81 |
entry->subDir == subDir) |
|
102 |
{ |
||
103 |
return *it; |
||
104 |
} |
||
105 |
} |
||
106 |
return nullptr; |
||
107 |
} |
||
108 |
|||
109 |
FsEntry *searchByTypeInternal(const std::string &restrict root, |
||
110 |
const FsEntryTypeT type) |
||
111 |
{ |
||
112 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
||
113 |
{ |
||
114 |
const FsEntry *const entry = *it; |
||
115 |
if (entry->root == root && |
||
116 |
entry->type == type) |
||
117 |
{ |
||
118 |
return *it; |
||
119 |
} |
||
120 |
} |
||
121 |
return nullptr; |
||
122 |
} |
||
123 |
|||
124 |
4634 |
bool exists(std::string name) |
|
125 |
{ |
||
126 |
4634 |
prepareFsPath(name); |
|
127 |
✓✓ | 4634 |
if (checkPath(name) == false) |
128 |
{ |
||
129 |
✓✗ | 6 |
reportAlways("FsDir::exists invalid path: %s", |
130 |
name.c_str()) |
||
131 |
return false; |
||
132 |
} |
||
133 |
|||
134 |
9264 |
std::string rootDir = name; |
|
135 |
✓✗✓✗ ✓✓ |
18528 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
136 |
4621 |
rootDir += dirSeparator; |
|
137 |
|||
138 |
✓✓ | 28552 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
139 |
{ |
||
140 |
8463 |
FsEntry *const entry = *it; |
|
141 |
✓✗✓✓ |
42315 |
if (entry->funcs->exists(entry, name, rootDir) == true) |
142 |
return true; |
||
143 |
} |
||
144 |
return false; |
||
145 |
} |
||
146 |
|||
147 |
27 |
List *enumerateFiles(std::string dirName) |
|
148 |
{ |
||
149 |
✓✗ | 27 |
List *const list = new List; |
150 |
27 |
prepareFsPath(dirName); |
|
151 |
✗✓ | 27 |
if (checkPath(dirName) == false) |
152 |
{ |
||
153 |
reportAlways("VirtFs::enumerateFiles invalid path: %s", |
||
154 |
dirName.c_str()) |
||
155 |
return list; |
||
156 |
} |
||
157 |
|||
158 |
81 |
std::string rootDir = STD_MOVE(dirName); |
|
159 |
✓✗✓✗ ✓✓ |
108 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
160 |
13 |
rootDir += dirSeparator; |
|
161 |
27 |
StringVect &names = list->names; |
|
162 |
|||
163 |
✓✓ | 170 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
164 |
{ |
||
165 |
35 |
FsEntry *const entry = *it; |
|
166 |
✓✗ | 105 |
entry->funcs->enumerate(entry, rootDir, names); |
167 |
} |
||
168 |
|||
169 |
27 |
return list; |
|
170 |
} |
||
171 |
|||
172 |
15 |
void getFiles(std::string dirName, |
|
173 |
StringVect &list) |
||
174 |
{ |
||
175 |
15 |
prepareFsPath(dirName); |
|
176 |
✗✓ | 15 |
if (checkPath(dirName) == false) |
177 |
{ |
||
178 |
reportAlways("VirtFs::enumerateFiles invalid path: %s", |
||
179 |
dirName.c_str()) |
||
180 |
return; |
||
181 |
} |
||
182 |
|||
183 |
45 |
std::string rootDir = STD_MOVE(dirName); |
|
184 |
✓✗✓✗ ✓✓ |
60 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
185 |
9 |
rootDir += dirSeparator; |
|
186 |
|||
187 |
✓✓ | 92 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
188 |
{ |
||
189 |
17 |
FsEntry *const entry = *it; |
|
190 |
✓✗ | 51 |
entry->funcs->getFiles(entry, rootDir, list); |
191 |
} |
||
192 |
15 |
} |
|
193 |
|||
194 |
95 |
void getFilesWithDir(std::string dirName, |
|
195 |
StringVect &list) |
||
196 |
{ |
||
197 |
95 |
prepareFsPath(dirName); |
|
198 |
✗✓ | 95 |
if (checkPath(dirName) == false) |
199 |
{ |
||
200 |
reportAlways("VirtFs::enumerateFiles invalid path: %s", |
||
201 |
dirName.c_str()) |
||
202 |
return; |
||
203 |
} |
||
204 |
|||
205 |
285 |
std::string rootDir = STD_MOVE(dirName); |
|
206 |
✓✗✓✗ ✓✓ |
380 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
207 |
89 |
rootDir += dirSeparator; |
|
208 |
|||
209 |
✓✓ | 653 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
210 |
{ |
||
211 |
178 |
FsEntry *const entry = *it; |
|
212 |
✓✗ | 178 |
entry->funcs->getFilesWithDir(entry, rootDir, list); |
213 |
} |
||
214 |
95 |
} |
|
215 |
|||
216 |
|||
217 |
12 |
void getDirs(std::string dirName, |
|
218 |
StringVect &list) |
||
219 |
{ |
||
220 |
12 |
prepareFsPath(dirName); |
|
221 |
✗✓ | 12 |
if (checkPath(dirName) == false) |
222 |
{ |
||
223 |
reportAlways("VirtFs::enumerateFiles invalid path: %s", |
||
224 |
dirName.c_str()) |
||
225 |
return; |
||
226 |
} |
||
227 |
|||
228 |
36 |
std::string rootDir = STD_MOVE(dirName); |
|
229 |
✓✗✓✗ ✓✓ |
48 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
230 |
7 |
rootDir += dirSeparator; |
|
231 |
|||
232 |
✓✓ | 74 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
233 |
{ |
||
234 |
14 |
FsEntry *const entry = *it; |
|
235 |
✓✗ | 42 |
entry->funcs->getDirs(entry, rootDir, list); |
236 |
} |
||
237 |
12 |
} |
|
238 |
|||
239 |
661 |
bool isDirectory(std::string name) |
|
240 |
{ |
||
241 |
661 |
prepareFsPath(name); |
|
242 |
✗✓ | 661 |
if (checkPath(name) == false) |
243 |
{ |
||
244 |
reportAlways("VirtFs::isDirectory invalid path: %s", |
||
245 |
name.c_str()) |
||
246 |
return false; |
||
247 |
} |
||
248 |
1983 |
std::string dirName = STD_MOVE(name); |
|
249 |
✓✗✓✗ ✓✓ |
2644 |
if (findLast(dirName, std::string(dirSeparator)) == false) |
250 |
171 |
dirName += dirSeparator; |
|
251 |
|||
252 |
✓✓ | 3817 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
253 |
{ |
||
254 |
1001 |
FsEntry *const entry = *it; |
|
255 |
1001 |
bool isDirFlag(false); |
|
256 |
✓✗✓✓ |
3003 |
if (entry->funcs->isDirectory(entry, dirName, isDirFlag) == true) |
257 |
{ |
||
258 |
489 |
return isDirFlag; |
|
259 |
} |
||
260 |
} |
||
261 |
return false; |
||
262 |
} |
||
263 |
|||
264 |
bool isSymbolicLink(const std::string &restrict name) |
||
265 |
{ |
||
266 |
return FsDir::isSymbolicLink(name); |
||
267 |
} |
||
268 |
|||
269 |
27 |
void freeList(List *restrict const handle) |
|
270 |
{ |
||
271 |
✓✗ | 27 |
delete handle; |
272 |
27 |
} |
|
273 |
|||
274 |
2451 |
File *openRead(std::string filename) |
|
275 |
{ |
||
276 |
2451 |
prepareFsPath(filename); |
|
277 |
✗✓ | 2451 |
if (checkPath(filename) == false) |
278 |
{ |
||
279 |
reportAlways("VirtFs::openRead invalid path: %s", |
||
280 |
filename.c_str()) |
||
281 |
return nullptr; |
||
282 |
} |
||
283 |
✓✓ | 13946 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
284 |
{ |
||
285 |
4072 |
FsEntry *const entry = *it; |
|
286 |
✓✗ | 12216 |
File *const file = entry->funcs->openRead(entry, filename); |
287 |
✓✓ | 4072 |
if (file != nullptr) |
288 |
return file; |
||
289 |
} |
||
290 |
return nullptr; |
||
291 |
} |
||
292 |
|||
293 |
File *openWrite(std::string filename) |
||
294 |
{ |
||
295 |
prepareFsPath(filename); |
||
296 |
if (checkPath(filename) == false) |
||
297 |
{ |
||
298 |
reportAlways("VirtFs::openWrite invalid path: %s", |
||
299 |
filename.c_str()) |
||
300 |
return nullptr; |
||
301 |
} |
||
302 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
||
303 |
{ |
||
304 |
FsEntry *const entry = *it; |
||
305 |
File *const file = entry->funcs->openWrite(entry, filename); |
||
306 |
if (file != nullptr) |
||
307 |
return file; |
||
308 |
} |
||
309 |
return nullptr; |
||
310 |
} |
||
311 |
|||
312 |
File *openAppend(std::string filename) |
||
313 |
{ |
||
314 |
prepareFsPath(filename); |
||
315 |
if (checkPath(filename) == false) |
||
316 |
{ |
||
317 |
reportAlways("VirtFs::openAppend invalid path: %s", |
||
318 |
filename.c_str()) |
||
319 |
return nullptr; |
||
320 |
} |
||
321 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
||
322 |
{ |
||
323 |
FsEntry *const entry = *it; |
||
324 |
File *const file = entry->funcs->openAppend(entry, filename); |
||
325 |
if (file != nullptr) |
||
326 |
return file; |
||
327 |
} |
||
328 |
return nullptr; |
||
329 |
} |
||
330 |
|||
331 |
bool setWriteDir(const std::string &restrict newDir) |
||
332 |
{ |
||
333 |
return FsDir::setWriteDir(newDir); |
||
334 |
} |
||
335 |
|||
336 |
605 |
void addEntry(FsEntry *const entry, |
|
337 |
const Append append) |
||
338 |
{ |
||
339 |
✓✓ | 605 |
if (append == Append_true) |
340 |
58 |
mEntries.push_back(entry); |
|
341 |
else |
||
342 |
1094 |
mEntries.insert(mEntries.begin(), entry); |
|
343 |
605 |
} |
|
344 |
|||
345 |
510 |
bool mountDirInternal(const std::string &restrict newDir, |
|
346 |
std::string subDir, |
||
347 |
const Append append) |
||
348 |
{ |
||
349 |
✗✓ | 510 |
if (newDir.find(".zip") != std::string::npos) |
350 |
{ |
||
351 |
reportAlways("Called FsDir::mount with zip archive") |
||
352 |
return false; |
||
353 |
} |
||
354 |
1020 |
std::string rootDir = newDir; |
|
355 |
✓✗✓✗ ✓✓ |
2040 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
356 |
506 |
rootDir += dirSeparator; |
|
357 |
✓✓ | 1020 |
if (subDir == dirSeparator) |
358 |
{ |
||
359 |
subDir.clear(); |
||
360 |
} |
||
361 |
✓✓✗✓ ✓✓ |
1474 |
else if (!subDir.empty() && |
362 |
✓✗✓✗ ✓✓✗✗ |
606 |
findLast(subDir, std::string(dirSeparator)) == false) |
363 |
{ |
||
364 |
43 |
subDir += dirSeparator; |
|
365 |
} |
||
366 |
510 |
const FsEntry *const entry = searchByRootInternal(rootDir, subDir); |
|
367 |
✗✓ | 510 |
if (entry != nullptr) |
368 |
{ |
||
369 |
reportAlways("VirtFs::mount already exists: %s", |
||
370 |
newDir.c_str()) |
||
371 |
return false; |
||
372 |
} |
||
373 |
✓✓ | 510 |
if (subDir.empty()) |
374 |
{ |
||
375 |
✓✗✓✗ |
934 |
logger->log("Add virtual directory: " + newDir); |
376 |
} |
||
377 |
else |
||
378 |
{ |
||
379 |
86 |
logger->log("Add virtual directory: %s with dir %s", |
|
380 |
newDir.c_str(), |
||
381 |
✓✗ | 43 |
subDir.c_str()); |
382 |
} |
||
383 |
|||
384 |
addEntry(new DirEntry(newDir, |
||
385 |
rootDir, |
||
386 |
subDir, |
||
387 |
✓✗ | 1020 |
rootDir + subDir, |
388 |
✓✗✓✗ ✓✗ |
510 |
FsDir::getFuncs()), |
389 |
✓✗ | 510 |
append); |
390 |
510 |
return true; |
|
391 |
} |
||
392 |
|||
393 |
31 |
bool mountDir(std::string newDir, |
|
394 |
const Append append) |
||
395 |
{ |
||
396 |
31 |
prepareFsPath(newDir); |
|
397 |
✗✓ | 31 |
if (Files::existsLocal(newDir) == false) |
398 |
{ |
||
399 |
reportNonTests("VirtFs::mount directory not exists: %s", |
||
400 |
newDir.c_str()) |
||
401 |
return false; |
||
402 |
} |
||
403 |
✓✗ | 124 |
return mountDirInternal(newDir, dirSeparator, append); |
404 |
} |
||
405 |
|||
406 |
10 |
bool mountDir2(std::string newDir, |
|
407 |
std::string subDir, |
||
408 |
const Append append) |
||
409 |
{ |
||
410 |
10 |
prepareFsPath(newDir); |
|
411 |
10 |
prepareFsPath(subDir); |
|
412 |
✗✓ | 10 |
if (Files::existsLocal(newDir) == false) |
413 |
{ |
||
414 |
reportNonTests("VirtFs::mount directory not exists: %s", |
||
415 |
newDir.c_str()) |
||
416 |
return false; |
||
417 |
} |
||
418 |
✓✗ | 20 |
return mountDirInternal(newDir, subDir, append); |
419 |
} |
||
420 |
|||
421 |
805 |
bool mountDirSilent(std::string newDir, |
|
422 |
const Append append) |
||
423 |
{ |
||
424 |
805 |
prepareFsPath(newDir); |
|
425 |
✓✓ | 805 |
if (Files::existsLocal(newDir) == false) |
426 |
{ |
||
427 |
399 |
logger->log("VirtFs::mount directory not exists: %s", |
|
428 |
399 |
newDir.c_str()); |
|
429 |
399 |
return false; |
|
430 |
} |
||
431 |
✓✗ | 812 |
return mountDirInternal(newDir, std::string(), append); |
432 |
} |
||
433 |
|||
434 |
16 |
bool mountDirSilent2(std::string newDir, |
|
435 |
std::string subDir, |
||
436 |
const Append append) |
||
437 |
{ |
||
438 |
16 |
prepareFsPath(newDir); |
|
439 |
16 |
prepareFsPath(subDir); |
|
440 |
✓✓ | 16 |
if (Files::existsLocal(newDir) == false) |
441 |
{ |
||
442 |
7 |
logger->log("VirtFs::mount directory not exists: %s", |
|
443 |
7 |
newDir.c_str()); |
|
444 |
7 |
return false; |
|
445 |
} |
||
446 |
✓✗ | 18 |
return mountDirInternal(newDir, subDir, append); |
447 |
} |
||
448 |
|||
449 |
#ifdef UNITTESTS |
||
450 |
28 |
bool mountDirSilentTest(std::string newDir, |
|
451 |
const Append append) |
||
452 |
{ |
||
453 |
28 |
prepareFsPath(newDir); |
|
454 |
✓✗ | 28 |
if (Files::existsLocal(newDir) == false) |
455 |
{ |
||
456 |
28 |
logger->log("VirtFs::mount directory not exists: %s", |
|
457 |
28 |
newDir.c_str()); |
|
458 |
} |
||
459 |
✓✗ | 56 |
return mountDirInternal(newDir, std::string(), append); |
460 |
} |
||
461 |
|||
462 |
26 |
bool mountDirSilentTest2(std::string newDir, |
|
463 |
std::string subDir, |
||
464 |
const Append append) |
||
465 |
{ |
||
466 |
26 |
prepareFsPath(newDir); |
|
467 |
26 |
prepareFsPath(subDir); |
|
468 |
✓✗ | 26 |
if (Files::existsLocal(newDir) == false) |
469 |
{ |
||
470 |
26 |
logger->log("VirtFs::mount directory not exists: %s", |
|
471 |
26 |
newDir.c_str()); |
|
472 |
} |
||
473 |
✓✗ | 52 |
return mountDirInternal(newDir, subDir, append); |
474 |
} |
||
475 |
#endif // UNITTESTS |
||
476 |
|||
477 |
869 |
bool unmountDirInternal(std::string oldDir, |
|
478 |
std::string subDir) |
||
479 |
{ |
||
480 |
✓✗✓✓ |
3476 |
if (findLast(oldDir, std::string(dirSeparator)) == false) |
481 |
865 |
oldDir += dirSeparator; |
|
482 |
✗✓ | 1738 |
if (subDir == dirSeparator) |
483 |
{ |
||
484 |
subDir.clear(); |
||
485 |
} |
||
486 |
✓✓✓✓ ✓✓ |
2628 |
else if (!subDir.empty() && |
487 |
✓✗✓✗ ✓✓✗✗ |
932 |
findLast(subDir, std::string(dirSeparator)) == false) |
488 |
{ |
||
489 |
20 |
subDir += dirSeparator; |
|
490 |
} |
||
491 |
✓✓ | 3284 |
FOR_EACH (STD_VECTOR<FsEntry*>::iterator, it, mEntries) |
492 |
{ |
||
493 |
1134 |
FsEntry *const entry = *it; |
|
494 |
✓✗✓✓ |
2729 |
if (entry->root == oldDir && |
495 |
✓✓✓✓ |
1595 |
entry->type == FsEntryType::Dir && |
496 |
461 |
entry->subDir == subDir) |
|
497 |
{ |
||
498 |
DirEntry *const dirEntry = static_cast<DirEntry*>( |
||
499 |
457 |
entry); |
|
500 |
✓✓ | 457 |
if (subDir.empty()) |
501 |
{ |
||
502 |
✓✗ | 880 |
logger->log("Remove virtual directory: " + oldDir); |
503 |
} |
||
504 |
else |
||
505 |
{ |
||
506 |
34 |
logger->log("Remove virtual directory: %s with dir %s", |
|
507 |
oldDir.c_str(), |
||
508 |
17 |
subDir.c_str()); |
|
509 |
} |
||
510 |
914 |
mEntries.erase(it); |
|
511 |
✓✗ | 457 |
delete dirEntry; |
512 |
return true; |
||
513 |
} |
||
514 |
} |
||
515 |
return false; |
||
516 |
} |
||
517 |
|||
518 |
52 |
bool unmountDir(std::string oldDir) |
|
519 |
{ |
||
520 |
52 |
prepareFsPath(oldDir); |
|
521 |
✗✓ | 52 |
if (oldDir.find(".zip") != std::string::npos) |
522 |
{ |
||
523 |
reportAlways("Called unmount with zip archive") |
||
524 |
return false; |
||
525 |
} |
||
526 |
✓✗✓✓ |
208 |
if (unmountDirInternal(oldDir, std::string()) == false) |
527 |
{ |
||
528 |
✓✗ | 42 |
reportAlways("VirtFs::unmountDir not exists: %s", |
529 |
oldDir.c_str()) |
||
530 |
return false; |
||
531 |
} |
||
532 |
return true; |
||
533 |
} |
||
534 |
|||
535 |
15 |
bool unmountDir2(std::string oldDir, |
|
536 |
std::string subDir) |
||
537 |
{ |
||
538 |
15 |
prepareFsPath(oldDir); |
|
539 |
✗✓ | 15 |
if (oldDir.find(".zip") != std::string::npos) |
540 |
{ |
||
541 |
reportAlways("Called unmount with zip archive") |
||
542 |
return false; |
||
543 |
} |
||
544 |
15 |
prepareFsPath(subDir); |
|
545 |
✓✗✓✓ |
60 |
if (unmountDirInternal(oldDir, subDir) == false) |
546 |
{ |
||
547 |
✓✗ | 9 |
reportAlways("VirtFs::unmountDir not exists: %s", |
548 |
oldDir.c_str()) |
||
549 |
return false; |
||
550 |
} |
||
551 |
return true; |
||
552 |
} |
||
553 |
|||
554 |
796 |
bool unmountDirSilent(std::string oldDir) |
|
555 |
{ |
||
556 |
796 |
prepareFsPath(oldDir); |
|
557 |
✗✓ | 796 |
if (oldDir.find(".zip") != std::string::npos) |
558 |
{ |
||
559 |
reportAlways("Called unmount with zip archive") |
||
560 |
return false; |
||
561 |
} |
||
562 |
✓✗✓✓ |
3184 |
if (unmountDirInternal(oldDir, std::string()) == false) |
563 |
{ |
||
564 |
394 |
logger->log("VirtFs::unmountDir not exists: %s", |
|
565 |
394 |
oldDir.c_str()); |
|
566 |
394 |
return false; |
|
567 |
} |
||
568 |
return true; |
||
569 |
} |
||
570 |
|||
571 |
6 |
bool unmountDirSilent2(std::string oldDir, |
|
572 |
std::string subDir) |
||
573 |
{ |
||
574 |
6 |
prepareFsPath(oldDir); |
|
575 |
✗✓ | 6 |
if (oldDir.find(".zip") != std::string::npos) |
576 |
{ |
||
577 |
reportAlways("Called unmount with zip archive") |
||
578 |
return false; |
||
579 |
} |
||
580 |
6 |
prepareFsPath(subDir); |
|
581 |
✓✗✓✓ |
24 |
if (unmountDirInternal(oldDir, subDir) == false) |
582 |
{ |
||
583 |
1 |
logger->log("VirtFs::unmountDir not exists: %s", |
|
584 |
1 |
oldDir.c_str()); |
|
585 |
1 |
return false; |
|
586 |
} |
||
587 |
return true; |
||
588 |
} |
||
589 |
|||
590 |
69 |
bool mountZip(std::string newDir, |
|
591 |
const Append append) |
||
592 |
{ |
||
593 |
69 |
prepareFsPath(newDir); |
|
594 |
✗✓ | 69 |
if (Files::existsLocal(newDir) == false) |
595 |
{ |
||
596 |
reportNonTests("FsZip::mount file not exists: %s", |
||
597 |
newDir.c_str()) |
||
598 |
return false; |
||
599 |
} |
||
600 |
✓✗✗✓ |
276 |
if (findLast(newDir, ".zip") == false) |
601 |
{ |
||
602 |
reportAlways("Called VirtFs::mount without " |
||
603 |
"zip archive") |
||
604 |
return false; |
||
605 |
} |
||
606 |
✗✓ | 138 |
if (searchByRootInternal(newDir, std::string()) != nullptr) |
607 |
{ |
||
608 |
reportAlways("FsZip::mount already exists: %s", |
||
609 |
newDir.c_str()) |
||
610 |
return false; |
||
611 |
} |
||
612 |
ZipEntry *const entry = new ZipEntry(newDir, |
||
613 |
138 |
std::string(), |
|
614 |
✓✗✓✗ ✓✗ |
69 |
FsZip::getFuncs()); |
615 |
✗✓ | 69 |
if (ZipReader::readArchiveInfo(entry) == false) |
616 |
{ |
||
617 |
delete entry; |
||
618 |
return false; |
||
619 |
} |
||
620 |
|||
621 |
✓✗ | 138 |
logger->log("Add virtual zip: " + newDir); |
622 |
69 |
addEntry(entry, append); |
|
623 |
69 |
return true; |
|
624 |
} |
||
625 |
|||
626 |
26 |
bool mountZip2(std::string newDir, |
|
627 |
std::string subDir, |
||
628 |
const Append append) |
||
629 |
{ |
||
630 |
26 |
prepareFsPath(newDir); |
|
631 |
✗✓ | 26 |
if (Files::existsLocal(newDir) == false) |
632 |
{ |
||
633 |
reportNonTests("FsZip::mount file not exists: %s", |
||
634 |
newDir.c_str()) |
||
635 |
return false; |
||
636 |
} |
||
637 |
✓✗✗✓ |
104 |
if (findLast(newDir, ".zip") == false) |
638 |
{ |
||
639 |
reportAlways("Called VirtFs::mount without " |
||
640 |
"zip archive") |
||
641 |
return false; |
||
642 |
} |
||
643 |
26 |
prepareFsPath(subDir); |
|
644 |
✓✓ | 52 |
if (subDir == dirSeparator) |
645 |
{ |
||
646 |
subDir.clear(); |
||
647 |
} |
||
648 |
✓✗✗✓ ✓✗ |
100 |
else if (!subDir.empty() && |
649 |
✓✗✓✗ ✓✗✗✗ |
100 |
findLast(subDir, std::string(dirSeparator)) == false) |
650 |
{ |
||
651 |
25 |
subDir += dirSeparator; |
|
652 |
} |
||
653 |
✗✓ | 26 |
if (searchByRootInternal(newDir, subDir) != nullptr) |
654 |
{ |
||
655 |
reportAlways("FsZip::mount already exists: %s", |
||
656 |
newDir.c_str()) |
||
657 |
return false; |
||
658 |
} |
||
659 |
ZipEntry *const entry = new ZipEntry(newDir, |
||
660 |
subDir, |
||
661 |
✓✗ | 26 |
FsZip::getFuncs()); |
662 |
✗✓ | 26 |
if (ZipReader::readArchiveInfo(entry) == false) |
663 |
{ |
||
664 |
delete entry; |
||
665 |
return false; |
||
666 |
} |
||
667 |
|||
668 |
52 |
logger->log("Add virtual zip: %s with dir %s", |
|
669 |
newDir.c_str(), |
||
670 |
26 |
subDir.c_str()); |
|
671 |
26 |
addEntry(entry, append); |
|
672 |
26 |
return true; |
|
673 |
} |
||
674 |
|||
675 |
58 |
bool unmountZip(std::string oldDir) |
|
676 |
{ |
||
677 |
58 |
prepareFsPath(oldDir); |
|
678 |
✓✗✗✓ |
232 |
if (findLast(oldDir, ".zip") == false) |
679 |
{ |
||
680 |
reportAlways("Called unmount without zip archive") |
||
681 |
return false; |
||
682 |
} |
||
683 |
✓✗ | 187 |
FOR_EACH (STD_VECTOR<FsEntry*>::iterator, it, mEntries) |
684 |
{ |
||
685 |
71 |
FsEntry *const entry = *it; |
|
686 |
✓✗✓✓ |
200 |
if (entry->root == oldDir && |
687 |
✓✓✗✓ |
129 |
entry->type == FsEntryType::Zip && |
688 |
116 |
entry->subDir.empty()) |
|
689 |
{ |
||
690 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>( |
||
691 |
58 |
entry); |
|
692 |
✓✗ | 116 |
logger->log("Remove virtual zip: " + oldDir); |
693 |
116 |
mEntries.erase(it); |
|
694 |
✓✗ | 58 |
delete zipEntry; |
695 |
58 |
return true; |
|
696 |
} |
||
697 |
} |
||
698 |
|||
699 |
reportAlways("VirtFs::unmountZip not exists: %s", |
||
700 |
oldDir.c_str()) |
||
701 |
return false; |
||
702 |
} |
||
703 |
|||
704 |
14 |
bool unmountZip2(std::string oldDir, |
|
705 |
std::string subDir) |
||
706 |
{ |
||
707 |
14 |
prepareFsPath(oldDir); |
|
708 |
✓✗✗✓ |
56 |
if (findLast(oldDir, ".zip") == false) |
709 |
{ |
||
710 |
reportAlways("Called unmount without zip archive") |
||
711 |
return false; |
||
712 |
} |
||
713 |
14 |
prepareFsPath(subDir); |
|
714 |
✗✓ | 28 |
if (subDir == dirSeparator) |
715 |
{ |
||
716 |
subDir.clear(); |
||
717 |
} |
||
718 |
✓✗✗✓ ✓✗ |
56 |
else if (!subDir.empty() && |
719 |
✓✗✓✗ ✓✗✗✗ |
56 |
findLast(subDir, std::string(dirSeparator)) == false) |
720 |
{ |
||
721 |
14 |
subDir += dirSeparator; |
|
722 |
} |
||
723 |
✓✗ | 45 |
FOR_EACH (STD_VECTOR<FsEntry*>::iterator, it, mEntries) |
724 |
{ |
||
725 |
17 |
FsEntry *const entry = *it; |
|
726 |
✓✗✓✓ |
48 |
if (entry->root == oldDir && |
727 |
✓✓✗✓ |
31 |
entry->type == FsEntryType::Zip && |
728 |
14 |
entry->subDir == subDir) |
|
729 |
{ |
||
730 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>( |
||
731 |
14 |
entry); |
|
732 |
28 |
logger->log("Remove virtual zip: %s with dir %s", |
|
733 |
oldDir.c_str(), |
||
734 |
14 |
subDir.c_str()); |
|
735 |
28 |
mEntries.erase(it); |
|
736 |
✓✗ | 14 |
delete zipEntry; |
737 |
14 |
return true; |
|
738 |
} |
||
739 |
} |
||
740 |
|||
741 |
reportAlways("VirtFs::unmountZip not exists: %s", |
||
742 |
oldDir.c_str()) |
||
743 |
return false; |
||
744 |
} |
||
745 |
|||
746 |
74 |
std::string getRealDir(std::string fileName) |
|
747 |
{ |
||
748 |
74 |
prepareFsPath(fileName); |
|
749 |
✗✓ | 74 |
if (checkPath(fileName) == false) |
750 |
{ |
||
751 |
reportAlways("FsDir::getRealDir invalid path: %s", |
||
752 |
fileName.c_str()) |
||
753 |
return std::string(); |
||
754 |
} |
||
755 |
|||
756 |
148 |
std::string rootDir = fileName; |
|
757 |
✓✗✓✗ ✓✗ |
296 |
if (findLast(rootDir, std::string(dirSeparator)) == false) |
758 |
74 |
rootDir += dirSeparator; |
|
759 |
|||
760 |
✓✓ | 418 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
761 |
{ |
||
762 |
96 |
FsEntry *const entry = *it; |
|
763 |
144 |
std::string realDir; |
|
764 |
✓✗✓✓ |
480 |
if (entry->funcs->getRealDir(entry, |
765 |
fileName, |
||
766 |
rootDir, |
||
767 |
realDir) == true) |
||
768 |
{ |
||
769 |
96 |
return realDir; |
|
770 |
} |
||
771 |
} |
||
772 |
return std::string(); |
||
773 |
} |
||
774 |
|||
775 |
bool mkdir(const std::string &restrict dirname) |
||
776 |
{ |
||
777 |
return FsDir::mkdir(dirname); |
||
778 |
} |
||
779 |
|||
780 |
bool remove(const std::string &restrict filename) |
||
781 |
{ |
||
782 |
return FsDir::remove(filename); |
||
783 |
} |
||
784 |
|||
785 |
119 |
bool deinit() |
|
786 |
{ |
||
787 |
119 |
FsDir::deinit(); |
|
788 |
119 |
FsZip::deinit(); |
|
789 |
✓✓ | 433 |
FOR_EACH (STD_VECTOR<FsEntry*>::iterator, it, mEntries) |
790 |
{ |
||
791 |
76 |
FsEntry *const entry = *it; |
|
792 |
✓✓ | 76 |
if (entry->type == FsEntryType::Dir) |
793 |
✓✗ | 53 |
delete static_cast<DirEntry*>(entry); |
794 |
✓✗ | 23 |
else if (entry->type == FsEntryType::Zip) |
795 |
✓✗ | 23 |
delete static_cast<ZipEntry*>(entry); |
796 |
else |
||
797 |
delete entry; |
||
798 |
} |
||
799 |
119 |
mEntries.clear(); |
|
800 |
119 |
return true; |
|
801 |
} |
||
802 |
|||
803 |
20 |
void permitLinks(const bool val) |
|
804 |
{ |
||
805 |
20 |
FsDir::permitLinks(val); |
|
806 |
20 |
} |
|
807 |
|||
808 |
47 |
int close(File *restrict const file) |
|
809 |
{ |
||
810 |
✓✗ | 47 |
if (file == nullptr) |
811 |
return 0; |
||
812 |
47 |
return file->funcs->close(file); |
|
813 |
} |
||
814 |
|||
815 |
61 |
int64_t read(File *restrict const file, |
|
816 |
void *restrict const buffer, |
||
817 |
const uint32_t objSize, |
||
818 |
const uint32_t objCount) |
||
819 |
{ |
||
820 |
61 |
return file->funcs->read(file, |
|
821 |
buffer, |
||
822 |
objSize, |
||
823 |
61 |
objCount); |
|
824 |
} |
||
825 |
|||
826 |
int64_t write(File *restrict const file, |
||
827 |
const void *restrict const buffer, |
||
828 |
const uint32_t objSize, |
||
829 |
const uint32_t objCount) |
||
830 |
{ |
||
831 |
return file->funcs->write(file, |
||
832 |
buffer, |
||
833 |
objSize, |
||
834 |
objCount); |
||
835 |
} |
||
836 |
|||
837 |
20 |
int64_t fileLength(File *restrict const file) |
|
838 |
{ |
||
839 |
20 |
return file->funcs->fileLength(file); |
|
840 |
} |
||
841 |
|||
842 |
84 |
int64_t tell(File *restrict const file) |
|
843 |
{ |
||
844 |
84 |
return file->funcs->tell(file); |
|
845 |
} |
||
846 |
|||
847 |
30 |
int seek(File *restrict const file, |
|
848 |
const uint64_t pos) |
||
849 |
{ |
||
850 |
30 |
return file->funcs->seek(file, |
|
851 |
30 |
pos); |
|
852 |
} |
||
853 |
|||
854 |
93 |
int eof(File *restrict const file) |
|
855 |
{ |
||
856 |
93 |
return file->funcs->eof(file); |
|
857 |
} |
||
858 |
|||
859 |
2510 |
const char *loadFile(std::string filename, |
|
860 |
int &restrict fileSize) |
||
861 |
{ |
||
862 |
2510 |
prepareFsPath(filename); |
|
863 |
✗✓ | 2510 |
if (checkPath(filename) == false) |
864 |
{ |
||
865 |
reportAlways("VirtFs::loadFile invalid path: %s", |
||
866 |
filename.c_str()) |
||
867 |
return nullptr; |
||
868 |
} |
||
869 |
✓✓ | 14424 |
FOR_EACH (STD_VECTOR<FsEntry*>::const_iterator, it, mEntries) |
870 |
{ |
||
871 |
4300 |
FsEntry *const entry = *it; |
|
872 |
12900 |
const char *const buf = entry->funcs->loadFile(entry, |
|
873 |
filename, |
||
874 |
✓✗ | 4300 |
fileSize); |
875 |
✓✓ | 4300 |
if (buf != nullptr) |
876 |
return buf; |
||
877 |
} |
||
878 |
return nullptr; |
||
879 |
} |
||
880 |
|||
881 |
2 |
} // namespace VirtFs |
Generated by: GCOVR (Version 3.3) |