File Coverage

Zlib.xs
Criterion Covered Total %
statement 332 612 54.2
branch 200 500 40.0
condition n/a
subroutine n/a
pod n/a
total 532 1112 47.8


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-2013 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             #define PERL_NO_GET_CONTEXT
30             #include "EXTERN.h"
31             #include "perl.h"
32             #include "XSUB.h"
33              
34             #if USE_ZLIB_NG
35             # include "zlib-ng.h"
36             #else
37             # include "zlib.h"
38             #endif
39              
40              
41             /* zlib prior to 1.06 doesn't know about z_off_t */
42             #ifndef z_off_t
43             # define z_off_t long
44             #endif
45              
46             #if ! USE_ZLIB_NG && (! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200)
47             # define NEED_DUMMY_BYTE_AT_END
48             #endif
49              
50             #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210)
51             # define MAGIC_APPEND
52             # define AT_LEAST_ZLIB_1_2_1
53             #endif
54              
55             #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221)
56             # define AT_LEAST_ZLIB_1_2_2_1
57             #endif
58              
59             #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1222)
60             # define AT_LEAST_ZLIB_1_2_2_2
61             #endif
62              
63             #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223)
64             # define AT_LEAST_ZLIB_1_2_2_3
65             #endif
66              
67             #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230)
68             # define AT_LEAST_ZLIB_1_2_3
69             #endif
70              
71             #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1252)
72             /*
73             Use Z_SOLO to build source means need own malloc/free
74             */
75             # define AT_LEAST_ZLIB_1_2_5_2
76             #endif
77              
78              
79             /* zlib vs zlib-ng */
80              
81             #if USE_ZLIB_NG
82              
83             /* zlibng native */
84              
85             # define HAVE_ZLIB_NG_NATIVE TRUE
86             # define HAVE_ZLIB_NG_COMPAT FALSE
87              
88             # ifndef ZLIBNG_VER_STATUS
89             # define ZLIBNG_VER_STATUS 0
90             # endif
91              
92             # ifndef ZLIBNG_VER_MODIFIED
93             # define ZLIBNG_VER_MODIFIED 0
94             # endif
95              
96             # define CRZ_adlerInitial zng_adler32(0L, Z_NULL, 0)
97             # define CRZ_crcInitial zng_crc32(0L, Z_NULL, 0)
98              
99             # define CRZ_ZSTREAM zng_stream
100              
101              
102              
103             # define CRZ_adler32 zng_adler32
104             # define CRZ_adler32_combine zng_adler32_combine
105             # define CRZ_crc32 zng_crc32
106             # define CRZ_crc32_combine zng_crc32_combine
107             # define CRZ_deflate zng_deflate
108             # define CRZ_deflateEnd zng_deflateEnd
109             # define CRZ_deflateInit zng_deflateInit
110             # define CRZ_deflateInit2 zng_deflateInit2
111             # define CRZ_deflateParams zng_deflateParams
112             # define CRZ_deflatePrime zng_deflatePrime
113             # define CRZ_deflateReset zng_deflateReset
114             # define CRZ_deflateSetDictionary zng_deflateSetDictionary
115             # define CRZ_deflateTune zng_deflateTune
116             # define CRZ_inflate zng_inflate
117             # define CRZ_inflateEnd zng_inflateEnd
118             # define CRZ_inflateInit2 zng_inflateInit2
119             # define CRZ_inflateReset zng_inflateReset
120             # define CRZ_inflateSetDictionary zng_inflateSetDictionary
121             # define CRZ_inflateSync zng_inflateSync
122             # define CRZ_zlibCompileFlags zng_zlibCompileFlags
123              
124              
125             /* zlib symbols & functions */
126              
127             // # define CRZ_ZLIB_VERSION ZLIBNG_VERSION
128             // # define ZLIB_VERSION ZLIBNG_VERSION
129             # define CRZ_ZLIB_VERSION ""
130             # define ZLIB_VERSION ""
131              
132             // # define CRZ_zlibVersion zlibng_version
133             // # define CRZ_zlib_version zlibng_version
134              
135             const char *CRZ_zlibVersion(void) { return ""; }
136             const char *CRZ_zlib_version(void) { return ""; }
137              
138              
139             #else /* zlib specific */
140              
141              
142             # define HAVE_ZLIB_NG_NATIVE FALSE
143              
144             /* Is this real zlib or zlib-ng in compat mode */
145             # ifdef ZLIBNG_VERSION
146             /* zlib-ng in compat mode */
147             # define HAVE_ZLIB_NG_COMPAT TRUE
148              
149             # ifndef ZLIBNG_VER_STATUS
150             # define ZLIBNG_VER_STATUS 0
151             # endif
152              
153             # ifndef ZLIBNG_VER_MODIFIED
154             # define ZLIBNG_VER_MODIFIED 0
155             # endif
156              
157             const char *zlibng_version(void) { return ZLIBNG_VERSION ; }
158              
159              
160             # else
161             /* zlib native mode */
162              
163             # define HAVE_ZLIB_NG_COMPAT FALSE
164              
165             /* zlib doesn't have the ZLIBNG synbols, so create them */
166             # define ZLIBNG_VERSION ""
167             # define ZLIBNG_VERNUM 0
168             # define ZLIBNG_VER_MAJOR 0
169             # define ZLIBNG_VER_MINOR 0
170             # define ZLIBNG_VER_REVISION 0
171             # define ZLIBNG_VER_STATUS 0
172             # define ZLIBNG_VER_MODIFIED 0
173             # define ZLIBNG_VERNUM 0
174              
175 0           const char *zlibng_version(void) { return ""; }
176              
177             # endif
178              
179              
180              
181             # define CRZ_adlerInitial adler32(0L, Z_NULL, 0)
182             # define CRZ_crcInitial crc32(0L, Z_NULL, 0)
183              
184             # define CRZ_ZSTREAM z_stream
185              
186             # define CRZ_adler32 adler32
187             # define CRZ_adler32_combine adler32_combine
188             # define CRZ_crc32 crc32
189             # define CRZ_crc32_combine crc32_combine
190             # define CRZ_deflate deflate
191             # define CRZ_deflateEnd deflateEnd
192             # define CRZ_deflateInit deflateInit
193             # define CRZ_deflateInit2 deflateInit2
194             # define CRZ_deflateParams deflateParams
195             # define CRZ_deflatePrime deflatePrime
196             # define CRZ_deflateReset deflateReset
197             # define CRZ_deflateSetDictionary deflateSetDictionary
198             # define CRZ_deflateTune deflateTune
199             # define CRZ_inflate inflate
200             # define CRZ_inflateEnd inflateEnd
201             # define CRZ_inflateInit2 inflateInit2
202             # define CRZ_inflateReset inflateReset
203             # define CRZ_inflateSetDictionary inflateSetDictionary
204             # define CRZ_inflateSync inflateSync
205             # define CRZ_zlibCompileFlags zlibCompileFlags
206             # define CRZ_zlibVersion zlibVersion
207             # define CRZ_zlib_version zlibVersion
208              
209             #endif
210              
211              
212             #ifdef USE_PPPORT_H
213             # define NEED_sv_2pvbyte
214             # define NEED_sv_2pv_nolen
215             # define NEED_sv_pvn_force_flags
216             # include "ppport.h"
217              
218             /* Proposed fix for https://github.com/Dual-Life/Devel-PPPort/issues/231 */
219              
220             # if PERL_VERSION < 18
221             # ifdef sv_2pv
222             # undef sv_2pv
223             # endif
224              
225             # if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
226             # define sv_2pv(sv, lp) ({ SV *_sv_2pv = (sv); SvPOKp(_sv_2pv) ? ((*(lp) = SvCUR(_sv_2pv)), SvPVX(_sv_2pv)) : Perl_sv_2pv(aTHX_ _sv_2pv, (lp)); })
227             # else
228             # define sv_2pv(sv, lp) (SvPOKp(sv) ? ((*(lp) = SvCUR(sv)), SvPVX(sv)) : Perl_sv_2pv(aTHX_ (sv), (lp)))
229             # endif
230              
231             #endif
232              
233             #endif
234              
235             #if PERL_REVISION == 5 && PERL_VERSION == 9
236             /* For Andreas */
237             # define sv_pvbyte_force(sv,lp) sv_pvbyten_force(sv,lp)
238             #endif
239              
240             #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
241              
242             # ifdef SvPVbyte_force
243             # undef SvPVbyte_force
244             # endif
245              
246             # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
247              
248             #endif
249              
250             #ifndef SvPVbyte_nolen
251             # define SvPVbyte_nolen SvPV_nolen
252             #endif
253              
254              
255              
256             #if 0
257             # ifndef SvPVbyte_nolen
258             # define SvPVbyte_nolen SvPV_nolen
259             # endif
260              
261             # ifndef SvPVbyte_force
262             # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
263             # endif
264             #endif
265              
266             #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
267             # define UTF8_AVAILABLE
268             #endif
269              
270             typedef int DualType ;
271             typedef int int_undef ;
272              
273             typedef struct di_stream {
274             int flags ;
275             #define FLAG_APPEND 1
276             #define FLAG_CRC32 2
277             #define FLAG_ADLER32 4
278             #define FLAG_CONSUME_INPUT 8
279             #define FLAG_LIMIT_OUTPUT 16
280             uLong crc32 ;
281             uLong adler32 ;
282             CRZ_ZSTREAM stream;
283             uLong bufsize;
284             SV * dictionary ;
285             uLong dict_adler ;
286             int last_error ;
287             bool zip_mode ;
288             /* #define SETP_BYTE */
289             #ifdef SETP_BYTE
290             /* SETP_BYTE only works with zlib up to 1.2.8 */
291             bool deflateParams_out_valid ;
292             Bytef deflateParams_out_byte;
293             #else
294             #define deflateParams_BUFFER_SIZE 0x40000
295             uLong deflateParams_out_length;
296             Bytef* deflateParams_out_buffer;
297             #endif
298             int Level;
299             int Method;
300             int WindowBits;
301             int MemLevel;
302             int Strategy;
303             uLong bytesInflated ;
304             uLong compressedBytes ;
305             uLong uncompressedBytes ;
306             #ifdef MAGIC_APPEND
307              
308             #define WINDOW_SIZE 32768U
309              
310             bool matchedEndBlock;
311             Bytef* window ;
312             int window_lastbit, window_left, window_full;
313             unsigned window_have;
314             off_t window_lastoff, window_end;
315             off_t window_endOffset;
316              
317             uLong lastBlockOffset ;
318             unsigned char window_lastByte ;
319              
320              
321             #endif
322             } di_stream;
323              
324             typedef di_stream * deflateStream ;
325             typedef di_stream * Compress__Raw__Zlib__deflateStream ;
326             typedef di_stream * inflateStream ;
327             typedef di_stream * Compress__Raw__Zlib__inflateStream ;
328             typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;
329              
330             #define ZMALLOC(to, typ) (to = (typ *)safecalloc(sizeof(typ), 1))
331              
332             /* Figure out the Operating System */
333             #ifdef MSDOS
334             # define OS_CODE 0x00
335             #endif
336              
337             #if defined(AMIGA) || defined(AMIGAOS) || defined(__amigaos4__)
338             # define OS_CODE 0x01
339             #endif
340              
341             #if defined(VAXC) || defined(VMS)
342             # define OS_CODE 0x02
343             #endif
344              
345             #if 0 /* VM/CMS */
346             # define OS_CODE 0x04
347             #endif
348              
349             #if defined(ATARI) || defined(atarist)
350             # define OS_CODE 0x05
351             #endif
352              
353             #ifdef OS2
354             # define OS_CODE 0x06
355             #endif
356              
357             #if defined(MACOS) || defined(TARGET_OS_MAC)
358             # define OS_CODE 0x07
359             #endif
360              
361             #if 0 /* Z-System */
362             # define OS_CODE 0x08
363             #endif
364              
365             #if 0 /* CP/M */
366             # define OS_CODE 0x09
367             #endif
368              
369             #ifdef TOPS20
370             # define OS_CODE 0x0a
371             #endif
372              
373             #ifdef WIN32 /* Window 95 & Windows NT */
374             # define OS_CODE 0x0b
375             #endif
376              
377             #if 0 /* QDOS */
378             # define OS_CODE 0x0c
379             #endif
380              
381             #if 0 /* Acorn RISCOS */
382             # define OS_CODE 0x0d
383             #endif
384              
385             #if 0 /* ??? */
386             # define OS_CODE 0x0e
387             #endif
388              
389             #ifdef __50SERIES /* Prime/PRIMOS */
390             # define OS_CODE 0x0F
391             #endif
392              
393             /* Default to UNIX */
394             #ifndef OS_CODE
395             # define OS_CODE 0x03 /* assume Unix */
396             #endif
397              
398             #ifndef GZIP_OS_CODE
399             # define GZIP_OS_CODE OS_CODE
400             #endif
401              
402              
403             /* static const char * const my_z_errmsg[] = { */
404             static const char my_z_errmsg[][32] = {
405             "need dictionary", /* Z_NEED_DICT 2 */
406             "stream end", /* Z_STREAM_END 1 */
407             "", /* Z_OK 0 */
408             "file error", /* Z_ERRNO (-1) */
409             "stream error", /* Z_STREAM_ERROR (-2) */
410             "data error", /* Z_DATA_ERROR (-3) */
411             "insufficient memory", /* Z_MEM_ERROR (-4) */
412             "buffer error", /* Z_BUF_ERROR (-5) */
413             "incompatible version",/* Z_VERSION_ERROR(-6) */
414             ""};
415              
416             #define setDUALstatus(var, err) \
417             sv_setnv(var, (double)err) ; \
418             sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
419             SvNOK_on(var);
420              
421              
422             #if defined(__SYMBIAN32__)
423             # define NO_WRITEABLE_DATA
424             #endif
425              
426             /* Set TRACE_DEFAULT to a non-zero value to enable tracing */
427             #define TRACE_DEFAULT 0
428              
429             #if defined(NO_WRITEABLE_DATA) || TRACE_DEFAULT == 0
430             # define trace TRACE_DEFAULT
431             #else
432             static int trace = TRACE_DEFAULT ;
433             #endif
434              
435             /* Dodge PerlIO hiding of these functions. */
436             #undef printf
437              
438             static char *
439             #ifdef CAN_PROTOTYPE
440 343           GetErrorString(int error_no)
441             #else
442             GetErrorString(error_no)
443             int error_no ;
444             #endif
445             {
446             dTHX;
447             char * errstr ;
448              
449 343 50         if (error_no == Z_ERRNO) {
450 0           errstr = Strerror(errno) ;
451             }
452             else
453             /* errstr = gzerror(fil, &error_no) ; */
454 343           errstr = (char*) my_z_errmsg[2 - error_no];
455              
456 343           return errstr ;
457             }
458              
459              
460             #ifdef MAGIC_APPEND
461              
462             /*
463             The following two functions are taken almost directly from
464             examples/gzappend.c. Only cosmetic changes have been made to conform to
465             the coding style of the rest of the code in this file.
466             */
467              
468              
469             /* return the greatest common divisor of a and b using Euclid's algorithm,
470             modified to be fast when one argument much greater than the other, and
471             coded to avoid unnecessary swapping */
472             static unsigned
473             #ifdef CAN_PROTOTYPE
474 0           gcd(unsigned a, unsigned b)
475             #else
476             gcd(a, b)
477             unsigned a;
478             unsigned b;
479             #endif
480             {
481             unsigned c;
482              
483 0 0         while (a && b)
    0          
484 0 0         if (a > b) {
485 0           c = b;
486 0 0         while (a - c >= c)
487 0           c <<= 1;
488 0           a -= c;
489             }
490             else {
491 0           c = a;
492 0 0         while (b - c >= c)
493 0           c <<= 1;
494 0           b -= c;
495             }
496 0           return a + b;
497             }
498              
499             /* rotate list[0..len-1] left by rot positions, in place */
500             static void
501             #ifdef CAN_PROTOTYPE
502 0           rotate(unsigned char *list, unsigned len, unsigned rot)
503             #else
504             rotate(list, len, rot)
505             unsigned char *list;
506             unsigned len ;
507             unsigned rot;
508             #endif
509             {
510             unsigned char tmp;
511             unsigned cycles;
512             unsigned char *start, *last, *to, *from;
513              
514             /* normalize rot and handle degenerate cases */
515 0 0         if (len < 2) return;
516 0 0         if (rot >= len) rot %= len;
517 0 0         if (rot == 0) return;
518              
519             /* pointer to last entry in list */
520 0           last = list + (len - 1);
521              
522             /* do simple left shift by one */
523 0 0         if (rot == 1) {
524 0           tmp = *list;
525 0           memmove(list, list + 1, len - 1);
526 0           *last = tmp;
527 0           return;
528             }
529              
530             /* do simple right shift by one */
531 0 0         if (rot == len - 1) {
532 0           tmp = *last;
533 0           memmove(list + 1, list, len - 1);
534 0           *list = tmp;
535 0           return;
536             }
537              
538             /* otherwise do rotate as a set of cycles in place */
539 0           cycles = gcd(len, rot); /* number of cycles */
540             do {
541 0           start = from = list + cycles; /* start index is arbitrary */
542 0           tmp = *from; /* save entry to be overwritten */
543             for (;;) {
544 0           to = from; /* next step in cycle */
545 0           from += rot; /* go right rot positions */
546 0 0         if (from > last) from -= len; /* (pointer better not wrap) */
547 0 0         if (from == start) break; /* all but one shifted */
548 0           *to = *from; /* shift left */
549             }
550 0           *to = tmp; /* complete the circle */
551 0 0         } while (--cycles);
552             }
553              
554             #endif /* MAGIC_APPEND */
555              
556             static void
557             #ifdef CAN_PROTOTYPE
558 0           DispHex(const void * ptr, int length)
559             #else
560             DispHex(ptr, length)
561             const void * ptr;
562             int length;
563             #endif
564             {
565 0           char * p = (char*)ptr;
566             int i;
567 0 0         for (i = 0; i < length; ++i) {
568 0           printf(" %02x", 0xFF & *(p+i));
569             }
570 0           }
571              
572              
573             static void
574             #ifdef CAN_PROTOTYPE
575 0           DispStream(di_stream * s, const char * message)
576             #else
577             DispStream(s, message)
578             di_stream * s;
579             const char * message;
580             #endif
581             {
582              
583             #if 0
584             if (! trace)
585             return ;
586             #endif
587              
588             #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
589              
590 0           printf("DispStream %p", s) ;
591 0 0         if (message)
592 0           printf("- %s \n", message) ;
593 0           printf("\n") ;
594              
595 0 0         if (!s) {
596 0           printf(" stream pointer is NULL\n");
597             }
598             else {
599 0           printf(" stream %p\n", &(s->stream));
600 0           printf(" zalloc %p\n", s->stream.zalloc);
601 0           printf(" zfree %p\n", s->stream.zfree);
602 0           printf(" opaque %p\n", s->stream.opaque);
603 0           printf(" state %p\n", s->stream.state);
604 0 0         if (s->stream.msg)
605 0           printf(" msg %s\n", s->stream.msg);
606             else
607 0           printf(" msg \n");
608 0           printf(" next_in %p", s->stream.next_in);
609 0 0         if (s->stream.next_in){
610 0           printf(" =>");
611 0           DispHex(s->stream.next_in, 4);
612             }
613 0           printf("\n");
614              
615 0           printf(" next_out %p", s->stream.next_out);
616 0 0         if (s->stream.next_out){
617 0           printf(" =>");
618 0           DispHex(s->stream.next_out, 4);
619             }
620 0           printf("\n");
621              
622 0           printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
623 0           printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
624 0           printf(" total_in %ld\n", s->stream.total_in);
625 0           printf(" total_out %ld\n", s->stream.total_out);
626             #if ! USE_ZLIB_NG
627 0           printf(" adler %ld\n", s->stream.adler );
628             #else
629             printf(" adler %u\n", s->stream.adler );
630             #endif
631 0           printf(" bufsize %ld\n", s->bufsize);
632 0           printf(" dictionary %p\n", s->dictionary);
633 0           printf(" dict_adler 0x%ld\n",s->dict_adler);
634 0           printf(" zip_mode %d\n", s->zip_mode);
635 0           printf(" crc32 0x%x\n", (unsigned)s->crc32);
636 0           printf(" adler32 0x%x\n", (unsigned)s->adler32);
637 0           printf(" flags 0x%x\n", s->flags);
638 0 0         printf(" APPEND %s\n", EnDis(FLAG_APPEND));
639 0 0         printf(" CRC32 %s\n", EnDis(FLAG_CRC32));
640 0 0         printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32));
641 0 0         printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
642 0 0         printf(" LIMIT %s\n", EnDis(FLAG_LIMIT_OUTPUT));
643              
644              
645             #ifdef MAGIC_APPEND
646 0           printf(" window %p\n", s->window);
647             #endif
648 0           printf("\n");
649              
650             }
651 0           }
652              
653             #ifdef AT_LEAST_ZLIB_1_2_5_2
654 245           voidpf my_zcalloc (voidpf opaque, unsigned items, unsigned size)
655             {
656             PERL_UNUSED_VAR(opaque);
657             /* TODO - put back to calloc */
658             /* return safecalloc(items, size); */
659 245           return (voidpf)safemalloc(items* size);
660             }
661              
662              
663 245           void my_zcfree (voidpf opaque, voidpf ptr)
664             {
665             PERL_UNUSED_VAR(opaque);
666 245           safefree(ptr);
667 245           return;
668             }
669              
670             #endif
671              
672             static di_stream *
673             #ifdef CAN_PROTOTYPE
674 78           InitStream(void)
675             #else
676             InitStream()
677             #endif
678             {
679             di_stream *s ;
680              
681 78           ZMALLOC(s, di_stream) ;
682              
683             #ifdef AT_LEAST_ZLIB_1_2_5_2
684 78           s->stream.zalloc = my_zcalloc;
685 78           s->stream.zfree = my_zcfree;
686             #endif
687              
688 78           return s ;
689             }
690              
691             static void
692             #ifdef CAN_PROTOTYPE
693 78           PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
694             #else
695             PostInitStream(s, flags, bufsize, windowBits)
696             di_stream *s ;
697             int flags ;
698             int bufsize ;
699             int windowBits ;
700             #endif
701             {
702 78           s->bufsize = bufsize ;
703 78           s->compressedBytes =
704 78           s->uncompressedBytes =
705 78           s->last_error = 0 ;
706 78           s->flags = flags ;
707 78           s->zip_mode = (windowBits < 0) ;
708 78 50         if (flags & FLAG_CRC32)
709 0           s->crc32 = CRZ_crcInitial ;
710 78 50         if (flags & FLAG_ADLER32)
711 0           s->adler32 = CRZ_adlerInitial ;
712 78           }
713              
714              
715             static SV*
716             #ifdef CAN_PROTOTYPE
717 50969           deRef(SV * sv, const char * string)
718             #else
719             deRef(sv, string)
720             SV * sv ;
721             char * string;
722             #endif
723             {
724             dTHX;
725 50969 100         SvGETMAGIC(sv);
    50          
726              
727 50969 50         if (SvROK(sv)) {
728 0           sv = SvRV(sv) ;
729 0 0         SvGETMAGIC(sv);
    0          
730 0 0         switch(SvTYPE(sv)) {
731 0           case SVt_PVAV:
732             case SVt_PVHV:
733             case SVt_PVCV:
734 0           croak("%s: buffer parameter is not a SCALAR reference", string);
735 0           default:
736 0           break;
737             }
738 0 0         if (SvROK(sv))
739 0           croak("%s: buffer parameter is a reference to a reference", string) ;
740             }
741              
742 50969 50         if (!SvOK(sv))
743 0           sv = sv_2mortal(newSVpv("", 0));
744              
745 50969           return sv ;
746             }
747              
748             static SV*
749             #ifdef CAN_PROTOTYPE
750 50826           deRef_l(SV * sv, const char * string)
751             #else
752             deRef_l(sv, string)
753             SV * sv ;
754             char * string ;
755             #endif
756             {
757             dTHX;
758 50826           bool wipe = 0 ;
759             STRLEN na;
760              
761 50826 100         SvGETMAGIC(sv);
    50          
762 50826           wipe = ! SvOK(sv) ;
763              
764 50826 100         if (SvROK(sv)) {
765 134           sv = SvRV(sv) ;
766 134 50         SvGETMAGIC(sv);
    0          
767 134           wipe = ! SvOK(sv) ;
768              
769 134 50         switch(SvTYPE(sv)) {
770 0           case SVt_PVAV:
771             case SVt_PVHV:
772             case SVt_PVCV:
773 0           croak("%s: buffer parameter is not a SCALAR reference", string);
774 134           default:
775 134           break;
776             }
777 134 50         if (SvROK(sv))
778 0           croak("%s: buffer parameter is a reference to a reference", string) ;
779             }
780              
781 50826 50         if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
    0          
782 0           croak("%s: buffer parameter is read-only", string);
783              
784 50826 100         SvUPGRADE(sv, SVt_PV);
785              
786 50826 100         if (wipe)
787 51           sv_setpv(sv, "") ;
788             else
789 50775           (void)SvPVbyte_force(sv, na) ;
790              
791 50826           return sv ;
792             }
793              
794             #if 0
795             int
796             flushToBuffer(di_stream* s, int flush)
797             {
798             dTHX;
799             int ret ;
800             CRZ_ZSTREAM * strm = &s->stream;
801              
802             Bytef* output = s->deflateParams_out_buffer ;
803              
804             strm->next_in = NULL;
805             strm->avail_in = 0;
806              
807             uLong total_output = 0;
808             uLong have = 0;
809              
810             do
811             {
812             if (output)
813             output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
814             else
815             output = (unsigned char *)safemalloc(s->bufsize);
816              
817             strm->next_out = output + total_output;
818             strm->avail_out = s->bufsize;
819              
820             ret = deflate(strm, flush); /* no bad return value */
821             //assert(ret != Z_STREAM_ERROR); /* state not clobbered */
822             if(ret == Z_STREAM_ERROR)
823             {
824             safefree(output);
825             return ret;
826             }
827             have = s->bufsize - strm->avail_out;
828             total_output += have;
829              
830             //fprintf(stderr, "FLUSH %s %d, return %d\n", flush_flags[flush], have, ret);
831              
832             } while (strm->avail_out == 0);
833              
834             s->deflateParams_out_buffer = output;
835             s->deflateParams_out_length = total_output;
836              
837             return Z_OK;
838             }
839             #endif
840              
841             #ifndef SETP_BYTE
842             int
843 4           flushParams(di_stream* s)
844             {
845             dTHX;
846             int ret ;
847 4           CRZ_ZSTREAM * strm = &s->stream;
848              
849 4           Bytef* output = s->deflateParams_out_buffer ;
850 4           uLong total_output = s->deflateParams_out_length;
851 4           uLong have = 0;
852              
853 4           strm->next_in = NULL;
854 4           strm->avail_in = 0;
855              
856              
857             do
858             {
859 4 100         if (output)
860 1           output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
861             else
862 3           output = (unsigned char *)safemalloc(s->bufsize);
863              
864 4           strm->next_out = output + total_output;
865 4           strm->avail_out = s->bufsize;
866              
867 4           ret = CRZ_deflateParams(&(s->stream), s->Level, s->Strategy);
868             /* fprintf(stderr, "deflateParams %d %s %lu\n", ret,
869             GetErrorString(ret), s->bufsize - strm->avail_out); */
870              
871 4 50         if (ret == Z_STREAM_ERROR)
872 0           break;
873              
874 4           have = s->bufsize - strm->avail_out;
875 4           total_output += have;
876              
877              
878 4 50         } while (ret == Z_BUF_ERROR) ;
879              
880 4 50         if(ret == Z_STREAM_ERROR)
881 0           safefree(output);
882             else
883             {
884 4           s->deflateParams_out_buffer = output;
885 4           s->deflateParams_out_length = total_output;
886             }
887              
888 4           return ret;
889             }
890             #endif /* ! SETP_BYTE */
891              
892             #include "constants.h"
893              
894             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
895              
896             REQUIRE: 1.924
897             PROTOTYPES: DISABLE
898              
899             INCLUDE: constants.xs
900              
901             BOOT:
902             #if ! USE_ZLIB_NG
903             /* Check this version of zlib is == 1 */
904 6 50         if (CRZ_zlibVersion()[0] != '1')
905 0           croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
906             #endif
907              
908             {
909             /* Create the $os_code scalar */
910 6           SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
911 6           sv_setiv(os_code_sv, GZIP_OS_CODE) ;
912             }
913              
914             {
915             /* BUILD_ZLIB */
916 6           SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::BUILD_ZLIB", GV_ADDMULTI) ;
917 6           sv_setiv(os_code_sv, Perl_crz_BUILD_ZLIB) ;
918             }
919              
920             #define Zip_zlib_version() (const char*)CRZ_zlib_version()
921             const char*
922             Zip_zlib_version()
923              
924             const char*
925             zlibng_version()
926              
927             #define Zip_is_zlib_native() (! (HAVE_ZLIB_NG_NATIVE || HAVE_ZLIB_NG_COMPAT))
928             bool
929             Zip_is_zlib_native()
930              
931             #define Zip_is_zlibng_native() (bool)HAVE_ZLIB_NG_NATIVE
932             bool
933             Zip_is_zlibng_native()
934              
935             #define Zip_is_zlibng_compat() (bool)HAVE_ZLIB_NG_COMPAT
936             bool
937             Zip_is_zlibng_compat()
938              
939             #define Zip_is_zlibng() (bool)(HAVE_ZLIB_NG_NATIVE || HAVE_ZLIB_NG_COMPAT)
940             bool
941             Zip_is_zlibng()
942              
943             unsigned
944             ZLIB_VERNUM()
945             CODE:
946             #ifdef ZLIB_VERNUM
947 12 50         RETVAL = ZLIB_VERNUM ;
948             #elif USE_ZLIB_NG
949             RETVAL = 0 ;
950             #else
951             /* 1.1.4 => 0x1140 */
952             RETVAL = (CRZ_ZLIB_VERSION[0] - '0') << 12 ;
953             RETVAL += (CRZ_ZLIB_VERSION[2] - '0') << 8 ;
954             RETVAL += (CRZ_ZLIB_VERSION[4] - '0') << 4 ;
955             if (strlen(CRZ_ZLIB_VERSION) > 5)
956             RETVAL += (CRZ_ZLIB_VERSION[6] - '0') ;
957             #endif
958             OUTPUT:
959             RETVAL
960              
961              
962             #ifndef AT_LEAST_ZLIB_1_2_1
963             # define Zip_zlibCompileFlags 0
964             #else
965             # define Zip_zlibCompileFlags CRZ_zlibCompileFlags
966             #endif
967             uLong
968             Zip_zlibCompileFlags()
969              
970             const char*
971             ZLIBNG_VER_STATUS()
972             CODE:
973             #ifdef ZLIBNG_VER_STATUS
974 0           RETVAL = STRINGIFY(ZLIBNG_VER_STATUS);
975             #else
976             RETVAL = "0";
977             #endif
978             OUTPUT:
979             RETVAL
980              
981             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
982              
983             #define Zip_adler32(buf, adler) CRZ_adler32(adler, buf, (uInt)len)
984              
985             uLong
986             Zip_adler32(buf, adler=CRZ_adlerInitial)
987             uLong adler = NO_INIT
988             STRLEN len = NO_INIT
989             Bytef * buf = NO_INIT
990             SV * sv = ST(0) ;
991             INIT:
992             /* If the buffer is a reference, dereference it */
993 3           sv = deRef(sv, "adler32") ;
994             #ifdef UTF8_AVAILABLE
995 3 50         if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
    0          
    0          
