mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-25 18:22:59 +02:00 
			
		
		
		
	zlib updated to the version 1.2.7
This commit is contained in:
		
							
								
								
									
										25
									
								
								Foundation/src/gzclose.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Foundation/src/gzclose.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /* gzclose.c -- zlib gzclose() function | ||||
|  * Copyright (C) 2004, 2010 Mark Adler | ||||
|  * For conditions of distribution and use, see copyright notice in zlib.h | ||||
|  */ | ||||
|  | ||||
| #include "gzguts.h" | ||||
|  | ||||
| /* gzclose() is in a separate file so that it is linked in only if it is used. | ||||
|    That way the other gzclose functions can be used instead to avoid linking in | ||||
|    unneeded compression or decompression routines. */ | ||||
| int ZEXPORT gzclose(file) | ||||
|     gzFile file; | ||||
| { | ||||
| #ifndef NO_GZCOMPRESS | ||||
|     gz_statep state; | ||||
|  | ||||
|     if (file == NULL) | ||||
|         return Z_STREAM_ERROR; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); | ||||
| #else | ||||
|     return gzclose_r(file); | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										193
									
								
								Foundation/src/gzguts.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								Foundation/src/gzguts.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /* gzguts.h -- zlib internal header definitions for gz* operations | ||||
|  * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler | ||||
|  * For conditions of distribution and use, see copyright notice in zlib.h | ||||
|  */ | ||||
|  | ||||
| #ifdef _LARGEFILE64_SOURCE | ||||
| #  ifndef _LARGEFILE_SOURCE | ||||
| #    define _LARGEFILE_SOURCE 1 | ||||
| #  endif | ||||
| #  ifdef _FILE_OFFSET_BITS | ||||
| #    undef _FILE_OFFSET_BITS | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #ifdef HAVE_HIDDEN | ||||
| #  define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) | ||||
| #else | ||||
| #  define ZLIB_INTERNAL | ||||
| #endif | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include "zlib.h" | ||||
| #ifdef STDC | ||||
| #  include <string.h> | ||||
| #  include <stdlib.h> | ||||
| #  include <limits.h> | ||||
| #endif | ||||
| #include <fcntl.h> | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #  include <stddef.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) | ||||
| #  include <io.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef NO_DEFLATE       /* for compatibility with old definition */ | ||||
| #  define NO_GZCOMPRESS | ||||
| #endif | ||||
|  | ||||
| #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) | ||||
| #  ifndef HAVE_VSNPRINTF | ||||
| #    define HAVE_VSNPRINTF | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #if defined(__CYGWIN__) | ||||
| #  ifndef HAVE_VSNPRINTF | ||||
| #    define HAVE_VSNPRINTF | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) | ||||
| #  ifndef HAVE_VSNPRINTF | ||||
| #    define HAVE_VSNPRINTF | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #ifndef HAVE_VSNPRINTF | ||||
| #  ifdef MSDOS | ||||
| /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), | ||||
|  but for now we just assume it doesn't. */ | ||||
| #    define NO_vsnprintf | ||||
| #  endif | ||||
| #  ifdef __TURBOC__ | ||||
| #    define NO_vsnprintf | ||||
| #  endif | ||||
| #  ifdef WIN32 | ||||
| /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ | ||||
| #    if !defined(vsnprintf) && !defined(NO_vsnprintf) | ||||
| #      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) | ||||
| #         define vsnprintf _vsnprintf | ||||
| #      endif | ||||
| #    endif | ||||
| #  endif | ||||
| #  ifdef __SASC | ||||
| #    define NO_vsnprintf | ||||
| #  endif | ||||
| #  ifdef VMS | ||||
| #    define NO_vsnprintf | ||||
| #  endif | ||||
| #  ifdef __OS400__ | ||||
| #    define NO_vsnprintf | ||||
| #  endif | ||||
| #  ifdef __MVS__ | ||||
| #    define NO_vsnprintf | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #ifndef local | ||||
| #  define local static | ||||
| #endif | ||||
| /* compile with -Dlocal if your debugger can't find static symbols */ | ||||
|  | ||||
| /* gz* functions always use library allocation functions */ | ||||
| #ifndef STDC | ||||
|   extern voidp  malloc OF((uInt size)); | ||||
|   extern void   free   OF((voidpf ptr)); | ||||
| #endif | ||||
|  | ||||
| /* get errno and strerror definition */ | ||||
| #if defined UNDER_CE | ||||
| #  include <windows.h> | ||||
| #  define zstrerror() gz_strwinerror((DWORD)GetLastError()) | ||||
| #else | ||||
| #  ifndef NO_STRERROR | ||||
| #    include <errno.h> | ||||
| #    define zstrerror() strerror(errno) | ||||
| #  else | ||||
| #    define zstrerror() "stdio error (consult errno)" | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| /* provide prototypes for these when building zlib without LFS */ | ||||
| #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 | ||||
|     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); | ||||
|     ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); | ||||
|     ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); | ||||
|     ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); | ||||
| #endif | ||||
|  | ||||
| /* default memLevel */ | ||||
| #if MAX_MEM_LEVEL >= 8 | ||||
| #  define DEF_MEM_LEVEL 8 | ||||
| #else | ||||
| #  define DEF_MEM_LEVEL  MAX_MEM_LEVEL | ||||
| #endif | ||||
|  | ||||
| /* default i/o buffer size -- double this for output when reading */ | ||||
| #define GZBUFSIZE 8192 | ||||
|  | ||||
| /* gzip modes, also provide a little integrity check on the passed structure */ | ||||
| #define GZ_NONE 0 | ||||
| #define GZ_READ 7247 | ||||
| #define GZ_WRITE 31153 | ||||
| #define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */ | ||||
|  | ||||
| /* values for gz_state how */ | ||||
| #define LOOK 0      /* look for a gzip header */ | ||||
| #define COPY 1      /* copy input directly */ | ||||
| #define GZIP 2      /* decompress a gzip stream */ | ||||
|  | ||||
| /* internal gzip file state data structure */ | ||||
| typedef struct { | ||||
|         /* exposed contents for gzgetc() macro */ | ||||
|     struct gzFile_s x;      /* "x" for exposed */ | ||||
|                             /* x.have: number of bytes available at x.next */ | ||||
|                             /* x.next: next output data to deliver or write */ | ||||
|                             /* x.pos: current position in uncompressed data */ | ||||
|         /* used for both reading and writing */ | ||||
|     int mode;               /* see gzip modes above */ | ||||
|     int fd;                 /* file descriptor */ | ||||
|     char *path;             /* path or fd for error messages */ | ||||
|     unsigned size;          /* buffer size, zero if not allocated yet */ | ||||
|     unsigned want;          /* requested buffer size, default is GZBUFSIZE */ | ||||
|     unsigned char *in;      /* input buffer */ | ||||
|     unsigned char *out;     /* output buffer (double-sized when reading) */ | ||||
|     int direct;             /* 0 if processing gzip, 1 if transparent */ | ||||
|         /* just for reading */ | ||||
|     int how;                /* 0: get header, 1: copy, 2: decompress */ | ||||
|     z_off64_t start;        /* where the gzip data started, for rewinding */ | ||||
|     int eof;                /* true if end of input file reached */ | ||||
|     int past;               /* true if read requested past end */ | ||||
|         /* just for writing */ | ||||
|     int level;              /* compression level */ | ||||
|     int strategy;           /* compression strategy */ | ||||
|         /* seek request */ | ||||
|     z_off64_t skip;         /* amount to skip (already rewound if backwards) */ | ||||
|     int seek;               /* true if seek request pending */ | ||||
|         /* error information */ | ||||
|     int err;                /* error code */ | ||||
|     char *msg;              /* error message */ | ||||
|         /* zlib inflate or deflate stream */ | ||||
|     z_stream strm;          /* stream structure in-place (not a pointer) */ | ||||
| } gz_state; | ||||
| typedef gz_state FAR *gz_statep; | ||||
|  | ||||
| /* shared functions */ | ||||
| void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); | ||||
| #if defined UNDER_CE | ||||
| char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); | ||||
| #endif | ||||
|  | ||||
| /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t | ||||
|    value -- needed when comparing unsigned to z_off64_t, which is signed | ||||
|    (possible z_off64_t types off_t, off64_t, and long are all signed) */ | ||||
| #ifdef INT_MAX | ||||
| #  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) | ||||
| #else | ||||
| unsigned ZLIB_INTERNAL gz_intmax OF((void)); | ||||
| #  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) | ||||
| #endif | ||||
							
								
								
									
										620
									
								
								Foundation/src/gzlib.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										620
									
								
								Foundation/src/gzlib.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,620 @@ | ||||
| /* gzlib.c -- zlib functions common to reading and writing gzip files | ||||
|  * Copyright (C) 2004, 2010, 2011, 2012 Mark Adler | ||||
|  * For conditions of distribution and use, see copyright notice in zlib.h | ||||
|  */ | ||||
|  | ||||
| #include "gzguts.h" | ||||
|  | ||||
| #if defined(_WIN32) && !defined(__BORLANDC__) | ||||
| #  define LSEEK _lseeki64 | ||||
| #else | ||||
| #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 | ||||
| #  define LSEEK lseek64 | ||||
| #else | ||||
| #  define LSEEK lseek | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| /* Local functions */ | ||||
| local void gz_reset OF((gz_statep)); | ||||
| local gzFile gz_open OF((const void *, int, const char *)); | ||||
|  | ||||
| #if defined UNDER_CE | ||||
|  | ||||
| /* Map the Windows error number in ERROR to a locale-dependent error message | ||||
|    string and return a pointer to it.  Typically, the values for ERROR come | ||||
|    from GetLastError. | ||||
|  | ||||
|    The string pointed to shall not be modified by the application, but may be | ||||
|    overwritten by a subsequent call to gz_strwinerror | ||||
|  | ||||
|    The gz_strwinerror function does not change the current setting of | ||||
|    GetLastError. */ | ||||
| char ZLIB_INTERNAL *gz_strwinerror (error) | ||||
|      DWORD error; | ||||
| { | ||||
|     static char buf[1024]; | ||||
|  | ||||
|     wchar_t *msgbuf; | ||||
|     DWORD lasterr = GetLastError(); | ||||
|     DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | ||||
|         | FORMAT_MESSAGE_ALLOCATE_BUFFER, | ||||
|         NULL, | ||||
|         error, | ||||
|         0, /* Default language */ | ||||
|         (LPVOID)&msgbuf, | ||||
|         0, | ||||
|         NULL); | ||||
|     if (chars != 0) { | ||||
|         /* If there is an \r\n appended, zap it.  */ | ||||
|         if (chars >= 2 | ||||
|             && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { | ||||
|             chars -= 2; | ||||
|             msgbuf[chars] = 0; | ||||
|         } | ||||
|  | ||||
|         if (chars > sizeof (buf) - 1) { | ||||
|             chars = sizeof (buf) - 1; | ||||
|             msgbuf[chars] = 0; | ||||
|         } | ||||
|  | ||||
|         wcstombs(buf, msgbuf, chars + 1); | ||||
|         LocalFree(msgbuf); | ||||
|     } | ||||
|     else { | ||||
|         sprintf(buf, "unknown win32 error (%ld)", error); | ||||
|     } | ||||
|  | ||||
|     SetLastError(lasterr); | ||||
|     return buf; | ||||
| } | ||||
|  | ||||
| #endif /* UNDER_CE */ | ||||
|  | ||||
| /* Reset gzip file state */ | ||||
| local void gz_reset(state) | ||||
|     gz_statep state; | ||||
| { | ||||
|     state->x.have = 0;              /* no output data available */ | ||||
|     if (state->mode == GZ_READ) {   /* for reading ... */ | ||||
|         state->eof = 0;             /* not at end of file */ | ||||
|         state->past = 0;            /* have not read past end yet */ | ||||
|         state->how = LOOK;          /* look for gzip header */ | ||||
|     } | ||||
|     state->seek = 0;                /* no seek request pending */ | ||||
|     gz_error(state, Z_OK, NULL);    /* clear error */ | ||||
|     state->x.pos = 0;               /* no uncompressed data yet */ | ||||
|     state->strm.avail_in = 0;       /* no input data yet */ | ||||
| } | ||||
|  | ||||
| /* Open a gzip file either by name or file descriptor. */ | ||||
| local gzFile gz_open(path, fd, mode) | ||||
|     const void *path; | ||||
|     int fd; | ||||
|     const char *mode; | ||||
| { | ||||
|     gz_statep state; | ||||
|     size_t len; | ||||
|     int oflag; | ||||
| #ifdef O_CLOEXEC | ||||
|     int cloexec = 0; | ||||
| #endif | ||||
| #ifdef O_EXCL | ||||
|     int exclusive = 0; | ||||
| #endif | ||||
|  | ||||
|     /* check input */ | ||||
|     if (path == NULL) | ||||
|         return NULL; | ||||
|  | ||||
|     /* allocate gzFile structure to return */ | ||||
|     state = malloc(sizeof(gz_state)); | ||||
|     if (state == NULL) | ||||
|         return NULL; | ||||
|     state->size = 0;            /* no buffers allocated yet */ | ||||
|     state->want = GZBUFSIZE;    /* requested buffer size */ | ||||
|     state->msg = NULL;          /* no error message yet */ | ||||
|  | ||||
|     /* interpret mode */ | ||||
|     state->mode = GZ_NONE; | ||||
|     state->level = Z_DEFAULT_COMPRESSION; | ||||
|     state->strategy = Z_DEFAULT_STRATEGY; | ||||
|     state->direct = 0; | ||||
|     while (*mode) { | ||||
|         if (*mode >= '0' && *mode <= '9') | ||||
|             state->level = *mode - '0'; | ||||
|         else | ||||
|             switch (*mode) { | ||||
|             case 'r': | ||||
|                 state->mode = GZ_READ; | ||||
|                 break; | ||||
| #ifndef NO_GZCOMPRESS | ||||
|             case 'w': | ||||
|                 state->mode = GZ_WRITE; | ||||
|                 break; | ||||
|             case 'a': | ||||
|                 state->mode = GZ_APPEND; | ||||
|                 break; | ||||
| #endif | ||||
|             case '+':       /* can't read and write at the same time */ | ||||
|                 free(state); | ||||
|                 return NULL; | ||||
|             case 'b':       /* ignore -- will request binary anyway */ | ||||
|                 break; | ||||
| #ifdef O_CLOEXEC | ||||
|             case 'e': | ||||
|                 cloexec = 1; | ||||
|                 break; | ||||
| #endif | ||||
| #ifdef O_EXCL | ||||
|             case 'x': | ||||
|                 exclusive = 1; | ||||
|                 break; | ||||
| #endif | ||||
|             case 'f': | ||||
|                 state->strategy = Z_FILTERED; | ||||
|                 break; | ||||
|             case 'h': | ||||
|                 state->strategy = Z_HUFFMAN_ONLY; | ||||
|                 break; | ||||
|             case 'R': | ||||
|                 state->strategy = Z_RLE; | ||||
|                 break; | ||||
|             case 'F': | ||||
|                 state->strategy = Z_FIXED; | ||||
|             case 'T': | ||||
|                 state->direct = 1; | ||||
|             default:        /* could consider as an error, but just ignore */ | ||||
|                 ; | ||||
|             } | ||||
|         mode++; | ||||
|     } | ||||
|  | ||||
|     /* must provide an "r", "w", or "a" */ | ||||
|     if (state->mode == GZ_NONE) { | ||||
|         free(state); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     /* can't force transparent read */ | ||||
|     if (state->mode == GZ_READ) { | ||||
|         if (state->direct) { | ||||
|             free(state); | ||||
|             return NULL; | ||||
|         } | ||||
|         state->direct = 1;      /* for empty file */ | ||||
|     } | ||||
|  | ||||
|     /* save the path name for error messages */ | ||||
| #ifdef _WIN32 | ||||
|     if (fd == -2) { | ||||
|         len = wcstombs(NULL, path, 0); | ||||
|         if (len == (size_t)-1) | ||||
|             len = 0; | ||||
|     } | ||||
|     else | ||||
| #endif | ||||
|         len = strlen(path); | ||||
|     state->path = malloc(len + 1); | ||||
|     if (state->path == NULL) { | ||||
|         free(state); | ||||
|         return NULL; | ||||
|     } | ||||
| #ifdef _WIN32 | ||||
|     if (fd == -2) | ||||
|         if (len) | ||||
|             wcstombs(state->path, path, len + 1); | ||||
|         else | ||||
|             *(state->path) = 0; | ||||
|     else | ||||
| #endif | ||||
|         strcpy(state->path, path); | ||||
|  | ||||
|     /* compute the flags for open() */ | ||||
|     oflag = | ||||
| #ifdef O_LARGEFILE | ||||
|         O_LARGEFILE | | ||||
| #endif | ||||
| #ifdef O_BINARY | ||||
|         O_BINARY | | ||||
| #endif | ||||
| #ifdef O_CLOEXEC | ||||
|         (cloexec ? O_CLOEXEC : 0) | | ||||
| #endif | ||||
|         (state->mode == GZ_READ ? | ||||
|          O_RDONLY : | ||||
|          (O_WRONLY | O_CREAT | | ||||
| #ifdef O_EXCL | ||||
|           (exclusive ? O_EXCL : 0) | | ||||
| #endif | ||||
|           (state->mode == GZ_WRITE ? | ||||
|            O_TRUNC : | ||||
|            O_APPEND))); | ||||
|  | ||||
|     /* open the file with the appropriate flags (or just use fd) */ | ||||
|     state->fd = fd > -1 ? fd : ( | ||||
| #ifdef _WIN32 | ||||
|         fd == -2 ? _wopen(path, oflag, 0666) : | ||||
| #endif | ||||
|         open(path, oflag, 0666)); | ||||
|     if (state->fd == -1) { | ||||
|         free(state->path); | ||||
|         free(state); | ||||
|         return NULL; | ||||
|     } | ||||
|     if (state->mode == GZ_APPEND) | ||||
|         state->mode = GZ_WRITE;         /* simplify later checks */ | ||||
|  | ||||
|     /* save the current position for rewinding (only if reading) */ | ||||
|     if (state->mode == GZ_READ) { | ||||
|         state->start = LSEEK(state->fd, 0, SEEK_CUR); | ||||
|         if (state->start == -1) state->start = 0; | ||||
|     } | ||||
|  | ||||
|     /* initialize stream */ | ||||
|     gz_reset(state); | ||||
|  | ||||
|     /* return stream */ | ||||
|     return (gzFile)state; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| gzFile ZEXPORT gzopen(path, mode) | ||||
|     const char *path; | ||||
|     const char *mode; | ||||
| { | ||||
|     return gz_open(path, -1, mode); | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| gzFile ZEXPORT gzopen64(path, mode) | ||||
|     const char *path; | ||||
|     const char *mode; | ||||
| { | ||||
|     return gz_open(path, -1, mode); | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| gzFile ZEXPORT gzdopen(fd, mode) | ||||
|     int fd; | ||||
|     const char *mode; | ||||
| { | ||||
|     char *path;         /* identifier for error messages */ | ||||
|     gzFile gz; | ||||
|  | ||||
|     if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL) | ||||
|         return NULL; | ||||
|     sprintf(path, "<fd:%d>", fd);   /* for debugging */ | ||||
|     gz = gz_open(path, fd, mode); | ||||
|     free(path); | ||||
|     return gz; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| #ifdef _WIN32 | ||||
| gzFile ZEXPORT gzopen_w(path, mode) | ||||
|     const wchar_t *path; | ||||
|     const char *mode; | ||||
| { | ||||
|     return gz_open(path, -2, mode); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzbuffer(file, size) | ||||
|     gzFile file; | ||||
|     unsigned size; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return -1; | ||||
|  | ||||
|     /* make sure we haven't already allocated memory */ | ||||
|     if (state->size != 0) | ||||
|         return -1; | ||||
|  | ||||
|     /* check and set requested size */ | ||||
|     if (size < 2) | ||||
|         size = 2;               /* need two bytes to check magic header */ | ||||
|     state->want = size; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzrewind(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're reading and that there's no error */ | ||||
|     if (state->mode != GZ_READ || | ||||
|             (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||||
|         return -1; | ||||
|  | ||||
|     /* back up and start over */ | ||||
|     if (LSEEK(state->fd, state->start, SEEK_SET) == -1) | ||||
|         return -1; | ||||
|     gz_reset(state); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| z_off64_t ZEXPORT gzseek64(file, offset, whence) | ||||
|     gzFile file; | ||||
|     z_off64_t offset; | ||||
|     int whence; | ||||
| { | ||||
|     unsigned n; | ||||
|     z_off64_t ret; | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return -1; | ||||
|  | ||||
|     /* check that there's no error */ | ||||
|     if (state->err != Z_OK && state->err != Z_BUF_ERROR) | ||||
|         return -1; | ||||
|  | ||||
|     /* can only seek from start or relative to current position */ | ||||
|     if (whence != SEEK_SET && whence != SEEK_CUR) | ||||
|         return -1; | ||||
|  | ||||
|     /* normalize offset to a SEEK_CUR specification */ | ||||
|     if (whence == SEEK_SET) | ||||
|         offset -= state->x.pos; | ||||
|     else if (state->seek) | ||||
|         offset += state->skip; | ||||
|     state->seek = 0; | ||||
|  | ||||
|     /* if within raw area while reading, just go there */ | ||||
|     if (state->mode == GZ_READ && state->how == COPY && | ||||
|             state->x.pos + offset >= 0) { | ||||
|         ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); | ||||
|         if (ret == -1) | ||||
|             return -1; | ||||
|         state->x.have = 0; | ||||
|         state->eof = 0; | ||||
|         state->past = 0; | ||||
|         state->seek = 0; | ||||
|         gz_error(state, Z_OK, NULL); | ||||
|         state->strm.avail_in = 0; | ||||
|         state->x.pos += offset; | ||||
|         return state->x.pos; | ||||
|     } | ||||
|  | ||||
|     /* calculate skip amount, rewinding if needed for back seek when reading */ | ||||
|     if (offset < 0) { | ||||
|         if (state->mode != GZ_READ)         /* writing -- can't go backwards */ | ||||
|             return -1; | ||||
|         offset += state->x.pos; | ||||
|         if (offset < 0)                     /* before start of file! */ | ||||
|             return -1; | ||||
|         if (gzrewind(file) == -1)           /* rewind, then skip to offset */ | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     /* if reading, skip what's in output buffer (one less gzgetc() check) */ | ||||
|     if (state->mode == GZ_READ) { | ||||
|         n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? | ||||
|             (unsigned)offset : state->x.have; | ||||
|         state->x.have -= n; | ||||
|         state->x.next += n; | ||||
|         state->x.pos += n; | ||||
|         offset -= n; | ||||
|     } | ||||
|  | ||||
|     /* request skip (if not zero) */ | ||||
|     if (offset) { | ||||
|         state->seek = 1; | ||||
|         state->skip = offset; | ||||
|     } | ||||
|     return state->x.pos + offset; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| z_off_t ZEXPORT gzseek(file, offset, whence) | ||||
|     gzFile file; | ||||
|     z_off_t offset; | ||||
|     int whence; | ||||
| { | ||||
|     z_off64_t ret; | ||||
|  | ||||
|     ret = gzseek64(file, (z_off64_t)offset, whence); | ||||
|     return ret == (z_off_t)ret ? (z_off_t)ret : -1; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| z_off64_t ZEXPORT gztell64(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return -1; | ||||
|  | ||||
|     /* return position */ | ||||
|     return state->x.pos + (state->seek ? state->skip : 0); | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| z_off_t ZEXPORT gztell(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     z_off64_t ret; | ||||
|  | ||||
|     ret = gztell64(file); | ||||
|     return ret == (z_off_t)ret ? (z_off_t)ret : -1; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| z_off64_t ZEXPORT gzoffset64(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     z_off64_t offset; | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return -1; | ||||
|  | ||||
|     /* compute and return effective offset in file */ | ||||
|     offset = LSEEK(state->fd, 0, SEEK_CUR); | ||||
|     if (offset == -1) | ||||
|         return -1; | ||||
|     if (state->mode == GZ_READ)             /* reading */ | ||||
|         offset -= state->strm.avail_in;     /* don't count buffered input */ | ||||
|     return offset; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| z_off_t ZEXPORT gzoffset(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     z_off64_t ret; | ||||
|  | ||||
|     ret = gzoffset64(file); | ||||
|     return ret == (z_off_t)ret ? (z_off_t)ret : -1; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzeof(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return 0; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return 0; | ||||
|  | ||||
|     /* return end-of-file state */ | ||||
|     return state->mode == GZ_READ ? state->past : 0; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| const char * ZEXPORT gzerror(file, errnum) | ||||
|     gzFile file; | ||||
|     int *errnum; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return NULL; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return NULL; | ||||
|  | ||||
|     /* return error information */ | ||||
|     if (errnum != NULL) | ||||
|         *errnum = state->err; | ||||
|     return state->msg == NULL ? "" : state->msg; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| void ZEXPORT gzclearerr(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure and check integrity */ | ||||
|     if (file == NULL) | ||||
|         return; | ||||
|     state = (gz_statep)file; | ||||
|     if (state->mode != GZ_READ && state->mode != GZ_WRITE) | ||||
|         return; | ||||
|  | ||||
|     /* clear error and end-of-file */ | ||||
|     if (state->mode == GZ_READ) { | ||||
|         state->eof = 0; | ||||
|         state->past = 0; | ||||
|     } | ||||
|     gz_error(state, Z_OK, NULL); | ||||
| } | ||||
|  | ||||
| /* Create an error message in allocated memory and set state->err and | ||||
|    state->msg accordingly.  Free any previous error message already there.  Do | ||||
|    not try to free or allocate space if the error is Z_MEM_ERROR (out of | ||||
|    memory).  Simply save the error message as a static string.  If there is an | ||||
|    allocation failure constructing the error message, then convert the error to | ||||
|    out of memory. */ | ||||
| void ZLIB_INTERNAL gz_error(state, err, msg) | ||||
|     gz_statep state; | ||||
|     int err; | ||||
|     const char *msg; | ||||
| { | ||||
|     /* free previously allocated message and clear */ | ||||
|     if (state->msg != NULL) { | ||||
|         if (state->err != Z_MEM_ERROR) | ||||
|             free(state->msg); | ||||
|         state->msg = NULL; | ||||
|     } | ||||
|  | ||||
|     /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ | ||||
|     if (err != Z_OK && err != Z_BUF_ERROR) | ||||
|         state->x.have = 0; | ||||
|  | ||||
|     /* set error code, and if no message, then done */ | ||||
|     state->err = err; | ||||
|     if (msg == NULL) | ||||
|         return; | ||||
|  | ||||
|     /* for an out of memory error, save as static string */ | ||||
|     if (err == Z_MEM_ERROR) { | ||||
|         state->msg = (char *)msg; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /* construct error message with path */ | ||||
|     if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { | ||||
|         state->err = Z_MEM_ERROR; | ||||
|         state->msg = (char *)"out of memory"; | ||||
|         return; | ||||
|     } | ||||
|     strcpy(state->msg, state->path); | ||||
|     strcat(state->msg, ": "); | ||||
|     strcat(state->msg, msg); | ||||
|     return; | ||||
| } | ||||
|  | ||||
| #ifndef INT_MAX | ||||
| /* portably return maximum value for an int (when limits.h presumed not | ||||
|    available) -- we need to do this to cover cases where 2's complement not | ||||
|    used, since C standard permits 1's complement and sign-bit representations, | ||||
|    otherwise we could just use ((unsigned)-1) >> 1 */ | ||||
| unsigned ZLIB_INTERNAL gz_intmax() | ||||
| { | ||||
|     unsigned p, q; | ||||
|  | ||||
|     p = 1; | ||||
|     do { | ||||
|         q = p; | ||||
|         p <<= 1; | ||||
|         p++; | ||||
|     } while (p > q); | ||||
|     return q >> 1; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										589
									
								
								Foundation/src/gzread.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										589
									
								
								Foundation/src/gzread.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,589 @@ | ||||
| /* gzread.c -- zlib functions for reading gzip files | ||||
|  * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler | ||||
|  * For conditions of distribution and use, see copyright notice in zlib.h | ||||
|  */ | ||||
|  | ||||
| #include "gzguts.h" | ||||
|  | ||||
| /* Local functions */ | ||||
| local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); | ||||
| local int gz_avail OF((gz_statep)); | ||||
| local int gz_look OF((gz_statep)); | ||||
| local int gz_decomp OF((gz_statep)); | ||||
| local int gz_fetch OF((gz_statep)); | ||||
| local int gz_skip OF((gz_statep, z_off64_t)); | ||||
|  | ||||
| /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from | ||||
|    state->fd, and update state->eof, state->err, and state->msg as appropriate. | ||||
|    This function needs to loop on read(), since read() is not guaranteed to | ||||
|    read the number of bytes requested, depending on the type of descriptor. */ | ||||
| local int gz_load(state, buf, len, have) | ||||
|     gz_statep state; | ||||
|     unsigned char *buf; | ||||
|     unsigned len; | ||||
|     unsigned *have; | ||||
| { | ||||
|     int ret; | ||||
|  | ||||
|     *have = 0; | ||||
|     do { | ||||
|         ret = read(state->fd, buf + *have, len - *have); | ||||
|         if (ret <= 0) | ||||
|             break; | ||||
|         *have += ret; | ||||
|     } while (*have < len); | ||||
|     if (ret < 0) { | ||||
|         gz_error(state, Z_ERRNO, zstrerror()); | ||||
|         return -1; | ||||
|     } | ||||
|     if (ret == 0) | ||||
|         state->eof = 1; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Load up input buffer and set eof flag if last data loaded -- return -1 on | ||||
|    error, 0 otherwise.  Note that the eof flag is set when the end of the input | ||||
|    file is reached, even though there may be unused data in the buffer.  Once | ||||
|    that data has been used, no more attempts will be made to read the file. | ||||
|    If strm->avail_in != 0, then the current data is moved to the beginning of | ||||
|    the input buffer, and then the remainder of the buffer is loaded with the | ||||
|    available data from the input file. */ | ||||
| local int gz_avail(state) | ||||
|     gz_statep state; | ||||
| { | ||||
|     unsigned got; | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     if (state->err != Z_OK && state->err != Z_BUF_ERROR) | ||||
|         return -1; | ||||
|     if (state->eof == 0) { | ||||
|         if (strm->avail_in) {       /* copy what's there to the start */ | ||||
|             unsigned char *p = state->in, *q = strm->next_in; | ||||
|             unsigned n = strm->avail_in; | ||||
|             do { | ||||
|                 *p++ = *q++; | ||||
|             } while (--n); | ||||
|         } | ||||
|         if (gz_load(state, state->in + strm->avail_in, | ||||
|                     state->size - strm->avail_in, &got) == -1) | ||||
|             return -1; | ||||
|         strm->avail_in += got; | ||||
|         strm->next_in = state->in; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0. | ||||
|    If this is the first time in, allocate required memory.  state->how will be | ||||
|    left unchanged if there is no more input data available, will be set to COPY | ||||
|    if there is no gzip header and direct copying will be performed, or it will | ||||
|    be set to GZIP for decompression.  If direct copying, then leftover input | ||||
|    data from the input buffer will be copied to the output buffer.  In that | ||||
|    case, all further file reads will be directly to either the output buffer or | ||||
|    a user buffer.  If decompressing, the inflate state will be initialized. | ||||
|    gz_look() will return 0 on success or -1 on failure. */ | ||||
| local int gz_look(state) | ||||
|     gz_statep state; | ||||
| { | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     /* allocate read buffers and inflate memory */ | ||||
|     if (state->size == 0) { | ||||
|         /* allocate buffers */ | ||||
|         state->in = malloc(state->want); | ||||
|         state->out = malloc(state->want << 1); | ||||
|         if (state->in == NULL || state->out == NULL) { | ||||
|             if (state->out != NULL) | ||||
|                 free(state->out); | ||||
|             if (state->in != NULL) | ||||
|                 free(state->in); | ||||
|             gz_error(state, Z_MEM_ERROR, "out of memory"); | ||||
|             return -1; | ||||
|         } | ||||
|         state->size = state->want; | ||||
|  | ||||
|         /* allocate inflate memory */ | ||||
|         state->strm.zalloc = Z_NULL; | ||||
|         state->strm.zfree = Z_NULL; | ||||
|         state->strm.opaque = Z_NULL; | ||||
|         state->strm.avail_in = 0; | ||||
|         state->strm.next_in = Z_NULL; | ||||
|         if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */ | ||||
|             free(state->out); | ||||
|             free(state->in); | ||||
|             state->size = 0; | ||||
|             gz_error(state, Z_MEM_ERROR, "out of memory"); | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* get at least the magic bytes in the input buffer */ | ||||
|     if (strm->avail_in < 2) { | ||||
|         if (gz_avail(state) == -1) | ||||
|             return -1; | ||||
|         if (strm->avail_in == 0) | ||||
|             return 0; | ||||
|     } | ||||
|  | ||||
|     /* look for gzip magic bytes -- if there, do gzip decoding (note: there is | ||||
|        a logical dilemma here when considering the case of a partially written | ||||
|        gzip file, to wit, if a single 31 byte is written, then we cannot tell | ||||
|        whether this is a single-byte file, or just a partially written gzip | ||||
|        file -- for here we assume that if a gzip file is being written, then | ||||
|        the header will be written in a single operation, so that reading a | ||||
|        single byte is sufficient indication that it is not a gzip file) */ | ||||
|     if (strm->avail_in > 1 && | ||||
|             strm->next_in[0] == 31 && strm->next_in[1] == 139) { | ||||
|         inflateReset(strm); | ||||
|         state->how = GZIP; | ||||
|         state->direct = 0; | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* no gzip header -- if we were decoding gzip before, then this is trailing | ||||
|        garbage.  Ignore the trailing garbage and finish. */ | ||||
|     if (state->direct == 0) { | ||||
|         strm->avail_in = 0; | ||||
|         state->eof = 1; | ||||
|         state->x.have = 0; | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* doing raw i/o, copy any leftover input to output -- this assumes that | ||||
|        the output buffer is larger than the input buffer, which also assures | ||||
|        space for gzungetc() */ | ||||
|     state->x.next = state->out; | ||||
|     if (strm->avail_in) { | ||||
|         memcpy(state->x.next, strm->next_in, strm->avail_in); | ||||
|         state->x.have = strm->avail_in; | ||||
|         strm->avail_in = 0; | ||||
|     } | ||||
|     state->how = COPY; | ||||
|     state->direct = 1; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Decompress from input to the provided next_out and avail_out in the state. | ||||
|    On return, state->x.have and state->x.next point to the just decompressed | ||||
|    data.  If the gzip stream completes, state->how is reset to LOOK to look for | ||||
|    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0 | ||||
|    on success, -1 on failure. */ | ||||
| local int gz_decomp(state) | ||||
|     gz_statep state; | ||||
| { | ||||
|     int ret = Z_OK; | ||||
|     unsigned had; | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     /* fill output buffer up to end of deflate stream */ | ||||
|     had = strm->avail_out; | ||||
|     do { | ||||
|         /* get more input for inflate() */ | ||||
|         if (strm->avail_in == 0 && gz_avail(state) == -1) | ||||
|             return -1; | ||||
|         if (strm->avail_in == 0) { | ||||
|             gz_error(state, Z_BUF_ERROR, "unexpected end of file"); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         /* decompress and handle errors */ | ||||
|         ret = inflate(strm, Z_NO_FLUSH); | ||||
|         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { | ||||
|             gz_error(state, Z_STREAM_ERROR, | ||||
|                      "internal error: inflate stream corrupt"); | ||||
|             return -1; | ||||
|         } | ||||
|         if (ret == Z_MEM_ERROR) { | ||||
|             gz_error(state, Z_MEM_ERROR, "out of memory"); | ||||
|             return -1; | ||||
|         } | ||||
|         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */ | ||||
|             gz_error(state, Z_DATA_ERROR, | ||||
|                      strm->msg == NULL ? "compressed data error" : strm->msg); | ||||
|             return -1; | ||||
|         } | ||||
|     } while (strm->avail_out && ret != Z_STREAM_END); | ||||
|  | ||||
|     /* update available output */ | ||||
|     state->x.have = had - strm->avail_out; | ||||
|     state->x.next = strm->next_out - state->x.have; | ||||
|  | ||||
|     /* if the gzip stream completed successfully, look for another */ | ||||
|     if (ret == Z_STREAM_END) | ||||
|         state->how = LOOK; | ||||
|  | ||||
|     /* good decompression */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0. | ||||
|    Data is either copied from the input file or decompressed from the input | ||||
|    file depending on state->how.  If state->how is LOOK, then a gzip header is | ||||
|    looked for to determine whether to copy or decompress.  Returns -1 on error, | ||||
|    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the | ||||
|    end of the input file has been reached and all data has been processed.  */ | ||||
| local int gz_fetch(state) | ||||
|     gz_statep state; | ||||
| { | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     do { | ||||
|         switch(state->how) { | ||||
|         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */ | ||||
|             if (gz_look(state) == -1) | ||||
|                 return -1; | ||||
|             if (state->how == LOOK) | ||||
|                 return 0; | ||||
|             break; | ||||
|         case COPY:      /* -> COPY */ | ||||
|             if (gz_load(state, state->out, state->size << 1, &(state->x.have)) | ||||
|                     == -1) | ||||
|                 return -1; | ||||
|             state->x.next = state->out; | ||||
|             return 0; | ||||
|         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */ | ||||
|             strm->avail_out = state->size << 1; | ||||
|             strm->next_out = state->out; | ||||
|             if (gz_decomp(state) == -1) | ||||
|                 return -1; | ||||
|         } | ||||
|     } while (state->x.have == 0 && (!state->eof || strm->avail_in)); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */ | ||||
| local int gz_skip(state, len) | ||||
|     gz_statep state; | ||||
|     z_off64_t len; | ||||
| { | ||||
|     unsigned n; | ||||
|  | ||||
|     /* skip over len bytes or reach end-of-file, whichever comes first */ | ||||
|     while (len) | ||||
|         /* skip over whatever is in output buffer */ | ||||
|         if (state->x.have) { | ||||
|             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? | ||||
|                 (unsigned)len : state->x.have; | ||||
|             state->x.have -= n; | ||||
|             state->x.next += n; | ||||
|             state->x.pos += n; | ||||
|             len -= n; | ||||
|         } | ||||
|  | ||||
|         /* output buffer empty -- return if we're at the end of the input */ | ||||
|         else if (state->eof && state->strm.avail_in == 0) | ||||
|             break; | ||||
|  | ||||
|         /* need more data to skip -- load up output buffer */ | ||||
|         else { | ||||
|             /* get more output, looking for header if required */ | ||||
|             if (gz_fetch(state) == -1) | ||||
|                 return -1; | ||||
|         } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzread(file, buf, len) | ||||
|     gzFile file; | ||||
|     voidp buf; | ||||
|     unsigned len; | ||||
| { | ||||
|     unsigned got, n; | ||||
|     gz_statep state; | ||||
|     z_streamp strm; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     strm = &(state->strm); | ||||
|  | ||||
|     /* check that we're reading and that there's no (serious) error */ | ||||
|     if (state->mode != GZ_READ || | ||||
|             (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||||
|         return -1; | ||||
|  | ||||
|     /* since an int is returned, make sure len fits in one, otherwise return | ||||
|        with an error (this avoids the flaw in the interface) */ | ||||
|     if ((int)len < 0) { | ||||
|         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     /* if len is zero, avoid unnecessary operations */ | ||||
|     if (len == 0) | ||||
|         return 0; | ||||
|  | ||||
|     /* process a skip request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_skip(state, state->skip) == -1) | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     /* get len bytes to buf, or less than len if at the end */ | ||||
|     got = 0; | ||||
|     do { | ||||
|         /* first just try copying data from the output buffer */ | ||||
|         if (state->x.have) { | ||||
|             n = state->x.have > len ? len : state->x.have; | ||||
|             memcpy(buf, state->x.next, n); | ||||
|             state->x.next += n; | ||||
|             state->x.have -= n; | ||||
|         } | ||||
|  | ||||
|         /* output buffer empty -- return if we're at the end of the input */ | ||||
|         else if (state->eof && strm->avail_in == 0) { | ||||
|             state->past = 1;        /* tried to read past end */ | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         /* need output data -- for small len or new stream load up our output | ||||
|            buffer */ | ||||
|         else if (state->how == LOOK || len < (state->size << 1)) { | ||||
|             /* get more output, looking for header if required */ | ||||
|             if (gz_fetch(state) == -1) | ||||
|                 return -1; | ||||
|             continue;       /* no progress yet -- go back to copy above */ | ||||
|             /* the copy above assures that we will leave with space in the | ||||
|                output buffer, allowing at least one gzungetc() to succeed */ | ||||
|         } | ||||
|  | ||||
|         /* large len -- read directly into user buffer */ | ||||
|         else if (state->how == COPY) {      /* read directly */ | ||||
|             if (gz_load(state, buf, len, &n) == -1) | ||||
|                 return -1; | ||||
|         } | ||||
|  | ||||
|         /* large len -- decompress directly into user buffer */ | ||||
|         else {  /* state->how == GZIP */ | ||||
|             strm->avail_out = len; | ||||
|             strm->next_out = buf; | ||||
|             if (gz_decomp(state) == -1) | ||||
|                 return -1; | ||||
|             n = state->x.have; | ||||
|             state->x.have = 0; | ||||
|         } | ||||
|  | ||||
|         /* update progress */ | ||||
|         len -= n; | ||||
|         buf = (char *)buf + n; | ||||
|         got += n; | ||||
|         state->x.pos += n; | ||||
|     } while (len); | ||||
|  | ||||
|     /* return number of bytes read into user buffer (will fit in int) */ | ||||
|     return (int)got; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| #undef gzgetc | ||||
| int ZEXPORT gzgetc(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     int ret; | ||||
|     unsigned char buf[1]; | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're reading and that there's no (serious) error */ | ||||
|     if (state->mode != GZ_READ || | ||||
|         (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||||
|         return -1; | ||||
|  | ||||
|     /* try output buffer (no need to check for skip request) */ | ||||
|     if (state->x.have) { | ||||
|         state->x.have--; | ||||
|         state->x.pos++; | ||||
|         return *(state->x.next)++; | ||||
|     } | ||||
|  | ||||
|     /* nothing there -- try gzread() */ | ||||
|     ret = gzread(file, buf, 1); | ||||
|     return ret < 1 ? -1 : buf[0]; | ||||
| } | ||||
|  | ||||
| int ZEXPORT gzgetc_(file) | ||||
| gzFile file; | ||||
| { | ||||
|     return gzgetc(file); | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzungetc(c, file) | ||||
|     int c; | ||||
|     gzFile file; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're reading and that there's no (serious) error */ | ||||
|     if (state->mode != GZ_READ || | ||||
|         (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||||
|         return -1; | ||||
|  | ||||
|     /* process a skip request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_skip(state, state->skip) == -1) | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     /* can't push EOF */ | ||||
|     if (c < 0) | ||||
|         return -1; | ||||
|  | ||||
|     /* if output buffer empty, put byte at end (allows more pushing) */ | ||||
|     if (state->x.have == 0) { | ||||
|         state->x.have = 1; | ||||
|         state->x.next = state->out + (state->size << 1) - 1; | ||||
|         state->x.next[0] = c; | ||||
|         state->x.pos--; | ||||
|         state->past = 0; | ||||
|         return c; | ||||
|     } | ||||
|  | ||||
|     /* if no room, give up (must have already done a gzungetc()) */ | ||||
|     if (state->x.have == (state->size << 1)) { | ||||
|         gz_error(state, Z_DATA_ERROR, "out of room to push characters"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     /* slide output data if needed and insert byte before existing data */ | ||||
|     if (state->x.next == state->out) { | ||||
|         unsigned char *src = state->out + state->x.have; | ||||
|         unsigned char *dest = state->out + (state->size << 1); | ||||
|         while (src > state->out) | ||||
|             *--dest = *--src; | ||||
|         state->x.next = dest; | ||||
|     } | ||||
|     state->x.have++; | ||||
|     state->x.next--; | ||||
|     state->x.next[0] = c; | ||||
|     state->x.pos--; | ||||
|     state->past = 0; | ||||
|     return c; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| char * ZEXPORT gzgets(file, buf, len) | ||||
|     gzFile file; | ||||
|     char *buf; | ||||
|     int len; | ||||
| { | ||||
|     unsigned left, n; | ||||
|     char *str; | ||||
|     unsigned char *eol; | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* check parameters and get internal structure */ | ||||
|     if (file == NULL || buf == NULL || len < 1) | ||||
|         return NULL; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're reading and that there's no (serious) error */ | ||||
|     if (state->mode != GZ_READ || | ||||
|         (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||||
|         return NULL; | ||||
|  | ||||
|     /* process a skip request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_skip(state, state->skip) == -1) | ||||
|             return NULL; | ||||
|     } | ||||
|  | ||||
|     /* copy output bytes up to new line or len - 1, whichever comes first -- | ||||
|        append a terminating zero to the string (we don't check for a zero in | ||||
|        the contents, let the user worry about that) */ | ||||
|     str = buf; | ||||
|     left = (unsigned)len - 1; | ||||
|     if (left) do { | ||||
|         /* assure that something is in the output buffer */ | ||||
|         if (state->x.have == 0 && gz_fetch(state) == -1) | ||||
|             return NULL;                /* error */ | ||||
|         if (state->x.have == 0) {       /* end of file */ | ||||
|             state->past = 1;            /* read past end */ | ||||
|             break;                      /* return what we have */ | ||||
|         } | ||||
|  | ||||
|         /* look for end-of-line in current output buffer */ | ||||
|         n = state->x.have > left ? left : state->x.have; | ||||
|         eol = memchr(state->x.next, '\n', n); | ||||
|         if (eol != NULL) | ||||
|             n = (unsigned)(eol - state->x.next) + 1; | ||||
|  | ||||
|         /* copy through end-of-line, or remainder if not found */ | ||||
|         memcpy(buf, state->x.next, n); | ||||
|         state->x.have -= n; | ||||
|         state->x.next += n; | ||||
|         state->x.pos += n; | ||||
|         left -= n; | ||||
|         buf += n; | ||||
|     } while (left && eol == NULL); | ||||
|  | ||||
|     /* return terminated string, or if nothing, end of file */ | ||||
|     if (buf == str) | ||||
|         return NULL; | ||||
|     buf[0] = 0; | ||||
|     return str; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzdirect(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return 0; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* if the state is not known, but we can find out, then do so (this is | ||||
|        mainly for right after a gzopen() or gzdopen()) */ | ||||
|     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) | ||||
|         (void)gz_look(state); | ||||
|  | ||||
|     /* return 1 if transparent, 0 if processing a gzip stream */ | ||||
|     return state->direct; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzclose_r(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     int ret, err; | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return Z_STREAM_ERROR; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're reading */ | ||||
|     if (state->mode != GZ_READ) | ||||
|         return Z_STREAM_ERROR; | ||||
|  | ||||
|     /* free memory and close file */ | ||||
|     if (state->size) { | ||||
|         inflateEnd(&(state->strm)); | ||||
|         free(state->out); | ||||
|         free(state->in); | ||||
|     } | ||||
|     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; | ||||
|     gz_error(state, Z_OK, NULL); | ||||
|     free(state->path); | ||||
|     ret = close(state->fd); | ||||
|     free(state); | ||||
|     return ret ? Z_ERRNO : err; | ||||
| } | ||||
							
								
								
									
										565
									
								
								Foundation/src/gzwrite.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										565
									
								
								Foundation/src/gzwrite.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,565 @@ | ||||
| /* gzwrite.c -- zlib functions for writing gzip files | ||||
|  * Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler | ||||
|  * For conditions of distribution and use, see copyright notice in zlib.h | ||||
|  */ | ||||
|  | ||||
| #include "gzguts.h" | ||||
|  | ||||
| /* Local functions */ | ||||
| local int gz_init OF((gz_statep)); | ||||
| local int gz_comp OF((gz_statep, int)); | ||||
| local int gz_zero OF((gz_statep, z_off64_t)); | ||||
|  | ||||
| /* Initialize state for writing a gzip file.  Mark initialization by setting | ||||
|    state->size to non-zero.  Return -1 on failure or 0 on success. */ | ||||
| local int gz_init(state) | ||||
|     gz_statep state; | ||||
| { | ||||
|     int ret; | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     /* allocate input buffer */ | ||||
|     state->in = malloc(state->want); | ||||
|     if (state->in == NULL) { | ||||
|         gz_error(state, Z_MEM_ERROR, "out of memory"); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     /* only need output buffer and deflate state if compressing */ | ||||
|     if (!state->direct) { | ||||
|         /* allocate output buffer */ | ||||
|         state->out = malloc(state->want); | ||||
|         if (state->out == NULL) { | ||||
|             free(state->in); | ||||
|             gz_error(state, Z_MEM_ERROR, "out of memory"); | ||||
|             return -1; | ||||
|         } | ||||
|  | ||||
|         /* allocate deflate memory, set up for gzip compression */ | ||||
|         strm->zalloc = Z_NULL; | ||||
|         strm->zfree = Z_NULL; | ||||
|         strm->opaque = Z_NULL; | ||||
|         ret = deflateInit2(strm, state->level, Z_DEFLATED, | ||||
|                            MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); | ||||
|         if (ret != Z_OK) { | ||||
|             free(state->out); | ||||
|             free(state->in); | ||||
|             gz_error(state, Z_MEM_ERROR, "out of memory"); | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* mark state as initialized */ | ||||
|     state->size = state->want; | ||||
|  | ||||
|     /* initialize write buffer if compressing */ | ||||
|     if (!state->direct) { | ||||
|         strm->avail_out = state->size; | ||||
|         strm->next_out = state->out; | ||||
|         state->x.next = strm->next_out; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Compress whatever is at avail_in and next_in and write to the output file. | ||||
|    Return -1 if there is an error writing to the output file, otherwise 0. | ||||
|    flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH, | ||||
|    then the deflate() state is reset to start a new gzip stream.  If gz->direct | ||||
|    is true, then simply write to the output file without compressing, and | ||||
|    ignore flush. */ | ||||
| local int gz_comp(state, flush) | ||||
|     gz_statep state; | ||||
|     int flush; | ||||
| { | ||||
|     int ret, got; | ||||
|     unsigned have; | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     /* allocate memory if this is the first time through */ | ||||
|     if (state->size == 0 && gz_init(state) == -1) | ||||
|         return -1; | ||||
|  | ||||
|     /* write directly if requested */ | ||||
|     if (state->direct) { | ||||
|         got = write(state->fd, strm->next_in, strm->avail_in); | ||||
|         if (got < 0 || (unsigned)got != strm->avail_in) { | ||||
|             gz_error(state, Z_ERRNO, zstrerror()); | ||||
|             return -1; | ||||
|         } | ||||
|         strm->avail_in = 0; | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* run deflate() on provided input until it produces no more output */ | ||||
|     ret = Z_OK; | ||||
|     do { | ||||
|         /* write out current buffer contents if full, or if flushing, but if | ||||
|            doing Z_FINISH then don't write until we get to Z_STREAM_END */ | ||||
|         if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && | ||||
|             (flush != Z_FINISH || ret == Z_STREAM_END))) { | ||||
|             have = (unsigned)(strm->next_out - state->x.next); | ||||
|             if (have && ((got = write(state->fd, state->x.next, have)) < 0 || | ||||
|                          (unsigned)got != have)) { | ||||
|                 gz_error(state, Z_ERRNO, zstrerror()); | ||||
|                 return -1; | ||||
|             } | ||||
|             if (strm->avail_out == 0) { | ||||
|                 strm->avail_out = state->size; | ||||
|                 strm->next_out = state->out; | ||||
|             } | ||||
|             state->x.next = strm->next_out; | ||||
|         } | ||||
|  | ||||
|         /* compress */ | ||||
|         have = strm->avail_out; | ||||
|         ret = deflate(strm, flush); | ||||
|         if (ret == Z_STREAM_ERROR) { | ||||
|             gz_error(state, Z_STREAM_ERROR, | ||||
|                       "internal error: deflate stream corrupt"); | ||||
|             return -1; | ||||
|         } | ||||
|         have -= strm->avail_out; | ||||
|     } while (have); | ||||
|  | ||||
|     /* if that completed a deflate stream, allow another to start */ | ||||
|     if (flush == Z_FINISH) | ||||
|         deflateReset(strm); | ||||
|  | ||||
|     /* all done, no errors */ | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Compress len zeros to output.  Return -1 on error, 0 on success. */ | ||||
| local int gz_zero(state, len) | ||||
|     gz_statep state; | ||||
|     z_off64_t len; | ||||
| { | ||||
|     int first; | ||||
|     unsigned n; | ||||
|     z_streamp strm = &(state->strm); | ||||
|  | ||||
|     /* consume whatever's left in the input buffer */ | ||||
|     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|         return -1; | ||||
|  | ||||
|     /* compress len zeros (len guaranteed > 0) */ | ||||
|     first = 1; | ||||
|     while (len) { | ||||
|         n = GT_OFF(state->size) || (z_off64_t)state->size > len ? | ||||
|             (unsigned)len : state->size; | ||||
|         if (first) { | ||||
|             memset(state->in, 0, n); | ||||
|             first = 0; | ||||
|         } | ||||
|         strm->avail_in = n; | ||||
|         strm->next_in = state->in; | ||||
|         state->x.pos += n; | ||||
|         if (gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|             return -1; | ||||
|         len -= n; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzwrite(file, buf, len) | ||||
|     gzFile file; | ||||
|     voidpc buf; | ||||
|     unsigned len; | ||||
| { | ||||
|     unsigned put = len; | ||||
|     unsigned n; | ||||
|     gz_statep state; | ||||
|     z_streamp strm; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return 0; | ||||
|     state = (gz_statep)file; | ||||
|     strm = &(state->strm); | ||||
|  | ||||
|     /* check that we're writing and that there's no error */ | ||||
|     if (state->mode != GZ_WRITE || state->err != Z_OK) | ||||
|         return 0; | ||||
|  | ||||
|     /* since an int is returned, make sure len fits in one, otherwise return | ||||
|        with an error (this avoids the flaw in the interface) */ | ||||
|     if ((int)len < 0) { | ||||
|         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* if len is zero, avoid unnecessary operations */ | ||||
|     if (len == 0) | ||||
|         return 0; | ||||
|  | ||||
|     /* allocate memory if this is the first time through */ | ||||
|     if (state->size == 0 && gz_init(state) == -1) | ||||
|         return 0; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             return 0; | ||||
|     } | ||||
|  | ||||
|     /* for small len, copy to input buffer, otherwise compress directly */ | ||||
|     if (len < state->size) { | ||||
|         /* copy to input buffer, compress when full */ | ||||
|         do { | ||||
|             if (strm->avail_in == 0) | ||||
|                 strm->next_in = state->in; | ||||
|             n = state->size - strm->avail_in; | ||||
|             if (n > len) | ||||
|                 n = len; | ||||
|             memcpy(strm->next_in + strm->avail_in, buf, n); | ||||
|             strm->avail_in += n; | ||||
|             state->x.pos += n; | ||||
|             buf = (char *)buf + n; | ||||
|             len -= n; | ||||
|             if (len && gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|                 return 0; | ||||
|         } while (len); | ||||
|     } | ||||
|     else { | ||||
|         /* consume whatever's left in the input buffer */ | ||||
|         if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|             return 0; | ||||
|  | ||||
|         /* directly compress user buffer to file */ | ||||
|         strm->avail_in = len; | ||||
|         strm->next_in = (voidp)buf; | ||||
|         state->x.pos += len; | ||||
|         if (gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|             return 0; | ||||
|     } | ||||
|  | ||||
|     /* input was all buffered or compressed (put will fit in int) */ | ||||
|     return (int)put; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzputc(file, c) | ||||
|     gzFile file; | ||||
|     int c; | ||||
| { | ||||
|     unsigned char buf[1]; | ||||
|     gz_statep state; | ||||
|     z_streamp strm; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     strm = &(state->strm); | ||||
|  | ||||
|     /* check that we're writing and that there's no error */ | ||||
|     if (state->mode != GZ_WRITE || state->err != Z_OK) | ||||
|         return -1; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     /* try writing to input buffer for speed (state->size == 0 if buffer not | ||||
|        initialized) */ | ||||
|     if (strm->avail_in < state->size) { | ||||
|         if (strm->avail_in == 0) | ||||
|             strm->next_in = state->in; | ||||
|         strm->next_in[strm->avail_in++] = c; | ||||
|         state->x.pos++; | ||||
|         return c & 0xff; | ||||
|     } | ||||
|  | ||||
|     /* no room in buffer or not initialized, use gz_write() */ | ||||
|     buf[0] = c; | ||||
|     if (gzwrite(file, buf, 1) != 1) | ||||
|         return -1; | ||||
|     return c & 0xff; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzputs(file, str) | ||||
|     gzFile file; | ||||
|     const char *str; | ||||
| { | ||||
|     int ret; | ||||
|     unsigned len; | ||||
|  | ||||
|     /* write string */ | ||||
|     len = (unsigned)strlen(str); | ||||
|     ret = gzwrite(file, str, len); | ||||
|     return ret == 0 && len != 0 ? -1 : ret; | ||||
| } | ||||
|  | ||||
| #if defined(STDC) || defined(Z_HAVE_STDARG_H) | ||||
| #include <stdarg.h> | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORTVA gzprintf (gzFile file, const char *format, ...) | ||||
| { | ||||
|     int size, len; | ||||
|     gz_statep state; | ||||
|     z_streamp strm; | ||||
|     va_list va; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     strm = &(state->strm); | ||||
|  | ||||
|     /* check that we're writing and that there's no error */ | ||||
|     if (state->mode != GZ_WRITE || state->err != Z_OK) | ||||
|         return 0; | ||||
|  | ||||
|     /* make sure we have some buffer space */ | ||||
|     if (state->size == 0 && gz_init(state) == -1) | ||||
|         return 0; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             return 0; | ||||
|     } | ||||
|  | ||||
|     /* consume whatever's left in the input buffer */ | ||||
|     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|         return 0; | ||||
|  | ||||
|     /* do the printf() into the input buffer, put length in len */ | ||||
|     size = (int)(state->size); | ||||
|     state->in[size - 1] = 0; | ||||
|     va_start(va, format); | ||||
| #ifdef NO_vsnprintf | ||||
| #  ifdef HAS_vsprintf_void | ||||
|     (void)vsprintf((char *)(state->in), format, va); | ||||
|     va_end(va); | ||||
|     for (len = 0; len < size; len++) | ||||
|         if (state->in[len] == 0) break; | ||||
| #  else | ||||
|     len = vsprintf((char *)(state->in), format, va); | ||||
|     va_end(va); | ||||
| #  endif | ||||
| #else | ||||
| #  ifdef HAS_vsnprintf_void | ||||
|     (void)vsnprintf((char *)(state->in), size, format, va); | ||||
|     va_end(va); | ||||
|     len = strlen((char *)(state->in)); | ||||
| #  else | ||||
|     len = vsnprintf((char *)(state->in), size, format, va); | ||||
|     va_end(va); | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
|     /* check that printf() results fit in buffer */ | ||||
|     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) | ||||
|         return 0; | ||||
|  | ||||
|     /* update buffer and position, defer compression until needed */ | ||||
|     strm->avail_in = (unsigned)len; | ||||
|     strm->next_in = state->in; | ||||
|     state->x.pos += len; | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| #else /* !STDC && !Z_HAVE_STDARG_H */ | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, | ||||
|                        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) | ||||
|     gzFile file; | ||||
|     const char *format; | ||||
|     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, | ||||
|         a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; | ||||
| { | ||||
|     int size, len; | ||||
|     gz_statep state; | ||||
|     z_streamp strm; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|     strm = &(state->strm); | ||||
|  | ||||
|     /* check that can really pass pointer in ints */ | ||||
|     if (sizeof(int) != sizeof(void *)) | ||||
|         return 0; | ||||
|  | ||||
|     /* check that we're writing and that there's no error */ | ||||
|     if (state->mode != GZ_WRITE || state->err != Z_OK) | ||||
|         return 0; | ||||
|  | ||||
|     /* make sure we have some buffer space */ | ||||
|     if (state->size == 0 && gz_init(state) == -1) | ||||
|         return 0; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             return 0; | ||||
|     } | ||||
|  | ||||
|     /* consume whatever's left in the input buffer */ | ||||
|     if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) | ||||
|         return 0; | ||||
|  | ||||
|     /* do the printf() into the input buffer, put length in len */ | ||||
|     size = (int)(state->size); | ||||
|     state->in[size - 1] = 0; | ||||
| #ifdef NO_snprintf | ||||
| #  ifdef HAS_sprintf_void | ||||
|     sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, | ||||
|             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); | ||||
|     for (len = 0; len < size; len++) | ||||
|         if (state->in[len] == 0) break; | ||||
| #  else | ||||
|     len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, | ||||
|                   a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); | ||||
| #  endif | ||||
| #else | ||||
| #  ifdef HAS_snprintf_void | ||||
|     snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, | ||||
|              a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); | ||||
|     len = strlen((char *)(state->in)); | ||||
| #  else | ||||
|     len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, | ||||
|                    a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, | ||||
|                    a19, a20); | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
|     /* check that printf() results fit in buffer */ | ||||
|     if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) | ||||
|         return 0; | ||||
|  | ||||
|     /* update buffer and position, defer compression until needed */ | ||||
|     strm->avail_in = (unsigned)len; | ||||
|     strm->next_in = state->in; | ||||
|     state->x.pos += len; | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzflush(file, flush) | ||||
|     gzFile file; | ||||
|     int flush; | ||||
| { | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return -1; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're writing and that there's no error */ | ||||
|     if (state->mode != GZ_WRITE || state->err != Z_OK) | ||||
|         return Z_STREAM_ERROR; | ||||
|  | ||||
|     /* check flush parameter */ | ||||
|     if (flush < 0 || flush > Z_FINISH) | ||||
|         return Z_STREAM_ERROR; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     /* compress remaining data with requested flush */ | ||||
|     gz_comp(state, flush); | ||||
|     return state->err; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzsetparams(file, level, strategy) | ||||
|     gzFile file; | ||||
|     int level; | ||||
|     int strategy; | ||||
| { | ||||
|     gz_statep state; | ||||
|     z_streamp strm; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return Z_STREAM_ERROR; | ||||
|     state = (gz_statep)file; | ||||
|     strm = &(state->strm); | ||||
|  | ||||
|     /* check that we're writing and that there's no error */ | ||||
|     if (state->mode != GZ_WRITE || state->err != Z_OK) | ||||
|         return Z_STREAM_ERROR; | ||||
|  | ||||
|     /* if no change is requested, then do nothing */ | ||||
|     if (level == state->level && strategy == state->strategy) | ||||
|         return Z_OK; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             return -1; | ||||
|     } | ||||
|  | ||||
|     /* change compression parameters for subsequent input */ | ||||
|     if (state->size) { | ||||
|         /* flush previous input with previous parameters before changing */ | ||||
|         if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) | ||||
|             return state->err; | ||||
|         deflateParams(strm, level, strategy); | ||||
|     } | ||||
|     state->level = level; | ||||
|     state->strategy = strategy; | ||||
|     return Z_OK; | ||||
| } | ||||
|  | ||||
| /* -- see zlib.h -- */ | ||||
| int ZEXPORT gzclose_w(file) | ||||
|     gzFile file; | ||||
| { | ||||
|     int ret = Z_OK; | ||||
|     gz_statep state; | ||||
|  | ||||
|     /* get internal structure */ | ||||
|     if (file == NULL) | ||||
|         return Z_STREAM_ERROR; | ||||
|     state = (gz_statep)file; | ||||
|  | ||||
|     /* check that we're writing */ | ||||
|     if (state->mode != GZ_WRITE) | ||||
|         return Z_STREAM_ERROR; | ||||
|  | ||||
|     /* check for seek request */ | ||||
|     if (state->seek) { | ||||
|         state->seek = 0; | ||||
|         if (gz_zero(state, state->skip) == -1) | ||||
|             ret = state->err; | ||||
|     } | ||||
|  | ||||
|     /* flush, free memory, and close file */ | ||||
|     if (state->size) { | ||||
|         if (gz_comp(state, Z_FINISH) == -1) | ||||
|             ret = state->err; | ||||
|         if (!state->direct) { | ||||
|             (void)deflateEnd(&(state->strm)); | ||||
|             free(state->out); | ||||
|         } | ||||
|         free(state->in); | ||||
|     } | ||||
|     gz_error(state, Z_OK, NULL); | ||||
|     free(state->path); | ||||
|     if (close(state->fd) == -1) | ||||
|         ret = Z_ERRNO; | ||||
|     free(state); | ||||
|     return ret; | ||||
| } | ||||
							
								
								
									
										59
									
								
								Foundation/src/uncompr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Foundation/src/uncompr.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| /* uncompr.c -- decompress a memory buffer | ||||
|  * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. | ||||
|  * For conditions of distribution and use, see copyright notice in zlib.h | ||||
|  */ | ||||
|  | ||||
| /* @(#) $Id$ */ | ||||
|  | ||||
| #define ZLIB_INTERNAL | ||||
| #include "zlib.h" | ||||
|  | ||||
| /* =========================================================================== | ||||
|      Decompresses the source buffer into the destination buffer.  sourceLen is | ||||
|    the byte length of the source buffer. Upon entry, destLen is the total | ||||
|    size of the destination buffer, which must be large enough to hold the | ||||
|    entire uncompressed data. (The size of the uncompressed data must have | ||||
|    been saved previously by the compressor and transmitted to the decompressor | ||||
|    by some mechanism outside the scope of this compression library.) | ||||
|    Upon exit, destLen is the actual size of the compressed buffer. | ||||
|  | ||||
|      uncompress returns Z_OK if success, Z_MEM_ERROR if there was not | ||||
|    enough memory, Z_BUF_ERROR if there was not enough room in the output | ||||
|    buffer, or Z_DATA_ERROR if the input data was corrupted. | ||||
| */ | ||||
| int ZEXPORT uncompress (dest, destLen, source, sourceLen) | ||||
|     Bytef *dest; | ||||
|     uLongf *destLen; | ||||
|     const Bytef *source; | ||||
|     uLong sourceLen; | ||||
| { | ||||
|     z_stream stream; | ||||
|     int err; | ||||
|  | ||||
|     stream.next_in = (Bytef*)source; | ||||
|     stream.avail_in = (uInt)sourceLen; | ||||
|     /* Check for source > 64K on 16-bit machine: */ | ||||
|     if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; | ||||
|  | ||||
|     stream.next_out = dest; | ||||
|     stream.avail_out = (uInt)*destLen; | ||||
|     if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; | ||||
|  | ||||
|     stream.zalloc = (alloc_func)0; | ||||
|     stream.zfree = (free_func)0; | ||||
|  | ||||
|     err = inflateInit(&stream); | ||||
|     if (err != Z_OK) return err; | ||||
|  | ||||
|     err = inflate(&stream, Z_FINISH); | ||||
|     if (err != Z_STREAM_END) { | ||||
|         inflateEnd(&stream); | ||||
|         if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) | ||||
|             return Z_DATA_ERROR; | ||||
|         return err; | ||||
|     } | ||||
|     *destLen = stream.total_out; | ||||
|  | ||||
|     err = inflateEnd(&stream); | ||||
|     return err; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Marian Krivos
					Marian Krivos