"Fossies" - the Fresh Open Source Software Archive

Member "muscle/zlib/zlib/gzwrite.c" (21 Nov 2020, 19298 Bytes) of package /linux/privat/muscle7.62.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 and the latest Fossies "Diffs" side-by-side code changes report: 7.61_vs_7.62.

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