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