2 * Author : Paul Marquess, <pmqs@cpan.org>
3 * Created : 22nd January 1996
6 * Copyright (c) 1995-2005 Paul Marquess. All rights reserved.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the same terms as Perl itself.
12 /* Parts of this code are based on the files gzio.c and gzappend.c from
13 * the standard zlib source distribution. Below are the copyright statements
17 /* gzio.c -- IO on .gz files
18 * Copyright (C) 1995 Jean-loup Gailly.
19 * For conditions of distribution and use, see copyright notice in zlib.h
22 /* gzappend -- command to append to a gzip file
24 Copyright (C) 2003 Mark Adler, all rights reserved
25 version 1.1, 4 Nov 2003
37 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210
41 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
42 # define AT_LEAST_ZLIB_1_2_2_1
45 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223
46 # define AT_LEAST_ZLIB_1_2_2_3
49 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
50 # define AT_LEAST_ZLIB_1_2_3
59 /* zlib prior to 1.06 doesn't know about z_off_t */
65 # include "patchlevel.h"
66 # define PERL_REVISION 5
67 # define PERL_VERSION PATCHLEVEL
68 # define PERL_SUBVERSION SUBVERSION
71 # if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))
73 # define PL_sv_undef sv_undef
75 # define PL_curcop curcop
76 # define PL_compiling compiling
81 # define newSVuv newSViv
87 #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
88 # define UTF8_AVAILABLE
91 #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
93 # ifdef SvPVbyte_force
94 # undef SvPVbyte_force
97 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
101 #ifndef SvPVbyte_nolen
102 # define SvPVbyte_nolen SvPV_nolen
106 # define SvPVbyte SvPV
115 #define sv_2pv_nolen(a) my_sv_2pv_nolen(a)
118 my_sv_2pv_nolen(register SV *sv)
121 return sv_2pv(sv, &n_a);
125 /* SvPV_nolen depends on sv_2pv_nolen */
126 #define SvPV_nolen(sv) \
127 ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
128 ? SvPVX(sv) : sv_2pv_nolen(sv))
134 # define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
137 typedef int DualType ;
138 typedef int int_undef ;
140 typedef struct di_stream {
142 #define FLAG_APPEND 1
144 #define FLAG_ADLER32 4
145 #define FLAG_CONSUME_INPUT 8
157 bool deflateParams_out_valid ;
158 Bytef deflateParams_out_byte;
160 #define deflateParams_BUFFER_SIZE 0x4000
161 uLong deflateParams_out_length;
162 Bytef* deflateParams_out_buffer;
169 uLong bytesInflated ;
172 #define WINDOW_SIZE 32768U
174 bool matchedEndBlock;
176 int window_lastbit, window_left, window_full;
177 unsigned window_have;
178 off_t window_lastoff, window_end;
179 off_t window_endOffset;
181 uLong lastBlockOffset ;
182 unsigned char window_lastByte ;
188 typedef di_stream * deflateStream ;
189 typedef di_stream * Compress__Zlib__deflateStream ;
190 typedef di_stream * inflateStream ;
191 typedef di_stream * Compress__Zlib__inflateStream ;
192 typedef di_stream * Compress__Zlib__inflateScanStream ;
194 #define GZERRNO "Compress::Zlib::gzerrno"
196 #define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
199 /* Figure out the Operating System */
201 # define OS_CODE 0x00
204 #if defined(AMIGA) || defined(AMIGAOS)
205 # define OS_CODE 0x01
208 #if defined(VAXC) || defined(VMS)
209 # define OS_CODE 0x02
213 # define OS_CODE 0x04
216 #if defined(ATARI) || defined(atarist)
217 # define OS_CODE 0x05
221 # define OS_CODE 0x06
224 #if defined(MACOS) || defined(TARGET_OS_MAC)
225 # define OS_CODE 0x07
229 # define OS_CODE 0x08
233 # define OS_CODE 0x09
237 # define OS_CODE 0x0a
240 #ifdef WIN32 /* Window 95 & Windows NT */
241 # define OS_CODE 0x0b
245 # define OS_CODE 0x0c
248 #if 0 /* Acorn RISCOS */
249 # define OS_CODE 0x0d
253 # define OS_CODE 0x0e
256 #ifdef __50SERIES /* Prime/PRIMOS */
257 # define OS_CODE 0x0F
260 /* Default to UNIX */
262 # define OS_CODE 0x03 /* assume Unix */
266 # define GZIP_OS_CODE OS_CODE
269 #define adlerInitial adler32(0L, Z_NULL, 0)
270 #define crcInitial crc32(0L, Z_NULL, 0)
273 static const char * const my_z_errmsg[] = {
274 "need dictionary", /* Z_NEED_DICT 2 */
275 "stream end", /* Z_STREAM_END 1 */
277 "file error", /* Z_ERRNO (-1) */
278 "stream error", /* Z_STREAM_ERROR (-2) */
279 "data error", /* Z_DATA_ERROR (-3) */
280 "insufficient memory", /* Z_MEM_ERROR (-4) */
281 "buffer error", /* Z_BUF_ERROR (-5) */
282 "incompatible version",/* Z_VERSION_ERROR(-6) */
285 #define setDUALstatus(var, err) \
286 sv_setnv(var, (double)err) ; \
287 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
291 #if defined(__SYMBIAN32__)
292 # define NO_WRITEABLE_DATA
295 #define TRACE_DEFAULT 0
297 #ifdef NO_WRITEABLE_DATA
298 # define trace TRACE_DEFAULT
300 static int trace = TRACE_DEFAULT ;
303 /* Dodge PerlIO hiding of these functions. */
308 GetErrorString(int error_no)
310 GetErrorString(error_no)
317 if (error_no == Z_ERRNO) {
318 errstr = Strerror(errno) ;
321 /* errstr = gzerror(fil, &error_no) ; */
322 errstr = (char*) my_z_errmsg[2 - error_no];
330 SetGzErrorNo(int error_no)
332 SetGzErrorNo(error_no)
337 SV * gzerror_sv = perl_get_sv(GZERRNO, FALSE) ;
339 if (error_no == Z_ERRNO) {
341 errstr = Strerror(errno) ;
344 /* errstr = gzerror(fil, &error_no) ; */
345 errstr = (char*) my_z_errmsg[2 - error_no];
347 if (SvIV(gzerror_sv) != error_no) {
348 sv_setiv(gzerror_sv, error_no) ;
349 sv_setpv(gzerror_sv, errstr) ;
350 SvIOK_on(gzerror_sv) ;
358 SetGzError(gzFile file)
366 (void)gzerror(file, &error_no) ;
367 SetGzErrorNo(error_no) ;
375 The following two functions are taken almost directly from
376 examples/gzappend.c. Only cosmetic changes have been made to conform to
377 the coding style of the rest of the code in this file.
381 /* return the greatest common divisor of a and b using Euclid's algorithm,
382 modified to be fast when one argument much greater than the other, and
383 coded to avoid unnecessary swapping */
386 gcd(unsigned a, unsigned b)
411 /* rotate list[0..len-1] left by rot positions, in place */
414 rotate(unsigned char *list, unsigned len, unsigned rot)
416 rotate(list, len, rot)
424 unsigned char *start, *last, *to, *from;
426 /* normalize rot and handle degenerate cases */
428 if (rot >= len) rot %= len;
429 if (rot == 0) return;
431 /* pointer to last entry in list */
432 last = list + (len - 1);
434 /* do simple left shift by one */
437 memcpy(list, list + 1, len - 1);
442 /* do simple right shift by one */
443 if (rot == len - 1) {
445 memmove(list + 1, list, len - 1);
450 /* otherwise do rotate as a set of cycles in place */
451 cycles = gcd(len, rot); /* number of cycles */
453 start = from = list + cycles; /* start index is arbitrary */
454 tmp = *from; /* save entry to be overwritten */
456 to = from; /* next step in cycle */
457 from += rot; /* go right rot positions */
458 if (from > last) from -= len; /* (pointer better not wrap) */
459 if (from == start) break; /* all but one shifted */
460 *to = *from; /* shift left */
462 *to = tmp; /* complete the circle */
466 #endif /* MAGIC_APPEND */
470 DispHex(void * ptr, int length)
477 char * p = (char*)ptr;
479 for (i = 0; i < length; ++i) {
480 printf(" %02x", 0xFF & *(p+i));
487 DispStream(di_stream * s, char * message)
489 DispStream(s, message)
500 #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
502 printf("DispStream 0x%p", s) ;
504 printf("- %s \n", message) ;
508 printf(" stream pointer is NULL\n");
511 printf(" stream 0x%p\n", &(s->stream));
512 printf(" zalloc 0x%p\n", s->stream.zalloc);
513 printf(" zfree 0x%p\n", s->stream.zfree);
514 printf(" opaque 0x%p\n", s->stream.opaque);
516 printf(" msg %s\n", s->stream.msg);
519 printf(" next_in 0x%p", s->stream.next_in);
520 if (s->stream.next_in){
522 DispHex(s->stream.next_in, 4);
526 printf(" next_out 0x%p", s->stream.next_out);
527 if (s->stream.next_out){
529 DispHex(s->stream.next_out, 4);
533 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
534 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
535 printf(" total_in %ld\n", s->stream.total_in);
536 printf(" total_out %ld\n", s->stream.total_out);
537 printf(" adler %ld\n", s->stream.adler );
538 printf(" bufsize %ld\n", s->bufsize);
539 printf(" dictionary 0x%p\n", s->dictionary);
540 printf(" dict_adler 0x%ld\n",s->dict_adler);
541 printf(" zip_mode %d\n", s->zip_mode);
542 printf(" crc32 0x%x\n", (unsigned)s->crc32);
543 printf(" adler32 0x%x\n", (unsigned)s->adler32);
544 printf(" flags 0x%x\n", s->flags);
545 printf(" APPEND %s\n", EnDis(FLAG_APPEND));
546 printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
547 printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
548 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
551 printf(" window 0x%p\n", s->window);
567 ZMALLOC(s, di_stream) ;
575 PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
577 PostInitStream(s, flags, bufsize, windowBits)
584 s->bufsize = bufsize ;
585 s->bufinc = bufsize ;
588 s->zip_mode = (windowBits < 0) ;
589 if (flags & FLAG_CRC32)
590 s->crc32 = crcInitial ;
591 if (flags & FLAG_ADLER32)
592 s->adler32 = adlerInitial ;
598 deRef(SV * sv, char * string)
615 croak("%s: buffer parameter is not a SCALAR reference", string);
618 croak("%s: buffer parameter is a reference to a reference", string) ;
630 deRef_l(SV * sv, char * string)
651 croak("%s: buffer parameter is not a SCALAR reference", string);
654 croak("%s: buffer parameter is a reference to a reference", string) ;
657 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
658 croak("%s: buffer parameter is read-only", string);
660 SvUPGRADE(sv, SVt_PV);
672 #include "constants.h"
674 MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_
679 INCLUDE: constants.xs
682 /* Check this version of zlib is == 1 */
683 if (zlibVersion()[0] != '1')
684 croak("Compress::Zlib needs zlib version 1.x\n") ;
687 /* Create the $os_code scalar */
688 SV * os_code_sv = perl_get_sv("Compress::Zlib::gzip_os_code", GV_ADDMULTI) ;
689 sv_setiv(os_code_sv, GZIP_OS_CODE) ;
693 /* Create the $gzerror scalar */
694 SV * gzerror_sv = perl_get_sv(GZERRNO, GV_ADDMULTI) ;
695 sv_setiv(gzerror_sv, 0) ;
696 sv_setpv(gzerror_sv, "") ;
697 SvIOK_on(gzerror_sv) ;
706 RETVAL = SvREADONLY(SvRV(sv)) ;
708 RETVAL = SvREADONLY(sv) ;
720 char *ptr = SvPVbyte(str,len);
721 ST(0) = sv_newmortal();
722 SvUPGRADE(ST(0),SVt_PVNV);
723 sv_setpvn(ST(0),ptr,len);
724 if(SvNOK(num) || SvPOK(num) || SvMAGICAL(num)) {
725 SvNV_set(ST(0), SvNV(num));
728 #ifdef SVf_IVisUVXXXX
729 else if (SvUOK(num)) {
730 SvUVX(ST(0)) = SvUV(num);
736 SvIV_set(ST(0), SvIV(num));
743 #define Zip_zlib_version() (char*)zlib_version
751 RETVAL = ZLIB_VERNUM ;
753 /* 1.1.4 => 0x1140 */
754 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
755 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
756 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
761 MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_
763 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
766 Zip_adler32(buf, adler=adlerInitial)
767 uLong adler = NO_INIT
769 Bytef * buf = NO_INIT
772 /* If the buffer is a reference, dereference it */
773 sv = deRef(sv, "adler32") ;
774 #ifdef UTF8_AVAILABLE
775 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
776 croak("Wide character in Compress::Zlib::adler32");
778 buf = (Byte*)SvPVbyte(sv, len) ;
781 adler = adlerInitial;
782 else if (SvOK(ST(1)))
783 adler = SvUV(ST(1)) ;
785 adler = adlerInitial;
787 #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
790 Zip_crc32(buf, crc=crcInitial)
793 Bytef * buf = NO_INIT
796 /* If the buffer is a reference, dereference it */
797 sv = deRef(sv, "crc32") ;
798 #ifdef UTF8_AVAILABLE
799 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
800 croak("Wide character in Compress::Zlib::crc32");
802 buf = (Byte*)SvPVbyte(sv, len) ;
806 else if (SvOK(ST(1)))
813 crc32_combine(crc1, crc2, len2)
818 #ifndef AT_LEAST_ZLIB_1_2_2_1
819 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
820 croak("crc32_combine needs zlib 1.2.3 or better");
822 RETVAL = crc32_combine(crc1, crc2, len2);
829 adler32_combine(adler1, adler2, len2)
834 #ifndef AT_LEAST_ZLIB_1_2_2_1
835 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
836 croak("adler32_combine needs zlib 1.2.3 or better");
838 RETVAL = adler32_combine(adler1, adler2, len2);
844 MODULE = Compress::Zlib PACKAGE = Compress::Zlib
847 _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
861 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld\n",
862 level, method, windowBits, memLevel, strategy, bufsize) ;
863 if ((s = InitStream() )) {
867 s->WindowBits = windowBits;
868 s->MemLevel = memLevel;
869 s->Strategy = strategy;
871 err = deflateInit2(&(s->stream), level,
872 method, windowBits, memLevel, strategy);
874 /* Check if a dictionary has been specified */
876 if (err == Z_OK && SvCUR(dictionary)) {
877 #ifdef UTF8_AVAILABLE
878 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
879 croak("Wide character in Compress::Zlib::Deflate::new dicrionary parameter");
881 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
883 s->dict_adler = s->stream.adler ;
891 PostInitStream(s, flags, bufsize, windowBits) ;
897 XPUSHs(sv_setref_pv(sv_newmortal(),
898 "Compress::Zlib::deflateStream", (void*)s));
899 if (GIMME == G_ARRAY) {
900 SV * sv = sv_2mortal(newSViv(err)) ;
901 setDUALstatus(sv, err);
906 _inflateInit(flags, windowBits, bufsize, dictionary)
919 croak("inflateScanInit needs zlib 1.2.1 or better");
922 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
923 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
924 if ((s = InitStream() )) {
926 s->WindowBits = windowBits;
928 err = inflateInit2(&(s->stream), windowBits);
933 else if (SvCUR(dictionary)) {
934 /* Dictionary specified - take a copy for use in inflate */
935 s->dictionary = newSVsv(dictionary) ;
938 PostInitStream(s, flags, bufsize, windowBits) ;
942 s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
950 XPUSHs(sv_setref_pv(sv_newmortal(),
952 ? "Compress::Zlib::inflateScanStream"
953 : "Compress::Zlib::inflateStream",
955 if (GIMME == G_ARRAY) {
956 SV * sv = sv_2mortal(newSViv(err)) ;
957 setDUALstatus(sv, err);
963 MODULE = Compress::Zlib PACKAGE = Compress::Zlib::deflateStream
966 DispStream(s, message=NULL)
967 Compress::Zlib::deflateStream s
972 Compress::Zlib::deflateStream s
974 RETVAL = deflateReset(&(s->stream)) ;
975 if (RETVAL == Z_OK) {
976 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
982 deflate (s, buf, output)
983 Compress::Zlib::deflateStream s
986 uInt cur_length = NO_INIT
987 uInt increment = NO_INIT
991 /* If the input buffer is a reference, dereference it */
992 buf = deRef(buf, "deflate") ;
994 /* initialise the input buffer */
995 #ifdef UTF8_AVAILABLE
996 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
997 croak("Wide character in Compress::Zlib::Deflate::deflate input parameter");
999 s->stream.next_in = (Bytef*)SvPVbyte(buf, *(STRLEN*)&s->stream.avail_in) ;
1000 /* s->stream.avail_in = SvCUR(buf) ; */
1002 if (s->flags & FLAG_CRC32)
1003 s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
1005 if (s->flags & FLAG_ADLER32)
1006 s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
1008 /* and retrieve the output buffer */
1009 output = deRef_l(output, "deflate") ;
1010 #ifdef UTF8_AVAILABLE
1011 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1012 croak("Wide character in Compress::Zlib::Deflate::deflate output parameter");
1015 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1016 SvCUR_set(output, 0);
1017 /* sv_setpvn(output, "", 0); */
1019 cur_length = SvCUR(output) ;
1020 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1021 increment = SvLEN(output) - cur_length;
1022 s->stream.avail_out = increment;
1024 /* Check for saved output from deflateParams */
1025 if (s->deflateParams_out_valid) {
1026 *(s->stream.next_out) = s->deflateParams_out_byte;
1027 ++ s->stream.next_out;
1028 -- s->stream.avail_out ;
1029 s->deflateParams_out_valid = FALSE;
1032 /* Check for saved output from deflateParams */
1033 if (s->deflateParams_out_length) {
1034 uLong plen = s->deflateParams_out_length ;
1035 /* printf("Copy %d bytes saved data\n", plen);*/
1036 if (s->stream.avail_out < plen) {
1037 /*printf("GROW from %d to %d\n", s->stream.avail_out,
1038 SvLEN(output) + plen - s->stream.avail_out); */
1039 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1042 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1043 cur_length = cur_length + plen;
1044 SvCUR_set(output, cur_length);
1045 s->stream.next_out += plen ;
1046 s->stream.avail_out = SvLEN(output) - cur_length ;
1047 increment = s->stream.avail_out;
1048 s->deflateParams_out_length = 0;
1051 while (s->stream.avail_in != 0) {
1053 if (s->stream.avail_out == 0) {
1054 /* out of space in the output buffer so make it bigger */
1056 Sv_Grow(output, SvLEN(output) + s->bufinc) ;
1057 cur_length += increment ;
1058 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1059 increment = s->bufinc ;
1060 s->stream.avail_out = increment;
1063 RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
1068 s->last_error = RETVAL ;
1069 if (RETVAL == Z_OK) {
1071 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1080 Compress::Zlib::deflateStream s
1082 deflateEnd(&s->stream) ;
1084 SvREFCNT_dec(s->dictionary) ;
1086 if (s->deflateParams_out_buffer)
1087 Safefree(s->deflateParams_out_buffer);
1093 flush(s, output, f=Z_FINISH)
1094 Compress::Zlib::deflateStream s
1097 uInt cur_length = NO_INIT
1098 uInt increment = NO_INIT
1101 s->stream.avail_in = 0; /* should be zero already anyway */
1103 /* retrieve the output buffer */
1104 output = deRef_l(output, "flush") ;
1105 #ifdef UTF8_AVAILABLE
1106 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1107 croak("Wide character in Compress::Zlib::Deflate::flush input parameter");
1109 if(! s->flags & FLAG_APPEND) {
1110 SvCUR_set(output, 0);
1111 /* sv_setpvn(output, "", 0); */
1113 cur_length = SvCUR(output) ;
1114 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1115 increment = SvLEN(output) - cur_length;
1116 s->stream.avail_out = increment;
1118 /* Check for saved output from deflateParams */
1119 if (s->deflateParams_out_valid) {
1120 *(s->stream.next_out) = s->deflateParams_out_byte;
1121 ++ s->stream.next_out;
1122 -- s->stream.avail_out ;
1123 s->deflateParams_out_valid = FALSE;
1126 /* Check for saved output from deflateParams */
1127 if (s->deflateParams_out_length) {
1128 uLong plen = s->deflateParams_out_length ;
1129 /* printf("Copy %d bytes saved data\n", plen); */
1130 if (s->stream.avail_out < plen) {
1131 /* printf("GROW from %d to %d\n", s->stream.avail_out,
1132 SvLEN(output) + plen - s->stream.avail_out); */
1133 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1136 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1137 cur_length = cur_length + plen;
1138 SvCUR_set(output, cur_length);
1139 s->stream.next_out += plen ;
1140 s->stream.avail_out = SvLEN(output) - cur_length ;
1141 increment = s->stream.avail_out;
1142 s->deflateParams_out_length = 0;
1147 if (s->stream.avail_out == 0) {
1148 /* consumed all the available output, so extend it */
1150 Sv_Grow(output, SvLEN(output) + s->bufinc) ;
1151 cur_length += increment ;
1152 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1153 increment = s->bufinc ;
1154 s->stream.avail_out = increment;
1156 RETVAL = deflate(&(s->stream), f);
1158 /* deflate has finished flushing only when it hasn't used up
1159 * all the available space in the output buffer:
1161 if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1165 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1166 s->last_error = RETVAL ;
1168 if (RETVAL == Z_OK) {
1170 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1178 _deflateParams(s, flags, level, strategy, bufsize)
1179 Compress::Zlib::deflateStream s
1185 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1186 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1190 s->Strategy = strategy ;
1192 s->bufsize = bufsize;
1193 s->bufinc = bufsize;
1195 /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1197 s->stream.avail_in = 0;
1198 s->stream.next_out = &(s->deflateParams_out_byte) ;
1199 s->stream.avail_out = 1;
1200 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1201 s->deflateParams_out_valid =
1202 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1203 /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1205 /* printf("Level %d Strategy %d, Prev Len %d\n",
1206 s->Level, s->Strategy, s->deflateParams_out_length); */
1207 s->stream.avail_in = 0;
1208 if (s->deflateParams_out_buffer == NULL)
1209 s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1210 s->stream.next_out = s->deflateParams_out_buffer ;
1211 s->stream.avail_out = deflateParams_BUFFER_SIZE;
1213 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1214 s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1215 /* printf("RETVAL %d, length out %d, avail %d\n",
1216 RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1224 Compress::Zlib::deflateStream s
1232 Compress::Zlib::deflateStream s
1234 RETVAL = s->Strategy ;
1241 Compress::Zlib::deflateStream s
1243 RETVAL = s->bufsize ;
1250 Compress::Zlib::deflateStream s
1252 RETVAL = s->last_error ;
1258 Compress::Zlib::deflateStream s
1266 Compress::Zlib::deflateStream s
1268 RETVAL = s->dict_adler ;
1274 Compress::Zlib::deflateStream s
1276 RETVAL = s->adler32 ;
1282 Compress::Zlib::deflateStream s
1284 RETVAL = s->stream.total_in ;
1290 Compress::Zlib::deflateStream s
1292 RETVAL = s->stream.total_out ;
1298 Compress::Zlib::deflateStream s
1300 RETVAL = s->stream.msg;
1305 deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1306 Compress::Zlib::deflateStream s
1312 #ifndef AT_LEAST_ZLIB_1_2_2_3
1313 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1314 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1315 croak("deflateTune needs zlib 1.2.2.3 or better");
1317 RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1323 MODULE = Compress::Zlib PACKAGE = Compress::Zlib::inflateStream
1326 DispStream(s, message=NULL)
1327 Compress::Zlib::inflateStream s
1332 Compress::Zlib::inflateStream s
1334 RETVAL = inflateReset(&(s->stream)) ;
1335 if (RETVAL == Z_OK) {
1336 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1342 inflate (s, buf, output)
1343 Compress::Zlib::inflateStream s
1346 uInt cur_length = NO_INIT
1347 uInt prefix_length = NO_INIT
1348 uInt increment = NO_INIT
1350 #ifdef UTF8_AVAILABLE
1351 bool out_utf8 = FALSE;
1354 /* If the buffer is a reference, dereference it */
1355 buf = deRef(buf, "inflate") ;
1357 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
1358 croak("Compress::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1359 #ifdef UTF8_AVAILABLE
1360 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1361 croak("Wide character in Compress::Zlib::Inflate::inflate input parameter");
1364 /* initialise the input buffer */
1365 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, *(STRLEN*)&s->stream.avail_in) ;
1367 /* and retrieve the output buffer */
1368 output = deRef_l(output, "inflate") ;
1369 #ifdef UTF8_AVAILABLE
1370 if (DO_UTF8(output))
1372 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1373 croak("Wide character in Compress::Zlib::Inflate::inflate output parameter");
1375 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1376 SvCUR_set(output, 0);
1378 prefix_length = cur_length = SvCUR(output) ;
1379 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1380 increment = SvLEN(output) - cur_length;
1381 s->stream.avail_out = increment;
1382 s->bytesInflated = 0;
1386 if (s->stream.avail_out == 0) {
1387 /* out of space in the output buffer so make it bigger */
1389 Sv_Grow(output, SvLEN(output) + s->bufinc + 1) ;
1390 cur_length += increment ;
1391 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1392 increment = s->bufinc ;
1393 s->stream.avail_out = increment;
1396 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1399 if (RETVAL == Z_BUF_ERROR) {
1400 if (s->stream.avail_out == 0)
1402 if (s->stream.avail_in == 0) {
1408 if (RETVAL == Z_NEED_DICT && s->dictionary) {
1409 s->dict_adler = s->stream.adler ;
1410 RETVAL = inflateSetDictionary(&(s->stream),
1411 (const Bytef*)SvPVbyte_nolen(s->dictionary),
1412 SvCUR(s->dictionary));
1419 s->last_error = RETVAL ;
1420 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_DATA_ERROR) {
1423 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1425 SvCUR_set(output, prefix_length + s->bytesInflated) ;
1426 *SvEND(output) = '\0';
1427 #ifdef UTF8_AVAILABLE
1429 sv_utf8_upgrade(output);
1432 if (s->flags & FLAG_CRC32 )
1433 s->crc32 = crc32(s->crc32,
1434 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1435 SvCUR(output)-prefix_length) ;
1437 if (s->flags & FLAG_ADLER32)
1438 s->adler32 = adler32(s->adler32,
1439 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1440 SvCUR(output)-prefix_length) ;
1442 /* fix the input buffer */
1443 if (s->flags & FLAG_CONSUME_INPUT) {
1444 in = s->stream.avail_in ;
1445 SvCUR_set(buf, in) ;
1447 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1459 Compress::Zlib::inflateStream s
1461 RETVAL = s->bytesInflated;
1467 inflateSync (s, buf)
1468 Compress::Zlib::inflateStream s
1472 /* If the buffer is a reference, dereference it */
1473 buf = deRef(buf, "inflateSync") ;
1474 #ifdef UTF8_AVAILABLE
1475 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1476 croak("Wide character in Compress::Zlib::Inflate::inflateSync");
1479 /* initialise the input buffer */
1480 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
1481 s->stream.avail_in = SvCUR(buf) ;
1483 /* inflateSync doesn't create any output */
1484 s->stream.next_out = (Bytef*) NULL;
1485 s->stream.avail_out = 0;
1487 RETVAL = inflateSync(&(s->stream));
1488 s->last_error = RETVAL ;
1490 /* fix the input buffer */
1492 unsigned in = s->stream.avail_in ;
1493 SvCUR_set(buf, in) ;
1495 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1505 Compress::Zlib::inflateStream s
1507 inflateEnd(&s->stream) ;
1509 SvREFCNT_dec(s->dictionary) ;
1511 if (s->deflateParams_out_buffer)
1512 Safefree(s->deflateParams_out_buffer);
1516 Safefree(s->window);
1523 Compress::Zlib::inflateStream s
1525 RETVAL = s->last_error ;
1531 Compress::Zlib::inflateStream s
1539 Compress::Zlib::inflateStream s
1541 RETVAL = s->dict_adler ;
1547 Compress::Zlib::inflateStream s
1549 RETVAL = s->stream.total_in ;
1555 Compress::Zlib::inflateStream s
1557 RETVAL = s->adler32 ;
1563 Compress::Zlib::inflateStream s
1565 RETVAL = s->stream.total_out ;
1571 Compress::Zlib::inflateStream s
1573 RETVAL = s->stream.msg;
1580 Compress::Zlib::inflateStream s
1582 RETVAL = s->bufsize ;
1588 Compress::Zlib::inflateStream s
1591 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1593 s->flags |= FLAG_APPEND ;
1595 s->flags &= ~FLAG_APPEND ;
1599 MODULE = Compress::Zlib PACKAGE = Compress::Zlib::inflateScanStream
1603 Compress::Zlib::inflateScanStream s
1605 inflateEnd(&s->stream) ;
1607 SvREFCNT_dec(s->dictionary) ;
1609 if (s->deflateParams_out_buffer)
1610 Safefree(s->deflateParams_out_buffer);
1614 Safefree(s->window);
1619 DispStream(s, message=NULL)
1620 Compress::Zlib::inflateScanStream s
1624 scan(s, buf, out=NULL)
1625 Compress::Zlib::inflateScanStream s
1628 int start_len = NO_INIT
1632 /* If the input buffer is a reference, dereference it */
1633 ix = ix ; /* warning suppression */
1634 #ifndef MAGIC_APPEND
1636 croak("scan needs zlib 1.2.1 or better");
1638 buf = deRef(buf, "inflateScan") ;
1639 #ifdef UTF8_AVAILABLE
1640 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1641 croak("Wide character in Compress::Zlib::InflateScan::scan input parameter");
1644 /* initialise the input buffer */
1645 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, *(STRLEN*)&s->stream.avail_in) ;
1646 start_len = s->stream.avail_in ;
1647 s->bytesInflated = 0 ;
1650 if (s->stream.avail_in == 0) {
1655 /* set up output to next available section of sliding window */
1656 s->stream.avail_out = WINDOW_SIZE - s->window_have;
1657 s->stream.next_out = s->window + s->window_have;
1659 /* DispStream(s, "before inflate\n"); */
1661 /* inflate and check for errors */
1662 RETVAL = inflate(&(s->stream), Z_BLOCK);
1666 s->window_lastByte = *(s->stream.next_in - 1 ) ;
1668 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1669 RETVAL == Z_DATA_ERROR )
1672 if (s->flags & FLAG_CRC32 )
1673 s->crc32 = crc32(s->crc32, s->window + s->window_have,
1674 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1676 if (s->flags & FLAG_ADLER32)
1677 s->adler32 = adler32(s->adler32, s->window + s->window_have,
1678 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1680 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1682 if (s->stream.avail_out)
1683 s->window_have = WINDOW_SIZE - s->stream.avail_out;
1689 /* process end of block */
1690 if (s->stream.data_type & 128) {
1691 if (s->stream.data_type & 64) {
1692 s->window_left = s->stream.data_type & 0x1f;
1695 s->window_lastbit = s->stream.data_type & 0x1f;
1696 s->lastBlockOffset = s->stream.total_in;
1700 } while (RETVAL != Z_STREAM_END);
1702 s->last_error = RETVAL ;
1703 s->window_lastoff = s->stream.total_in ;
1705 if (RETVAL == Z_STREAM_END)
1707 s->matchedEndBlock = 1 ;
1709 /* save the location of the end of the compressed data */
1710 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1711 s->window_endOffset = s->stream.total_in ;
1714 -- s->window_endOffset ;
1717 /* if window wrapped, build dictionary from window by rotating */
1718 if (s->window_full) {
1719 rotate(s->window, WINDOW_SIZE, s->window_have);
1720 s->window_have = WINDOW_SIZE;
1723 /* if (s->flags & FLAG_CONSUME_INPUT) { */
1725 unsigned in = s->stream.avail_in ;
1726 SvCUR_set(buf, in) ;
1728 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1740 Compress::Zlib::inflateScanStream s
1742 #ifndef MAGIC_APPEND
1743 croak("getEndOffset needs zlib 1.2.1 or better");
1745 RETVAL = s->window_endOffset;
1752 Compress::Zlib::inflateScanStream s
1754 #ifndef MAGIC_APPEND
1755 croak("inflateCount needs zlib 1.2.1 or better");
1757 RETVAL = s->bytesInflated;
1764 getLastBlockOffset(s)
1765 Compress::Zlib::inflateScanStream s
1767 #ifndef MAGIC_APPEND
1768 croak("getLastBlockOffset needs zlib 1.2.1 or better");
1770 RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
1776 getLastBufferOffset(s)
1777 Compress::Zlib::inflateScanStream s
1779 #ifndef MAGIC_APPEND
1780 croak("getLastBufferOffset needs zlib 1.2.1 or better");
1782 RETVAL = s->window_lastoff;
1788 resetLastBlockByte(s, byte)
1789 Compress::Zlib::inflateScanStream s
1792 #ifndef MAGIC_APPEND
1793 croak("resetLastBlockByte needs zlib 1.2.1 or better");
1795 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
1800 _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1801 Compress::Zlib::inflateScanStream inf_s
1811 #ifndef MAGIC_APPEND
1815 windowBits = windowBits;
1816 memLevel = memLevel;
1817 strategy = strategy;
1819 croak("_createDeflateStream needs zlib 1.2.1 or better");
1825 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1826 level, method, windowBits, memLevel, strategy, bufsize) ;
1827 if ((s = InitStream() )) {
1831 s->WindowBits = windowBits;
1832 s->MemLevel = memLevel;
1833 s->Strategy = strategy;
1835 err = deflateInit2(&(s->stream), level,
1836 method, windowBits, memLevel, strategy);
1839 err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1840 s->dict_adler = s->stream.adler ;
1848 PostInitStream(s, flags, bufsize, windowBits) ;
1849 s->crc32 = inf_s->crc32;
1850 s->adler32 = inf_s->adler32;
1851 s->stream.adler = inf_s->stream.adler ;
1852 /* s->stream.total_out = inf_s->bytesInflated ; */
1853 s->stream.total_in = inf_s->stream.total_out ;
1854 if (inf_s->window_left) {
1855 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1856 deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1863 XPUSHs(sv_setref_pv(sv_newmortal(),
1864 "Compress::Zlib::deflateStream", (void*)s));
1865 if (GIMME == G_ARRAY) {
1866 SV * sv = sv_2mortal(newSViv(err)) ;
1867 setDUALstatus(sv, err);
1875 Compress::Zlib::inflateScanStream s
1877 RETVAL = s->last_error ;
1883 Compress::Zlib::inflateScanStream s
1892 Compress::Zlib::inflateScanStream s
1894 RETVAL = s->adler32 ;