Added zip reader/writer class to encapsulate a lot of functionality.

Added create/delete functions for zip class.
Simplify locating an entry by filename.
Added more advanced functions for locating an entry based on callback decision.
Change default mem grow size to 64kb since we have unzOpen_MZ and zipOpen_MZ. #283
This commit is contained in:
Nathan Moinvaziri 2018-08-13 23:07:42 -07:00
parent 77687f3a42
commit 9a170d4d60
12 changed files with 1917 additions and 625 deletions

View file

@ -59,7 +59,8 @@ set(MINIZIP_SRC
mz_strm_mem.c
mz_strm_posix.c
mz_strm_split.c
mz_zip.c)
mz_zip.c
mz_zip_rw.c)
set(MINIZIP_PUBLIC_HEADERS
mz.h
@ -71,7 +72,8 @@ set(MINIZIP_PUBLIC_HEADERS
mz_strm_mem.h
mz_strm_posix.h
mz_strm_split.h
mz_zip.h)
mz_zip.h
mz_zip_rw.h)
if(COMPRESS_ONLY)
add_definitions(-DMZ_ZIP_NO_DECOMPRESSION)

View file

@ -76,6 +76,7 @@ cmake . -DZLIB_LIBRARY=lib\zlib\release\zlibstatic.lib -DZLIB_INCLUDE_DIR=lib\zl
| mz_strm_win32.\* | File stream using Win32 API functions | Windows systems |
| mz_strm_zlib.\* | Deflate stream using zlib | zlib or liblzma |
| mz_zip.\* | Zip functionality | Yes |
| mz_zip_rw.\* | Zip reader/writer | No |
## Features

779
minizip.c
View file

