18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* gzio.c -- IO on .gz files 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (C) 1995-2005 Jean-loup Gailly. 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* @(#) $Id$ */ 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "zutil.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_DEFLATE /* for compatibility with old definition */ 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define NO_GZCOMPRESS 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NO_DUMMY_DECL 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct internal_state {int dummy;}; /* for buggy compilers */ 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef Z_BUFSIZE 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# ifdef MAXSEG_64K 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# else 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define Z_BUFSIZE 16384 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef Z_PRINTF_BUFSIZE 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define Z_PRINTF_BUFSIZE 4096 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef __MVS__ 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# pragma map (fdopen , "\174\174FDOPEN") 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FILE *fdopen(int, const char *); 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef STDC 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern voidp malloc OF((uInt size)); 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void free OF((voidpf ptr)); 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ALLOC(size) malloc(size) 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TRYFREE(p) {if (p) free(p);} 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* gzip flag byte */ 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define COMMENT 0x10 /* bit 4 set: file comment present */ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define RESERVED 0xE0 /* bits 5..7: reserved */ 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct gz_stream { 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_stream stream; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int z_err; /* error code for last stream operation */ 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int z_eof; /* set if end of input file */ 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FILE *file; /* .gz file */ 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Byte *inbuf; /* input buffer */ 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Byte *outbuf; /* output buffer */ 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uLong crc; /* crc32 of uncompressed data */ 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *msg; /* error message */ 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *path; /* path name for debugging only */ 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int transparent; /* 1 if input file is not a .gz file */ 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char mode; /* 'w' or 'r' */ 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_off_t start; /* start of compressed data in file (header skipped) */ 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_off_t in; /* bytes into deflate or inflate */ 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_off_t out; /* bytes out of deflate or inflate */ 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int back; /* one character push-back */ 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int last; /* true if push-back is last character */ 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} gz_stream; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal gzFile gz_open OF((const char *path, const char *mode, int fd)); 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int do_flush OF((gzFile file, int flush)); 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int get_byte OF((gz_stream *s)); 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void check_header OF((gz_stream *s)); 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int destroy OF((gz_stream *s)); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void putLong OF((FILE *file, uLong x)); 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal uLong getLong OF((gz_stream *s)); 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Opens a gzip (.gz) file for reading or writing. The mode parameter 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is as in fopen ("rb" or "wb"). The file is given either by file descriptor 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project or path name (if fd == -1). 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_open returns NULL if the file could not be opened or if there was 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insufficient memory to allocate the (de)compression state; errno 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project can be checked to distinguish the two cases (if errno is zero, the 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project zlib error is Z_MEM_ERROR). 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal gzFile gz_open (path, mode, fd) 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *path; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *mode; 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int level = Z_DEFAULT_COMPRESSION; /* compression level */ 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *p = (char*)mode; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char fmode[80]; /* copy of mode, without the compression level */ 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *m = fmode; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!path || !mode) return Z_NULL; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = (gz_stream *)ALLOC(sizeof(gz_stream)); 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s) return Z_NULL; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.zalloc = (alloc_func)0; 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.zfree = (free_func)0; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.opaque = (voidpf)0; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf = Z_NULL; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = s->outbuf = Z_NULL; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = s->stream.avail_out = 0; 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->file = NULL; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_OK; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_eof = 0; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in = 0; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out = 0; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->back = EOF; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->crc = crc32(0L, Z_NULL, 0); 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->msg = NULL; 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->transparent = 0; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->path = (char*)ALLOC(strlen(path)+1); 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->path == NULL) { 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return destroy(s), (gzFile)Z_NULL; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcpy(s->path, path); /* do this early for debugging */ 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->mode = '\0'; 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*p == 'r') s->mode = 'r'; 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*p == 'w' || *p == 'a') s->mode = 'w'; 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*p >= '0' && *p <= '9') { 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project level = *p - '0'; 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (*p == 'f') { 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strategy = Z_FILTERED; 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (*p == 'h') { 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strategy = Z_HUFFMAN_ONLY; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (*p == 'R') { 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strategy = Z_RLE; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *m++ = *p; /* copy the mode */ 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (*p++ && m != fmode + sizeof(fmode)); 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->mode == 'w') { 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_GZCOMPRESS 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = Z_STREAM_ERROR; 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = deflateInit2(&(s->stream), level, 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* windowBits is passed < 0 to suppress zlib header */ 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err != Z_OK || s->outbuf == Z_NULL) { 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return destroy(s), (gzFile)Z_NULL; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = inflateInit2(&(s->stream), -MAX_WBITS); 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* windowBits is passed < 0 to tell that there is no zlib header. 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Note that in this case inflate *requires* an extra "dummy" byte 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * after the compressed stream in order to complete decompression and 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * present after the compressed stream. 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err != Z_OK || s->inbuf == Z_NULL) { 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return destroy(s), (gzFile)Z_NULL; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out = Z_BUFSIZE; 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = 0; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->file == NULL) { 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return destroy(s), (gzFile)Z_NULL; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->mode == 'w') { 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Write a very simple .gz header: 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->start = 10L; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* We use 10L instead of ftell(s->file) to because ftell causes an 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * fflush on some systems. This version of the library doesn't use 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * start anyway in write mode, so this initialization is not 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * necessary. 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project check_header(s); /* skip the .gz header */ 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->start = ftell(s->file) - s->stream.avail_in; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (gzFile)s; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Opens a gzip (.gz) file for reading or writing. 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectgzFile ZEXPORT gzopen (path, mode) 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *path; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *mode; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gz_open (path, mode, -1); 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Associate a gzFile with the file descriptor fd. fd is not dup'ed here 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project to mimic the behavio(u)r of fdopen. 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectgzFile ZEXPORT gzdopen (fd, mode) 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *mode; 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char name[46]; /* allow for up to 128-bit integers */ 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fd < 0) return (gzFile)Z_NULL; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sprintf(name, "<fd:%d>", fd); /* for debugging */ 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gz_open (name, mode, fd); 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Update the compression level and strategy 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzsetparams (file, level, strategy) 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int level; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int strategy; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Make room to allow flushing */ 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_out == 0) { 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = s->outbuf; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_ERRNO; 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out = Z_BUFSIZE; 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return deflateParams (&(s->stream), level, strategy); 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Read a byte from a gz_stream; update next_in and avail_in. Return EOF 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for end of file. 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IN assertion: the stream s has been sucessfully opened for reading. 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int get_byte(s) 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_eof) return EOF; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_in == 0) { 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = 0; 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_in == 0) { 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_eof = 1; 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ferror(s->file)) s->z_err = Z_ERRNO; 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return EOF; 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf; 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in--; 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return *(s->stream.next_in)++; 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Check the gzip header of a gz_stream opened for reading. Set the stream 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mode to transparent if the gzip magic header is not present; set s->err 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project to Z_DATA_ERROR if the magic header is present but the rest of the header 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is incorrect. 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project IN assertion: the stream s has already been created sucessfully; 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in is zero for the first time, but may be non-zero 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for concatenated .gz files. 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void check_header(s) 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int method; /* method byte */ 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flags; /* flags byte */ 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uInt len; 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c; 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Assure two bytes in the buffer so we can peek ahead -- handle case 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project where first byte of header is at the end of the buffer after the last 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzip segment */ 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = s->stream.avail_in; 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len < 2) { 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len) s->inbuf[0] = s->stream.next_in[0]; 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = 0; 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in += len; 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf; 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_in < 2) { 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->transparent = s->stream.avail_in; 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Peek ahead to check the gzip magic header */ 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.next_in[0] != gz_magic[0] || 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in[1] != gz_magic[1]) { 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->transparent = 1; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in -= 2; 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in += 2; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Check the rest of the gzip header */ 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project method = get_byte(s); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = get_byte(s); 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (method != Z_DEFLATED || (flags & RESERVED) != 0) { 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_DATA_ERROR; 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Discard time, xflags and OS code: */ 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (len = 0; len < 6; len++) (void)get_byte(s); 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (uInt)get_byte(s); 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len += ((uInt)get_byte(s))<<8; 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* len is garbage if EOF but the loop below will quit anyway */ 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (len-- != 0 && get_byte(s) != EOF) ; 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while ((c = get_byte(s)) != 0 && c != EOF) ; 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while ((c = get_byte(s)) != 0 && c != EOF) ; 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (len = 0; len < 2; len++) (void)get_byte(s); 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* =========================================================================== 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Cleanup then free the given gz_stream. Return a zlib error code. 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Try freeing in the reverse order of allocations. 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int destroy (s) 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err = Z_OK; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s) return Z_STREAM_ERROR; 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TRYFREE(s->msg); 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.state != NULL) { 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->mode == 'w') { 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_GZCOMPRESS 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = Z_STREAM_ERROR; 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = deflateEnd(&(s->stream)); 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (s->mode == 'r') { 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = inflateEnd(&(s->stream)); 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->file != NULL && fclose(s->file)) { 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef ESPIPE 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = Z_ERRNO; 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err < 0) err = s->z_err; 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TRYFREE(s->inbuf); 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TRYFREE(s->outbuf); 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TRYFREE(s->path); 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TRYFREE(s); 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return err; 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Reads the given number of uncompressed bytes from the compressed file. 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzread returns the number of bytes actually read (0 for end of file). 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzread (file, buf, len) 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project voidp buf; 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned len; 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Bytef *start = (Bytef*)buf; /* starting point for crc computation */ 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err == Z_STREAM_END) return 0; /* EOF */ 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next_out = (Byte*)buf; 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = (Bytef*)buf; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out = len; 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_out && s->back != EOF) { 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *next_out++ = s->back; 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out++; 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out--; 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->back = EOF; 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out++; 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project start++; 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->last) { 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_STREAM_END; 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (s->stream.avail_out != 0) { 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->transparent) { 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Copy first the lookahead bytes: */ 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uInt n = s->stream.avail_in; 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n > s->stream.avail_out) n = s->stream.avail_out; 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n > 0) { 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project zmemcpy(s->stream.next_out, s->stream.next_in, n); 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next_out += n; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = next_out; 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in += n; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out -= n; 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in -= n; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_out > 0) { 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out -= 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (uInt)fread(next_out, 1, s->stream.avail_out, s->file); 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len -= s->stream.avail_out; 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in += len; 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out += len; 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len == 0) s->z_eof = 1; 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (int)len; 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_in == 0 && !s->z_eof) { 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = 0; 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_in == 0) { 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_eof = 1; 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ferror(s->file)) { 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_ERRNO; 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf; 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in += s->stream.avail_in; 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out += s->stream.avail_out; 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = inflate(&(s->stream), Z_NO_FLUSH); 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in -= s->stream.avail_in; 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out -= s->stream.avail_out; 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err == Z_STREAM_END) { 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Check CRC and original size */ 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project start = s->stream.next_out; 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (getLong(s) != s->crc) { 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_DATA_ERROR; 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void)getLong(s); 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The uncompressed length returned by above getlong() may be 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * different from s->out in case of concatenated .gz files. 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check for such files: 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project check_header(s); 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err == Z_OK) { 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflateReset(&(s->stream)); 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->crc = crc32(0L, Z_NULL, 0); 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err != Z_OK || s->z_eof) break; 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len == s->stream.avail_out && 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (int)(len - s->stream.avail_out); 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Reads one byte from the compressed file. gzgetc returns this byte 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project or -1 in case of end of file or error. 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzgetc(file) 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char c; 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gzread(file, &c, 1) == 1 ? c : -1; 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Push one byte back onto the stream. 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzungetc(c, file) 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c; 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->back = c; 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out--; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->last = (s->z_err == Z_STREAM_END); 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->last) s->z_err = Z_OK; 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_eof = 0; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return c; 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Reads bytes from the compressed file until len-1 characters are 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project read, or a newline character is read and transferred to buf, or an 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project end-of-file condition is encountered. The string is then terminated 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project with a null character. 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzgets returns buf, or Z_NULL in case of error. 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project The current implementation is not optimized at all. 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar * ZEXPORT gzgets(file, buf, len) 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *buf; 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *b = buf; 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (buf == Z_NULL || len <= 0) return Z_NULL; 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *buf = '\0'; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return b == buf && len > 0 ? Z_NULL : b; 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef NO_GZCOMPRESS 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Writes the given number of uncompressed bytes into the compressed file. 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzwrite returns the number of bytes actually written (0 in case of error). 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzwrite (file, buf, len) 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project voidpc buf; 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned len; 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = (Bytef*)buf; 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = len; 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (s->stream.avail_in != 0) { 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->stream.avail_out == 0) { 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = s->outbuf; 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_ERRNO; 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out = Z_BUFSIZE; 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in += s->stream.avail_in; 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out += s->stream.avail_out; 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = deflate(&(s->stream), Z_NO_FLUSH); 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in -= s->stream.avail_in; 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out -= s->stream.avail_out; 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err != Z_OK) break; 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->crc = crc32(s->crc, (const Bytef *)buf, len); 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (int)(len - s->stream.avail_in); 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Converts, formats, and writes the args to the compressed file under 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project control of the format string, as in fprintf. gzprintf returns the number of 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uncompressed bytes actually written (0 in case of error). 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef STDC 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdarg.h> 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[Z_PRINTF_BUFSIZE]; 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_list va; 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[sizeof(buf) - 1] = 0; 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_start(va, format); 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_vsnprintf 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# ifdef HAS_vsprintf_void 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void)vsprintf(buf, format, va); 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end(va); 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (len = 0; len < sizeof(buf); len++) 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (buf[len] == 0) break; 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# else 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = vsprintf(buf, format, va); 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end(va); 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# ifdef HAS_vsnprintf_void 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void)vsnprintf(buf, sizeof(buf), format, va); 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end(va); 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = strlen(buf); 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# else 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = vsnprintf(buf, sizeof(buf), format, va); 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end(va); 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gzwrite(file, buf, (unsigned)len); 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* not ANSI C */ 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *format; 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[Z_PRINTF_BUFSIZE]; 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[sizeof(buf) - 1] = 0; 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_snprintf 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# ifdef HAS_sprintf_void 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (len = 0; len < sizeof(buf); len++) 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (buf[len] == 0) break; 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# else 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# ifdef HAS_snprintf_void 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = strlen(buf); 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# else 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gzwrite(file, buf, len); 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Writes c, converted to an unsigned char, into the compressed file. 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzputc returns the value that was written, or -1 in case of error. 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzputc(file, c) 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c; 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char cc = (unsigned char) c; /* required for big endian systems */ 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Writes the given null-terminated string to the compressed file, excluding 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the terminating null character. 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzputs returns the number of characters written, or -1 in case of error. 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzputs(file, s) 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *s; 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gzwrite(file, (char*)s, (unsigned)strlen(s)); 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Flushes all pending output into the compressed file. The parameter 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flush is as in the deflate() function. 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int do_flush (file, flush) 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flush; 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uInt len; 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int done = 0; 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = 0; /* should be zero already anyway */ 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = Z_BUFSIZE - s->stream.avail_out; 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len != 0) { 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_ERRNO; 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_ERRNO; 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_out = s->outbuf; 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_out = Z_BUFSIZE; 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (done) break; 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out += s->stream.avail_out; 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = deflate(&(s->stream), flush); 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out -= s->stream.avail_out; 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Ignore the second of two consecutive flushes: */ 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* deflate has finished flushing only when it hasn't used up 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all the available space in the output buffer: 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzflush (file, flush) 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flush; 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err = do_flush (file, flush); 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) return err; 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fflush(s->file); 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* NO_GZCOMPRESS */ 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Sets the starting position for the next gzread or gzwrite on the given 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compressed file. The offset represents a number of bytes in the 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzseek returns the resulting offset location as measured in bytes from 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the beginning of the uncompressed stream, or -1 in case of error. 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SEEK_END is not implemented, returns error. 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project In this version of the library, gzseek can be extremely slow. 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_off_t ZEXPORT gzseek (file, offset, whence) 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_off_t offset; 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int whence; 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || whence == SEEK_END || 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1L; 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->mode == 'w') { 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_GZCOMPRESS 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1L; 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (whence == SEEK_SET) { 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset -= s->in; 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset < 0) return -1L; 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* At this point, offset is the number of zero bytes to write. */ 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->inbuf == Z_NULL) { 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->inbuf == Z_NULL) return -1L; 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project zmemzero(s->inbuf, Z_BUFSIZE); 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (offset > 0) { 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uInt size = Z_BUFSIZE; 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset < Z_BUFSIZE) size = (uInt)offset; 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = gzwrite(file, s->inbuf, size); 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size == 0) return -1L; 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset -= size; 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->in; 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Rest of function is for reading only */ 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* compute absolute position */ 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (whence == SEEK_CUR) { 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset += s->out; 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset < 0) return -1L; 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->transparent) { 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* map to fseek */ 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->back = EOF; 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = 0; 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf; 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in = s->out = offset; 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return offset; 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* For a negative seek, rewind and use positive seek */ 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset >= s->out) { 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset -= s->out; 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (gzrewind(file) < 0) { 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1L; 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* offset is now the number of bytes to skip. */ 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset != 0 && s->outbuf == Z_NULL) { 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->outbuf == Z_NULL) return -1L; 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset && s->back != EOF) { 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->back = EOF; 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out++; 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset--; 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->last) s->z_err = Z_STREAM_END; 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (offset > 0) { 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int size = Z_BUFSIZE; 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset < Z_BUFSIZE) size = (int)offset; 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = gzread(file, s->outbuf, (uInt)size); 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size <= 0) return -1L; 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset -= size; 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->out; 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Rewinds input file. 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzrewind (file) 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'r') return -1; 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_err = Z_OK; 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_eof = 0; 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->back = EOF; 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.avail_in = 0; 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->stream.next_in = s->inbuf; 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->crc = crc32(0L, Z_NULL, 0); 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s->transparent) (void)inflateReset(&s->stream); 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->in = 0; 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->out = 0; 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return fseek(s->file, s->start, SEEK_SET); 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Returns the starting position for the next gzread or gzwrite on the 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project given compressed file. This position represents a number of bytes in the 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uncompressed data stream. 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_off_t ZEXPORT gztell (file) 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return gzseek(file, 0L, SEEK_CUR); 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Returns 1 when EOF has previously been detected reading the given 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project input stream, otherwise zero. 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzeof (file) 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* With concatenated compressed files that can have embedded 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * crc trailers, z_eof is no longer the only/best indicator of EOF 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * on a gz_stream. Handle end-of-stream error explicitly here. 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'r') return 0; 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_eof) return 1; 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->z_err == Z_STREAM_END; 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Returns 1 if reading and doing so transparently, otherwise zero. 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzdirect (file) 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL || s->mode != 'r') return 0; 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->transparent; 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Outputs a long in LSB order to the given file 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void putLong (file, x) 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FILE *file; 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uLong x; 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < 4; n++) { 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fputc((int)(x & 0xff), file); 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x >>= 8; 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Reads a long in LSB order from the given gz_stream. Sets z_err in case 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project of error. 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal uLong getLong (s) 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s; 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uLong x = (uLong)get_byte(s); 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int c; 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x += ((uLong)get_byte(s))<<8; 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x += ((uLong)get_byte(s))<<16; 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = get_byte(s); 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == EOF) s->z_err = Z_DATA_ERROR; 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x += ((uLong)c)<<24; 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return x; 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Flushes all pending output if necessary, closes the compressed file 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project and deallocates all the (de)compression state. 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT gzclose (file) 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL) return Z_STREAM_ERROR; 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->mode == 'w') { 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef NO_GZCOMPRESS 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_STREAM_ERROR; 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (do_flush (file, Z_FINISH) != Z_OK) 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return destroy((gz_stream*)file); 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project putLong (s->file, s->crc); 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project putLong (s->file, (uLong)(s->in & 0xffffffff)); 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return destroy((gz_stream*)file); 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef STDC 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define zstrerror(errnum) strerror(errnum) 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define zstrerror(errnum) "" 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Returns the error message for the last error which occurred on the 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project given compressed file. errnum is set to zlib error number. If an 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project error occurred in the file system and not in the compression library, 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errnum is set to Z_ERRNO and the application may consult errno 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project to get the exact error code. 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char * ZEXPORT gzerror (file, errnum) 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *errnum; 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *m; 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL) { 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *errnum = Z_STREAM_ERROR; 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (const char*)ERR_MSG(Z_STREAM_ERROR); 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *errnum = s->z_err; 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*errnum == Z_OK) return (const char*)""; 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TRYFREE(s->msg); 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcpy(s->msg, s->path); 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcat(s->msg, ": "); 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strcat(s->msg, m); 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (const char*)s->msg; 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* =========================================================================== 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Clear the error and end-of-file flags, and do the same for the real file. 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid ZEXPORT gzclearerr (file) 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gzFile file; 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project gz_stream *s = (gz_stream*)file; 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s == NULL) return; 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->z_eof = 0; 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clearerr(s->file); 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1027