< prev index next >

src/java.base/share/native/libzip/zlib/gzlib.c

Print this page

  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 /* gzlib.c -- zlib functions common to reading and writing gzip files
 26  * Copyright (C) 2004-2019 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(_WIN32) && !defined(__BORLANDC__)
 33 #  define LSEEK _lseeki64
 34 #else
 35 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
 36 #  define LSEEK lseek64
 37 #else
 38 #  define LSEEK lseek
 39 #endif
 40 #endif
 41 
 42 /* Local functions */
 43 local void gz_reset OF((gz_statep));
 44 local gzFile gz_open OF((const void *, int, const char *));
 45 
 46 #if defined UNDER_CE
 47 
 48 /* Map the Windows error number in ERROR to a locale-dependent error message
 49    string and return a pointer to it.  Typically, the values for ERROR come
 50    from GetLastError.
 51 
 52    The string pointed to shall not be modified by the application, but may be
 53    overwritten by a subsequent call to gz_strwinerror
 54 
 55    The gz_strwinerror function does not change the current setting of
 56    GetLastError. */
 57 char ZLIB_INTERNAL *gz_strwinerror(error)
 58      DWORD error;
 59 {
 60     static char buf[1024];
 61 
 62     wchar_t *msgbuf;
 63     DWORD lasterr = GetLastError();
 64     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
 65         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
 66         NULL,
 67         error,
 68         0, /* Default language */
 69         (LPVOID)&msgbuf,
 70         0,
 71         NULL);
 72     if (chars != 0) {
 73         /* If there is an \r\n appended, zap it.  */
 74         if (chars >= 2
 75             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
 76             chars -= 2;
 77             msgbuf[chars] = 0;
 78         }
 79 
 80         if (chars > sizeof (buf) - 1) {
 81             chars = sizeof (buf) - 1;
 82             msgbuf[chars] = 0;
 83         }
 84 
 85         wcstombs(buf, msgbuf, chars + 1);
 86         LocalFree(msgbuf);
 87     }
 88     else {
 89         sprintf(buf, "unknown win32 error (%ld)", error);
 90     }
 91 
 92     SetLastError(lasterr);
 93     return buf;
 94 }
 95 
 96 #endif /* UNDER_CE */
 97 
 98 /* Reset gzip file state */
 99 local void gz_reset(state)
