1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

#include "fsCZipFile.h"

#include "miniz/miniz.h"

#include "fsCResourceName.h"
#include "fsIFile.h"
#include "debug/fsAssert.h"


struct fsCZipFile::Impl {
    mz_zip_archive archive;
    fsStr zipBytes;
};

fsCZipFile::fsCZipFile(const fsCResourceName& pResourceName) :
fsIZipFile(pResourceName)
{
    mArchive = std::make_unique<Impl>();
    memset(&mArchive->archive, 0, sizeof(mArchive->archive));
    mArchive->zipBytes = fsIFile::bytesGetFromCompressedFileBinary(pResourceName);

    const fsU8* zipData = mArchive->zipBytes.ptrGet();
    const size_t zipSize = static_cast<size_t>(mArchive->zipBytes.dataSizeGet());

    if (mz_zip_reader_init_mem(&mArchive->archive, zipData, zipSize, 0) != MZ_TRUE) {
        // handle error
    }
}

fsStr fsCZipFile::assetRead(fsStr &pAssetName)
{
    std::string entry = pAssetName.utf8Get(); // exporter stores entries at zip root
    int fileIndex = mz_zip_reader_locate_file(&mArchive->archive, entry.c_str(), nullptr, 0);
    fsAssert(fileIndex >= 0, "cluster load error (missing zip entry)");

    size_t outSize = 0;
    void* outBuf = mz_zip_reader_extract_to_heap(&mArchive->archive, fileIndex, &outSize, 0);
    fsAssert(outBuf && outSize > 0, "cluster load error (zip extract)");

    fsStr out(reinterpret_cast<const char*>(outBuf), static_cast<fsS32>(outSize));
    mz_free(outBuf);
    return out;

}

fsCZipFile::~fsCZipFile()
{
    mz_zip_reader_end(&mArchive->archive);
}