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/fszip.h" |
||
23 |
|||
24 |
#include "fs/virtfs/file.h" |
||
25 |
#include "fs/virtfs/fsfuncs.h" |
||
26 |
#include "fs/virtfs/fsziprwops.h" |
||
27 |
#include "fs/virtfs/list.h" |
||
28 |
#include "fs/virtfs/zipentry.h" |
||
29 |
#include "fs/virtfs/zipreader.h" |
||
30 |
#include "fs/virtfs/ziplocalheader.h" |
||
31 |
|||
32 |
#include "utils/cast.h" |
||
33 |
#include "utils/checkutils.h" |
||
34 |
#include "utils/foreach.h" |
||
35 |
#include "utils/stringutils.h" |
||
36 |
|||
37 |
#include "debug.h" |
||
38 |
|||
39 |
extern const char *dirSeparator; |
||
40 |
|||
41 |
namespace |
||
42 |
{ |
||
43 |
VirtFs::FsFuncs funcs; |
||
44 |
} // namespace |
||
45 |
|||
46 |
namespace VirtFs |
||
47 |
{ |
||
48 |
|||
49 |
namespace FsZip |
||
50 |
{ |
||
51 |
103 |
FsFuncs *getFuncs() |
|
52 |
{ |
||
53 |
103 |
return &funcs; |
|
54 |
} |
||
55 |
|||
56 |
119 |
void deinit() |
|
57 |
{ |
||
58 |
119 |
} |
|
59 |
|||
60 |
120 |
void init() |
|
61 |
{ |
||
62 |
120 |
initFuncs(&funcs); |
|
63 |
120 |
} |
|
64 |
|||
65 |
void initFuncs(FsFuncs *restrict const ptr) |
||
66 |
{ |
||
67 |
120 |
ptr->close = &FsZip::close; |
|
68 |
120 |
ptr->read = &FsZip::read; |
|
69 |
120 |
ptr->write = &FsZip::write; |
|
70 |
120 |
ptr->fileLength = &FsZip::fileLength; |
|
71 |
120 |
ptr->tell = &FsZip::tell; |
|
72 |
120 |
ptr->seek = &FsZip::seek; |
|
73 |
120 |
ptr->eof = &FsZip::eof; |
|
74 |
120 |
ptr->exists = &FsZip::exists; |
|
75 |
120 |
ptr->getRealDir = &FsZip::getRealDir; |
|
76 |
120 |
ptr->enumerate = &FsZip::enumerate; |
|
77 |
120 |
ptr->isDirectory = &FsZip::isDirectory; |
|
78 |
120 |
ptr->openRead = &FsZip::openRead; |
|
79 |
120 |
ptr->openWrite = &FsZip::openWrite; |
|
80 |
120 |
ptr->openAppend = &FsZip::openAppend; |
|
81 |
120 |
ptr->loadFile = &FsZip::loadFile; |
|
82 |
120 |
ptr->getFiles = &FsZip::getFiles; |
|
83 |
120 |
ptr->getFilesWithDir = &FsZip::getFilesWithDir; |
|
84 |
120 |
ptr->getDirs = &FsZip::getDirs; |
|
85 |
120 |
ptr->rwops_seek = &FsZip::rwops_seek; |
|
86 |
120 |
ptr->rwops_read = &FsZip::rwops_read; |
|
87 |
120 |
ptr->rwops_write = &FsZip::rwops_write; |
|
88 |
120 |
ptr->rwops_close = &FsZip::rwops_close; |
|
89 |
#ifdef USE_SDL2 |
||
90 |
120 |
ptr->rwops_size = &FsZip::rwops_size; |
|
91 |
#endif // USE_SDL2 |
||
92 |
} |
||
93 |
|||
94 |
27 |
bool getRealDir(FsEntry *restrict const entry, |
|
95 |
std::string filename, |
||
96 |
std::string dirName, |
||
97 |
std::string &realDir) |
||
98 |
{ |
||
99 |
27 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
100 |
81 |
std::string subDir = zipEntry->subDir; |
|
101 |
✓✓ | 27 |
if (!subDir.empty()) |
102 |
{ |
||
103 |
✓✗ | 6 |
filename = pathJoin(subDir, filename); |
104 |
✓✗ | 6 |
dirName = pathJoin(subDir, dirName); |
105 |
} |
||
106 |
✓✓ | 319 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
107 |
it2, |
||
108 |
zipEntry->mHeaders) |
||
109 |
{ |
||
110 |
✓✓ | 169 |
if ((*it2)->fileName == filename) |
111 |
{ |
||
112 |
12 |
realDir = entry->root; |
|
113 |
return true; |
||
114 |
} |
||
115 |
} |
||
116 |
✓✓ | 130 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
117 |
it2, |
||
118 |
zipEntry->mDirs) |
||
119 |
{ |
||
120 |
✓✓ | 41 |
if (*it2 == dirName) |
121 |
{ |
||
122 |
1 |
realDir = entry->root; |
|
123 |
return true; |
||
124 |
} |
||
125 |
} |
||
126 |
return false; |
||
127 |
} |
||
128 |
|||
129 |
52 |
bool exists(FsEntry *restrict const entry, |
|
130 |
std::string filename, |
||
131 |
std::string dirName) |
||
132 |
{ |
||
133 |
52 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
134 |
156 |
std::string subDir = zipEntry->subDir; |
|
135 |
✓✓ | 52 |
if (!subDir.empty()) |
136 |
{ |
||
137 |
✓✗ | 39 |
filename = pathJoin(subDir, filename); |
138 |
✓✗ | 39 |
dirName = pathJoin(subDir, dirName); |
139 |
} |
||
140 |
✓✓ | 663 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
141 |
it2, |
||
142 |
zipEntry->mHeaders) |
||
143 |
{ |
||
144 |
✓✓ | 365 |
if ((*it2)->fileName == filename) |
145 |
return true; |
||
146 |
} |
||
147 |
✓✓ | 336 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
148 |
it2, |
||
149 |
zipEntry->mDirs) |
||
150 |
{ |
||
151 |
✓✓ | 112 |
if (*it2 == dirName) |
152 |
return true; |
||
153 |
} |
||
154 |
return false; |
||
155 |
} |
||
156 |
|||
157 |
12 |
void enumerate(FsEntry *restrict const entry, |
|
158 |
std::string dirName, |
||
159 |
StringVect &names) |
||
160 |
{ |
||
161 |
12 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
162 |
36 |
const std::string subDir = zipEntry->subDir; |
|
163 |
✓✓ | 12 |
if (!subDir.empty()) |
164 |
✓✗ | 6 |
dirName = pathJoin(subDir, dirName); |
165 |
✓✓ | 24 |
if (dirName == dirSeparator) |
166 |
{ |
||
167 |
✓✓ | 50 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
168 |
it2, |
||
169 |
zipEntry->mHeaders) |
||
170 |
{ |
||
171 |
26 |
ZipLocalHeader *const header = *it2; |
|
172 |
78 |
std::string fileName = header->fileName; |
|
173 |
// skip subdirs from enumeration |
||
174 |
52 |
const size_t idx = fileName.find(dirSeparator); |
|
175 |
✓✓ | 26 |
if (idx != std::string::npos) |
176 |
✓✗ | 22 |
fileName.erase(idx); |
177 |
26 |
bool found(false); |
|
178 |
✓✓ | 164 |
FOR_EACH (StringVectCIter, itn, names) |
179 |
{ |
||
180 |
✓✓ | 50 |
if (*itn == fileName) |
181 |
{ |
||
182 |
found = true; |
||
183 |
break; |
||
184 |
} |
||
185 |
} |
||
186 |
✓✓ | 26 |
if (found == false) |
187 |
✓✗ | 10 |
names.push_back(fileName); |
188 |
} |
||
189 |
} |
||
190 |
else |
||
191 |
{ |
||
192 |
✓✓ | 109 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
193 |
it2, |
||
194 |
zipEntry->mHeaders) |
||
195 |
{ |
||
196 |
61 |
ZipLocalHeader *const header = *it2; |
|
197 |
183 |
std::string fileName = header->fileName; |
|
198 |
✓✗✓✓ |
61 |
if (findCutFirst(fileName, dirName) == true) |
199 |
{ |
||
200 |
// skip subdirs from enumeration |
||
201 |
52 |
const size_t idx = fileName.find(dirSeparator); |
|
202 |
✓✓ | 26 |
if (idx != std::string::npos) |
203 |
✓✗ | 6 |
fileName.erase(idx); |
204 |
26 |
bool found(false); |
|
205 |
✓✓ | 212 |
FOR_EACH (StringVectCIter, itn, names) |
206 |
{ |
||
207 |
✓✓ | 85 |
if (*itn == fileName) |
208 |
{ |
||
209 |
found = true; |
||
210 |
break; |
||
211 |
} |
||
212 |
} |
||
213 |
✓✓ | 26 |
if (found == false) |
214 |
✓✗ | 23 |
names.push_back(fileName); |
215 |
} |
||
216 |
} |
||
217 |
} |
||
218 |
12 |
} |
|
219 |
|||
220 |
4 |
void getFiles(FsEntry *restrict const entry, |
|
221 |
std::string dirName, |
||
222 |
StringVect &names) |
||
223 |
{ |
||
224 |
4 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
225 |
12 |
const std::string subDir = zipEntry->subDir; |
|
226 |
✓✓ | 4 |
if (!subDir.empty()) |
227 |
✓✗ | 6 |
dirName = pathJoin(subDir, dirName); |
228 |
✗✓ | 8 |
if (dirName == dirSeparator) |
229 |
{ |
||
230 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
||
231 |
it2, |
||
232 |
zipEntry->mHeaders) |
||
233 |
{ |
||
234 |
ZipLocalHeader *const header = *it2; |
||
235 |
std::string fileName = header->fileName; |
||
236 |
// skip subdirs from enumeration |
||
237 |
const size_t idx = fileName.find(dirSeparator); |
||
238 |
if (idx != std::string::npos) |
||
239 |
fileName.erase(idx); |
||
240 |
bool found(false); |
||
241 |
FOR_EACH (StringVectCIter, itn, names) |
||
242 |
{ |
||
243 |
if (*itn == fileName) |
||
244 |
{ |
||
245 |
found = true; |
||
246 |
break; |
||
247 |
} |
||
248 |
} |
||
249 |
if (found == false) |
||
250 |
{ |
||
251 |
std::string dirName2 = pathJoin(dirName, fileName); |
||
252 |
if (findLast(dirName2, std::string(dirSeparator)) == false) |
||
253 |
dirName2 += dirSeparator; |
||
254 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
||
255 |
it, |
||
256 |
zipEntry->mDirs) |
||
257 |
{ |
||
258 |
if (*it == dirName2) |
||
259 |
{ |
||
260 |
found = true; |
||
261 |
break; |
||
262 |
} |
||
263 |
} |
||
264 |
if (found == false) |
||
265 |
names.push_back(fileName); |
||
266 |
} |
||
267 |
} |
||
268 |
} |
||
269 |
else |
||
270 |
{ |
||
271 |
✓✓ | 68 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
272 |
it2, |
||
273 |
zipEntry->mHeaders) |
||
274 |
{ |
||
275 |
44 |
ZipLocalHeader *const header = *it2; |
|
276 |
132 |
std::string fileName = header->fileName; |
|
277 |
✓✗✓✓ |
44 |
if (findCutFirst(fileName, dirName) == true) |
278 |
{ |
||
279 |
// skip subdirs from enumeration |
||
280 |
32 |
const size_t idx = fileName.find(dirSeparator); |
|
281 |
✓✓ | 16 |
if (idx != std::string::npos) |
282 |
✓✗ | 6 |
fileName.erase(idx); |
283 |
16 |
bool found(false); |
|
284 |
✓✓ | 95 |
FOR_EACH (StringVectCIter, itn, names) |
285 |
{ |
||
286 |
✓✗ | 15 |
if (*itn == fileName) |
287 |
{ |
||
288 |
found = true; |
||
289 |
break; |
||
290 |
} |
||
291 |
} |
||
292 |
✓✗ | 16 |
if (found == false) |
293 |
{ |
||
294 |
✓✗ | 48 |
std::string dirName2 = pathJoin(dirName, fileName); |
295 |
✓✗✓✗ ✓✗ |
64 |
if (findLast(dirName2, std::string(dirSeparator)) == |
296 |
false) |
||
297 |
{ |
||
298 |
16 |
dirName2 += dirSeparator; |
|
299 |
} |
||
300 |
✓✓ | 150 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
301 |
it, |
||
302 |
zipEntry->mDirs) |
||
303 |
{ |
||
304 |
✓✓ | 60 |
if (*it == dirName2) |
305 |
{ |
||
306 |
found = true; |
||
307 |
break; |
||
308 |
} |
||
309 |
} |
||
310 |
✓✓ | 16 |
if (found == false) |
311 |
✓✗ | 10 |
names.push_back(fileName); |
312 |
} |
||
313 |
} |
||
314 |
} |
||
315 |
} |
||
316 |
4 |
} |
|
317 |
|||
318 |
5 |
void getFilesWithDir(FsEntry *restrict const entry, |
|
319 |
const std::string &dirName, |
||
320 |
StringVect &names) |
||
321 |
{ |
||
322 |
5 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
323 |
15 |
const std::string subDir = zipEntry->subDir; |
|
324 |
10 |
std::string dirNameFull; |
|
325 |
✓✓ | 5 |
if (!subDir.empty()) |
326 |
✓✗ | 6 |
dirNameFull = pathJoin(subDir, dirName); |
327 |
else |
||
328 |
dirNameFull = dirName; |
||
329 |
✓✓ | 10 |
if (dirNameFull == dirSeparator) |
330 |
{ |
||
331 |
✓✓ | 17 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
332 |
it2, |
||
333 |
zipEntry->mHeaders) |
||
334 |
{ |
||
335 |
11 |
ZipLocalHeader *const header = *it2; |
|
336 |
33 |
std::string fileName = header->fileName; |
|
337 |
// skip subdirs from enumeration |
||
338 |
22 |
const size_t idx = fileName.find(dirSeparator); |
|
339 |
✓✓ | 11 |
if (idx != std::string::npos) |
340 |
✓✗ | 9 |
fileName.erase(idx); |
341 |
11 |
bool found(false); |
|
342 |
✓✓ | 110 |
FOR_EACH (StringVectCIter, itn, names) |
343 |
{ |
||
344 |
✓✗ | 55 |
if (*itn == fileName) |
345 |
{ |
||
346 |
found = true; |
||
347 |
break; |
||
348 |
} |
||
349 |
} |
||
350 |
✓✗ | 11 |
if (found == false) |
351 |
{ |
||
352 |
✓✗ | 33 |
std::string dirName2 = pathJoin(dirNameFull, fileName); |
353 |
✓✗✓✗ ✓✗ |
44 |
if (findLast(dirName2, std::string(dirSeparator)) == false) |
354 |
11 |
dirName2 += dirSeparator; |
|
355 |
✓✓ | 110 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
356 |
it, |
||
357 |
zipEntry->mDirs) |
||
358 |
{ |
||
359 |
✓✗ | 44 |
if (*it == dirName2) |
360 |
{ |
||
361 |
found = true; |
||
362 |
break; |
||
363 |
} |
||
364 |
} |
||
365 |
✓✗ | 11 |
if (found == false) |
366 |
✓✗ | 44 |
names.push_back(pathJoin(dirName, fileName)); |
367 |
} |
||
368 |
} |
||
369 |
} |
||
370 |
else |
||
371 |
{ |
||
372 |
✓✓ | 68 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
373 |
it2, |
||
374 |
zipEntry->mHeaders) |
||
375 |
{ |
||
376 |
44 |
ZipLocalHeader *const header = *it2; |
|
377 |
132 |
std::string fileName = header->fileName; |
|
378 |
✓✗✓✓ |
44 |
if (findCutFirst(fileName, dirNameFull) == true) |
379 |
{ |
||
380 |
// skip subdirs from enumeration |
||
381 |
32 |
const size_t idx = fileName.find(dirSeparator); |
|
382 |
✓✓ | 16 |
if (idx != std::string::npos) |
383 |
✓✗ | 6 |
fileName.erase(idx); |
384 |
16 |
bool found(false); |
|
385 |
✓✓ | 95 |
FOR_EACH (StringVectCIter, itn, names) |
386 |
{ |
||
387 |
✓✗ | 15 |
if (*itn == fileName) |
388 |
{ |
||
389 |
found = true; |
||
390 |
break; |
||
391 |
} |
||
392 |
} |
||
393 |
✓✗ | 16 |
if (found == false) |
394 |
{ |
||
395 |
✓✗ | 48 |
std::string dirName2 = pathJoin(dirNameFull, fileName); |
396 |
✓✗✓✗ ✓✗ |
64 |
if (findLast(dirName2, std::string(dirSeparator)) == |
397 |
false) |
||
398 |
{ |
||
399 |
16 |
dirName2 += dirSeparator; |
|
400 |
} |
||
401 |
✓✓ | 150 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
402 |
it, |
||
403 |
zipEntry->mDirs) |
||
404 |
{ |
||
405 |
✓✓ | 60 |
if (*it == dirName2) |
406 |
{ |
||
407 |
found = true; |
||
408 |
break; |
||
409 |
} |
||
410 |
} |
||
411 |
✓✓ | 16 |
if (found == false) |
412 |
✓✗ | 40 |
names.push_back(pathJoin(dirName, fileName)); |
413 |
} |
||
414 |
} |
||
415 |
} |
||
416 |
} |
||
417 |
5 |
} |
|
418 |
|||
419 |
4 |
void getDirs(FsEntry *restrict const entry, |
|
420 |
std::string dirName, |
||
421 |
StringVect &names) |
||
422 |
{ |
||
423 |
4 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
424 |
12 |
const std::string subDir = zipEntry->subDir; |
|
425 |
✓✓ | 4 |
if (!subDir.empty()) |
426 |
✓✗ | 6 |
dirName = pathJoin(subDir, dirName); |
427 |
✗✓ | 8 |
if (dirName == dirSeparator) |
428 |
{ |
||
429 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
||
430 |
it2, |
||
431 |
zipEntry->mHeaders) |
||
432 |
{ |
||
433 |
ZipLocalHeader *const header = *it2; |
||
434 |
std::string fileName = header->fileName; |
||
435 |
// skip subdirs from enumeration |
||
436 |
const size_t idx = fileName.find(dirSeparator); |
||
437 |
if (idx != std::string::npos) |
||
438 |
fileName.erase(idx); |
||
439 |
bool found(false); |
||
440 |
FOR_EACH (StringVectCIter, itn, names) |
||
441 |
{ |
||
442 |
if (*itn == fileName) |
||
443 |
{ |
||
444 |
found = true; |
||
445 |
break; |
||
446 |
} |
||
447 |
} |
||
448 |
if (found == false) |
||
449 |
{ |
||
450 |
std::string dirName2 = pathJoin(dirName, fileName); |
||
451 |
if (findLast(dirName2, std::string(dirSeparator)) == false) |
||
452 |
dirName2 += dirSeparator; |
||
453 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
||
454 |
it, |
||
455 |
zipEntry->mDirs) |
||
456 |
{ |
||
457 |
if (*it == dirName2) |
||
458 |
{ |
||
459 |
found = true; |
||
460 |
break; |
||
461 |
} |
||
462 |
} |
||
463 |
if (found == true) |
||
464 |
names.push_back(fileName); |
||
465 |
} |
||
466 |
} |
||
467 |
} |
||
468 |
else |
||
469 |
{ |
||
470 |
✓✓ | 68 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
471 |
it2, |
||
472 |
zipEntry->mHeaders) |
||
473 |
{ |
||
474 |
44 |
ZipLocalHeader *const header = *it2; |
|
475 |
132 |
std::string fileName = header->fileName; |
|
476 |
✓✗✓✓ |
44 |
if (findCutFirst(fileName, dirName) == true) |
477 |
{ |
||
478 |
// skip subdirs from enumeration |
||
479 |
32 |
const size_t idx = fileName.find(dirSeparator); |
|
480 |
✓✓ | 16 |
if (idx != std::string::npos) |
481 |
✓✗ | 6 |
fileName.erase(idx); |
482 |
16 |
bool found(false); |
|
483 |
✓✓ | 86 |
FOR_EACH (StringVectCIter, itn, names) |
484 |
{ |
||
485 |
✓✓ | 8 |
if (*itn == fileName) |
486 |
{ |
||
487 |
found = true; |
||
488 |
break; |
||
489 |
} |
||
490 |
} |
||
491 |
✓✓ | 16 |
if (found == false) |
492 |
{ |
||
493 |
✓✗ | 42 |
std::string dirName2 = pathJoin(dirName, fileName); |
494 |
✓✗✓✗ ✓✗ |
56 |
if (findLast(dirName2, std::string(dirSeparator)) == |
495 |
false) |
||
496 |
{ |
||
497 |
14 |
dirName2 += dirSeparator; |
|
498 |
} |
||
499 |
✓✓ | 134 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
500 |
it, |
||
501 |
zipEntry->mDirs) |
||
502 |
{ |
||
503 |
✓✓ | 54 |
if (*it == dirName2) |
504 |
{ |
||
505 |
found = true; |
||
506 |
break; |
||
507 |
} |
||
508 |
} |
||
509 |
✓✓ | 14 |
if (found == true) |
510 |
✓✗ | 4 |
names.push_back(fileName); |
511 |
} |
||
512 |
} |
||
513 |
} |
||
514 |
} |
||
515 |
4 |
} |
|
516 |
|||
517 |
113 |
bool isDirectory(FsEntry *restrict const entry, |
|
518 |
std::string dirName, |
||
519 |
bool &isDirFlag) |
||
520 |
{ |
||
521 |
113 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
522 |
339 |
std::string subDir = zipEntry->subDir; |
|
523 |
✓✓ | 113 |
if (!subDir.empty()) |
524 |
✓✗ | 51 |
dirName = pathJoin(subDir, dirName); |
525 |
✓✓ | 944 |
FOR_EACH (STD_VECTOR<std::string>::const_iterator, |
526 |
it2, |
||
527 |
zipEntry->mDirs) |
||
528 |
{ |
||
529 |
✓✓ | 291 |
if (*it2 == dirName) |
530 |
{ |
||
531 |
25 |
isDirFlag = true; |
|
532 |
25 |
return true; |
|
533 |
} |
||
534 |
} |
||
535 |
return false; |
||
536 |
} |
||
537 |
|||
538 |
void freeList(List *restrict const handle) |
||
539 |
{ |
||
540 |
delete handle; |
||
541 |
} |
||
542 |
|||
543 |
88 |
File *openRead(FsEntry *restrict const entry, |
|
544 |
std::string filename) |
||
545 |
{ |
||
546 |
88 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
547 |
264 |
std::string subDir = zipEntry->subDir; |
|
548 |
✓✓ | 88 |
if (!subDir.empty()) |
549 |
✓✗ | 81 |
filename = pathJoin(subDir, filename); |
550 |
✓✓ | 1047 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
551 |
it2, |
||
552 |
zipEntry->mHeaders) |
||
553 |
{ |
||
554 |
563 |
const ZipLocalHeader *restrict const header = *it2; |
|
555 |
✓✓ | 563 |
if (header->fileName == filename) |
556 |
{ |
||
557 |
const uint8_t *restrict const buf = |
||
558 |
✓✗ | 44 |
ZipReader::readFile(header); |
559 |
✓✗ | 44 |
if (buf == nullptr) |
560 |
return nullptr; |
||
561 |
return new File(&funcs, |
||
562 |
buf, |
||
563 |
✓✗✓✗ |
44 |
header->uncompressSize); |
564 |
} |
||
565 |
} |
||
566 |
return nullptr; |
||
567 |
} |
||
568 |
|||
569 |
File *openWrite(FsEntry *restrict const entry A_UNUSED, |
||
570 |
const std::string &filename A_UNUSED) |
||
571 |
{ |
||
572 |
reportAlways("VirtFs::openWrite for zip not implemented.") |
||
573 |
return nullptr; |
||
574 |
} |
||
575 |
|||
576 |
File *openAppend(FsEntry *restrict const entry A_UNUSED, |
||
577 |
const std::string &filename A_UNUSED) |
||
578 |
{ |
||
579 |
reportAlways("VirtFs::openAppend for zip not implemented.") |
||
580 |
return nullptr; |
||
581 |
} |
||
582 |
|||
583 |
29 |
int close(File *restrict const file) |
|
584 |
{ |
||
585 |
✓✗ | 29 |
if (file == nullptr) |
586 |
return 0; |
||
587 |
29 |
delete file; |
|
588 |
29 |
return 1; |
|
589 |
} |
||
590 |
|||
591 |
230 |
int64_t read(File *restrict const file, |
|
592 |
void *restrict const buffer, |
||
593 |
const uint32_t objSize, |
||
594 |
const uint32_t objCount) |
||
595 |
{ |
||
596 |
✓✗ | 460 |
if (file == nullptr || |
597 |
✓✗ | 460 |
objSize == 0 || |
598 |
objCount == 0) |
||
599 |
{ |
||
600 |
return 0; |
||
601 |
} |
||
602 |
✗✓ | 230 |
if (buffer == nullptr) |
603 |
{ |
||
604 |
reportAlways("FsZip::read buffer is null") |
||
605 |
return 0; |
||
606 |
} |
||
607 |
230 |
const size_t pos = file->mPos; |
|
608 |
230 |
const size_t sz = file->mSize; |
|
609 |
// if outside of buffer, return |
||
610 |
✓✗ | 230 |
if (pos >= sz) |
611 |
return 0; |
||
612 |
// pointer to start for buffer ready to read |
||
613 |
230 |
const uint8_t *restrict const memPtr = file->mBuf + pos; |
|
614 |
// left buffer size from pos to end |
||
615 |
230 |
const uint32_t memSize = CAST_U32(sz - pos); |
|
616 |
// number of objects possible to read |
||
617 |
230 |
uint32_t memCount = memSize / objSize; |
|
618 |
✓✓ | 230 |
if (memCount == 0) |
619 |
return 0; |
||
620 |
// limit number of possible objects to read to objCount |
||
621 |
✓✓ | 228 |
if (memCount > objCount) |
622 |
203 |
memCount = objCount; |
|
623 |
// number of bytes to read from buffer |
||
624 |
228 |
const size_t memEnd = memCount * objSize; |
|
625 |
228 |
memcpy(buffer, memPtr, memEnd); |
|
626 |
228 |
file->mPos += memEnd; |
|
627 |
228 |
return memCount; |
|
628 |
} |
||
629 |
|||
630 |
int64_t write(File *restrict const file A_UNUSED, |
||
631 |
const void *restrict const buffer A_UNUSED, |
||
632 |
const uint32_t objSize A_UNUSED, |
||
633 |
const uint32_t objCount A_UNUSED) |
||
634 |
{ |
||
635 |
return 0; |
||
636 |
} |
||
637 |
|||
638 |
14 |
int64_t fileLength(File *restrict const file) |
|
639 |
{ |
||
640 |
✓✗ | 14 |
if (file == nullptr) |
641 |
return -1; |
||
642 |
|||
643 |
14 |
return file->mSize; |
|
644 |
} |
||
645 |
|||
646 |
78 |
int64_t tell(File *restrict const file) |
|
647 |
{ |
||
648 |
✓✗ | 78 |
if (file == nullptr) |
649 |
return -1; |
||
650 |
|||
651 |
78 |
return file->mPos; |
|
652 |
} |
||
653 |
|||
654 |
27 |
int seek(File *restrict const file, |
|
655 |
const uint64_t pos) |
||
656 |
{ |
||
657 |
✓✗ | 27 |
if (file == nullptr) |
658 |
return 0; |
||
659 |
|||
660 |
✓✗ | 27 |
if (pos > file->mSize) |
661 |
return 0; |
||
662 |
27 |
file->mPos = pos; |
|
663 |
27 |
return 1; |
|
664 |
} |
||
665 |
|||
666 |
84 |
int eof(File *restrict const file) |
|
667 |
{ |
||
668 |
✓✗ | 84 |
if (file == nullptr) |
669 |
return -1; |
||
670 |
|||
671 |
84 |
return static_cast<int>(file->mPos >= file->mSize); |
|
672 |
} |
||
673 |
|||
674 |
4 |
const char *loadFile(FsEntry *restrict const entry, |
|
675 |
std::string filename, |
||
676 |
int &restrict fileSize) |
||
677 |
{ |
||
678 |
4 |
ZipEntry *const zipEntry = static_cast<ZipEntry*>(entry); |
|
679 |
12 |
const std::string subDir = zipEntry->subDir; |
|
680 |
✓✓ | 4 |
if (!subDir.empty()) |
681 |
✓✗ | 6 |
filename = pathJoin(subDir, filename); |
682 |
✓✗ | 32 |
FOR_EACH (STD_VECTOR<ZipLocalHeader*>::const_iterator, |
683 |
it2, |
||
684 |
zipEntry->mHeaders) |
||
685 |
{ |
||
686 |
12 |
const ZipLocalHeader *restrict const header = *it2; |
|
687 |
✓✓ | 12 |
if (header->fileName == filename) |
688 |
{ |
||
689 |
const uint8_t *restrict const buf = |
||
690 |
✓✗ | 4 |
ZipReader::readFile(header); |
691 |
✓✗ | 4 |
if (buf == nullptr) |
692 |
return nullptr; |
||
693 |
|||
694 |
8 |
logger->log("Loaded %s/%s", |
|
695 |
entry->root.c_str(), |
||
696 |
✓✗ | 4 |
filename.c_str()); |
697 |
|||
698 |
4 |
fileSize = header->uncompressSize; |
|
699 |
4 |
return reinterpret_cast<const char*>(buf); |
|
700 |
} |
||
701 |
} |
||
702 |
return nullptr; |
||
703 |
} |
||
704 |
} // namespace FsZip |
||
705 |
|||
706 |
✓✗✓✗ |
3 |
} // namespace VirtFs |
Generated by: GCOVR (Version 3.3) |