996 0           croak("Wide character in Compress::Raw::Zlib::adler32");
997             #endif
998 3           buf = (Byte*)SvPVbyte(sv, len) ;
999              
1000 3 50         if (items < 2)
1001 3           adler = CRZ_adlerInitial;
1002 0 0         else if (SvOK(ST(1)))
1003 0           adler = SvUV(ST(1)) ;
1004             else
1005 0           adler = CRZ_adlerInitial;
1006             OUTPUT:
1007             RETVAL
1008              
1009             #define Zip_crc32(buf, crc, offset) CRZ_crc32(crc, buf+offset, (uInt)len-offset)
1010              
1011             uLong
1012             Zip_crc32(buf, crc=CRZ_crcInitial, offset=0)
1013             uLong crc = NO_INIT
1014             STRLEN len = NO_INIT
1015             Bytef * buf = NO_INIT
1016             STRLEN offset
1017             SV * sv = ST(0) ;
1018             INIT:
1019             /* If the buffer is a reference, dereference it */
1020 5           sv = deRef(sv, "crc32") ;
1021             #ifdef UTF8_AVAILABLE
1022 5 50         if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
    0          
    0          
1023 0           croak("Wide character in Compress::Raw::Zlib::crc32");
1024             #endif
1025 5           buf = (Byte*)SvPVbyte(sv, len) ;
1026              
1027 5 100         if (offset > len)
1028 1           croak("Offset out of range in Compress::Raw::Zlib::crc32");
1029              
1030 4 100         if (items < 2)
1031 3           crc = CRZ_crcInitial;
1032 1 50         else if (SvOK(ST(1)))
1033 1           crc = SvUV(ST(1)) ;
1034             else
1035 0           crc = CRZ_crcInitial;
1036              
1037             uLong
1038             crc32_combine(crc1, crc2, len2)
1039             uLong crc1
1040             uLong crc2
1041             z_off_t len2
1042             CODE:
1043             #ifndef AT_LEAST_ZLIB_1_2_2_1
1044             crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
1045             croak("crc32_combine needs zlib 1.2.3 or better");
1046             #else
1047 1           RETVAL = CRZ_crc32_combine(crc1, crc2, len2);
1048             #endif
1049             OUTPUT:
1050             RETVAL
1051              
1052              
1053             uLong
1054             adler32_combine(adler1, adler2, len2)
1055             uLong adler1
1056             uLong adler2
1057             z_off_t len2
1058             CODE:
1059             #ifndef AT_LEAST_ZLIB_1_2_2_1
1060             adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
1061             croak("adler32_combine needs zlib 1.2.3 or better");
1062             #else
1063 1           RETVAL = CRZ_adler32_combine(adler1, adler2, len2);
1064             #endif
1065             OUTPUT:
1066             RETVAL
1067              
1068              
1069             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
1070              
1071             void
1072             _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
1073             int flags
1074             int level
1075             int method
1076             int windowBits
1077             int memLevel
1078             int strategy
1079             uLong bufsize
1080             SV* dictionary
1081             PPCODE:
1082             int err ;
1083             deflateStream s ;
1084              
1085             if (trace)
1086             warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
1087             level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
1088 33 50         if ((s = InitStream() )) {
1089              
1090 33           s->Level = level;
1091 33           s->Method = method;
1092 33           s->WindowBits = windowBits;
1093 33           s->MemLevel = memLevel;
1094 33           s->Strategy = strategy;
1095              
1096 33           err = CRZ_deflateInit2(&(s->stream), level,
1097             method, windowBits, memLevel, strategy);
1098              
1099             if (trace) {
1100             warn(" _deflateInit2 returned %d (state %p)\n", err, s);
1101             DispStream(s, "INIT");
1102             }
1103              
1104             /* Check if a dictionary has been specified */
1105 33 50         SvGETMAGIC(dictionary);
    0          
1106 33 50         if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) {
    100          
    100          
1107             #ifdef UTF8_AVAILABLE
1108 1 50         if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
    0          
    0          
1109 0           croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
1110             #endif
1111 1           err = CRZ_deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ;
1112             if (trace)
1113             warn("deflateSetDictionary returned %d\n", err);
1114 1           s->dict_adler = s->stream.adler ;
1115             }
1116              
1117 33 50         if (err != Z_OK) {
1118 0           Safefree(s) ;
1119 0           s = NULL ;
1120             }
1121             else
1122 33           PostInitStream(s, flags, bufsize, windowBits) ;
1123              
1124             }
1125             else
1126 0           err = Z_MEM_ERROR ;
1127              
1128             {
1129 33           SV* obj = sv_setref_pv(sv_newmortal(),
1130             "Compress::Raw::Zlib::deflateStream", (void*)s);
1131 33 50         XPUSHs(obj);
1132             }
1133 33 100         if (GIMME_V == G_ARRAY) {
1134 22           SV * sv = sv_2mortal(newSViv(err)) ;
1135 22 50         setDUALstatus(sv, err);
1136 22 50         XPUSHs(sv) ;
1137             }
1138              
1139             void
1140             _inflateInit(flags, windowBits, bufsize, dictionary)
1141             int flags
1142             int windowBits
1143             uLong bufsize
1144             SV * dictionary
1145             ALIAS:
1146             _inflateScanInit = 1
1147             PPCODE:
1148              
1149 45           int err = Z_OK ;
1150             inflateStream s ;
1151             #ifndef MAGIC_APPEND
1152             if (ix == 1)
1153             croak("inflateScanInit needs zlib 1.2.1 or better");
1154             #endif
1155             if (trace)
1156             warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
1157             windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
1158 45 50         if ((s = InitStream() )) {
1159              
1160 45           s->WindowBits = windowBits;
1161              
1162 45           err = CRZ_inflateInit2(&(s->stream), windowBits);
1163 45 50         if (err != Z_OK) {
1164 0           Safefree(s) ;
1165 0           s = NULL ;
1166             }
1167 45 100         else if (sv_len(dictionary)) {
1168             #ifdef AT_LEAST_ZLIB_1_2_2_1
1169             /* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */
1170 2 50         if (s->WindowBits < 0) {
1171             STRLEN dlen;
1172 0           const Bytef* b = (const Bytef*)SvPVbyte(dictionary, dlen);
1173 0           err = CRZ_inflateSetDictionary(&(s->stream),
1174             b, dlen);
1175 0 0         if (err != Z_OK) {
1176 0           Safefree(s) ;
1177 0           s = NULL ;
1178             }
1179             }
1180             else
1181             #endif
1182             /* Dictionary specified - take a copy for use in inflate */
1183 2           s->dictionary = newSVsv(dictionary) ;
1184             }
1185 45 50         if (s) {
1186 45           PostInitStream(s, flags, bufsize, windowBits) ;
1187             #ifdef MAGIC_APPEND
1188 45 100         if (ix == 1)
1189             {
1190 1           s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
1191             }
1192             #endif
1193             }
1194             }
1195             else
1196 0           err = Z_MEM_ERROR ;
1197              
1198             {
1199 45 100         SV* obj = sv_setref_pv(sv_newmortal(),
1200             ix == 1
1201             ? "Compress::Raw::Zlib::inflateScanStream"
1202             : "Compress::Raw::Zlib::inflateStream",
1203             (void*)s);
1204 45 50         XPUSHs(obj);
1205             }
1206 45 100         if (GIMME_V == G_ARRAY) {
1207 31           SV * sv = sv_2mortal(newSViv(err)) ;
1208 31 50         setDUALstatus(sv, err);
1209 31 50         XPUSHs(sv) ;
1210             }
1211              
1212              
1213              
1214             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
1215              
1216             void
1217             DispStream(s, message=NULL)
1218             Compress::Raw::Zlib::deflateStream s
1219             const char * message
1220              
1221             DualType
1222             deflateReset(s)
1223             Compress::Raw::Zlib::deflateStream s
1224             CODE:
1225 0           RETVAL = CRZ_deflateReset(&(s->stream)) ;
1226 0 0         if (RETVAL == Z_OK) {
1227 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1228             }
1229             OUTPUT:
1230             RETVAL
1231              
1232             DualType
1233             deflate (s, buf, output)
1234             Compress::Raw::Zlib::deflateStream s
1235             SV * buf
1236             SV * output
1237             uInt cur_length = NO_INIT
1238             uInt increment = NO_INIT
1239             uInt prefix = NO_INIT
1240             int RETVAL = 0;
1241             uLong bufinc = NO_INIT
1242             STRLEN origlen = NO_INIT
1243             CODE:
1244 243           bufinc = s->bufsize;
1245              
1246             /*
1247             if (trace) {
1248             printf("\nDEFLATE Before deRef of input buffer\n");
1249             printf("\nPerl_sv_dump\n");
1250             Perl_sv_dump(buf);
1251             printf("\n");
1252             }
1253             */
1254              
1255             /* If the input buffer is a reference, dereference it */
1256 243           buf = deRef(buf, "deflate") ;
1257              
1258             /* initialise the input buffer */
1259             #ifdef UTF8_AVAILABLE
1260 243 50         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
1261 0           croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
1262             #endif
1263 243           s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
1264 243           s->stream.avail_in = origlen;
1265              
1266             if (trace) {
1267             printf("\nDEFLATE Starts\n");
1268             DispStream(s, "START");
1269             /*
1270             printf("\nPerl_sv_dump\n");
1271             Perl_sv_dump(buf);
1272             printf("\n");
1273             */
1274             }
1275              
1276 243 50         if (s->flags & FLAG_CRC32)
1277 0           s->crc32 = CRZ_crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
1278              
1279 243 50         if (s->flags & FLAG_ADLER32)
1280 0           s->adler32 = CRZ_adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
1281              
1282             /* and retrieve the output buffer */
1283 243           output = deRef_l(output, "deflate") ;
1284             #ifdef UTF8_AVAILABLE
1285 243 50         if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
    0          
    0          
