| /* mz_compat.c -- Backwards compatible interface for older versions |
| part of the minizip-ng project |
| |
| Copyright (C) Nathan Moinvaziri |
| https://github.com/zlib-ng/minizip-ng |
| Copyright (C) 1998-2010 Gilles Vollant |
| https://www.winimage.com/zLibDll/minizip.html |
| |
| This program is distributed under the terms of the same license as zlib. |
| See the accompanying LICENSE file for the full text of the license. |
| */ |
| |
| #include "mz.h" |
| #include "mz_os.h" |
| #include "mz_strm.h" |
| #include "mz_strm_mem.h" |
| #include "mz_strm_os.h" |
| #include "mz_strm_zlib.h" |
| #include "mz_zip.h" |
| |
| #include <stdio.h> /* SEEK */ |
| |
| #include "mz_compat.h" |
| |
| /***************************************************************************/ |
| |
| typedef struct mz_compat_s { |
| void *stream; |
| void *handle; |
| uint64_t entry_index; |
| int64_t entry_pos; |
| int64_t total_out; |
| } mz_compat; |
| |
| /***************************************************************************/ |
| |
| typedef struct mz_stream_ioapi_s { |
| mz_stream stream; |
| void *handle; |
| zlib_filefunc_def filefunc; |
| zlib_filefunc64_def filefunc64; |
| } mz_stream_ioapi; |
| |
| /***************************************************************************/ |
| |
| static int32_t mz_stream_ioapi_open(void *stream, const char *path, int32_t mode); |
| static int32_t mz_stream_ioapi_is_open(void *stream); |
| static int32_t mz_stream_ioapi_read(void *stream, void *buf, int32_t size); |
| static int32_t mz_stream_ioapi_write(void *stream, const void *buf, int32_t size); |
| static int64_t mz_stream_ioapi_tell(void *stream); |
| static int32_t mz_stream_ioapi_seek(void *stream, int64_t offset, int32_t origin); |
| static int32_t mz_stream_ioapi_close(void *stream); |
| static int32_t mz_stream_ioapi_error(void *stream); |
| static void *mz_stream_ioapi_create(void); |
| static void mz_stream_ioapi_delete(void **stream); |
| |
| /***************************************************************************/ |
| |
| static mz_stream_vtbl mz_stream_ioapi_vtbl = { |
| mz_stream_ioapi_open, |
| mz_stream_ioapi_is_open, |
| mz_stream_ioapi_read, |
| mz_stream_ioapi_write, |
| mz_stream_ioapi_tell, |
| mz_stream_ioapi_seek, |
| mz_stream_ioapi_close, |
| mz_stream_ioapi_error, |
| mz_stream_ioapi_create, |
| mz_stream_ioapi_delete, |
| NULL, |
| NULL |
| }; |
| |
| /***************************************************************************/ |
| |
| static int32_t mz_stream_ioapi_open(void *stream, const char *path, int32_t mode) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| int32_t ioapi_mode = 0; |
| |
| if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ) |
| ioapi_mode = ZLIB_FILEFUNC_MODE_READ; |
| else if (mode & MZ_OPEN_MODE_APPEND) |
| ioapi_mode = ZLIB_FILEFUNC_MODE_EXISTING; |
| else if (mode & MZ_OPEN_MODE_CREATE) |
| ioapi_mode = ZLIB_FILEFUNC_MODE_CREATE; |
| else |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc64.zopen64_file) |
| ioapi->handle = ioapi->filefunc64.zopen64_file(ioapi->filefunc64.opaque, path, ioapi_mode); |
| else if (ioapi->filefunc.zopen_file) |
| ioapi->handle = ioapi->filefunc.zopen_file(ioapi->filefunc.opaque, path, ioapi_mode); |
| |
| if (!ioapi->handle) |
| return MZ_PARAM_ERROR; |
| |
| return MZ_OK; |
| } |
| |
| static int32_t mz_stream_ioapi_is_open(void *stream) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| if (!ioapi->handle) |
| return MZ_OPEN_ERROR; |
| return MZ_OK; |
| } |
| |
| static int32_t mz_stream_ioapi_read(void *stream, void *buf, int32_t size) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| read_file_func zread = NULL; |
| void *opaque = NULL; |
| |
| if (mz_stream_ioapi_is_open(stream) != MZ_OK) |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc64.zread_file) { |
| zread = ioapi->filefunc64.zread_file; |
| opaque = ioapi->filefunc64.opaque; |
| } else if (ioapi->filefunc.zread_file) { |
| zread = ioapi->filefunc.zread_file; |
| opaque = ioapi->filefunc.opaque; |
| } else |
| return MZ_PARAM_ERROR; |
| |
| return (int32_t)zread(opaque, ioapi->handle, buf, size); |
| } |
| |
| static int32_t mz_stream_ioapi_write(void *stream, const void *buf, int32_t size) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| write_file_func zwrite = NULL; |
| int32_t written = 0; |
| void *opaque = NULL; |
| |
| if (mz_stream_ioapi_is_open(stream) != MZ_OK) |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc64.zwrite_file) { |
| zwrite = ioapi->filefunc64.zwrite_file; |
| opaque = ioapi->filefunc64.opaque; |
| } else if (ioapi->filefunc.zwrite_file) { |
| zwrite = ioapi->filefunc.zwrite_file; |
| opaque = ioapi->filefunc.opaque; |
| } else |
| return MZ_PARAM_ERROR; |
| |
| written = (int32_t)zwrite(opaque, ioapi->handle, buf, size); |
| return written; |
| } |
| |
| static int64_t mz_stream_ioapi_tell(void *stream) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| |
| if (mz_stream_ioapi_is_open(stream) != MZ_OK) |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc64.ztell64_file) |
| return ioapi->filefunc64.ztell64_file(ioapi->filefunc64.opaque, ioapi->handle); |
| else if (ioapi->filefunc.ztell_file) |
| return ioapi->filefunc.ztell_file(ioapi->filefunc.opaque, ioapi->handle); |
| |
| return MZ_INTERNAL_ERROR; |
| } |
| |
| static int32_t mz_stream_ioapi_seek(void *stream, int64_t offset, int32_t origin) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| |
| if (mz_stream_ioapi_is_open(stream) != MZ_OK) |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc64.zseek64_file) { |
| if (ioapi->filefunc64.zseek64_file(ioapi->filefunc64.opaque, ioapi->handle, offset, origin) != 0) |
| return MZ_INTERNAL_ERROR; |
| } else if (ioapi->filefunc.zseek_file) { |
| if (ioapi->filefunc.zseek_file(ioapi->filefunc.opaque, ioapi->handle, (int32_t)offset, origin) != 0) |
| return MZ_INTERNAL_ERROR; |
| } else |
| return MZ_PARAM_ERROR; |
| |
| return MZ_OK; |
| } |
| |
| static int32_t mz_stream_ioapi_close(void *stream) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| close_file_func zclose = NULL; |
| void *opaque = NULL; |
| |
| if (mz_stream_ioapi_is_open(stream) != MZ_OK) |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc.zclose_file) { |
| zclose = ioapi->filefunc.zclose_file; |
| opaque = ioapi->filefunc.opaque; |
| } else if (ioapi->filefunc64.zclose_file) { |
| zclose = ioapi->filefunc64.zclose_file; |
| opaque = ioapi->filefunc64.opaque; |
| } else |
| return MZ_PARAM_ERROR; |
| |
| if (zclose(opaque, ioapi->handle) != 0) |
| return MZ_CLOSE_ERROR; |
| ioapi->handle = NULL; |
| return MZ_OK; |
| } |
| |
| static int32_t mz_stream_ioapi_error(void *stream) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| testerror_file_func zerror = NULL; |
| void *opaque = NULL; |
| |
| if (mz_stream_ioapi_is_open(stream) != MZ_OK) |
| return MZ_OPEN_ERROR; |
| |
| if (ioapi->filefunc.zerror_file) { |
| zerror = ioapi->filefunc.zerror_file; |
| opaque = ioapi->filefunc.opaque; |
| } else if (ioapi->filefunc64.zerror_file) { |
| zerror = ioapi->filefunc64.zerror_file; |
| opaque = ioapi->filefunc64.opaque; |
| } else |
| return MZ_PARAM_ERROR; |
| |
| return zerror(opaque, ioapi->handle); |
| } |
| |
| static int32_t mz_stream_ioapi_set_filefunc(void *stream, zlib_filefunc_def *filefunc) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| memcpy(&ioapi->filefunc, filefunc, sizeof(zlib_filefunc_def)); |
| return MZ_OK; |
| } |
| |
| static int32_t mz_stream_ioapi_set_filefunc64(void *stream, zlib_filefunc64_def *filefunc) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)stream; |
| memcpy(&ioapi->filefunc64, filefunc, sizeof(zlib_filefunc64_def)); |
| return MZ_OK; |
| } |
| |
| static void *mz_stream_ioapi_create(void) { |
| mz_stream_ioapi *ioapi = (mz_stream_ioapi *)calloc(1, sizeof(mz_stream_ioapi)); |
| if (ioapi) |
| ioapi->stream.vtbl = &mz_stream_ioapi_vtbl; |
| return ioapi; |
| } |
| |
| static void mz_stream_ioapi_delete(void **stream) { |
| mz_stream_ioapi *ioapi = NULL; |
| if (!stream) |
| return; |
| ioapi = (mz_stream_ioapi *)*stream; |
| if (ioapi) |
| free(ioapi); |
| *stream = NULL; |
| } |
| |
| /***************************************************************************/ |
| |
| void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def) { |
| /* For 32-bit file support only, compile with MZ_FILE32_API */ |
| if (pzlib_filefunc_def) |
| memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def)); |
| } |
| |
| void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def) { |
| /* All mz_stream_os_* support large files if compilation supports it */ |
| if (pzlib_filefunc_def) |
| memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def)); |
| } |
| |
| void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def) { |
| /* Handled by mz_stream_os_win32 */ |
| if (pzlib_filefunc_def) |
| memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def)); |
| } |
| |
| void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def) { |
| /* Automatically supported in mz_stream_os_win32 */ |
| if (pzlib_filefunc_def) |
| memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def)); |
| } |
| |
| void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def) { |
| /* Automatically supported in mz_stream_os_win32 */ |
| if (pzlib_filefunc_def) |
| memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc64_def)); |
| } |
| |
| /* NOTE: fill_win32_filefunc64W is no longer necessary since wide-character |
| support is automatically handled by the underlying os stream. Do not |
| pass wide-characters to zipOpen or unzOpen. */ |
| |
| void fill_memory_filefunc(zlib_filefunc_def *pzlib_filefunc_def) { |
| /* Use opaque to indicate which stream interface to create */ |
| if (pzlib_filefunc_def) { |
| memset(pzlib_filefunc_def, 0, sizeof(zlib_filefunc_def)); |
| pzlib_filefunc_def->opaque = mz_stream_mem_get_interface(); |
| } |
| } |
| |
| /***************************************************************************/ |
| |
| static int32_t zipConvertAppendToStreamMode(int append) { |
| int32_t mode = MZ_OPEN_MODE_WRITE; |
| switch (append) { |
| case APPEND_STATUS_CREATE: |
| mode |= MZ_OPEN_MODE_CREATE; |
| break; |
| case APPEND_STATUS_CREATEAFTER: |
| mode |= MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_APPEND; |
| break; |
| case APPEND_STATUS_ADDINZIP: |
| mode |= MZ_OPEN_MODE_READ | MZ_OPEN_MODE_APPEND; |
| break; |
| } |
| return mode; |
| } |
| |
| zipFile zipOpen(const char *path, int append) { |
| return zipOpen2(path, append, NULL, NULL); |
| } |
| |
| zipFile zipOpen64(const void *path, int append) { |
| return zipOpen2(path, append, NULL, NULL); |
| } |
| |
| zipFile zipOpen2(const char *path, int append, const char **globalcomment, |
| zlib_filefunc_def *pzlib_filefunc_def) { |
| zipFile zip = NULL; |
| int32_t mode = zipConvertAppendToStreamMode(append); |
| void *stream = NULL; |
| |
| if (pzlib_filefunc_def) { |
| if (pzlib_filefunc_def->zopen_file) { |
| stream = mz_stream_ioapi_create(); |
| if (!stream) |
| return NULL; |
| mz_stream_ioapi_set_filefunc(stream, pzlib_filefunc_def); |
| } else if (pzlib_filefunc_def->opaque) { |
| stream = mz_stream_create((mz_stream_vtbl *)pzlib_filefunc_def->opaque); |
| if (!stream) |
| return NULL; |
| } |
| } |
| |
| if (!stream) { |
| stream = mz_stream_os_create(); |
| if (!stream) |
| return NULL; |
| } |
| |
| if (mz_stream_open(stream, path, mode) != MZ_OK) { |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| |
| zip = zipOpen_MZ(stream, append, globalcomment); |
| |
| if (!zip) { |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| |
| return zip; |
| } |
| |
| zipFile zipOpen2_64(const void *path, int append, const char **globalcomment, |
| zlib_filefunc64_def *pzlib_filefunc_def) { |
| zipFile zip = NULL; |
| int32_t mode = zipConvertAppendToStreamMode(append); |
| void *stream = NULL; |
| |
| if (pzlib_filefunc_def) { |
| if (pzlib_filefunc_def->zopen64_file) { |
| stream = mz_stream_ioapi_create(); |
| if (!stream) |
| return NULL; |
| mz_stream_ioapi_set_filefunc64(stream, pzlib_filefunc_def); |
| } else if (pzlib_filefunc_def->opaque) { |
| stream = mz_stream_create((mz_stream_vtbl *)pzlib_filefunc_def->opaque); |
| if (!stream) |
| return NULL; |
| } |
| } |
| |
| if (!stream) { |
| stream = mz_stream_os_create(); |
| if (!stream) |
| return NULL; |
| } |
| |
| if (mz_stream_open(stream, path, mode) != MZ_OK) { |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| |
| zip = zipOpen_MZ(stream, append, globalcomment); |
| |
| if (!zip) { |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| |
| return zip; |
| } |
| |
| zipFile zipOpen_MZ(void *stream, int append, const char **globalcomment) { |
| mz_compat *compat = NULL; |
| int32_t err = MZ_OK; |
| int32_t mode = zipConvertAppendToStreamMode(append); |
| void *handle = NULL; |
| |
| handle = mz_zip_create(); |
| if (!handle) |
| return NULL; |
| |
| err = mz_zip_open(handle, stream, mode); |
| |
| if (err != MZ_OK) { |
| mz_zip_delete(&handle); |
| return NULL; |
| } |
| |
| if (globalcomment) |
| mz_zip_get_comment(handle, globalcomment); |
| |
| compat = (mz_compat *)calloc(1, sizeof(mz_compat)); |
| if (compat) { |
| compat->handle = handle; |
| compat->stream = stream; |
| } else { |
| mz_zip_delete(&handle); |
| } |
| |
| return (zipFile)compat; |
| } |
| |
| void* zipGetHandle_MZ(zipFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return NULL; |
| return compat->handle; |
| } |
| |
| void* zipGetStream_MZ(zipFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return NULL; |
| return (void *)compat->stream; |
| } |
| |
| int zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw, int windowBits, int memLevel, int strategy, const char *password, |
| unsigned long crc_for_crypting, unsigned long version_madeby, unsigned long flag_base, int zip64) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file file_info; |
| |
| MZ_UNUSED(strategy); |
| MZ_UNUSED(memLevel); |
| MZ_UNUSED(windowBits); |
| MZ_UNUSED(size_extrafield_local); |
| MZ_UNUSED(extrafield_local); |
| MZ_UNUSED(crc_for_crypting); |
| |
| if (!compat) |
| return ZIP_PARAMERROR; |
| |
| /* The filename and comment length must fit in 16 bits. */ |
| if (filename && strlen(filename) > 0xffff) |
| return ZIP_PARAMERROR; |
| if (comment && strlen(comment) > 0xffff) |
| return ZIP_PARAMERROR; |
| |
| memset(&file_info, 0, sizeof(file_info)); |
| |
| if (zipfi) { |
| uint64_t dos_date = 0; |
| |
| if (zipfi->mz_dos_date != 0) |
| dos_date = zipfi->mz_dos_date; |
| else |
| dos_date = mz_zip_tm_to_dosdate(&zipfi->tmz_date); |
| |
| file_info.modified_date = mz_zip_dosdate_to_time_t(dos_date); |
| file_info.external_fa = (uint32_t)zipfi->external_fa; |
| file_info.internal_fa = (uint16_t)zipfi->internal_fa; |
| } |
| |
| if (!filename) |
| filename = "-"; |
| |
| file_info.compression_method = (uint16_t)compression_method; |
| file_info.filename = filename; |
| /* file_info.extrafield_local = extrafield_local; */ |
| /* file_info.extrafield_local_size = size_extrafield_local; */ |
| file_info.extrafield = extrafield_global; |
| file_info.extrafield_size = size_extrafield_global; |
| file_info.version_madeby = (uint16_t)version_madeby; |
| file_info.comment = comment; |
| if (file_info.comment) |
| file_info.comment_size = (uint16_t)strlen(file_info.comment); |
| file_info.flag = (uint16_t)flag_base; |
| if (zip64) |
| file_info.zip64 = MZ_ZIP64_FORCE; |
| else |
| file_info.zip64 = MZ_ZIP64_DISABLE; |
| #ifdef HAVE_WZAES |
| if (password || (raw && (file_info.flag & MZ_ZIP_FLAG_ENCRYPTED))) |
| file_info.aes_version = MZ_AES_VERSION; |
| #endif |
| |
| return mz_zip_entry_write_open(compat->handle, &file_info, (int16_t)level, (uint8_t)raw, password); |
| } |
| |
| int zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw, int windowBits, int memLevel, int strategy, const char *password, |
| unsigned long crc_for_crypting, unsigned long version_madeby, unsigned long flag_base, int zip64) { |
| return zipOpenNewFileInZip5(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, |
| memLevel, strategy, password, crc_for_crypting, version_madeby, flag_base, zip64); |
| } |
| |
| int zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw, int windowBits, int memLevel, int strategy, const char *password, |
| unsigned long crc_for_crypting, unsigned long version_madeby, unsigned long flag_base) { |
| return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, |
| memLevel, strategy, password, crc_for_crypting, version_madeby, flag_base, 0); |
| } |
| |
| int zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw, int windowBits, int memLevel, int strategy, const char *password, |
| unsigned long crc_for_crypting) { |
| return zipOpenNewFileInZip3_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, |
| memLevel, strategy, password, crc_for_crypting, 0); |
| } |
| |
| int zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw, int windowBits, int memLevel, int strategy, const char *password, |
| unsigned long crc_for_crypting, int zip64) { |
| return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, |
| memLevel, strategy, password, crc_for_crypting, MZ_VERSION_MADEBY, 0, zip64); |
| } |
| |
| int zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw) { |
| return zipOpenNewFileInZip3_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, raw, |
| 0, 0, 0, NULL, 0, 0); |
| } |
| |
| int zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int raw, int zip64) { |
| return zipOpenNewFileInZip3_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, raw, 0, |
| 0, 0, NULL, 0, zip64); |
| } |
| |
| int zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level) { |
| return zipOpenNewFileInZip_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, 0); |
| } |
| |
| int zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int zip64) { |
| return zipOpenNewFileInZip2_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, 0, zip64); |
| } |
| |
| int zipOpenNewFileInZip_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, |
| const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, |
| uint16_t size_extrafield_global, const char *comment, int compression_method, int level, |
| int zip64) { |
| return zipOpenNewFileInZip2_64(file, filename, zipfi, extrafield_local, size_extrafield_local, |
| extrafield_global, size_extrafield_global, comment, compression_method, level, 0, zip64); |
| } |
| |
| int zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t written = 0; |
| if (!compat || len >= INT32_MAX) |
| return ZIP_PARAMERROR; |
| written = mz_zip_entry_write(compat->handle, buf, (int32_t)len); |
| if ((written < 0) || ((uint32_t)written != len)) |
| return ZIP_ERRNO; |
| return ZIP_OK; |
| } |
| |
| int zipCloseFileInZipRaw(zipFile file, unsigned long uncompressed_size, unsigned long crc32) { |
| return zipCloseFileInZipRaw64(file, uncompressed_size, crc32); |
| } |
| |
| int zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, unsigned long crc32) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return ZIP_PARAMERROR; |
| return mz_zip_entry_close_raw(compat->handle, (int64_t)uncompressed_size, (uint32_t)crc32); |
| } |
| |
| int zipCloseFileInZip(zipFile file) { |
| return zipCloseFileInZip64(file); |
| } |
| |
| int zipCloseFileInZip64(zipFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return ZIP_PARAMERROR; |
| return mz_zip_entry_close(compat->handle); |
| } |
| |
| int zipClose(zipFile file, const char *global_comment) { |
| return zipClose_64(file, global_comment); |
| } |
| |
| int zipClose_64(zipFile file, const char *global_comment) { |
| return zipClose2_64(file, global_comment, MZ_VERSION_MADEBY); |
| } |
| |
| int zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| |
| if (compat->handle) |
| err = zipClose2_MZ(file, global_comment, version_madeby); |
| |
| if (compat->stream) { |
| mz_stream_close(compat->stream); |
| mz_stream_delete(&compat->stream); |
| } |
| |
| free(compat); |
| |
| return err; |
| } |
| |
| /* Only closes the zip handle, does not close the stream */ |
| int zipClose_MZ(zipFile file, const char *global_comment) { |
| return zipClose2_MZ(file, global_comment, MZ_VERSION_MADEBY); |
| } |
| |
| /* Only closes the zip handle, does not close the stream */ |
| int zipClose2_MZ(zipFile file, const char *global_comment, uint16_t version_madeby) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| |
| if (!compat) |
| return ZIP_PARAMERROR; |
| if (!compat->handle) |
| return err; |
| |
| if (global_comment) |
| mz_zip_set_comment(compat->handle, global_comment); |
| |
| mz_zip_set_version_madeby(compat->handle, version_madeby); |
| err = mz_zip_close(compat->handle); |
| mz_zip_delete(&compat->handle); |
| |
| return err; |
| } |
| |
| /***************************************************************************/ |
| |
| unzFile unzOpen(const char *path) { |
| return unzOpen64(path); |
| } |
| |
| unzFile unzOpen64(const void *path) { |
| return unzOpen2(path, NULL); |
| } |
| |
| unzFile unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def) { |
| unzFile unz = NULL; |
| void *stream = NULL; |
| |
| if (pzlib_filefunc_def) { |
| if (pzlib_filefunc_def->zopen_file) { |
| stream = mz_stream_ioapi_create(); |
| if (!stream) |
| return NULL; |
| mz_stream_ioapi_set_filefunc(stream, pzlib_filefunc_def); |
| } else if (pzlib_filefunc_def->opaque) { |
| stream = mz_stream_create((mz_stream_vtbl *)pzlib_filefunc_def->opaque); |
| if (!stream) |
| return NULL; |
| } |
| } |
| |
| if (!stream) { |
| stream = mz_stream_os_create(); |
| if (!stream) |
| return NULL; |
| } |
| |
| if (mz_stream_open(stream, path, MZ_OPEN_MODE_READ) != MZ_OK) { |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| |
| unz = unzOpen_MZ(stream); |
| if (!unz) { |
| mz_stream_close(stream); |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| return unz; |
| } |
| |
| unzFile unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def) { |
| unzFile unz = NULL; |
| void *stream = NULL; |
| |
| if (pzlib_filefunc_def) { |
| if (pzlib_filefunc_def->zopen64_file) { |
| stream = mz_stream_ioapi_create(); |
| if (!stream) |
| return NULL; |
| mz_stream_ioapi_set_filefunc64(stream, pzlib_filefunc_def); |
| } else if (pzlib_filefunc_def->opaque) { |
| stream = mz_stream_create((mz_stream_vtbl *)pzlib_filefunc_def->opaque); |
| if (!stream) |
| return NULL; |
| } |
| } |
| |
| if (!stream) { |
| stream = mz_stream_os_create(); |
| if (!stream) |
| return NULL; |
| } |
| |
| if (mz_stream_open(stream, path, MZ_OPEN_MODE_READ) != MZ_OK) { |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| |
| unz = unzOpen_MZ(stream); |
| if (!unz) { |
| mz_stream_close(stream); |
| mz_stream_delete(&stream); |
| return NULL; |
| } |
| return unz; |
| } |
| |
| void* unzGetHandle_MZ(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return NULL; |
| return compat->handle; |
| } |
| |
| void* unzGetStream_MZ(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return NULL; |
| return compat->stream; |
| } |
| |
| unzFile unzOpen_MZ(void *stream) { |
| mz_compat *compat = NULL; |
| int32_t err = MZ_OK; |
| void *handle = NULL; |
| |
| handle = mz_zip_create(); |
| if (!handle) |
| return NULL; |
| |
| err = mz_zip_open(handle, stream, MZ_OPEN_MODE_READ); |
| if (err != MZ_OK) { |
| mz_zip_delete(&handle); |
| return NULL; |
| } |
| |
| compat = (mz_compat *)calloc(1, sizeof(mz_compat)); |
| if (compat) { |
| compat->handle = handle; |
| compat->stream = stream; |
| |
| mz_zip_goto_first_entry(compat->handle); |
| } else { |
| mz_zip_delete(&handle); |
| } |
| |
| return (unzFile)compat; |
| } |
| |
| int unzClose(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| if (compat->handle) |
| err = unzClose_MZ(file); |
| |
| if (compat->stream) { |
| mz_stream_close(compat->stream); |
| mz_stream_delete(&compat->stream); |
| } |
| |
| free(compat); |
| |
| return err; |
| } |
| |
| /* Only closes the zip handle, does not close the stream */ |
| int unzClose_MZ(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| err = mz_zip_close(compat->handle); |
| mz_zip_delete(&compat->handle); |
| |
| return err; |
| } |
| |
| int unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) { |
| mz_compat *compat = (mz_compat *)file; |
| unz_global_info64 global_info64; |
| int32_t err = MZ_OK; |
| |
| memset(pglobal_info32, 0, sizeof(unz_global_info)); |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| err = unzGetGlobalInfo64(file, &global_info64); |
| if (err == MZ_OK) { |
| pglobal_info32->number_entry = (uint32_t)global_info64.number_entry; |
| pglobal_info32->size_comment = global_info64.size_comment; |
| pglobal_info32->number_disk_with_CD = global_info64.number_disk_with_CD; |
| } |
| return err; |
| } |
| |
| int unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info) { |
| mz_compat *compat = (mz_compat *)file; |
| const char *comment_ptr = NULL; |
| int32_t err = MZ_OK; |
| |
| memset(pglobal_info, 0, sizeof(unz_global_info64)); |
| if (!compat) |
| return UNZ_PARAMERROR; |
| err = mz_zip_get_comment(compat->handle, &comment_ptr); |
| if (err == MZ_OK) |
| pglobal_info->size_comment = (uint16_t)strlen(comment_ptr); |
| if ((err == MZ_OK) || (err == MZ_EXIST_ERROR)) |
| err = mz_zip_get_number_entry(compat->handle, &pglobal_info->number_entry); |
| if (err == MZ_OK) |
| err = mz_zip_get_disk_number_with_cd(compat->handle, &pglobal_info->number_disk_with_CD); |
| return err; |
| } |
| |
| int unzGetGlobalComment(unzFile file, char *comment, unsigned long comment_size) { |
| mz_compat *compat = (mz_compat *)file; |
| const char *comment_ptr = NULL; |
| int32_t err = MZ_OK; |
| |
| if (!comment || !comment_size) |
| return UNZ_PARAMERROR; |
| err = mz_zip_get_comment(compat->handle, &comment_ptr); |
| if (err == MZ_OK) { |
| strncpy(comment, comment_ptr, comment_size - 1); |
| comment[comment_size - 1] = 0; |
| } |
| return err; |
| } |
| |
| int unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| int32_t err = MZ_OK; |
| void *stream = NULL; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| if (method) |
| *method = 0; |
| if (level) |
| *level = 0; |
| |
| if (mz_zip_entry_is_open(compat->handle) == MZ_OK) { |
| /* zlib minizip does not error out here if close returns errors */ |
| unzCloseCurrentFile(file); |
| } |
| |
| compat->total_out = 0; |
| err = mz_zip_entry_read_open(compat->handle, (uint8_t)raw, password); |
| if (err == MZ_OK) |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err == MZ_OK) { |
| if (method) { |
| *method = file_info->compression_method; |
| } |
| |
| if (level) { |
| *level = 6; |
| switch (file_info->flag & 0x06) { |
| case MZ_ZIP_FLAG_DEFLATE_SUPER_FAST: |
| *level = 1; |
| break; |
| case MZ_ZIP_FLAG_DEFLATE_FAST: |
| *level = 2; |
| break; |
| case MZ_ZIP_FLAG_DEFLATE_MAX: |
| *level = 9; |
| break; |
| } |
| } |
| } |
| if (err == MZ_OK) |
| err = mz_zip_get_stream(compat->handle, &stream); |
| if (err == MZ_OK) |
| compat->entry_pos = mz_stream_tell(stream); |
| return err; |
| } |
| |
| int unzOpenCurrentFile(unzFile file) { |
| return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); |
| } |
| |
| int unzOpenCurrentFilePassword(unzFile file, const char *password) { |
| return unzOpenCurrentFile3(file, NULL, NULL, 0, password); |
| } |
| |
| int unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw) { |
| return unzOpenCurrentFile3(file, method, level, raw, NULL); |
| } |
| |
| int unzReadCurrentFile(unzFile file, void *buf, uint32_t len) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| if (!compat || len >= INT32_MAX) |
| return UNZ_PARAMERROR; |
| err = mz_zip_entry_read(compat->handle, buf, (int32_t)len); |
| if (err > 0) |
| compat->total_out += (uint32_t)err; |
| return err; |
| } |
| |
| int unzCloseCurrentFile(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| if (!compat) |
| return UNZ_PARAMERROR; |
| err = mz_zip_entry_close(compat->handle); |
| return err; |
| } |
| |
| int unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename, |
| unsigned long filename_size, void *extrafield, unsigned long extrafield_size, char *comment, |
| unsigned long comment_size) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| uint16_t bytes_to_copy = 0; |
| int32_t err = MZ_OK; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| return err; |
| |
| if (pfile_info) { |
| pfile_info->version = file_info->version_madeby; |
| pfile_info->version_needed = file_info->version_needed; |
| pfile_info->flag = file_info->flag; |
| pfile_info->compression_method = file_info->compression_method; |
| pfile_info->mz_dos_date = mz_zip_time_t_to_dos_date(file_info->modified_date); |
| mz_zip_time_t_to_tm(file_info->modified_date, &pfile_info->tmu_date); |
| pfile_info->tmu_date.tm_year += 1900; |
| pfile_info->crc = file_info->crc; |
| |
| pfile_info->size_filename = file_info->filename_size; |
| pfile_info->size_file_extra = file_info->extrafield_size; |
| pfile_info->size_file_comment = file_info->comment_size; |
| |
| pfile_info->disk_num_start = (uint16_t)file_info->disk_number; |
| pfile_info->internal_fa = file_info->internal_fa; |
| pfile_info->external_fa = file_info->external_fa; |
| |
| pfile_info->compressed_size = (uint32_t)file_info->compressed_size; |
| pfile_info->uncompressed_size = (uint32_t)file_info->uncompressed_size; |
| } |
| if (filename_size > 0 && filename && file_info->filename) { |
| bytes_to_copy = (uint16_t)filename_size; |
| if (bytes_to_copy > file_info->filename_size) |
| bytes_to_copy = file_info->filename_size; |
| memcpy(filename, file_info->filename, bytes_to_copy); |
| if (bytes_to_copy < filename_size) |
| filename[bytes_to_copy] = 0; |
| } |
| if (extrafield_size > 0 && extrafield) { |
| bytes_to_copy = (uint16_t)extrafield_size; |
| if (bytes_to_copy > file_info->extrafield_size) |
| bytes_to_copy = file_info->extrafield_size; |
| memcpy(extrafield, file_info->extrafield, bytes_to_copy); |
| } |
| if (comment_size > 0 && comment && file_info->comment) { |
| bytes_to_copy = (uint16_t)comment_size; |
| if (bytes_to_copy > file_info->comment_size) |
| bytes_to_copy = file_info->comment_size; |
| memcpy(comment, file_info->comment, bytes_to_copy); |
| if (bytes_to_copy < comment_size) |
| comment[bytes_to_copy] = 0; |
| } |
| return err; |
| } |
| |
| int unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename, |
| unsigned long filename_size, void *extrafield, unsigned long extrafield_size, char *comment, |
| unsigned long comment_size) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| uint16_t bytes_to_copy = 0; |
| int32_t err = MZ_OK; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| return err; |
| |
| if (pfile_info) { |
| pfile_info->version = file_info->version_madeby; |
| pfile_info->version_needed = file_info->version_needed; |
| pfile_info->flag = file_info->flag; |
| pfile_info->compression_method = file_info->compression_method; |
| pfile_info->mz_dos_date = mz_zip_time_t_to_dos_date(file_info->modified_date); |
| mz_zip_time_t_to_tm(file_info->modified_date, &pfile_info->tmu_date); |
| pfile_info->tmu_date.tm_year += 1900; |
| pfile_info->crc = file_info->crc; |
| |
| pfile_info->size_filename = file_info->filename_size; |
| pfile_info->size_file_extra = file_info->extrafield_size; |
| pfile_info->size_file_comment = file_info->comment_size; |
| |
| pfile_info->disk_num_start = file_info->disk_number; |
| pfile_info->internal_fa = file_info->internal_fa; |
| pfile_info->external_fa = file_info->external_fa; |
| |
| pfile_info->compressed_size = (uint64_t)file_info->compressed_size; |
| pfile_info->uncompressed_size = (uint64_t)file_info->uncompressed_size; |
| } |
| if (filename_size > 0 && filename && file_info->filename) { |
| bytes_to_copy = (uint16_t)filename_size; |
| if (bytes_to_copy > file_info->filename_size) |
| bytes_to_copy = file_info->filename_size; |
| memcpy(filename, file_info->filename, bytes_to_copy); |
| if (bytes_to_copy < filename_size) |
| filename[bytes_to_copy] = 0; |
| } |
| if (extrafield_size > 0 && extrafield) { |
| bytes_to_copy = (uint16_t)extrafield_size; |
| if (bytes_to_copy > file_info->extrafield_size) |
| bytes_to_copy = file_info->extrafield_size; |
| memcpy(extrafield, file_info->extrafield, bytes_to_copy); |
| } |
| if (comment_size > 0 && comment && file_info->comment) { |
| bytes_to_copy = (uint16_t)comment_size; |
| if (bytes_to_copy > file_info->comment_size) |
| bytes_to_copy = file_info->comment_size; |
| memcpy(comment, file_info->comment, bytes_to_copy); |
| if (bytes_to_copy < comment_size) |
| comment[bytes_to_copy] = 0; |
| } |
| return err; |
| } |
| |
| int unzGoToFirstFile(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return UNZ_PARAMERROR; |
| compat->entry_index = 0; |
| return mz_zip_goto_first_entry(compat->handle); |
| } |
| |
| int unzGoToNextFile(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| if (!compat) |
| return UNZ_PARAMERROR; |
| err = mz_zip_goto_next_entry(compat->handle); |
| if (err != MZ_END_OF_LIST) |
| compat->entry_index += 1; |
| return err; |
| } |
| |
| #if !defined(MZ_COMPAT_VERSION) || MZ_COMPAT_VERSION < 110 |
| #ifdef WIN32 |
| # define UNZ_DEFAULT_IGNORE_CASE 1 |
| #else |
| # define UNZ_DEFAULT_IGNORE_CASE 0 |
| #endif |
| |
| int unzLocateFile(unzFile file, const char *filename, unzFileNameCase filename_case) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| uint64_t preserve_index = 0; |
| int32_t err = MZ_OK; |
| int32_t result = 0; |
| uint8_t ignore_case = UNZ_DEFAULT_IGNORE_CASE; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| if (filename_case == 1) { |
| ignore_case = 0; |
| } else if (filename_case > 1) { |
| ignore_case = 1; |
| } |
| |
| preserve_index = compat->entry_index; |
| |
| err = mz_zip_goto_first_entry(compat->handle); |
| while (err == MZ_OK) { |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| break; |
| |
| result = mz_path_compare_wc(filename, file_info->filename, !ignore_case); |
| |
| if (result == 0) |
| return MZ_OK; |
| |
| err = mz_zip_goto_next_entry(compat->handle); |
| } |
| |
| compat->entry_index = preserve_index; |
| return err; |
| } |
| #else |
| int unzLocateFile(unzFile file, const char* filename, unzFileNameComparer filename_compare_func) { |
| mz_compat* compat = (mz_compat*)file; |
| mz_zip_file* file_info = NULL; |
| uint64_t preserve_index = 0; |
| int32_t err = MZ_OK; |
| int32_t result = 0; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| |
| preserve_index = compat->entry_index; |
| |
| err = mz_zip_goto_first_entry(compat->handle); |
| while (err == MZ_OK) { |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| break; |
| |
| if ((intptr_t)filename_compare_func > 2) { |
| result = filename_compare_func(file, filename, file_info->filename); |
| } |
| else { |
| int32_t case_sensitive = (int32_t)(intptr_t)filename_compare_func; |
| result = mz_path_compare_wc(filename, file_info->filename, !case_sensitive); |
| } |
| |
| if (result == 0) |
| return MZ_OK; |
| |
| err = mz_zip_goto_next_entry(compat->handle); |
| } |
| |
| compat->entry_index = preserve_index; |
| return err; |
| } |
| #endif |
| |
| /***************************************************************************/ |
| |
| int unzGetFilePos(unzFile file, unz_file_pos *file_pos) { |
| unz64_file_pos file_pos64; |
| int32_t err = 0; |
| |
| err = unzGetFilePos64(file, &file_pos64); |
| if (err < 0) |
| return err; |
| |
| file_pos->pos_in_zip_directory = (uint32_t)file_pos64.pos_in_zip_directory; |
| file_pos->num_of_file = (uint32_t)file_pos64.num_of_file; |
| return err; |
| } |
| |
| int unzGoToFilePos(unzFile file, unz_file_pos *file_pos) { |
| mz_compat *compat = (mz_compat *)file; |
| unz64_file_pos file_pos64; |
| |
| if (!compat || !file_pos) |
| return UNZ_PARAMERROR; |
| |
| file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; |
| file_pos64.num_of_file = file_pos->num_of_file; |
| |
| return unzGoToFilePos64(file, &file_pos64); |
| } |
| |
| int unzGetFilePos64(unzFile file, unz64_file_pos *file_pos) { |
| mz_compat *compat = (mz_compat *)file; |
| int64_t offset = 0; |
| |
| if (!compat || !file_pos) |
| return UNZ_PARAMERROR; |
| |
| offset = unzGetOffset64(file); |
| if (offset < 0) |
| return (int)offset; |
| |
| file_pos->pos_in_zip_directory = offset; |
| file_pos->num_of_file = compat->entry_index; |
| return UNZ_OK; |
| } |
| |
| int unzGoToFilePos64(unzFile file, const unz64_file_pos *file_pos) { |
| mz_compat *compat = (mz_compat *)file; |
| int32_t err = MZ_OK; |
| |
| if (!compat || !file_pos) |
| return UNZ_PARAMERROR; |
| |
| err = mz_zip_goto_entry(compat->handle, file_pos->pos_in_zip_directory); |
| if (err == MZ_OK) |
| compat->entry_index = file_pos->num_of_file; |
| return err; |
| } |
| |
| unsigned long unzGetOffset(unzFile file) { |
| return (uint32_t)unzGetOffset64(file); |
| } |
| |
| int64_t unzGetOffset64(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return UNZ_PARAMERROR; |
| return mz_zip_get_entry(compat->handle); |
| } |
| |
| int unzSetOffset(unzFile file, unsigned long pos) { |
| return unzSetOffset64(file, pos); |
| } |
| |
| int unzSetOffset64(unzFile file, int64_t pos) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return UNZ_PARAMERROR; |
| return (int)mz_zip_goto_entry(compat->handle, pos); |
| } |
| |
| int unzGetLocalExtrafield(unzFile file, void *buf, unsigned int len) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| int32_t err = MZ_OK; |
| int32_t bytes_to_copy = 0; |
| |
| if (!compat || !buf || len >= INT32_MAX) |
| return UNZ_PARAMERROR; |
| |
| err = mz_zip_entry_get_local_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| return err; |
| |
| bytes_to_copy = (int32_t)len; |
| if (bytes_to_copy > file_info->extrafield_size) |
| bytes_to_copy = file_info->extrafield_size; |
| |
| memcpy(buf, file_info->extrafield, bytes_to_copy); |
| return MZ_OK; |
| } |
| |
| int32_t unzTell(unzFile file) { |
| return unztell(file); |
| } |
| |
| int32_t unztell(unzFile file) { |
| return (int32_t)unztell64(file); |
| } |
| |
| uint64_t unzTell64(unzFile file) { |
| return unztell64(file); |
| } |
| |
| uint64_t unztell64(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return UNZ_PARAMERROR; |
| return compat->total_out; |
| } |
| |
| int unzSeek(unzFile file, int32_t offset, int origin) { |
| return unzSeek64(file, offset, origin); |
| } |
| |
| int unzSeek64(unzFile file, int64_t offset, int origin) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| int64_t position = 0; |
| int32_t err = MZ_OK; |
| void *stream = NULL; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| return err; |
| if (file_info->compression_method != MZ_COMPRESS_METHOD_STORE) |
| return UNZ_ERRNO; |
| |
| if (origin == SEEK_SET) |
| position = offset; |
| else if (origin == SEEK_CUR) |
| position = compat->total_out + offset; |
| else if (origin == SEEK_END) |
| position = (int64_t)file_info->compressed_size + offset; |
| else |
| return UNZ_PARAMERROR; |
| |
| if (position > (int64_t)file_info->compressed_size) |
| return UNZ_PARAMERROR; |
| |
| err = mz_zip_get_stream(compat->handle, &stream); |
| if (err == MZ_OK) |
| err = mz_stream_seek(stream, compat->entry_pos + position, MZ_SEEK_SET); |
| if (err == MZ_OK) |
| compat->total_out = position; |
| return err; |
| } |
| |
| int unzEndOfFile(unzFile file) { |
| return unzeof(file); |
| } |
| |
| int unzeof(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| mz_zip_file *file_info = NULL; |
| int32_t err = MZ_OK; |
| |
| if (!compat) |
| return UNZ_PARAMERROR; |
| err = mz_zip_entry_get_info(compat->handle, &file_info); |
| if (err != MZ_OK) |
| return err; |
| if (compat->total_out == (int64_t)file_info->uncompressed_size) |
| return 1; |
| return 0; |
| } |
| |
| void* unzGetStream(unzFile file) { |
| mz_compat *compat = (mz_compat *)file; |
| if (!compat) |
| return NULL; |
| return (void *)compat->stream; |
| } |
| |
| /***************************************************************************/ |