minizip_helpers.h (2902B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "file_system.h" 7 #include "ioapi.h" 8 #include "types.h" 9 #include "unzip.h" 10 #include <algorithm> 11 12 namespace MinizipHelpers { 13 14 [[maybe_unused]] static unzFile OpenUnzMemoryFile(const void* memory, size_t memory_size) 15 { 16 struct MemoryFileInfo 17 { 18 const u8* data; 19 ZPOS64_T data_size; 20 ZPOS64_T position; 21 }; 22 23 MemoryFileInfo* fi = new MemoryFileInfo; 24 fi->data = static_cast<const u8*>(memory); 25 fi->data_size = static_cast<ZPOS64_T>(memory_size); 26 fi->position = 0; 27 28 #define FI static_cast<MemoryFileInfo*>(stream) 29 30 zlib_filefunc64_def funcs = { 31 [](voidpf opaque, const void* filename, int mode) -> voidpf { return opaque; }, // open 32 [](voidpf opaque, voidpf stream, void* buf, uLong size) -> uLong { // read 33 const ZPOS64_T remaining = FI->data_size - FI->position; 34 const ZPOS64_T to_read = std::min(remaining, static_cast<ZPOS64_T>(size)); 35 if (to_read > 0) 36 { 37 std::memcpy(buf, FI->data + FI->position, to_read); 38 FI->position += to_read; 39 } 40 41 return static_cast<uLong>(to_read); 42 }, 43 [](voidpf opaque, voidpf stream, const void* buf, uLong size) -> uLong { return 0; }, // write 44 [](voidpf opaque, voidpf stream) -> ZPOS64_T { return static_cast<ZPOS64_T>(FI->position); }, // tell 45 [](voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) -> long { // seek 46 ZPOS64_T new_position = FI->position; 47 if (origin == SEEK_SET) 48 new_position = static_cast<int>(offset); 49 else if (origin == SEEK_CUR) 50 new_position += static_cast<int>(offset); 51 else 52 new_position = FI->data_size; 53 if (new_position < 0 || new_position > FI->data_size) 54 return -1; 55 56 FI->position = new_position; 57 return 0; 58 }, 59 [](voidpf opaque, voidpf stream) -> int { 60 delete FI; 61 return 0; 62 }, // close 63 [](voidpf opaque, voidpf stream) -> int { return 0; }, // testerror 64 static_cast<voidpf>(fi)}; 65 66 #undef FI 67 68 return unzOpen2_64("", &funcs); 69 } 70 71 [[maybe_unused]] static unzFile OpenUnzFile(const char* filename) 72 { 73 zlib_filefunc64_def funcs; 74 fill_fopen64_filefunc(&funcs); 75 76 funcs.zopen64_file = [](voidpf opaque, const void* filename, int mode) -> voidpf { 77 const char* mode_fopen = NULL; 78 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) 79 mode_fopen = "rb"; 80 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 81 mode_fopen = "r+b"; 82 else if (mode & ZLIB_FILEFUNC_MODE_CREATE) 83 mode_fopen = "wb"; 84 85 return FileSystem::OpenCFile(static_cast<const char*>(filename), mode_fopen); 86 }; 87 88 return unzOpen2_64(filename, &funcs); 89 } 90 91 } // namespace MinizipHelpers