mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-12-28 03:55:19 +01:00
1304 lines
42 KiB
C
1304 lines
42 KiB
C
/* mz_compat.c -- Backwards compatible interface for older versions
|
|
part of the minizip-ng project
|
|
|
|
Copyright (C) 2010-2021 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 **stream);
|
|
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 != NULL)
|
|
ioapi->handle = ioapi->filefunc64.zopen64_file(ioapi->filefunc64.opaque, path, ioapi_mode);
|
|
else if (ioapi->filefunc.zopen_file != NULL)
|
|
ioapi->handle = ioapi->filefunc.zopen_file(ioapi->filefunc.opaque, path, ioapi_mode);
|
|
|
|
if (ioapi->handle == NULL)
|
|
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 == NULL)
|
|
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 != NULL) {
|
|
zread = ioapi->filefunc64.zread_file;
|
|
opaque = ioapi->filefunc64.opaque;
|
|
} else if (ioapi->filefunc.zread_file != NULL) {
|
|
zread = ioapi->filefunc.zread_file;
|
|
opaque = ioapi->filefunc.opaque;
|
|
} else
|
|
return MZ_PARAM_ERROR;
|
|
|
|
return 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 != NULL) {
|
|
zwrite = ioapi->filefunc64.zwrite_file;
|
|
opaque = ioapi->filefunc64.opaque;
|
|
} else if (ioapi->filefunc.zwrite_file != NULL) {
|
|
zwrite = ioapi->filefunc.zwrite_file;
|
|
opaque = ioapi->filefunc.opaque;
|
|
} else
|
|
return MZ_PARAM_ERROR;
|
|
|
|
written = 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 != NULL)
|
|
return ioapi->filefunc64.ztell64_file(ioapi->filefunc64.opaque, ioapi->handle);
|
|
else if (ioapi->filefunc.ztell_file != NULL)
|
|
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;
|
|
int32_t written = 0;
|
|
void *opaque = NULL;
|
|
|
|
if (mz_stream_ioapi_is_open(stream) != MZ_OK)
|
|
return MZ_OPEN_ERROR;
|
|
|
|
if (ioapi->filefunc64.zseek64_file != NULL) {
|
|
if (ioapi->filefunc64.zseek64_file(ioapi->filefunc64.opaque, ioapi->handle, offset, origin) != 0)
|
|
return MZ_INTERNAL_ERROR;
|
|
} else if (ioapi->filefunc.zseek_file != NULL) {
|
|
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 != NULL) {
|
|
zclose = ioapi->filefunc.zclose_file;
|
|
opaque = ioapi->filefunc.opaque;
|
|
} else if (ioapi->filefunc64.zclose_file != NULL) {
|
|
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 != NULL) {
|
|
zerror = ioapi->filefunc.zerror_file;
|
|
opaque = ioapi->filefunc.opaque;
|
|
} else if (ioapi->filefunc64.zerror_file != NULL) {
|
|
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 **stream) {
|
|
mz_stream_ioapi *ioapi = NULL;
|
|
|
|
ioapi = (mz_stream_ioapi *)MZ_ALLOC(sizeof(mz_stream_ioapi));
|
|
if (ioapi != NULL) {
|
|
memset(ioapi, 0, sizeof(mz_stream_ioapi));
|
|
ioapi->stream.vtbl = &mz_stream_ioapi_vtbl;
|
|
}
|
|
if (stream != NULL)
|
|
*stream = ioapi;
|
|
|
|
return ioapi;
|
|
}
|
|
|
|
static void mz_stream_ioapi_delete(void **stream) {
|
|
mz_stream_ioapi *ioapi = NULL;
|
|
if (stream == NULL)
|
|
return;
|
|
ioapi = (mz_stream_ioapi *)*stream;
|
|
if (ioapi != NULL)
|
|
MZ_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 != NULL)
|
|
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 != NULL)
|
|
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 != NULL)
|
|
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 != NULL)
|
|
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 != NULL)
|
|
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 != NULL) {
|
|
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 != NULL) {
|
|
if (mz_stream_ioapi_create(&stream) == NULL)
|
|
return NULL;
|
|
mz_stream_ioapi_set_filefunc(stream, pzlib_filefunc_def);
|
|
} else if (pzlib_filefunc_def->opaque != NULL) {
|
|
if (mz_stream_create(&stream, (mz_stream_vtbl *)pzlib_filefunc_def->opaque) == NULL)
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (stream == NULL) {
|
|
if (mz_stream_os_create(&stream) == NULL)
|
|
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 == NULL) {
|
|
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 != NULL) {
|
|
if (mz_stream_ioapi_create(&stream) == NULL)
|
|
return NULL;
|
|
mz_stream_ioapi_set_filefunc64(stream, pzlib_filefunc_def);
|
|
} else if (pzlib_filefunc_def->opaque != NULL) {
|
|
if (mz_stream_create(&stream, (mz_stream_vtbl *)pzlib_filefunc_def->opaque) == NULL)
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (stream == NULL) {
|
|
if (mz_stream_os_create(&stream) == NULL)
|
|
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 == NULL) {
|
|
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;
|
|
|
|
mz_zip_create(&handle);
|
|
err = mz_zip_open(handle, stream, mode);
|
|
|
|
if (err != MZ_OK) {
|
|
mz_zip_delete(&handle);
|
|
return NULL;
|
|
}
|
|
|
|
if (globalcomment != NULL)
|
|
mz_zip_get_comment(handle, globalcomment);
|
|
|
|
compat = (mz_compat *)MZ_ALLOC(sizeof(mz_compat));
|
|
if (compat != NULL) {
|
|
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 == NULL)
|
|
return NULL;
|
|
return compat->handle;
|
|
}
|
|
|
|
void* zipGetStream_MZ(zipFile file) {
|
|
mz_compat *compat = (mz_compat *)file;
|
|
if (compat == NULL)
|
|
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 == NULL)
|
|
return ZIP_PARAMERROR;
|
|
|
|
memset(&file_info, 0, sizeof(file_info));
|
|
|
|
if (zipfi != NULL) {
|
|
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 = zipfi->external_fa;
|
|
file_info.internal_fa = zipfi->internal_fa;
|
|
}
|
|
|
|
if (filename == NULL)
|
|
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 != NULL)
|
|
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 != NULL) || (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,
|
|
uint32_t 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 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 == NULL || 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 == NULL)
|
|
return ZIP_PARAMERROR;
|
|
return mz_zip_entry_close_raw(compat->handle, (int64_t)uncompressed_size, crc32);
|
|
}
|
|
|
|
int zipCloseFileInZip(zipFile file) {
|
|
return zipCloseFileInZip64(file);
|
|
}
|
|
|
|
int zipCloseFileInZip64(zipFile file) {
|
|
mz_compat *compat = (mz_compat *)file;
|
|
if (compat == NULL)
|
|
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 != NULL)
|
|
err = zipClose2_MZ(file, global_comment, version_madeby);
|
|
|
|
if (compat->stream != NULL) {
|
|
mz_stream_close(compat->stream);
|
|
mz_stream_delete(&compat->stream);
|
|
}
|
|
|
|
MZ_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 == NULL)
|
|
return ZIP_PARAMERROR;
|
|
if (compat->handle == NULL)
|
|
return err;
|
|
|
|
if (global_comment != NULL)
|
|
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 != NULL) {
|
|
if (mz_stream_ioapi_create(&stream) == NULL)
|
|
return NULL;
|
|
mz_stream_ioapi_set_filefunc(stream, pzlib_filefunc_def);
|
|
} else if (pzlib_filefunc_def->opaque != NULL) {
|
|
if (mz_stream_create(&stream, (mz_stream_vtbl *)pzlib_filefunc_def->opaque) == NULL)
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (stream == NULL) {
|
|
if (mz_stream_os_create(&stream) == NULL)
|
|
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 == NULL) {
|
|
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 != NULL) {
|
|
if (mz_stream_ioapi_create(&stream) == NULL)
|
|
return NULL;
|
|
mz_stream_ioapi_set_filefunc64(stream, pzlib_filefunc_def);
|
|
} else if (pzlib_filefunc_def->opaque != NULL) {
|
|
if (mz_stream_create(&stream, (mz_stream_vtbl *)pzlib_filefunc_def->opaque) == NULL)
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (stream == NULL) {
|
|
if (mz_stream_os_create(&stream) == NULL)
|
|
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 == NULL) {
|
|
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 == NULL)
|
|
return NULL;
|
|
return compat->handle;
|
|
}
|
|
|
|
void* unzGetStream_MZ(unzFile file) {
|
|
mz_compat *compat = (mz_compat *)file;
|
|
if (compat == NULL)
|
|
return NULL;
|
|
return compat->stream;
|
|
}
|
|
|
|
unzFile unzOpen_MZ(void *stream) {
|
|
mz_compat *compat = NULL;
|
|
int32_t err = MZ_OK;
|
|
void *handle = NULL;
|
|
|
|
mz_zip_create(&handle);
|
|
err = mz_zip_open(handle, stream, MZ_OPEN_MODE_READ);
|
|
|
|
if (err != MZ_OK) {
|
|
mz_zip_delete(&handle);
|
|
return NULL;
|
|
}
|
|
|
|
compat = (mz_compat *)MZ_ALLOC(sizeof(mz_compat));
|
|
if (compat != NULL) {
|
|
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 == NULL)
|
|
return UNZ_PARAMERROR;
|
|
|
|
if (compat->handle != NULL)
|
|
err = unzClose_MZ(file);
|
|
|
|
if (compat->stream != NULL) {
|
|
mz_stream_close(compat->stream);
|
|
mz_stream_delete(&compat->stream);
|
|
}
|
|
|
|
MZ_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 == NULL)
|
|
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 == NULL)
|
|
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 == NULL)
|
|
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 == NULL || comment_size == 0)
|
|
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 == NULL)
|
|
return UNZ_PARAMERROR;
|
|
if (method != NULL)
|
|
*method = 0;
|
|
if (level != NULL)
|
|
*level = 0;
|
|
|
|
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 != NULL) {
|
|
*method = file_info->compression_method;
|
|
}
|
|
|
|
if (level != NULL) {
|
|
*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 == NULL || 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 == NULL)
|
|
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 == NULL)
|
|
return UNZ_PARAMERROR;
|
|
|
|
err = mz_zip_entry_get_info(compat->handle, &file_info);
|
|
if (err != MZ_OK)
|
|
return err;
|
|
|
|
if (pfile_info != NULL) {
|
|
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 != NULL && file_info->filename != NULL) {
|
|
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 != NULL) {
|
|
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 != NULL && file_info->comment != NULL) {
|
|
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 == NULL)
|
|
return UNZ_PARAMERROR;
|
|
|
|
err = mz_zip_entry_get_info(compat->handle, &file_info);
|
|
if (err != MZ_OK)
|
|
return err;
|
|
|
|
if (pfile_info != NULL) {
|
|
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 != NULL && file_info->filename != NULL) {
|
|
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 != NULL) {
|
|
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 != NULL && file_info->comment != NULL) {
|
|
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 == NULL)
|
|
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 == NULL)
|
|
return UNZ_PARAMERROR;
|
|
err = mz_zip_goto_next_entry(compat->handle);
|
|
if (err != MZ_END_OF_LIST)
|
|
compat->entry_index += 1;
|
|
return err;
|
|
}
|
|
|
|
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 == NULL)
|
|
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;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
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 == NULL || file_pos == NULL)
|
|
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 == NULL || file_pos == NULL)
|
|
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 == NULL || file_pos == NULL)
|
|
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 == NULL)
|
|
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 == NULL)
|
|
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 == NULL || buf == NULL || 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 == NULL)
|
|
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 == NULL)
|
|
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 == NULL)
|
|
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 == NULL)
|
|
return NULL;
|
|
return (void *)compat->stream;
|
|
}
|
|
|
|
/***************************************************************************/
|