📄 zlib.xs
字号:
/* Filename: Zlib.xs * Author : Paul Marquess, <pmqs@cpan.org> * Created : 22nd January 1996 * Version : 2.000 * * Copyright (c) 1995-2007 Paul Marquess. All rights reserved. * This program is free software; you can redistribute it and/or * modify it under the same terms as Perl itself. * *//* Parts of this code are based on the files gzio.c and gzappend.c from * the standard zlib source distribution. Below are the copyright statements * from each. *//* gzio.c -- IO on .gz files * Copyright (C) 1995 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h *//* gzappend -- command to append to a gzip file Copyright (C) 2003 Mark Adler, all rights reserved version 1.1, 4 Nov 2003*/#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include <zlib.h> /* zlib prior to 1.06 doesn't know about z_off_t */#ifndef z_off_t# define z_off_t long#endif#if ! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200# define NEED_DUMMY_BYTE_AT_END #endif#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210# define MAGIC_APPEND#endif#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221# define AT_LEAST_ZLIB_1_2_2_1#endif#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223# define AT_LEAST_ZLIB_1_2_2_3#endif#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230# define AT_LEAST_ZLIB_1_2_3#endif#ifdef USE_PPPORT_H# define NEED_sv_2pvbyte# define NEED_sv_2pv_nolen# include "ppport.h"#endif#if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))# ifdef SvPVbyte_force# undef SvPVbyte_force# endif# define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)#endif#ifndef SvPVbyte_nolen# define SvPVbyte_nolen SvPV_nolen#endif#if 0# ifndef SvPVbyte_nolen# define SvPVbyte_nolen SvPV_nolen# endif# ifndef SvPVbyte_force# define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)# endif#endif#if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))# define UTF8_AVAILABLE#endiftypedef int DualType ;typedef int int_undef ;typedef struct di_stream { int flags ;#define FLAG_APPEND 1#define FLAG_CRC32 2#define FLAG_ADLER32 4#define FLAG_CONSUME_INPUT 8 uLong crc32 ; uLong adler32 ; z_stream stream; uLong bufsize; SV * dictionary ; uLong dict_adler ; int last_error ; bool zip_mode ;#define SETP_BYTE#ifdef SETP_BYTE bool deflateParams_out_valid ; Bytef deflateParams_out_byte;#else#define deflateParams_BUFFER_SIZE 0x4000 uLong deflateParams_out_length; Bytef* deflateParams_out_buffer;#endif int Level; int Method; int WindowBits; int MemLevel; int Strategy; uLong bytesInflated ; uLong compressedBytes ; uLong uncompressedBytes ;#ifdef MAGIC_APPEND#define WINDOW_SIZE 32768U bool matchedEndBlock; Bytef* window ; int window_lastbit, window_left, window_full; unsigned window_have; off_t window_lastoff, window_end; off_t window_endOffset; uLong lastBlockOffset ; unsigned char window_lastByte ; #endif} di_stream;typedef di_stream * deflateStream ;typedef di_stream * Compress__Raw__Zlib__deflateStream ;typedef di_stream * inflateStream ;typedef di_stream * Compress__Raw__Zlib__inflateStream ;typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;#define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \ Zero(to,1,typ))/* Figure out the Operating System */#ifdef MSDOS# define OS_CODE 0x00#endif#if defined(AMIGA) || defined(AMIGAOS) # define OS_CODE 0x01#endif #if defined(VAXC) || defined(VMS)# define OS_CODE 0x02#endif#if 0 /* VM/CMS */# define OS_CODE 0x04#endif #if defined(ATARI) || defined(atarist)# define OS_CODE 0x05#endif #ifdef OS2# define OS_CODE 0x06#endif #if defined(MACOS) || defined(TARGET_OS_MAC)# define OS_CODE 0x07#endif#if 0 /* Z-System */# define OS_CODE 0x08#endif #if 0 /* CP/M */# define OS_CODE 0x09#endif #ifdef TOPS20# define OS_CODE 0x0a#endif#ifdef WIN32 /* Window 95 & Windows NT */# define OS_CODE 0x0b#endif #if 0 /* QDOS */# define OS_CODE 0x0c#endif #if 0 /* Acorn RISCOS */# define OS_CODE 0x0d#endif #if 0 /* ??? */# define OS_CODE 0x0e#endif #ifdef __50SERIES /* Prime/PRIMOS */# define OS_CODE 0x0F#endif /* Default to UNIX */ #ifndef OS_CODE# define OS_CODE 0x03 /* assume Unix */#endif#ifndef GZIP_OS_CODE# define GZIP_OS_CODE OS_CODE#endif#define adlerInitial adler32(0L, Z_NULL, 0)#define crcInitial crc32(0L, Z_NULL, 0)static const char * const my_z_errmsg[] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR(-6) */ ""};#define setDUALstatus(var, err) \ sv_setnv(var, (double)err) ; \ sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \ SvNOK_on(var); #if defined(__SYMBIAN32__)# define NO_WRITEABLE_DATA#endif#define TRACE_DEFAULT 0#ifdef NO_WRITEABLE_DATA# define trace TRACE_DEFAULT#else static int trace = TRACE_DEFAULT ;#endif/* Dodge PerlIO hiding of these functions. */#undef printfstatic char *#ifdef CAN_PROTOTYPEGetErrorString(int error_no)#elseGetErrorString(error_no)int error_no ;#endif{ dTHX; char * errstr ; if (error_no == Z_ERRNO) { errstr = Strerror(errno) ; } else /* errstr = gzerror(fil, &error_no) ; */ errstr = (char*) my_z_errmsg[2 - error_no]; return errstr ;}#ifdef MAGIC_APPEND/* The following two functions are taken almost directly from examples/gzappend.c. Only cosmetic changes have been made to conform to the coding style of the rest of the code in this file.*//* return the greatest common divisor of a and b using Euclid's algorithm, modified to be fast when one argument much greater than the other, and coded to avoid unnecessary swapping */static unsigned #ifdef CAN_PROTOTYPEgcd(unsigned a, unsigned b)#elsegcd(a, b) unsigned a; unsigned b;#endif{ unsigned c; while (a && b) if (a > b) { c = b; while (a - c >= c) c <<= 1; a -= c; } else { c = a; while (b - c >= c) c <<= 1; b -= c; } return a + b;}/* rotate list[0..len-1] left by rot positions, in place */static void #ifdef CAN_PROTOTYPErotate(unsigned char *list, unsigned len, unsigned rot)#elserotate(list, len, rot) unsigned char *list; unsigned len ; unsigned rot;#endif{ unsigned char tmp; unsigned cycles; unsigned char *start, *last, *to, *from; /* normalize rot and handle degenerate cases */ if (len < 2) return; if (rot >= len) rot %= len; if (rot == 0) return; /* pointer to last entry in list */ last = list + (len - 1); /* do simple left shift by one */ if (rot == 1) { tmp = *list; memcpy(list, list + 1, len - 1); *last = tmp; return; } /* do simple right shift by one */ if (rot == len - 1) { tmp = *last; memmove(list + 1, list, len - 1); *list = tmp; return; } /* otherwise do rotate as a set of cycles in place */ cycles = gcd(len, rot); /* number of cycles */ do { start = from = list + cycles; /* start index is arbitrary */ tmp = *from; /* save entry to be overwritten */ for (;;) { to = from; /* next step in cycle */ from += rot; /* go right rot positions */ if (from > last) from -= len; /* (pointer better not wrap) */ if (from == start) break; /* all but one shifted */ *to = *from; /* shift left */ } *to = tmp; /* complete the circle */ } while (--cycles);}#endif /* MAGIC_APPEND */static void#ifdef CAN_PROTOTYPEDispHex(void * ptr, int length)#elseDispHex(ptr, length) void * ptr; int length;#endif{ char * p = (char*)ptr; int i; for (i = 0; i < length; ++i) { printf(" %02x", 0xFF & *(p+i)); }}static void#ifdef CAN_PROTOTYPEDispStream(di_stream * s, char * message)#elseDispStream(s, message) di_stream * s; char * message;#endif{#if 0 if (! trace) return ;#endif#define EnDis(f) (s->flags & f ? "Enabled" : "Disabled") printf("DispStream 0x%p", s) ; if (message) printf("- %s \n", message) ; printf("\n") ; if (!s) { printf(" stream pointer is NULL\n"); } else { printf(" stream 0x%p\n", &(s->stream)); printf(" zalloc 0x%p\n", s->stream.zalloc); printf(" zfree 0x%p\n", s->stream.zfree); printf(" opaque 0x%p\n", s->stream.opaque); if (s->stream.msg) printf(" msg %s\n", s->stream.msg); else printf(" msg \n"); printf(" next_in 0x%p", s->stream.next_in); if (s->stream.next_in){ printf(" =>"); DispHex(s->stream.next_in, 4); } printf("\n"); printf(" next_out 0x%p", s->stream.next_out); if (s->stream.next_out){ printf(" =>"); DispHex(s->stream.next_out, 4); } printf("\n"); printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in); printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out); printf(" total_in %ld\n", s->stream.total_in); printf(" total_out %ld\n", s->stream.total_out); printf(" adler %ld\n", s->stream.adler ); printf(" bufsize %ld\n", s->bufsize); printf(" dictionary 0x%p\n", s->dictionary); printf(" dict_adler 0x%ld\n",s->dict_adler); printf(" zip_mode %d\n", s->zip_mode); printf(" crc32 0x%x\n", (unsigned)s->crc32); printf(" adler32 0x%x\n", (unsigned)s->adler32); printf(" flags 0x%x\n", s->flags); printf(" APPEND %s\n", EnDis(FLAG_APPEND)); printf(" CRC32 %s\n", EnDis(FLAG_CRC32)); printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32)); printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));#ifdef MAGIC_APPEND printf(" window 0x%p\n", s->window);#endif printf("\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -