"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/zlib/gzwrite.c" (10 Oct 2018, 19253 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


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 "gzwrite.c" see the Fossies "Dox" file reference documentation.

    1 /* gzwrite.c -- zlib functions for writing gzip files
    2  * Copyright (C) 2004-2017 Mark Adler
    3  * For conditions of distribution and use, see copyright notice in zlib.h
    4  */
    5 
    6 #include "gzguts.h"
    7 
    8 /* Local functions */
    9 local int gz_init OF((gz_statep));
   10 local int gz_comp OF((gz_statep, int));
   11 local int gz_zero OF((gz_statep, z_off64_t));
   12 local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
   13 
   14 /* Initialize state for writing a gzip file.  Mark initialization by setting
   15    state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on
   16    success. */
   17 local int gz_init(state)
   18     gz_statep state;
   19 {
   20     int ret;
   21     z_streamp strm = &(state->strm);
   22 
   23     /* allocate input buffer (double size for gzprintf) */
   24     state->in = (unsigned char *)malloc(state->want << 1);
   25     if (state->in == NULL) {
   26         gz_error(state, Z_MEM_ERROR, "out of memory");
   27         return -1;
   28     }
   29 
   30     /* only need output buffer and deflate state if compressing */
   31     if (!state->direct) {
   32         /* allocate output buffer */
   33         state->out = (unsigned char *)malloc(state->want);
   34         if (state->out == NULL) {
   35             free(state->in);
   36             gz_error(state, Z_MEM_ERROR, "out of memory");
   37             return -1;
   38         }
   39 
   40         /* allocate deflate memory, set up for gzip compression */
   41         strm->zalloc = Z_NULL;
   42         strm->zfree = Z_NULL;
   43         strm->opaque = Z_NULL;
   44         ret = deflateInit2(strm, state->level, Z_DEFLATED,
   45                            MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
   46         if (ret != Z_OK) {
   47             free(state->out);
   48             free(state->in);
   49             gz_error(state, Z_MEM_ERROR, "out of memory");
   50             return -1;
   51         }
   52         strm->next_in = NULL;
   53     }
   54 
   55     /* mark state as initialized */
   56     state->size = state->want;
   57 
   58     /* initialize write buffer if compressing */
   59     if (!state->direct) {
   60         strm->avail_out = state->size;
   61         strm->next_out = state->out;
   62         state->x.next = strm->next_out;
   63     }
   64     return 0;
   65 }
   66 
   67 /* Compress whatever is at avail_in and next_in and write to the output file.
   68    Return -1 if there is an error writing to the output file or if gz_init()
   69    fails to allocate memory, otherwise 0.  flush is assumed to be a valid
   70    deflate() flush value.  If flush is Z_FINISH, then the deflate() state is
   71    reset to start a new gzip stream.  If gz->direct is true, then simply write
   72    to the output file without compressing, and ignore flush. */
   73 local int gz_comp(state, flush)
   74     gz_statep state;
   75     int flush;
   76 {
   77     int ret, writ;
   78     unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
   79     z_streamp strm = &(state->strm);
   80 
   81     /* allocate memory if this is the first time through */
   82     if (state->size == 0 && gz_init(state) == -1)
   83         return -1;
   84 
   85     /* write directly if requested */
   86     if (state->direct) {
   87         while (strm->avail_in) {
   88             put = strm->avail_in > max ? max : strm->avail_in;
   89             writ = write(state->fd, strm->next_in, put);
   90             if (writ < 0) {
   91                 gz_error(state, Z_ERRNO, zstrerror());
   92                 return -1;
   93             }
   94             strm->avail_in -= (unsigned)writ;
   95             strm->next_in += writ;
   96         }
   97         return 0;
   98     }
   99 
  100     /* run deflate() on provided input until it produces no more output */
  101     ret = Z_OK;
  102     do {
  103         /* write out current buffer contents if full, or if flushing, but if
  104            doing Z_FINISH then don't write until we get to Z_STREAM_END */
  105         if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
  106             (flush != Z_FINISH || ret == Z_STREAM_END))) {
  107             while (strm->next_out > state->x.next) {
  108                 put = strm->next_out - state->x.next > (int)max ? max :
  109                       (unsigned)(strm->next_out - state->x.next);
  110                 writ = write(state->fd, state->x.next, put);
  111                 if (writ < 0) {
  112                     gz_error(state, Z_ERRNO, zstrerror());
  113                     return -1;
  114                 }
  115                 state->x.next += writ;
  116             }
  117             if (strm->avail_out == 0) {
  118                 strm->avail_out = state->size;
  119                 strm->next_out = state->out;
  120                 state->x.next = state->out;
  121             }
  122         }
  123 
  124         /* compress */
  125         have = strm->avail_out;
  126         ret = deflate(strm, flush);
  127         if (ret == Z_STREAM_ERROR) {
  128             gz_error(state, Z_STREAM_ERROR,
  129                       "internal error: deflate stream corrupt");
  130             return -1;
  131         }
  132         have -= strm->avail_out;
  133     } while (have);
  134 
  135     /* if that completed a deflate stream, allow another to start */
  136     if (flush == Z_FINISH)
  137         deflateReset(strm);
  138 
  139     /* all done, no errors */
  140     return 0;
  141 }
  142 
  143 /* Compress len zeros to output.  Return -1 on a write error or memory
  144    allocation failure by gz_comp(), or 0 on success. */
  145 local int gz_zero(state, len)
  146     gz_statep state;
  147     z_off64_t len;
  148 {
  149     int first;
  150     unsigned n;
  151     z_streamp strm = &(state->strm);
  152 
  153     /* consume whatever's left in the input buffer */
  154     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
  155         return -1;
  156 
  157     /* compress len zeros (len guaranteed > 0) */
  158     first = 1;
  159     while (len) {
  160         n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
  161             (unsigned)len : state->size;
  162         if (first) {
  163             memset(state->in, 0, n);
  164             first = 0;
  165         }
  166         strm->avail_in = n;
  167         strm->next_in = state->in;
  168         state->x.pos += n;
  169         if (gz_comp(state, Z_NO_FLUSH) == -1)
  170             return -1;
  171         len -= n;
  172     }
  173     return 0;
  174 }
  175 
  176 /* Write len bytes from buf to file.  Return the number of bytes written.  If
  177    the returned value is less than len, then there was an error. */
  178 local z_size_t gz_write(state, buf, len)
  179     gz_statep state;
  180     voidpc buf;
  181     z_size_t len;
  182 {
  183     z_size_t put = len;
  184 
  185     /* if len is zero, avoid unnecessary operations */
  186     if (len == 0)
  187         return 0;
  188 
  189     /* allocate memory if this is the first time through */
  190     if (state->size == 0 && gz_init(state) == -1)
  191         return 0;
  192 
  193     /* check for seek request */
  194     if (state->seek) {
  195         state->seek = 0;
  196         if (gz_zero(state, state->skip) == -1)
  197             return 0;
  198     }
  199 
  200     /* for small len, copy to input buffer, otherwise compress directly */
  201     if (len < state->size) {
  202         /* copy to input buffer, compress when full */
  203         do {
  204             unsigned have, copy;
  205 
  206             if (state->strm.avail_in == 0)
  207                 state->strm.next_in = state->in;
  208             have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
  209                               state->in);
  210             copy = state->size - have;
  211             if (copy > len)
  212                 copy = len;
  213             memcpy(state->in + have, buf, copy);
  214             state->strm.avail_in += copy;
  215             state->x.pos += copy;
  216             buf = (const char *)buf + copy;
  217             len -= copy;
  218             if (len && gz_comp(state, Z_NO_FLUSH) == -1)
  219                 return 0;
  220         } while (len);
  221     }
  222     else {
  223         /* consume whatever's left in the input buffer */
  224         if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
  225             return 0;
  226 
  227         /* directly compress user buffer to file */
  228         state->strm.next_in = (z_const Bytef *)buf;
  229         do {
  230             unsigned n = (unsigned)-1;
  231             if (n > len)
  232                 n = len;
  233             state->strm.avail_in = n;
  234             state->x.pos += n;
  235             if (gz_comp(state, Z_NO_FLUSH) == -1)
  236                 return 0;
  237             len -= n;
  238         } while (len);
  239     }
  240 
  241     /* input was all buffered or compressed */
  242     return put;
  243 }
  244 
  245 /* -- see zlib.h -- */
  246 int ZEXPORT gzwrite(file, buf, len)
  247     gzFile file;
  248     voidpc buf;
  249     unsigned len;
  250 {
  251     gz_statep state;
  252 
  253     /* get internal structure */
  254     if (file == NULL)
  255         return 0;
  256     state = (gz_statep)file;
  257 
  258     /* check that we're writing and that there's no error */
  259     if (state->mode != GZ_WRITE || state->err != Z_OK)
  260         return 0;
  261 
  262     /* since an int is returned, make sure len fits in one, otherwise return
  263        with an error (this avoids a flaw in the interface) */
  264     if ((int)len < 0) {
  265         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
  266         return 0;
  267     }
  268 
  269     /* write len bytes from buf (the return value will fit in an int) */
  270     return (int)gz_write(state, buf, len);
  271 }
  272 
  273 /* -- see zlib.h -- */
  274 z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
  275     voidpc buf;
  276     z_size_t size;
  277     z_size_t nitems;
  278     gzFile file;
  279 {
  280     z_size_t len;
  281     gz_statep state;
  282 
  283     /* get internal structure */
  284     if (file == NULL)
  285         return 0;
  286     state = (gz_statep)file;
  287 
  288     /* check that we're writing and that there's no error */
  289     if (state->mode != GZ_WRITE || state->err != Z_OK)
  290         return 0;
  291 
  292     /* compute bytes to read -- error on overflow */
  293     len = nitems * size;
  294     if (size && len / size != nitems) {
  295         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
  296         return 0;
  297     }
  298 
  299     /* write len bytes to buf, return the number of full items written */
  300     return len ? gz_write(state, buf, len) / size : 0;
  301 }
  302 
  303 /* -- see zlib.h -- */
  304 int ZEXPORT gzputc(file, c)
  305     gzFile file;
  306     int c;
  307 {
  308     unsigned have;
  309     unsigned char buf[1];
  310     gz_statep state;
  311     z_streamp strm;
  312 
  313     /* get internal structure */
  314     if (file == NULL)
  315         return -1;
  316     state = (gz_statep)file;
  317     strm = &(state->strm);
  318 
  319     /* check that we're writing and that there's no error */
  320     if (state->mode != GZ_WRITE || state->err != Z_OK)
  321         return -1;
  322 
  323     /* check for seek request */
  324     if (state->seek) {
  325         state->seek = 0;
  326         if (gz_zero(state, state->skip) == -1)
  327             return -1;
  328     }
  329 
  330     /* try writing to input buffer for speed (state->size == 0 if buffer not
  331        initialized) */
  332     if (state->size) {
  333         if (strm->avail_in == 0)
  334             strm->next_in = state->in;
  335         have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
  336         if (have < state->size) {
  337             state->in[have] = (unsigned char)c;
  338             strm->avail_in++;
  339             state->x.pos++;
  340             return c & 0xff;
  341         }
  342     }
  343 
  344     /* no room in buffer or not initialized, use gz_write() */
  345     buf[0] = (unsigned char)c;
  346     if (gz_write(state, buf, 1) != 1)
  347         return -1;
  348     return c & 0xff;
  349 }
  350 
  351 /* -- see zlib.h -- */
  352 int ZEXPORT gzputs(file, str)
  353     gzFile file;
  354     const char *str;
  355 {
  356     int ret;
  357     z_size_t len;
  358     gz_statep state;
  359 
  360     /* get internal structure */
  361     if (file == NULL)
  362         return -1;
  363     state = (gz_statep)file;
  364 
  365     /* check that we're writing and that there's no error */
  366     if (state->mode != GZ_WRITE || state->err != Z_OK)
  367         return -1;
  368 
  369     /* write string */
  370     len = strlen(str);
  371     ret = gz_write(state, str, len);
  372     return ret == 0 && len != 0 ? -1 : ret;
  373 }
  374 
  375 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
  376 #include <stdarg.h>
  377 
  378 /* -- see zlib.h -- */
  379 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
  380 {
  381     int len;
  382     unsigned left;
  383     char *next;
  384     gz_statep state;
  385     z_streamp strm;
  386 
  387     /* get internal structure */
  388     if (file == NULL)
  389         return Z_STREAM_ERROR;
  390     state = (gz_statep)file;
  391     strm = &(state->strm);
  392 
  393     /* check that we're writing and that there's no error */
  394     if (state->mode != GZ_WRITE || state->err != Z_OK)
  395         return Z_STREAM_ERROR;
  396 
  397     /* make sure we have some buffer space */
  398     if (state->size == 0 && gz_init(state) == -1)
  399         return state->err;
  400 
  401     /* check for seek request */
  402     if (state->seek) {
  403         state->seek = 0;
  404         if (gz_zero(state, state->skip) == -1)
  405             return state->err;
  406     }
  407 
  408     /* do the printf() into the input buffer, put length in len -- the input
  409        buffer is double-sized just for this function, so there is guaranteed to
  410        be state->size bytes available after the current contents */
  411     if (strm->avail_in == 0)
  412         strm->next_in = state->in;
  413     next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
  414     next[state->size - 1] = 0;
  415 #ifdef NO_vsnprintf
  416 #  ifdef HAS_vsprintf_void
  417     (void)vsprintf(next, format, va);
  418     for (len = 0; len < state->size; len++)
  419         if (next[len] == 0) break;
  420 #  else
  421     len = vsprintf(next, format, va);
  422 #  endif
  423 #else
  424 #  ifdef HAS_vsnprintf_void
  425     (void)vsnprintf(next, state->size, format, va);
  426     len = strlen(next);
  427 #  else
  428     len = vsnprintf(next, state->size, format, va);
  429 #  endif
  430 #endif
  431 
  432     /* check that printf() results fit in buffer */
  433     if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
  434         return 0;
  435 
  436     /* update buffer and position, compress first half if past that */
  437     strm->avail_in += (unsigned)len;
  438     state->x.pos += len;
  439     if (strm->avail_in >= state->size) {
  440         left = strm->avail_in - state->size;
  441         strm->avail_in = state->size;
  442         if (gz_comp(state, Z_NO_FLUSH) == -1)
  443             return state->err;
  444         memcpy(state->in, state->in + state->size, left);
  445         strm->next_in = state->in;
  446         strm->avail_in = left;
  447     }
  448     return len;
  449 }
  450 
  451 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
  452 {
  453     va_list va;
  454     int ret;
  455 
  456     va_start(va, format);
  457     ret = gzvprintf(file, format, va);
  458     va_end(va);
  459     return ret;
  460 }
  461 
  462 #else /* !STDC && !Z_HAVE_STDARG_H */
  463 
  464 /* -- see zlib.h -- */
  465 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
  466                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
  467     gzFile file;
  468     const char *format;
  469     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
  470         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
  471 {
  472     unsigned len, left;
  473     char *next;
  474     gz_statep state;
  475     z_streamp strm;
  476 
  477     /* get internal structure */
  478     if (file == NULL)
  479         return Z_STREAM_ERROR;
  480     state = (gz_statep)file;
  481     strm = &(state->strm);
  482 
  483     /* check that can really pass pointer in ints */
  484     if (sizeof(int) != sizeof(void *))
  485         return Z_STREAM_ERROR;
  486 
  487     /* check that we're writing and that there's no error */
  488     if (state->mode != GZ_WRITE || state->err != Z_OK)
  489         return Z_STREAM_ERROR;
  490 
  491     /* make sure we have some buffer space */
  492     if (state->size == 0 && gz_init(state) == -1)
  493         return state->error;
  494 
  495     /* check for seek request */
  496     if (state->seek) {
  497         state->seek = 0;
  498         if (gz_zero(state, state->skip) == -1)
  499             return state->error;
  500     }
  501 
  502     /* do the printf() into the input buffer, put length in len -- the input
  503        buffer is double-sized just for this function, so there is guaranteed to
  504        be state->size bytes available after the current contents */
  505     if (strm->avail_in == 0)
  506         strm->next_in = state->in;
  507     next = (char *)(strm->next_in + strm->avail_in);
  508     next[state->size - 1] = 0;
  509 #ifdef NO_snprintf
  510 #  ifdef HAS_sprintf_void
  511     sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
  512             a13, a14, a15, a16, a17, a18, a19, a20);
  513     for (len = 0; len < size; len++)
  514         if (next[len] == 0)
  515             break;
  516 #  else
  517     len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
  518                   a12, a13, a14, a15, a16, a17, a18, a19, a20);
  519 #  endif
  520 #else
  521 #  ifdef HAS_snprintf_void
  522     snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
  523              a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
  524     len = strlen(next);
  525 #  else
  526     len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
  527                    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
  528 #  endif
  529 #endif
  530 
  531     /* check that printf() results fit in buffer */
  532     if (len == 0 || len >= state->size || next[state->size - 1] != 0)
  533         return 0;
  534 
  535     /* update buffer and position, compress first half if past that */
  536     strm->avail_in += len;
  537     state->x.pos += len;
  538     if (strm->avail_in >= state->size) {
  539         left = strm->avail_in - state->size;
  540         strm->avail_in = state->size;
  541         if (gz_comp(state, Z_NO_FLUSH) == -1)
  542             return state->err;
  543         memcpy(state->in, state->in + state->size, left);
  544         strm->next_in = state->in;
  545         strm->avail_in = left;
  546     }
  547     return (int)len;
  548 }
  549 
  550 #endif
  551 
  552 /* -- see zlib.h -- */
  553 int ZEXPORT gzflush(file, flush)
  554     gzFile file;
  555     int flush;
  556 {
  557     gz_statep state;
  558 
  559     /* get internal structure */
  560     if (file == NULL)
  561         return Z_STREAM_ERROR;
  562     state = (gz_statep)file;
  563 
  564     /* check that we're writing and that there's no error */
  565     if (state->mode != GZ_WRITE || state->err != Z_OK)
  566         return Z_STREAM_ERROR;
  567 
  568     /* check flush parameter */
  569     if (flush < 0 || flush > Z_FINISH)
  570         return Z_STREAM_ERROR;
  571 
  572     /* check for seek request */
  573     if (state->seek) {
  574         state->seek = 0;
  575         if (gz_zero(state, state->skip) == -1)
  576             return state->err;
  577     }
  578 
  579     /* compress remaining data with requested flush */
  580     (void)gz_comp(state, flush);
  581     return state->err;
  582 }
  583 
  584 /* -- see zlib.h -- */
  585 int ZEXPORT gzsetparams(file, level, strategy)
  586     gzFile file;
  587     int level;
  588     int strategy;
  589 {
  590     gz_statep state;
  591     z_streamp strm;
  592 
  593     /* get internal structure */
  594     if (file == NULL)
  595         return Z_STREAM_ERROR;
  596     state = (gz_statep)file;
  597     strm = &(state->strm);
  598 
  599     /* check that we're writing and that there's no error */
  600     if (state->mode != GZ_WRITE || state->err != Z_OK)
  601         return Z_STREAM_ERROR;
  602 
  603     /* if no change is requested, then do nothing */
  604     if (level == state->level && strategy == state->strategy)
  605         return Z_OK;
  606 
  607     /* check for seek request */
  608     if (state->seek) {
  609         state->seek = 0;
  610         if (gz_zero(state, state->skip) == -1)
  611             return state->err;
  612     }
  613 
  614     /* change compression parameters for subsequent input */
  615     if (state->size) {
  616         /* flush previous input with previous parameters before changing */
  617         if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
  618             return state->err;
  619         deflateParams(strm, level, strategy);
  620     }
  621     state->level = level;
  622     state->strategy = strategy;
  623     return Z_OK;
  624 }
  625 
  626 /* -- see zlib.h -- */
  627 int ZEXPORT gzclose_w(file)
  628     gzFile file;
  629 {
  630     int ret = Z_OK;
  631     gz_statep state;
  632 
  633     /* get internal structure */
  634     if (file == NULL)
  635         return Z_STREAM_ERROR;
  636     state = (gz_statep)file;
  637 
  638     /* check that we're writing */
  639     if (state->mode != GZ_WRITE)
  640         return Z_STREAM_ERROR;
  641 
  642     /* check for seek request */
  643     if (state->seek) {
  644         state->seek = 0;
  645         if (gz_zero(state, state->skip) == -1)
  646             ret = state->err;
  647     }
  648 
  649     /* flush, free memory, and close file */
  650     if (gz_comp(state, Z_FINISH) == -1)
  651         ret = state->err;
  652     if (state->size) {
  653         if (!state->direct) {
  654             (void)deflateEnd(&(state->strm));
  655             free(state->out);
  656         }
  657         free(state->in);
  658     }
  659     gz_error(state, Z_OK, NULL);
  660     free(state->path);
  661     if (close(state->fd) == -1)
  662         ret = Z_ERRNO;
  663     free(state);
  664     return ret;
  665 }