Coverage Report

Created: 2025-11-11 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/Common/ZipArchiveIOSystem.cpp
Line
Count
Source
1
/*
2
Open Asset Import Library (assimp)
3
----------------------------------------------------------------------
4
5
Copyright (c) 2006-2025, assimp team
6
7
All rights reserved.
8
9
Redistribution and use of this software in source and binary forms,
10
with or without modification, are permitted provided that the
11
following conditions are met:
12
13
* Redistributions of source code must retain the above
14
  copyright notice, this list of conditions and the
15
  following disclaimer.
16
17
* Redistributions in binary form must reproduce the above
18
  copyright notice, this list of conditions and the
19
  following disclaimer in the documentation and/or other
20
  materials provided with the distribution.
21
22
* Neither the name of the assimp team, nor the names of its
23
  contributors may be used to endorse or promote products
24
  derived from this software without specific prior
25
  written permission of the assimp team.
26
27
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39
----------------------------------------------------------------------
40
*/
41
42
/** @file  ZipArchiveIOSystem.cpp
43
 *  @brief Zip File I/O implementation for #Importer
44
 */
45
46
#include <assimp/BaseImporter.h>
47
#include <assimp/ZipArchiveIOSystem.h>
48
49
#include <assimp/ai_assert.h>
50
51
#include <map>
52
#include <memory>
53
54
#ifdef ASSIMP_USE_HUNTER
55
#    include <minizip/unzip.h>
56
#else
57
#    include <unzip.h>
58
#endif
59
60
namespace Assimp {
61
62
// ----------------------------------------------------------------
63
// A read-only file inside a ZIP
64
65
class ZipFile final : public IOStream {
66
    friend class ZipFileInfo;
67
    explicit ZipFile(std::string &filename, size_t size);
68
69
public:
70
    std::string m_Filename;
71
0
    ~ZipFile() override = default;
72
73
    // IOStream interface
74
    size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
75
0
    size_t Write(const void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override { return 0; }
76
    size_t FileSize() const override;
77
    aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
78
    size_t Tell() const override;
79
0
    void Flush() override {}
80
81
private:
82
    size_t m_Size = 0;
83
    size_t m_SeekPtr = 0;
84
    std::unique_ptr<uint8_t[]> m_Buffer;
85
};
86
87
88
// ----------------------------------------------------------------
89
// Wraps an existing Assimp::IOSystem for unzip
90
class IOSystem2Unzip {
91
public:
92
    IOSystem2Unzip() = default;
93
    ~IOSystem2Unzip() = default;
94
    static voidpf open(voidpf opaque, const char *filename, int mode);
95
    static voidpf opendisk(voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
96
    static uLong read(voidpf opaque, voidpf stream, void *buf, uLong size);
97
    static uLong write(voidpf opaque, voidpf stream, const void *buf, uLong size);
98
    static long tell(voidpf opaque, voidpf stream);
99
    static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
100
    static int close(voidpf opaque, voidpf stream);
101
    static int testerror(voidpf opaque, voidpf stream);
102
    static zlib_filefunc_def get(IOSystem *pIOHandler);
103
};
104
105
// ----------------------------------------------------------------
106
494
voidpf IOSystem2Unzip::open(voidpf opaque, const char *filename, int mode) {
107
494
    IOSystem *io_system = reinterpret_cast<IOSystem *>(opaque);
108
109
494
    const char *mode_fopen = nullptr;
110
494
    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) {
111
494
        mode_fopen = "rb";
112
494
    } else {
113
0
        if (mode & ZLIB_FILEFUNC_MODE_EXISTING) {
114
0
            mode_fopen = "r+b";
115
0
        } else {
116
0
            if (mode & ZLIB_FILEFUNC_MODE_CREATE) {
117
0
                mode_fopen = "wb";
118
0
            }
119
0
        }
120
0
    }
121
122
494
    return (voidpf)io_system->Open(filename, mode_fopen);
123
494
}
124
125
// ----------------------------------------------------------------
126
0
voidpf IOSystem2Unzip::opendisk(voidpf opaque, voidpf stream, uint32_t number_disk, int mode) {
127
0
    ZipFile *io_stream = (ZipFile *)stream;
128
0
    voidpf ret = nullptr;
129
0
    int i;
130
131
0
    char *disk_filename = (char*)malloc(io_stream->m_Filename.length() + 1);
132
0
    strncpy(disk_filename, io_stream->m_Filename.c_str(), io_stream->m_Filename.length() + 1);
133
0
    for (i = (int)io_stream->m_Filename.length() - 1; i >= 0; i -= 1)
134
0
    {
135
0
        if (disk_filename[i] != '.')
136
0
            continue;
137
0
        snprintf(&disk_filename[i], io_stream->m_Filename.length() - size_t(i), ".z%02u", number_disk + 1);
138
0
        break;
139
0
    }
140
141
0
    if (i >= 0)
142
0
        ret = open(opaque, disk_filename, mode);
143
144
0
    free(disk_filename);
145
0
    return ret;
146
0
}
147
148
// ----------------------------------------------------------------
149
49.0k
uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void *buf, uLong size) {
150
49.0k
    IOStream *io_stream = (IOStream *)stream;
151
152
49.0k
    return static_cast<uLong>(io_stream->Read(buf, 1, size));
153
49.0k
}
154
155
// ----------------------------------------------------------------
156
0
uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void *buf, uLong size) {
157
0
    IOStream *io_stream = (IOStream *)stream;
158
159
0
    return static_cast<uLong>(io_stream->Write(buf, 1, size));
160
0
}
161
162
// ----------------------------------------------------------------
163
988
long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
164
988
    IOStream *io_stream = (IOStream *)stream;
165
166
988
    return static_cast<long>(io_stream->Tell());
167
988
}
168
169
// ----------------------------------------------------------------
170
37.8k
long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int origin) {
171
37.8k
    IOStream *io_stream = (IOStream *)stream;
172
173
37.8k
    aiOrigin assimp_origin;
174
37.8k
    switch (origin) {
175
0
        default:
176
96
        case ZLIB_FILEFUNC_SEEK_CUR:
177
96
            assimp_origin = aiOrigin_CUR;
178
96
            break;
179
988
        case ZLIB_FILEFUNC_SEEK_END:
180
988
            assimp_origin = aiOrigin_END;
181
988
            break;
182
36.7k
        case ZLIB_FILEFUNC_SEEK_SET:
183
36.7k
            assimp_origin = aiOrigin_SET;
184
36.7k
            break;
185
37.8k
    }
186
187
37.8k
    return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1);
188
37.8k
}
189
190
// ----------------------------------------------------------------
191
494
int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
192
494
    IOSystem *io_system = (IOSystem *)opaque;
193
494
    IOStream *io_stream = (IOStream *)stream;
194
195
494
    io_system->Close(io_stream);
196
197
494
    return 0;
198
494
}
199
200
// ----------------------------------------------------------------
201
6
int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
202
6
    return 0;
203
6
}
204
205
// ----------------------------------------------------------------
206
494
zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
207
494
    zlib_filefunc_def mapping;
208
209
494
    mapping.zopen_file = (open_file_func)open;
210
#ifdef _UNZ_H
211
    mapping.zopendisk_file = (opendisk_file_func)opendisk;
212
#endif
213
494
    mapping.zread_file = (read_file_func)read;
214
494
    mapping.zwrite_file = (write_file_func)write;
215
494
    mapping.ztell_file = (tell_file_func)tell;
216
494
    mapping.zseek_file = (seek_file_func)seek;
217
494
    mapping.zclose_file = (close_file_func)close;
218
494
    mapping.zerror_file = testerror;
219
220
494
    mapping.opaque = reinterpret_cast<voidpf>(pIOHandler);
