2 * Author : Paul Marquess, <pmqs@cpan.org>
3 * Created : 22nd January 1996
6 * Copyright (c) 1995-2007 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
36 /* zlib prior to 1.06 doesn't know about z_off_t */
41 #if ! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200
42 # define NEED_DUMMY_BYTE_AT_END
45 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210
49 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
50 # define AT_LEAST_ZLIB_1_2_2_1
53 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223
54 # define AT_LEAST_ZLIB_1_2_2_3
57 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
58 # define AT_LEAST_ZLIB_1_2_3
62 # define NEED_sv_2pvbyte
63 # define NEED_sv_2pv_nolen
67 #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
69 # ifdef SvPVbyte_force
70 # undef SvPVbyte_force
73 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
77 #ifndef SvPVbyte_nolen
78 # define SvPVbyte_nolen SvPV_nolen
84 # ifndef SvPVbyte_nolen
85 # define SvPVbyte_nolen SvPV_nolen
88 # ifndef SvPVbyte_force
89 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
93 #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
94 # define UTF8_AVAILABLE
97 typedef int DualType ;
98 typedef int int_undef ;
100 typedef struct di_stream {
102 #define FLAG_APPEND 1
104 #define FLAG_ADLER32 4
105 #define FLAG_CONSUME_INPUT 8
116 bool deflateParams_out_valid ;
117 Bytef deflateParams_out_byte;
119 #define deflateParams_BUFFER_SIZE 0x4000
120 uLong deflateParams_out_length;
121 Bytef* deflateParams_out_buffer;
128 uLong bytesInflated ;
129 uLong compressedBytes ;
130 uLong uncompressedBytes ;
133 #define WINDOW_SIZE 32768U
135 bool matchedEndBlock;
137 int window_lastbit, window_left, window_full;
138 unsigned window_have;
139 off_t window_lastoff, window_end;
140 off_t window_endOffset;
142 uLong lastBlockOffset ;
143 unsigned char window_lastByte ;
149 typedef di_stream * deflateStream ;
150 typedef di_stream * Compress__Raw__Zlib__deflateStream ;
151 typedef di_stream * inflateStream ;
152 typedef di_stream * Compress__Raw__Zlib__inflateStream ;
153 typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;
155 #define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
158 /* Figure out the Operating System */
160 # define OS_CODE 0x00
163 #if defined(AMIGA) || defined(AMIGAOS)
164 # define OS_CODE 0x01
167 #if defined(VAXC) || defined(VMS)
168 # define OS_CODE 0x02
172 # define OS_CODE 0x04
175 #if defined(ATARI) || defined(atarist)
176 # define OS_CODE 0x05
180 # define OS_CODE 0x06
183 #if defined(MACOS) || defined(TARGET_OS_MAC)
184 # define OS_CODE 0x07
188 # define OS_CODE 0x08
192 # define OS_CODE 0x09
196 # define OS_CODE 0x0a
199 #ifdef WIN32 /* Window 95 & Windows NT */
200 # define OS_CODE 0x0b
204 # define OS_CODE 0x0c
207 #if 0 /* Acorn RISCOS */
208 # define OS_CODE 0x0d
212 # define OS_CODE 0x0e
215 #ifdef __50SERIES /* Prime/PRIMOS */
216 # define OS_CODE 0x0F
219 /* Default to UNIX */
221 # define OS_CODE 0x03 /* assume Unix */
225 # define GZIP_OS_CODE OS_CODE
228 #define adlerInitial adler32(0L, Z_NULL, 0)
229 #define crcInitial crc32(0L, Z_NULL, 0)
231 static const char * const my_z_errmsg[] = {
232 "need dictionary", /* Z_NEED_DICT 2 */
233 "stream end", /* Z_STREAM_END 1 */
235 "file error", /* Z_ERRNO (-1) */
236 "stream error", /* Z_STREAM_ERROR (-2) */
237 "data error", /* Z_DATA_ERROR (-3) */
238 "insufficient memory", /* Z_MEM_ERROR (-4) */
239 "buffer error", /* Z_BUF_ERROR (-5) */
240 "incompatible version",/* Z_VERSION_ERROR(-6) */
243 #define setDUALstatus(var, err) \
244 sv_setnv(var, (double)err) ; \
245 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
249 #if defined(__SYMBIAN32__)
250 # define NO_WRITEABLE_DATA
253 #define TRACE_DEFAULT 0
255 #ifdef NO_WRITEABLE_DATA
256 # define trace TRACE_DEFAULT
258 static int trace = TRACE_DEFAULT ;
261 /* Dodge PerlIO hiding of these functions. */
266 GetErrorString(int error_no)
268 GetErrorString(error_no)
275 if (error_no == Z_ERRNO) {
276 errstr = Strerror(errno) ;
279 /* errstr = gzerror(fil, &error_no) ; */
280 errstr = (char*) my_z_errmsg[2 - error_no];
289 The following two functions are taken almost directly from
290 examples/gzappend.c. Only cosmetic changes have been made to conform to
291 the coding style of the rest of the code in this file.
295 /* return the greatest common divisor of a and b using Euclid's algorithm,
296 modified to be fast when one argument much greater than the other, and
297 coded to avoid unnecessary swapping */
300 gcd(unsigned a, unsigned b)
325 /* rotate list[0..len-1] left by rot positions, in place */
328 rotate(unsigned char *list, unsigned len, unsigned rot)
330 rotate(list, len, rot)
338 unsigned char *start, *last, *to, *from;
340 /* normalize rot and handle degenerate cases */
342 if (rot >= len) rot %= len;
343 if (rot == 0) return;
345 /* pointer to last entry in list */
346 last = list + (len - 1);
348 /* do simple left shift by one */
351 memcpy(list, list + 1, len - 1);
356 /* do simple right shift by one */
357 if (rot == len - 1) {
359 memmove(list + 1, list, len - 1);
364 /* otherwise do rotate as a set of cycles in place */
365 cycles = gcd(len, rot); /* number of cycles */
367 start = from = list + cycles; /* start index is arbitrary */
368 tmp = *from; /* save entry to be overwritten */
370 to = from; /* next step in cycle */
371 from += rot; /* go right rot positions */
372 if (from > last) from -= len; /* (pointer better not wrap) */
373 if (from == start) break; /* all but one shifted */
374 *to = *from; /* shift left */
376 *to = tmp; /* complete the circle */
380 #endif /* MAGIC_APPEND */
384 DispHex(void * ptr, int length)
391 char * p = (char*)ptr;
393 for (i = 0; i < length; ++i) {
394 printf(" %02x", 0xFF & *(p+i));
401 DispStream(di_stream * s, char * message)
403 DispStream(s, message)
414 #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
416 printf("DispStream 0x%p", s) ;
418 printf("- %s \n", message) ;
422 printf(" stream pointer is NULL\n");
425 printf(" stream 0x%p\n", &(s->stream));
426 printf(" zalloc 0x%p\n", s->stream.zalloc);
427 printf(" zfree 0x%p\n", s->stream.zfree);
428 printf(" opaque 0x%p\n", s->stream.opaque);
430 printf(" msg %s\n", s->stream.msg);
433 printf(" next_in 0x%p", s->stream.next_in);
434 if (s->stream.next_in){
436 DispHex(s->stream.next_in, 4);
440 printf(" next_out 0x%p", s->stream.next_out);
441 if (s->stream.next_out){
443 DispHex(s->stream.next_out, 4);
447 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
448 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
449 printf(" total_in %ld\n", s->stream.total_in);
450 printf(" total_out %ld\n", s->stream.total_out);
451 printf(" adler %ld\n", s->stream.adler );
452 printf(" bufsize %ld\n", s->bufsize);
453 printf(" dictionary 0x%p\n", s->dictionary);
454 printf(" dict_adler 0x%ld\n",s->dict_adler);
455 printf(" zip_mode %d\n", s->zip_mode);
456 printf(" crc32 0x%x\n", (unsigned)s->crc32);
457 printf(" adler32 0x%x\n", (unsigned)s->adler32);
458 printf(" flags 0x%x\n", s->flags);
459 printf(" APPEND %s\n", EnDis(FLAG_APPEND));
460 printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
461 printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
462 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
465 printf(" window 0x%p\n", s->window);
481 ZMALLOC(s, di_stream) ;
489 PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
491 PostInitStream(s, flags, bufsize, windowBits)
498 s->bufsize = bufsize ;
500 s->uncompressedBytes =
503 s->zip_mode = (windowBits < 0) ;
504 if (flags & FLAG_CRC32)
505 s->crc32 = crcInitial ;
506 if (flags & FLAG_ADLER32)
507 s->adler32 = adlerInitial ;
513 deRef(SV * sv, char * string)
530 croak("%s: buffer parameter is not a SCALAR reference", string);
533 croak("%s: buffer parameter is a reference to a reference", string) ;
545 deRef_l(SV * sv, char * string)
567 croak("%s: buffer parameter is not a SCALAR reference", string);
570 croak("%s: buffer parameter is a reference to a reference", string) ;
573 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
574 croak("%s: buffer parameter is read-only", string);
576 SvUPGRADE(sv, SVt_PV);
588 #include "constants.h"
590 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
595 INCLUDE: constants.xs
598 /* Check this version of zlib is == 1 */
599 if (zlibVersion()[0] != '1')
600 croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
603 /* Create the $os_code scalar */
604 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
605 sv_setiv(os_code_sv, GZIP_OS_CODE) ;
609 #define Zip_zlib_version() (const char*)zlib_version
617 RETVAL = ZLIB_VERNUM ;
619 /* 1.1.4 => 0x1140 */
620 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
621 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
622 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
627 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
629 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
632 Zip_adler32(buf, adler=adlerInitial)
633 uLong adler = NO_INIT
635 Bytef * buf = NO_INIT
638 /* If the buffer is a reference, dereference it */
639 sv = deRef(sv, "adler32") ;
640 #ifdef UTF8_AVAILABLE
641 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
642 croak("Wide character in Compress::Raw::Zlib::adler32");
644 buf = (Byte*)SvPVbyte(sv, len) ;
647 adler = adlerInitial;
648 else if (SvOK(ST(1)))
649 adler = SvUV(ST(1)) ;
651 adler = adlerInitial;
655 #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
658 Zip_crc32(buf, crc=crcInitial)
661 Bytef * buf = NO_INIT
664 /* If the buffer is a reference, dereference it */
665 sv = deRef(sv, "crc32") ;
666 #ifdef UTF8_AVAILABLE
667 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
668 croak("Wide character in Compress::Raw::Zlib::crc32");
670 buf = (Byte*)SvPVbyte(sv, len) ;
674 else if (SvOK(ST(1)))
681 crc32_combine(crc1, crc2, len2)
686 #ifndef AT_LEAST_ZLIB_1_2_2_1
687 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
688 croak("crc32_combine needs zlib 1.2.3 or better");
690 RETVAL = crc32_combine(crc1, crc2, len2);
697 adler32_combine(adler1, adler2, len2)
702 #ifndef AT_LEAST_ZLIB_1_2_2_1
703 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
704 croak("adler32_combine needs zlib 1.2.3 or better");
706 RETVAL = adler32_combine(adler1, adler2, len2);
712 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
715 _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
729 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
730 level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
731 if ((s = InitStream() )) {
735 s->WindowBits = windowBits;
736 s->MemLevel = memLevel;
737 s->Strategy = strategy;
739 err = deflateInit2(&(s->stream), level,
740 method, windowBits, memLevel, strategy);
742 /* Check if a dictionary has been specified */
744 if (err == Z_OK && SvCUR(dictionary)) {
745 #ifdef UTF8_AVAILABLE
746 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
747 croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
749 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
751 s->dict_adler = s->stream.adler ;
759 PostInitStream(s, flags, bufsize, windowBits) ;
766 SV* obj = sv_setref_pv(sv_newmortal(),
767 "Compress::Raw::Zlib::deflateStream", (void*)s);
770 if (GIMME == G_ARRAY) {
771 SV * sv = sv_2mortal(newSViv(err)) ;
772 setDUALstatus(sv, err);
777 _inflateInit(flags, windowBits, bufsize, dictionary)
790 croak("inflateScanInit needs zlib 1.2.1 or better");
793 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
794 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
795 if ((s = InitStream() )) {
797 s->WindowBits = windowBits;
799 err = inflateInit2(&(s->stream), windowBits);
804 else if (SvCUR(dictionary)) {
805 /* Dictionary specified - take a copy for use in inflate */
806 s->dictionary = newSVsv(dictionary) ;
809 PostInitStream(s, flags, bufsize, windowBits) ;
813 s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
822 SV* obj = sv_setref_pv(sv_newmortal(),
824 ? "Compress::Raw::Zlib::inflateScanStream"
825 : "Compress::Raw::Zlib::inflateStream",
829 if (GIMME == G_ARRAY) {
830 SV * sv = sv_2mortal(newSViv(err)) ;
831 setDUALstatus(sv, err);
837 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
840 DispStream(s, message=NULL)
841 Compress::Raw::Zlib::deflateStream s
846 Compress::Raw::Zlib::deflateStream s
848 RETVAL = deflateReset(&(s->stream)) ;
849 if (RETVAL == Z_OK) {
850 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
856 deflate (s, buf, output)
857 Compress::Raw::Zlib::deflateStream s
860 uInt cur_length = NO_INIT
861 uInt increment = NO_INIT
862 uInt prefix = NO_INIT
864 uLong bufinc = NO_INIT
868 /* If the input buffer is a reference, dereference it */
869 buf = deRef(buf, "deflate") ;
871 /* initialise the input buffer */
872 #ifdef UTF8_AVAILABLE
873 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
874 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
876 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
877 s->stream.avail_in = SvCUR(buf) ;
879 if (s->flags & FLAG_CRC32)
880 s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
882 if (s->flags & FLAG_ADLER32)
883 s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
885 /* and retrieve the output buffer */
886 output = deRef_l(output, "deflate") ;
887 #ifdef UTF8_AVAILABLE
888 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
889 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
892 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
893 SvCUR_set(output, 0);
894 /* sv_setpvn(output, "", 0); */
896 prefix = cur_length = SvCUR(output) ;
897 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
898 increment = SvLEN(output) - cur_length;
899 s->stream.avail_out = increment;
901 /* Check for saved output from deflateParams */
902 if (s->deflateParams_out_valid) {
903 *(s->stream.next_out) = s->deflateParams_out_byte;
904 ++ s->stream.next_out;
905 -- s->stream.avail_out ;
906 s->deflateParams_out_valid = FALSE;
909 /* Check for saved output from deflateParams */
910 if (s->deflateParams_out_length) {
911 uLong plen = s->deflateParams_out_length ;
912 /* printf("Copy %d bytes saved data\n", plen);*/
913 if (s->stream.avail_out < plen) {
914 /*printf("GROW from %d to %d\n", s->stream.avail_out,
915 SvLEN(output) + plen - s->stream.avail_out); */
916 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
919 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
920 cur_length = cur_length + plen;
921 SvCUR_set(output, cur_length);
922 s->stream.next_out += plen ;
923 s->stream.avail_out = SvLEN(output) - cur_length ;
924 increment = s->stream.avail_out;
925 s->deflateParams_out_length = 0;
928 while (s->stream.avail_in != 0) {
930 if (s->stream.avail_out == 0) {
931 /* out of space in the output buffer so make it bigger */
932 Sv_Grow(output, SvLEN(output) + bufinc) ;
933 cur_length += increment ;
934 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
936 s->stream.avail_out = increment;
940 RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
945 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
946 s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
948 s->last_error = RETVAL ;
949 if (RETVAL == Z_OK) {
951 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
960 Compress::Raw::Zlib::deflateStream s
962 deflateEnd(&s->stream) ;
964 SvREFCNT_dec(s->dictionary) ;
966 if (s->deflateParams_out_buffer)
967 Safefree(s->deflateParams_out_buffer);
973 flush(s, output, f=Z_FINISH)
974 Compress::Raw::Zlib::deflateStream s
977 uInt cur_length = NO_INIT
978 uInt increment = NO_INIT
979 uInt prefix = NO_INIT
980 uLong bufinc = NO_INIT
984 s->stream.avail_in = 0; /* should be zero already anyway */
986 /* retrieve the output buffer */
987 output = deRef_l(output, "flush") ;
988 #ifdef UTF8_AVAILABLE
989 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
990 croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
992 if(! s->flags & FLAG_APPEND) {
993 SvCUR_set(output, 0);
994 /* sv_setpvn(output, "", 0); */
996 prefix = cur_length = SvCUR(output) ;
997 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
998 increment = SvLEN(output) - cur_length;
999 s->stream.avail_out = increment;
1001 /* Check for saved output from deflateParams */
1002 if (s->deflateParams_out_valid) {
1003 *(s->stream.next_out) = s->deflateParams_out_byte;
1004 ++ s->stream.next_out;
1005 -- s->stream.avail_out ;
1006 s->deflateParams_out_valid = FALSE;
1009 /* Check for saved output from deflateParams */
1010 if (s->deflateParams_out_length) {
1011 uLong plen = s->deflateParams_out_length ;
1012 /* printf("Copy %d bytes saved data\n", plen); */
1013 if (s->stream.avail_out < plen) {
1014 /* printf("GROW from %d to %d\n", s->stream.avail_out,
1015 SvLEN(output) + plen - s->stream.avail_out); */
1016 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1019 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1020 cur_length = cur_length + plen;
1021 SvCUR_set(output, cur_length);
1022 s->stream.next_out += plen ;
1023 s->stream.avail_out = SvLEN(output) - cur_length ;
1024 increment = s->stream.avail_out;
1025 s->deflateParams_out_length = 0;
1030 if (s->stream.avail_out == 0) {
1031 /* consumed all the available output, so extend it */
1032 Sv_Grow(output, SvLEN(output) + bufinc) ;
1033 cur_length += increment ;
1034 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1035 increment = bufinc ;
1036 s->stream.avail_out = increment;
1039 RETVAL = deflate(&(s->stream), f);
1041 /* deflate has finished flushing only when it hasn't used up
1042 * all the available space in the output buffer:
1044 if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1048 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1049 s->last_error = RETVAL ;
1051 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1053 if (RETVAL == Z_OK) {
1055 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1063 _deflateParams(s, flags, level, strategy, bufsize)
1064 Compress::Raw::Zlib::deflateStream s
1070 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1071 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1075 s->Strategy = strategy ;
1077 s->bufsize = bufsize;
1079 /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1081 s->stream.avail_in = 0;
1082 s->stream.next_out = &(s->deflateParams_out_byte) ;
1083 s->stream.avail_out = 1;
1084 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1085 s->deflateParams_out_valid =
1086 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1087 /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1089 /* printf("Level %d Strategy %d, Prev Len %d\n",
1090 s->Level, s->Strategy, s->deflateParams_out_length); */
1091 s->stream.avail_in = 0;
1092 if (s->deflateParams_out_buffer == NULL)
1093 s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1094 s->stream.next_out = s->deflateParams_out_buffer ;
1095 s->stream.avail_out = deflateParams_BUFFER_SIZE;
1097 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1098 s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1099 /* printf("RETVAL %d, length out %d, avail %d\n",
1100 RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1108 Compress::Raw::Zlib::deflateStream s
1116 Compress::Raw::Zlib::deflateStream s
1118 RETVAL = s->Strategy ;
1125 Compress::Raw::Zlib::deflateStream s
1127 RETVAL = s->bufsize ;
1134 Compress::Raw::Zlib::deflateStream s
1136 RETVAL = s->last_error ;
1142 Compress::Raw::Zlib::deflateStream s
1150 Compress::Raw::Zlib::deflateStream s
1152 RETVAL = s->dict_adler ;
1158 Compress::Raw::Zlib::deflateStream s
1160 RETVAL = s->adler32 ;
1166 Compress::Raw::Zlib::deflateStream s
1168 RETVAL = s->compressedBytes;
1173 uncompressedBytes(s)
1174 Compress::Raw::Zlib::deflateStream s
1176 RETVAL = s->uncompressedBytes;
1182 Compress::Raw::Zlib::deflateStream s
1184 RETVAL = s->stream.total_in ;
1190 Compress::Raw::Zlib::deflateStream s
1192 RETVAL = s->stream.total_out ;
1198 Compress::Raw::Zlib::deflateStream s
1200 RETVAL = s->stream.msg;
1205 deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1206 Compress::Raw::Zlib::deflateStream s
1212 #ifndef AT_LEAST_ZLIB_1_2_2_3
1213 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1214 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1215 croak("deflateTune needs zlib 1.2.2.3 or better");
1217 RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1223 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1226 DispStream(s, message=NULL)
1227 Compress::Raw::Zlib::inflateStream s
1232 Compress::Raw::Zlib::inflateStream s
1234 RETVAL = inflateReset(&(s->stream)) ;
1235 if (RETVAL == Z_OK) {
1236 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1242 inflate (s, buf, output, eof=FALSE)
1243 Compress::Raw::Zlib::inflateStream s
1247 uInt cur_length = 0;
1248 uInt prefix_length = 0;
1250 STRLEN stmp = NO_INIT
1251 uLong bufinc = NO_INIT
1253 #ifdef UTF8_AVAILABLE
1254 bool out_utf8 = FALSE;
1257 bufinc = s->bufsize;
1258 /* If the buffer is a reference, dereference it */
1259 buf = deRef(buf, "inflate") ;
1261 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
1262 croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1263 #ifdef UTF8_AVAILABLE
1264 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1265 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1268 /* initialise the input buffer */
1269 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1270 s->stream.avail_in = SvCUR(buf) ;
1272 /* and retrieve the output buffer */
1273 output = deRef_l(output, "inflate") ;
1274 #ifdef UTF8_AVAILABLE
1275 if (DO_UTF8(output))
1277 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1278 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1280 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1281 SvCUR_set(output, 0);
1283 if (SvLEN(output)) {
1284 prefix_length = cur_length = SvCUR(output) ;
1285 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1286 increment = SvLEN(output) - cur_length - 1;
1287 s->stream.avail_out = increment;
1290 s->stream.avail_out = 0;
1292 s->bytesInflated = 0;
1296 if (s->stream.avail_out == 0 ) {
1297 /* out of space in the output buffer so make it bigger */
1298 Sv_Grow(output, SvLEN(output) + bufinc) ;
1299 cur_length += increment ;
1300 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1301 increment = bufinc ;
1302 s->stream.avail_out = increment;
1306 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1308 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1309 RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1312 if (RETVAL == Z_BUF_ERROR) {
1313 if (s->stream.avail_out == 0)
1315 if (s->stream.avail_in == 0) {
1321 if (RETVAL == Z_NEED_DICT && s->dictionary) {
1322 s->dict_adler = s->stream.adler ;
1323 RETVAL = inflateSetDictionary(&(s->stream),
1324 (const Bytef*)SvPVbyte_nolen(s->dictionary),
1325 SvCUR(s->dictionary));
1331 #ifdef NEED_DUMMY_BYTE_AT_END
1332 if (eof && RETVAL == Z_OK) {
1333 Bytef* nextIn = s->stream.next_in;
1334 uInt availIn = s->stream.avail_in;
1335 s->stream.next_in = (Bytef*) " ";
1336 s->stream.avail_in = 1;
1337 if (s->stream.avail_out == 0) {
1338 /* out of space in the output buffer so make it bigger */
1339 Sv_Grow(output, SvLEN(output) + bufinc) ;
1340 cur_length += increment ;
1341 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1342 increment = bufinc ;
1343 s->stream.avail_out = increment;
1346 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1347 s->stream.next_in = nextIn ;
1348 s->stream.avail_in = availIn ;
1352 s->last_error = RETVAL ;
1353 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_DATA_ERROR) {
1356 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1357 s->uncompressedBytes += s->bytesInflated ;
1358 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1361 SvCUR_set(output, prefix_length + s->bytesInflated) ;
1362 *SvEND(output) = '\0';
1363 #ifdef UTF8_AVAILABLE
1365 sv_utf8_upgrade(output);
1369 if (s->flags & FLAG_CRC32 )
1370 s->crc32 = crc32(s->crc32,
1371 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1372 SvCUR(output)-prefix_length) ;
1374 if (s->flags & FLAG_ADLER32)
1375 s->adler32 = adler32(s->adler32,
1376 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1377 SvCUR(output)-prefix_length) ;
1379 /* fix the input buffer */
1380 if (s->flags & FLAG_CONSUME_INPUT) {
1381 in = s->stream.avail_in ;
1382 SvCUR_set(buf, in) ;
1384 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1394 Compress::Raw::Zlib::inflateStream s
1396 RETVAL = s->bytesInflated;
1402 Compress::Raw::Zlib::inflateStream s
1404 RETVAL = s->compressedBytes;
1409 uncompressedBytes(s)
1410 Compress::Raw::Zlib::inflateStream s
1412 RETVAL = s->uncompressedBytes;
1418 inflateSync (s, buf)
1419 Compress::Raw::Zlib::inflateStream s
1423 /* If the buffer is a reference, dereference it */
1424 buf = deRef(buf, "inflateSync") ;
1425 #ifdef UTF8_AVAILABLE
1426 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1427 croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1430 /* initialise the input buffer */
1431 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
1432 s->stream.avail_in = SvCUR(buf) ;
1434 /* inflateSync doesn't create any output */
1435 s->stream.next_out = (Bytef*) NULL;
1436 s->stream.avail_out = 0;
1438 RETVAL = inflateSync(&(s->stream));
1439 s->last_error = RETVAL ;
1441 /* fix the input buffer */
1443 unsigned in = s->stream.avail_in ;
1444 SvCUR_set(buf, in) ;
1446 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1455 Compress::Raw::Zlib::inflateStream s
1457 inflateEnd(&s->stream) ;
1459 SvREFCNT_dec(s->dictionary) ;
1461 if (s->deflateParams_out_buffer)
1462 Safefree(s->deflateParams_out_buffer);
1466 Safefree(s->window);
1473 Compress::Raw::Zlib::inflateStream s
1475 RETVAL = s->last_error ;
1481 Compress::Raw::Zlib::inflateStream s
1489 Compress::Raw::Zlib::inflateStream s
1491 RETVAL = s->dict_adler ;
1497 Compress::Raw::Zlib::inflateStream s
1499 RETVAL = s->stream.total_in ;
1505 Compress::Raw::Zlib::inflateStream s
1507 RETVAL = s->adler32 ;
1513 Compress::Raw::Zlib::inflateStream s
1515 RETVAL = s->stream.total_out ;
1521 Compress::Raw::Zlib::inflateStream s
1523 RETVAL = s->stream.msg;
1530 Compress::Raw::Zlib::inflateStream s
1532 RETVAL = s->bufsize ;
1538 Compress::Raw::Zlib::inflateStream s
1541 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1543 s->flags |= FLAG_APPEND ;
1545 s->flags &= ~FLAG_APPEND ;
1549 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
1553 Compress::Raw::Zlib::inflateScanStream s
1555 inflateEnd(&s->stream) ;
1557 SvREFCNT_dec(s->dictionary) ;
1559 if (s->deflateParams_out_buffer)
1560 Safefree(s->deflateParams_out_buffer);
1564 Safefree(s->window);
1569 DispStream(s, message=NULL)
1570 Compress::Raw::Zlib::inflateScanStream s
1575 Compress::Raw::Zlib::inflateScanStream s
1577 RETVAL = inflateReset(&(s->stream)) ;
1578 if (RETVAL == Z_OK) {
1579 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1585 scan(s, buf, out=NULL, eof=FALSE)
1586 Compress::Raw::Zlib::inflateScanStream s
1590 bool eof_mode = FALSE;
1591 int start_len = NO_INIT
1592 STRLEN stmp = NO_INIT
1594 /* If the input buffer is a reference, dereference it */
1595 #ifndef MAGIC_APPEND
1597 croak("scan needs zlib 1.2.1 or better");
1599 buf = deRef(buf, "inflateScan") ;
1600 #ifdef UTF8_AVAILABLE
1601 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1602 croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
1604 /* initialise the input buffer */
1605 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1606 s->stream.avail_in = SvCUR(buf) ;
1607 start_len = s->stream.avail_in ;
1608 s->bytesInflated = 0 ;
1611 if (s->stream.avail_in == 0) {
1616 /* set up output to next available section of sliding window */
1617 s->stream.avail_out = WINDOW_SIZE - s->window_have;
1618 s->stream.next_out = s->window + s->window_have;
1620 /* DispStream(s, "before inflate\n"); */
1622 /* inflate and check for errors */
1623 RETVAL = inflate(&(s->stream), Z_BLOCK);
1625 if (start_len > 1 && ! eof_mode)
1626 s->window_lastByte = *(s->stream.next_in - 1 ) ;
1628 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1629 RETVAL == Z_DATA_ERROR )
1632 if (s->flags & FLAG_CRC32 )
1633 s->crc32 = crc32(s->crc32, s->window + s->window_have,
1634 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1636 if (s->flags & FLAG_ADLER32)
1637 s->adler32 = adler32(s->adler32, s->window + s->window_have,
1638 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1640 s->uncompressedBytes =
1641 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1643 if (s->stream.avail_out)
1644 s->window_have = WINDOW_SIZE - s->stream.avail_out;
1650 /* process end of block */
1651 if (s->stream.data_type & 128) {
1652 if (s->stream.data_type & 64) {
1653 s->window_left = s->stream.data_type & 0x1f;
1656 s->window_lastbit = s->stream.data_type & 0x1f;
1657 s->lastBlockOffset = s->stream.total_in;
1661 } while (RETVAL != Z_STREAM_END);
1663 s->last_error = RETVAL ;
1664 s->window_lastoff = s->stream.total_in ;
1665 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1667 if (RETVAL == Z_STREAM_END)
1669 s->matchedEndBlock = 1 ;
1671 /* save the location of the end of the compressed data */
1672 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1673 s->window_endOffset = s->stream.total_in ;
1676 -- s->window_endOffset ;
1679 /* if window wrapped, build dictionary from window by rotating */
1680 if (s->window_full) {
1681 rotate(s->window, WINDOW_SIZE, s->window_have);
1682 s->window_have = WINDOW_SIZE;
1685 /* if (s->flags & FLAG_CONSUME_INPUT) { */
1687 unsigned in = s->stream.avail_in ;
1688 SvCUR_set(buf, in) ;
1690 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1702 Compress::Raw::Zlib::inflateScanStream s
1704 #ifndef MAGIC_APPEND
1705 croak("getEndOffset needs zlib 1.2.1 or better");
1707 RETVAL = s->window_endOffset;
1714 Compress::Raw::Zlib::inflateScanStream s
1716 #ifndef MAGIC_APPEND
1717 croak("inflateCount needs zlib 1.2.1 or better");
1719 RETVAL = s->bytesInflated;
1726 Compress::Raw::Zlib::inflateScanStream s
1728 RETVAL = s->compressedBytes;
1733 uncompressedBytes(s)
1734 Compress::Raw::Zlib::inflateScanStream s
1736 RETVAL = s->uncompressedBytes;
1742 getLastBlockOffset(s)
1743 Compress::Raw::Zlib::inflateScanStream s
1745 #ifndef MAGIC_APPEND
1746 croak("getLastBlockOffset needs zlib 1.2.1 or better");
1748 RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
1754 getLastBufferOffset(s)
1755 Compress::Raw::Zlib::inflateScanStream s
1757 #ifndef MAGIC_APPEND
1758 croak("getLastBufferOffset needs zlib 1.2.1 or better");
1760 RETVAL = s->window_lastoff;
1766 resetLastBlockByte(s, byte)
1767 Compress::Raw::Zlib::inflateScanStream s
1770 #ifndef MAGIC_APPEND
1771 croak("resetLastBlockByte needs zlib 1.2.1 or better");
1774 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
1779 _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1780 Compress::Raw::Zlib::inflateScanStream inf_s
1790 #ifndef MAGIC_APPEND
1794 windowBits = windowBits;
1795 memLevel = memLevel;
1796 strategy = strategy;
1798 croak("_createDeflateStream needs zlib 1.2.1 or better");
1804 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1805 level, method, windowBits, memLevel, strategy, bufsize) ;
1806 if ((s = InitStream() )) {
1810 s->WindowBits = windowBits;
1811 s->MemLevel = memLevel;
1812 s->Strategy = strategy;
1814 err = deflateInit2(&(s->stream), level,
1815 method, windowBits, memLevel, strategy);
1818 err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1819 s->dict_adler = s->stream.adler ;
1827 PostInitStream(s, flags, bufsize, windowBits) ;
1828 s->crc32 = inf_s->crc32;
1829 s->adler32 = inf_s->adler32;
1830 s->stream.adler = inf_s->stream.adler ;
1831 /* s->stream.total_out = inf_s->bytesInflated ; */
1832 s->stream.total_in = inf_s->stream.total_out ;
1833 if (inf_s->window_left) {
1834 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1835 deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1842 XPUSHs(sv_setref_pv(sv_newmortal(),
1843 "Compress::Raw::Zlib::deflateStream", (void*)s));
1844 if (GIMME == G_ARRAY) {
1845 SV * sv = sv_2mortal(newSViv(err)) ;
1846 setDUALstatus(sv, err);
1854 Compress::Raw::Zlib::inflateScanStream s
1856 RETVAL = s->last_error ;
1862 Compress::Raw::Zlib::inflateScanStream s
1871 Compress::Raw::Zlib::inflateScanStream s
1873 RETVAL = s->adler32 ;