Add mz_zip_[reader,writer]_set_progress_interval

With mz_zip_reader_set_progress_interval the user can specify how
often in milliseconds the progress callback should be called. This
makes it possible to make a smoother progress bar when using
minizip from a GUI application.
This commit is contained in:
Christer Fletcher 2018-09-18 12:06:54 +02:00
parent bb96c73f7b
commit 72538543aa
6 changed files with 78 additions and 20 deletions

View File

@ -33,6 +33,11 @@
# include <stdlib.h>
#endif
#ifdef __APPLE__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#include "mz.h"
#include "mz_strm.h"
#include "mz_os.h"
@ -260,3 +265,21 @@ int32_t mz_posix_is_dir(const char *path)
return MZ_OK;
return MZ_EXIST_ERROR;
}
uint64_t mz_posix_ms_time(void) {
struct timespec ts;
#ifdef __APPLE__
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts.tv_sec = mts.tv_sec;
ts.tv_nsec = mts.tv_nsec;
#else
clock_gettime(CLOCK_MONOTONIC, &ts);
#endif
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

View File

@ -45,6 +45,7 @@ struct
dirent* mz_posix_read_dir(DIR *dir);
int32_t mz_posix_close_dir(DIR *dir);
int32_t mz_posix_is_dir(const char *path);
uint64_t mz_posix_ms_time(void);
/***************************************************************************/
@ -62,6 +63,7 @@ int32_t mz_posix_is_dir(const char *path);
#define mz_os_read_dir mz_posix_read_dir
#define mz_os_close_dir mz_posix_close_dir
#define mz_os_is_dir mz_posix_is_dir
#define mz_os_ms_time mz_posix_ms_time
/***************************************************************************/

View File

@ -381,3 +381,13 @@ int32_t mz_win32_is_dir(const char *path)
return MZ_EXIST_ERROR;
}
uint64_t mz_win32_ms_time(void) {
SYSTEMTIME system_time;
GetSystemTime(&system_time);
FILETIME file_time;
SystemTimeToFileTime(&system_time, &file_time);
return ((((ULONGLONG) file_time.dwHighDateTime) << 32) + file_time.dwLowDateTime)/10000 - 11644473600000;
}

View File

@ -46,6 +46,7 @@ struct
dirent* mz_win32_read_dir(DIR *dir);
int32_t mz_win32_close_dir(DIR *dir);
int32_t mz_win32_is_dir(const char *path);
uint64_t mz_win32_ms_time(void);
/***************************************************************************/
@ -63,6 +64,7 @@ int32_t mz_win32_is_dir(const char *path);
#define mz_os_read_dir mz_win32_read_dir
#define mz_os_close_dir mz_win32_close_dir
#define mz_os_is_dir mz_win32_is_dir
#define mz_os_ms_time mz_win32_ms_time
/***************************************************************************/

View File

@ -46,6 +46,7 @@ typedef struct mz_zip_reader_s {
void *progress_userdata;
mz_zip_reader_progress_cb
progress_cb;
uint32_t progress_cb_interval_ms;
void *entry_userdata;
mz_zip_reader_entry_cb
entry_cb;
@ -56,6 +57,8 @@ typedef struct mz_zip_reader_s {
/***************************************************************************/
#define DEFAULT_PROGRESS_INTERVAL 1000u
int32_t mz_zip_reader_is_open(void *handle)
{
mz_zip_reader *reader = (mz_zip_reader *)handle;
@ -413,8 +416,8 @@ int32_t mz_zip_reader_entry_save(void *handle, void *stream, mz_stream_write_cb
int64_t update_pos = 0;
int32_t err = MZ_OK;
int32_t written = 0;
time_t current_time = time(NULL);
time_t update_time = 0;
uint64_t current_time = 0;
uint64_t update_time = 0;
if (mz_zip_reader_is_open(reader) != MZ_OK)
return MZ_PARAM_ERROR;
@ -436,9 +439,9 @@ int32_t mz_zip_reader_entry_save(void *handle, void *stream, mz_stream_write_cb
if (written < 0)
err = written;
// Every 1 second lets update the progress
current_time = time(NULL);
if (current_time > update_time)
// Update progress if enough time have passed
current_time = mz_os_ms_time();
if (current_time - update_time > reader->progress_cb_interval_ms)
{
if (reader->progress_cb != NULL)
reader->progress_cb(handle, reader->progress_userdata, reader->file_info, current_pos);
@ -513,7 +516,7 @@ int32_t mz_zip_reader_entry_save_file(void *handle, const char *path)
if (err == MZ_OK)
{
// Set the time of the file that has been created
mz_os_set_file_date(path, reader->file_info->modified_date,
mz_os_set_file_date(path, reader->file_info->modified_date,
reader->file_info->accessed_date, reader->file_info->creation_date);
}
@ -544,7 +547,7 @@ int32_t mz_zip_reader_entry_save_buffer(void *handle, void *buf, int32_t len)
if (len != (int32_t)reader->file_info->uncompressed_size)
return MZ_PARAM_ERROR;
// Create a memory stream backed by our buffer and save to it
// Create a memory stream backed by our buffer and save to it
mz_stream_mem_create(&mem_stream);
mz_stream_mem_set_buffer(mem_stream, buf, len);
@ -672,6 +675,12 @@ void mz_zip_reader_set_progress_cb(void *handle, void *userdata, mz_zip_reader_p
reader->progress_userdata = userdata;
}
void mz_zip_reader_set_progress_interval(void *handle, uint32_t milliseconds)
{
mz_zip_reader *reader = (mz_zip_reader *)handle;
reader->progress_cb_interval_ms = milliseconds;
}
void mz_zip_reader_set_entry_cb(void *handle, void *userdata, mz_zip_reader_entry_cb cb)
{
mz_zip_reader *reader = (mz_zip_reader *)handle;
@ -700,9 +709,9 @@ void *mz_zip_reader_create(void **handle)
if (reader != NULL)
{
memset(reader, 0, sizeof(mz_zip_reader));
}
if (reader != NULL)
reader->progress_cb_interval_ms = DEFAULT_PROGRESS_INTERVAL;
*handle = reader;
}
return reader;
}
@ -739,6 +748,7 @@ typedef struct mz_zip_writer_s {
void *progress_userdata;
mz_zip_writer_progress_cb
progress_cb;
uint32_t progress_cb_interval_ms;
void *entry_userdata;
mz_zip_writer_entry_cb
entry_cb;
@ -1007,9 +1017,8 @@ int32_t mz_zip_writer_add(void *handle, void *stream, mz_stream_read_cb read_cb)
int64_t update_pos = 0;
int32_t err = MZ_OK;
int32_t written = 0;
time_t current_time = time(NULL);
time_t update_time = 0;
uint64_t current_time = 0;
uint64_t update_time = 0;
// Update the progress at the beginning
if (writer->progress_cb != NULL)
@ -1026,9 +1035,9 @@ int32_t mz_zip_writer_add(void *handle, void *stream, mz_stream_read_cb read_cb)
if (written < 0)
err = written;
// Every 1 second lets update the progress
current_time = time(NULL);
if (current_time > update_time)
// Update progress if enough time have passed
current_time = mz_os_ms_time();
if (current_time - update_time > writer->progress_cb_interval_ms)
{
if (writer->progress_cb != NULL)
writer->progress_cb(handle, writer->progress_userdata, &writer->file_info, current_pos);
@ -1124,7 +1133,7 @@ int32_t mz_zip_writer_add_file(void *handle, const char *path, const char *filen
filename += 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 = writer->compress_method;
file_info.filename = filename;
@ -1336,6 +1345,11 @@ void mz_zip_writer_set_progress_cb(void *handle, void *userdata, mz_zip_writer_p
writer->progress_userdata = userdata;
}
void mz_zip_writer_set_progress_interval(void *handle, uint32_t milliseconds) {
mz_zip_writer *writer = (mz_zip_writer *)handle;
writer->progress_cb_interval_ms = milliseconds;
}
void mz_zip_writer_set_entry_cb(void *handle, void *userdata, mz_zip_writer_entry_cb cb)
{
mz_zip_writer *writer = (mz_zip_writer *)handle;
@ -1367,9 +1381,10 @@ void *mz_zip_writer_create(void **handle)
writer->compress_method = MZ_COMPRESS_METHOD_DEFLATE;
writer->compress_level = MZ_COMPRESS_LEVEL_BEST;
}
if (writer != NULL)
writer->progress_cb_interval_ms = DEFAULT_PROGRESS_INTERVAL;
*handle = writer;
}
return writer;
}

View File

@ -119,6 +119,9 @@ void mz_zip_reader_set_password_cb(void *handle, void *userdata, mz_zip_reade
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_progress_interval(void *handle, uint32_t milliseconds);
// Let at least milliseconds pass between calls to progress callback
void mz_zip_reader_set_entry_cb(void *handle, void *userdata, mz_zip_reader_entry_cb cb);
// Callback for zip file entries
@ -161,7 +164,7 @@ int32_t mz_zip_writer_entry_open(void *handle, mz_zip_file *file_info);
// Opens an entry in the zip file for writing
int32_t mz_zip_writer_entry_close(void *handle);
// Closes entry in zip file
// Closes entry in zip file
int32_t mz_zip_writer_entry_write(void *handle, const void *buf, int32_t len);
// Writes data into entry for zip
@ -187,7 +190,7 @@ int32_t mz_zip_writer_add_path(void *handle, const char *path, const char *root_
// 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
// Adds an entry from a zip reader instance
/***************************************************************************/
@ -218,6 +221,9 @@ void mz_zip_writer_set_password_cb(void *handle, void *userdata, mz_zip_write
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_progress_interval(void *handle, uint32_t milliseconds);
// Let at least milliseconds pass between calls to progress callback
void mz_zip_writer_set_entry_cb(void *handle, void *userdata, mz_zip_writer_entry_cb cb);
// Callback for zip file entries