mirror of
https://github.com/zlib-ng/minizip-ng
synced 2025-03-28 21:13:18 +00:00
262 lines
9.0 KiB
C
262 lines
9.0 KiB
C
#include "mz.h"
|
|
#include "mz_strm.h"
|
|
#include "mz_strm_mem.h"
|
|
|
|
#include "ioapi.h"
|
|
|
|
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 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);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|