1286 0           croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
1287             #endif
1288              
1289 243 100         if((s->flags & FLAG_APPEND) == FLAG_APPEND) {
1290 163 100         SvOOK_off(output);
1291             } else {
1292 80           SvCUR_set(output, 0);
1293             }
1294 243           prefix = cur_length = SvCUR(output) ;
1295 243           s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
1296 243           increment = SvLEN(output) - cur_length;
1297 243           s->stream.avail_out = increment;
1298             #ifdef SETP_BYTE
1299             /* Check for saved output from deflateParams */
1300             if (s->deflateParams_out_valid) {
1301             *(s->stream.next_out) = s->deflateParams_out_byte;
1302             ++ s->stream.next_out;
1303             -- s->stream.avail_out ;
1304             s->deflateParams_out_valid = FALSE;
1305             }
1306             #else
1307             /* Check for saved output from deflateParams */
1308 243 100         if (s->deflateParams_out_length) {
1309 3           uLong plen = s->deflateParams_out_length ;
1310             /* printf("Copy %lu bytes saved data\n", plen); */
1311 3 50         if (s->stream.avail_out < plen) {
1312             /* printf("GROW from %d to %lu\n", s->stream.avail_out,
1313             SvLEN(output) + plen - s->stream.avail_out); */
1314 3           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1315 3           s->stream.next_out += cur_length;
1316             }
1317              
1318 3           Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;
1319 3           cur_length += plen;
1320 3           SvCUR_set(output, cur_length);
1321 3           s->stream.next_out += plen ;
1322 3           s->stream.avail_out = SvLEN(output) - cur_length ;
1323 3           increment = s->stream.avail_out;
1324              
1325 3           s->deflateParams_out_length = 0;
1326 3           Safefree(s->deflateParams_out_buffer);
1327 3           s->deflateParams_out_buffer = NULL;
1328             }
1329             #endif
1330 243           RETVAL = Z_OK ;
1331 491 100         while (s->stream.avail_in != 0) {
1332              
1333 248 100         if (s->stream.avail_out == 0) {
1334             /* out of space in the output buffer so make it bigger */
1335 5           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
1336 5           cur_length += increment ;
1337 5           s->stream.next_out += cur_length ;
1338 5           increment = bufinc ;
1339 5           s->stream.avail_out = increment;
1340 5           bufinc *= 2 ;
1341             }
1342              
1343             if (trace) {
1344             printf("DEFLATE Avail In %d, Out %d\n", s->stream.avail_in, s->stream.avail_out);
1345             DispStream(s, "BEFORE");
1346             /* Perl_sv_dump(output); */
1347             }
1348              
1349 248           RETVAL = CRZ_deflate(&(s->stream), Z_NO_FLUSH);
1350             /*
1351             if (RETVAL != Z_STREAM_ERROR) {
1352             int done = increment - s->stream.avail_out ;
1353             printf("std DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
1354             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out, done);
1355             }
1356             */
1357              
1358             if (trace) {
1359             printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1360             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
1361             DispStream(s, "AFTER");
1362             }
1363              
1364 248 50         if (RETVAL != Z_OK)
1365 0           break;
1366             }
1367              
1368 243           s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1369 243           s->uncompressedBytes += origlen - s->stream.avail_in ;
1370              
1371 243           s->last_error = RETVAL ;
1372 243 50         if (RETVAL == Z_OK) {
1373 243           SvPOK_only(output);
1374 243           SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1375 243 100         SvSETMAGIC(output);
1376             }
1377             OUTPUT:
1378             RETVAL
1379              
1380              
1381             void
1382             DESTROY(s)
1383             Compress::Raw::Zlib::deflateStream s
1384             CODE:
1385             if (trace)
1386             printf("Compress::Raw::Zlib::deflateStream::DESTROY %p\n", s);
1387 33           CRZ_deflateEnd(&s->stream) ;
1388 33 50         if (s->dictionary)
1389 0           SvREFCNT_dec(s->dictionary) ;
1390             #ifndef SETP_BYTE
1391 33 50         if (s->deflateParams_out_buffer)
1392 0           Safefree(s->deflateParams_out_buffer);
1393             #endif
1394 33           Safefree(s) ;
1395              
1396              
1397             DualType
1398             flush(s, output, f=Z_FINISH)
1399             Compress::Raw::Zlib::deflateStream s
1400             SV * output
1401             int f
1402             uInt cur_length = NO_INIT
1403             uInt increment = NO_INIT
1404             uInt prefix = NO_INIT
1405             uLong bufinc = NO_INIT
1406             uLong availableout = NO_INIT
1407             CODE:
1408 36           bufinc = s->bufsize;
1409              
1410              
1411              
1412             /* retrieve the output buffer */
1413 36           output = deRef_l(output, "flush") ;
1414             #ifdef UTF8_AVAILABLE
1415 36 50         if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
    0          
    0          