100     gz_statep state;
101 {
102     state->x.have = 0;              /* no output data available */
103     if (state->mode == GZ_READ) {   /* for reading ... */
104         state->eof = 0;             /* not at end of file */
105         state->past = 0;            /* have not read past end yet */
106         state->how = LOOK;          /* look for gzip header */
107     }
108     else                            /* for writing ... */
109         state->reset = 0;           /* no deflateReset pending */
110     state->seek = 0;                /* no seek request pending */
111     gz_error(state, Z_OK, NULL);    /* clear error */
112     state->x.pos = 0;               /* no uncompressed data yet */
113     state->strm.avail_in = 0;       /* no input data yet */
114 }
115 
116 /* Open a gzip file either by name or file descriptor. */
117 local gzFile gz_open(path, fd, mode)
118     const void *path;
119     int fd;
120     const char *mode;
121 {
122     gz_statep state;
123     z_size_t len;
124     int oflag;
125 #ifdef O_CLOEXEC
126     int cloexec = 0;
127 #endif
128 #ifdef O_EXCL
129     int exclusive = 0;
130 #endif
131 
132     /* check input */
133     if (path == NULL)
134         return NULL;
135 
136     /* allocate gzFile structure to return */
137     state = (gz_statep)malloc(sizeof(gz_state));
138     if (state == NULL)
139         return NULL;
140     state->size = 0;            /* no buffers allocated yet */
141     state->want = GZBUFSIZE;    /* requested buffer size */

276     }
277     if (state->mode == GZ_APPEND) {
278         LSEEK(state->fd, 0, SEEK_END);  /* so gzoffset() is correct */
279         state->mode = GZ_WRITE;         /* simplify later checks */
280     }
281 
282     /* save the current position for rewinding (only if reading) */
283     if (state->mode == GZ_READ) {
284         state->start = LSEEK(state->fd, 0, SEEK_CUR);
285         if (state->start == -1) state->start = 0;
286     }
287 
288     /* initialize stream */
289     gz_reset(state);
290 
291     /* return stream */
292     return (gzFile)state;
293 }
294 
295 /* -- see zlib.h -- */
296 gzFile ZEXPORT gzopen(path, mode)
297     const char *path;
298     const char *mode;
299 {
300     return gz_open(path, -1, mode);
301 }
302 
303 /* -- see zlib.h -- */
304 gzFile ZEXPORT gzopen64(path, mode)
305     const char *path;
306     const char *mode;
307 {
308     return gz_open(path, -1, mode);
309 }
310 
311 /* -- see zlib.h -- */
312 gzFile ZEXPORT gzdopen(fd, mode)
313     int fd;
314     const char *mode;
315 {
316     char *path;         /* identifier for error messages */
317     gzFile gz;
318 
319     if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
320         return NULL;
321 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
322     (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
323 #else
324     sprintf(path, "<fd:%d>", fd);   /* for debugging */
325 #endif
326     gz = gz_open(path, fd, mode);
327     free(path);
328     return gz;
329 }
330 
331 /* -- see zlib.h -- */
332 #ifdef WIDECHAR
333 gzFile ZEXPORT gzopen_w(path, mode)
334     const wchar_t *path;
335     const char *mode;
336 {
337     return gz_open(path, -2, mode);
338 }
339 #endif
340 
341 /* -- see zlib.h -- */
342 int ZEXPORT gzbuffer(file, size)
343     gzFile file;
344     unsigned size;
345 {
346     gz_statep state;
347 
348     /* get internal structure and check integrity */
349     if (file == NULL)
350         return -1;
351     state = (gz_statep)file;
352     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
353         return -1;
354 
355     /* make sure we haven't already allocated memory */
356     if (state->size != 0)
357         return -1;
358 
359     /* check and set requested size */
360     if ((size << 1) < size)
361         return -1;              /* need to be able to double it */
362     if (size < 2)
363         size = 2;               /* need two bytes to check magic header */
364     state->want = size;
365     return 0;
366 }
367 
368 /* -- see zlib.h -- */
369 int ZEXPORT gzrewind(file)
370     gzFile file;
371 {
372     gz_statep state;
373 
374     /* get internal structure */
375     if (file == NULL)
376         return -1;
377     state = (gz_statep)file;
378 
379     /* check that we're reading and that there's no error */
380     if (state->mode != GZ_READ ||
381             (state->err != Z_OK && state->err != Z_BUF_ERROR))
382         return -1;
383 
384     /* back up and start over */
385     if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
386         return -1;
387     gz_reset(state);
388     return 0;
389 }
390 
391 /* -- see zlib.h -- */
392 z_off64_t ZEXPORT gzseek64(file, offset, whence)
393     gzFile file;
394     z_off64_t offset;
395     int whence;
396 {
397     unsigned n;
398     z_off64_t ret;
399     gz_statep state;
400 
401     /* get internal structure and check integrity */
402     if (file == NULL)
403         return -1;
404     state = (gz_statep)file;
405     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
406         return -1;
407 
408     /* check that there's no error */
409     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
410         return -1;
411 
412     /* can only seek from start or relative to current position */
413     if (whence != SEEK_SET && whence != SEEK_CUR)
414         return -1;
415 
416     /* normalize offset to a SEEK_CUR specification */

449 
450     /* if reading, skip what's in output buffer (one less gzgetc() check) */
451     if (state->mode == GZ_READ) {
452         n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
453             (unsigned)offset : state->x.have;
454         state->x.have -= n;
455         state->x.next += n;
456         state->x.pos += n;
457         offset -= n;
458     }
459 
460     /* request skip (if not zero) */
461     if (offset) {
462         state->seek = 1;
463         state->skip = offset;
464     }
465     return state->x.pos + offset;
466 }
467 
468 /* -- see zlib.h -- */
469 z_off_t ZEXPORT gzseek(file, offset, whence)
470     gzFile file;
471     z_off_t offset;
472     int whence;
473 {
474     z_off64_t ret;
475 
476     ret = gzseek64(file, (z_off64_t)offset, whence);
477     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
478 }
479 
480 /* -- see zlib.h -- */
481 z_off64_t ZEXPORT gztell64(file)
482     gzFile file;
483 {
484     gz_statep state;
485 
486     /* get internal structure and check integrity */
487     if (file == NULL)
488         return -1;
489     state = (gz_statep)file;
490     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
491         return -1;
492 
493     /* return position */
494     return state->x.pos + (state->seek ? state->skip : 0);
495 }
496 
497 /* -- see zlib.h -- */
498 z_off_t ZEXPORT gztell(file)
499     gzFile file;
500 {
501     z_off64_t ret;
502 
503     ret = gztell64(file);
504     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
505 }
506 
507 /* -- see zlib.h -- */
508 z_off64_t ZEXPORT gzoffset64(file)
509     gzFile file;
510 {
511     z_off64_t offset;
512     gz_statep state;
513 
514     /* get internal structure and check integrity */
515     if (file == NULL)
516         return -1;
517     state = (gz_statep)file;
518     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
519         return -1;
520 
521     /* compute and return effective offset in file */
522     offset = LSEEK(state->fd, 0, SEEK_CUR);
523     if (offset == -1)
524         return -1;
525     if (state->mode == GZ_READ)             /* reading */
526         offset -= state->strm.avail_in;     /* don't count buffered input */
527     return offset;
528 }
529 
530 /* -- see zlib.h -- */
531 z_off_t ZEXPORT gzoffset(file)
532     gzFile file;
533 {
534     z_off64_t ret;
535 
536     ret = gzoffset64(file);
537     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
538 }
539 
540 /* -- see zlib.h -- */
541 int ZEXPORT gzeof(file)
542     gzFile file;
543 {
544     gz_statep state;
545 
546     /* get internal structure and check integrity */
547     if (file == NULL)
548         return 0;
549     state = (gz_statep)file;
550     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
551         return 0;
552 
553     /* return end-of-file state */
554     return state->mode == GZ_READ ? state->past : 0;
555 }
556 
557 /* -- see zlib.h -- */
558 const char * ZEXPORT gzerror(file, errnum)
559     gzFile file;
560     int *errnum;
561 {
562     gz_statep state;
563 
564     /* get internal structure and check integrity */
565     if (file == NULL)
566         return NULL;
567     state = (gz_statep)file;
568     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
569         return NULL;
570 
571     /* return error information */
572     if (errnum != NULL)
573         *errnum = state->err;
574     return state->err == Z_MEM_ERROR ? "out of memory" :
575                                        (state->msg == NULL ? "" : state->msg);
576 }
577 
578 /* -- see zlib.h -- */
579 void ZEXPORT gzclearerr(file)
580     gzFile file;
581 {
582     gz_statep state;
583 
584     /* get internal structure and check integrity */
585     if (file == NULL)
586         return;
587     state = (gz_statep)file;
588     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
589         return;
590 
591     /* clear error and end-of-file */
592     if (state->mode == GZ_READ) {
593         state->eof = 0;
594         state->past = 0;
595     }
596     gz_error(state, Z_OK, NULL);
597 }
598 
599 /* Create an error message in allocated memory and set state->err and
600    state->msg accordingly.  Free any previous error message already there.  Do
601    not try to free or allocate space if the error is Z_MEM_ERROR (out of
602    memory).  Simply save the error message as a static string.  If there is an
603    allocation failure constructing the error message, then convert the error to
604    out of memory. */
605 void ZLIB_INTERNAL gz_error(state, err, msg)
606     gz_statep state;
607     int err;
608     const char *msg;
609 {
610     /* free previously allocated message and clear */
611     if (state->msg != NULL) {
612         if (state->err != Z_MEM_ERROR)
613             free(state->msg);
614         state->msg = NULL;
615     }
616 
617     /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
618     if (err != Z_OK && err != Z_BUF_ERROR)
619         state->x.have = 0;
620 
621     /* set error code, and if no message, then done */
622     state->err = err;
623     if (msg == NULL)
624         return;
625 
626     /* for an out of memory error, return literal string when requested */
627     if (err == Z_MEM_ERROR)
628         return;
629 
630     /* construct error message with path */
631     if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
632             NULL) {
633         state->err = Z_MEM_ERROR;
634         return;
635     }
636 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
637     (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
638                    "%s%s%s", state->path, ": ", msg);
639 #else
640     strcpy(state->msg, state->path);
641     strcat(state->msg, ": ");
642     strcat(state->msg, msg);
643 #endif
644 }
645 
646 #ifndef INT_MAX
647 /* portably return maximum value for an int (when limits.h presumed not
648    available) -- we need to do this to cover cases where 2's complement not
649    used, since C standard permits 1's complement and sign-bit representations,
650    otherwise we could just use ((unsigned)-1) >> 1 */
651 unsigned ZLIB_INTERNAL gz_intmax()
652 {
653     unsigned p, q;
654 
655     p = 1;
656     do {
657         q = p;
658         p <<= 1;
659         p++;
660     } while (p > q);
661     return q >> 1;
662 }
663 #endif


  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 /* gzlib.c -- zlib functions common to reading and writing gzip files
 26  * Copyright (C) 2004-2024 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(_WIN32) && !defined(__BORLANDC__)
 33 #  define LSEEK _lseeki64
 34 #else
 35 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
 36 #  define LSEEK lseek64
 37 #else
 38 #  define LSEEK lseek
 39 #endif
 40 #endif
 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(DWORD error) {


 54     static char buf[1024];
 55 
 56     wchar_t *msgbuf;
 57     DWORD lasterr = GetLastError();
 58     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
 59         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
 60         NULL,
 61         error,
 62         0, /* Default language */
 63         (LPVOID)&msgbuf,
 64         0,
 65         NULL);
 66     if (chars != 0) {
 67         /* If there is an \r\n appended, zap it.  */
 68         if (chars >= 2
 69             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
 70             chars -= 2;
 71             msgbuf[chars] = 0;
 72         }
 73 
 74         if (chars > sizeof (buf) - 1) {
 75             chars = sizeof (buf) - 1;
 76             msgbuf[chars] = 0;
 77         }
 78 
 79         wcstombs(buf, msgbuf, chars + 1);
 80         LocalFree(msgbuf);
 81     }
 82     else {
 83         sprintf(buf, "unknown win32 error (%ld)", error);
 84     }
 85 
 86     SetLastError(lasterr);
 87     return buf;
 88 }
 89 
 90 #endif /* UNDER_CE */
 91 
 92 /* Reset gzip file state */
 93 local void gz_reset(gz_statep state) {


 94     state->x.have = 0;              /* no output data available */
 95     if (state->mode == GZ_READ) {   /* for reading ... */
 96         state->eof = 0;             /* not at end of file */
 97         state->past = 0;            /* have not read past end yet */
 98         state->how = LOOK;          /* look for gzip header */
 99     }
100     else                            /* for writing ... */
101         state->reset = 0;           /* no deflateReset pending */
102     state->seek = 0;                /* no seek request pending */
103     gz_error(state, Z_OK, NULL);    /* clear error */
104     state->x.pos = 0;               /* no uncompressed data yet */
105     state->strm.avail_in = 0;       /* no input data yet */
106 }
107 
108 /* Open a gzip file either by name or file descriptor. */
109 local gzFile gz_open(const void *path, int fd, const char *mode) {




110     gz_statep state;
111     z_size_t len;
112     int oflag;
113 #ifdef O_CLOEXEC
114     int cloexec = 0;
115 #endif
116 #ifdef O_EXCL
117     int exclusive = 0;
118 #endif
119 
120     /* check input */
121     if (path == NULL)
122         return NULL;
123 
124     /* allocate gzFile structure to return */
125     state = (gz_statep)malloc(sizeof(gz_state));
126     if (state == NULL)
127         return NULL;
128     state->size = 0;            /* no buffers allocated yet */
129     state->want = GZBUFSIZE;    /* requested buffer size */

264     }
265     if (state->mode == GZ_APPEND) {
266         LSEEK(state->fd, 0, SEEK_END);  /* so gzoffset() is correct */
267         state->mode = GZ_WRITE;         /* simplify later checks */
268     }
269 
270     /* save the current position for rewinding (only if reading) */
271     if (state->mode == GZ_READ) {
272         state->start = LSEEK(state->fd, 0, SEEK_CUR);
273         if (state->start == -1) state->start = 0;
274     }
275 
276     /* initialize stream */
277     gz_reset(state);
278 
279     /* return stream */
280     return (gzFile)state;
281 }
282 
283 /* -- see zlib.h -- */
284 gzFile ZEXPORT gzopen(const char *path, const char *mode) {



285     return gz_open(path, -1, mode);
286 }
287 
288 /* -- see zlib.h -- */
289 gzFile ZEXPORT gzopen64(const char *path, const char *mode) {



290     return gz_open(path, -1, mode);
291 }
292 
293 /* -- see zlib.h -- */
294 gzFile ZEXPORT gzdopen(int fd, const char *mode) {



295     char *path;         /* identifier for error messages */
296     gzFile gz;
297 
298     if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
299         return NULL;
300 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
301     (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
302 #else
303     sprintf(path, "<fd:%d>", fd);   /* for debugging */
304 #endif
305     gz = gz_open(path, fd, mode);
306     free(path);
307     return gz;
308 }
309 
310 /* -- see zlib.h -- */
311 #ifdef WIDECHAR
312 gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) {



313     return gz_open(path, -2, mode);
314 }
315 #endif
316 
317 /* -- see zlib.h -- */
318 int ZEXPORT gzbuffer(gzFile file, unsigned size) {



319     gz_statep state;
320 
321     /* get internal structure and check integrity */
322     if (file == NULL)
323         return -1;
324     state = (gz_statep)file;
325     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
326         return -1;
327 
328     /* make sure we haven't already allocated memory */
329     if (state->size != 0)
330         return -1;
331 
332     /* check and set requested size */
333     if ((size << 1) < size)
334         return -1;              /* need to be able to double it */
335     if (size < 8)
336         size = 8;               /* needed to behave well with flushing */
337     state->want = size;
338     return 0;
339 }
340 
341 /* -- see zlib.h -- */
342 int ZEXPORT gzrewind(gzFile file) {


343     gz_statep state;
344 
345     /* get internal structure */
346     if (file == NULL)
347         return -1;
348     state = (gz_statep)file;
349 
350     /* check that we're reading and that there's no error */
351     if (state->mode != GZ_READ ||
352             (state->err != Z_OK && state->err != Z_BUF_ERROR))
353         return -1;
354 
355     /* back up and start over */
356     if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
357         return -1;
358     gz_reset(state);
359     return 0;
360 }
361 
362 /* -- see zlib.h -- */
363 z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {




364     unsigned n;
365     z_off64_t ret;
366     gz_statep state;
367 
368     /* get internal structure and check integrity */
369     if (file == NULL)
370         return -1;
371     state = (gz_statep)file;
372     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
373         return -1;
374 
375     /* check that there's no error */
376     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
377         return -1;
378 
379     /* can only seek from start or relative to current position */
380     if (whence != SEEK_SET && whence != SEEK_CUR)
381         return -1;
382 
383     /* normalize offset to a SEEK_CUR specification */

416 
417     /* if reading, skip what's in output buffer (one less gzgetc() check) */
418     if (state->mode == GZ_READ) {
419         n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
420             (unsigned)offset : state->x.have;
421         state->x.have -= n;
422         state->x.next += n;
423         state->x.pos += n;
424         offset -= n;
425     }
426 
427     /* request skip (if not zero) */
428     if (offset) {
429         state->seek = 1;
430         state->skip = offset;
431     }
432     return state->x.pos + offset;
433 }
434 
435 /* -- see zlib.h -- */
436 z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) {




437     z_off64_t ret;
438 
439     ret = gzseek64(file, (z_off64_t)offset, whence);
440     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
441 }
442 
443 /* -- see zlib.h -- */
444 z_off64_t ZEXPORT gztell64(gzFile file) {


445     gz_statep state;
446 
447     /* get internal structure and check integrity */
448     if (file == NULL)
449         return -1;
450     state = (gz_statep)file;
451     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
452         return -1;
453 
454     /* return position */
455     return state->x.pos + (state->seek ? state->skip : 0);
456 }
457 
458 /* -- see zlib.h -- */
459 z_off_t ZEXPORT gztell(gzFile file) {


460     z_off64_t ret;
461 
462     ret = gztell64(file);
463     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
464 }
465 
466 /* -- see zlib.h -- */
467 z_off64_t ZEXPORT gzoffset64(gzFile file) {


468     z_off64_t offset;
469     gz_statep state;
470 
471     /* get internal structure and check integrity */
472     if (file == NULL)
473         return -1;
474     state = (gz_statep)file;
475     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
476         return -1;
477 
478     /* compute and return effective offset in file */
479     offset = LSEEK(state->fd, 0, SEEK_CUR);
480     if (offset == -1)
481         return -1;
482     if (state->mode == GZ_READ)             /* reading */
483         offset -= state->strm.avail_in;     /* don't count buffered input */
484     return offset;
485 }
486 
487 /* -- see zlib.h -- */
488 z_off_t ZEXPORT gzoffset(gzFile file) {


489     z_off64_t ret;
490 
491     ret = gzoffset64(file);
492     return ret == (z_off_t)ret ? (z_off_t)ret : -1;
493 }
494 
495 /* -- see zlib.h -- */
496 int ZEXPORT gzeof(gzFile file) {


497     gz_statep state;
498 
499     /* get internal structure and check integrity */
500     if (file == NULL)
501         return 0;
502     state = (gz_statep)file;
503     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
504         return 0;
505 
506     /* return end-of-file state */
507     return state->mode == GZ_READ ? state->past : 0;
508 }
509 
510 /* -- see zlib.h -- */
511 const char * ZEXPORT gzerror(gzFile file, int *errnum) {



512     gz_statep state;
513 
514     /* get internal structure and check integrity */
515     if (file == NULL)
516         return NULL;
517     state = (gz_statep)file;
518     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
519         return NULL;
520 
521     /* return error information */
522     if (errnum != NULL)
523         *errnum = state->err;
524     return state->err == Z_MEM_ERROR ? "out of memory" :
525                                        (state->msg == NULL ? "" : state->msg);
526 }
527 
528 /* -- see zlib.h -- */
529 void ZEXPORT gzclearerr(gzFile file) {


530     gz_statep state;
531 
532     /* get internal structure and check integrity */
533     if (file == NULL)
534         return;
535     state = (gz_statep)file;
536     if (state->mode != GZ_READ && state->mode != GZ_WRITE)
537         return;
538 
539     /* clear error and end-of-file */
540     if (state->mode == GZ_READ) {
541         state->eof = 0;
542         state->past = 0;
543     }
544     gz_error(state, Z_OK, NULL);
545 }
546 
547 /* Create an error message in allocated memory and set state->err and
548    state->msg accordingly.  Free any previous error message already there.  Do
549    not try to free or allocate space if the error is Z_MEM_ERROR (out of
550    memory).  Simply save the error message as a static string.  If there is an
551    allocation failure constructing the error message, then convert the error to
552    out of memory. */
553 void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {




554     /* free previously allocated message and clear */
555     if (state->msg != NULL) {
556         if (state->err != Z_MEM_ERROR)
557             free(state->msg);
558         state->msg = NULL;
559     }
560 
561     /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
562     if (err != Z_OK && err != Z_BUF_ERROR)
563         state->x.have = 0;
564 
565     /* set error code, and if no message, then done */
566     state->err = err;
567     if (msg == NULL)
568         return;
569 
570     /* for an out of memory error, return literal string when requested */
571     if (err == Z_MEM_ERROR)
572         return;
573 
574     /* construct error message with path */
575     if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
576             NULL) {
577         state->err = Z_MEM_ERROR;
578         return;
579     }
580 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
581     (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
582                    "%s%s%s", state->path, ": ", msg);
583 #else
584     strcpy(state->msg, state->path);
585     strcat(state->msg, ": ");
586     strcat(state->msg, msg);
587 #endif
588 }
589 

590 /* portably return maximum value for an int (when limits.h presumed not
591    available) -- we need to do this to cover cases where 2's complement not
592    used, since C standard permits 1's complement and sign-bit representations,
593    otherwise we could just use ((unsigned)-1) >> 1 */
594 unsigned ZLIB_INTERNAL gz_intmax(void) {
595 #ifdef INT_MAX
596     return INT_MAX;
597 #else
598     unsigned p = 1, q;
599     do {
600         q = p;
601         p <<= 1;
602         p++;
603     } while (p > q);
604     return q >> 1;

605 #endif
606 }
< prev index next >