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 static const char my_z_errmsg[][32] = {
233 "need dictionary", /* Z_NEED_DICT 2 */
234 "stream end", /* Z_STREAM_END 1 */
236 "file error", /* Z_ERRNO (-1) */
237 "stream error", /* Z_STREAM_ERROR (-2) */
238 "data error", /* Z_DATA_ERROR (-3) */
239 "insufficient memory", /* Z_MEM_ERROR (-4) */
240 "buffer error", /* Z_BUF_ERROR (-5) */
241 "incompatible version",/* Z_VERSION_ERROR(-6) */
244 #define setDUALstatus(var, err) \
245 sv_setnv(var, (double)err) ; \
246 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
250 #if defined(__SYMBIAN32__)
251 # define NO_WRITEABLE_DATA
254 #define TRACE_DEFAULT 0
256 #ifdef NO_WRITEABLE_DATA
257 # define trace TRACE_DEFAULT
259 static int trace = TRACE_DEFAULT ;
262 /* Dodge PerlIO hiding of these functions. */
267 GetErrorString(int error_no)
269 GetErrorString(error_no)
276 if (error_no == Z_ERRNO) {
277 errstr = Strerror(errno) ;
280 /* errstr = gzerror(fil, &error_no) ; */
281 errstr = (char*) my_z_errmsg[2 - error_no];
290 The following two functions are taken almost directly from
291 examples/gzappend.c. Only cosmetic changes have been made to conform to
292 the coding style of the rest of the code in this file.
296 /* return the greatest common divisor of a and b using Euclid's algorithm,
297 modified to be fast when one argument much greater than the other, and
298 coded to avoid unnecessary swapping */
301 gcd(unsigned a, unsigned b)
326 /* rotate list[0..len-1] left by rot positions, in place */
329 rotate(unsigned char *list, unsigned len, unsigned rot)
331 rotate(list, len, rot)
339 unsigned char *start, *last, *to, *from;
341 /* normalize rot and handle degenerate cases */
343 if (rot >= len) rot %= len;
344 if (rot == 0) return;
346 /* pointer to last entry in list */
347 last = list + (len - 1);
349 /* do simple left shift by one */
352 memcpy(list, list + 1, len - 1);
357 /* do simple right shift by one */
358 if (rot == len - 1) {
360 memmove(list + 1, list, len - 1);
365 /* otherwise do rotate as a set of cycles in place */
366 cycles = gcd(len, rot); /* number of cycles */
368 start = from = list + cycles; /* start index is arbitrary */
369 tmp = *from; /* save entry to be overwritten */
371 to = from; /* next step in cycle */
372 from += rot; /* go right rot positions */
373 if (from > last) from -= len; /* (pointer better not wrap) */
374 if (from == start) break; /* all but one shifted */
375 *to = *from; /* shift left */
377 *to = tmp; /* complete the circle */
381 #endif /* MAGIC_APPEND */
385 DispHex(void * ptr, int length)
392 char * p = (char*)ptr;
394 for (i = 0; i < length; ++i) {
395 printf(" %02x", 0xFF & *(p+i));
402 DispStream(di_stream * s, char * message)
404 DispStream(s, message)
415 #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
417 printf("DispStream 0x%p", s) ;
419 printf("- %s \n", message) ;
423 printf(" stream pointer is NULL\n");
426 printf(" stream 0x%p\n", &(s->stream));
427 printf(" zalloc 0x%p\n", s->stream.zalloc);
428 printf(" zfree 0x%p\n", s->stream.zfree);
429 printf(" opaque 0x%p\n", s->stream.opaque);
431 printf(" msg %s\n", s->stream.msg);
434 printf(" next_in 0x%p", s->stream.next_in);
435 if (s->stream.next_in){
437 DispHex(s->stream.next_in, 4);
441 printf(" next_out 0x%p", s->stream.next_out);
442 if (s->stream.next_out){
444 DispHex(s->stream.next_out, 4);
448 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
449 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
450 printf(" total_in %ld\n", s->stream.total_in);
451 printf(" total_out %ld\n", s->stream.total_out);
452 printf(" adler %ld\n", s->stream.adler );
453 printf(" bufsize %ld\n", s->bufsize);
454 printf(" dictionary 0x%p\n", s->dictionary);
455 printf(" dict_adler 0x%ld\n",s->dict_adler);
456 printf(" zip_mode %d\n", s->zip_mode);
457 printf(" crc32 0x%x\n", (unsigned)s->crc32);
458 printf(" adler32 0x%x\n", (unsigned)s->adler32);
459 printf(" flags 0x%x\n", s->flags);
460 printf(" APPEND %s\n", EnDis(FLAG_APPEND));
461 printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
462 printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
463 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
466 printf(" window 0x%p\n", s->window);
482 ZMALLOC(s, di_stream) ;
490 PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
492 PostInitStream(s, flags, bufsize, windowBits)
499 s->bufsize = bufsize ;
501 s->uncompressedBytes =
504 s->zip_mode = (windowBits < 0) ;
505 if (flags & FLAG_CRC32)
506 s->crc32 = crcInitial ;
507 if (flags & FLAG_ADLER32)
508 s->adler32 = adlerInitial ;
514 deRef(SV * sv, const char * string)
531 croak("%s: buffer parameter is not a SCALAR reference", string);
534 croak("%s: buffer parameter is a reference to a reference", string) ;
546 deRef_l(SV * sv, const char * string)
568 croak("%s: buffer parameter is not a SCALAR reference", string);
571 croak("%s: buffer parameter is a reference to a reference", string) ;
574 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
575 croak("%s: buffer parameter is read-only", string);
577 SvUPGRADE(sv, SVt_PV);
589 #include "constants.h"
591 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
596 INCLUDE: constants.xs
599 /* Check this version of zlib is == 1 */
600 if (zlibVersion()[0] != '1')
601 croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
604 /* Create the $os_code scalar */
605 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
606 sv_setiv(os_code_sv, GZIP_OS_CODE) ;
610 #define Zip_zlib_version() (const char*)zlib_version
618 RETVAL = ZLIB_VERNUM ;
620 /* 1.1.4 => 0x1140 */
621 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
622 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
623 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
628 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
630 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
633 Zip_adler32(buf, adler=adlerInitial)
634 uLong adler = NO_INIT
636 Bytef * buf = NO_INIT
639 /* If the buffer is a reference, dereference it */
640 sv = deRef(sv, "adler32") ;
641 #ifdef UTF8_AVAILABLE
642 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
643 croak("Wide character in Compress::Raw::Zlib::adler32");
645 buf = (Byte*)SvPVbyte(sv, len) ;
648 adler = adlerInitial;
649 else if (SvOK(ST(1)))
650 adler = SvUV(ST(1)) ;
652 adler = adlerInitial;
656 #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
659 Zip_crc32(buf, crc=crcInitial)
662 Bytef * buf = NO_INIT
665 /* If the buffer is a reference, dereference it */
666 sv = deRef(sv, "crc32") ;
667 #ifdef UTF8_AVAILABLE
668 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
669 croak("Wide character in Compress::Raw::Zlib::crc32");
671 buf = (Byte*)SvPVbyte(sv, len) ;
675 else if (SvOK(ST(1)))
682 crc32_combine(crc1, crc2, len2)
687 #ifndef AT_LEAST_ZLIB_1_2_2_1
688 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
689 croak("crc32_combine needs zlib 1.2.3 or better");
691 RETVAL = crc32_combine(crc1, crc2, len2);
698 adler32_combine(adler1, adler2, len2)
703 #ifndef AT_LEAST_ZLIB_1_2_2_1
704 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
705 croak("adler32_combine needs zlib 1.2.3 or better");
707 RETVAL = adler32_combine(adler1, adler2, len2);
713 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
716 _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
730 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
731 level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
732 if ((s = InitStream() )) {
736 s->WindowBits = windowBits;
737 s->MemLevel = memLevel;
738 s->Strategy = strategy;
740 err = deflateInit2(&(s->stream), level,
741 method, windowBits, memLevel, strategy);
743 /* Check if a dictionary has been specified */
745 if (err == Z_OK && SvCUR(dictionary)) {
746 #ifdef UTF8_AVAILABLE
747 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
748 croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
750 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
752 s->dict_adler = s->stream.adler ;
760 PostInitStream(s, flags, bufsize, windowBits) ;
767 SV* obj = sv_setref_pv(sv_newmortal(),
768 "Compress::Raw::Zlib::deflateStream", (void*)s);
771 if (GIMME == G_ARRAY) {
772 SV * sv = sv_2mortal(newSViv(err)) ;
773 setDUALstatus(sv, err);
778 _inflateInit(flags, windowBits, bufsize, dictionary)
791 croak("inflateScanInit needs zlib 1.2.1 or better");
794 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
795 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
796 if ((s = InitStream() )) {
798 s->WindowBits = windowBits;
800 err = inflateInit2(&(s->stream), windowBits);
805 else if (SvCUR(dictionary)) {
806 /* Dictionary specified - take a copy for use in inflate */
807 s->dictionary = newSVsv(dictionary) ;
810 PostInitStream(s, flags, bufsize, windowBits) ;
814 s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
823 SV* obj = sv_setref_pv(sv_newmortal(),
825 ? "Compress::Raw::Zlib::inflateScanStream"
826 : "Compress::Raw::Zlib::inflateStream",
830 if (GIMME == G_ARRAY) {
831 SV * sv = sv_2mortal(newSViv(err)) ;
832 setDUALstatus(sv, err);
838 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
841 DispStream(s, message=NULL)
842 Compress::Raw::Zlib::deflateStream s
847 Compress::Raw::Zlib::deflateStream s
849 RETVAL = deflateReset(&(s->stream)) ;
850 if (RETVAL == Z_OK) {
851 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
857 deflate (s, buf, output)
858 Compress::Raw::Zlib::deflateStream s
861 uInt cur_length = NO_INIT
862 uInt increment = NO_INIT
863 uInt prefix = NO_INIT
865 uLong bufinc = NO_INIT
869 /* If the input buffer is a reference, dereference it */
870 buf = deRef(buf, "deflate") ;
872 /* initialise the input buffer */
873 #ifdef UTF8_AVAILABLE
874 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
875 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
877 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
878 s->stream.avail_in = SvCUR(buf) ;
880 if (s->flags & FLAG_CRC32)
881 s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
883 if (s->flags & FLAG_ADLER32)
884 s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
886 /* and retrieve the output buffer */
887 output = deRef_l(output, "deflate") ;
888 #ifdef UTF8_AVAILABLE
889 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
890 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
893 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
894 SvCUR_set(output, 0);
895 /* sv_setpvn(output, "", 0); */
897 prefix = cur_length = SvCUR(output) ;
898 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
899 increment = SvLEN(output) - cur_length;
900 s->stream.avail_out = increment;
902 /* Check for saved output from deflateParams */
903 if (s->deflateParams_out_valid) {
904 *(s->stream.next_out) = s->deflateParams_out_byte;
905 ++ s->stream.next_out;
906 -- s->stream.avail_out ;
907 s->deflateParams_out_valid = FALSE;
910 /* Check for saved output from deflateParams */
911 if (s->deflateParams_out_length) {
912 uLong plen = s->deflateParams_out_length ;
913 /* printf("Copy %d bytes saved data\n", plen);*/
914 if (s->stream.avail_out < plen) {
915 /*printf("GROW from %d to %d\n", s->stream.avail_out,
916 SvLEN(output) + plen - s->stream.avail_out); */
917 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
920 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
921 cur_length = cur_length + plen;
922 SvCUR_set(output, cur_length);
923 s->stream.next_out += plen ;
924 s->stream.avail_out = SvLEN(output) - cur_length ;
925 increment = s->stream.avail_out;
926 s->deflateParams_out_length = 0;
929 while (s->stream.avail_in != 0) {
931 if (s->stream.avail_out == 0) {
932 /* out of space in the output buffer so make it bigger */
933 Sv_Grow(output, SvLEN(output) + bufinc) ;
934 cur_length += increment ;
935 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
937 s->stream.avail_out = increment;
941 RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
946 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
947 s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
949 s->last_error = RETVAL ;
950 if (RETVAL == Z_OK) {
952 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
961 Compress::Raw::Zlib::deflateStream s
963 deflateEnd(&s->stream) ;
965 SvREFCNT_dec(s->dictionary) ;
967 if (s->deflateParams_out_buffer)
968 Safefree(s->deflateParams_out_buffer);
974 flush(s, output, f=Z_FINISH)
975 Compress::Raw::Zlib::deflateStream s
978 uInt cur_length = NO_INIT
979 uInt increment = NO_INIT
980 uInt prefix = NO_INIT
981 uLong bufinc = NO_INIT
985 s->stream.avail_in = 0; /* should be zero already anyway */
987 /* retrieve the output buffer */
988 output = deRef_l(output, "flush") ;
989 #ifdef UTF8_AVAILABLE
990 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
991 croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
993 if(! s->flags & FLAG_APPEND) {
994 SvCUR_set(output, 0);
995 /* sv_setpvn(output, "", 0); */
997 prefix = cur_length = SvCUR(output) ;
998 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
999 increment = SvLEN(output) - cur_length;
1000 s->stream.avail_out = increment;
1002 /* Check for saved output from deflateParams */
1003 if (s->deflateParams_out_valid) {
1004 *(s->stream.next_out) = s->deflateParams_out_byte;
1005 ++ s->stream.next_out;
1006 -- s->stream.avail_out ;
1007 s->deflateParams_out_valid = FALSE;
1010 /* Check for saved output from deflateParams */
1011 if (s->deflateParams_out_length) {
1012 uLong plen = s->deflateParams_out_length ;
1013 /* printf("Copy %d bytes saved data\n", plen); */
1014 if (s->stream.avail_out < plen) {
1015 /* printf("GROW from %d to %d\n", s->stream.avail_out,
1016 SvLEN(output) + plen - s->stream.avail_out); */
1017 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1020 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1021 cur_length = cur_length + plen;
1022 SvCUR_set(output, cur_length);
1023 s->stream.next_out += plen ;
1024 s->stream.avail_out = SvLEN(output) - cur_length ;
1025 increment = s->stream.avail_out;
1026 s->deflateParams_out_length = 0;
1031 if (s->stream.avail_out == 0) {
1032 /* consumed all the available output, so extend it */
1033 Sv_Grow(output, SvLEN(output) + bufinc) ;
1034 cur_length += increment ;
1035 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1036 increment = bufinc ;
1037 s->stream.avail_out = increment;
1040 RETVAL = deflate(&(s->stream), f);
1042 /* deflate has finished flushing only when it hasn't used up
1043 * all the available space in the output buffer:
1045 if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1049 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1050 s->last_error = RETVAL ;
1052 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1054 if (RETVAL == Z_OK) {
1056 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1064 _deflateParams(s, flags, level, strategy, bufsize)
1065 Compress::Raw::Zlib::deflateStream s
1071 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1072 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1076 s->Strategy = strategy ;
1078 s->bufsize = bufsize;
1080 /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1082 s->stream.avail_in = 0;
1083 s->stream.next_out = &(s->deflateParams_out_byte) ;
1084 s->stream.avail_out = 1;
1085 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1086 s->deflateParams_out_valid =
1087 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1088 /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1090 /* printf("Level %d Strategy %d, Prev Len %d\n",
1091 s->Level, s->Strategy, s->deflateParams_out_length); */
1092 s->stream.avail_in = 0;
1093 if (s->deflateParams_out_buffer == NULL)
1094 s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1095 s->stream.next_out = s->deflateParams_out_buffer ;
1096 s->stream.avail_out = deflateParams_BUFFER_SIZE;
1098 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1099 s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1100 /* printf("RETVAL %d, length out %d, avail %d\n",
1101 RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1109 Compress::Raw::Zlib::deflateStream s
1117 Compress::Raw::Zlib::deflateStream s
1119 RETVAL = s->Strategy ;
1126 Compress::Raw::Zlib::deflateStream s
1128 RETVAL = s->bufsize ;
1135 Compress::Raw::Zlib::deflateStream s
1137 RETVAL = s->last_error ;
1143 Compress::Raw::Zlib::deflateStream s
1151 Compress::Raw::Zlib::deflateStream s
1153 RETVAL = s->dict_adler ;
1159 Compress::Raw::Zlib::deflateStream s
1161 RETVAL = s->adler32 ;
1167 Compress::Raw::Zlib::deflateStream s
1169 RETVAL = s->compressedBytes;
1174 uncompressedBytes(s)
1175 Compress::Raw::Zlib::deflateStream s
1177 RETVAL = s->uncompressedBytes;
1183 Compress::Raw::Zlib::deflateStream s
1185 RETVAL = s->stream.total_in ;
1191 Compress::Raw::Zlib::deflateStream s
1193 RETVAL = s->stream.total_out ;
1199 Compress::Raw::Zlib::deflateStream s
1201 RETVAL = s->stream.msg;
1206 deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1207 Compress::Raw::Zlib::deflateStream s
1213 #ifndef AT_LEAST_ZLIB_1_2_2_3
1214 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1215 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1216 croak("deflateTune needs zlib 1.2.2.3 or better");
1218 RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1224 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1227 DispStream(s, message=NULL)
1228 Compress::Raw::Zlib::inflateStream s
1233 Compress::Raw::Zlib::inflateStream s
1235 RETVAL = inflateReset(&(s->stream)) ;
1236 if (RETVAL == Z_OK) {
1237 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1243 inflate (s, buf, output, eof=FALSE)
1244 Compress::Raw::Zlib::inflateStream s
1248 uInt cur_length = 0;
1249 uInt prefix_length = 0;
1251 STRLEN stmp = NO_INIT
1252 uLong bufinc = NO_INIT
1254 #ifdef UTF8_AVAILABLE
1255 bool out_utf8 = FALSE;
1258 bufinc = s->bufsize;
1259 /* If the buffer is a reference, dereference it */
1260 buf = deRef(buf, "inflate") ;
1262 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
1263 croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1264 #ifdef UTF8_AVAILABLE
1265 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1266 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1269 /* initialise the input buffer */
1270 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1271 s->stream.avail_in = SvCUR(buf) ;
1273 /* and retrieve the output buffer */
1274 output = deRef_l(output, "inflate") ;
1275 #ifdef UTF8_AVAILABLE
1276 if (DO_UTF8(output))
1278 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1279 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1281 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1282 SvCUR_set(output, 0);
1284 if (SvLEN(output)) {
1285 prefix_length = cur_length = SvCUR(output) ;
1286 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1287 increment = SvLEN(output) - cur_length - 1;
1288 s->stream.avail_out = increment;
1291 s->stream.avail_out = 0;
1293 s->bytesInflated = 0;
1297 if (s->stream.avail_out == 0 ) {
1298 /* out of space in the output buffer so make it bigger */
1299 Sv_Grow(output, SvLEN(output) + bufinc) ;
1300 cur_length += increment ;
1301 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1302 increment = bufinc ;
1303 s->stream.avail_out = increment;
1307 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1309 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1310 RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1313 if (RETVAL == Z_BUF_ERROR) {
1314 if (s->stream.avail_out == 0)
1316 if (s->stream.avail_in == 0) {
1322 if (RETVAL == Z_NEED_DICT && s->dictionary) {
1323 s->dict_adler = s->stream.adler ;
1324 RETVAL = inflateSetDictionary(&(s->stream),
1325 (const Bytef*)SvPVbyte_nolen(s->dictionary),
1326 SvCUR(s->dictionary));
1332 #ifdef NEED_DUMMY_BYTE_AT_END
1333 if (eof && RETVAL == Z_OK) {
1334 Bytef* nextIn = s->stream.next_in;
1335 uInt availIn = s->stream.avail_in;
1336 s->stream.next_in = (Bytef*) " ";
1337 s->stream.avail_in = 1;
1338 if (s->stream.avail_out == 0) {
1339 /* out of space in the output buffer so make it bigger */
1340 Sv_Grow(output, SvLEN(output) + bufinc) ;
1341 cur_length += increment ;
1342 s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1343 increment = bufinc ;
1344 s->stream.avail_out = increment;
1347 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1348 s->stream.next_in = nextIn ;
1349 s->stream.avail_in = availIn ;
1353 s->last_error = RETVAL ;
1354 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_DATA_ERROR) {
1357 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1358 s->uncompressedBytes += s->bytesInflated ;
1359 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1362 SvCUR_set(output, prefix_length + s->bytesInflated) ;
1363 *SvEND(output) = '\0';
1364 #ifdef UTF8_AVAILABLE
1366 sv_utf8_upgrade(output);
1370 if (s->flags & FLAG_CRC32 )
1371 s->crc32 = crc32(s->crc32,
1372 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1373 SvCUR(output)-prefix_length) ;
1375 if (s->flags & FLAG_ADLER32)
1376 s->adler32 = adler32(s->adler32,
1377 (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1378 SvCUR(output)-prefix_length) ;
1380 /* fix the input buffer */
1381 if (s->flags & FLAG_CONSUME_INPUT) {
1382 in = s->stream.avail_in ;
1383 SvCUR_set(buf, in) ;
1385 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1395 Compress::Raw::Zlib::inflateStream s
1397 RETVAL = s->bytesInflated;
1403 Compress::Raw::Zlib::inflateStream s
1405 RETVAL = s->compressedBytes;
1410 uncompressedBytes(s)
1411 Compress::Raw::Zlib::inflateStream s
1413 RETVAL = s->uncompressedBytes;
1419 inflateSync (s, buf)
1420 Compress::Raw::Zlib::inflateStream s
1424 /* If the buffer is a reference, dereference it */
1425 buf = deRef(buf, "inflateSync") ;
1426 #ifdef UTF8_AVAILABLE
1427 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1428 croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1431 /* initialise the input buffer */
1432 s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
1433 s->stream.avail_in = SvCUR(buf) ;
1435 /* inflateSync doesn't create any output */
1436 s->stream.next_out = (Bytef*) NULL;
1437 s->stream.avail_out = 0;
1439 RETVAL = inflateSync(&(s->stream));
1440 s->last_error = RETVAL ;
1442 /* fix the input buffer */
1444 unsigned in = s->stream.avail_in ;
1445 SvCUR_set(buf, in) ;
1447 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1456 Compress::Raw::Zlib::inflateStream s
1458 inflateEnd(&s->stream) ;
1460 SvREFCNT_dec(s->dictionary) ;
1462 if (s->deflateParams_out_buffer)
1463 Safefree(s->deflateParams_out_buffer);
1467 Safefree(s->window);
1474 Compress::Raw::Zlib::inflateStream s
1476 RETVAL = s->last_error ;
1482 Compress::Raw::Zlib::inflateStream s
1490 Compress::Raw::Zlib::inflateStream s
1492 RETVAL = s->dict_adler ;
1498 Compress::Raw::Zlib::inflateStream s
1500 RETVAL = s->stream.total_in ;
1506 Compress::Raw::Zlib::inflateStream s
1508 RETVAL = s->adler32 ;
1514 Compress::Raw::Zlib::inflateStream s
1516 RETVAL = s->stream.total_out ;
1522 Compress::Raw::Zlib::inflateStream s
1524 RETVAL = s->stream.msg;
1531 Compress::Raw::Zlib::inflateStream s
1533 RETVAL = s->bufsize ;
1539 Compress::Raw::Zlib::inflateStream s
1542 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1544 s->flags |= FLAG_APPEND ;
1546 s->flags &= ~FLAG_APPEND ;
1550 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
1554 Compress::Raw::Zlib::inflateScanStream s
1556 inflateEnd(&s->stream) ;
1558 SvREFCNT_dec(s->dictionary) ;
1560 if (s->deflateParams_out_buffer)
1561 Safefree(s->deflateParams_out_buffer);
1565 Safefree(s->window);
1570 DispStream(s, message=NULL)
1571 Compress::Raw::Zlib::inflateScanStream s
1576 Compress::Raw::Zlib::inflateScanStream s
1578 RETVAL = inflateReset(&(s->stream)) ;
1579 if (RETVAL == Z_OK) {
1580 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1586 scan(s, buf, out=NULL, eof=FALSE)
1587 Compress::Raw::Zlib::inflateScanStream s
1591 bool eof_mode = FALSE;
1592 int start_len = NO_INIT
1593 STRLEN stmp = NO_INIT
1595 /* If the input buffer is a reference, dereference it */
1596 #ifndef MAGIC_APPEND
1598 croak("scan needs zlib 1.2.1 or better");
1600 buf = deRef(buf, "inflateScan") ;
1601 #ifdef UTF8_AVAILABLE
1602 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1603 croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
1605 /* initialise the input buffer */
1606 s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1607 s->stream.avail_in = SvCUR(buf) ;
1608 start_len = s->stream.avail_in ;
1609 s->bytesInflated = 0 ;
1612 if (s->stream.avail_in == 0) {
1617 /* set up output to next available section of sliding window */
1618 s->stream.avail_out = WINDOW_SIZE - s->window_have;
1619 s->stream.next_out = s->window + s->window_have;
1621 /* DispStream(s, "before inflate\n"); */
1623 /* inflate and check for errors */
1624 RETVAL = inflate(&(s->stream), Z_BLOCK);
1626 if (start_len > 1 && ! eof_mode)
1627 s->window_lastByte = *(s->stream.next_in - 1 ) ;
1629 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1630 RETVAL == Z_DATA_ERROR )
1633 if (s->flags & FLAG_CRC32 )
1634 s->crc32 = crc32(s->crc32, s->window + s->window_have,
1635 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1637 if (s->flags & FLAG_ADLER32)
1638 s->adler32 = adler32(s->adler32, s->window + s->window_have,
1639 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1641 s->uncompressedBytes =
1642 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1644 if (s->stream.avail_out)
1645 s->window_have = WINDOW_SIZE - s->stream.avail_out;
1651 /* process end of block */
1652 if (s->stream.data_type & 128) {
1653 if (s->stream.data_type & 64) {
1654 s->window_left = s->stream.data_type & 0x1f;
1657 s->window_lastbit = s->stream.data_type & 0x1f;
1658 s->lastBlockOffset = s->stream.total_in;
1662 } while (RETVAL != Z_STREAM_END);
1664 s->last_error = RETVAL ;
1665 s->window_lastoff = s->stream.total_in ;
1666 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1668 if (RETVAL == Z_STREAM_END)
1670 s->matchedEndBlock = 1 ;
1672 /* save the location of the end of the compressed data */
1673 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1674 s->window_endOffset = s->stream.total_in ;
1677 -- s->window_endOffset ;
1680 /* if window wrapped, build dictionary from window by rotating */
1681 if (s->window_full) {
1682 rotate(s->window, WINDOW_SIZE, s->window_have);
1683 s->window_have = WINDOW_SIZE;
1686 /* if (s->flags & FLAG_CONSUME_INPUT) { */
1688 unsigned in = s->stream.avail_in ;
1689 SvCUR_set(buf, in) ;
1691 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1703 Compress::Raw::Zlib::inflateScanStream s
1705 #ifndef MAGIC_APPEND
1706 croak("getEndOffset needs zlib 1.2.1 or better");
1708 RETVAL = s->window_endOffset;
1715 Compress::Raw::Zlib::inflateScanStream s
1717 #ifndef MAGIC_APPEND
1718 croak("inflateCount needs zlib 1.2.1 or better");
1720 RETVAL = s->bytesInflated;
1727 Compress::Raw::Zlib::inflateScanStream s
1729 RETVAL = s->compressedBytes;
1734 uncompressedBytes(s)
1735 Compress::Raw::Zlib::inflateScanStream s
1737 RETVAL = s->uncompressedBytes;
1743 getLastBlockOffset(s)
1744 Compress::Raw::Zlib::inflateScanStream s
1746 #ifndef MAGIC_APPEND
1747 croak("getLastBlockOffset needs zlib 1.2.1 or better");
1749 RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
1755 getLastBufferOffset(s)
1756 Compress::Raw::Zlib::inflateScanStream s
1758 #ifndef MAGIC_APPEND
1759 croak("getLastBufferOffset needs zlib 1.2.1 or better");
1761 RETVAL = s->window_lastoff;
1767 resetLastBlockByte(s, byte)
1768 Compress::Raw::Zlib::inflateScanStream s
1771 #ifndef MAGIC_APPEND
1772 croak("resetLastBlockByte needs zlib 1.2.1 or better");
1775 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
1780 _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1781 Compress::Raw::Zlib::inflateScanStream inf_s
1791 #ifndef MAGIC_APPEND
1795 windowBits = windowBits;
1796 memLevel = memLevel;
1797 strategy = strategy;
1799 croak("_createDeflateStream needs zlib 1.2.1 or better");
1805 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1806 level, method, windowBits, memLevel, strategy, bufsize) ;
1807 if ((s = InitStream() )) {
1811 s->WindowBits = windowBits;
1812 s->MemLevel = memLevel;
1813 s->Strategy = strategy;
1815 err = deflateInit2(&(s->stream), level,
1816 method, windowBits, memLevel, strategy);
1819 err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1820 s->dict_adler = s->stream.adler ;
1828 PostInitStream(s, flags, bufsize, windowBits) ;
1829 s->crc32 = inf_s->crc32;
1830 s->adler32 = inf_s->adler32;
1831 s->stream.adler = inf_s->stream.adler ;
1832 /* s->stream.total_out = inf_s->bytesInflated ; */
1833 s->stream.total_in = inf_s->stream.total_out ;
1834 if (inf_s->window_left) {
1835 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1836 deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1843 XPUSHs(sv_setref_pv(sv_newmortal(),
1844 "Compress::Raw::Zlib::deflateStream", (void*)s));
1845 if (GIMME == G_ARRAY) {
1846 SV * sv = sv_2mortal(newSViv(err)) ;
1847 setDUALstatus(sv, err);
1855 Compress::Raw::Zlib::inflateScanStream s
1857 RETVAL = s->last_error ;
1863 Compress::Raw::Zlib::inflateScanStream s
1872 Compress::Raw::Zlib::inflateScanStream s
1874 RETVAL = s->adler32 ;