1416 0           croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
1417             #endif
1418 36 100         if((s->flags & FLAG_APPEND) == FLAG_APPEND) {
1419 22 100         SvOOK_off(output);
1420             } else {
1421 14           SvCUR_set(output, 0);
1422             }
1423 36           prefix = cur_length = SvCUR(output) ;
1424 36           s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
1425 36           increment = SvLEN(output) - cur_length;
1426 36           s->stream.avail_out = increment;
1427             #ifdef SETP_BYTE
1428             /* Check for saved output from deflateParams */
1429             if (s->deflateParams_out_valid) {
1430             *(s->stream.next_out) = s->deflateParams_out_byte;
1431             ++ s->stream.next_out;
1432             -- s->stream.avail_out ;
1433             s->deflateParams_out_valid = FALSE;
1434             }
1435             #else
1436             /* Check for saved output from deflateParams */
1437 36 50         if (s->deflateParams_out_length) {
1438 0           uLong plen = s->deflateParams_out_length ;
1439             /* printf("Copy %lu bytes saved data\n", plen); */
1440 0 0         if (s->stream.avail_out < plen) {
1441             /* printf("GROW from %d to %lu\n", s->stream.avail_out,
1442             SvLEN(output) + plen - s->stream.avail_out); */
1443 0           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1444 0           s->stream.next_out += cur_length;
1445             }
1446              
1447 0           Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;
1448 0           cur_length += plen;
1449 0           SvCUR_set(output, cur_length);
1450 0           s->stream.next_out += plen ;
1451 0           s->stream.avail_out = SvLEN(output) - cur_length ;
1452 0           increment = s->stream.avail_out;
1453              
1454 0           s->deflateParams_out_length = 0;
1455 0           Safefree(s->deflateParams_out_buffer);
1456 0           s->deflateParams_out_buffer = NULL;
1457             }
1458             #endif
1459              
1460             for (;;) {
1461 94 100         if (s->stream.avail_out == 0) {
1462             /* consumed all the available output, so extend it */
1463 58           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
1464 58           cur_length += increment ;
1465 58           s->stream.next_out += cur_length ;
1466 58           increment = bufinc ;
1467 58           s->stream.avail_out = increment;
1468 58           bufinc *= 2 ;
1469             }
1470              
1471 94           availableout = s->stream.avail_out ;
1472              
1473             if (trace) {
1474             printf("flush (%d) DEFLATE Avail In %d, Out %d\n", f, s->stream.avail_in, s->stream.avail_out);
1475             DispStream(s, "BEFORE");
1476             /* Perl_sv_dump(output); */
1477             }
1478              
1479 94           RETVAL = CRZ_deflate(&(s->stream), f);
1480             /*
1481             if (RETVAL != Z_STREAM_ERROR) {
1482             int done = availableout - s->stream.avail_out ;
1483             printf("flush DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
1484             GetErrorString(RETVAL), s->stream.avail_in,
1485             s->stream.avail_out, done);
1486             }
1487             */
1488              
1489             if (trace) {
1490             printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL,
1491             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
1492             DispStream(s, "AFTER");
1493             }
1494              
1495             /* Ignore the second of two consecutive flushes: */
1496 94 100         if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR)
    50          