@ -29,6 +29,7 @@
#include "mz_strm_buf.h"
#include "mz_strm_split.h"
#include "mz_zip.h"
#include "mz_zip_rw.h"
/***************************************************************************/
@ -46,7 +47,6 @@ void minizip_help(void)
" -d Destination directory\n" \
" -o Overwrite existing files\n" \
" -a Append to existing zip file\n" \
" -u Buffered reading and writing\n" \
" -i Include full path of files\n" \
" -0 Store only\n" \
" -1 Compress faster\n" \
@ -68,198 +68,20 @@ void minizip_help(void)
/***************************************************************************/
typedef struct minizip_opt_s {
int16_t include_path;
uint8_t include_path;
int16_t compress_level;
int16_t compress_method;
int16_t overwrite;
uint8_t compress_method;
uint8_t overwrite;
uint8_t append;
int64_t disk_size;
#ifdef HAVE_AES
int16_t aes;
uint8_t aes;
#endif
} minizip_opt;
/***************************************************************************/
int32_t minizip_add_path(void *handle, const char *path, const char *filenameinzip, const char *password, int16_t is_dir, minizip_opt *options)
{
mz_zip_file file_info;
int32_t read = 0;
int32_t written = 0;
int32_t err = MZ_OK;
int32_t err_close = MZ_OK;
void *stream = NULL;
char buf[INT16_MAX];
memset(&file_info, 0, sizeof(file_info));
// The path name saved, should not include a leading slash.
// If it did, windows/xp and dynazip couldn't read the zip file.
if (filenameinzip == NULL)
filenameinzip = path;
while (filenameinzip[0] == '\\' || filenameinzip[0] == '/')
filenameinzip += 1;
// Get information about the file on disk so we can store it in zip
file_info.version_madeby = MZ_VERSION_MADEBY;
file_info.compression_method = options->compress_method;
file_info.filename = filenameinzip;
file_info.uncompressed_size = mz_os_get_file_size(path);
#ifdef HAVE_AES
if (options->aes)
file_info.aes_version = MZ_AES_VERSION;
#endif
mz_os_get_file_date(path, &file_info.modified_date, &file_info.accessed_date,
&file_info.creation_date);
mz_os_get_file_attribs(path, &file_info.external_fa);
printf("Adding: %s\n", file_info.filename);
// Add to zip
err = mz_zip_entry_write_open(handle, &file_info, options->compress_level, 0, password);
if (err != MZ_OK)
{
printf("Error in opening %s in zip file (%d)\n", filenameinzip, err);
return err;
}
if (!is_dir)
{
mz_stream_os_create(&stream);
err = mz_stream_os_open(stream, path, MZ_OPEN_MODE_READ);
if (err == MZ_OK)
{
// Read contents of file and write it to zip
do
{
read = mz_stream_os_read(stream, buf, sizeof(buf));
if (read < 0)
{
err = mz_stream_os_error(stream);
printf("Error %d in reading %s\n", err, filenameinzip);
break;
}
if (read == 0)
break;
written = mz_zip_entry_write(handle, buf, read);
if (written != read)
{
err = mz_stream_os_error(stream);
printf("Error in writing %s in the zip file (%d)\n", filenameinzip, err);
break;
}
} while (err == MZ_OK);
mz_stream_os_close(stream);
}
else
{
printf("Error in opening %s for reading\n", path);
}
mz_stream_os_delete(&stream);
}
err_close = mz_zip_entry_close(handle);
if (err_close != MZ_OK)
{
printf("Error in closing %s in the zip file (%d)\n", filenameinzip, err_close);
err = err_close;
}
return err;
}
int32_t minizip_add(void *handle, const char *path, const char *root_path, const char *password, minizip_opt *options, uint8_t recursive)
{
DIR *dir = NULL;
struct dirent *entry = NULL;
int32_t err = MZ_OK;
int16_t is_dir = 0;
const char *filename = NULL;
const char *filenameinzip = path;
char *wildcard_ptr = NULL;
char full_path[320];
char path_dir[320];
if (mz_os_is_dir(path) == MZ_OK)
is_dir = 1;
if (strrchr(path, '*') != NULL)
{
strncpy(path_dir, path, sizeof(path_dir));
mz_path_remove_filename(path_dir);
wildcard_ptr = path_dir + strlen(path_dir) + 1;
root_path = path = path_dir;
}
else
{
// Construct the filename that our file will be stored in the zip as
if (root_path == NULL)
root_path = path;
// Should the file be stored with any path info at all?
if (!options->include_path)
{
if (!is_dir && root_path == path)
{
if (mz_path_get_filename(filenameinzip, &filename) == MZ_OK)
filenameinzip = filename;
}
else
{
filenameinzip += strlen(root_path);
}
}
if (*filenameinzip != 0)
err = minizip_add_path(handle, path, filenameinzip, password, is_dir, options);
if (!is_dir)
return err;
}
dir = mz_os_open_dir(path);
if (dir == NULL)
{
printf("Cannot enumerate directory %s\n", path);
return MZ_EXIST_ERROR;
}
while ((entry = mz_os_read_dir(dir)) != NULL)
{
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
full_path[0] = 0;
mz_path_combine(full_path, path, sizeof(full_path));
mz_path_combine(full_path, entry->d_name, sizeof(full_path));
if (!recursive && mz_os_is_dir(full_path))
continue;
if ((wildcard_ptr != NULL) && (mz_path_compare_wc(entry->d_name, wildcard_ptr, 1) != MZ_OK))
continue;
err = minizip_add(handle, full_path, root_path, password, options, recursive);
if (err != MZ_OK)
return err;
}
mz_os_close_dir(dir);
return MZ_OK;
}
/***************************************************************************/
int32_t minizip_list(void *handle)
int32_t minizip_list(const char *path)
{
mz_zip_file *file_info = NULL;
uint32_t ratio = 0;
@ -269,21 +91,34 @@ int32_t minizip_list(void *handle)
const char *string_method = NULL;
char crypt = ' ';
void *reader = NULL;
err = mz_zip_goto_first_entry(handle);
mz_zip_reader_create(&reader);
err = mz_zip_reader_open_file(reader, path);
if (err != MZ_OK)
{
printf("Error %d opening zip file %s\n", err, path);
mz_zip_reader_delete(&reader);
return err;
}
err = mz_zip_reader_goto_first(reader);
if (err != MZ_OK && err != MZ_END_OF_LIST)
{
printf("Error %d going to first entry in zip file\n", err);
mz_zip_reader_delete(&reader);
return err;
}
printf(" Length Method Size Attribs Ratio Date Time CRC-32 Name\n");
printf(" ------ ------ ---- ------- ----- ---- ---- ------ ----\n");
while (err == MZ_OK)
do
{
err = mz_zip_entry_get_info(handle, &file_info);
err = mz_zip_reader_get_info(reader, &file_info);
if (err != MZ_OK)
{
@ -336,14 +171,18 @@ int32_t minizip_list(void *handle)
(uint32_t)tmu_date.tm_hour, (uint32_t)tmu_date.tm_min,
file_info->crc, file_info->filename);
err = mz_zip_goto_next_entry(handle);
err = mz_zip_reader_goto_next(reader);
if (err != MZ_OK && err != MZ_END_OF_LIST)
{
printf("Error %d going to next entry in zip file\n", err);
mz_zip_reader_delete(&reader);
return err;
}
}
while (err == MZ_OK);
mz_zip_reader_delete(&reader);
if (err == MZ_END_OF_LIST)
return MZ_OK;
@ -353,262 +192,243 @@ int32_t minizip_list(void *handle)
/***************************************************************************/
int32_t minizip_extract_currentfile(void *handle, const char *destination, const char *password, minizip_opt *options)
int32_t minizip_add_entry_cb(void *handle, void *userdata, mz_zip_file *file_info)
{
mz_zip_file *file_info = NULL;
uint8_t buf[INT16_MAX];
int32_t read = 0;
int32_t written = 0;
int32_t err = MZ_OK;
int32_t err_close = MZ_OK;
void *stream = NULL;
const char *filename = NULL;
char out_name[512];
char out_path[512];
char directory[512];
printf("Adding %s\n", file_info->filename);
return MZ_OK;
}
int32_t minizip_add_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, uint64_t position)
{
double progress = 0;
uint8_t raw = 0;
err = mz_zip_entry_get_info(handle, &file_info);
mz_zip_writer_get_raw(handle, &raw);
if (err != MZ_OK)
{
printf("Error %d getting entry info in zip file\n", err);
return err;
}
if (mz_path_get_filename(file_info->filename, &filename) != MZ_OK)
filename = file_info->filename;
// Construct output path
out_path[0] = 0;
if ((*file_info->filename == '/') || (file_info->filename[1] == ':'))
{
strncpy(out_path, file_info->filename, sizeof(out_path));
}
else
{
if (destination != NULL)
mz_path_combine(out_path, destination, sizeof(out_path));
err = mz_path_resolve(file_info->filename, out_name, sizeof(out_name));
if (err != MZ_OK)
{
printf("Error %d resolving output path\n", err);
return err;
}
mz_path_combine(out_path, out_name, sizeof(out_path));
}
// If zip entry is a directory then create it on disk
if (mz_zip_attrib_is_dir(file_info->external_fa, file_info->version_madeby) == MZ_OK)
{
printf("Creating directory: %s\n", out_path);
mz_make_dir(out_path);
return err;
}
err = mz_zip_entry_read_open(handle, 0, password);
if (err != MZ_OK)
{
printf("Error %d opening entry in zip file\n", err);
return err;
}
// Determine if the file should be overwritten or not and ask the user if needed
if ((err == MZ_OK) && (options->overwrite == 0) && (mz_os_file_exists(out_path) == MZ_OK))
if (raw && file_info->compressed_size > 0)
progress = ((double)position / file_info->compressed_size) * 100;
else if (!raw && file_info->uncompressed_size > 0)
progress = ((double)position / file_info->uncompressed_size) * 100;
printf("%s - %lld / %lld (%.02f%%)\n", file_info->filename, position, file_info->uncompressed_size, progress);
return MZ_OK;
}
int32_t minizip_add_overwrite_cb(void *handle, void *userdata, const char *path)
{
minizip_opt *options = (minizip_opt *)userdata;
if (options->overwrite == 0)
{
// If ask the user what to do because append and overwrite args not set
char rep = 0;
do
{
char answer[128];
printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", out_path);
printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ", path);
if (scanf("%1s", answer) != 1)
exit(EXIT_FAILURE);
rep = answer[0];
if ((rep >= 'a') && (rep <= 'z'))
rep -= 0x20;
}
while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
if (rep == 'N')
return err;
if (rep == 'A')
options->overwrite = 1;
}
mz_stream_os_create(&stream);
// Create the file on disk so we can unzip to it
if (err == MZ_OK)
{
// Some zips don't contain directory alone before file
err = mz_stream_os_open(stream, out_path, MZ_OPEN_MODE_CREATE);
if ((err != MZ_OK) && (filename != file_info->filename))
{
// Create the directory of the output path
strncpy(directory, out_path, sizeof(directory));
mz_path_remove_filename(directory);
mz_make_dir(directory);
err = mz_stream_os_open(stream, out_path, MZ_OPEN_MODE_CREATE);
return MZ_EXIST_ERROR;
}
else if (rep == 'N')
{
return MZ_INTERNAL_ERROR;
}
}
// Read from the zip, unzip to buffer, and write to disk
return MZ_OK;
}
int32_t minizip_add(const char *path, const char *password, minizip_opt *options, int32_t arg_count, const char **args)
{
void *writer = NULL;
int32_t err = MZ_OK;
int32_t err_close = MZ_OK;
int32_t i = 0;
const char *filename_in_zip = NULL;
printf("Archive %s\n", path);
mz_zip_writer_create(&writer);
mz_zip_writer_set_password(writer, password);
mz_zip_writer_set_compress_method(writer, options->compress_method);
mz_zip_writer_set_compress_level(writer, options->compress_level);
mz_zip_writer_set_overwrite_cb(writer, options, minizip_add_overwrite_cb);
mz_zip_writer_set_progress_cb(writer, options, minizip_add_progress_cb);
err = mz_zip_writer_open_file(writer, path, options->disk_size, options->append);
if (err == MZ_OK)
{
printf(" Extracting: %s\n", out_path);
while (1)
for (i = 0; i < arg_count; i += 1)
{
read = mz_zip_entry_read(handle, buf, sizeof(buf));
if (read < 0)
{
err = read;
printf("Error %d reading entry in zip file\n", err);
break;
}
if (read == 0)
break;
written = mz_stream_os_write(stream, buf, read);
if (written != read)
{
err = mz_stream_os_error(stream);
printf("Error %d in writing extracted file\n", err);
break;
}
filename_in_zip = args[i];
err = mz_zip_writer_add_path(writer, filename_in_zip, NULL, options->include_path, 1);
if (err != MZ_OK)
printf("Error %d adding path to zip %s\n", err, filename_in_zip);
}
mz_stream_os_close(stream);
// Set the time of the file that has been unzipped
if (err == MZ_OK)
mz_os_set_file_date(out_path, file_info->modified_date, file_info->accessed_date,
file_info->creation_date);
}
else
{
printf("Error %d opening %s\n", err, out_path);
printf("Error %d opening zip for writing\n", err);
}
mz_stream_os_delete(&stream);
err_close = mz_zip_entry_close(handle);
err_close = mz_zip_writer_close(writer);
if (err_close != MZ_OK)
{
printf("Error %d closing entry in zip file\n", err_close);
printf("Error %d closing zip for writing %s\n", err_close, path);
err = err_close;
}
mz_zip_writer_delete(&writer);
return err;
}
int32_t minizip_extract_all(void *handle, const char *destination, const char *password, minizip_opt *options)
{
int32_t err = MZ_OK;
err = mz_zip_goto_first_entry(handle);
if (err == MZ_END_OF_LIST)
return MZ_OK;
if (err != MZ_OK)
printf("Error %d going to first entry in zip file\n", err);
while (err == MZ_OK)
{
err = minizip_extract_currentfile(handle, destination, password, options);
if (err != MZ_OK)
break;
err = mz_zip_goto_next_entry(handle);
if (err == MZ_END_OF_LIST)
return MZ_OK;
if (err != MZ_OK)
printf("Error %d going to next entry in zip file\n", err);
}
return err;
}
int32_t minizip_extract_onefile(void *handle, const char *filename, const char *destination, const char *password, minizip_opt *options)
{
int32_t err = mz_zip_locate_entry(handle, filename, NULL);
if (err != MZ_OK)
{
printf("File %s not found in the zip file\n", filename);
return err;
}
return minizip_extract_currentfile(handle, destination, password, options);
}
/***************************************************************************/
int32_t minizip_copy_current_entry(void *src_handle, void *target_handle)
int32_t minizip_extract_entry_cb(void *handle, void *userdata, mz_zip_file *file_info)
{
int32_t err = MZ_OK;
mz_zip_file *file_info = NULL;
int32_t read = 0;
int32_t written = 0;
uint8_t buf[INT16_MAX];
printf("Extracting %s\n", file_info->filename);
return MZ_OK;
}
err = mz_zip_entry_get_info(src_handle, &file_info);
if (err != MZ_OK)
return err;
int32_t minizip_extract_progress_cb(void *handle, void *userdata, mz_zip_file *file_info, uint64_t position)
{
double progress = 0;
uint8_t raw = 0;
mz_zip_reader_get_raw(handle, &raw);
err = mz_zip_entry_read_open(src_handle, 1, NULL);
if (err != MZ_OK)
return err;
if (raw && file_info->compressed_size > 0)
progress = ((double)position / file_info->compressed_size) * 100;
else if (!raw && file_info->uncompressed_size > 0)
progress = ((double)position / file_info->uncompressed_size) * 100;
err = mz_zip_entry_write_open(target_handle, file_info, 0, 1, NULL);
if (err == MZ_OK)
printf("%s - %lld / %lld (%.02f%%)\n", file_info->filename, position, file_info->uncompressed_size, progress);
return MZ_OK;
}
int32_t minizip_extract_overwrite_cb(void *handle, void *userdata, mz_zip_file *file_info, const char *path)
{
minizip_opt *options = (minizip_opt *)userdata;
if (options->overwrite == 0)
{
while (1)
char rep = 0;
do
{
read = mz_zip_entry_read(src_handle, buf, sizeof(buf));
if (read < 0)
{
err = read;
printf("Error %d reading entry in zip file\n", err);
break;
}
if (read == 0)
break;
char answer[128];
printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", path);
if (scanf("%1s", answer) != 1)
exit(EXIT_FAILURE);
rep = answer[0];
if ((rep >= 'a') && (rep <= 'z'))
rep -= 0x20;
} while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
mz_zip_entry_write(target_handle, buf, read);
}
mz_zip_entry_close_raw(target_handle, file_info->uncompressed_size, file_info->crc);
if (rep == 'N')
return MZ_EXIST_ERROR;
if (rep == 'A')
options->overwrite = 1;
}
mz_zip_entry_close(src_handle);
return MZ_OK;
}
int32_t minizip_extract(const char *path, const char *pattern, const char *destination, const char *password, minizip_opt *options)
{
void *reader = NULL;
int32_t err = MZ_OK;
int32_t err_close = MZ_OK;
printf("Archive %s\n", path);
mz_zip_reader_create(&reader);
mz_zip_reader_set_pattern(reader, pattern, 1);
mz_zip_reader_set_password(reader, password);
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);
err = mz_zip_reader_open_file(reader, path);
if (err != MZ_OK)
{
printf("Error %d opening zip file %s\n", err, path);
}
else
{
err = mz_zip_reader_save_all(reader, destination);
if (err == MZ_END_OF_LIST && pattern != NULL)
printf("Files matching %s not found in zip file\n", pattern);
if (err != MZ_OK)
printf("Error %d saving zip entries to disk %s\n", err, path);
}
err_close = mz_zip_reader_close(reader);
if (err_close != MZ_OK)
{
printf("Error %d closing zip for reading\n", err_close);
err = err_close;
}
mz_zip_reader_delete(&reader);
return err;
}
int32_t minizip_copy_specific_entries(void *src_handle, void *target_handle, int32_t arg_count, const char **args)
/***************************************************************************/
int32_t minizip_erase(const char *src_path, const char *target_path, int32_t arg_count, const char **args)
{
mz_zip_file *file_info = NULL;
const char *filename_in_zip = NULL;
void *reader = NULL;
void *writer = NULL;
int32_t err = MZ_OK;
int32_t i = 0;
err = mz_zip_goto_first_entry(src_handle);
mz_zip_reader_create(&reader);
mz_zip_writer_create(&writer);
if (err == MZ_END_OF_LIST)
return MZ_OK;
err = mz_zip_reader_open_file(reader, src_path);
if (err != MZ_OK)
{
printf("Error %d opening zip for reading %s\n", err, src_path);
mz_zip_reader_delete(&reader);
return err;
}
err = mz_zip_writer_open_file(writer, target_path, 0, 0);
if (err != MZ_OK)
{
printf("Error %d opening zip for writing %s\n", err, target_path);
mz_zip_reader_delete(&reader);
mz_zip_writer_delete(&writer);
return err;
}
err = mz_zip_reader_goto_first(reader);
if (err != MZ_OK && err != MZ_END_OF_LIST)
printf("Error %d going to first entry in zip file\n", err);
while (err == MZ_OK)
{
err = mz_zip_entry_get_info(src_handle, &file_info);
err = mz_zip_reader_get_info(reader, &file_info);
if (err != MZ_OK)
{
printf("Error %d getting entry info in zip file\n", err);
printf("Error %d getting info from zip\n", err);
break;
}
@ -619,7 +439,7 @@ int32_t minizip_copy_specific_entries(void *src_handle, void *target_handle, int
if (mz_path_compare_wc(file_info->filename, filename_in_zip, 1) != MZ_OK)
{
printf("Copying %s\n", file_info->filename);
err = minizip_copy_current_entry(src_handle, target_handle);
err = mz_zip_writer_copy_from_reader(writer, reader);
}
else
{
@ -628,16 +448,26 @@ int32_t minizip_copy_specific_entries(void *src_handle, void *target_handle, int
}
if (err != MZ_OK)
{
printf("Error %d copying entry into new zip\n", err);
break;
}
err = mz_zip_goto_next_entry(src_handle);
err = mz_zip_reader_goto_next(reader);
if (err == MZ_END_OF_LIST)
return MZ_OK;
if (err != MZ_OK)
if (err != MZ_OK && err != MZ_END_OF_LIST)
printf("Error %d going to next entry in zip file\n", err);
}
mz_zip_reader_close(reader);
mz_zip_reader_delete(&reader);
mz_zip_writer_close(writer);
mz_zip_writer_delete(&writer);
if (err == MZ_END_OF_LIST)
return MZ_OK;
return err;
}
@ -664,8 +494,6 @@ int main(int argc, const char *argv[])
uint8_t do_list = 0;
uint8_t do_extract = 0;
uint8_t do_erase = 0;
uint8_t buffered = 0;
uint8_t append = 0;
char bak_path[256];
char tmp_path[256];
const char *path = NULL;
@ -699,9 +527,7 @@ int main(int argc, const char *argv[])
if ((c == 'e') || (c == 'E'))
do_erase = 1;
if ((c == 'a') || (c == 'A'))
append = 1;
if ((c == 'u') || (c == 'U'))
buffered = 1;
options.append = 1;
if ((c == 'o') || (c == 'O'))
options.overwrite = 1;
if ((c == 'i') || (c == 'I'))
@ -727,7 +553,7 @@ int main(int argc, const char *argv[])
#endif
if (((c == 'k') || (c == 'K')) && (i + 1 < argc))
{
disk_size = atoi(argv[i + 1]) * 1024;
options.disk_size = atoi(argv[i + 1]) * 1024;
i += 1;
}
if (((c == 'd') || (c == 'D')) && (i + 1 < argc))
@ -753,172 +579,29 @@ int main(int argc, const char *argv[])
path = argv[path_arg];
mode = MZ_OPEN_MODE_READ;
if ((do_list == 0) && (do_extract == 0) && (do_erase == 0))
if (do_list)
{
mode |= MZ_OPEN_MODE_WRITE;
if (mz_os_file_exists(path) != MZ_OK)
{
// If the file doesn't exist, we don't append file
mode |= MZ_OPEN_MODE_CREATE;
}
else if (append == 1)
{
mode |= MZ_OPEN_MODE_APPEND;
}
else if (options.overwrite == 0)
{
// If ask the user what to do because append and overwrite args not set
char rep = 0;
do
{
char answer[128];
printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ", path);
if (scanf("%1s", answer) != 1)
exit(EXIT_FAILURE);
rep = answer[0];
if ((rep >= 'a') && (rep <= 'z'))
rep -= 0x20;
}
while ((rep != 'Y') && (rep != 'N') && (rep != 'A'));
if (rep == 'A')
{
mode |= MZ_OPEN_MODE_APPEND;
}
else if (rep == 'Y')
{
mode |= MZ_OPEN_MODE_CREATE;
}
else if (rep == 'N')
{
minizip_help();
return 0;
}
}
err = minizip_list(path);
}
mz_stream_os_create(&file_stream);
mz_stream_buffered_create(&buf_stream);
mz_stream_split_create(&split_stream);
if (buffered)
else if (do_extract)
{
mz_stream_set_base(buf_stream, file_stream);
mz_stream_set_base(split_stream, buf_stream);
if (argc > path_arg + 1)
filename_to_extract = argv[path_arg + 1];
err = minizip_extract(path, filename_to_extract, destination, password, &options);
}
else if (do_erase)
{
strncpy(tmp_path, path, sizeof(tmp_path));
strncat(tmp_path, ".tmp", sizeof(tmp_path) - strlen(tmp_path) - 1);
err = minizip_erase(path, tmp_path, argc - (path_arg + 1), &argv[path_arg + 1]);
}
else
{
mz_stream_set_base(split_stream, file_stream);
err = minizip_add(path, password, &options, argc - (path_arg + 1), &argv[path_arg + 1]);
}
mz_stream_split_set_prop_int64(split_stream, MZ_STREAM_PROP_DISK_SIZE, disk_size);
err = mz_stream_open(split_stream, path, mode);
if (err != MZ_OK)
{
printf("Error opening file %s (%d)\n", path, err);
}
else
{
handle = mz_zip_open(split_stream, mode);
if (handle == NULL)
{
printf("Error opening zip %s\n", path);
err = MZ_FORMAT_ERROR;
}
if (do_list)
{
err = minizip_list(handle);
}
else if (do_extract)
{
// Create target directory if it doesn't exist
if (destination != NULL)
mz_make_dir(destination);
if (argc > path_arg + 1)
filename_to_extract = argv[path_arg + 1];
if (filename_to_extract == NULL)
err = minizip_extract_all(handle, destination, password, &options);
else
err = minizip_extract_onefile(handle, filename_to_extract, destination, password, &options);
}
else if (do_erase)
{
strncpy(tmp_path, path, sizeof(tmp_path));
strncat(tmp_path, ".tmp", sizeof(tmp_path) - strlen(tmp_path) - 1);
mz_stream_os_create(&tmp_file_stream);
mz_stream_buffered_create(&tmp_buf_stream);
mz_stream_split_create(&tmp_split_stream);
if (buffered)
{
mz_stream_set_base(tmp_buf_stream, tmp_file_stream);
mz_stream_set_base(tmp_split_stream, tmp_buf_stream);
}
else
{
mz_stream_set_base(tmp_split_stream, tmp_file_stream);
}
err = mz_stream_open(tmp_split_stream, tmp_path, MZ_OPEN_MODE_WRITE | MZ_OPEN_MODE_CREATE);
if (err != MZ_OK)
{
printf("Error creating temp file %s (%d)\n", tmp_path, err);
}
else
{
target_handle = mz_zip_open(tmp_split_stream, MZ_OPEN_MODE_WRITE);
if (target_handle != NULL)
{
err = minizip_copy_specific_entries(handle, target_handle, argc - (path_arg + 1), &argv[path_arg + 1]);
mz_zip_close(target_handle);
}
mz_stream_close(tmp_split_stream);
}
mz_stream_split_delete(&tmp_split_stream);
mz_stream_buffered_delete(&tmp_buf_stream);
mz_stream_os_delete(&tmp_file_stream);
}
else
{
printf("Creating %s\n", path);
// Go through command line args looking for files to add to zip
for (i = path_arg + 1; (i < argc) && (err == MZ_OK); i += 1)
err = minizip_add(handle, argv[i], NULL, password, &options, 1);
mz_zip_set_version_madeby(handle, MZ_VERSION_MADEBY);
}
err_close = mz_zip_close(handle);
if (err_close != MZ_OK)
{
printf("Error in closing %s (%d)\n", path, err_close);
err = err_close;
}
mz_stream_close(split_stream);
}
mz_stream_split_delete(&split_stream);
mz_stream_buffered_delete(&buf_stream);
mz_stream_os_delete(&file_stream);
if (err == MZ_OK && do_erase)
{
// Swap zip with temporary zip, backup old zip if possible

10
mz.h
View file

@ -22,10 +22,12 @@ extern "C" {
#define MZ_VERSION ("2.4.0")
// MZ_ERROR
#define MZ_OK (0)
#define MZ_STREAM_ERROR (-1)
#define MZ_DATA_ERROR (-3)
#define MZ_MEM_ERROR (-4)
#define MZ_OK (0) // zlib
#define MZ_STREAM_ERROR (-1) // zlib
#define MZ_DATA_ERROR (-3) // zlib
#define MZ_MEM_ERROR (-4) // zlib
#define MZ_BUF_ERROR (-5) // zlib
#define MZ_VERSION_ERROR (-6) // zlib
#define MZ_END_OF_LIST (-100)
#define MZ_END_OF_STREAM (-101)
#define MZ_PARAM_ERROR (-102)

View file

@ -108,13 +108,18 @@ extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **gl
extern zipFile ZEXPORT 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_open(stream, mode);
mz_zip_create(&handle);
err = mz_zip_open(handle, stream, mode);
if (handle == NULL)
if (err != MZ_OK)
{
mz_zip_delete(&handle);
return NULL;
}
if (globalcomment != NULL)
mz_zip_get_comment(handle, globalcomment);
@ -318,8 +323,7 @@ extern int ZEXPORT zipClose2_MZ(zipFile file, const char *global_comment, uint16
mz_zip_set_version_madeby(compat->handle, version_madeby);
err = mz_zip_close(compat->handle);
compat->handle = NULL;
mz_zip_delete(&compat->handle);
return err;
}
@ -384,12 +388,17 @@ extern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_
extern unzFile ZEXPORT unzOpen_MZ(void *stream)
{
mz_compat *compat = NULL;
int32_t err = MZ_OK;
void *handle = NULL;
handle = mz_zip_open(stream, MZ_OPEN_MODE_READ);
mz_zip_create(&handle);
err = mz_zip_open(handle, stream, MZ_OPEN_MODE_READ);
if (handle == NULL)
if (err != MZ_OK)
{
mz_zip_delete(&handle);
return NULL;
}
compat = (mz_compat *)MZ_ALLOC(sizeof(mz_compat));
compat->handle = handle;
@ -431,7 +440,7 @@ extern int ZEXPORT unzClose_MZ(unzFile file)
return UNZ_PARAMERROR;
err = mz_zip_close(compat->handle);
compat->handle = NULL;
mz_zip_delete(&compat->handle);
return err;
}
@ -709,9 +718,32 @@ extern int ZEXPORT unzGoToNextFile(unzFile file)
extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func)
{
mz_compat *compat = (mz_compat *)file;
mz_zip_file *file_info = NULL;
int32_t err = MZ_OK;
int32_t result = 0;
if (compat == NULL)
return UNZ_PARAMERROR;
return mz_zip_locate_entry(compat->handle, filename, filename_compare_func);
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 (filename_compare_func != NULL)
result = filename_compare_func(file, filename, file_info->filename);
else
result = strcmp(filename, file_info->filename);
if (result == 0)
return MZ_OK;
err = mz_zip_goto_next_entry(compat->handle);
}
return err;
}
extern int32_t ZEXPORT unzGetOffset(unzFile file)

View file

@ -159,7 +159,7 @@ int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
if ((*check == '\\') || (*check == '/'))
check += 1;
if ((source == path) || (check != source) || (*target == 0))
if ((source == path) || (check != source))
{
// Skip double paths
if ((*check == '\\') || (*check == '/'))

View file

@ -66,10 +66,24 @@ typedef struct mz_stream_buffered_s {
/***************************************************************************/
static int32_t mz_stream_buffered_reset(void *stream)
{
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
buffered->readbuf_len = 0;
buffered->readbuf_pos = 0;
buffered->writebuf_len = 0;
buffered->writebuf_pos = 0;
buffered->position = 0;
return MZ_OK;
}
int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode)
{
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
mz_stream_buffered_print(buffered, "open [mode %d]\n", mode);
mz_stream_buffered_reset(buffered);
return mz_stream_open(buffered->stream.base, path, mode);
}
@ -350,10 +364,7 @@ int32_t mz_stream_buffered_close(void *stream)
mz_stream_buffered_print(stream, "write efficency %.02f%%\n",
(buffered->writebuf_hits / ((float)buffered->writebuf_hits + buffered->writebuf_misses)) * 100);
buffered->readbuf_len = 0;
buffered->readbuf_pos = 0;
buffered->writebuf_len = 0;
buffered->writebuf_pos = 0;
mz_stream_buffered_reset(buffered);
return mz_stream_close(buffered->stream.base);
}

View file

@ -48,7 +48,7 @@ static mz_stream_vtbl mz_stream_mem_vtbl = {
typedef struct mz_stream_mem_s {
mz_stream stream;
int32_t mode;
char *buffer; // Memory buffer pointer
uint8_t *buffer; // Memory buffer pointer
int32_t size; // Size of the memory buffer
int32_t limit; // Furthest we've written
int32_t position; // Current position in the memory
@ -206,10 +206,10 @@ int32_t mz_stream_mem_error(void *stream)
return MZ_OK;
}
void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size)
void mz_stream_mem_set_buffer(void *stream, const void *buf, int32_t size)
{
mz_stream_mem *mem = (mz_stream_mem *)stream;
mem->buffer = buf;
mem->buffer = (uint8_t *)buf;
mem->size = size;
mem->limit = size;
}
@ -255,8 +255,7 @@ void *mz_stream_mem_create(void **stream)
{
memset(mem, 0, sizeof(mz_stream_mem));
mem->stream.vtbl = &mz_stream_mem_vtbl;
// Large grow size to prevent fragmentation
mem->grow_size = 128 * 1024;
mem->grow_size = 4096;
}
if (stream != NULL)
*stream = mem;

160
mz_zip.c
View file

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
#include <limits.h>
@ -472,17 +473,42 @@ static int32_t mz_zip_write_cd(void *handle)
return err;
}
extern void* mz_zip_open(void *stream, int32_t mode)
extern void *mz_zip_create(void **handle)
{
mz_zip *zip = NULL;
zip = (mz_zip *)MZ_ALLOC(sizeof(mz_zip));
if (zip != NULL)
{
memset(zip, 0, sizeof(mz_zip));
}
if (handle != NULL)
*handle = zip;
return zip;
}
extern void mz_zip_delete(void **handle)
{
mz_zip *zip = NULL;
if (handle == NULL)
return;
zip = (mz_zip *)*handle;
if (zip != NULL)
{
MZ_FREE(zip);
}
*handle = NULL;
}
extern int32_t mz_zip_open(void *handle, void *stream, int32_t mode)
{
mz_zip *zip = (mz_zip *)handle;
int32_t err = MZ_OK;
zip = (mz_zip *)MZ_ALLOC(sizeof(mz_zip));
if (zip == NULL)
return NULL;
memset(zip, 0, sizeof(mz_zip));
return MZ_PARAM_ERROR;
zip->stream = stream;
@ -530,23 +556,21 @@ extern void* mz_zip_open(void *stream, int32_t mode)
{
// Memory streams used to store variable length file info data
mz_stream_mem_create(&zip->file_info_stream);
mz_stream_mem_set_grow_size(zip->file_info_stream, 4096);
mz_stream_mem_open(zip->file_info_stream, NULL, MZ_OPEN_MODE_CREATE);
mz_stream_mem_create(&zip->local_file_info_stream);
mz_stream_mem_set_grow_size(zip->local_file_info_stream, 4096);
mz_stream_mem_open(zip->local_file_info_stream, NULL, MZ_OPEN_MODE_CREATE);
}
if (err != MZ_OK)
{
mz_zip_close(zip);
return NULL;
return err;
}
zip->open_mode = mode;
return zip;
return err;
}
extern int32_t mz_zip_close(void *handle)
@ -587,8 +611,6 @@ extern int32_t mz_zip_close(void *handle)
if (zip->comment)
MZ_FREE(zip->comment);
MZ_FREE(zip);
return err;
}
@ -1296,7 +1318,7 @@ static int32_t mz_zip_entry_open_int(void *handle, uint8_t raw, int16_t compress
}
else
{
if (zip->entry_raw || zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED)
if (zip->entry_raw || zip->file_info.compression_method == MZ_COMPRESS_METHOD_STORE || zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED)
{
max_total_in = zip->file_info.compressed_size;
mz_stream_set_prop_int64(zip->crypt_stream, MZ_STREAM_PROP_TOTAL_IN_MAX, max_total_in);
@ -1319,6 +1341,7 @@ static int32_t mz_zip_entry_open_int(void *handle, uint8_t raw, int16_t compress
err = mz_stream_open(zip->compress_stream, NULL, zip->open_mode);
}
if (err == MZ_OK)
{
mz_stream_crc32_create(&zip->crc32_stream);
@ -1340,7 +1363,7 @@ extern int32_t mz_zip_entry_is_open(void *handle)
mz_zip *zip = (mz_zip *)handle;
if (zip == NULL)
return MZ_PARAM_ERROR;
if (zip->entry_scanned == 0 || zip->entry_opened == 0)
if (zip->entry_opened == 0)
return MZ_EXIST_ERROR;
return MZ_OK;
}
@ -1451,14 +1474,14 @@ extern int32_t mz_zip_entry_write_open(void *handle, const mz_zip_file *file_inf
return err;
}
extern int32_t mz_zip_entry_read(void *handle, void *buf, uint32_t len)
extern int32_t mz_zip_entry_read(void *handle, void *buf, int32_t len)
{
mz_zip *zip = (mz_zip *)handle;
int32_t read = 0;
if (zip == NULL || mz_zip_entry_is_open(handle) != MZ_OK)
return MZ_PARAM_ERROR;
if (UINT_MAX == UINT16_MAX && len > UINT16_MAX) // Zlib limitation
if (UINT_MAX == UINT16_MAX && len > UINT16_MAX) // zlib limitation
return MZ_PARAM_ERROR;
if (len == 0)
return MZ_PARAM_ERROR;
@ -1472,7 +1495,7 @@ extern int32_t mz_zip_entry_read(void *handle, void *buf, uint32_t len)
return read;
}
extern int32_t mz_zip_entry_write(void *handle, const void *buf, uint32_t len)
extern int32_t mz_zip_entry_write(void *handle, const void *buf, int32_t len)
{
mz_zip *zip = (mz_zip *)handle;
int32_t written = 0;
@ -1683,29 +1706,7 @@ extern int32_t mz_zip_goto_next_entry(void *handle)
return mz_zip_goto_next_entry_int(handle);
}
static int32_t mz_zip_locate_entry_default_cb(void *handle, const char *filename1, const char *filename2)
{
do
{
if ((*filename1 == '\\' && *filename2 == '/') ||
(*filename1 == '/' && *filename2 == '\\'))
{
// ignore comparison of path slashes
}
else if (*filename1 != *filename2)
{
break;
}
filename1 += 1;
filename2 += 1;
}
while (*filename1 != 0 && *filename2 != 0);
return (int32_t)(*filename1 - *filename2);
}
extern int32_t mz_zip_locate_entry(void *handle, const char *filename, mz_filename_compare_cb filename_compare_cb)
extern int32_t mz_zip_locate_entry(void *handle, const char *filename, uint8_t ignore_case)
{
mz_zip *zip = (mz_zip *)handle;
int32_t err = MZ_OK;
@ -1714,22 +1715,57 @@ extern int32_t mz_zip_locate_entry(void *handle, const char *filename, mz_filena
if (zip == NULL || filename == NULL)
return MZ_PARAM_ERROR;
if (filename_compare_cb == NULL)
filename_compare_cb = mz_zip_locate_entry_default_cb;
// if we are already on the current entry, no need to search
// If we are already on the current entry, no need to search
if ((zip->entry_scanned) && (zip->file_info.filename != NULL))
{
result = filename_compare_cb(handle, zip->file_info.filename, filename);
result = mz_zip_path_compare(zip->file_info.filename, filename, ignore_case);
if (result == 0)
return MZ_OK;
}
// search all entries starting at the first
// Search all entries starting at the first
err = mz_zip_goto_first_entry(handle);
while (err == MZ_OK)
{
result = filename_compare_cb(handle, zip->file_info.filename, filename);
result = mz_zip_path_compare(zip->file_info.filename, filename, ignore_case);
if (result == 0)
return MZ_OK;
err = mz_zip_goto_next_entry(handle);
}
return err;
}
extern int32_t mz_zip_locate_first_entry(void *handle, void *userdata, mz_zip_locate_entry_cb cb)
{
mz_zip *zip = (mz_zip *)handle;
int32_t err = MZ_OK;
int32_t result = 0;
// Search first entry looking for match
err = mz_zip_goto_first_entry(handle);
if (err != MZ_OK)
return err;
result = cb(handle, userdata, &zip->file_info);
if (result == 0)
return MZ_OK;
return mz_zip_locate_next_entry(handle, userdata, cb);
}
extern int32_t mz_zip_locate_next_entry(void *handle, void *userdata, mz_zip_locate_entry_cb cb)
{
mz_zip *zip = (mz_zip *)handle;
int32_t err = MZ_OK;
int32_t result = 0;
// Search next entries looking for match
err = mz_zip_goto_next_entry(handle);
while (err == MZ_OK)
{
result = cb(handle, userdata, &zip->file_info);
if (result == 0)
return MZ_OK;
@ -1869,3 +1905,35 @@ int32_t mz_zip_unix_to_ntfs_time(time_t unix_time, uint64_t *ntfs_time)
*ntfs_time = ((uint64_t)unix_time * 10000000) + 116444736000000000LL;
return MZ_OK;
}
int32_t mz_zip_path_compare(const char *path1, const char *path2, uint8_t ignore_case)
{
do
{
if ((*path1 == '\\' && *path2 == '/') ||
(*path2 == '\\' && *path1 == '/'))
{
// Ignore comparison of path slashes
}
else if (ignore_case)
{
if (tolower(*path1) != tolower(*path2))
break;
}
else if (*path1 != *path2)
{
break;
}
path1 += 1;
path2 += 1;
}
while (*path1 != 0 && *path2 != 0);
if (ignore_case)
return (int32_t)(tolower(*path1) - tolower(*path2));
return (int32_t)(*path1 - *path2);
}
/***************************************************************************/

View file

@ -57,11 +57,21 @@ typedef struct mz_zip_file_s
uint16_t aes_version; // winzip aes extension if not 0
uint8_t aes_encryption_mode; // winzip aes encryption mode
#endif
} mz_zip_file;
} mz_zip_file, mz_zip_entry;
/***************************************************************************/
extern void * mz_zip_open(void *stream, int32_t mode);
typedef int32_t (*mz_zip_locate_entry_cb)(void *handle, void *userdata, mz_zip_file *file_info);
/***************************************************************************/
extern void * mz_zip_create(void **handle);
// Create zip instance for opening
extern void mz_zip_delete(void **handle);
// Delete zip object
extern int32_t mz_zip_open(void *handle, void *stream, int32_t mode);
// Create a zip file, no delete file in zip functionality
extern int32_t mz_zip_close(void *handle);
@ -79,11 +89,13 @@ extern int32_t mz_zip_get_version_madeby(void *handle, uint16_t *version_madeby)
extern int32_t mz_zip_set_version_madeby(void *handle, uint16_t version_madeby);
// Set the version made by used for writing zip file
/***************************************************************************/
extern int32_t mz_zip_entry_write_open(void *handle, const mz_zip_file *file_info,
int16_t compress_level, uint8_t raw, const char *password);
// Open for writing the current file in the zip file
extern int32_t mz_zip_entry_write(void *handle, const void *buf, uint32_t len);
extern int32_t mz_zip_entry_write(void *handle, const void *buf, int32_t len);
// Write bytes from the current file in the zip file
extern int32_t mz_zip_entry_is_open(void *handle);
@ -92,7 +104,7 @@ extern int32_t mz_zip_entry_is_open(void *handle);
extern int32_t mz_zip_entry_read_open(void *handle, uint8_t raw, const char *password);
// Open for reading the current file in the zip file
extern int32_t mz_zip_entry_read(void *handle, void *buf, uint32_t len);
extern int32_t mz_zip_entry_read(void *handle, void *buf, int32_t len);
// Read bytes from the current file in the zip file
extern int32_t mz_zip_entry_get_info(void *handle, mz_zip_file **file_info);
@ -127,11 +139,15 @@ extern int32_t mz_zip_goto_first_entry(void *handle);
extern int32_t mz_zip_goto_next_entry(void *handle);
// Go to the next entry in the zip file or MZ_END_OF_LIST if reaching the end
typedef int32_t (*mz_filename_compare_cb)(void *handle, const char *filename1, const char *filename2);
extern int32_t mz_zip_locate_entry(void *handle, const char *filename,
mz_filename_compare_cb filename_compare_cb);
extern int32_t mz_zip_locate_entry(void *handle, const char *filename, uint8_t ignore_case);
// Locate the file with the specified name in the zip file or MZ_END_LIST if not found
extern int32_t mz_zip_locate_first_entry(void *handle, void *userdata, mz_zip_locate_entry_cb cb);
// Locate the first matching entry based on a match callback
extern int32_t mz_zip_locate_next_entry(void *handle, void *userdata, mz_zip_locate_entry_cb cb);
// LOcate the next matching entry based on a match callback
/***************************************************************************/
int32_t mz_zip_attrib_is_dir(int32_t attributes, int32_t version_madeby);
@ -158,6 +174,9 @@ int32_t mz_zip_ntfs_to_unix_time(uint64_t ntfs_time, time_t *unix_time);
int32_t mz_zip_unix_to_ntfs_time(time_t unix_time, uint64_t *ntfs_time);
// Convert unix time to ntfs time
int32_t mz_zip_path_compare(const char *path1, const char *path2, uint8_t ignore_case);
// Compare two paths without regard to slashes
/***************************************************************************/
#ifdef __cplusplus

1265
mz_zip_rw.c Normal file

File diff suppressed because it is too large Load diff

210
mz_zip_rw.h Normal file
View file

@ -0,0 +1,210 @@
/* mz_zip_rw.h -- Zip reader/writer
Version 2.4.0, August 5, 2018
part of the MiniZip project
Copyright (C) 2010-2018 Nathan Moinvaziri
https://github.com/nmoinvaz/minizip
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.
*/
#ifndef MZ_ZIP_RW_H
#define MZ_ZIP_RW_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "mz_zip.h"
/***************************************************************************/
typedef int32_t (*mz_zip_reader_overwrite_cb)(void *handle, void *userdata, mz_zip_file *file_info, const char *path);
typedef int32_t (*mz_zip_reader_password_cb)(void *handle, void *userdata, mz_zip_file *file_info, char *password, int32_t max_password);
typedef int32_t (*mz_zip_reader_progress_cb)(void *handle, void *userdata, mz_zip_file *file_info, uint64_t position);
typedef int32_t (*mz_zip_reader_entry_cb)(void *handle, void *userdata, mz_zip_file *file_info);
/***************************************************************************/
int32_t mz_zip_reader_is_open(void *handle);
// Checks to see if the zip file is open
int32_t mz_zip_reader_open(void *handle, void *stream);
// Opens zip file from stream
int32_t mz_zip_reader_open_file(void *handle, const char *path);
// Opens zip file from a file path
int32_t mz_zip_reader_open_file_in_memory(void *handle, const char *path);
// Opens zip file from a file path into memory for faster access
int32_t mz_zip_reader_open_buffer(void *handle, uint8_t *buf, int32_t len, uint8_t copy);
// Opens zip file from memory buffer
int32_t mz_zip_reader_close(void *handle);
// Closes the zip file
/***************************************************************************/
int32_t mz_zip_reader_goto_first(void *handle);
// Goto the first entry in the zip file that matches the pattern
int32_t mz_zip_reader_goto_next(void *handle);
// Goto the next entry in the zip file that matches the pattern
int32_t mz_zip_reader_get_info(void *handle, mz_zip_file **file_info);
// Gets the current entry file info
/***************************************************************************/
int32_t mz_zip_reader_save(void *handle, void *stream, mz_stream_write_cb write_cb);
// Save the current entry to a steam
int32_t mz_zip_reader_save_process(void *handle, void *stream, mz_stream_write_cb write_cb);
// Saves a portion of the current entry to a stream callback
int32_t mz_zip_reader_save_file(void *handle, const char *path);
// Save the current entry to a file
int32_t mz_zip_reader_save_buffer(void *handle, const void *buf, int32_t len);
// Save the current entry to a memory buffer
int32_t mz_zip_reader_save_buffer_length(void *handle);
// Gets the length of the buffer required to save
int32_t mz_zip_reader_save_all(void *handle, const char *destination_dir);
// Save all files into a directory
/***************************************************************************/
void mz_zip_reader_set_pattern(void *handle, const char *pattern, uint8_t ignore_case);
// Sets the match pattern for entries in the zip file, if null all entries are matched
void mz_zip_reader_set_password(void *handle, const char *password);
// Sets the password required for extraction
void mz_zip_reader_set_raw(void *handle, uint8_t raw);
// Sets whether or not we should save the entry raw
int32_t mz_zip_reader_get_raw(void *handle, uint8_t *raw);
// Gets whether or not we should save the entry raw
void mz_zip_reader_set_overwrite_cb(void *handle, void *userdata, mz_zip_reader_overwrite_cb cb);
// Callback for what to do when a file is being overwritten
void mz_zip_reader_set_password_cb(void *handle, void *userdata, mz_zip_reader_password_cb cb);
// Callback for when a password is required and hasn't been set
void mz_zip_reader_set_progress_cb(void *handle, void *userdata, mz_zip_reader_progress_cb cb);
// Callback for extraction progress
void mz_zip_reader_set_entry_cb(void *handle, void *userdata, mz_zip_reader_entry_cb cb);
// Callback for zip file entries
int32_t mz_zip_reader_get_zip_handle(void *handle, void **zip_handle);
// Gets the underlying zip instance handle
void* mz_zip_reader_create(void **handle);
// Create new instance of zip reader
void mz_zip_reader_delete(void **handle);
// Delete instance of zip reader
/***************************************************************************/
typedef int32_t (*mz_zip_writer_overwrite_cb)(void *handle, void *userdata, const char *path);
typedef int32_t (*mz_zip_writer_password_cb)(void *handle, void *userdata, mz_zip_file *file_info, char *password, int32_t max_password);
typedef int32_t (*mz_zip_writer_progress_cb)(void *handle, void *userdata, mz_zip_file *file_info, uint64_t position);
typedef int32_t (*mz_zip_writer_entry_cb)(void *handle, void *userdata, mz_zip_file *file_info);
/***************************************************************************/
int32_t mz_zip_writer_is_open(void *handle);
// Checks to see if the zip file is open
int32_t mz_zip_writer_open(void *handle, void *stream);
// Opens zip file from stream
int32_t mz_zip_writer_open_file(void *handle, const char *path, int64_t disk_size, uint8_t append);
// Opens zip file from a file path
int32_t mz_zip_writer_open_file_in_memory(void *handle, const char *path);
// Opens zip file from a file path into memory for faster access
int32_t mz_zip_writer_close(void *handle);
// Closes the zip file
/***************************************************************************/
int32_t mz_zip_writer_add(void *handle, void *stream, mz_stream_read_cb read_cb);
// Writes all data to the currently open entry in the zip
int32_t mz_zip_writer_add_process(void *handle, void *stream, mz_stream_read_cb read_cb);
// Writes a portion of data to the currently open entry in the zip
int32_t mz_zip_writer_add_info(void *handle, void *stream, mz_stream_read_cb read_cb, mz_zip_file *file_info);
// Adds an entry to the zip based on the info
int32_t mz_zip_writer_add_buffer(void *handle, const void *buf, int32_t len, mz_zip_file *file_info);
// Adds an entry to the zip with a memory buffer
int32_t mz_zip_writer_add_file(void *handle, const char *path, const char *filename_in_zip);
// Adds an entry to the zip from a file
int32_t mz_zip_writer_add_path(void *handle, const char *path, const char *root_path, uint8_t include_path, uint8_t recursive);
// Enumerates a directory or pattern and adds entries to the zip
int32_t mz_zip_writer_copy_from_reader(void *handle, void *reader);
// Adds an entry from a zip reader instance
/***************************************************************************/
void mz_zip_writer_set_password(void *handle, const char *password);
// Password to use for encrypting files in the zip
void mz_zip_writer_set_raw(void *handle, uint8_t raw);
// Sets whether or not we should write the entry raw
int32_t mz_zip_writer_get_raw(void *handle, uint8_t *raw);
// Gets whether or not we should write the entry raw
void mz_zip_writer_set_aes(void *handle, uint8_t aes);
// Use aes encryption when adding files in zip
void mz_zip_writer_set_compress_method(void *handle, int16_t compress_method);
// Sets the compression method when adding files in zip
void mz_zip_writer_set_compress_level(void *handle, int16_t compress_level);
// Sets the compression level when adding files in zip
void mz_zip_writer_set_overwrite_cb(void *handle, void *userdata, mz_zip_writer_overwrite_cb cb);
// Callback for what to do when zip file already exists
void mz_zip_writer_set_password_cb(void *handle, void *userdata, mz_zip_writer_password_cb cb);
// Callback for ask if a password is required for adding
void mz_zip_writer_set_progress_cb(void *handle, void *userdata, mz_zip_writer_progress_cb cb);
// Callback for compression progress
void mz_zip_writer_set_entry_cb(void *handle, void *userdata, mz_zip_writer_entry_cb cb);
// Callback for zip file entries
int32_t mz_zip_writer_get_zip_handle(void *handle, void **zip_handle);
// Gets the underlying zip handle
void* mz_zip_writer_create(void **handle);
// Create new instance of zip writer
void mz_zip_writer_delete(void **handle);
// Delete instance of zip writer
/***************************************************************************/
#ifdef __cplusplus
}
#endif
#endif