VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/libzip/zip_progress.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/libzip/zip_progress.c')
-rw-r--r--src/Common/libzip/zip_progress.c172
1 files changed, 143 insertions, 29 deletions
diff --git a/src/Common/libzip/zip_progress.c b/src/Common/libzip/zip_progress.c
index 9b116942..d48ae563 100644
--- a/src/Common/libzip/zip_progress.c
+++ b/src/Common/libzip/zip_progress.c
@@ -1,6 +1,6 @@
/*
zip_progress.c -- progress reporting
- Copyright (C) 2017-2018 Dieter Baron and Thomas Klausner
+ Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -40,10 +40,14 @@
struct zip_progress {
zip_t *za;
- zip_progress_callback callback;
- void (*ud_free)(void *);
- void *ud;
+ zip_progress_callback callback_progress;
+ void (*ud_progress_free)(void *);
+ void *ud_progress;
+
+ zip_cancel_callback callback_cancel;
+ void (*ud_cancel_free)(void *);
+ void *ud_cancel;
double precision;
@@ -54,6 +58,11 @@ struct zip_progress {
double end; /* end of sub-progress section */
};
+static void _zip_progress_free_cancel_callback(zip_progress_t *progress);
+static void _zip_progress_free_progress_callback(zip_progress_t *progress);
+static zip_progress_t *_zip_progress_new(zip_t *za);
+static void _zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud);
+static void _zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud);
void
_zip_progress_end(zip_progress_t *progress) {
@@ -67,16 +76,15 @@ _zip_progress_free(zip_progress_t *progress) {
return;
}
- if (progress->ud_free) {
- progress->ud_free(progress->ud);
- }
+ _zip_progress_free_progress_callback(progress);
+ _zip_progress_free_cancel_callback(progress);
free(progress);
}
-zip_progress_t *
-_zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
+static zip_progress_t *
+_zip_progress_new(zip_t *za) {
zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress));
if (progress == NULL) {
@@ -85,52 +93,117 @@ _zip_progress_new(zip_t *za, double precision, zip_progress_callback callback, v
}
progress->za = za;
- progress->callback = callback;
- progress->ud_free = ud_free;
- progress->ud = ud;
- progress->precision = precision;
+
+ progress->callback_progress = NULL;
+ progress->ud_progress_free = NULL;
+ progress->ud_progress = NULL;
+ progress->precision = 0.0;
+
+ progress->callback_cancel = NULL;
+ progress->ud_cancel_free = NULL;
+ progress->ud_cancel = NULL;
return progress;
}
+static void
+_zip_progress_free_progress_callback(zip_progress_t *progress) {
+ if (progress->ud_progress_free) {
+ progress->ud_progress_free(progress->ud_progress);
+ }
+
+ progress->callback_progress = NULL;
+ progress->ud_progress = NULL;
+ progress->ud_progress_free = NULL;
+}
+
+static void
+_zip_progress_free_cancel_callback(zip_progress_t *progress) {
+ if (progress->ud_cancel_free) {
+ progress->ud_cancel_free(progress->ud_cancel);
+ }
+
+ progress->callback_cancel = NULL;
+ progress->ud_cancel = NULL;
+ progress->ud_cancel_free = NULL;
+}
+
+static void
+_zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
+ _zip_progress_free_progress_callback(progress);
+
+ progress->callback_progress = callback;
+ progress->ud_progress_free = ud_free;
+ progress->ud_progress = ud;
+ progress->precision = precision;
+}
void
+_zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
+ _zip_progress_free_cancel_callback(progress);
+
+ progress->callback_cancel = callback;
+ progress->ud_cancel_free = ud_free;
+ progress->ud_cancel = ud;
+}
+
+int
_zip_progress_start(zip_progress_t *progress) {
if (progress == NULL) {
- return;
+ return 0;
+ }
+
+ if (progress->callback_progress != NULL) {
+ progress->last_update = 0.0;
+ progress->callback_progress(progress->za, 0.0, progress->ud_progress);
+ }
+
+ if (progress->callback_cancel != NULL) {
+ if (progress->callback_cancel(progress->za, progress->ud_cancel)) {
+ return -1;
+ }
}
- progress->last_update = 0.0;
- progress->callback(progress->za, 0.0, progress->ud);
+ return 0;
}
-void
+int
_zip_progress_subrange(zip_progress_t *progress, double start, double end) {
if (progress == NULL) {
- return;
+ return 0;
}
progress->start = start;
progress->end = end;
- _zip_progress_update(progress, 0.0);
+ return _zip_progress_update(progress, 0.0);
}
-void
+int
_zip_progress_update(zip_progress_t *progress, double sub_current) {
double current;
if (progress == NULL) {
- return;
+ return 0;
}
- current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
+ if (progress->callback_progress != NULL) {
+ current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
- if (current - progress->last_update > progress->precision) {
- progress->callback(progress->za, current, progress->ud);
- progress->last_update = current;
+ if (current - progress->last_update > progress->precision) {
+ progress->callback_progress(progress->za, current, progress->ud_progress);
+ progress->last_update = current;
+ }
}
+
+ if (progress->callback_cancel != NULL) {
+ if (progress->callback_cancel(progress->za, progress->ud_cancel)) {
+ return -1;
+ }
+ }
+
+ return 0;
}
@@ -139,13 +212,54 @@ zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progr
zip_progress_t *progress = NULL;
if (callback != NULL) {
- if ((progress = _zip_progress_new(za, precision, callback, ud_free, ud)) == NULL) {
- return -1;
+ if (za->progress == NULL) {
+ if ((za->progress = _zip_progress_new(za)) == NULL) {
+ return -1;
+ }
}
+
+ _zip_progress_set_progress_callback(za->progress, precision, callback, ud_free, ud);
}
+ else {
+ if (za->progress != NULL) {
+ if (za->progress->callback_cancel == NULL) {
+ _zip_progress_free(za->progress);
+ za->progress = NULL;
+ }
+ else {
+ _zip_progress_free_progress_callback(za->progress);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+ZIP_EXTERN int
+zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
+ zip_progress_t *progress = NULL;
+
+ if (callback != NULL) {
+ if (za->progress == NULL) {
+ if ((za->progress = _zip_progress_new(za)) == NULL) {
+ return -1;
+ }
+ }
- _zip_progress_free(za->progress);
- za->progress = progress;
+ _zip_progress_set_cancel_callback(za->progress, callback, ud_free, ud);
+ }
+ else {
+ if (za->progress != NULL) {
+ if (za->progress->callback_progress == NULL) {
+ _zip_progress_free(za->progress);
+ za->progress = NULL;
+ }
+ else {
+ _zip_progress_free_cancel_callback(za->progress);
+ }
+ }
+ }
return 0;
}