1497 2           RETVAL = Z_OK;
1498              
1499             /* deflate has finished flushing only when it hasn't used up
1500             * all the available space in the output buffer:
1501             */
1502 94 100         if (s->stream.avail_out != 0 || RETVAL != Z_OK )
    50          
1503             break;
1504             }
1505              
1506 36 100         RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1507 36           s->last_error = RETVAL ;
1508              
1509 36           s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1510              
1511 36 50         if (RETVAL == Z_OK) {
1512 36           SvPOK_only(output);
1513 36           SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1514 36 100         SvSETMAGIC(output);
1515             }
1516             OUTPUT:
1517             RETVAL
1518              
1519              
1520             DualType
1521             _deflateParams(s, flags, level, strategy, bufsize)
1522             Compress::Raw::Zlib::deflateStream s
1523             int flags
1524             int level
1525             int strategy
1526             uLong bufsize
1527             bool changed = FALSE;
1528             CODE:
1529             /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1530             printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1531 4 100         if (flags & 1 && level != s->Level) {
    50          
1532 3           s->Level = level ;
1533 3           changed = TRUE;
1534             }
1535 4 100         if (flags & 2 && strategy != s->Strategy) {
    50          
1536 3           s->Strategy = strategy ;
1537 3           changed = TRUE;
1538             }
1539 4 100         if (flags & 4)
1540 2           s->bufsize = bufsize;
1541 4 50         if (changed) {
1542             #ifdef SETP_BYTE
1543             s->stream.avail_in = 0;
1544             s->stream.next_out = &(s->deflateParams_out_byte) ;
1545             s->stream.avail_out = 1;
1546             RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1547             s->deflateParams_out_valid =
1548             (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1549             #else
1550             /* printf("Level %d Strategy %d, Prev Len %d\n",
1551             s->Level, s->Strategy, s->deflateParams_out_length); */
1552 4           RETVAL = flushParams(s);
1553             #endif
1554             }
1555             else
1556 0           RETVAL = Z_OK;
1557             OUTPUT:
1558             RETVAL
1559              
1560              
1561             int
1562             get_Level(s)
1563             Compress::Raw::Zlib::deflateStream s
1564             CODE:
1565 6 50         RETVAL = s->Level ;
1566             OUTPUT:
1567             RETVAL
1568              
1569             int
1570             get_Strategy(s)
1571             Compress::Raw::Zlib::deflateStream s
1572             CODE:
1573 6 50         RETVAL = s->Strategy ;
1574             OUTPUT:
1575             RETVAL
1576              
1577              
1578             uLong
1579             get_Bufsize(s)
1580             Compress::Raw::Zlib::deflateStream s
1581             CODE:
1582 0 0         RETVAL = s->bufsize ;
1583             OUTPUT:
1584             RETVAL
1585              
1586              
1587             int
1588             status(s)
1589             Compress::Raw::Zlib::deflateStream s
1590             CODE:
1591 0 0         RETVAL = s->last_error ;
1592             OUTPUT:
1593             RETVAL
1594              
1595             uLong
1596             crc32(s)
1597             Compress::Raw::Zlib::deflateStream s
1598             CODE:
1599 0 0         RETVAL = s->crc32 ;
1600             OUTPUT:
1601             RETVAL
1602              
1603             uLong
1604             dict_adler(s)
1605             Compress::Raw::Zlib::deflateStream s
1606             CODE:
1607 2 50         RETVAL = s->dict_adler ;
1608             OUTPUT:
1609             RETVAL
1610              
1611             uLong
1612             adler32(s)
1613             Compress::Raw::Zlib::deflateStream s
1614             CODE:
1615 0 0         RETVAL = s->adler32 ;
1616             OUTPUT:
1617             RETVAL
1618              
1619             uLong
1620             compressedBytes(s)
1621             Compress::Raw::Zlib::deflateStream s
1622             CODE:
1623 0 0         RETVAL = s->compressedBytes;
1624             OUTPUT:
1625             RETVAL
1626              
1627             uLong
1628             uncompressedBytes(s)
1629             Compress::Raw::Zlib::deflateStream s
1630             CODE:
1631 0 0         RETVAL = s->uncompressedBytes;
1632             OUTPUT:
1633             RETVAL
1634              
1635             uLong
1636             total_in(s)
1637             Compress::Raw::Zlib::deflateStream s
1638             CODE:
1639 4 50         RETVAL = s->stream.total_in ;
1640             OUTPUT:
1641             RETVAL
1642              
1643             uLong
1644             total_out(s)
1645             Compress::Raw::Zlib::deflateStream s
1646             CODE:
1647 4 50         RETVAL = s->stream.total_out ;
1648             OUTPUT:
1649             RETVAL
1650              
1651             char*
1652             msg(s)
1653             Compress::Raw::Zlib::deflateStream s
1654             CODE:
1655 4           RETVAL = (char*)s->stream.msg;
1656             OUTPUT:
1657             RETVAL
1658              
1659             int
1660             deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1661             Compress::Raw::Zlib::deflateStream s
1662             int good_length
1663             int max_lazy
1664             int nice_length
1665             int max_chain
1666             CODE:
1667             #ifndef AT_LEAST_ZLIB_1_2_2_3
1668             good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1669             nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1670             croak("deflateTune needs zlib 1.2.2.3 or better");
1671             #else
1672 0           RETVAL = CRZ_deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1673             #endif
1674             OUTPUT:
1675             RETVAL
1676              
1677              
1678             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1679              
1680             void
1681             DispStream(s, message=NULL)
1682             Compress::Raw::Zlib::inflateStream s
1683             const char * message
1684              
1685             DualType
1686             inflateReset(s)
1687             Compress::Raw::Zlib::inflateStream s
1688             CODE:
1689 0           RETVAL = CRZ_inflateReset(&(s->stream)) ;
1690 0 0         if (RETVAL == Z_OK) {
1691 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1692             }
1693             OUTPUT:
1694             RETVAL
1695              
1696             DualType
1697             inflate (s, buf, output, eof=FALSE)
1698             Compress::Raw::Zlib::inflateStream s
1699             SV * buf
1700             SV * output
1701             bool eof
1702             uInt cur_length = 0;
1703             uInt prefix_length = 0;
1704             int increment = 0;
1705             uLong bufinc = NO_INIT
1706             STRLEN na = NO_INIT ;
1707             PREINIT:
1708             #ifdef UTF8_AVAILABLE
1709 50548 50         bool out_utf8 = FALSE;
1710             #endif
1711             STRLEN origlen;
1712             CODE:
1713 50548           bufinc = s->bufsize;
1714             /* If the buffer is a reference, dereference it */
1715 50548           buf = deRef(buf, "inflate") ;
1716              
1717 50548 100         if (s->flags & FLAG_CONSUME_INPUT) {
1718 50540 100         if (SvREADONLY(buf))
1719 1           croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1720 50539           SvPV_force(buf, na);
1721             }
1722             #ifdef UTF8_AVAILABLE
1723 50547 50         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
1724 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1725             #endif
1726              
1727             /* initialise the input buffer */
1728 50547           s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
1729 50547           s->stream.avail_in = origlen ;
1730              
1731             /* and retrieve the output buffer */
1732 50547           output = deRef_l(output, "inflate") ;
1733             #ifdef UTF8_AVAILABLE
1734 50547 50         if (DO_UTF8(output))
    0          
1735 0           out_utf8 = TRUE ;
1736 50547 50         if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
    0          
    0          
1737 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1738             #endif
1739 50547 100         if((s->flags & FLAG_APPEND) == FLAG_APPEND) {
1740 50414 100         SvOOK_off(output);
1741             } else {
1742 133           SvCUR_set(output, 0);
1743             }
1744              
1745             /* Assume no output buffer - the code below will update if there is any available */
1746 50547           s->stream.avail_out = 0;
1747              
1748              
1749 50547 50         if (SvLEN(output)) {
1750 50547           prefix_length = cur_length = SvCUR(output) ;
1751              
1752 50547 100         if (s->flags & FLAG_LIMIT_OUTPUT && SvLEN(output) - cur_length - 1 < bufinc)
    100          
1753             {
1754 136           Sv_Grow(output, bufinc + cur_length + 1) ;
1755             }
1756              
1757             /* Only setup the stream output pointers if there is spare
1758             capacity in the outout SV
1759             */
1760 50547 50         if (SvLEN(output) > cur_length + 1)
1761             {
1762 50547           s->stream.next_out = (Bytef*) SvPV_nomg_nolen(output) + cur_length;
1763 50547           increment = SvLEN(output) - cur_length - 1;
1764 50547           s->stream.avail_out = increment;
1765             }
1766             }
1767              
1768              
1769 50547           s->bytesInflated = 0;
1770              
1771 50547           RETVAL = Z_OK;
1772              
1773 100947 50         while (RETVAL == Z_OK) {
1774 100947 100         if (s->stream.avail_out == 0) {
1775             /* out of space in the output buffer so make it bigger */
1776 58           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc +1) ;
1777 58           cur_length += increment ;
1778 58           s->stream.next_out += cur_length ;
1779 58           increment = bufinc ;
1780 58           s->stream.avail_out = increment;
1781 58           bufinc *= 2 ;
1782             }
1783              
1784             /* printf("INFLATE Availl In %d, Out %d\n", s->stream.avail_in,
1785             s->stream.avail_out);
1786             DispStream(s, "BEFORE");
1787             Perl_sv_dump(output); */
1788 100947           RETVAL = CRZ_inflate(&(s->stream), Z_SYNC_FLUSH);
1789             /* printf("INFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1790             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); */
1791              
1792              
1793 100947 100         if (RETVAL == Z_NEED_DICT && s->dictionary) {
    50          
1794             STRLEN dlen;
1795 1           const Bytef* b = (const Bytef*)SvPV(s->dictionary, dlen) ;
1796 1           s->dict_adler = s->stream.adler ;
1797 1           RETVAL = CRZ_inflateSetDictionary(&(s->stream),
1798             b, dlen);
1799 1 50         if (RETVAL == Z_OK)
1800 1           continue;
1801             }
1802              
1803 100946 100         if (s->flags & FLAG_LIMIT_OUTPUT &&
    100          
1804 7 50         (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) {
1805 133 50         if (s->stream.avail_out == 0)
1806 133           RETVAL = Z_BUF_ERROR;
1807 133           break;
1808             }
1809 100813 100         if (s->flags & FLAG_LIMIT_OUTPUT &&
    50          
1810 7 50         (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR ))
1811             break;
1812              
1813 100813 50         if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
    50          
    100          
1814 100810 100         RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1815             break ;
1816              
1817 100771 100         if (RETVAL == Z_BUF_ERROR) {
1818 50372 50         if (s->stream.avail_out == 0)
1819 0           continue ;
1820 50372 50         if (s->stream.avail_in == 0) {
1821 50372           RETVAL = Z_OK ;
1822 50372           break ;
1823             }
1824             }
1825             }
1826             #ifdef NEED_DUMMY_BYTE_AT_END
1827             if (eof && RETVAL == Z_OK && (s->flags & FLAG_LIMIT_OUTPUT) == 0) {
1828             Bytef* nextIn = (Bytef*)s->stream.next_in;
1829             uInt availIn = s->stream.avail_in;
1830             s->stream.next_in = (Bytef*) " ";
1831             s->stream.avail_in = 1;
1832             if (s->stream.avail_out == 0) {
1833             /* out of space in the output buffer so make it bigger */
1834             s->stream.next_out = Sv_Grow(output, SvLEN(output) + bufinc) ;
1835             cur_length += increment ;
1836             s->stream.next_out += cur_length ;
1837             increment = bufinc ;
1838             s->stream.avail_out = increment;
1839             bufinc *= 2 ;
1840             }
1841             RETVAL = CRZ_inflate(&(s->stream), Z_SYNC_FLUSH);
1842             s->stream.next_in = nextIn ;
1843             s->stream.avail_in = availIn ;
1844             }
1845             #else
1846             PERL_UNUSED_VAR(eof);
1847             #endif
1848              
1849 50547           s->last_error = RETVAL ;
1850 50547 100         if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_BUF_ERROR || RETVAL == Z_DATA_ERROR) {
    100          
    100          
    50          
1851             unsigned in ;
1852              
1853 50547           s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1854 50547           s->uncompressedBytes += s->bytesInflated ;
1855 50547           s->compressedBytes += origlen - s->stream.avail_in ;
1856              
1857 50547           SvPOK_only(output);
1858 50547           SvCUR_set(output, prefix_length + s->bytesInflated) ;
1859 50547           *SvEND(output) = '\0';
1860             #ifdef UTF8_AVAILABLE
1861 50547 50         if (out_utf8)
1862 0           sv_utf8_upgrade(output);
1863             #endif
1864 50547 100         SvSETMAGIC(output);
1865              
1866 50547 50         if (s->flags & FLAG_CRC32 )
1867 0           s->crc32 = CRZ_crc32(s->crc32,
1868 0           (const Bytef*)SvPVX(output)+prefix_length,
1869 0           SvCUR(output)-prefix_length) ;
1870              
1871 50547 50         if (s->flags & FLAG_ADLER32)
1872 0           s->adler32 = CRZ_adler32(s->adler32,
1873 0           (const Bytef*)SvPVX(output)+prefix_length,
1874 0           SvCUR(output)-prefix_length) ;
1875              
1876             /* fix the input buffer */
1877 50547 100         if (s->flags & FLAG_CONSUME_INPUT || s->flags & FLAG_LIMIT_OUTPUT) {
    50          
1878 50539           in = s->stream.avail_in ;
1879 50539           SvCUR_set(buf, in) ;
1880 50539 100         if (in)
1881 139           Move(s->stream.next_in, SvPVX(buf), in, char) ;
1882 50539           *SvEND(buf) = '\0';
1883 50539 100         SvSETMAGIC(buf);
1884             }
1885              
1886             }
1887             OUTPUT:
1888             RETVAL
1889              
1890             uLong
1891             inflateCount(s)
1892             Compress::Raw::Zlib::inflateStream s
1893             CODE:
1894 0 0         RETVAL = s->bytesInflated;
1895             OUTPUT:
1896             RETVAL
1897              
1898             uLong
1899             compressedBytes(s)
1900             Compress::Raw::Zlib::inflateStream s
1901             CODE:
1902 0 0         RETVAL = s->compressedBytes;
1903             OUTPUT:
1904             RETVAL
1905              
1906             uLong
1907             uncompressedBytes(s)
1908             Compress::Raw::Zlib::inflateStream s
1909             CODE:
1910 0 0         RETVAL = s->uncompressedBytes;
1911             OUTPUT:
1912             RETVAL
1913              
1914              
1915             DualType
1916             inflateSync (s, buf)
1917             Compress::Raw::Zlib::inflateStream s
1918             SV * buf
1919             CODE:
1920              
1921             /* If the buffer is a reference, dereference it */
1922 170           buf = deRef(buf, "inflateSync") ;
1923             #ifdef UTF8_AVAILABLE
1924 170 50         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
1925 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1926             #endif
1927              
1928             /* initialise the input buffer */
1929 170           s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
1930 170           s->stream.avail_in = SvCUR(buf) ;
1931              
1932             /* inflateSync doesn't create any output */
1933 170           s->stream.next_out = (Bytef*) NULL;
1934 170           s->stream.avail_out = 0;
1935              
1936 170           RETVAL = CRZ_inflateSync(&(s->stream));
1937 170           s->last_error = RETVAL ;
1938              
1939             /* fix the input buffer */
1940             {
1941 170           unsigned in = s->stream.avail_in ;
1942 170           SvCUR_set(buf, in) ;
1943 170 100         if (in)
1944 1           Move(s->stream.next_in, SvPVX(buf), in, char) ;
1945 170           *SvEND(buf) = '\0';
1946 170 50         SvSETMAGIC(buf);
1947             }
1948             OUTPUT:
1949             RETVAL
1950              
1951             void
1952             DESTROY(s)
1953             Compress::Raw::Zlib::inflateStream s
1954             CODE:
1955 44           CRZ_inflateEnd(&s->stream) ;
1956 44 100         if (s->dictionary)
1957 2           SvREFCNT_dec(s->dictionary) ;
1958             #ifndef SETP_BYTE
1959 44 50         if (s->deflateParams_out_buffer)
1960 0           Safefree(s->deflateParams_out_buffer);
1961             #endif
1962             #ifdef MAGIC_APPEND
1963 44 50         if (s->window)
1964 0           Safefree(s->window);
1965             #endif
1966 44           Safefree(s) ;
1967              
1968              
1969             uLong
1970             status(s)
1971             Compress::Raw::Zlib::inflateStream s
1972             CODE:
1973 0 0         RETVAL = s->last_error ;
1974             OUTPUT:
1975             RETVAL
1976              
1977             uLong
1978             crc32(s)
1979             Compress::Raw::Zlib::inflateStream s
1980             CODE:
1981 0 0         RETVAL = s->crc32 ;
1982             OUTPUT:
1983             RETVAL
1984              
1985             uLong
1986             dict_adler(s)
1987             Compress::Raw::Zlib::inflateStream s
1988             CODE:
1989 2 50         RETVAL = s->dict_adler ;
1990             OUTPUT:
1991             RETVAL
1992              
1993             uLong
1994             total_in(s)
1995             Compress::Raw::Zlib::inflateStream s
1996             CODE:
1997 16 100         RETVAL = s->stream.total_in ;
1998             OUTPUT:
1999             RETVAL
2000              
2001             uLong
2002             adler32(s)
2003             Compress::Raw::Zlib::inflateStream s
2004             CODE:
2005 0 0         RETVAL = s->adler32 ;
2006             OUTPUT:
2007             RETVAL
2008              
2009             uLong
2010             total_out(s)
2011             Compress::Raw::Zlib::inflateStream s
2012             CODE:
2013 22 100         RETVAL = s->stream.total_out ;
2014             OUTPUT:
2015             RETVAL
2016              
2017             char*
2018             msg(s)
2019             Compress::Raw::Zlib::inflateStream s
2020             CODE:
2021 16           RETVAL = (char*)s->stream.msg;
2022             OUTPUT:
2023             RETVAL
2024              
2025              
2026             uLong
2027             get_Bufsize(s)
2028             Compress::Raw::Zlib::inflateStream s
2029             CODE:
2030 0 0         RETVAL = s->bufsize ;
2031             OUTPUT:
2032             RETVAL
2033              
2034             bool
2035             set_Append(s, mode)
2036             Compress::Raw::Zlib::inflateStream s
2037             bool mode
2038             CODE:
2039 0           RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
2040 0 0         if (mode)
2041 0           s->flags |= FLAG_APPEND ;
2042             else
2043 0           s->flags &= ~FLAG_APPEND ;
2044             OUTPUT:
2045             RETVAL
2046              
2047             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
2048              
2049             void
2050             DESTROY(s)
2051             Compress::Raw::Zlib::inflateScanStream s
2052             CODE:
2053 1           CRZ_inflateEnd(&s->stream) ;
2054 1 50         if (s->dictionary)
2055 0           SvREFCNT_dec(s->dictionary) ;
2056             #ifndef SETP_BYTE
2057 1 50         if (s->deflateParams_out_buffer)
2058 0           Safefree(s->deflateParams_out_buffer);
2059             #endif
2060             #ifdef MAGIC_APPEND
2061 1 50         if (s->window)
2062 1           Safefree(s->window);
2063             #endif
2064 1           Safefree(s) ;
2065              
2066             void
2067             DispStream(s, message=NULL)
2068             Compress::Raw::Zlib::inflateScanStream s
2069             const char * message
2070              
2071             DualType
2072             inflateReset(s)
2073             Compress::Raw::Zlib::inflateScanStream s
2074             CODE:
2075 0           RETVAL = CRZ_inflateReset(&(s->stream)) ;
2076 0 0         if (RETVAL == Z_OK) {
2077 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
2078             }
2079             OUTPUT:
2080             RETVAL
2081              
2082             DualType
2083             scan(s, buf, out=NULL, eof=FALSE)
2084             Compress::Raw::Zlib::inflateScanStream s
2085             SV * buf
2086             SV * out
2087             bool eof
2088             bool eof_mode = FALSE;
2089             int start_len = NO_INIT
2090             CODE:
2091             PERL_UNUSED_VAR(out);
2092             PERL_UNUSED_VAR(eof);
2093             /* If the input buffer is a reference, dereference it */
2094             #ifndef MAGIC_APPEND
2095             buf = buf;
2096             croak("scan needs zlib 1.2.1 or better");
2097             #else
2098 0           buf = deRef(buf, "inflateScan") ;
2099             #ifdef UTF8_AVAILABLE
2100 0 0         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
2101 0           croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
2102             #endif
2103             /* initialise the input buffer */
2104 0           s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
2105 0           s->stream.avail_in = SvCUR(buf) ;
2106 0           start_len = s->stream.avail_in ;
2107 0           s->bytesInflated = 0 ;
2108             do
2109             {
2110 0 0         if (s->stream.avail_in == 0) {
2111 0           RETVAL = Z_OK ;
2112 0           break ;
2113             }
2114              
2115             /* set up output to next available section of sliding window */
2116 0           s->stream.avail_out = WINDOW_SIZE - s->window_have;
2117 0           s->stream.next_out = s->window + s->window_have;
2118              
2119             /* DispStream(s, "before inflate\n"); */
2120              
2121             /* inflate and check for errors */
2122 0           RETVAL = CRZ_inflate(&(s->stream), Z_BLOCK);
2123              
2124 0 0         if (start_len > 1 && ! eof_mode)
    0          
2125 0           s->window_lastByte = *(s->stream.next_in - 1 ) ;
2126              
2127 0 0         if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
    0          
    0          
2128             RETVAL == Z_DATA_ERROR )
2129             break ;
2130              
2131 0 0         if (s->flags & FLAG_CRC32 )
2132 0           s->crc32 = CRZ_crc32(s->crc32, s->window + s->window_have,
2133 0           WINDOW_SIZE - s->window_have - s->stream.avail_out);
2134              
2135 0 0         if (s->flags & FLAG_ADLER32)
2136 0           s->adler32 = CRZ_adler32(s->adler32, s->window + s->window_have,
2137 0           WINDOW_SIZE - s->window_have - s->stream.avail_out);
2138              
2139 0           s->uncompressedBytes =
2140 0           s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
2141              
2142 0 0         if (s->stream.avail_out)
2143 0           s->window_have = WINDOW_SIZE - s->stream.avail_out;
2144             else {
2145 0           s->window_have = 0;
2146 0           s->window_full = 1;
2147             }
2148              
2149             /* process end of block */
2150 0 0         if (s->stream.data_type & 128) {
2151 0 0         if (s->stream.data_type & 64) {
2152 0           s->window_left = s->stream.data_type & 0x1f;
2153             }
2154             else {
2155 0           s->window_lastbit = s->stream.data_type & 0x1f;
2156 0           s->lastBlockOffset = s->stream.total_in;
2157             }
2158             }
2159              
2160 0 0         } while (RETVAL != Z_STREAM_END);
2161              
2162 0           s->last_error = RETVAL ;
2163 0           s->window_lastoff = s->stream.total_in ;
2164 0           s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
2165              
2166 0 0         if (RETVAL == Z_STREAM_END)
2167             {
2168 0           s->matchedEndBlock = 1 ;
2169              
2170             /* save the location of the end of the compressed data */
2171 0           s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
2172 0           s->window_endOffset = s->stream.total_in ;
2173 0 0         if (s->window_left)
2174             {
2175 0           -- s->window_endOffset ;
2176             }
2177              
2178             /* if window wrapped, build dictionary from window by rotating */
2179 0 0         if (s->window_full) {
2180 0           rotate(s->window, WINDOW_SIZE, s->window_have);
2181 0           s->window_have = WINDOW_SIZE;
2182             }
2183              
2184             /* if (s->flags & FLAG_CONSUME_INPUT) { */
2185             if (1) {
2186 0           unsigned in = s->stream.avail_in ;
2187 0           SvCUR_set(buf, in) ;
2188 0 0         if (in)
2189 0           Move(s->stream.next_in, SvPVX(buf), in, char) ;
2190 0           *SvEND(buf) = '\0';
2191 0 0         SvSETMAGIC(buf);
2192             }
2193             }
2194             #endif
2195             OUTPUT:
2196             RETVAL
2197              
2198              
2199             uLong
2200             getEndOffset(s)
2201             Compress::Raw::Zlib::inflateScanStream s
2202             CODE:
2203             #ifndef MAGIC_APPEND
2204             croak("getEndOffset needs zlib 1.2.1 or better");
2205             #else
2206 0 0         RETVAL = s->window_endOffset;
2207             #endif
2208             OUTPUT:
2209             RETVAL
2210              
2211             uLong
2212             inflateCount(s)
2213             Compress::Raw::Zlib::inflateScanStream s
2214             CODE:
2215             #ifndef MAGIC_APPEND
2216             croak("inflateCount needs zlib 1.2.1 or better");
2217             #else
2218 0 0         RETVAL = s->bytesInflated;
2219             #endif
2220             OUTPUT:
2221             RETVAL
2222              
2223             uLong
2224             compressedBytes(s)
2225             Compress::Raw::Zlib::inflateScanStream s
2226             CODE:
2227 0 0         RETVAL = s->compressedBytes;
2228             OUTPUT:
2229             RETVAL
2230              
2231             uLong
2232             uncompressedBytes(s)
2233             Compress::Raw::Zlib::inflateScanStream s
2234             CODE:
2235 0 0         RETVAL = s->uncompressedBytes;
2236             OUTPUT:
2237             RETVAL
2238              
2239              
2240             uLong
2241             getLastBlockOffset(s)
2242             Compress::Raw::Zlib::inflateScanStream s
2243             CODE:
2244             #ifndef MAGIC_APPEND
2245             croak("getLastBlockOffset needs zlib 1.2.1 or better");
2246             #else
2247 0 0         RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
2248             #endif
2249             OUTPUT:
2250             RETVAL
2251              
2252             uLong
2253             getLastBufferOffset(s)
2254             Compress::Raw::Zlib::inflateScanStream s
2255             CODE:
2256             #ifndef MAGIC_APPEND
2257             croak("getLastBufferOffset needs zlib 1.2.1 or better");
2258             #else
2259 0 0         RETVAL = s->window_lastoff;
2260             #endif
2261             OUTPUT:
2262             RETVAL
2263              
2264             void
2265             resetLastBlockByte(s, byte)
2266             Compress::Raw::Zlib::inflateScanStream s
2267             unsigned char* byte
2268             CODE:
2269             #ifndef MAGIC_APPEND
2270             croak("resetLastBlockByte needs zlib 1.2.1 or better");
2271             #else
2272 1 50         if (byte != NULL)
2273 0           *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
2274             #endif
2275              
2276              
2277             void
2278             _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
2279             Compress::Raw::Zlib::inflateScanStream inf_s
2280             int flags
2281             int level
2282             int method
2283             int windowBits
2284             int memLevel
2285             int strategy
2286             uLong bufsize
2287             PPCODE:
2288             {
2289             #ifndef MAGIC_APPEND
2290             flags = flags;
2291             level = level ;
2292             method = method;
2293             windowBits = windowBits;
2294             memLevel = memLevel;
2295             strategy = strategy;
2296             bufsize= bufsize;
2297             croak("_createDeflateStream needs zlib 1.2.1 or better");
2298             #else
2299             int err ;
2300             deflateStream s ;
2301              
2302             if (trace)
2303             warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
2304             level, method, windowBits, memLevel, strategy, bufsize) ;
2305 0 0         if ((s = InitStream() )) {
2306              
2307 0           s->Level = level;
2308 0           s->Method = method;
2309 0           s->WindowBits = windowBits;
2310 0           s->MemLevel = memLevel;
2311 0           s->Strategy = strategy;
2312              
2313 0           err = CRZ_deflateInit2(&(s->stream), level,
2314             method, windowBits, memLevel, strategy);
2315              
2316 0 0         if (err == Z_OK) {
2317 0           err = CRZ_deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
2318 0           s->dict_adler = s->stream.adler ;
2319             }
2320              
2321 0 0         if (err != Z_OK) {
2322 0           Safefree(s) ;
2323 0           s = NULL ;
2324             }
2325             else {
2326 0           PostInitStream(s, flags, bufsize, windowBits) ;
2327 0           s->crc32 = inf_s->crc32;
2328 0           s->adler32 = inf_s->adler32;
2329 0           s->stream.adler = inf_s->stream.adler ;
2330             /* s->stream.total_out = inf_s->bytesInflated ; */
2331 0           s->stream.total_in = inf_s->stream.total_out ;
2332 0 0         if (inf_s->window_left) {
2333             /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
2334 0           CRZ_deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
2335             }
2336             }
2337             }
2338             else
2339 0           err = Z_MEM_ERROR ;
2340              
2341 0 0         XPUSHs(sv_setref_pv(sv_newmortal(),
2342             "Compress::Raw::Zlib::deflateStream", (void*)s));
2343 0 0         if (GIMME_V == G_ARRAY) {
2344 0           SV * sv = sv_2mortal(newSViv(err)) ;
2345 0 0         setDUALstatus(sv, err);
2346 0 0         XPUSHs(sv) ;
2347             }
2348             #endif
2349             }
2350              
2351             DualType
2352             status(s)
2353             Compress::Raw::Zlib::inflateScanStream s
2354             CODE:
2355 0           RETVAL = s->last_error ;
2356             OUTPUT:
2357             RETVAL
2358              
2359             uLong
2360             crc32(s)
2361             Compress::Raw::Zlib::inflateScanStream s
2362             CODE:
2363 0 0         RETVAL = s->crc32 ;
2364             OUTPUT:
2365             RETVAL
2366              
2367              
2368             uLong
2369             adler32(s)
2370             Compress::Raw::Zlib::inflateScanStream s
2371             CODE:
2372 0 0         RETVAL = s->adler32 ;
2373             OUTPUT:
2374             RETVAL