Initial support for other encodings. #330

This commit is contained in:
Nathan Moinvaziri 2018-10-30 13:59:17 -07:00
parent 1e21dc3a9b
commit ea5e45dfe2
9 changed files with 226 additions and 116 deletions

View File

@ -35,7 +35,7 @@ typedef struct minizip_opt_s {
uint8_t append;
int64_t disk_size;
uint8_t zip_cd;
uint8_t legacy_encoding;
int32_t encoding;
uint8_t verbose;
#ifdef HAVE_AES
uint8_t aes;
@ -76,7 +76,7 @@ int32_t minizip_banner(void)
int32_t minizip_help(void)
{
printf("Usage : minizip [-x -d dir|-l|-e] [-o] [-c] [-a] [-j] [-0 to -9] [-b|-m] [-k 512] [-p pwd] [-s] file.zip [files]\n\n" \
printf("Usage : minizip [-x -d dir|-l|-e] [-o] [-c codepage] [-a] [-j] [-0 to -9] [-b|-m] [-k 512] [-p pwd] [-s] file.zip [files]\n\n" \
" -x Extract files\n" \
" -l List files\n" \
" -d Destination directory\n" \
@ -89,7 +89,7 @@ int32_t minizip_help(void)
" -1 Compress faster\n" \
" -9 Compress better\n" \
" -k Disk size in KB\n" \
" -z Zip central directory" \
" -z Zip central directory\n" \
" -p Encryption password\n");
#ifdef HAVE_AES
printf(" -s AES encryption\n" \
@ -410,7 +410,7 @@ int32_t minizip_extract(const char *path, const char *pattern, const char *desti
mz_zip_reader_create(&reader);
mz_zip_reader_set_pattern(reader, pattern, 1);
mz_zip_reader_set_password(reader, password);
mz_zip_reader_set_legacy_encoding(reader, options->legacy_encoding);
mz_zip_reader_set_encoding(reader, options->encoding);
mz_zip_reader_set_entry_cb(reader, options, minizip_extract_entry_cb);
mz_zip_reader_set_progress_cb(reader, options, minizip_extract_progress_cb);
mz_zip_reader_set_overwrite_cb(reader, options, minizip_extract_overwrite_cb);
@ -551,7 +551,7 @@ int main(int argc, const char *argv[])
minizip_help();
return 0;
}
memset(&options, 0, sizeof(options));
options.compress_method = MZ_COMPRESS_METHOD_DEFLATE;
@ -610,8 +610,11 @@ int main(int argc, const char *argv[])
i += 1;
}
#endif
else if ((c == 'c') || (c == 'C'))
options.legacy_encoding = 1;
else if (((c == 'c') || (c == 'C')) && (i + 1 < argc))
{
options.encoding = (int32_t)atoi(argv[i + 1]);
i += 1;
}
else if (((c == 'k') || (c == 'K')) && (i + 1 < argc))
{
options.disk_size = (int64_t)atoi(argv[i + 1]) * 1024;

7
mz.h
View File

@ -128,6 +128,13 @@ extern "C" {
#define MZ_HASH_SHA256_SIZE (32)
#define MZ_HASH_MAX_SIZE (256)
// MZ_ENCODING
#define MZ_ENCODING_CODEPAGE_437 (437)
#define MZ_ENCODING_CODEPAGE_932 (932)
#define MZ_ENCODING_CODEPAGE_936 (936)
#define MZ_ENCODING_CODEPAGE_950 (950)
#define MZ_ENCODING_UTF8 (65001)
// MZ_UTILITY
#define MZ_UNUSED(SYMBOL) ((void)SYMBOL)

View File

@ -80,12 +80,18 @@ int32_t mz_file_get_crc(const char *path, uint32_t *result_crc);
/***************************************************************************/
// Platform specific functions
wchar_t *mz_os_unicode_string_create(const char *string);
wchar_t *mz_os_unicode_string_create(const char *string, int32_t encoding);
// Create unicode string from a utf8 string
void mz_os_unicode_string_delete(wchar_t **string);
// Delete a unicode string that was created
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding);
// Create a utf8 string from a string with another encoding
void mz_os_utf8_string_delete(uint8_t **string);
// Delete a utf8 string that was created
int32_t mz_os_rand(uint8_t *buf, int32_t size);
// Random number generator (not cryptographically secure)

View File

@ -42,16 +42,18 @@ typedef struct DIR_int_s {
/***************************************************************************/
wchar_t *mz_os_unicode_string_create(const char *string)
wchar_t *mz_os_unicode_string_create(const char *string, int32_t encoding)
{
wchar_t *string_wide = NULL;
uint32_t string_wide_size = 0;
string_wide_size = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
string_wide_size = MultiByteToWideChar(encoding, 0, string, -1, NULL, 0);
if (string_wide_size == 0)
return NULL;
string_wide = (wchar_t *)MZ_ALLOC((string_wide_size + 1) * sizeof(wchar_t));
memset(string_wide, 0, sizeof(wchar_t) * (string_wide_size + 1));
MultiByteToWideChar(CP_UTF8, 0, string, -1, string_wide, string_wide_size);
MultiByteToWideChar(encoding, 0, string, -1, string_wide, string_wide_size);
return string_wide;
}
@ -65,6 +67,39 @@ void mz_os_unicode_string_delete(wchar_t **string)
}
}
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding)
{
wchar_t *string_wide = NULL;
uint8_t *string_utf8 = NULL;
uint32_t string_utf8_size = 0;
string_wide = mz_os_unicode_string_create(string, encoding);
if (string_wide)
{
string_utf8_size = WideCharToMultiByte(CP_UTF8, 0, string_wide, -1, NULL, 0, NULL, NULL);
string_utf8 = (uint8_t *)MZ_ALLOC((string_utf8_size + 1) * sizeof(wchar_t));
if (string_utf8)
{
memset(string_utf8, 0, string_utf8_size + 1);
WideCharToMultiByte(CP_UTF8, 0, string_wide, -1, string_utf8, string_utf8_size, NULL, NULL);
}
mz_os_unicode_string_delete(&string_wide);
}
return string_utf8;
}
void mz_os_utf8_string_delete(uint8_t **string)
{
if (string != NULL)
{
MZ_FREE(*string);
*string = NULL;
}
}
/***************************************************************************/
int32_t mz_os_rand(uint8_t *buf, int32_t size)
@ -87,18 +122,36 @@ int32_t mz_os_rename(const char *source_path, const char *target_path)
wchar_t *source_path_wide = NULL;
wchar_t *target_path_wide = NULL;
int32_t result = 0;
int32_t err = MZ_OK;
if (source_path == NULL || target_path == NULL)
return MZ_PARAM_ERROR;
source_path_wide = mz_os_unicode_string_create(source_path);
target_path_wide = mz_os_unicode_string_create(target_path);
result = MoveFileW(source_path_wide, target_path_wide);
mz_os_unicode_string_delete(&source_path_wide);
mz_os_unicode_string_delete(&target_path_wide);
source_path_wide = mz_os_unicode_string_create(source_path, MZ_ENCODING_UTF8);
if (source_path_wide == NULL)
{
err = MZ_PARAM_ERROR;
}
else
{
target_path_wide = mz_os_unicode_string_create(target_path, MZ_ENCODING_UTF8);
if (target_path_wide == NULL)
err = MZ_PARAM_ERROR;
}
if (result == 0)
return MZ_EXIST_ERROR;
if (err == MZ_OK)
{
result = MoveFileW(source_path_wide, target_path_wide);
if (result == 0)
err = MZ_EXIST_ERROR;
}
return MZ_OK;
if (target_path_wide)
mz_os_unicode_string_delete(&target_path_wide);
if (source_path_wide)
mz_os_unicode_string_delete(&source_path_wide);
return err;
}
int32_t mz_os_delete(const char *path)
@ -106,8 +159,12 @@ int32_t mz_os_delete(const char *path)
wchar_t *path_wide = NULL;
int32_t result = 0;
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path);
result = DeleteFileW(path_wide);
mz_os_unicode_string_delete(&path_wide);
@ -122,8 +179,12 @@ int32_t mz_os_file_exists(const char *path)
wchar_t *path_wide = NULL;
DWORD attribs = 0;
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path);
attribs = GetFileAttributesW(path_wide);
mz_os_unicode_string_delete(&path_wide);
@ -139,8 +200,11 @@ int64_t mz_os_get_file_size(const char *path)
LARGE_INTEGER large_size;
wchar_t *path_wide = NULL;
path_wide = mz_os_unicode_string_create(path);
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
#ifdef MZ_WINRT_API
handle = CreateFile2W(path_wide, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
#else
@ -182,7 +246,12 @@ int32_t mz_os_get_file_date(const char *path, time_t *modified_date, time_t *acc
wchar_t *path_wide = NULL;
int32_t err = MZ_INTERNAL_ERROR;
path_wide = mz_os_unicode_string_create(path);
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
handle = FindFirstFileW(path_wide, &ff32);
MZ_FREE(path_wide);
@ -209,8 +278,12 @@ int32_t mz_os_set_file_date(const char *path, time_t modified_date, time_t acces
wchar_t *path_wide = NULL;
int32_t err = MZ_OK;
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path);
#ifdef MZ_WINRT_API
handle = CreateFile2W(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
#else
@ -243,9 +316,14 @@ int32_t mz_os_get_file_attribs(const char *path, uint32_t *attributes)
wchar_t *path_wide = NULL;
int32_t err = MZ_OK;
path_wide = mz_os_unicode_string_create(path);
if (path == NULL || attributes == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
*attributes = GetFileAttributesW(path_wide);
MZ_FREE(path_wide);
mz_os_unicode_string_delete(&path_wide);
if (*attributes == INVALID_FILE_ATTRIBUTES)
err = MZ_INTERNAL_ERROR;
@ -258,10 +336,15 @@ int32_t mz_os_set_file_attribs(const char *path, uint32_t attributes)
wchar_t *path_wide = NULL;
int32_t err = MZ_OK;
path_wide = mz_os_unicode_string_create(path);
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
if (SetFileAttributesW(path_wide, attributes) == 0)
err = MZ_INTERNAL_ERROR;
MZ_FREE(path_wide);
mz_os_unicode_string_delete(&path_wide);
return err;
}
@ -271,8 +354,12 @@ int32_t mz_os_make_dir(const char *path)
wchar_t *path_wide = NULL;
int32_t err = 0;
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path);
err = _wmkdir(path_wide);
mz_os_unicode_string_delete(&path_wide);
@ -291,11 +378,17 @@ DIR *mz_os_open_dir(const char *path)
void *handle = NULL;
if (path == NULL)
return NULL;
fixed_path[0] = 0;
mz_path_combine(fixed_path, path, sizeof(fixed_path));
mz_path_combine(fixed_path, "*", sizeof(fixed_path));
path_wide = mz_os_unicode_string_create(fixed_path);
path_wide = mz_os_unicode_string_create(fixed_path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return NULL;
handle = FindFirstFileW(path_wide, &find_data);
mz_os_unicode_string_delete(&path_wide);
@ -355,7 +448,12 @@ int32_t mz_os_is_dir(const char *path)
wchar_t *path_wide = NULL;
uint32_t attribs = 0;
path_wide = mz_os_unicode_string_create(path);
if (path == NULL)
return MZ_PARAM_ERROR;
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
attribs = GetFileAttributesW(path_wide);
mz_os_unicode_string_delete(&path_wide);

View File

@ -18,6 +18,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <iconv.h>
#include "mz.h"
#include "mz_strm.h"
@ -76,6 +77,66 @@ typedef struct mz_stream_posix_s
/***************************************************************************/
uint8_t *mz_os_utf8_string_create(const char *string, int32_t encoding)
{
iconv_t cd;
const char *from_encoding = NULL;
int32_t result = 0;
int32_t string_length = 0;
int32_t string_utf8_size = 0;
uint8_t string_utf8 = NULL;
if (string == NULL)
return NULL;
if (encoding == MZ_ENCODING_CODEPAGE_437)
from_encoding = "CP437";
else if (encoding == MZ_ENCODING_CODEPAGE_932)
from_encoding = "CP932";
else if (encoding == MZ_ENCODING_CODEPAGE_936)
from_encoding = "CP936";
else if (encoding == MZ_ENCODING_CODEPAGE_950)
from_encoding = "CP950";
else if (encoding == MZ_ENCODING_UTF8)
from_encoding = "UTF-8"
else
return NULL;
cd = iconv_open("UTF-8", from_encoding);
if (cd == (iconv_t)-1)
return NULL;
string_length = (int32_t)strlen(string);
string_utf8_size = string_length * 2;
string_utf8 = (uint8_t *)MZ_ALLOC(string_utf8_size + 1);
if (string_utf8)
{
memset(string_utf8, 0, string_utf8_size + 1);
result = iconv(cd, string, &string_length, string_utf8, &string_utf8_size);
iconv_close(cd);
}
if (result == -1)
{
MZ_FREE(string_utf8);
string_utf8 = NULL;
}
return string_utf8;
}
void mz_os_utf8_string_delete(uint8_t **string)
{
if (string != NULL)
{
MZ_FREE(*string);
*string = NULL;
}
}
/***************************************************************************/
int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode)
{
mz_stream_posix *posix = (mz_stream_posix *)stream;

View File

@ -98,10 +98,12 @@ int32_t mz_stream_os_open(void *stream, const char *path, int32_t mode)
}
else
{
return MZ_OPEN_ERROR;
return MZ_PARAM_ERROR;
}
path_wide = mz_os_unicode_string_create(path);
path_wide = mz_os_unicode_string_create(path, MZ_ENCODING_UTF8);
if (path_wide == NULL)
return MZ_PARAM_ERROR;
#ifdef MZ_WINRT_API
win32->handle = CreateFile2W(path_wide, desired_access, share_mode,

View File

@ -2245,75 +2245,4 @@ int32_t mz_zip_path_compare(const char *path1, const char *path2, uint8_t ignore
return (int32_t)(*path1 - *path2);
}
static uint32_t mz_zip_encoding_codepage437_to_utf8[256] = {
0x000000, 0xba98e2, 0xbb98e2, 0xa599e2, 0xa699e2, 0xa399e2, 0xa099e2, 0xa280e2,
0x9897e2, 0x8b97e2, 0x9997e2, 0x8299e2, 0x8099e2, 0xaa99e2, 0xab99e2, 0xbc98e2,
0xba96e2, 0x8497e2, 0x9586e2, 0xbc80e2, 0x00b6c2, 0x00a7c2, 0xac96e2, 0xa886e2,
0x9186e2, 0x9386e2, 0x9286e2, 0x9086e2, 0x9f88e2, 0x9486e2, 0xb296e2, 0xbc96e2,
0x000020, 0x000021, 0x000022, 0x000023, 0x000024, 0x000025, 0x000026, 0x000027,
0x000028, 0x000029, 0x00002a, 0x00002b, 0x00002c, 0x00002d, 0x00002e, 0x00002f,
0x000030, 0x000031, 0x000032, 0x000033, 0x000034, 0x000035, 0x000036, 0x000037,
0x000038, 0x000039, 0x00003a, 0x00003b, 0x00003c, 0x00003d, 0x00003e, 0x00003f,
0x000040, 0x000041, 0x000042, 0x000043, 0x000044, 0x000045, 0x000046, 0x000047,
0x000048, 0x000049, 0x00004a, 0x00004b, 0x00004c, 0x00004d, 0x00004e, 0x00004f,
0x000050, 0x000051, 0x000052, 0x000053, 0x000054, 0x000055, 0x000056, 0x000057,
0x000058, 0x000059, 0x00005a, 0x00005b, 0x00005c, 0x00005d, 0x00005e, 0x00005f,
0x000060, 0x000061, 0x000062, 0x000063, 0x000064, 0x000065, 0x000066, 0x000067,
0x000068, 0x000069, 0x00006a, 0x00006b, 0x00006c, 0x00006d, 0x00006e, 0x00006f,
0x000070, 0x000071, 0x000072, 0x000073, 0x000074, 0x000075, 0x000076, 0x000077,
0x000078, 0x000079, 0x00007a, 0x00007b, 0x00007c, 0x00007d, 0x00007e, 0x828ce2,
0x0087c3, 0x00bcc3, 0x00a9c3, 0x00a2c3, 0x00a4c3, 0x00a0c3, 0x00a5c3, 0x00a7c3,
0x00aac3, 0x00abc3, 0x00a8c3, 0x00afc3, 0x00aec3, 0x00acc3, 0x0084c3, 0x0085c3,
0x0089c3, 0x00a6c3, 0x0086c3, 0x00b4c3, 0x00b6c3, 0x00b2c3, 0x00bbc3, 0x00b9c3,
0x00bfc3, 0x0096c3, 0x009cc3, 0x00a2c2, 0x00a3c2, 0x00a5c2, 0xa782e2, 0x0092c6,
0x00a1c3, 0x00adc3, 0x00b3c3, 0x00bac3, 0x00b1c3, 0x0091c3, 0x00aac2, 0x00bac2,
0x00bfc2, 0x908ce2, 0x00acc2, 0x00bdc2, 0x00bcc2, 0x00a1c2, 0x00abc2, 0x00bbc2,
0x9196e2, 0x9296e2, 0x9396e2, 0x8294e2, 0xa494e2, 0xa195e2, 0xa295e2, 0x9695e2,
0x9595e2, 0xa395e2, 0x9195e2, 0x9795e2, 0x9d95e2, 0x9c95e2, 0x9b95e2, 0x9094e2,
0x9494e2, 0xb494e2, 0xac94e2, 0x9c94e2, 0x8094e2, 0xbc94e2, 0x9e95e2, 0x9f95e2,
0x9a95e2, 0x9495e2, 0xa995e2, 0xa695e2, 0xa095e2, 0x9095e2, 0xac95e2, 0xa795e2,
0xa895e2, 0xa495e2, 0xa595e2, 0x9995e2, 0x9895e2, 0x9295e2, 0x9395e2, 0xab95e2,
0xaa95e2, 0x9894e2, 0x8c94e2, 0x8896e2, 0x8496e2, 0x8c96e2, 0x9096e2, 0x8096e2,
0x00b1ce, 0x009fc3, 0x0093ce, 0x0080cf, 0x00a3ce, 0x0083cf, 0x00b5c2, 0x0084cf,
0x00a6ce, 0x0098ce, 0x00a9ce, 0x00b4ce, 0x9e88e2, 0x0086cf, 0x00b5ce, 0xa988e2,
0xa189e2, 0x00b1c2, 0xa589e2, 0xa489e2, 0xa08ce2, 0xa18ce2, 0x00b7c3, 0x8889e2,
0x00b0c2, 0x9988e2, 0x00b7c2, 0x9a88e2, 0xbf81e2, 0x00b2c2, 0xa096e2, 0x00a0c2
};
int32_t mz_zip_encoding_cp437_to_utf8(const char *source, char *target, int32_t max_target)
{
uint32_t utf8_char = 0;
uint8_t utf8_byte = 0;
uint8_t cp437_char = 0;
int32_t x = 0;
int32_t written = 0;
// Convert ibm codepage 437 encoding to utf-8
while (*source != 0)
{
cp437_char = (uint8_t)*source;
source += 1;
utf8_char = mz_zip_encoding_codepage437_to_utf8[cp437_char];
for (x = 0; x < 32; x += 8)
{
utf8_byte = (uint8_t)(utf8_char >> x);
if (x > 0 && utf8_byte == 0)
continue;
if (max_target <= 1)
break;
target[written] = (char)utf8_byte;
written += 1;
max_target -= 1;
}
}
if (max_target > 0)
{
target[written] = 0;
written += 1;
}
return written;
}
/***************************************************************************/

View File

@ -64,7 +64,7 @@ typedef struct mz_zip_reader_s {
entry_cb;
uint8_t raw;
uint8_t buffer[UINT16_MAX];
uint8_t legacy_encoding;
int32_t encoding;
uint8_t sign_required;
} mz_zip_reader;
@ -852,6 +852,7 @@ int32_t mz_zip_reader_save_all(void *handle, const char *destination_dir)
{
mz_zip_reader *reader = (mz_zip_reader *)handle;
int32_t err = MZ_OK;
uint8_t *utf8_string = NULL;
char path[512];
char utf8_name[256];
char resolved_name[256];
@ -863,14 +864,17 @@ int32_t mz_zip_reader_save_all(void *handle, const char *destination_dir)
// Construct output path
path[0] = 0;
if ((reader->legacy_encoding) && (reader->file_info->flag & MZ_ZIP_FLAG_UTF8) == 0)
strncpy(utf8_name, reader->file_info->filename, sizeof(utf8_name) - 1);
utf8_name[sizeof(utf8_name) - 1] = 0;
if ((reader->encoding > 0) && (reader->file_info->flag & MZ_ZIP_FLAG_UTF8) == 0)
{
mz_zip_encoding_cp437_to_utf8(reader->file_info->filename, utf8_name, sizeof(utf8_name));
}
else
{
strncpy(utf8_name, reader->file_info->filename, sizeof(utf8_name) - 1);
utf8_name[sizeof(utf8_name) - 1] = 0;
utf8_string = mz_os_utf8_string_create(reader->file_info->filename, reader->encoding);
if (utf8_string)
{
strncpy(utf8_name, utf8_string, sizeof(utf8_name));
mz_os_utf8_string_delete(&utf8_string);
}
}
err = mz_path_resolve(utf8_name, resolved_name, sizeof(resolved_name));
@ -925,10 +929,10 @@ int32_t mz_zip_reader_get_raw(void *handle, uint8_t *raw)
return MZ_OK;
}
void mz_zip_reader_set_legacy_encoding(void *handle, uint8_t legacy_encoding)
void mz_zip_reader_set_encoding(void *handle, int32_t encoding)
{
mz_zip_reader *reader = (mz_zip_reader *)handle;
reader->legacy_encoding = legacy_encoding;
reader->encoding = encoding;
}
void mz_zip_reader_set_sign_required(void *handle, uint8_t sign_required)

View File

@ -124,7 +124,7 @@ void mz_zip_reader_set_raw(void *handle, uint8_t raw);
int32_t mz_zip_reader_get_raw(void *handle, uint8_t *raw);
// Gets whether or not it should save the entry raw
void mz_zip_reader_set_legacy_encoding(void *handle, uint8_t legacy_encoding);
void mz_zip_reader_set_encoding(void *handle, int32_t encoding);
// Sets whether or not it should support cp437 in zip file names
void mz_zip_reader_set_sign_required(void *handle, uint8_t sign_required);