jdk/src/share/native/java/util/zip/zlib-1.2.5/gzlib.c
changeset 24710 c019dc4104b2
parent 24709 52f4fc801542
child 24711 796059d86950
equal deleted inserted replaced
24709:52f4fc801542 24710:c019dc4104b2
     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 /*
       
    26  * Copyright (C) 2004, 2010 Mark Adler
       
    27  * For conditions of distribution and use, see copyright notice in zlib.h
       
    28  */
       
    29 
       
    30 #include "gzguts.h"
       
    31 
       
    32 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
       
    33 #  define LSEEK lseek64
       
    34 #else
       
    35 #  define LSEEK lseek
       
    36 #endif
       
    37 
       
    38 /* Local functions */
       
    39 local void gz_reset OF((gz_statep));
       
    40 local gzFile gz_open OF((const char *, int, const char *));
       
    41 
       
    42 #if defined UNDER_CE
       
    43 
       
    44 /* Map the Windows error number in ERROR to a locale-dependent error message
       
    45    string and return a pointer to it.  Typically, the values for ERROR come
       
    46    from GetLastError.
       
    47 
       
    48    The string pointed to shall not be modified by the application, but may be
       
    49    overwritten by a subsequent call to gz_strwinerror
       
    50 
       
    51    The gz_strwinerror function does not change the current setting of
       
    52    GetLastError. */
       
    53 char ZLIB_INTERNAL *gz_strwinerror (error)
       
    54      DWORD error;
       
    55 {
       
    56     static char buf[1024];
       
    57 
       
    58     wchar_t *msgbuf;
       
    59     DWORD lasterr = GetLastError();
       
    60     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
       
    61         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
       
    62         NULL,
       
    63         error,
       
    64         0, /* Default language */
       
    65         (LPVOID)&msgbuf,
       
    66         0,
       
    67         NULL);
       
    68     if (chars != 0) {
       
    69         /* If there is an \r\n appended, zap it.  */
       
    70         if (chars >= 2
       
    71             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
       
    72             chars -= 2;
       
    73             msgbuf[chars] = 0;
       
    74         }
       
    75 
       
    76         if (chars > sizeof (buf) - 1) {
       
    77             chars = sizeof (buf) - 1;
       
    78             msgbuf[chars] = 0;
       
    79         }
       
    80 
       
    81         wcstombs(buf, msgbuf, chars + 1);
       
    82         LocalFree(msgbuf);
       
    83     }
       
    84     else {
       
    85         sprintf(buf, "unknown win32 error (%ld)", error);
       
    86     }
       
    87 
       
    88     SetLastError(lasterr);
       
    89     return buf;
       
    90 }
       
    91 
       
    92 #endif /* UNDER_CE */
       
    93 
       
    94 /* Reset gzip file state */
       
    95 local void gz_reset(state)
       
    96     gz_statep state;
       
    97 {
       
    98     if (state->mode == GZ_READ) {   /* for reading ... */
       
    99         state->have = 0;            /* no output data available */
       
   100         state->eof = 0;             /* not at end of file */
       
   101         state->how = LOOK;          /* look for gzip header */
       
   102         state->direct = 1;          /* default for empty file */
       
   103     }
       
   104     state->seek = 0;                /* no seek request pending */
       
   105     gz_error(state, Z_OK, NULL);    /* clear error */
       
   106     state->pos = 0;                 /* no uncompressed data yet */
       
   107     state->strm.avail_in = 0;       /* no input data yet */
       
   108 }
       
   109 
       
   110 /* Open a gzip file either by name or file descriptor. */
       
   111 local gzFile gz_open(path, fd, mode)
       
   112     const char *path;
       
   113     int fd;
       
   114     const char *mode;
       
   115 {
       
   116     gz_statep state;
       
   117 
       
   118     /* allocate gzFile structure to return */
       
   119     state = malloc(sizeof(gz_state));
       
   120     if (state == NULL)
       
   121         return NULL;
       
   122     state->size = 0;            /* no buffers allocated yet */
       
   123     state->want = GZBUFSIZE;    /* requested buffer size */
       
   124     state->msg = NULL;          /* no error message yet */
       
   125 
       
   126     /* interpret mode */
       
   127     state->mode = GZ_NONE;
       
   128     state->level = Z_DEFAULT_COMPRESSION;
       
   129     state->strategy = Z_DEFAULT_STRATEGY;
       
   130     while (*mode) {
       
   131         if (*mode >= '0' && *mode <= '9')
       
   132             state->level = *mode - '0';
       
   133         else
       
   134             switch (*mode) {
       
   135             case 'r':
       
   136                 state->mode = GZ_READ;
       
   137                 break;
       
   138 #ifndef NO_GZCOMPRESS
       
   139             case 'w':
       
   140                 state->mode = GZ_WRITE;
       
   141                 break;
       
   142             case 'a':
       
   143                 state->mode = GZ_APPEND;
       
   144                 break;
       
   145 #endif
       
   146             case '+':       /* can't read and write at the same time */
       
   147                 free(state);
       
   148                 return NULL;
       
   149             case 'b':       /* ignore -- will request binary anyway */
       
   150                 break;
       
   151             case 'f':
       
   152                 state->strategy = Z_FILTERED;
       
   153                 break;
       
   154             case 'h':
       
   155                 state->strategy = Z_HUFFMAN_ONLY;
       
   156                 break;
       
   157             case 'R':
       
   158                 state->strategy = Z_RLE;
       
   159                 break;
       
   160             case 'F':
       
   161                 state->strategy = Z_FIXED;
       
   162             default:        /* could consider as an error, but just ignore */
       
   163                 ;
       
   164             }
       
   165         mode++;
       
   166     }
       
   167 
       
   168     /* must provide an "r", "w", or "a" */
       
   169     if (state->mode == GZ_NONE) {
       
   170         free(state);
       
   171         return NULL;
       
   172     }
       
   173 
       
   174     /* save the path name for error messages */
       
   175     state->path = malloc(strlen(path) + 1);
       
   176     if (state->path == NULL) {
       
   177         free(state);
       
   178         return NULL;
       
   179     }
       
   180     strcpy(state->path, path);
       
   181 
       
   182     /* open the file with the appropriate mode (or just use fd) */
       
   183     state->fd = fd != -1 ? fd :
       
   184         open(path,
       
   185 #ifdef O_LARGEFILE
       
   186             O_LARGEFILE |
       
   187 #endif
       
   188 #ifdef O_BINARY
       
   189             O_BINARY |
       
   190 #endif
       
   191             (state->mode == GZ_READ ?
       
   192                 O_RDONLY :
       
   193                 (O_WRONLY | O_CREAT | (
       
   194                     state->mode == GZ_WRITE ?
       
   195                         O_TRUNC :
       
   196                         O_APPEND))),
       
   197             0666);
       
   198     if (state->fd == -1) {
       
   199         free(state->path);
       
   200         free(state);
       
   201         return NULL;
       
   202     }
       
   203     if (state->mode == GZ_APPEND)
       
   204         state->mode = GZ_WRITE;         /* simplify later checks */
       
   205 
       
   206     /* save the current position for rewinding (only if reading) */
       
   207     if (state->mode == GZ_READ) {
       
   208         state->start = LSEEK(state->fd, 0, SEEK_CUR);
       
   209         if (state->start == -1) state->start = 0;
       
   210     }
       
   211 
       
   212     /* initialize stream */
       
   213     gz_reset(state);
       
   214 
       
   215     /* return stream */
       
   216     return (gzFile)state;
       
   217 }
       
   218 
       
   219 /* -- see zlib.h -- */
       
   220 gzFile ZEXPORT gzopen(path, mode)
       
   221     const char *path;
       
   222     const char *mode;
       
   223 {
       
   224     return gz_open(path, -1, mode);
       
   225 }
       
   226 
       
   227 /* -- see zlib.h -- */
       
   228 gzFile ZEXPORT gzopen64(path, mode)
       
   229     const char *path;
       
   230     const char *mode;
       
   231 {
       
   232     return gz_open(path, -1, mode);
       
   233 }
       
   234 
       
   235 /* -- see zlib.h -- */
       
   236 gzFile ZEXPORT gzdopen(fd, mode)
       
   237     int fd;
       
   238     const char *mode;
       
   239 {
       
   240     char *path;         /* identifier for error messages */
       
   241     gzFile gz;
       
   242 
       
   243     if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
       
   244         return NULL;
       
   245     sprintf(path, "<fd:%d>", fd);   /* for debugging */
       
   246     gz = gz_open(path, fd, mode);
       
   247     free(path);
       
   248     return gz;
       
   249 }
       
   250 
       
   251 /* -- see zlib.h -- */
       
   252 int ZEXPORT gzbuffer(file, size)
       
   253     gzFile file;
       
   254     unsigned size;
       
   255 {
       
   256     gz_statep state;
       
   257 
       
   258     /* get internal structure and check integrity */
       
   259     if (file == NULL)
       
   260         return -1;
       
   261     state = (gz_statep)file;
       
   262     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   263         return -1;
       
   264 
       
   265     /* make sure we haven't already allocated memory */
       
   266     if (state->size != 0)
       
   267         return -1;
       
   268 
       
   269     /* check and set requested size */
       
   270     if (size == 0)
       
   271         return -1;
       
   272     state->want = size;
       
   273     return 0;
       
   274 }
       
   275 
       
   276 /* -- see zlib.h -- */
       
   277 int ZEXPORT gzrewind(file)
       
   278     gzFile file;
       
   279 {
       
   280     gz_statep state;
       
   281 
       
   282     /* get internal structure */
       
   283     if (file == NULL)
       
   284         return -1;
       
   285     state = (gz_statep)file;
       
   286 
       
   287     /* check that we're reading and that there's no error */
       
   288     if (state->mode != GZ_READ || state->err != Z_OK)
       
   289         return -1;
       
   290 
       
   291     /* back up and start over */
       
   292     if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
       
   293         return -1;
       
   294     gz_reset(state);
       
   295     return 0;
       
   296 }
       
   297 
       
   298 /* -- see zlib.h -- */
       
   299 z_off64_t ZEXPORT gzseek64(file, offset, whence)
       
   300     gzFile file;
       
   301     z_off64_t offset;
       
   302     int whence;
       
   303 {
       
   304     unsigned n;
       
   305     z_off64_t ret;
       
   306     gz_statep state;
       
   307 
       
   308     /* get internal structure and check integrity */
       
   309     if (file == NULL)
       
   310         return -1;
       
   311     state = (gz_statep)file;
       
   312     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   313         return -1;
       
   314 
       
   315     /* check that there's no error */
       
   316     if (state->err != Z_OK)
       
   317         return -1;
       
   318 
       
   319     /* can only seek from start or relative to current position */
       
   320     if (whence != SEEK_SET && whence != SEEK_CUR)
       
   321         return -1;
       
   322 
       
   323     /* normalize offset to a SEEK_CUR specification */
       
   324     if (whence == SEEK_SET)
       
   325         offset -= state->pos;
       
   326     else if (state->seek)
       
   327         offset += state->skip;
       
   328     state->seek = 0;
       
   329 
       
   330     /* if within raw area while reading, just go there */
       
   331     if (state->mode == GZ_READ && state->how == COPY &&
       
   332         state->pos + offset >= state->raw) {
       
   333         ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
       
   334         if (ret == -1)
       
   335             return -1;
       
   336         state->have = 0;
       
   337         state->eof = 0;
       
   338         state->seek = 0;
       
   339         gz_error(state, Z_OK, NULL);
       
   340         state->strm.avail_in = 0;
       
   341         state->pos += offset;
       
   342         return state->pos;
       
   343     }
       
   344 
       
   345     /* calculate skip amount, rewinding if needed for back seek when reading */
       
   346     if (offset < 0) {
       
   347         if (state->mode != GZ_READ)         /* writing -- can't go backwards */
       
   348             return -1;
       
   349         offset += state->pos;
       
   350         if (offset < 0)                     /* before start of file! */
       
   351             return -1;
       
   352         if (gzrewind(file) == -1)           /* rewind, then skip to offset */
       
   353             return -1;
       
   354     }
       
   355 
       
   356     /* if reading, skip what's in output buffer (one less gzgetc() check) */
       
   357     if (state->mode == GZ_READ) {
       
   358         n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
       
   359             (unsigned)offset : state->have;
       
   360         state->have -= n;
       
   361         state->next += n;
       
   362         state->pos += n;
       
   363         offset -= n;
       
   364     }
       
   365 
       
   366     /* request skip (if not zero) */
       
   367     if (offset) {
       
   368         state->seek = 1;
       
   369         state->skip = offset;
       
   370     }
       
   371     return state->pos + offset;
       
   372 }
       
   373 
       
   374 /* -- see zlib.h -- */
       
   375 z_off_t ZEXPORT gzseek(file, offset, whence)
       
   376     gzFile file;
       
   377     z_off_t offset;
       
   378     int whence;
       
   379 {
       
   380     z_off64_t ret;
       
   381 
       
   382     ret = gzseek64(file, (z_off64_t)offset, whence);
       
   383     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
       
   384 }
       
   385 
       
   386 /* -- see zlib.h -- */
       
   387 z_off64_t ZEXPORT gztell64(file)
       
   388     gzFile file;
       
   389 {
       
   390     gz_statep state;
       
   391 
       
   392     /* get internal structure and check integrity */
       
   393     if (file == NULL)
       
   394         return -1;
       
   395     state = (gz_statep)file;
       
   396     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   397         return -1;
       
   398 
       
   399     /* return position */
       
   400     return state->pos + (state->seek ? state->skip : 0);
       
   401 }
       
   402 
       
   403 /* -- see zlib.h -- */
       
   404 z_off_t ZEXPORT gztell(file)
       
   405     gzFile file;
       
   406 {
       
   407     z_off64_t ret;
       
   408 
       
   409     ret = gztell64(file);
       
   410     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
       
   411 }
       
   412 
       
   413 /* -- see zlib.h -- */
       
   414 z_off64_t ZEXPORT gzoffset64(file)
       
   415     gzFile file;
       
   416 {
       
   417     z_off64_t offset;
       
   418     gz_statep state;
       
   419 
       
   420     /* get internal structure and check integrity */
       
   421     if (file == NULL)
       
   422         return -1;
       
   423     state = (gz_statep)file;
       
   424     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   425         return -1;
       
   426 
       
   427     /* compute and return effective offset in file */
       
   428     offset = LSEEK(state->fd, 0, SEEK_CUR);
       
   429     if (offset == -1)
       
   430         return -1;
       
   431     if (state->mode == GZ_READ)             /* reading */
       
   432         offset -= state->strm.avail_in;     /* don't count buffered input */
       
   433     return offset;
       
   434 }
       
   435 
       
   436 /* -- see zlib.h -- */
       
   437 z_off_t ZEXPORT gzoffset(file)
       
   438     gzFile file;
       
   439 {
       
   440     z_off64_t ret;
       
   441 
       
   442     ret = gzoffset64(file);
       
   443     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
       
   444 }
       
   445 
       
   446 /* -- see zlib.h -- */
       
   447 int ZEXPORT gzeof(file)
       
   448     gzFile file;
       
   449 {
       
   450     gz_statep state;
       
   451 
       
   452     /* get internal structure and check integrity */
       
   453     if (file == NULL)
       
   454         return 0;
       
   455     state = (gz_statep)file;
       
   456     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   457         return 0;
       
   458 
       
   459     /* return end-of-file state */
       
   460     return state->mode == GZ_READ ?
       
   461         (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
       
   462 }
       
   463 
       
   464 /* -- see zlib.h -- */
       
   465 const char * ZEXPORT gzerror(file, errnum)
       
   466     gzFile file;
       
   467     int *errnum;
       
   468 {
       
   469     gz_statep state;
       
   470 
       
   471     /* get internal structure and check integrity */
       
   472     if (file == NULL)
       
   473         return NULL;
       
   474     state = (gz_statep)file;
       
   475     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   476         return NULL;
       
   477 
       
   478     /* return error information */
       
   479     if (errnum != NULL)
       
   480         *errnum = state->err;
       
   481     return state->msg == NULL ? "" : state->msg;
       
   482 }
       
   483 
       
   484 /* -- see zlib.h -- */
       
   485 void ZEXPORT gzclearerr(file)
       
   486     gzFile file;
       
   487 {
       
   488     gz_statep state;
       
   489 
       
   490     /* get internal structure and check integrity */
       
   491     if (file == NULL)
       
   492         return;
       
   493     state = (gz_statep)file;
       
   494     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
       
   495         return;
       
   496 
       
   497     /* clear error and end-of-file */
       
   498     if (state->mode == GZ_READ)
       
   499         state->eof = 0;
       
   500     gz_error(state, Z_OK, NULL);
       
   501 }
       
   502 
       
   503 /* Create an error message in allocated memory and set state->err and
       
   504    state->msg accordingly.  Free any previous error message already there.  Do
       
   505    not try to free or allocate space if the error is Z_MEM_ERROR (out of
       
   506    memory).  Simply save the error message as a static string.  If there is an
       
   507    allocation failure constructing the error message, then convert the error to
       
   508    out of memory. */
       
   509 void ZLIB_INTERNAL gz_error(state, err, msg)
       
   510     gz_statep state;
       
   511     int err;
       
   512     const char *msg;
       
   513 {
       
   514     /* free previously allocated message and clear */
       
   515     if (state->msg != NULL) {
       
   516         if (state->err != Z_MEM_ERROR)
       
   517             free(state->msg);
       
   518         state->msg = NULL;
       
   519     }
       
   520 
       
   521     /* set error code, and if no message, then done */
       
   522     state->err = err;
       
   523     if (msg == NULL)
       
   524         return;
       
   525 
       
   526     /* for an out of memory error, save as static string */
       
   527     if (err == Z_MEM_ERROR) {
       
   528         state->msg = (char *)msg;
       
   529         return;
       
   530     }
       
   531 
       
   532     /* construct error message with path */
       
   533     if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
       
   534         state->err = Z_MEM_ERROR;
       
   535         state->msg = (char *)"out of memory";
       
   536         return;
       
   537     }
       
   538     strcpy(state->msg, state->path);
       
   539     strcat(state->msg, ": ");
       
   540     strcat(state->msg, msg);
       
   541     return;
       
   542 }
       
   543 
       
   544 #ifndef INT_MAX
       
   545 /* portably return maximum value for an int (when limits.h presumed not
       
   546    available) -- we need to do this to cover cases where 2's complement not
       
   547    used, since C standard permits 1's complement and sign-bit representations,
       
   548    otherwise we could just use ((unsigned)-1) >> 1 */
       
   549 unsigned ZLIB_INTERNAL gz_intmax()
       
   550 {
       
   551     unsigned p, q;
       
   552 
       
   553     p = 1;
       
   554     do {
       
   555         q = p;
       
   556         p <<= 1;
       
   557         p++;
       
   558     } while (p > q);
       
   559     return q >> 1;
       
   560 }
       
   561 #endif