File Coverage

Zlib.xs
Criterion Covered Total %
statement 332 609 54.5
branch 211 494 42.7
condition n/a
subroutine n/a
pod n/a
total 543 1103 49.2


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