File Coverage

Zlib.xs
Criterion Covered Total %
statement 216 441 49.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 216 441 49.0


line stmt bran cond sub pod time code
1             /* Filename: Zlib.xs
2             * Author : Paul Marquess, <pmqs@cpan.org>
3             * Created : 22nd January 1996
4             * Version : 2.000
5             *
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.
9              *
10              */
11            
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
14              * from each.
15              */
16            
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
20              */
21            
22             /* gzappend -- command to append to a gzip file
23              
24               Copyright (C) 2003 Mark Adler, all rights reserved
25               version 1.1, 4 Nov 2003
26             */
27            
28            
29            
30             #include "EXTERN.h"
31             #include "perl.h"
32             #include "XSUB.h"
33            
34             #include <zlib.h>
35            
36             /* zlib prior to 1.06 doesn't know about z_off_t */
37             #ifndef z_off_t
38             # define z_off_t long
39             #endif
40            
41             #if ! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200
42             # define NEED_DUMMY_BYTE_AT_END
43             #endif
44            
45             #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210
46             # define MAGIC_APPEND
47             #endif
48            
49             #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
50             # define AT_LEAST_ZLIB_1_2_2_1
51             #endif
52            
53             #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223
54             # define AT_LEAST_ZLIB_1_2_2_3
55             #endif
56            
57             #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
58             # define AT_LEAST_ZLIB_1_2_3
59             #endif
60            
61             #define NEED_sv_2pvbyte
62             #define NEED_sv_2pv_nolen
63             #include "ppport.h"
64            
65             #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
66            
67             # ifdef SvPVbyte_force
68             # undef SvPVbyte_force
69             # endif
70            
71             # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
72            
73             #endif
74            
75             #ifndef SvPVbyte_nolen
76             # define SvPVbyte_nolen SvPV_nolen
77             #endif
78            
79            
80            
81             #if 0
82             # ifndef SvPVbyte_nolen
83             # define SvPVbyte_nolen SvPV_nolen
84             # endif
85            
86             # ifndef SvPVbyte_force
87             # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
88             # endif
89             #endif
90            
91             #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
92             # define UTF8_AVAILABLE
93             #endif
94            
95             typedef int DualType ;
96             typedef int int_undef ;
97            
98             typedef struct di_stream {
99             int flags ;
100             #define FLAG_APPEND 1
101             #define FLAG_CRC32 2
102             #define FLAG_ADLER32 4
103             #define FLAG_CONSUME_INPUT 8
104             uLong crc32 ;
105             uLong adler32 ;
106             z_stream stream;
107             uLong bufsize;
108             SV * dictionary ;
109             uLong dict_adler ;
110             int last_error ;
111             bool zip_mode ;
112             #define SETP_BYTE
113             #ifdef SETP_BYTE
114             bool deflateParams_out_valid ;
115             Bytef deflateParams_out_byte;
116             #else
117             #define deflateParams_BUFFER_SIZE 0x4000
118             uLong deflateParams_out_length;
119             Bytef* deflateParams_out_buffer;
120             #endif
121             int Level;
122             int Method;
123             int WindowBits;
124             int MemLevel;
125             int Strategy;
126             uLong bytesInflated ;
127             uLong compressedBytes ;
128             uLong uncompressedBytes ;
129             #ifdef MAGIC_APPEND
130            
131             #define WINDOW_SIZE 32768U
132            
133             bool matchedEndBlock;
134             Bytef* window ;
135             int window_lastbit, window_left, window_full;
136             unsigned window_have;
137             off_t window_lastoff, window_end;
138             off_t window_endOffset;
139            
140             uLong lastBlockOffset ;
141             unsigned char window_lastByte ;
142            
143            
144             #endif
145             } di_stream;
146            
147             typedef di_stream * deflateStream ;
148             typedef di_stream * Compress__Raw__Zlib__deflateStream ;
149             typedef di_stream * inflateStream ;
150             typedef di_stream * Compress__Raw__Zlib__inflateStream ;
151             typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;
152            
153             #define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
154             Zero(to,1,typ))
155            
156             /* Figure out the Operating System */
157             #ifdef MSDOS
158             # define OS_CODE 0x00
159             #endif
160            
161             #if defined(AMIGA) || defined(AMIGAOS)
162             # define OS_CODE 0x01
163             #endif
164            
165             #if defined(VAXC) || defined(VMS)
166             # define OS_CODE 0x02
167             #endif
168            
169             #if 0 /* VM/CMS */
170             # define OS_CODE 0x04
171             #endif
172            
173             #if defined(ATARI) || defined(atarist)
174             # define OS_CODE 0x05
175             #endif
176            
177             #ifdef OS2
178             # define OS_CODE 0x06
179             #endif
180            
181             #if defined(MACOS) || defined(TARGET_OS_MAC)
182             # define OS_CODE 0x07
183             #endif
184            
185             #if 0 /* Z-System */
186             # define OS_CODE 0x08
187             #endif
188            
189             #if 0 /* CP/M */
190             # define OS_CODE 0x09
191             #endif
192            
193             #ifdef TOPS20
194             # define OS_CODE 0x0a
195             #endif
196            
197             #ifdef WIN32 /* Window 95 & Windows NT */
198             # define OS_CODE 0x0b
199             #endif
200            
201             #if 0 /* QDOS */
202             # define OS_CODE 0x0c
203             #endif
204            
205             #if 0 /* Acorn RISCOS */
206             # define OS_CODE 0x0d
207             #endif
208            
209             #if 0 /* ??? */
210             # define OS_CODE 0x0e
211             #endif
212            
213             #ifdef __50SERIES /* Prime/PRIMOS */
214             # define OS_CODE 0x0F
215             #endif
216            
217             /* Default to UNIX */
218             #ifndef OS_CODE
219             # define OS_CODE 0x03 /* assume Unix */
220             #endif
221            
222             #ifndef GZIP_OS_CODE
223             # define GZIP_OS_CODE OS_CODE
224             #endif
225            
226             #define adlerInitial adler32(0L, Z_NULL, 0)
227             #define crcInitial crc32(0L, Z_NULL, 0)
228            
229            
230             static const char * const my_z_errmsg[] = {
231             "need dictionary", /* Z_NEED_DICT 2 */
232             "stream end", /* Z_STREAM_END 1 */
233             "", /* Z_OK 0 */
234             "file error", /* Z_ERRNO (-1) */
235             "stream error", /* Z_STREAM_ERROR (-2) */
236             "data error", /* Z_DATA_ERROR (-3) */
237             "insufficient memory", /* Z_MEM_ERROR (-4) */
238             "buffer error", /* Z_BUF_ERROR (-5) */
239             "incompatible version",/* Z_VERSION_ERROR(-6) */
240             ""};
241            
242             #define setDUALstatus(var, err) \
243             sv_setnv(var, (double)err) ; \
244             sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
245             SvNOK_on(var);
246            
247            
248             #if defined(__SYMBIAN32__)
249             # define NO_WRITEABLE_DATA
250             #endif
251            
252             #define TRACE_DEFAULT 0
253            
254             #ifdef NO_WRITEABLE_DATA
255             # define trace TRACE_DEFAULT
256             #else
257             static int trace = TRACE_DEFAULT ;
258             #endif
259            
260             /* Dodge PerlIO hiding of these functions. */
261             #undef printf
262            
263             static char *
264             #ifdef CAN_PROTOTYPE
265             GetErrorString(int error_no)
266             #else
267             GetErrorString(error_no)
268             int error_no ;
269             #endif
270 201           {
271             dTHX;
272             char * errstr ;
273            
274 201           if (error_no == Z_ERRNO) {
275 0           errstr = Strerror(errno) ;
276             }
277             else
278             /* errstr = gzerror(fil, &error_no) ; */
279 201           errstr = (char*) my_z_errmsg[2 - error_no];
280            
281             return errstr ;
282             }
283            
284            
285             #ifdef MAGIC_APPEND
286            
287             /*
288                The following two functions are taken almost directly from
289                examples/gzappend.c. Only cosmetic changes have been made to conform to
290                the coding style of the rest of the code in this file.
291             */
292            
293            
294             /* return the greatest common divisor of a and b using Euclid's algorithm,
295                modified to be fast when one argument much greater than the other, and
296                coded to avoid unnecessary swapping */
297             static unsigned
298             #ifdef CAN_PROTOTYPE
299             gcd(unsigned a, unsigned b)
300             #else
301             gcd(a, b)
302             unsigned a;
303             unsigned b;
304             #endif
305             {
306             unsigned c;
307            
308 0           while (a && b)
309 0           if (a > b) {
310             c = b;
311 0           while (a - c >= c)
312 0           c <<= 1;
313             a -= c;
314             }
315             else {
316             c = a;
317 0           while (b - c >= c)
318 0           c <<= 1;
319             b -= c;
320             }
321 0           return a + b;
322             }
323            
324             /* rotate list[0..len-1] left by rot positions, in place */
325             static void
326             #ifdef CAN_PROTOTYPE
327             rotate(unsigned char *list, unsigned len, unsigned rot)
328             #else
329             rotate(list, len, rot)
330             unsigned char *list;
331             unsigned len ;
332             unsigned rot;
333             #endif
334             {
335             unsigned char tmp;
336             unsigned cycles;
337             unsigned char *start, *last, *to, *from;
338            
339             /* normalize rot and handle degenerate cases */
340             if (len < 2) return;
341 0           if (rot >= len) rot %= len;
342 0           if (rot == 0) return;
343            
344             /* pointer to last entry in list */
345 0           last = list + (len - 1);
346            
347             /* do simple left shift by one */
348 0           if (rot == 1) {
349 0           tmp = *list;
350 0           memcpy(list, list + 1, len - 1);
351 0           *last = tmp;
352             return;
353             }
354            
355             /* do simple right shift by one */
356 0           if (rot == len - 1) {
357 0           tmp = *last;
358 0           memmove(list + 1, list, len - 1);
359 0           *list = tmp;
360             return;
361             }
362            
363             /* otherwise do rotate as a set of cycles in place */
364             cycles = gcd(len, rot); /* number of cycles */
365             do {
366             start = from = list + cycles; /* start index is arbitrary */
367 0           tmp = *from; /* save entry to be overwritten */
368             for (;;) {
369             to = from; /* next step in cycle */
370 0           from += rot; /* go right rot positions */
371 0           if (from > last) from -= len; /* (pointer better not wrap) */
372 0           if (from == start) break; /* all but one shifted */
373 0           *to = *from; /* shift left */
374 0           }
375 0           *to = tmp; /* complete the circle */
376 0           } while (--cycles);
377             }
378            
379             #endif /* MAGIC_APPEND */
380            
381             static void
382             #ifdef CAN_PROTOTYPE
383             DispHex(void * ptr, int length)
384             #else
385             DispHex(ptr, length)
386             void * ptr;
387             int length;
388             #endif
389 0           {
390 0           char * p = (char*)ptr;
391             int i;
392 0           for (i = 0; i < length; ++i) {
393 0           printf(" %02x", 0xFF & *(p+i));
394             }
395             }
396            
397            
398             static void
399             #ifdef CAN_PROTOTYPE
400             DispStream(di_stream * s, char * message)
401             #else
402             DispStream(s, message)
403             di_stream * s;
404             char * message;
405             #endif
406 0           {
407            
408             #if 0
409             if (! trace)
410             return ;
411             #endif
412            
413             #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
414            
415 0           printf("DispStream 0x%p", s) ;
416 0           if (message)
417 0           printf("- %s \n", message) ;
418 0           printf("\n") ;
419            
420 0           if (!s) {
421 0           printf(" stream pointer is NULL\n");
422             }
423             else {
424 0           printf(" stream 0x%p\n", &(s->stream));
425 0           printf(" zalloc 0x%p\n", s->stream.zalloc);
426 0           printf(" zfree 0x%p\n", s->stream.zfree);
427 0           printf(" opaque 0x%p\n", s->stream.opaque);
428 0           if (s->stream.msg)
429 0           printf(" msg %s\n", s->stream.msg);
430             else
431 0           printf(" msg \n");
432 0           printf(" next_in 0x%p", s->stream.next_in);
433 0           if (s->stream.next_in){
434 0           printf(" =>");
435 0           DispHex(s->stream.next_in, 4);
436             }
437 0           printf("\n");
438            
439 0           printf(" next_out 0x%p", s->stream.next_out);
440 0           if (s->stream.next_out){
441 0           printf(" =>");
442 0           DispHex(s->stream.next_out, 4);
443             }
444 0           printf("\n");
445            
446 0           printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
447 0           printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
448 0           printf(" total_in %ld\n", s->stream.total_in);
449 0           printf(" total_out %ld\n", s->stream.total_out);
450 0           printf(" adler %ld\n", s->stream.adler );
451 0           printf(" bufsize %ld\n", s->bufsize);
452 0           printf(" dictionary 0x%p\n", s->dictionary);
453 0           printf(" dict_adler 0x%ld\n",s->dict_adler);
454 0           printf(" zip_mode %d\n", s->zip_mode);
455 0           printf(" crc32 0x%x\n", (unsigned)s->crc32);
456 0           printf(" adler32 0x%x\n", (unsigned)s->adler32);
457 0           printf(" flags 0x%x\n", s->flags);
458 0           printf(" APPEND %s\n", EnDis(FLAG_APPEND));
459 0           printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
460 0           printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
461 0           printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
462            
463             #ifdef MAGIC_APPEND
464 0           printf(" window 0x%p\n", s->window);
465             #endif
466 0           printf("\n");
467            
468             }
469             }
470            
471             static di_stream *
472             #ifdef CAN_PROTOTYPE
473             InitStream(void)
474             #else
475             InitStream()
476             #endif
477 67           {
478             di_stream *s ;
479            
480 67           ZMALLOC(s, di_stream) ;
481            
482             return s ;
483            
484             }
485            
486             static void
487             #ifdef CAN_PROTOTYPE
488             PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
489             #else
490             PostInitStream(s, flags, bufsize, windowBits)
491             di_stream *s ;
492             int flags ;
493             int bufsize ;
494             int windowBits ;
495             #endif
496 67           {
497 67           s->bufsize = bufsize ;
498 67           s->compressedBytes =
499             s->uncompressedBytes =
500             s->last_error = 0 ;
501 67           s->flags = flags ;
502 67           s->zip_mode = (windowBits < 0) ;
503 67           if (flags & FLAG_CRC32)
504 0           s->crc32 = crcInitial ;
505 67           if (flags & FLAG_ADLER32)
506 0           s->adler32 = adlerInitial ;
507             }
508            
509            
510             static SV*
511             #ifdef CAN_PROTOTYPE
512             deRef(SV * sv, char * string)
513             #else
514             deRef(sv, string)
515             SV * sv ;
516             char * string;
517             #endif
518 204064           {
519             dTHX;
520 204064           SvGETMAGIC(sv);
521            
522 204064           if (SvROK(sv)) {
523 0           sv = SvRV(sv) ;
524 0           SvGETMAGIC(sv);
525 0           switch(SvTYPE(sv)) {
526             case SVt_PVAV:
527             case SVt_PVHV:
528             case SVt_PVCV:
529 0           croak("%s: buffer parameter is not a SCALAR reference", string);
530             }
531 0           if (SvROK(sv))
532 0           croak("%s: buffer parameter is a reference to a reference", string) ;
533             }
534            
535 204064           if (!SvOK(sv)) {
536 0           sv = newSVpv("", 0);
537             }
538            
539             return sv ;
540             }
541            
542             static SV*
543             #ifdef CAN_PROTOTYPE
544             deRef_l(SV * sv, char * string)
545             #else
546             deRef_l(sv, string)
547             SV * sv ;
548             char * string ;
549             #endif
550 203926           {
551             dTHX;
552             bool wipe = 0 ;
553            
554 203926           SvGETMAGIC(sv);
555 203926           wipe = ! SvOK(sv) ;
556            
557 203926           if (SvROK(sv)) {
558 0           sv = SvRV(sv) ;
559 0           SvGETMAGIC(sv);
560 0           wipe = ! SvOK(sv) ;
561            
562 0           switch(SvTYPE(sv)) {
563             case SVt_PVAV:
564             case SVt_PVHV:
565             case SVt_PVCV:
566 0           croak("%s: buffer parameter is not a SCALAR reference", string);
567             }
568 0           if (SvROK(sv))
569 0           croak("%s: buffer parameter is a reference to a reference", string) ;
570             }
571            
572 203926           if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
573 0           croak("%s: buffer parameter is read-only", string);
574            
575 203926           SvUPGRADE(sv, SVt_PV);
576            
577 203926           if (wipe)
578 40           SvCUR_set(sv, 0);
579            
580 203926           SvOOK_off(sv);
581 203926           SvPOK_only(sv);
582            
583             return sv ;
584             }
585            
586            
587             #include "constants.h"
588            
589             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
590            
591             REQUIRE: 1.924
592             PROTOTYPES: DISABLE
593            
594             INCLUDE: constants.xs
595            
596             BOOT:
597             /* Check this version of zlib is == 1 */
598 4           if (zlibVersion()[0] != '1')
599 0           croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
600            
601             {
602             /* Create the $os_code scalar */
603 4           SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
604 4           sv_setiv(os_code_sv, GZIP_OS_CODE) ;
605             }
606            
607            
608             #define Zip_zlib_version() (char*)zlib_version
609             char*
610             Zip_zlib_version()
611            
612             unsigned
613             ZLIB_VERNUM()
614             CODE:
615             #ifdef ZLIB_VERNUM
616             RETVAL = ZLIB_VERNUM ;
617             #else
618             /* 1.1.4 => 0x1140 */
619             RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
620             RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
621             RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
622             #endif
623             OUTPUT:
624             RETVAL
625            
626             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
627            
628             #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
629            
630             uLong
631             Zip_adler32(buf, adler=adlerInitial)
632             uLong adler = NO_INIT
633             STRLEN len = NO_INIT
634             Bytef * buf = NO_INIT
635             SV * sv = ST(0) ;
636             INIT:
637             /* If the buffer is a reference, dereference it */
638 0           sv = deRef(sv, "adler32") ;
639             #ifdef UTF8_AVAILABLE
640 0           if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
641 0           croak("Wide character in Compress::Raw::Zlib::adler32");
642             #endif
643 0           buf = (Byte*)SvPVbyte(sv, len) ;
644            
645 0           if (items < 2)
646 0           adler = adlerInitial;
647 0           else if (SvOK(ST(1)))
648 0           adler = SvUV(ST(1)) ;
649             else
650 0           adler = adlerInitial;
651            
652             #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
653            
654             uLong
655             Zip_crc32(buf, crc=crcInitial)
656             uLong crc = NO_INIT
657             STRLEN len = NO_INIT
658             Bytef * buf = NO_INIT
659             SV * sv = ST(0) ;
660             INIT:
661             /* If the buffer is a reference, dereference it */
662 0           sv = deRef(sv, "crc32") ;
663             #ifdef UTF8_AVAILABLE
664 0           if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
665 0           croak("Wide character in Compress::Raw::Zlib::crc32");
666             #endif
667 0           buf = (Byte*)SvPVbyte(sv, len) ;
668            
669 0           if (items < 2)
670 0           crc = crcInitial;
671 0           else if (SvOK(ST(1)))
672 0           crc = SvUV(ST(1)) ;
673             else
674 0           crc = crcInitial;
675            
676            
677             uLong
678             crc32_combine(crc1, crc2, len2)
679             uLong crc1
680             uLong crc2
681             z_off_t len2
682             CODE:
683             #ifndef AT_LEAST_ZLIB_1_2_2_1
684             crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
685             croak("crc32_combine needs zlib 1.2.3 or better");
686             #else
687 0           RETVAL = crc32_combine(crc1, crc2, len2);
688             #endif
689             OUTPUT:
690             RETVAL
691            
692            
693             uLong
694             adler32_combine(adler1, adler2, len2)
695             uLong adler1
696             uLong adler2
697             z_off_t len2
698             CODE:
699             #ifndef AT_LEAST_ZLIB_1_2_2_1
700             adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
701             croak("adler32_combine needs zlib 1.2.3 or better");
702             #else
703 0           RETVAL = adler32_combine(adler1, adler2, len2);
704             #endif
705             OUTPUT:
706             RETVAL
707            
708            
709             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
710            
711             void
712             _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
713             int flags
714             int level
715             int method
716             int windowBits
717             int memLevel
718             int strategy
719             uLong bufsize
720             SV* dictionary
721             PPCODE:
722             int err ;
723             deflateStream s ;
724            
725 31           if (trace)
726 0           warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld\n",
727             level, method, windowBits, memLevel, strategy, bufsize) ;
728 31           if ((s = InitStream() )) {
729            
730 31           s->Level = level;
731 31           s->Method = method;
732 31           s->WindowBits = windowBits;
733 31           s->MemLevel = memLevel;
734 31           s->Strategy = strategy;
735            
736 31           err = deflateInit2(&(s->stream), level,
737             method, windowBits, memLevel, strategy);
738            
739             /* Check if a dictionary has been specified */
740            
741 31           if (err == Z_OK && SvCUR(dictionary)) {
742             #ifdef UTF8_AVAILABLE
743 1           if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
744 0           croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
745             #endif
746 1           err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary),
747             SvCUR(dictionary)) ;
748 1           s->dict_adler = s->stream.adler ;
749             }
750            
751 1           if (err != Z_OK) {
752 0           Safefree(s) ;
753             s = NULL ;
754             }
755             else
756 31           PostInitStream(s, flags, bufsize, windowBits) ;
757            
758             }
759             else
760             err = Z_MEM_ERROR ;
761            
762 31           XPUSHs(sv_setref_pv(sv_newmortal(),
763             "Compress::Raw::Zlib::deflateStream", (void*)s));
764 31           if (GIMME == G_ARRAY) {
765 26           SV * sv = sv_2mortal(newSViv(err)) ;
766 26           setDUALstatus(sv, err);
767 26           XPUSHs(sv) ;
768             }
769            
770             void
771             _inflateInit(flags, windowBits, bufsize, dictionary)
772             int flags
773             int windowBits
774             uLong bufsize
775             SV * dictionary
776             ALIAS:
777             _inflateScanInit = 1
778             PPCODE:
779            
780             int err = Z_OK ;
781             inflateStream s ;
782             #ifndef MAGIC_APPEND
783             if (ix == 1)
784             croak("inflateScanInit needs zlib 1.2.1 or better");
785             #endif
786 36           if (trace)
787 0           warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
788             windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
789 36           if ((s = InitStream() )) {
790            
791 36           s->WindowBits = windowBits;
792            
793 36           err = inflateInit2(&(s->stream), windowBits);
794 36           if (err != Z_OK) {
795 0           Safefree(s) ;
796             s = NULL ;
797             }
798 36           else if (SvCUR(dictionary)) {
799             /* Dictionary specified - take a copy for use in inflate */
800 1           s->dictionary = newSVsv(dictionary) ;
801             }
802             if (s) {
803 36           PostInitStream(s, flags, bufsize, windowBits) ;
804             #ifdef MAGIC_APPEND
805 36           if (ix == 1)
806             {
807 1           s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
808             }
809             #endif
810             }
811             }
812             else
813             err = Z_MEM_ERROR ;
814            
815 36           XPUSHs(sv_setref_pv(sv_newmortal(),
816             ix == 1
817             ? "Compress::Raw::Zlib::inflateScanStream"
818             : "Compress::Raw::Zlib::inflateStream",
819             (void*)s));
820 36           if (GIMME == G_ARRAY) {
821 28           SV * sv = sv_2mortal(newSViv(err)) ;
822 28           setDUALstatus(sv, err);
823 28           XPUSHs(sv) ;
824             }
825            
826            
827            
828             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
829            
830             void
831             DispStream(s, message=NULL)
832             Compress::Raw::Zlib::deflateStream s
833             char * message
834            
835             DualType
836             deflateReset(s)
837             Compress::Raw::Zlib::deflateStream s
838             CODE:
839 0           RETVAL = deflateReset(&(s->stream)) ;
840 0           if (RETVAL == Z_OK) {
841 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
842             }
843             OUTPUT:
844             RETVAL
845            
846             DualType
847             deflate (s, buf, output)
848             Compress::Raw::Zlib::deflateStream s
849             SV * buf
850             SV * output
851             uInt cur_length = NO_INIT
852             uInt increment = NO_INIT
853             uInt prefix = NO_INIT
854             int RETVAL = 0;
855             uLong bufinc = NO_INIT
856             CODE:
857 152954           bufinc = s->bufsize;
858            
859             /* If the input buffer is a reference, dereference it */
860 152954           buf = deRef(buf, "deflate") ;
861            
862             /* initialise the input buffer */
863             #ifdef UTF8_AVAILABLE
864 152954           if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
865 0           croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
866             #endif
867 152954           s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
868 152954           s->stream.avail_in = SvCUR(buf) ;
869            
870 152954           if (s->flags & FLAG_CRC32)
871 0           s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
872            
873 152954           if (s->flags & FLAG_ADLER32)
874 0           s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
875            
876             /* and retrieve the output buffer */
877 152954           output = deRef_l(output, "deflate") ;
878             #ifdef UTF8_AVAILABLE
879 152954           if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
880 0           croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
881             #endif
882            
883 152954           if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
884 76           SvCUR_set(output, 0);
885             /* sv_setpvn(output, "", 0); */
886             }
887 152954           prefix = cur_length = SvCUR(output) ;
888 152954           s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
889 152954           increment = SvLEN(output) - cur_length;
890 152954           s->stream.avail_out = increment;
891             #ifdef SETP_BYTE
892             /* Check for saved output from deflateParams */
893 152954           if (s->deflateParams_out_valid) {
894 2           *(s->stream.next_out) = s->deflateParams_out_byte;
895 2           ++ s->stream.next_out;
896 2           -- s->stream.avail_out ;
897 2           s->deflateParams_out_valid = FALSE;
898             }
899             #else
900             /* Check for saved output from deflateParams */
901             if (s->deflateParams_out_length) {
902             uLong plen = s->deflateParams_out_length ;
903             /* printf("Copy %d bytes saved data\n", plen);*/
904             if (s->stream.avail_out < plen) {
905             /*printf("GROW from %d to %d\n", s->stream.avail_out,
906             SvLEN(output) + plen - s->stream.avail_out); */
907             Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
908             }
909            
910             Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
911             cur_length = cur_length + plen;
912             SvCUR_set(output, cur_length);
913             s->stream.next_out += plen ;
914             s->stream.avail_out = SvLEN(output) - cur_length ;
915             increment = s->stream.avail_out;
916             s->deflateParams_out_length = 0;
917             }
918             #endif
919 305912           while (s->stream.avail_in != 0) {
920            
921 152958           if (s->stream.avail_out == 0) {
922             /* out of space in the output buffer so make it bigger */
923 13           Sv_Grow(output, SvLEN(output) + bufinc) ;
924 13           cur_length += increment ;
925 13           s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
926             increment = bufinc ;
927 13           s->stream.avail_out = increment;
928 13           bufinc *= 2 ;
929             }
930            
931 152958           RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
932 152958           if (RETVAL != Z_OK)
933             break;
934             }
935            
936 152954           s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
937 152954           s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
938            
939 152954           s->last_error = RETVAL ;
940 152954           if (RETVAL == Z_OK) {
941 152954           SvPOK_only(output);
942 152954           SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
943 152954           SvSETMAGIC(output);
944             }
945             OUTPUT:
946             RETVAL
947            
948            
949             void
950             DESTROY(s)
951             Compress::Raw::Zlib::deflateStream s
952             CODE:
953 31           deflateEnd(&s->stream) ;
954 31           if (s->dictionary)
955 0           SvREFCNT_dec(s->dictionary) ;
956             #ifndef SETP_BYTE
957             if (s->deflateParams_out_buffer)
958             Safefree(s->deflateParams_out_buffer);
959             #endif
960 31           Safefree(s) ;
961            
962            
963             DualType
964             flush(s, output, f=Z_FINISH)
965             Compress::Raw::Zlib::deflateStream s
966             SV * output
967             int f
968             uInt cur_length = NO_INIT
969             uInt increment = NO_INIT
970             uInt prefix = NO_INIT
971             uLong bufinc = NO_INIT
972             CODE:
973 32           bufinc = s->bufsize;
974            
975 32           s->stream.avail_in = 0; /* should be zero already anyway */
976            
977             /* retrieve the output buffer */
978 32           output = deRef_l(output, "flush") ;
979             #ifdef UTF8_AVAILABLE
980 32           if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
981 0           croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
982             #endif
983 32           if(! s->flags & FLAG_APPEND) {
984 7           SvCUR_set(output, 0);
985             /* sv_setpvn(output, "", 0); */
986             }
987 32           prefix = cur_length = SvCUR(output) ;
988 32           s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
989 32           increment = SvLEN(output) - cur_length;
990 32           s->stream.avail_out = increment;
991             #ifdef SETP_BYTE
992             /* Check for saved output from deflateParams */
993 32           if (s->deflateParams_out_valid) {
994 0           *(s->stream.next_out) = s->deflateParams_out_byte;
995 0           ++ s->stream.next_out;
996 0           -- s->stream.avail_out ;
997 0           s->deflateParams_out_valid = FALSE;
998             }
999             #else
1000             /* Check for saved output from deflateParams */
1001             if (s->deflateParams_out_length) {
1002             uLong plen = s->deflateParams_out_length ;
1003             /* printf("Copy %d bytes saved data\n", plen); */
1004             if (s->stream.avail_out < plen) {
1005             /* printf("GROW from %d to %d\n", s->stream.avail_out,
1006             SvLEN(output) + plen - s->stream.avail_out); */
1007             Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1008             }
1009            
1010             Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1011             cur_length = cur_length + plen;
1012             SvCUR_set(output, cur_length);
1013             s->stream.next_out += plen ;
1014             s->stream.avail_out = SvLEN(output) - cur_length ;
1015             increment = s->stream.avail_out;
1016             s->deflateParams_out_length = 0;
1017             }
1018             #endif
1019            
1020             for (;;) {
1021 32           if (s->stream.avail_out == 0) {
1022             /* consumed all the available output, so extend it */
1023 41           Sv_Grow(output, SvLEN(output) + bufinc) ;
1024 44           cur_length += increment ;
1025 44           s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1026             increment = bufinc ;
1027 44           s->stream.avail_out = increment;
1028 44           bufinc *= 2 ;
1029             }
1030 73           RETVAL = deflate(&(s->stream), f);
1031            
1032             /* deflate has finished flushing only when it hasn't used up
1033                      * all the available space in the output buffer:
1034                      */
1035 73           if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1036             break;
1037             }
1038            
1039 32           RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1040 32           s->last_error = RETVAL ;
1041            
1042 32           s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1043            
1044 32           if (RETVAL == Z_OK) {
1045 32           SvPOK_only(output);
1046 32           SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1047 32           SvSETMAGIC(output);
1048             }
1049             OUTPUT:
1050             RETVAL
1051            
1052            
1053             DualType
1054             _deflateParams(s, flags, level, strategy, bufsize)
1055             Compress::Raw::Zlib::deflateStream s
1056             int flags
1057             int level
1058             int strategy
1059             uLong bufsize
1060             CODE:
1061             /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1062             printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1063 3           if (flags & 1)
1064 2           s->Level = level ;
1065 3           if (flags & 2)
1066 2           s->Strategy = strategy ;
1067 3           if (flags & 4) {
1068 1           s->bufsize = bufsize;
1069             }
1070             /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1071             #ifdef SETP_BYTE
1072 3           s->stream.avail_in = 0;
1073 3           s->stream.next_out = &(s->deflateParams_out_byte) ;
1074 3           s->stream.avail_out = 1;
1075 3           RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1076 3           s->deflateParams_out_valid =
1077             (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1078             /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1079             #else
1080             /* printf("Level %d Strategy %d, Prev Len %d\n",
1081             s->Level, s->Strategy, s->deflateParams_out_length); */
1082             s->stream.avail_in = 0;
1083                     if (s->deflateParams_out_buffer == NULL)
1084             s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1085             s->stream.next_out = s->deflateParams_out_buffer ;
1086             s->stream.avail_out = deflateParams_BUFFER_SIZE;
1087            
1088             RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1089             s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1090             /* printf("RETVAL %d, length out %d, avail %d\n",
1091             RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1092             #endif
1093             OUTPUT:
1094             RETVAL
1095            
1096            
1097             int
1098             get_Level(s)
1099             Compress::Raw::Zlib::deflateStream s
1100             CODE:
1101             RETVAL = s->Level ;
1102             OUTPUT:
1103             RETVAL
1104            
1105             int
1106             get_Strategy(s)
1107             Compress::Raw::Zlib::deflateStream s
1108             CODE:
1109             RETVAL = s->Strategy ;
1110             OUTPUT:
1111             RETVAL
1112            
1113            
1114             uLong
1115             get_Bufsize(s)
1116             Compress::Raw::Zlib::deflateStream s
1117             CODE:
1118             RETVAL = s->bufsize ;
1119             OUTPUT:
1120             RETVAL
1121            
1122            
1123             int
1124             status(s)
1125             Compress::Raw::Zlib::deflateStream s
1126             CODE:
1127             RETVAL = s->last_error ;
1128             OUTPUT:
1129             RETVAL
1130            
1131             uLong
1132             crc32(s)
1133             Compress::Raw::Zlib::deflateStream s
1134             CODE:
1135             RETVAL = s->crc32 ;
1136             OUTPUT:
1137             RETVAL
1138            
1139             uLong
1140             dict_adler(s)
1141             Compress::Raw::Zlib::deflateStream s
1142             CODE:
1143             RETVAL = s->dict_adler ;
1144             OUTPUT:
1145             RETVAL
1146            
1147             uLong
1148             adler32(s)
1149             Compress::Raw::Zlib::deflateStream s
1150             CODE:
1151             RETVAL = s->adler32 ;
1152             OUTPUT:
1153             RETVAL
1154            
1155             uLong
1156             compressedBytes(s)
1157             Compress::Raw::Zlib::deflateStream s
1158             CODE:
1159             RETVAL = s->compressedBytes;
1160             OUTPUT:
1161             RETVAL
1162            
1163             uLong
1164             uncompressedBytes(s)
1165             Compress::Raw::Zlib::deflateStream s
1166             CODE:
1167             RETVAL = s->uncompressedBytes;
1168             OUTPUT:
1169             RETVAL
1170            
1171             uLong
1172             total_in(s)
1173             Compress::Raw::Zlib::deflateStream s
1174             CODE:
1175             RETVAL = s->stream.total_in ;
1176             OUTPUT:
1177             RETVAL
1178            
1179             uLong
1180             total_out(s)
1181             Compress::Raw::Zlib::deflateStream s
1182             CODE:
1183             RETVAL = s->stream.total_out ;
1184             OUTPUT:
1185             RETVAL
1186            
1187             char*
1188             msg(s)
1189             Compress::Raw::Zlib::deflateStream s
1190             CODE:
1191             RETVAL = s->stream.msg;
1192             OUTPUT:
1193             RETVAL
1194            
1195             int
1196             deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1197             Compress::Raw::Zlib::deflateStream s
1198             int good_length
1199             int max_lazy
1200             int nice_length
1201             int max_chain
1202             CODE:
1203             #ifndef AT_LEAST_ZLIB_1_2_2_3
1204             good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1205             nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1206             croak("deflateTune needs zlib 1.2.2.3 or better");
1207             #else
1208 0           RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1209             #endif
1210             OUTPUT:
1211             RETVAL
1212            
1213            
1214             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1215            
1216             void
1217             DispStream(s, message=NULL)
1218             Compress::Raw::Zlib::inflateStream s
1219             char * message
1220            
1221             DualType
1222             inflateReset(s)
1223             Compress::Raw::Zlib::inflateStream s
1224             CODE:
1225 0           RETVAL = inflateReset(&(s->stream)) ;
1226 0           if (RETVAL == Z_OK) {
1227 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1228             }
1229             OUTPUT:
1230             RETVAL
1231            
1232             DualType
1233             inflate (s, buf, output, eof=FALSE)
1234             Compress::Raw::Zlib::inflateStream s
1235             SV * buf
1236             SV * output
1237             bool eof
1238             uInt cur_length = 0;
1239             uInt prefix_length = 0;
1240             uInt increment = 0;
1241             STRLEN stmp = NO_INIT
1242             uLong bufinc = NO_INIT
1243             PREINIT:
1244             #ifdef UTF8_AVAILABLE
1245             bool out_utf8 = FALSE;
1246             #endif
1247             CODE:
1248 50941           bufinc = s->bufsize;
1249             /* If the buffer is a reference, dereference it */
1250 50941           buf = deRef(buf, "inflate") ;
1251            
1252 50941           if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
1253 1           croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1254             #ifdef UTF8_AVAILABLE
1255 50940           if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1256 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1257             #endif
1258            
1259             /* initialise the input buffer */
1260 50940           s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1261 50940           s->stream.avail_in = SvCUR(buf) ;
1262            
1263             /* and retrieve the output buffer */
1264 50940           output = deRef_l(output, "inflate") ;
1265             #ifdef UTF8_AVAILABLE
1266 50940           if (DO_UTF8(output))
1267             out_utf8 = TRUE ;
1268 0           if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1269 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1270             #endif
1271 50940           if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1272 132           SvCUR_set(output, 0);
1273             }
1274 50940           if (SvLEN(output)) {
1275 50927           prefix_length = cur_length = SvCUR(output) ;
1276 50927           s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
1277 50927           increment = SvLEN(output) - cur_length - 1;
1278 50927           s->stream.avail_out = increment;
1279             }
1280             else {
1281 13           s->stream.avail_out = 0;
1282             }
1283 50940           s->bytesInflated = 0;
1284            
1285             while (1) {
1286            
1287 101872           if (s->stream.avail_out == 0 ) {
1288             /* out of space in the output buffer so make it bigger */
1289 59           Sv_Grow(output, SvLEN(output) + bufinc) ;
1290 59           cur_length += increment ;
1291 59           s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1292             increment = bufinc ;
1293 59           s->stream.avail_out = increment;
1294 59           bufinc *= 2 ;
1295             }
1296            
1297 101872           RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1298            
1299 101872           if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1300             RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1301             break ;
1302            
1303 101838           if (RETVAL == Z_BUF_ERROR) {
1304 50906           if (s->stream.avail_out == 0)
1305 50906           continue ;
1306 50906           if (s->stream.avail_in == 0) {
1307             RETVAL = Z_OK ;
1308             break ;
1309             }
1310             }
1311            
1312 50932           if (RETVAL == Z_NEED_DICT && s->dictionary) {
1313 1           s->dict_adler = s->stream.adler ;
1314 1           RETVAL = inflateSetDictionary(&(s->stream),
1315             (const Bytef*)SvPVbyte_nolen(s->dictionary),
1316             SvCUR(s->dictionary));
1317             }
1318            
1319 50932           if (RETVAL != Z_OK)
1320             break;
1321             }
1322             #ifdef NEED_DUMMY_BYTE_AT_END
1323             if (eof && RETVAL == Z_OK) {
1324             Bytef* nextIn = s->stream.next_in;
1325             uInt availIn = s->stream.avail_in;
1326             s->stream.next_in = (Bytef*) " ";
1327             s->stream.avail_in = 1;
1328             if (s->stream.avail_out == 0) {
1329             /* out of space in the output buffer so make it bigger */
1330             Sv_Grow(output, SvLEN(output) + bufinc) ;
1331             cur_length += increment ;
1332             s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
1333             increment = bufinc ;
1334             s->stream.avail_out = increment;
1335             bufinc *= 2 ;
1336             }
1337             RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1338             s->stream.next_in = nextIn ;
1339             s->stream.avail_in = availIn ;
1340             }
1341             #endif
1342            
1343 50940           s->last_error = RETVAL ;
1344 50940           if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_DATA_ERROR) {
1345             unsigned in ;
1346            
1347 50940           s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1348 50940           s->uncompressedBytes += s->bytesInflated ;
1349 50940           s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1350            
1351 50940           SvPOK_only(output);
1352 50940           SvCUR_set(output, prefix_length + s->bytesInflated) ;
1353 50940           *SvEND(output) = '\0';
1354             #ifdef UTF8_AVAILABLE
1355 50940           if (out_utf8)
1356 0           sv_utf8_upgrade(output);
1357             #endif
1358 50940           SvSETMAGIC(output);
1359            
1360 50940           if (s->flags & FLAG_CRC32 )
1361 0           s->crc32 = crc32(s->crc32,
1362             (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1363             SvCUR(output)-prefix_length) ;
1364            
1365 50940           if (s->flags & FLAG_ADLER32)
1366 0           s->adler32 = adler32(s->adler32,
1367             (const Bytef*)SvPVbyte_nolen(output)+prefix_length,
1368             SvCUR(output)-prefix_length) ;
1369            
1370             /* fix the input buffer */
1371 50940           if (s->flags & FLAG_CONSUME_INPUT) {
1372 50935           in = s->stream.avail_in ;
1373 50935           SvCUR_set(buf, in) ;
1374 50935           if (in)
1375 3           Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1376 50935           *SvEND(buf) = '\0';
1377 50935           SvSETMAGIC(buf);
1378             }
1379             }
1380             OUTPUT:
1381             RETVAL
1382            
1383             uLong
1384             inflateCount(s)
1385             Compress::Raw::Zlib::inflateStream s
1386             CODE:
1387             RETVAL = s->bytesInflated;
1388             OUTPUT:
1389             RETVAL
1390            
1391             uLong
1392             compressedBytes(s)
1393             Compress::Raw::Zlib::inflateStream s
1394             CODE:
1395             RETVAL = s->compressedBytes;
1396             OUTPUT:
1397             RETVAL
1398            
1399             uLong
1400             uncompressedBytes(s)
1401             Compress::Raw::Zlib::inflateStream s
1402             CODE:
1403             RETVAL = s->uncompressedBytes;
1404             OUTPUT:
1405             RETVAL
1406            
1407            
1408             DualType
1409             inflateSync (s, buf)
1410             Compress::Raw::Zlib::inflateStream s
1411             SV * buf
1412             CODE:
1413            
1414             /* If the buffer is a reference, dereference it */
1415 169           buf = deRef(buf, "inflateSync") ;
1416             #ifdef UTF8_AVAILABLE
1417 169           if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1418 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1419             #endif
1420            
1421             /* initialise the input buffer */
1422 169           s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ;
1423 169           s->stream.avail_in = SvCUR(buf) ;
1424            
1425             /* inflateSync doesn't create any output */
1426 169           s->stream.next_out = (Bytef*) NULL;
1427 169           s->stream.avail_out = 0;
1428            
1429 169           RETVAL = inflateSync(&(s->stream));
1430 169           s->last_error = RETVAL ;
1431            
1432             /* fix the input buffer */
1433             {
1434 169           unsigned in = s->stream.avail_in ;
1435 169           SvCUR_set(buf, in) ;
1436 169           if (in)
1437 1           Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1438 169           *SvEND(buf) = '\0';
1439 169           SvSETMAGIC(buf);
1440             }
1441             OUTPUT:
1442             RETVAL
1443            
1444             void
1445             DESTROY(s)
1446             Compress::Raw::Zlib::inflateStream s
1447             CODE:
1448 35           inflateEnd(&s->stream) ;
1449 35           if (s->dictionary)
1450 1           SvREFCNT_dec(s->dictionary) ;
1451             #ifndef SETP_BYTE
1452             if (s->deflateParams_out_buffer)
1453             Safefree(s->deflateParams_out_buffer);
1454             #endif
1455             #ifdef MAGIC_APPEND
1456 35           if (s->window)
1457 0           Safefree(s->window);
1458             #endif
1459 35           Safefree(s) ;
1460            
1461            
1462             uLong
1463             status(s)
1464             Compress::Raw::Zlib::inflateStream s
1465             CODE:
1466             RETVAL = s->last_error ;
1467             OUTPUT:
1468             RETVAL
1469            
1470             uLong
1471             crc32(s)
1472             Compress::Raw::Zlib::inflateStream s
1473             CODE:
1474             RETVAL = s->crc32 ;
1475             OUTPUT:
1476             RETVAL
1477            
1478             uLong
1479             dict_adler(s)
1480             Compress::Raw::Zlib::inflateStream s
1481             CODE:
1482             RETVAL = s->dict_adler ;
1483             OUTPUT:
1484             RETVAL
1485            
1486             uLong
1487             total_in(s)
1488             Compress::Raw::Zlib::inflateStream s
1489             CODE:
1490             RETVAL = s->stream.total_in ;
1491             OUTPUT:
1492             RETVAL
1493            
1494             uLong
1495             adler32(s)
1496             Compress::Raw::Zlib::inflateStream s
1497             CODE:
1498             RETVAL = s->adler32 ;
1499             OUTPUT:
1500             RETVAL
1501            
1502             uLong
1503             total_out(s)
1504             Compress::Raw::Zlib::inflateStream s
1505             CODE:
1506             RETVAL = s->stream.total_out ;
1507             OUTPUT:
1508             RETVAL
1509            
1510             char*
1511             msg(s)
1512             Compress::Raw::Zlib::inflateStream s
1513             CODE:
1514             RETVAL = s->stream.msg;
1515             OUTPUT:
1516             RETVAL
1517            
1518            
1519             uLong
1520             get_Bufsize(s)
1521             Compress::Raw::Zlib::inflateStream s
1522             CODE:
1523             RETVAL = s->bufsize ;
1524             OUTPUT:
1525             RETVAL
1526            
1527             bool
1528             set_Append(s, mode)
1529             Compress::Raw::Zlib::inflateStream s
1530             bool mode
1531             CODE:
1532 0           RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1533 0           if (mode)
1534 0           s->flags |= FLAG_APPEND ;
1535             else
1536 0           s->flags &= ~FLAG_APPEND ;
1537             OUTPUT:
1538             RETVAL
1539            
1540             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
1541            
1542             void
1543             DESTROY(s)
1544             Compress::Raw::Zlib::inflateScanStream s
1545             CODE:
1546 1           inflateEnd(&s->stream) ;
1547 1           if (s->dictionary)
1548 0           SvREFCNT_dec(s->dictionary) ;
1549             #ifndef SETP_BYTE
1550             if (s->deflateParams_out_buffer)
1551             Safefree(s->deflateParams_out_buffer);
1552             #endif
1553             #ifdef MAGIC_APPEND
1554 1           if (s->window)
1555 1           Safefree(s->window);
1556             #endif
1557 1           Safefree(s) ;
1558            
1559             void
1560             DispStream(s, message=NULL)
1561             Compress::Raw::Zlib::inflateScanStream s
1562             char * message
1563            
1564             DualType
1565             inflateReset(s)
1566             Compress::Raw::Zlib::inflateScanStream s
1567             CODE:
1568 0           RETVAL = inflateReset(&(s->stream)) ;
1569 0           if (RETVAL == Z_OK) {
1570 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1571             }
1572             OUTPUT:
1573             RETVAL
1574            
1575             DualType
1576             scan(s, buf, out=NULL, eof=FALSE)
1577             Compress::Raw::Zlib::inflateScanStream s
1578             SV * buf
1579             SV * out
1580             bool eof
1581             bool eof_mode = FALSE;
1582             int start_len = NO_INIT
1583             STRLEN stmp = NO_INIT
1584             CODE:
1585             /* If the input buffer is a reference, dereference it */
1586             #ifndef MAGIC_APPEND
1587             buf = buf;
1588             croak("scan needs zlib 1.2.1 or better");
1589             #else
1590 0           buf = deRef(buf, "inflateScan") ;
1591             #ifdef UTF8_AVAILABLE
1592 0           if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1593 0           croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
1594             #endif
1595             /* initialise the input buffer */
1596 0           s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ;
1597 0           s->stream.avail_in = SvCUR(buf) ;
1598 0           start_len = s->stream.avail_in ;
1599 0           s->bytesInflated = 0 ;
1600             do
1601             {
1602 0           if (s->stream.avail_in == 0) {
1603             RETVAL = Z_OK ;
1604             break ;
1605             }
1606            
1607             /* set up output to next available section of sliding window */
1608 0           s->stream.avail_out = WINDOW_SIZE - s->window_have;
1609 0           s->stream.next_out = s->window + s->window_have;
1610            
1611             /* DispStream(s, "before inflate\n"); */
1612            
1613             /* inflate and check for errors */
1614 0           RETVAL = inflate(&(s->stream), Z_BLOCK);
1615            
1616 0           if (start_len > 1 && ! eof_mode)
1617 0           s->window_lastByte = *(s->stream.next_in - 1 ) ;
1618            
1619 0           if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1620             RETVAL == Z_DATA_ERROR )
1621             break ;
1622            
1623 0           if (s->flags & FLAG_CRC32 )
1624 0           s->crc32 = crc32(s->crc32, s->window + s->window_have,
1625             WINDOW_SIZE - s->window_have - s->stream.avail_out);
1626              
1627 0                   if (s->flags & FLAG_ADLER32)
1628 0           s->adler32 = adler32(s->adler32, s->window + s->window_have,
1629             WINDOW_SIZE - s->window_have - s->stream.avail_out);
1630              
1631 0                   s->uncompressedBytes =
1632             s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1633              
1634 0                   if (s->stream.avail_out)
1635 0           s->window_have = WINDOW_SIZE - s->stream.avail_out;
1636             else {
1637 0           s->window_have = 0;
1638 0           s->window_full = 1;
1639                     }
1640              
1641                     /* process end of block */
1642 0           if (s->stream.data_type & 128) {
1643 0           if (s->stream.data_type & 64) {
1644 0           s->window_left = s->stream.data_type & 0x1f;
1645             }
1646             else {
1647 0           s->window_lastbit = s->stream.data_type & 0x1f;
1648 0           s->lastBlockOffset = s->stream.total_in;
1649             }
1650             }
1651            
1652 0           } while (RETVAL != Z_STREAM_END);
1653            
1654 0           s->last_error = RETVAL ;
1655 0           s->window_lastoff = s->stream.total_in ;
1656 0           s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1657            
1658 0           if (RETVAL == Z_STREAM_END)
1659             {
1660 0           s->matchedEndBlock = 1 ;
1661            
1662             /* save the location of the end of the compressed data */
1663 0           s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1664 0           s->window_endOffset = s->stream.total_in ;
1665 0           if (s->window_left)
1666             {
1667 0           -- s->window_endOffset ;
1668             }
1669            
1670             /* if window wrapped, build dictionary from window by rotating */
1671 0           if (s->window_full) {
1672 0           rotate(s->window, WINDOW_SIZE, s->window_have);
1673 0           s->window_have = WINDOW_SIZE;
1674             }
1675            
1676             /* if (s->flags & FLAG_CONSUME_INPUT) { */
1677             if (1) {
1678 0           unsigned in = s->stream.avail_in ;
1679 0           SvCUR_set(buf, in) ;
1680 0           if (in)
1681 0           Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
1682 0                           *SvEND(buf) = '\0';
1683 0                           SvSETMAGIC(buf);
1684                     }
1685                 }
1686             #endif
1687               OUTPUT:
1688             RETVAL
1689              
1690              
1691             uLong
1692             getEndOffset(s)
1693             Compress::Raw::Zlib::inflateScanStream s
1694             CODE:
1695             #ifndef MAGIC_APPEND
1696             croak("getEndOffset needs zlib 1.2.1 or better");
1697             #else
1698             RETVAL = s->window_endOffset;
1699             #endif
1700             OUTPUT:
1701             RETVAL
1702            
1703             uLong
1704             inflateCount(s)
1705                 Compress::Raw::Zlib::inflateScanStream s
1706             CODE:
1707             #ifndef MAGIC_APPEND
1708             croak("inflateCount needs zlib 1.2.1 or better");
1709             #else
1710             RETVAL = s->bytesInflated;
1711             #endif
1712             OUTPUT:
1713             RETVAL
1714            
1715             uLong
1716             compressedBytes(s)
1717             Compress::Raw::Zlib::inflateScanStream s
1718             CODE:
1719             RETVAL = s->compressedBytes;
1720             OUTPUT:
1721             RETVAL
1722            
1723             uLong
1724             uncompressedBytes(s)
1725             Compress::Raw::Zlib::inflateScanStream s
1726             CODE:
1727             RETVAL = s->uncompressedBytes;
1728             OUTPUT:
1729             RETVAL
1730            
1731            
1732             uLong
1733             getLastBlockOffset(s)
1734             Compress::Raw::Zlib::inflateScanStream s
1735             CODE:
1736             #ifndef MAGIC_APPEND
1737             croak("getLastBlockOffset needs zlib 1.2.1 or better");
1738             #else
1739             RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
1740             #endif
1741             OUTPUT:
1742             RETVAL
1743            
1744             uLong
1745             getLastBufferOffset(s)
1746             Compress::Raw::Zlib::inflateScanStream s
1747             CODE:
1748             #ifndef MAGIC_APPEND
1749             croak("getLastBufferOffset needs zlib 1.2.1 or better");
1750             #else
1751             RETVAL = s->window_lastoff;
1752             #endif
1753             OUTPUT:
1754             RETVAL
1755            
1756             void
1757             resetLastBlockByte(s, byte)
1758             Compress::Raw::Zlib::inflateScanStream s
1759             unsigned char* byte
1760             CODE:
1761             #ifndef MAGIC_APPEND
1762             croak("resetLastBlockByte needs zlib 1.2.1 or better");
1763             #else
1764 0           if (byte != NULL)
1765 0           *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
1766             #endif
1767            
1768            
1769             void
1770             _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1771             Compress::Raw::Zlib::inflateScanStream inf_s
1772             int flags
1773             int level
1774             int method
1775             int windowBits
1776             int memLevel
1777             int strategy
1778             uLong bufsize
1779             PPCODE:
1780             {
1781             #ifndef MAGIC_APPEND
1782             flags = flags;
1783             level = level ;
1784             method = method;
1785             windowBits = windowBits;
1786             memLevel = memLevel;
1787             strategy = strategy;
1788             bufsize= bufsize;
1789             croak("_createDeflateStream needs zlib 1.2.1 or better");
1790             #else
1791             int err ;
1792             deflateStream s ;
1793            
1794 0           if (trace)
1795 0           warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1796             level, method, windowBits, memLevel, strategy, bufsize) ;
1797 0           if ((s = InitStream() )) {
1798            
1799 0           s->Level = level;
1800 0           s->Method = method;
1801 0           s->WindowBits = windowBits;
1802 0           s->MemLevel = memLevel;
1803 0           s->Strategy = strategy;
1804            
1805 0           err = deflateInit2(&(s->stream), level,
1806             method, windowBits, memLevel, strategy);
1807            
1808 0           if (err == Z_OK) {
1809 0           err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1810 0           s->dict_adler = s->stream.adler ;
1811             }
1812            
1813 0           if (err != Z_OK) {
1814 0           Safefree(s) ;
1815             s = NULL ;
1816             }
1817             else {
1818 0           PostInitStream(s, flags, bufsize, windowBits) ;
1819 0           s->crc32 = inf_s->crc32;
1820 0           s->adler32 = inf_s->adler32;
1821 0           s->stream.adler = inf_s->stream.adler ;
1822             /* s->stream.total_out = inf_s->bytesInflated ; */
1823 0           s->stream.total_in = inf_s->stream.total_out ;
1824 0           if (inf_s->window_left) {
1825             /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1826 0           deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1827             }
1828             }