"Fossies" - the Fresh Open Source Software Archive

Member "libzip-1.6.0/lib/zip_progress.c" (24 Jan 2020, 8059 Bytes) of package /linux/misc/libzip-1.6.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zip_progress.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.2_vs_1.6.0.

    1 /*
    2  zip_progress.c -- progress reporting
    3  Copyright (C) 2017-2020 Dieter Baron and Thomas Klausner
    4 
    5  This file is part of libzip, a library to manipulate ZIP archives.
    6  The authors can be contacted at <libzip@nih.at>
    7 
    8  Redistribution and use in source and binary forms, with or without
    9  modification, are permitted provided that the following conditions
   10  are met:
   11  1. Redistributions of source code must retain the above copyright
   12  notice, this list of conditions and the following disclaimer.
   13  2. Redistributions in binary form must reproduce the above copyright
   14  notice, this list of conditions and the following disclaimer in
   15  the documentation and/or other materials provided with the
   16  distribution.
   17  3. The names of the authors may not be used to endorse or promote
   18  products derived from this software without specific prior
   19  written permission.
   20 
   21  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
   22  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
   25  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   27  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   30  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   31  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 
   35 #include <stdlib.h>
   36 
   37 
   38 #define _ZIP_COMPILING_DEPRECATED
   39 #include "zipint.h"
   40 
   41 struct zip_progress {
   42     zip_t *za;
   43 
   44     zip_progress_callback callback_progress;
   45     void (*ud_progress_free)(void *);
   46     void *ud_progress;
   47 
   48     zip_cancel_callback callback_cancel;
   49     void (*ud_cancel_free)(void *);
   50     void *ud_cancel;
   51 
   52     double precision;
   53 
   54     /* state */
   55     double last_update; /* last value callback function was called with */
   56 
   57     double start; /* start of sub-progress section */
   58     double end;   /* end of sub-progress section */
   59 };
   60 
   61 static void _zip_progress_free_cancel_callback(zip_progress_t *progress);
   62 static void _zip_progress_free_progress_callback(zip_progress_t *progress);
   63 static zip_progress_t *_zip_progress_new(zip_t *za);
   64 static void _zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud);
   65 static void _zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud);
   66 
   67 void
   68 _zip_progress_end(zip_progress_t *progress) {
   69     _zip_progress_update(progress, 1.0);
   70 }
   71 
   72 
   73 void
   74 _zip_progress_free(zip_progress_t *progress) {
   75     if (progress == NULL) {
   76     return;
   77     }
   78 
   79     _zip_progress_free_progress_callback(progress);
   80     _zip_progress_free_cancel_callback(progress);
   81 
   82     free(progress);
   83 }
   84 
   85 
   86 static zip_progress_t *
   87 _zip_progress_new(zip_t *za) {
   88     zip_progress_t *progress = (zip_progress_t *)malloc(sizeof(*progress));
   89 
   90     if (progress == NULL) {
   91     zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
   92     return NULL;
   93     }
   94 
   95     progress->za = za;
   96 
   97     progress->callback_progress = NULL;
   98     progress->ud_progress_free = NULL;
   99     progress->ud_progress = NULL;
  100     progress->precision = 0.0;
  101 
  102     progress->callback_cancel = NULL;
  103     progress->ud_cancel_free = NULL;
  104     progress->ud_cancel = NULL;
  105 
  106     return progress;
  107 }
  108 
  109 static void
  110 _zip_progress_free_progress_callback(zip_progress_t *progress) {
  111     if (progress->ud_progress_free) {
  112     progress->ud_progress_free(progress->ud_progress);
  113     }
  114 
  115     progress->callback_progress = NULL;
  116     progress->ud_progress = NULL;
  117     progress->ud_progress_free = NULL;
  118 }
  119 
  120 static void
  121 _zip_progress_free_cancel_callback(zip_progress_t *progress) {
  122     if (progress->ud_cancel_free) {
  123     progress->ud_cancel_free(progress->ud_cancel);
  124     }
  125 
  126     progress->callback_cancel = NULL;
  127     progress->ud_cancel = NULL;
  128     progress->ud_cancel_free = NULL;
  129 }
  130 
  131 static void
  132 _zip_progress_set_progress_callback(zip_progress_t *progress, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
  133     _zip_progress_free_progress_callback(progress);
  134 
  135     progress->callback_progress = callback;
  136     progress->ud_progress_free = ud_free;
  137     progress->ud_progress = ud;
  138     progress->precision = precision;
  139 }
  140 
  141 void
  142 _zip_progress_set_cancel_callback(zip_progress_t *progress, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
  143     _zip_progress_free_cancel_callback(progress);
  144 
  145     progress->callback_cancel = callback;
  146     progress->ud_cancel_free = ud_free;
  147     progress->ud_cancel = ud;
  148 }
  149 
  150 int
  151 _zip_progress_start(zip_progress_t *progress) {
  152     if (progress == NULL) {
  153     return 0;
  154     }
  155 
  156     if (progress->callback_progress != NULL) {
  157     progress->last_update = 0.0;
  158     progress->callback_progress(progress->za, 0.0, progress->ud_progress);
  159     }
  160 
  161     if (progress->callback_cancel != NULL) {
  162     if (progress->callback_cancel(progress->za, progress->ud_cancel)) {
  163         return -1;
  164     }
  165     }
  166 
  167     return 0;
  168 }
  169 
  170 
  171 int
  172 _zip_progress_subrange(zip_progress_t *progress, double start, double end) {
  173     if (progress == NULL) {
  174     return 0;
  175     }
  176 
  177     progress->start = start;
  178     progress->end = end;
  179 
  180     return _zip_progress_update(progress, 0.0);
  181 }
  182 
  183 int
  184 _zip_progress_update(zip_progress_t *progress, double sub_current) {
  185     double current;
  186 
  187     if (progress == NULL) {
  188     return 0;
  189     }
  190 
  191     if (progress->callback_progress != NULL) {
  192     current = ZIP_MIN(ZIP_MAX(sub_current, 0.0), 1.0) * (progress->end - progress->start) + progress->start;
  193 
  194     if (current - progress->last_update > progress->precision) {
  195         progress->callback_progress(progress->za, current, progress->ud_progress);
  196         progress->last_update = current;
  197     }
  198     }
  199 
  200     if (progress->callback_cancel != NULL) {
  201     if (progress->callback_cancel(progress->za, progress->ud_cancel)) {
  202         return -1;
  203     }
  204     }
  205 
  206     return 0;
  207 }
  208 
  209 
  210 ZIP_EXTERN int
  211 zip_register_progress_callback_with_state(zip_t *za, double precision, zip_progress_callback callback, void (*ud_free)(void *), void *ud) {
  212     zip_progress_t *progress = NULL;
  213 
  214     if (callback != NULL) {
  215         if (za->progress == NULL) {
  216         if ((za->progress = _zip_progress_new(za)) == NULL) {
  217         return -1;
  218         }
  219     }
  220 
  221     _zip_progress_set_progress_callback(za->progress, precision, callback, ud_free, ud);
  222     }
  223     else {
  224     if (za->progress != NULL) {
  225         if (za->progress->callback_cancel == NULL) {
  226         _zip_progress_free(za->progress);
  227         za->progress = NULL;
  228         }
  229         else {
  230         _zip_progress_free_progress_callback(za->progress);
  231         }
  232     }
  233     }
  234 
  235     return 0;
  236 }
  237 
  238 
  239 ZIP_EXTERN int
  240 zip_register_cancel_callback_with_state(zip_t *za, zip_cancel_callback callback, void (*ud_free)(void *), void *ud) {
  241     zip_progress_t *progress = NULL;
  242 
  243     if (callback != NULL) {
  244         if (za->progress == NULL) {
  245         if ((za->progress = _zip_progress_new(za)) == NULL) {
  246         return -1;
  247         }
  248     }
  249 
  250     _zip_progress_set_cancel_callback(za->progress, callback, ud_free, ud);
  251     }
  252     else {
  253     if (za->progress != NULL) {
  254         if (za->progress->callback_progress == NULL) {
  255         _zip_progress_free(za->progress);
  256         za->progress = NULL;
  257         }
  258         else {
  259         _zip_progress_free_cancel_callback(za->progress);
  260         }
  261     }
  262     }
  263 
  264     return 0;
  265 }
  266 
  267 
  268 struct legacy_ud {
  269     zip_progress_callback_t callback;
  270 };
  271 
  272 
  273 static void
  274 _zip_legacy_progress_callback(zip_t *za, double progress, void *vud) {
  275     struct legacy_ud *ud = (struct legacy_ud *)vud;
  276 
  277     ud->callback(progress);
  278 }
  279 
  280 ZIP_EXTERN void
  281 zip_register_progress_callback(zip_t *za, zip_progress_callback_t progress_callback) {
  282     struct legacy_ud *ud;
  283 
  284     if (progress_callback == NULL) {
  285     zip_register_progress_callback_with_state(za, 0, NULL, NULL, NULL);
  286     }
  287 
  288     if ((ud = (struct legacy_ud *)malloc(sizeof(*ud))) == NULL) {
  289     return;
  290     }
  291 
  292     ud->callback = progress_callback;
  293 
  294     if (zip_register_progress_callback_with_state(za, 0.001, _zip_legacy_progress_callback, free, ud) < 0) {
  295     free(ud);
  296     }
  297 }