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 >= 0x1222
54 # define AT_LEAST_ZLIB_1_2_2_2
57 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223
58 # define AT_LEAST_ZLIB_1_2_2_3
61 #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
62 # define AT_LEAST_ZLIB_1_2_3
66 # define NEED_sv_2pvbyte
67 # define NEED_sv_2pv_nolen
71 #if PERL_REVISION == 5 && PERL_VERSION == 9
73 # define sv_pvbyte_force(sv,lp) sv_pvbyten_force(sv,lp)
76 #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
78 # ifdef SvPVbyte_force
79 # undef SvPVbyte_force
82 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
86 #ifndef SvPVbyte_nolen
87 # define SvPVbyte_nolen SvPV_nolen
93 # ifndef SvPVbyte_nolen
94 # define SvPVbyte_nolen SvPV_nolen
97 # ifndef SvPVbyte_force
98 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
102 #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
103 # define UTF8_AVAILABLE
106 typedef int DualType ;
107 typedef int int_undef ;
109 typedef struct di_stream {
111 #define FLAG_APPEND 1
113 #define FLAG_ADLER32 4
114 #define FLAG_CONSUME_INPUT 8
125 bool deflateParams_out_valid ;
126 Bytef deflateParams_out_byte;
128 #define deflateParams_BUFFER_SIZE 0x4000
129 uLong deflateParams_out_length;
130 Bytef* deflateParams_out_buffer;
137 uLong bytesInflated ;
138 uLong compressedBytes ;
139 uLong uncompressedBytes ;
142 #define WINDOW_SIZE 32768U
144 bool matchedEndBlock;
146 int window_lastbit, window_left, window_full;
147 unsigned window_have;
148 off_t window_lastoff, window_end;
149 off_t window_endOffset;
151 uLong lastBlockOffset ;
152 unsigned char window_lastByte ;
158 typedef di_stream * deflateStream ;
159 typedef di_stream * Compress__Raw__Zlib__deflateStream ;
160 typedef di_stream * inflateStream ;
161 typedef di_stream * Compress__Raw__Zlib__inflateStream ;
162 typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;
164 #define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
167 /* Figure out the Operating System */
169 # define OS_CODE 0x00
172 #if defined(AMIGA) || defined(AMIGAOS)
173 # define OS_CODE 0x01
176 #if defined(VAXC) || defined(VMS)
177 # define OS_CODE 0x02
181 # define OS_CODE 0x04
184 #if defined(ATARI) || defined(atarist)
185 # define OS_CODE 0x05
189 # define OS_CODE 0x06
192 #if defined(MACOS) || defined(TARGET_OS_MAC)
193 # define OS_CODE 0x07
197 # define OS_CODE 0x08
201 # define OS_CODE 0x09
205 # define OS_CODE 0x0a
208 #ifdef WIN32 /* Window 95 & Windows NT */
209 # define OS_CODE 0x0b
213 # define OS_CODE 0x0c
216 #if 0 /* Acorn RISCOS */
217 # define OS_CODE 0x0d
221 # define OS_CODE 0x0e
224 #ifdef __50SERIES /* Prime/PRIMOS */
225 # define OS_CODE 0x0F
228 /* Default to UNIX */
230 # define OS_CODE 0x03 /* assume Unix */
234 # define GZIP_OS_CODE OS_CODE
237 #define adlerInitial adler32(0L, Z_NULL, 0)
238 #define crcInitial crc32(0L, Z_NULL, 0)
240 /* static const char * const my_z_errmsg[] = { */
241 static const char my_z_errmsg[][32] = {
242 "need dictionary", /* Z_NEED_DICT 2 */
243 "stream end", /* Z_STREAM_END 1 */
245 "file error", /* Z_ERRNO (-1) */
246 "stream error", /* Z_STREAM_ERROR (-2) */
247 "data error", /* Z_DATA_ERROR (-3) */
248 "insufficient memory", /* Z_MEM_ERROR (-4) */
249 "buffer error", /* Z_BUF_ERROR (-5) */
250 "incompatible version",/* Z_VERSION_ERROR(-6) */
253 #define setDUALstatus(var, err) \
254 sv_setnv(var, (double)err) ; \
255 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
259 #if defined(__SYMBIAN32__)
260 # define NO_WRITEABLE_DATA
263 #define TRACE_DEFAULT 0
265 #ifdef NO_WRITEABLE_DATA
266 # define trace TRACE_DEFAULT
268 static int trace = TRACE_DEFAULT ;
271 /* Dodge PerlIO hiding of these functions. */
276 GetErrorString(int error_no)
278 GetErrorString(error_no)
285 if (error_no == Z_ERRNO) {
286 errstr = Strerror(errno) ;
289 /* errstr = gzerror(fil, &error_no) ; */
290 errstr = (char*) my_z_errmsg[2 - error_no];
299 The following two functions are taken almost directly from
300 examples/gzappend.c. Only cosmetic changes have been made to conform to
301 the coding style of the rest of the code in this file.
305 /* return the greatest common divisor of a and b using Euclid's algorithm,
306 modified to be fast when one argument much greater than the other, and
307 coded to avoid unnecessary swapping */
310 gcd(unsigned a, unsigned b)
335 /* rotate list[0..len-1] left by rot positions, in place */
338 rotate(unsigned char *list, unsigned len, unsigned rot)
340 rotate(list, len, rot)
348 unsigned char *start, *last, *to, *from;
350 /* normalize rot and handle degenerate cases */
352 if (rot >= len) rot %= len;
353 if (rot == 0) return;
355 /* pointer to last entry in list */
356 last = list + (len - 1);
358 /* do simple left shift by one */
361 memcpy(list, list + 1, len - 1);
366 /* do simple right shift by one */
367 if (rot == len - 1) {
369 memmove(list + 1, list, len - 1);
374 /* otherwise do rotate as a set of cycles in place */
375 cycles = gcd(len, rot); /* number of cycles */
377 start = from = list + cycles; /* start index is arbitrary */
378 tmp = *from; /* save entry to be overwritten */
380 to = from; /* next step in cycle */
381 from += rot; /* go right rot positions */
382 if (from > last) from -= len; /* (pointer better not wrap) */
383 if (from == start) break; /* all but one shifted */
384 *to = *from; /* shift left */
386 *to = tmp; /* complete the circle */
390 #endif /* MAGIC_APPEND */
394 DispHex(void * ptr, int length)
401 char * p = (char*)ptr;
403 for (i = 0; i < length; ++i) {
404 printf(" %02x", 0xFF & *(p+i));
411 DispStream(di_stream * s, char * message)
413 DispStream(s, message)
424 #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
426 printf("DispStream 0x%p", s) ;
428 printf("- %s \n", message) ;
432 printf(" stream pointer is NULL\n");
435 printf(" stream 0x%p\n", &(s->stream));
436 printf(" zalloc 0x%p\n", s->stream.zalloc);
437 printf(" zfree 0x%p\n", s->stream.zfree);
438 printf(" opaque 0x%p\n", s->stream.opaque);
440 printf(" msg %s\n", s->stream.msg);
443 printf(" next_in 0x%p", s->stream.next_in);
444 if (s->stream.next_in){
446 DispHex(s->stream.next_in, 4);
450 printf(" next_out 0x%p", s->stream.next_out);
451 if (s->stream.next_out){
453 DispHex(s->stream.next_out, 4);
457 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
458 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
459 printf(" total_in %ld\n", s->stream.total_in);
460 printf(" total_out %ld\n", s->stream.total_out);
461 printf(" adler %ld\n", s->stream.adler );
462 printf(" bufsize %ld\n", s->bufsize);
463 printf(" dictionary 0x%p\n", s->dictionary);
464 printf(" dict_adler 0x%ld\n",s->dict_adler);
465 printf(" zip_mode %d\n", s->zip_mode);
466 printf(" crc32 0x%x\n", (unsigned)s->crc32);
467 printf(" adler32 0x%x\n", (unsigned)s->adler32);
468 printf(" flags 0x%x\n", s->flags);
469 printf(" APPEND %s\n", EnDis(FLAG_APPEND));
470 printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
471 printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
472 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
475 printf(" window 0x%p\n", s->window);
491 ZMALLOC(s, di_stream) ;
499 PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
501 PostInitStream(s, flags, bufsize, windowBits)
508 s->bufsize = bufsize ;
510 s->uncompressedBytes =
513 s->zip_mode = (windowBits < 0) ;
514 if (flags & FLAG_CRC32)
515 s->crc32 = crcInitial ;
516 if (flags & FLAG_ADLER32)
517 s->adler32 = adlerInitial ;
523 deRef(SV * sv, const char * string)
540 croak("%s: buffer parameter is not a SCALAR reference", string);
543 croak("%s: buffer parameter is a reference to a reference", string) ;
555 deRef_l(SV * sv, const char * string)
577 croak("%s: buffer parameter is not a SCALAR reference", string);
580 croak("%s: buffer parameter is a reference to a reference", string) ;
583 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
584 croak("%s: buffer parameter is read-only", string);
586 SvUPGRADE(sv, SVt_PV);
598 #include "constants.h"
600 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
605 INCLUDE: constants.xs
608 /* Check this version of zlib is == 1 */
609 if (zlibVersion()[0] != '1')
610 croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
613 /* Create the $os_code scalar */
614 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
615 sv_setiv(os_code_sv, GZIP_OS_CODE) ;
619 #define Zip_zlib_version() (const char*)zlib_version
627 RETVAL = ZLIB_VERNUM ;
629 /* 1.1.4 => 0x1140 */
630 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
631 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
632 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
637 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
639 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
642 Zip_adler32(buf, adler=adlerInitial)
643 uLong adler = NO_INIT
645 Bytef * buf = NO_INIT
648 /* If the buffer is a reference, dereference it */
649 sv = deRef(sv, "adler32") ;
650 #ifdef UTF8_AVAILABLE
651 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
652 croak("Wide character in Compress::Raw::Zlib::adler32");
654 buf = (Byte*)SvPVbyte(sv, len) ;
657 adler = adlerInitial;
658 else if (SvOK(ST(1)))
659 adler = SvUV(ST(1)) ;
661 adler = adlerInitial;
665 #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
668 Zip_crc32(buf, crc=crcInitial)
671 Bytef * buf = NO_INIT
674 /* If the buffer is a reference, dereference it */
675 sv = deRef(sv, "crc32") ;
676 #ifdef UTF8_AVAILABLE
677 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
678 croak("Wide character in Compress::Raw::Zlib::crc32");
680 buf = (Byte*)SvPVbyte(sv, len) ;
684 else if (SvOK(ST(1)))
691 crc32_combine(crc1, crc2, len2)
696 #ifndef AT_LEAST_ZLIB_1_2_2_1
697 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
698 croak("crc32_combine needs zlib 1.2.3 or better");
700 RETVAL = crc32_combine(crc1, crc2, len2);
707 adler32_combine(adler1, adler2, len2)
712 #ifndef AT_LEAST_ZLIB_1_2_2_1
713 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
714 croak("adler32_combine needs zlib 1.2.3 or better");
716 RETVAL = adler32_combine(adler1, adler2, len2);
722 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
725 _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
739 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
740 level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
741 if ((s = InitStream() )) {
745 s->WindowBits = windowBits;
746 s->MemLevel = memLevel;
747 s->Strategy = strategy;
749 err = deflateInit2(&(s->stream), level,
750 method, windowBits, memLevel, strategy);
752 /* Check if a dictionary has been specified */
754 if (err == Z_OK && SvCUR(dictionary)) {
755 #ifdef UTF8_AVAILABLE
756 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
757 croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
759 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
761 s->dict_adler = s->stream.adler ;
769 PostInitStream(s, flags, bufsize, windowBits) ;
776 SV* obj = sv_setref_pv(sv_newmortal(),
777 "Compress::Raw::Zlib::deflateStream", (void*)s);
780 if (GIMME == G_ARRAY) {
781 SV * sv = sv_2mortal(newSViv(err)) ;
782 setDUALstatus(sv, err);
787 _inflateInit(flags, windowBits, bufsize, dictionary)
800 croak("inflateScanInit needs zlib 1.2.1 or better");
803 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
804 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
805 if ((s = InitStream() )) {
807 s->WindowBits = windowBits;
809 err = inflateInit2(&(s->stream), windowBits);
814 else if (SvCUR(dictionary)) {
815 #ifdef AT_LEAST_ZLIB_1_2_2_1
816 /* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */
817 if (s->WindowBits < 0) {
818 err = inflateSetDictionary(&(s->stream),
819 (const Bytef*)SvPVbyte_nolen(dictionary),
828 /* Dictionary specified - take a copy for use in inflate */
829 s->dictionary = newSVsv(dictionary) ;
832 PostInitStream(s, flags, bufsize, windowBits) ;
836 s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
845 SV* obj = sv_setref_pv(sv_newmortal(),
847 ? "Compress::Raw::Zlib::inflateScanStream"
848 : "Compress::Raw::Zlib::inflateStream",
852 if (GIMME == G_ARRAY) {
853 SV * sv = sv_2mortal(newSViv(err)) ;
854 setDUALstatus(sv, err);
860 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
863 DispStream(s, message=NULL)
864 Compress::Raw::Zlib::deflateStream s
869 Compress::Raw::Zlib::deflateStream s
871 RETVAL = deflateReset(&(s->stream)) ;
872 if (RETVAL == Z_OK) {
873 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
879 deflate (s, buf, output)
880 Compress::Raw::Zlib::deflateStream s
883 uInt cur_length = NO_INIT
884 uInt increment = NO_INIT
885 uInt prefix = NO_INIT
887 uLong bufinc = NO_INIT
891 /* If the input buffer is a reference, dereference it */
892 buf = deRef(buf, "deflate") ;
894 /* initialise the input buffer */
895 #ifdef UTF8_AVAILABLE
896 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
897 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
899 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
900 s->stream.avail_in = SvCUR(buf) ;
902 if (s->flags & FLAG_CRC32)
903 s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
905 if (s->flags & FLAG_ADLER32)
906 s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
908 /* and retrieve the output buffer */
909 output = deRef_l(output, "deflate") ;
910 #ifdef UTF8_AVAILABLE
911 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
912 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
915 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
916 SvCUR_set(output, 0);
917 /* sv_setpvn(output, "", 0); */
919 prefix = cur_length = SvCUR(output) ;
920 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
921 increment = SvLEN(output) - cur_length;
922 s->stream.avail_out = increment;
924 /* Check for saved output from deflateParams */
925 if (s->deflateParams_out_valid) {
926 *(s->stream.next_out) = s->deflateParams_out_byte;
927 ++ s->stream.next_out;
928 -- s->stream.avail_out ;
929 s->deflateParams_out_valid = FALSE;
932 /* Check for saved output from deflateParams */
933 if (s->deflateParams_out_length) {
934 uLong plen = s->deflateParams_out_length ;
935 /* printf("Copy %d bytes saved data\n", plen);*/
936 if (s->stream.avail_out < plen) {
937 /*printf("GROW from %d to %d\n", s->stream.avail_out,
938 SvLEN(output) + plen - s->stream.avail_out); */
939 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
942 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
943 cur_length = cur_length + plen;
944 SvCUR_set(output, cur_length);
945 s->stream.next_out += plen ;
946 s->stream.avail_out = SvLEN(output) - cur_length ;
947 increment = s->stream.avail_out;
948 s->deflateParams_out_length = 0;
951 while (s->stream.avail_in != 0) {
953 if (s->stream.avail_out == 0) {
954 /* out of space in the output buffer so make it bigger */
955 Sv_Grow(output, SvLEN(output) + bufinc) ;
956 cur_length += increment ;
957 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
959 s->stream.avail_out = increment;
963 RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
968 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
969 s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
971 s->last_error = RETVAL ;
972 if (RETVAL == Z_OK) {
974 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
983 Compress::Raw::Zlib::deflateStream s
985 deflateEnd(&s->stream) ;
987 SvREFCNT_dec(s->dictionary) ;
989 if (s->deflateParams_out_buffer)
990 Safefree(s->deflateParams_out_buffer);
996 flush(s, output, f=Z_FINISH)
997 Compress::Raw::Zlib::deflateStream s
1000 uInt cur_length = NO_INIT
1001 uInt increment = NO_INIT
1002 uInt prefix = NO_INIT
1003 uLong bufinc = NO_INIT
1005 bufinc = s->bufsize;
1007 s->stream.avail_in = 0; /* should be zero already anyway */
1009 /* retrieve the output buffer */
1010 output = deRef_l(output, "flush") ;
1011 #ifdef UTF8_AVAILABLE
1012 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1013 croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
1015 if(! s->flags & FLAG_APPEND) {
1016 SvCUR_set(output, 0);
1017 /* sv_setpvn(output, "", 0); */
1019 prefix = 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;
1053 if (s->stream.avail_out == 0) {
1054 /* consumed all the available output, so extend it */
1055 Sv_Grow(output, SvLEN(output) + bufinc) ;
1056 cur_length += increment ;
1057 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1058 increment = bufinc ;
1059 s->stream.avail_out = increment;
1062 RETVAL = deflate(&(s->stream), f);
1064 /* deflate has finished flushing only when it hasn't used up
1065 * all the available space in the output buffer:
1067 if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1071 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1072 s->last_error = RETVAL ;
1074 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1076 if (RETVAL == Z_OK) {
1078 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1086 _deflateParams(s, flags, level, strategy, bufsize)
1087 Compress::Raw::Zlib::deflateStream s
1093 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1094 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1098 s->Strategy = strategy ;
1100 s->bufsize = bufsize;
1102 /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1104 s->stream.avail_in = 0;
1105 s->stream.next_out = &(s->deflateParams_out_byte) ;
1106 s->stream.avail_out = 1;
1107 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1108 s->deflateParams_out_valid =
1109 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1110 /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1112 /* printf("Level %d Strategy %d, Prev Len %d\n",
1113 s->Level, s->Strategy, s->deflateParams_out_length); */
1114 s->stream.avail_in = 0;
1115 if (s->deflateParams_out_buffer == NULL)
1116 s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1117 s->stream.next_out = s->deflateParams_out_buffer ;
1118 s->stream.avail_out = deflateParams_BUFFER_SIZE;
1120 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1121 s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1122 /* printf("RETVAL %d, length out %d, avail %d\n",
1123 RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1131 Compress::Raw::Zlib::deflateStream s
1139 Compress::Raw::Zlib::deflateStream s
1141 RETVAL = s->Strategy ;
1148 Compress::Raw::Zlib::deflateStream s
1150 RETVAL = s->bufsize ;
1157 Compress::Raw::Zlib::deflateStream s
1159 RETVAL = s->last_error ;
1165 Compress::Raw::Zlib::deflateStream s
1173 Compress::Raw::Zlib::deflateStream s
1175 RETVAL = s->dict_adler ;
1181 Compress::Raw::Zlib::deflateStream s
1183 RETVAL = s->adler32 ;
1189 Compress::Raw::Zlib::deflateStream s
1191 RETVAL = s->compressedBytes;
1196 uncompressedBytes(s)
1197 Compress::Raw::Zlib::deflateStream s
1199 RETVAL = s->uncompressedBytes;
1205 Compress::Raw::Zlib::deflateStream s
1207 RETVAL = s->stream.total_in ;
1213 Compress::Raw::Zlib::deflateStream s
1215 RETVAL = s->stream.total_out ;
1221 Compress::Raw::Zlib::deflateStream s
1223 RETVAL = s->stream.msg;
1228 deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1229 Compress::Raw::Zlib::deflateStream s
1235 #ifndef AT_LEAST_ZLIB_1_2_2_3
1236 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1237 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1238 croak("deflateTune needs zlib 1.2.2.3 or better");
1240 RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1246 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1249 DispStream(s, message=NULL)
1250 Compress::Raw::Zlib::inflateStream s
1255 Compress::Raw::Zlib::inflateStream s
1257 RETVAL = inflateReset(&(s->stream)) ;
1258 if (RETVAL == Z_OK) {
1259 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1265 inflate (s, buf, output, eof=FALSE)
1266 Compress::Raw::Zlib::inflateStream s
1270 uInt cur_length = 0;
1271 uInt prefix_length = 0;
1273 STRLEN stmp = NO_INIT
1274 uLong bufinc = NO_INIT
1276 #ifdef UTF8_AVAILABLE
1277 bool out_utf8 = FALSE;
1280 bufinc = s->bufsize;
1281 /* If the buffer is a reference, dereference it */
1282 buf = deRef(buf, "inflate") ;
1284 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
1285 croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1286 #ifdef UTF8_AVAILABLE
1287 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1288 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1291 /* initialise the input buffer */
1292 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1293 s->stream.avail_in = SvCUR(buf) ;
1295 /* and retrieve the output buffer */
1296 output = deRef_l(output, "inflate") ;
1297 #ifdef UTF8_AVAILABLE
1298 if (DO_UTF8(output))
1300 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1301 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1303 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1304 SvCUR_set(output, 0);
1306 if (SvLEN(output)) {
1307 prefix_length = cur_length = SvCUR(output) ;
1308 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1309 increment = SvLEN(output) - cur_length - 1;
1310 s->stream.avail_out = increment;
1313 s->stream.avail_out = 0;
1315 s->bytesInflated = 0;
1319 while (RETVAL == Z_OK) {
1320 if (s->stream.avail_out == 0 ) {
1321 /* out of space in the output buffer so make it bigger */
1322 Sv_Grow(output, SvLEN(output) + bufinc) ;
1323 cur_length += increment ;
1324 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1325 increment = bufinc ;
1326 s->stream.avail_out = increment;
1330 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1332 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1333 RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1336 if (RETVAL == Z_BUF_ERROR) {
1337 if (s->stream.avail_out == 0)
1339 if (s->stream.avail_in == 0) {
1345 if (RETVAL == Z_NEED_DICT && s->dictionary) {
1346 s->dict_adler = s->stream.adler ;
1347 RETVAL = inflateSetDictionary(&(s->stream),
1348 (const Bytef*)SvPVbyte_nolen(s->dictionary),
1349 SvCUR(s->dictionary));
1353 #ifdef NEED_DUMMY_BYTE_AT_END
1354 if (eof && RETVAL == Z_OK) {
1355 Bytef* nextIn = s->stream.next_in;
1356 uInt availIn = s->stream.avail_in;
1357 s->stream.next_in = (Bytef*) " ";
1358 s->stream.avail_in = 1;
1359 if (s->stream.avail_out == 0) {
1360 /* out of space in the output buffer so make it bigger */
1361 Sv_Grow(output, SvLEN(output) + bufinc) ;
1362 cur_length += increment ;
1363 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1364 increment = bufinc ;
1365 s->stream.avail_out = increment;
1368 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1369 s->stream.next_in = nextIn ;
1370 s->stream.avail_in = availIn ;
1374 s->last_error = RETVAL ;
1375 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_DATA_ERROR) {
1378 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1379 s->uncompressedBytes += s->bytesInflated ;
1380 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1383 SvCUR_set(output, prefix_length + s->bytesInflated) ;
1384 *SvEND(output) = '\0';
1385 #ifdef UTF8_AVAILABLE
1387 sv_utf8_upgrade(output);
1391 if (s->flags & FLAG_CRC32 )
1392 s->crc32 = crc32(s->crc32,
1393 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1394 SvCUR(output)-prefix_length) ;
1396 if (s->flags & FLAG_ADLER32)
1397 s->adler32 = adler32(s->adler32,
1398 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1399 SvCUR(output)-prefix_length) ;
1401 /* fix the input buffer */
1402 if (s->flags & FLAG_CONSUME_INPUT) {
1403 in = s->stream.avail_in ;
1404 SvCUR_set(buf, in) ;
1406 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1416 Compress::Raw::Zlib::inflateStream s
1418 RETVAL = s->bytesInflated;
1424 Compress::Raw::Zlib::inflateStream s
1426 RETVAL = s->compressedBytes;
1431 uncompressedBytes(s)
1432 Compress::Raw::Zlib::inflateStream s
1434 RETVAL = s->uncompressedBytes;
1440 inflateSync (s, buf)
1441 Compress::Raw::Zlib::inflateStream s
1445 /* If the buffer is a reference, dereference it */
1446 buf = deRef(buf, "inflateSync") ;
1447 #ifdef UTF8_AVAILABLE
1448 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1449 croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1452 /* initialise the input buffer */
1453 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
1454 s->stream.avail_in = SvCUR(buf) ;
1456 /* inflateSync doesn't create any output */
1457 s->stream.next_out = (Bytef*) NULL;
1458 s->stream.avail_out = 0;
1460 RETVAL = inflateSync(&(s->stream));
1461 s->last_error = RETVAL ;
1463 /* fix the input buffer */
1465 unsigned in = s->stream.avail_in ;
1466 SvCUR_set(buf, in) ;
1468 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1477 Compress::Raw::Zlib::inflateStream s
1479 inflateEnd(&s->stream) ;
1481 SvREFCNT_dec(s->dictionary) ;
1483 if (s->deflateParams_out_buffer)
1484 Safefree(s->deflateParams_out_buffer);
1488 Safefree(s->window);
1495 Compress::Raw::Zlib::inflateStream s
1497 RETVAL = s->last_error ;
1503 Compress::Raw::Zlib::inflateStream s
1511 Compress::Raw::Zlib::inflateStream s
1513 RETVAL = s->dict_adler ;
1519 Compress::Raw::Zlib::inflateStream s
1521 RETVAL = s->stream.total_in ;
1527 Compress::Raw::Zlib::inflateStream s
1529 RETVAL = s->adler32 ;
1535 Compress::Raw::Zlib::inflateStream s
1537 RETVAL = s->stream.total_out ;
1543 Compress::Raw::Zlib::inflateStream s
1545 RETVAL = s->stream.msg;
1552 Compress::Raw::Zlib::inflateStream s
1554 RETVAL = s->bufsize ;
1560 Compress::Raw::Zlib::inflateStream s
1563 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1565 s->flags |= FLAG_APPEND ;
1567 s->flags &= ~FLAG_APPEND ;
1571 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
1575 Compress::Raw::Zlib::inflateScanStream s
1577 inflateEnd(&s->stream) ;
1579 SvREFCNT_dec(s->dictionary) ;
1581 if (s->deflateParams_out_buffer)
1582 Safefree(s->deflateParams_out_buffer);
1586 Safefree(s->window);
1591 DispStream(s, message=NULL)
1592 Compress::Raw::Zlib::inflateScanStream s
1597 Compress::Raw::Zlib::inflateScanStream s
1599 RETVAL = inflateReset(&(s->stream)) ;
1600 if (RETVAL == Z_OK) {
1601 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1607 scan(s, buf, out=NULL, eof=FALSE)
1608 Compress::Raw::Zlib::inflateScanStream s
1612 bool eof_mode = FALSE;
1613 int start_len = NO_INIT
1614 STRLEN stmp = NO_INIT
1616 /* If the input buffer is a reference, dereference it */
1617 #ifndef MAGIC_APPEND
1619 croak("scan needs zlib 1.2.1 or better");
1621 buf = deRef(buf, "inflateScan") ;
1622 #ifdef UTF8_AVAILABLE
1623 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1624 croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
1626 /* initialise the input buffer */
1627 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1628 s->stream.avail_in = SvCUR(buf) ;
1629 start_len = s->stream.avail_in ;
1630 s->bytesInflated = 0 ;
1633 if (s->stream.avail_in == 0) {
1638 /* set up output to next available section of sliding window */
1639 s->stream.avail_out = WINDOW_SIZE - s->window_have;
1640 s->stream.next_out = s->window + s->window_have;
1642 /* DispStream(s, "before inflate\n"); */
1644 /* inflate and check for errors */
1645 RETVAL = inflate(&(s->stream), Z_BLOCK);
1647 if (start_len > 1 && ! eof_mode)
1648 s->window_lastByte = *(s->stream.next_in - 1 ) ;
1650 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1651 RETVAL == Z_DATA_ERROR )
1654 if (s->flags & FLAG_CRC32 )
1655 s->crc32 = crc32(s->crc32, s->window + s->window_have,
1656 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1658 if (s->flags & FLAG_ADLER32)
1659 s->adler32 = adler32(s->adler32, s->window + s->window_have,
1660 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1662 s->uncompressedBytes =
1663 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1665 if (s->stream.avail_out)
1666 s->window_have = WINDOW_SIZE - s->stream.avail_out;
1672 /* process end of block */
1673 if (s->stream.data_type & 128) {
1674 if (s->stream.data_type & 64) {
1675 s->window_left = s->stream.data_type & 0x1f;
1678 s->window_lastbit = s->stream.data_type & 0x1f;
1679 s->lastBlockOffset = s->stream.total_in;
1683 } while (RETVAL != Z_STREAM_END);
1685 s->last_error = RETVAL ;
1686 s->window_lastoff = s->stream.total_in ;
1687 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1689 if (RETVAL == Z_STREAM_END)
1691 s->matchedEndBlock = 1 ;
1693 /* save the location of the end of the compressed data */
1694 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1695 s->window_endOffset = s->stream.total_in ;
1698 -- s->window_endOffset ;
1701 /* if window wrapped, build dictionary from window by rotating */
1702 if (s->window_full) {
1703 rotate(s->window, WINDOW_SIZE, s->window_have);
1704 s->window_have = WINDOW_SIZE;
1707 /* if (s->flags & FLAG_CONSUME_INPUT) { */
1709 unsigned in = s->stream.avail_in ;
1710 SvCUR_set(buf, in) ;
1712 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1724 Compress::Raw::Zlib::inflateScanStream s
1726 #ifndef MAGIC_APPEND
1727 croak("getEndOffset needs zlib 1.2.1 or better");
1729 RETVAL = s->window_endOffset;
1736 Compress::Raw::Zlib::inflateScanStream s
1738 #ifndef MAGIC_APPEND
1739 croak("inflateCount needs zlib 1.2.1 or better");
1741 RETVAL = s->bytesInflated;
1748 Compress::Raw::Zlib::inflateScanStream s
1750 RETVAL = s->compressedBytes;
1755 uncompressedBytes(s)
1756 Compress::Raw::Zlib::inflateScanStream s
1758 RETVAL = s->uncompressedBytes;
1764 getLastBlockOffset(s)
1765 Compress::Raw::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::Raw::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::Raw::Zlib::inflateScanStream s
1792 #ifndef MAGIC_APPEND
1793 croak("resetLastBlockByte needs zlib 1.2.1 or better");
1796 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
1801 _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1802 Compress::Raw::Zlib::inflateScanStream inf_s
1812 #ifndef MAGIC_APPEND
1816 windowBits = windowBits;
1817 memLevel = memLevel;
1818 strategy = strategy;
1820 croak("_createDeflateStream needs zlib 1.2.1 or better");
1826 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1827 level, method, windowBits, memLevel, strategy, bufsize) ;
1828 if ((s = InitStream() )) {
1832 s->WindowBits = windowBits;
1833 s->MemLevel = memLevel;
1834 s->Strategy = strategy;
1836 err = deflateInit2(&(s->stream), level,
1837 method, windowBits, memLevel, strategy);
1840 err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1841 s->dict_adler = s->stream.adler ;
1849 PostInitStream(s, flags, bufsize, windowBits) ;
1850 s->crc32 = inf_s->crc32;
1851 s->adler32 = inf_s->adler32;
1852 s->stream.adler = inf_s->stream.adler ;
1853 /* s->stream.total_out = inf_s->bytesInflated ; */
1854 s->stream.total_in = inf_s->stream.total_out ;
1855 if (inf_s->window_left) {
1856 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1857 deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1864 XPUSHs(sv_setref_pv(sv_newmortal(),
1865 "Compress::Raw::Zlib::deflateStream", (void*)s));
1866 if (GIMME == G_ARRAY) {
1867 SV * sv = sv_2mortal(newSViv(err)) ;
1868 setDUALstatus(sv, err);
1876 Compress::Raw::Zlib::inflateScanStream s
1878 RETVAL = s->last_error ;
1884 Compress::Raw::Zlib::inflateScanStream s
1893 Compress::Raw::Zlib::inflateScanStream s
1895 RETVAL = s->adler32 ;