Skip to content

Commit 9729dc3

Browse files
committed
Improve progress callback.
- Pass zip archive and user provided context (void pointer) into callback. - Optional free function for context.
1 parent 677f980 commit 9729dc3

File tree

11 files changed

+229
-67
lines changed

11 files changed

+229
-67
lines changed

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ SET(LIBZIP_SOURCES
111111
zip_name_locate.c
112112
zip_new.c
113113
zip_open.c
114+
zip_progress.c
114115
zip_rename.c
115116
zip_replace.c
116117
zip_set_archive_comment.c

lib/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ libzip_la_SOURCES=\
8787
zip_name_locate.c \
8888
zip_new.c \
8989
zip_open.c \
90+
zip_progress.c \
9091
zip_rename.c \
9192
zip_replace.c \
9293
zip_set_archive_comment.c \

lib/zip.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,12 @@ typedef struct zip_stat zip_stat_t;
309309
typedef zip_uint32_t zip_flags_t;
310310

311311
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
312-
typedef void (*zip_progress_callback_t)(double);
313-
312+
typedef void (*zip_progress_callback)(zip_t *, double, void *);
314313

315314
#ifndef ZIP_DISABLE_DEPRECATED
315+
typedef void (*zip_progress_callback_t)(double);
316+
ZIP_EXTERN void zip_register_progress_callback(zip_t *, zip_progress_callback_t);
317+
316318
ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */
317319
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */
318320
ZIP_EXTERN const char *zip_get_file_comment(zip_t *, zip_uint64_t, int *, int); /* use zip_file_get_comment */
@@ -378,7 +380,7 @@ ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t);
378380
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
379381
ZIP_EXTERN zip_t *zip_open(const char *, int, int *);
380382
ZIP_EXTERN zip_t *zip_open_from_source(zip_source_t *, int, zip_error_t *);
381-
ZIP_EXTERN void zip_register_progress_callback(zip_t *, zip_progress_callback_t);
383+
ZIP_EXTERN int zip_register_progress_callback_with_state(zip_t *, double, zip_progress_callback, void (*)(void *), void *);
382384
ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
383385
ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
384386
ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);

lib/zip_close.c

Lines changed: 17 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,10 @@
5151
#endif
5252

5353

54-
typedef struct {
55-
double last_update; /* last value callback function was called with */
56-
57-
double start; /* start of sub-progress setcion */
58-
double end; /* end of sub-progress setcion */
59-
} progress_state_t;
60-
61-
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, progress_state_t *);
62-
static int copy_data(zip_t *, zip_uint64_t, progress_state_t *);
63-
static int copy_source(zip_t *, zip_source_t *, progress_state_t *, zip_int64_t);
54+
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
55+
static int copy_data(zip_t *, zip_uint64_t);
56+
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
6457
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
65-
static void _zip_progress(zip_t *, progress_state_t *, double);
6658

6759
ZIP_EXTERN int
6860
zip_close(zip_t *za)
@@ -72,7 +64,6 @@ zip_close(zip_t *za)
7264
int error;
7365
zip_filelist_t *filelist;
7466
int changed;
75-
progress_state_t progress_state;
7667

7768
if (za == NULL)
7869
return -1;
@@ -129,22 +120,15 @@ zip_close(zip_t *za)
129120
free(filelist);
130121
return -1;
131122
}
132-
133-
if (za->progress_callback) {
134-
progress_state.last_update = 0.0;
135-
za->progress_callback(0.0);
136-
}
123+
124+
_zip_progress_start(za->progress);
137125
error = 0;
138126
for (j=0; j<survivors; j++) {
139127
int new_data;
140128
zip_entry_t *entry;
141129
zip_dirent_t *de;
142130

143-
if (za->progress_callback) {
144-
progress_state.start = (double)j / (double)survivors;
145-
progress_state.end = (double)(j+1) / (double)survivors;
146-
_zip_progress(za, &progress_state, 0.0);
147-
}
131+
_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j+1) / (double)survivors);
148132

149133
i = filelist[j].idx;
150134
entry = za->entry+i;
@@ -184,7 +168,7 @@ zip_close(zip_t *za)
184168
}
185169