221
222
494
    return mapping;
223
494
}
224
225
// ----------------------------------------------------------------
226
// Info about a read-only file inside a ZIP
227
class ZipFileInfo final {
228
public:
229
    explicit ZipFileInfo(unzFile zip_handle, size_t size);
230
    ~ZipFileInfo() = default;
231
232
    // Allocate and Extract data from the ZIP
233
    ZipFile *Extract(std::string &filename, unzFile zip_handle) const;
234
235
private:
236
    size_t m_Size = 0;
237
    unz_file_pos_s m_ZipFilePos;
238
};
239
240
// ----------------------------------------------------------------
241
ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) :
242
272
        m_Size(size) {
243
272
    ai_assert(m_Size != 0);
244
    // Workaround for MSVC 2013 - C2797
245
272
    m_ZipFilePos.num_of_file = 0;
246
272
    m_ZipFilePos.pos_in_zip_directory = 0;
247
272
    unzGetFilePos(zip_handle, &(m_ZipFilePos));
248
272
}
249
250
// ----------------------------------------------------------------
251
0
ZipFile *ZipFileInfo::Extract(std::string &filename, unzFile zip_handle) const {
252
    // Find in the ZIP. This cannot fail
253
0
    unz_file_pos_s *filepos = const_cast<unz_file_pos_s *>(&(m_ZipFilePos));
254
0
    if (unzGoToFilePos(zip_handle, filepos) != UNZ_OK)
255
0
        return nullptr;
256
257
0
    if (unzOpenCurrentFile(zip_handle) != UNZ_OK)
258
0
        return nullptr;
259
260
0
    ZipFile *zip_file = new ZipFile(filename, m_Size);
261
262
    // Unzip has a limit of UINT16_MAX bytes buffer
263
0
    uint16_t unzipBufferSize = zip_file->m_Size <= UINT16_MAX ? static_cast<uint16_t>(zip_file->m_Size) : UINT16_MAX;
264
0
    std::unique_ptr<uint8_t[]> unzipBuffer = std::unique_ptr<uint8_t[]>(new uint8_t[unzipBufferSize]);
265
0
    size_t readCount = 0;
266
0
    while (readCount < zip_file->m_Size)
267
0
    {
268
0
        size_t bufferSize = zip_file->m_Size - readCount;
269
0
        if (bufferSize > UINT16_MAX) {
270
0
            bufferSize = UINT16_MAX;
271
0
        }
272
273
0
        int ret = unzReadCurrentFile(zip_handle, unzipBuffer.get(), static_cast<unsigned int>(bufferSize));
274
0
        if (ret != static_cast<int>(bufferSize))
275
0
        {
276
            // Failed, release the memory
277
0
            delete zip_file;
278
0
            zip_file = nullptr;
279
0
            break;
280
0
        }
281
282
0
        std::memcpy(zip_file->m_Buffer.get() + readCount, unzipBuffer.get(), ret);
283
0
        readCount += ret;
284
0
    }
285
286
0
    ai_assert(unzCloseCurrentFile(zip_handle) == UNZ_OK);
287
0
    return zip_file;
288
0
}
289
290
// ----------------------------------------------------------------
291
ZipFile::ZipFile(std::string &filename, size_t size) :
292
0
        m_Filename(filename), m_Size(size) {
293
0
    ai_assert(m_Size != 0);
294
0
    m_Buffer = std::unique_ptr<uint8_t[]>(new uint8_t[m_Size]);
295
0
}
296
297
// ----------------------------------------------------------------
298
0
size_t ZipFile::Read(void *pvBuffer, size_t pSize, size_t pCount) {
299
    // Should be impossible
300
0
    ai_assert(m_Buffer != nullptr);
301
0
    ai_assert(nullptr != pvBuffer);
302
0
    ai_assert(0 != pSize);
303
0
    ai_assert(0 != pCount);
304
305
    // Clip down to file size
306
0
    size_t byteSize = pSize * pCount;
307
0
    if ((byteSize + m_SeekPtr) > m_Size) {
308
0
        pCount = (m_Size - m_SeekPtr) / pSize;
309
0
        byteSize = pSize * pCount;
310
0
        if (byteSize == 0) {
311
0
            return 0;
312
0
        }
313
0
    }
314
315
0
    std::memcpy(pvBuffer, m_Buffer.get() + m_SeekPtr, byteSize);
316
317
0
    m_SeekPtr += byteSize;
318
319
0
    return pCount;
320
0
}
321
322
// ----------------------------------------------------------------
323
0
size_t ZipFile::FileSize() const {
324
0
    return m_Size;
325
0
}
326
327
// ----------------------------------------------------------------
328
0
aiReturn ZipFile::Seek(size_t pOffset, aiOrigin pOrigin) {
329
0
    switch (pOrigin) {
330
0
        case aiOrigin_SET: {
331
0
            if (pOffset > m_Size) return aiReturn_FAILURE;
332
0
            m_SeekPtr = pOffset;
333
0
            return aiReturn_SUCCESS;
334
0
        }
335
336
0
        case aiOrigin_CUR: {
337
0
            if ((pOffset + m_SeekPtr) > m_Size) return aiReturn_FAILURE;
338
0
            m_SeekPtr += pOffset;
339
0
            return aiReturn_SUCCESS;
340
0
        }
341
342
0
        case aiOrigin_END: {
343
0
            if (pOffset > m_Size) return aiReturn_FAILURE;
344
0
            m_SeekPtr = m_Size - pOffset;
345
0
            return aiReturn_SUCCESS;
346
0
        }
347
0
        default:;
348
0
    }
349
350
0
    return aiReturn_FAILURE;
351
0
}
352
353
// ----------------------------------------------------------------
354
0
size_t ZipFile::Tell() const {
355
0
    return m_SeekPtr;
356
0
}
357
358
// ----------------------------------------------------------------
359
// pImpl of the Zip Archive IO
360
class ZipArchiveIOSystem::Implement {
361
public:
362
    static const unsigned int FileNameSize = 256;
363
364
    Implement(IOSystem *pIOHandler, const char *pFilename, const char *pMode);
365
    ~Implement();
366
367
    bool isOpen() const;
368
    void getFileList(std::vector<std::string> &rFileList);
369
    void getFileListExtension(std::vector<std::string> &rFileList, const std::string &extension);
370
    bool Exists(std::string &filename);
371
    IOStream *OpenFile(std::string &filename);
372
373
    static void SimplifyFilename(std::string &filename);
374
375
private:
376
    void MapArchive();
377
378
private:
379
    typedef std::map<std::string, ZipFileInfo> ZipFileInfoMap;
380
381
    unzFile m_ZipFileHandle = nullptr;
382
    ZipFileInfoMap m_ArchiveMap;
383
};
384
385
// ----------------------------------------------------------------
386
494
ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFilename, const char *pMode) {
387
494
    ai_assert(strcmp(pMode, "r") == 0);
388
494
    ai_assert(pFilename != nullptr);
389
494
    if (pFilename[0] == 0 || nullptr == pMode) {
390
0
        return;
391
0
    }
392
393
494
    zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
394
494
    m_ZipFileHandle = unzOpen2(pFilename, &mapping);
395
494
}
396
397
// ----------------------------------------------------------------
398
494
ZipArchiveIOSystem::Implement::~Implement() {
399
494
    if (m_ZipFileHandle != nullptr) {
400
18
        unzClose(m_ZipFileHandle);
401
18
    }
402
494
}
403
404
// ----------------------------------------------------------------
405
18
void ZipArchiveIOSystem::Implement::MapArchive() {
406
18
    if (m_ZipFileHandle == nullptr)
407
0
        return;
408
409
18
    if (!m_ArchiveMap.empty())
410
6
        return;
411
412
    //  At first ensure file is already open
413
12
    if (unzGoToFirstFile(m_ZipFileHandle) != UNZ_OK)
414
0
        return;
415
416
    // Loop over all files
417
272
    do {
418
272
        char filename[FileNameSize];
419
272
        unz_file_info fileInfo;
420
421
272
        if (unzGetCurrentFileInfo(m_ZipFileHandle, &fileInfo, filename, FileNameSize, nullptr, 0, nullptr, 0) == UNZ_OK) {
422
272
            if (fileInfo.uncompressed_size != 0 && fileInfo.size_filename <= FileNameSize) {
423
272
                std::string filename_string(filename, fileInfo.size_filename);
424
272
                SimplifyFilename(filename_string);
425
272
                m_ArchiveMap.emplace(filename_string, ZipFileInfo(m_ZipFileHandle, fileInfo.uncompressed_size));
426
272
            }
427
272
        }
428
272
    } while (unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE);
429
12
}
430
431
// ----------------------------------------------------------------
432
488
bool ZipArchiveIOSystem::Implement::isOpen() const {
433
488
    return (m_ZipFileHandle != nullptr);
434
488
}
435
436
// ----------------------------------------------------------------
437
0
void ZipArchiveIOSystem::Implement::getFileList(std::vector<std::string> &rFileList) {
438
0
    MapArchive();
439
0
    rFileList.clear();
440
441
0
    for (const auto &file : m_ArchiveMap) {
442
0
        rFileList.push_back(file.first);
443
0
    }
444
0
}
445
446
// ----------------------------------------------------------------
447
6
void ZipArchiveIOSystem::Implement::getFileListExtension(std::vector<std::string> &rFileList, const std::string &extension) {
448
6
    MapArchive();
449
6
    rFileList.clear();
450
451
134
    for (const auto &file : m_ArchiveMap) {
452
134
        if (extension == BaseImporter::GetExtension(file.first))
453
0
            rFileList.push_back(file.first);
454
134
    }
455
6
}
456
457
// ----------------------------------------------------------------
458
6
bool ZipArchiveIOSystem::Implement::Exists(std::string &filename) {
459
6
    MapArchive();
460
461
6
    ZipFileInfoMap::const_iterator it = m_ArchiveMap.find(filename);
462
6
    return (it != m_ArchiveMap.end());
463
6
}
464
465
// ----------------------------------------------------------------
466
6
IOStream *ZipArchiveIOSystem::Implement::OpenFile(std::string &filename) {
467
6
    MapArchive();
468
469
6
    SimplifyFilename(filename);
470
471
    // Find in the map
472
6
    ZipFileInfoMap::const_iterator zip_it = m_ArchiveMap.find(filename);
473
6
    if (zip_it == m_ArchiveMap.cend())
474
6
        return nullptr;
475
476
0
    const ZipFileInfo &zip_file = (*zip_it).second;
477
0
    return zip_file.Extract(filename, m_ZipFileHandle);
478
6
}
479
480
// ----------------------------------------------------------------
481
0
inline void ReplaceAll(std::string &data, const std::string &before, const std::string &after) {
482
0
    size_t pos = data.find(before);
483
0
    while (pos != std::string::npos) {
484
0
        data.replace(pos, before.size(), after);
485
0
        pos = data.find(before, pos + after.size());
486
0
    }
487
0
}
488
489
// ----------------------------------------------------------------
490
278
inline void ReplaceAllChar(std::string &data, const char before, const char after) {
491
278
    size_t pos = data.find(before);
492
278
    while (pos != std::string::npos) {
493
0
        data[pos] = after;
494
0
        pos = data.find(before, pos + 1);
495
0
    }
496
278
}
497
498
// ----------------------------------------------------------------
499
278
void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string &filename) {
500
278
    ReplaceAllChar(filename, '\\', '/');
501
502
    // Remove all . and / from the beginning of the path
503
278
    size_t pos = filename.find_first_not_of("./");
504
278
    if (pos != 0)
505
0
        filename.erase(0, pos);
506
507
    // Simplify "my/folder/../file.png" constructions, if any
508
278
    static const std::string relative("/../");
509
278
    const size_t relsize = relative.size() - 1;
510
278
    pos = filename.find(relative);
511
278
    while (pos != std::string::npos) {
512
        // Previous slash
513
0
        size_t prevpos = filename.rfind('/', pos - 1);
514
0
        if (prevpos == pos)
515
0
            filename.erase(0, pos + relative.size());
516
0
        else
517
0
            filename.erase(prevpos, pos + relsize - prevpos);
518
519
0
        pos = filename.find(relative);
520
0
    }
521
278
}
522
523
// ----------------------------------------------------------------
524
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const char *pFilename, const char *pMode) :
525
0
        pImpl(new Implement(pIOHandler, pFilename, pMode)) {
526
0
}
527
528
// ----------------------------------------------------------------
529
// The ZipArchiveIO
530
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const std::string &rFilename, const char *pMode) :
531
412
        pImpl(new Implement(pIOHandler, rFilename.c_str(), pMode)) {
532
412
}
533
534
// ----------------------------------------------------------------
535
412
ZipArchiveIOSystem::~ZipArchiveIOSystem() {
536
412
    delete pImpl;
537
412
}
538
539
// ----------------------------------------------------------------
540
6
bool ZipArchiveIOSystem::Exists(const char *pFilename) const {
541
6
    ai_assert(pFilename != nullptr);
542
543
6
    if (pFilename == nullptr) {
544
0
        return false;
545
0
    }
546
547
6
    std::string filename(pFilename);
548
6
    return pImpl->Exists(filename);
549
6
}
550
551
// ----------------------------------------------------------------
552
// This is always '/' in a ZIP
553
0
char ZipArchiveIOSystem::getOsSeparator() const {
554
0
    return '/';
555
0
}
556
557
// ----------------------------------------------------------------
558
// Only supports Reading
559
6
IOStream *ZipArchiveIOSystem::Open(const char *pFilename, const char *pMode) {
560
6
    ai_assert(pFilename != nullptr);
561
562
18
    for (size_t i = 0; pMode[i] != 0; ++i) {
563
12
        ai_assert(pMode[i] != 'w');
564
12
        if (pMode[i] == 'w')
565
0
            return nullptr;
566
12
    }
567
568
6
    std::string filename(pFilename);
569
6
    return pImpl->OpenFile(filename);
570
6
}
571
572
// ----------------------------------------------------------------
573
0
void ZipArchiveIOSystem::Close(IOStream *pFile) {
574
0
    delete pFile;
575
0
}
576
577
// ----------------------------------------------------------------
578
406
bool ZipArchiveIOSystem::isOpen() const {
579
406
    return (pImpl->isOpen());
580
406
}
581
582
// ----------------------------------------------------------------
583
0
void ZipArchiveIOSystem::getFileList(std::vector<std::string> &rFileList) const {
584
0
    return pImpl->getFileList(rFileList);
585
0
}
586
587
// ----------------------------------------------------------------
588
6
void ZipArchiveIOSystem::getFileListExtension(std::vector<std::string> &rFileList, const std::string &extension) const {
589
6
    return pImpl->getFileListExtension(rFileList, extension);
590
6
}
591
592
// ----------------------------------------------------------------
593
82
bool ZipArchiveIOSystem::isZipArchive(IOSystem *pIOHandler, const char *pFilename) {
594
82
    Implement tmp(pIOHandler, pFilename, "r");
595
82
    return tmp.isOpen();
596
82
}
597
598
82
bool ZipArchiveIOSystem::isZipArchive(IOSystem *pIOHandler, const std::string &rFilename) {
599
82
    return isZipArchive(pIOHandler, rFilename.c_str());
600
82
}
601
602
} // namespace Assimp