186170
/* add_data writes dirent */
187-
if (add_data(za, zs ? zs : entry->source, de, &progress_state) < 0) {
171+
if (add_data(za, zs ? zs : entry->source, de) < 0) {
188172
error = 1;
189173
if (zs)
190174
zip_source_free(zs);
@@ -211,7 +195,7 @@ zip_close(zip_t *za)
211195
error = 1;
212196
break;
213197
}
214-
if (copy_data(za, de->comp_size, &progress_state) < 0) {
198+
if (copy_data(za, de->comp_size) < 0) {
215199
error = 1;
216200
break;
217201
}
@@ -237,9 +221,7 @@ zip_close(zip_t *za)
237221
return -1;
238222
}
239223

240-
if (za->progress_callback) {
241-
_zip_progress(za, &progress_state, 1.0);
242-
}
224+
_zip_progress_end(za->progress);
243225

244226
zip_discard(za);
245227

@@ -248,7 +230,7 @@ zip_close(zip_t *za)
248230

249231

250232
static int
251-
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, progress_state_t *progress_state)
233+
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
252234
{
253235
zip_int64_t offstart, offdata, offend, data_length;
254236
struct zip_stat st;
@@ -430,7 +412,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, progress_state_t *progr
430412
return -1;
431413
}
432414

433-
ret = copy_source(za, src_final, progress_state, data_length);
415+
ret = copy_source(za, src_final, data_length);
434416

435417
if (zip_source_stat(src_final, &st) < 0) {
436418
_zip_error_set_from_source(&za->error, src_final);
@@ -495,7 +477,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, progress_state_t *progr
495477

496478

497479
static int
498-
copy_data(zip_t *za, zip_uint64_t len, progress_state_t *progress_state)
480+
copy_data(zip_t *za, zip_uint64_t len)
499481
{
500482
zip_uint8_t buf[BUFSIZE];
501483
size_t n;
@@ -512,18 +494,16 @@ copy_data(zip_t *za, zip_uint64_t len, progress_state_t *progress_state)
512494
}
513495

514496
len -= n;
515-
516-
if (za->progress_callback) {
517-
_zip_progress(za, progress_state, (total - (double)len) / total);
518-
}
497+
498+
_zip_progress_update(za->progress, (total - (double)len) / total);
519499
}
520500

521501
return 0;
522502
}
523503

524504

525505
static int
526-
copy_source(zip_t *za, zip_source_t *src, progress_state_t *progress_state, zip_int64_t data_length)
506+
copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length)
527507
{
528508
zip_uint8_t buf[BUFSIZE];
529509
zip_int64_t n, current;
@@ -541,9 +521,9 @@ copy_source(zip_t *za, zip_source_t *src, progress_state_t *progress_state, zip_
541521
ret = -1;
542522
break;
543523
}
544-
if (n == sizeof(buf) && za->progress_callback && data_length > 0) {
524+
if (n == sizeof(buf) && za->progress && data_length > 0) {
545525
current += n;
546-
_zip_progress(za, progress_state, (double)current/(double)data_length);
526+
_zip_progress_update(za->progress, (double)current/(double)data_length);
547527
}
548528
}
549529

@@ -602,20 +582,3 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp)
602582

603583
return changed;
604584
}
605-
606-
static void
607-
_zip_progress(zip_t *za, progress_state_t *progress_state, double sub_current)
608-
{
609-
double current;
610-
611-
if (za->progress_callback == NULL) {
612-
return;
613-
}
614-
615-
current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress_state->end - progress_state->start) + progress_state->start;
616-
617-
if (current - progress_state->last_update > 0.001) {
618-
za->progress_callback(current);
619-
progress_state->last_update = current;
620-
}
621-
}

lib/zip_discard.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ zip_discard(zip_t *za)
7171
}
7272
free(za->open_source);
7373

74+
_zip_progress_free(za->progress);
75+
7476
zip_error_fini(&za->error);
7577

7678
free(za);

lib/zip_new.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ _zip_new(zip_error_t *error)
6868
za->entry = NULL;
6969
za->nopen_source = za->nopen_source_alloc = 0;
7070
za->open_source = NULL;
71-
za->progress_callback = NULL;
71+
za->progress = NULL;
7272

7373
return za;
7474
}

lib/zip_open.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,6 @@ zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
157157
}
158158
}
159159

160-
ZIP_EXTERN void
161-
zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback)
162-
{
163-
za->progress_callback = progress_callback;
164-
}
165-
166160

167161
zip_t *
168162
_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)

0 commit comments

Comments
 (0)