File Coverage

Zlib.xs
Criterion Covered Total %
statement 332 610 54.4
branch 211 494 42.7
condition n/a
subroutine n/a
pod n/a
total 543 1104 49.1


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             const char*
955             ZLIBNG_VER_STATUS()
956             CODE:
957             #ifdef ZLIBNG_VER_STATUS
958 0           RETVAL = STRINGIFY(ZLIBNG_VER_STATUS);
959             #else
960             RETVAL = "0";
961             #endif
962             OUTPUT:
963             RETVAL
964              
965             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
966              
967             #define Zip_adler32(buf, adler) CRZ_adler32(adler, buf, (uInt)len)
968              
969             uLong
970             Zip_adler32(buf, adler=CRZ_adlerInitial)
971             uLong adler = NO_INIT
972             STRLEN len = NO_INIT
973             Bytef * buf = NO_INIT
974             SV * sv = ST(0) ;
975             INIT:
976             /* If the buffer is a reference, dereference it */
977 3           sv = deRef(sv, "adler32") ;
978             #ifdef UTF8_AVAILABLE
979 3 50         if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
    0          
    0          
980 0           croak("Wide character in Compress::Raw::Zlib::adler32");
981             #endif
982 3 50         buf = (Byte*)SvPVbyte(sv, len) ;
983              
984 3 50         if (items < 2)
985 3           adler = CRZ_adlerInitial;
986 0 0         else if (SvOK(ST(1)))
    0          
    0          
987 0 0         adler = SvUV(ST(1)) ;
988             else
989 0           adler = CRZ_adlerInitial;
990             OUTPUT:
991             RETVAL
992              
993             #define Zip_crc32(buf, crc, offset) CRZ_crc32(crc, buf+offset, (uInt)len-offset)
994              
995             uLong
996             Zip_crc32(buf, crc=CRZ_crcInitial, offset=0)
997             uLong crc = NO_INIT
998             STRLEN len = NO_INIT
999             Bytef * buf = NO_INIT
1000             STRLEN offset
1001             SV * sv = ST(0) ;
1002             INIT:
1003             /* If the buffer is a reference, dereference it */
1004 5           sv = deRef(sv, "crc32") ;
1005             #ifdef UTF8_AVAILABLE
1006 5 50         if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
    0          
    0          
1007 0           croak("Wide character in Compress::Raw::Zlib::crc32");
1008             #endif
1009 5 50         buf = (Byte*)SvPVbyte(sv, len) ;
1010              
1011 5 100         if (offset > len)
1012 1           croak("Offset out of range in Compress::Raw::Zlib::crc32");
1013              
1014 4 100         if (items < 2)
1015 3           crc = CRZ_crcInitial;
1016 1 50         else if (SvOK(ST(1)))
    0          
    0          
1017 1 50         crc = SvUV(ST(1)) ;
1018             else
1019 0           crc = CRZ_crcInitial;
1020              
1021             uLong
1022             crc32_combine(crc1, crc2, len2)
1023             uLong crc1
1024             uLong crc2
1025             z_off_t len2
1026             CODE:
1027             #ifndef AT_LEAST_ZLIB_1_2_2_1
1028             crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
1029             croak("crc32_combine needs zlib 1.2.3 or better");
1030             #else
1031 1           RETVAL = CRZ_crc32_combine(crc1, crc2, len2);
1032             #endif
1033             OUTPUT:
1034             RETVAL
1035              
1036              
1037             uLong
1038             adler32_combine(adler1, adler2, len2)
1039             uLong adler1
1040             uLong adler2
1041             z_off_t len2
1042             CODE:
1043             #ifndef AT_LEAST_ZLIB_1_2_2_1
1044             adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
1045             croak("adler32_combine needs zlib 1.2.3 or better");
1046             #else
1047 1           RETVAL = CRZ_adler32_combine(adler1, adler2, len2);
1048             #endif
1049             OUTPUT:
1050             RETVAL
1051              
1052              
1053             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
1054              
1055             void
1056             _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
1057             int flags
1058             int level
1059             int method
1060             int windowBits
1061             int memLevel
1062             int strategy
1063             uLong bufsize
1064             SV* dictionary
1065             PPCODE:
1066             int err ;
1067             deflateStream s ;
1068              
1069             if (trace)
1070             warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
1071             level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
1072 33 50         if ((s = InitStream() )) {
1073              
1074 33           s->Level = level;
1075 33           s->Method = method;
1076 33           s->WindowBits = windowBits;
1077 33           s->MemLevel = memLevel;
1078 33           s->Strategy = strategy;
1079              
1080 33           err = CRZ_deflateInit2(&(s->stream), level,
1081             method, windowBits, memLevel, strategy);
1082              
1083             if (trace) {
1084             warn(" _deflateInit2 returned %d (state %p)\n", err, s);
1085             DispStream(s, "INIT");
1086             }
1087              
1088             /* Check if a dictionary has been specified */
1089 33 50         SvGETMAGIC(dictionary);
    0          
1090 33 50         if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) {
    100          
    100          
1091             #ifdef UTF8_AVAILABLE
1092 1 50         if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
    0          
    0          
1093 0           croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
1094             #endif
1095 1           err = CRZ_deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ;
1096             if (trace)
1097             warn("deflateSetDictionary returned %d\n", err);
1098 1           s->dict_adler = s->stream.adler ;
1099             }
1100              
1101 33 50         if (err != Z_OK) {
1102 0           Safefree(s) ;
1103 0           s = NULL ;
1104             }
1105             else
1106 33           PostInitStream(s, flags, bufsize, windowBits) ;
1107              
1108             }
1109             else
1110 0           err = Z_MEM_ERROR ;
1111              
1112             {
1113 33           SV* obj = sv_setref_pv(sv_newmortal(),
1114             "Compress::Raw::Zlib::deflateStream", (void*)s);
1115 33 50         XPUSHs(obj);
1116             }
1117 33 50         if (GIMME_V == G_ARRAY) {
    100          
1118 22           SV * sv = sv_2mortal(newSViv(err)) ;
1119 22 50         setDUALstatus(sv, err);
1120 22 50         XPUSHs(sv) ;
1121             }
1122              
1123             void
1124             _inflateInit(flags, windowBits, bufsize, dictionary)
1125             int flags
1126             int windowBits
1127             uLong bufsize
1128             SV * dictionary
1129             ALIAS:
1130             _inflateScanInit = 1
1131             PPCODE:
1132              
1133 45           int err = Z_OK ;
1134             inflateStream s ;
1135             #ifndef MAGIC_APPEND
1136             if (ix == 1)
1137             croak("inflateScanInit needs zlib 1.2.1 or better");
1138             #endif
1139             if (trace)
1140             warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
1141             windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
1142 45 50         if ((s = InitStream() )) {
1143              
1144 45           s->WindowBits = windowBits;
1145              
1146 45           err = CRZ_inflateInit2(&(s->stream), windowBits);
1147 45 50         if (err != Z_OK) {
1148 0           Safefree(s) ;
1149 0           s = NULL ;
1150             }
1151 45 100         else if (sv_len(dictionary)) {
1152             #ifdef AT_LEAST_ZLIB_1_2_2_1
1153             /* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */
1154 2 50         if (s->WindowBits < 0) {
1155             STRLEN dlen;
1156 0 0         const Bytef* b = (const Bytef*)SvPVbyte(dictionary, dlen);
1157 0           err = CRZ_inflateSetDictionary(&(s->stream),
1158             b, dlen);
1159 0 0         if (err != Z_OK) {
1160 0           Safefree(s) ;
1161 0           s = NULL ;
1162             }
1163             }
1164             else
1165             #endif
1166             /* Dictionary specified - take a copy for use in inflate */
1167 2           s->dictionary = newSVsv(dictionary) ;
1168             }
1169 45 50         if (s) {
1170 45           PostInitStream(s, flags, bufsize, windowBits) ;
1171             #ifdef MAGIC_APPEND
1172 45 100         if (ix == 1)
1173             {
1174 45           s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
1175             }
1176             #endif
1177             }
1178             }
1179             else
1180 0           err = Z_MEM_ERROR ;
1181              
1182             {
1183 45 100         SV* obj = sv_setref_pv(sv_newmortal(),
1184             ix == 1
1185             ? "Compress::Raw::Zlib::inflateScanStream"
1186             : "Compress::Raw::Zlib::inflateStream",
1187             (void*)s);
1188 45 50         XPUSHs(obj);
1189             }
1190 45 50         if (GIMME_V == G_ARRAY) {
    100          
1191 31           SV * sv = sv_2mortal(newSViv(err)) ;
1192 31 50         setDUALstatus(sv, err);
1193 31 50         XPUSHs(sv) ;
1194             }
1195              
1196              
1197              
1198             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
1199              
1200             void
1201             DispStream(s, message=NULL)
1202             Compress::Raw::Zlib::deflateStream s
1203             const char * message
1204              
1205             DualType
1206             deflateReset(s)
1207             Compress::Raw::Zlib::deflateStream s
1208             CODE:
1209 0           RETVAL = CRZ_deflateReset(&(s->stream)) ;
1210 0 0         if (RETVAL == Z_OK) {
1211 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1212             }
1213             OUTPUT:
1214             RETVAL
1215              
1216             DualType
1217             deflate (s, buf, output)
1218             Compress::Raw::Zlib::deflateStream s
1219             SV * buf
1220             SV * output
1221             uInt cur_length = NO_INIT
1222             uInt increment = NO_INIT
1223             uInt prefix = NO_INIT
1224             int RETVAL = 0;
1225             uLong bufinc = NO_INIT
1226             STRLEN origlen = NO_INIT
1227             CODE:
1228 243           bufinc = s->bufsize;
1229              
1230             /* If the input buffer is a reference, dereference it */
1231 243           buf = deRef(buf, "deflate") ;
1232              
1233             /* initialise the input buffer */
1234             #ifdef UTF8_AVAILABLE
1235 243 50         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
1236 0           croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
1237             #endif
1238 243 100         s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
1239 243           s->stream.avail_in = origlen;
1240              
1241 243 50         if (s->flags & FLAG_CRC32)
1242 0           s->crc32 = CRZ_crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
1243              
1244 243 50         if (s->flags & FLAG_ADLER32)
1245 0           s->adler32 = CRZ_adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
1246              
1247             /* and retrieve the output buffer */
1248 243           output = deRef_l(output, "deflate") ;
1249             #ifdef UTF8_AVAILABLE
1250 243 50         if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
    0          
    0          
1251 0           croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
1252             #endif
1253              
1254 243 100         if((s->flags & FLAG_APPEND) == FLAG_APPEND) {
1255 163 100         SvOOK_off(output);
1256             } else {
1257 80           SvCUR_set(output, 0);
1258             }
1259 243           prefix = cur_length = SvCUR(output) ;
1260 243           s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
1261 243           increment = SvLEN(output) - cur_length;
1262 243           s->stream.avail_out = increment;
1263             #ifdef SETP_BYTE
1264             /* Check for saved output from deflateParams */
1265             if (s->deflateParams_out_valid) {
1266             *(s->stream.next_out) = s->deflateParams_out_byte;
1267             ++ s->stream.next_out;
1268             -- s->stream.avail_out ;
1269             s->deflateParams_out_valid = FALSE;
1270             }
1271             #else
1272             /* Check for saved output from deflateParams */
1273 243 100         if (s->deflateParams_out_length) {
1274 3           uLong plen = s->deflateParams_out_length ;
1275             /* printf("Copy %lu bytes saved data\n", plen); */
1276 3 50         if (s->stream.avail_out < plen) {
1277             /* printf("GROW from %d to %lu\n", s->stream.avail_out,
1278             SvLEN(output) + plen - s->stream.avail_out); */
1279 3           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1280 3           s->stream.next_out += cur_length;
1281             }
1282              
1283 3           Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;
1284 3           cur_length += plen;
1285 3           SvCUR_set(output, cur_length);
1286 3           s->stream.next_out += plen ;
1287 3           s->stream.avail_out = SvLEN(output) - cur_length ;
1288 3           increment = s->stream.avail_out;
1289              
1290 3           s->deflateParams_out_length = 0;
1291 3           Safefree(s->deflateParams_out_buffer);
1292 3           s->deflateParams_out_buffer = NULL;
1293             }
1294             #endif
1295 243           RETVAL = Z_OK ;
1296 491 100         while (s->stream.avail_in != 0) {
1297              
1298 248 100         if (s->stream.avail_out == 0) {
1299             /* out of space in the output buffer so make it bigger */
1300 5           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
1301 5           cur_length += increment ;
1302 5           s->stream.next_out += cur_length ;
1303 5           increment = bufinc ;
1304 5           s->stream.avail_out = increment;
1305 248           bufinc *= 2 ;
1306             }
1307              
1308             if (trace) {
1309             printf("DEFLATE Avail In %d, Out %d\n", s->stream.avail_in, s->stream.avail_out);
1310             DispStream(s, "BEFORE");
1311             /* Perl_sv_dump(output); */
1312             }
1313              
1314 248           RETVAL = CRZ_deflate(&(s->stream), Z_NO_FLUSH);
1315             /*
1316             if (RETVAL != Z_STREAM_ERROR) {
1317             int done = increment - s->stream.avail_out ;
1318             printf("std DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
1319             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out, done);
1320             }
1321             */
1322              
1323             if (trace) {
1324             printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1325             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
1326             DispStream(s, "AFTER");
1327             }
1328              
1329 248 50         if (RETVAL != Z_OK)
1330 0           break;
1331             }
1332              
1333 243           s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1334 243           s->uncompressedBytes += origlen - s->stream.avail_in ;
1335              
1336 243           s->last_error = RETVAL ;
1337 243 50         if (RETVAL == Z_OK) {
1338 243           SvPOK_only(output);
1339 243           SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1340 243 100         SvSETMAGIC(output);
1341             }
1342             OUTPUT:
1343             RETVAL
1344              
1345              
1346             void
1347             DESTROY(s)
1348             Compress::Raw::Zlib::deflateStream s
1349             CODE:
1350             if (trace)
1351             printf("Compress::Raw::Zlib::deflateStream::DESTROY %p\n", s);
1352 33           CRZ_deflateEnd(&s->stream) ;
1353 33 50         if (s->dictionary)
1354 0           SvREFCNT_dec(s->dictionary) ;
1355             #ifndef SETP_BYTE
1356 33 50         if (s->deflateParams_out_buffer)
1357 0           Safefree(s->deflateParams_out_buffer);
1358             #endif
1359 33           Safefree(s) ;
1360              
1361              
1362             DualType
1363             flush(s, output, f=Z_FINISH)
1364             Compress::Raw::Zlib::deflateStream s
1365             SV * output
1366             int f
1367             uInt cur_length = NO_INIT
1368             uInt increment = NO_INIT
1369             uInt prefix = NO_INIT
1370             uLong bufinc = NO_INIT
1371             uLong availableout = NO_INIT
1372             CODE:
1373 36           bufinc = s->bufsize;
1374              
1375              
1376              
1377             /* retrieve the output buffer */
1378 36           output = deRef_l(output, "flush") ;
1379             #ifdef UTF8_AVAILABLE
1380 36 50         if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
    0          
    0          
1381 0           croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
1382             #endif
1383 36 100         if((s->flags & FLAG_APPEND) == FLAG_APPEND) {
1384 22 100         SvOOK_off(output);
1385             } else {
1386 14           SvCUR_set(output, 0);
1387             }
1388 36           prefix = cur_length = SvCUR(output) ;
1389 36           s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
1390 36           increment = SvLEN(output) - cur_length;
1391 36           s->stream.avail_out = increment;
1392             #ifdef SETP_BYTE
1393             /* Check for saved output from deflateParams */
1394             if (s->deflateParams_out_valid) {
1395             *(s->stream.next_out) = s->deflateParams_out_byte;
1396             ++ s->stream.next_out;
1397             -- s->stream.avail_out ;
1398             s->deflateParams_out_valid = FALSE;
1399             }
1400             #else
1401             /* Check for saved output from deflateParams */
1402 36 50         if (s->deflateParams_out_length) {
1403 0           uLong plen = s->deflateParams_out_length ;
1404             /* printf("Copy %lu bytes saved data\n", plen); */
1405 0 0         if (s->stream.avail_out < plen) {
1406             /* printf("GROW from %d to %lu\n", s->stream.avail_out,
1407             SvLEN(output) + plen - s->stream.avail_out); */
1408 0           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1409 0           s->stream.next_out += cur_length;
1410             }
1411              
1412 0           Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;
1413 0           cur_length += plen;
1414 0           SvCUR_set(output, cur_length);
1415 0           s->stream.next_out += plen ;
1416 0           s->stream.avail_out = SvLEN(output) - cur_length ;
1417 0           increment = s->stream.avail_out;
1418              
1419 0           s->deflateParams_out_length = 0;
1420 0           Safefree(s->deflateParams_out_buffer);
1421 0           s->deflateParams_out_buffer = NULL;
1422             }
1423             #endif
1424              
1425             for (;;) {
1426 97 100         if (s->stream.avail_out == 0) {
1427             /* consumed all the available output, so extend it */
1428 63           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
1429 63           cur_length += increment ;
1430 63           s->stream.next_out += cur_length ;
1431 63           increment = bufinc ;
1432 63           s->stream.avail_out = increment;
1433 63           bufinc *= 2 ;
1434             }
1435              
1436 97           availableout = s->stream.avail_out ;
1437              
1438             if (trace) {
1439             printf("flush (%d) DEFLATE Avail In %d, Out %d\n", f, s->stream.avail_in, s->stream.avail_out);
1440             DispStream(s, "BEFORE");
1441             /* Perl_sv_dump(output); */
1442             }
1443              
1444 97           RETVAL = CRZ_deflate(&(s->stream), f);
1445             /*
1446             if (RETVAL != Z_STREAM_ERROR) {
1447             int done = availableout - s->stream.avail_out ;
1448             printf("flush DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
1449             GetErrorString(RETVAL), s->stream.avail_in,
1450             s->stream.avail_out, done);
1451             }
1452             */
1453              
1454             if (trace) {
1455             printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL,
1456             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
1457             DispStream(s, "AFTER");
1458             }
1459              
1460             /* Ignore the second of two consecutive flushes: */
1461 97 100         if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR)
    50          
1462 2           RETVAL = Z_OK;
1463              
1464             /* deflate has finished flushing only when it hasn't used up
1465             * all the available space in the output buffer:
1466             */
1467 97 100         if (s->stream.avail_out != 0 || RETVAL != Z_OK )
    50          
1468             break;
1469 61           }
1470              
1471 36 100         RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1472 36           s->last_error = RETVAL ;
1473              
1474 36           s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1475              
1476 36 50         if (RETVAL == Z_OK) {
1477 36           SvPOK_only(output);
1478 36           SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
1479 36 100         SvSETMAGIC(output);
1480             }
1481             OUTPUT:
1482             RETVAL
1483              
1484              
1485             DualType
1486             _deflateParams(s, flags, level, strategy, bufsize)
1487             Compress::Raw::Zlib::deflateStream s
1488             int flags
1489             int level
1490             int strategy
1491             uLong bufsize
1492             bool changed = FALSE;
1493             CODE:
1494             /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1495             printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1496 4 100         if (flags & 1 && level != s->Level) {
    50          
1497 3           s->Level = level ;
1498 3           changed = TRUE;
1499             }
1500 4 100         if (flags & 2 && strategy != s->Strategy) {
    50          
1501 3           s->Strategy = strategy ;
1502 3           changed = TRUE;
1503             }
1504 4 100         if (flags & 4)
1505 2           s->bufsize = bufsize;
1506 4 50         if (changed) {
1507             #ifdef SETP_BYTE
1508             s->stream.avail_in = 0;
1509             s->stream.next_out = &(s->deflateParams_out_byte) ;
1510             s->stream.avail_out = 1;
1511             RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1512             s->deflateParams_out_valid =
1513             (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1514             #else
1515             /* printf("Level %d Strategy %d, Prev Len %d\n",
1516             s->Level, s->Strategy, s->deflateParams_out_length); */
1517 4           RETVAL = flushParams(s);
1518             #endif
1519             }
1520             else
1521 0           RETVAL = Z_OK;
1522             OUTPUT:
1523             RETVAL
1524              
1525              
1526             int
1527             get_Level(s)
1528             Compress::Raw::Zlib::deflateStream s
1529             CODE:
1530 6           RETVAL = s->Level ;
1531             OUTPUT:
1532             RETVAL
1533              
1534             int
1535             get_Strategy(s)
1536             Compress::Raw::Zlib::deflateStream s
1537             CODE:
1538 6           RETVAL = s->Strategy ;
1539             OUTPUT:
1540             RETVAL
1541              
1542              
1543             uLong
1544             get_Bufsize(s)
1545             Compress::Raw::Zlib::deflateStream s
1546             CODE:
1547 0           RETVAL = s->bufsize ;
1548             OUTPUT:
1549             RETVAL
1550              
1551              
1552             int
1553             status(s)
1554             Compress::Raw::Zlib::deflateStream s
1555             CODE:
1556 0           RETVAL = s->last_error ;
1557             OUTPUT:
1558             RETVAL
1559              
1560             uLong
1561             crc32(s)
1562             Compress::Raw::Zlib::deflateStream s
1563             CODE:
1564 0           RETVAL = s->crc32 ;
1565             OUTPUT:
1566             RETVAL
1567              
1568             uLong
1569             dict_adler(s)
1570             Compress::Raw::Zlib::deflateStream s
1571             CODE:
1572 2           RETVAL = s->dict_adler ;
1573             OUTPUT:
1574             RETVAL
1575              
1576             uLong
1577             adler32(s)
1578             Compress::Raw::Zlib::deflateStream s
1579             CODE:
1580 0           RETVAL = s->adler32 ;
1581             OUTPUT:
1582             RETVAL
1583              
1584             uLong
1585             compressedBytes(s)
1586             Compress::Raw::Zlib::deflateStream s
1587             CODE:
1588 0           RETVAL = s->compressedBytes;
1589             OUTPUT:
1590             RETVAL
1591              
1592             uLong
1593             uncompressedBytes(s)
1594             Compress::Raw::Zlib::deflateStream s
1595             CODE:
1596 0           RETVAL = s->uncompressedBytes;
1597             OUTPUT:
1598             RETVAL
1599              
1600             uLong
1601             total_in(s)
1602             Compress::Raw::Zlib::deflateStream s
1603             CODE:
1604 4           RETVAL = s->stream.total_in ;
1605             OUTPUT:
1606             RETVAL
1607              
1608             uLong
1609             total_out(s)
1610             Compress::Raw::Zlib::deflateStream s
1611             CODE:
1612 4           RETVAL = s->stream.total_out ;
1613             OUTPUT:
1614             RETVAL
1615              
1616             char*
1617             msg(s)
1618             Compress::Raw::Zlib::deflateStream s
1619             CODE:
1620 4           RETVAL = (char*)s->stream.msg;
1621             OUTPUT:
1622             RETVAL
1623              
1624             int
1625             deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1626             Compress::Raw::Zlib::deflateStream s
1627             int good_length
1628             int max_lazy
1629             int nice_length
1630             int max_chain
1631             CODE:
1632             #ifndef AT_LEAST_ZLIB_1_2_2_3
1633             good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1634             nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1635             croak("deflateTune needs zlib 1.2.2.3 or better");
1636             #else
1637 0           RETVAL = CRZ_deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1638             #endif
1639             OUTPUT:
1640             RETVAL
1641              
1642              
1643             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1644              
1645             void
1646             DispStream(s, message=NULL)
1647             Compress::Raw::Zlib::inflateStream s
1648             const char * message
1649              
1650             DualType
1651             inflateReset(s)
1652             Compress::Raw::Zlib::inflateStream s
1653             CODE:
1654 0           RETVAL = CRZ_inflateReset(&(s->stream)) ;
1655 0 0         if (RETVAL == Z_OK) {
1656 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1657             }
1658             OUTPUT:
1659             RETVAL
1660              
1661             DualType
1662             inflate (s, buf, output, eof=FALSE)
1663             Compress::Raw::Zlib::inflateStream s
1664             SV * buf
1665             SV * output
1666             bool eof
1667             uInt cur_length = 0;
1668             uInt prefix_length = 0;
1669             int increment = 0;
1670             uLong bufinc = NO_INIT
1671             STRLEN na = NO_INIT ;
1672             PREINIT:
1673             #ifdef UTF8_AVAILABLE
1674 50555           bool out_utf8 = FALSE;
1675             #endif
1676             STRLEN origlen;
1677             CODE:
1678 50555           bufinc = s->bufsize;
1679             /* If the buffer is a reference, dereference it */
1680 50555           buf = deRef(buf, "inflate") ;
1681              
1682 50555 100         if (s->flags & FLAG_CONSUME_INPUT) {
1683 50547 100         if (SvREADONLY(buf))
1684 1           croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1685 50546 100         SvPV_force(buf, na);
1686             }
1687             #ifdef UTF8_AVAILABLE
1688 50554 50         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
1689 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1690             #endif
1691              
1692             /* initialise the input buffer */
1693 50554 100         s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
1694 50554           s->stream.avail_in = origlen ;
1695              
1696             /* and retrieve the output buffer */
1697 50554           output = deRef_l(output, "inflate") ;
1698             #ifdef UTF8_AVAILABLE
1699 50554 50         if (DO_UTF8(output))
    0          
1700 0           out_utf8 = TRUE ;
1701 50554 50         if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
    0          
    0          
1702 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1703             #endif
1704 50554 100         if((s->flags & FLAG_APPEND) == FLAG_APPEND) {
1705 50421 100         SvOOK_off(output);
1706             } else {
1707 133           SvCUR_set(output, 0);
1708             }
1709              
1710             /* Assume no output buffer - the code below will update if there is any available */
1711 50554           s->stream.avail_out = 0;
1712              
1713              
1714 50554 50         if (SvLEN(output)) {
1715 50554           prefix_length = cur_length = SvCUR(output) ;
1716              
1717 50554 100         if (s->flags & FLAG_LIMIT_OUTPUT && SvLEN(output) - cur_length - 1 < bufinc)
    100          
1718             {
1719 144           Sv_Grow(output, bufinc + cur_length + 1) ;
1720             }
1721              
1722             /* Only setup the stream output pointers if there is spare
1723             capacity in the outout SV
1724             */
1725 50554 50         if (SvLEN(output) > cur_length + 1)
1726             {
1727 50554 100         s->stream.next_out = (Bytef*) SvPV_nomg_nolen(output) + cur_length;
1728 50554           increment = SvLEN(output) - cur_length - 1;
1729 50554           s->stream.avail_out = increment;
1730             }
1731             }
1732              
1733              
1734 50554           s->bytesInflated = 0;
1735              
1736 50554           RETVAL = Z_OK;
1737              
1738 100954 50         while (RETVAL == Z_OK) {
1739 100954 100         if (s->stream.avail_out == 0) {
1740             /* out of space in the output buffer so make it bigger */
1741 71           s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc +1) ;
1742 71           cur_length += increment ;
1743 71           s->stream.next_out += cur_length ;
1744 71           increment = bufinc ;
1745 71           s->stream.avail_out = increment;
1746 71           bufinc *= 2 ;
1747             }
1748              
1749             /* printf("INFLATE Availl In %d, Out %d\n", s->stream.avail_in,
1750             s->stream.avail_out);
1751             DispStream(s, "BEFORE");
1752             Perl_sv_dump(output); */
1753 100954           RETVAL = CRZ_inflate(&(s->stream), Z_SYNC_FLUSH);
1754             /* printf("INFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1755             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); */
1756              
1757              
1758 100954 100         if (RETVAL == Z_NEED_DICT && s->dictionary) {
    50          
1759             STRLEN dlen;
1760 1 50         const Bytef* b = (const Bytef*)SvPV(s->dictionary, dlen) ;
1761 1           s->dict_adler = s->stream.adler ;
1762 1           RETVAL = CRZ_inflateSetDictionary(&(s->stream),
1763             b, dlen);
1764 1 50         if (RETVAL == Z_OK)
1765 1           continue;
1766             }
1767              
1768 100953 100         if (s->flags & FLAG_LIMIT_OUTPUT &&
    100          
1769 7 50         (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) {
1770 140 50         if (s->stream.avail_out == 0)
1771 140           RETVAL = Z_BUF_ERROR;
1772 140           break;
1773             }
1774 100813 100         if (s->flags & FLAG_LIMIT_OUTPUT &&
    50          
1775 7 50         (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR ))
1776             break;
1777              
1778 100813 50         if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
    50          
    100          
1779 100810 100         RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
1780             break ;
1781              
1782 100771 100         if (RETVAL == Z_BUF_ERROR) {
1783 50372 50         if (s->stream.avail_out == 0)
1784 0           continue ;
1785 50372 50         if (s->stream.avail_in == 0) {
1786 50372           RETVAL = Z_OK ;
1787 50372           break ;
1788             }
1789             }
1790             }
1791             #ifdef NEED_DUMMY_BYTE_AT_END
1792             if (eof && RETVAL == Z_OK && (s->flags & FLAG_LIMIT_OUTPUT) == 0) {
1793             Bytef* nextIn = (Bytef*)s->stream.next_in;
1794             uInt availIn = s->stream.avail_in;
1795             s->stream.next_in = (Bytef*) " ";
1796             s->stream.avail_in = 1;
1797             if (s->stream.avail_out == 0) {
1798             /* out of space in the output buffer so make it bigger */
1799             s->stream.next_out = Sv_Grow(output, SvLEN(output) + bufinc) ;
1800             cur_length += increment ;
1801             s->stream.next_out += cur_length ;
1802             increment = bufinc ;
1803             s->stream.avail_out = increment;
1804             bufinc *= 2 ;
1805             }
1806             RETVAL = CRZ_inflate(&(s->stream), Z_SYNC_FLUSH);
1807             s->stream.next_in = nextIn ;
1808             s->stream.avail_in = availIn ;
1809             }
1810             #else
1811             PERL_UNUSED_VAR(eof);
1812             #endif
1813              
1814 50554           s->last_error = RETVAL ;
1815 50554 100         if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_BUF_ERROR || RETVAL == Z_DATA_ERROR) {
    100          
    100          
    50          
1816             unsigned in ;
1817              
1818 50554           s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1819 50554           s->uncompressedBytes += s->bytesInflated ;
1820 50554           s->compressedBytes += origlen - s->stream.avail_in ;
1821              
1822 50554           SvPOK_only(output);
1823 50554           SvCUR_set(output, prefix_length + s->bytesInflated) ;
1824 50554           *SvEND(output) = '\0';
1825             #ifdef UTF8_AVAILABLE
1826 50554 50         if (out_utf8)
1827 0           sv_utf8_upgrade(output);
1828             #endif
1829 50554 100         SvSETMAGIC(output);
1830              
1831 50554 50         if (s->flags & FLAG_CRC32 )
1832 0           s->crc32 = CRZ_crc32(s->crc32,
1833 0           (const Bytef*)SvPVX(output)+prefix_length,
1834 0           SvCUR(output)-prefix_length) ;
1835              
1836 50554 50         if (s->flags & FLAG_ADLER32)
1837 0           s->adler32 = CRZ_adler32(s->adler32,
1838 0           (const Bytef*)SvPVX(output)+prefix_length,
1839 0           SvCUR(output)-prefix_length) ;
1840              
1841             /* fix the input buffer */
1842 50554 100         if (s->flags & FLAG_CONSUME_INPUT || s->flags & FLAG_LIMIT_OUTPUT) {
    50          
1843 50546           in = s->stream.avail_in ;
1844 50546           SvCUR_set(buf, in) ;
1845 50546 100         if (in)
1846 146           Move(s->stream.next_in, SvPVX(buf), in, char) ;
1847 50546           *SvEND(buf) = '\0';
1848 50546 100         SvSETMAGIC(buf);
1849             }
1850              
1851             }
1852             OUTPUT:
1853             RETVAL
1854              
1855             uLong
1856             inflateCount(s)
1857             Compress::Raw::Zlib::inflateStream s
1858             CODE:
1859 0           RETVAL = s->bytesInflated;
1860             OUTPUT:
1861             RETVAL
1862              
1863             uLong
1864             compressedBytes(s)
1865             Compress::Raw::Zlib::inflateStream s
1866             CODE:
1867 0           RETVAL = s->compressedBytes;
1868             OUTPUT:
1869             RETVAL
1870              
1871             uLong
1872             uncompressedBytes(s)
1873             Compress::Raw::Zlib::inflateStream s
1874             CODE:
1875 0           RETVAL = s->uncompressedBytes;
1876             OUTPUT:
1877             RETVAL
1878              
1879              
1880             DualType
1881             inflateSync (s, buf)
1882             Compress::Raw::Zlib::inflateStream s
1883             SV * buf
1884             CODE:
1885              
1886             /* If the buffer is a reference, dereference it */
1887 170           buf = deRef(buf, "inflateSync") ;
1888             #ifdef UTF8_AVAILABLE
1889 170 50         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
1890 0           croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1891             #endif
1892              
1893             /* initialise the input buffer */
1894 170 100         s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
1895 170           s->stream.avail_in = SvCUR(buf) ;
1896              
1897             /* inflateSync doesn't create any output */
1898 170           s->stream.next_out = (Bytef*) NULL;
1899 170           s->stream.avail_out = 0;
1900              
1901 170           RETVAL = CRZ_inflateSync(&(s->stream));
1902 170           s->last_error = RETVAL ;
1903              
1904             /* fix the input buffer */
1905             {
1906 170           unsigned in = s->stream.avail_in ;
1907 170           SvCUR_set(buf, in) ;
1908 170 100         if (in)
1909 1           Move(s->stream.next_in, SvPVX(buf), in, char) ;
1910 170           *SvEND(buf) = '\0';
1911 170 50         SvSETMAGIC(buf);
1912             }
1913             OUTPUT:
1914             RETVAL
1915              
1916             void
1917             DESTROY(s)
1918             Compress::Raw::Zlib::inflateStream s
1919             CODE:
1920 44           CRZ_inflateEnd(&s->stream) ;
1921 44 100         if (s->dictionary)
1922 2           SvREFCNT_dec(s->dictionary) ;
1923             #ifndef SETP_BYTE
1924 44 50         if (s->deflateParams_out_buffer)
1925 0           Safefree(s->deflateParams_out_buffer);
1926             #endif
1927             #ifdef MAGIC_APPEND
1928 44 50         if (s->window)
1929 0           Safefree(s->window);
1930             #endif
1931 44           Safefree(s) ;
1932              
1933              
1934             uLong
1935             status(s)
1936             Compress::Raw::Zlib::inflateStream s
1937             CODE:
1938 0           RETVAL = s->last_error ;
1939             OUTPUT:
1940             RETVAL
1941              
1942             uLong
1943             crc32(s)
1944             Compress::Raw::Zlib::inflateStream s
1945             CODE:
1946 0           RETVAL = s->crc32 ;
1947             OUTPUT:
1948             RETVAL
1949              
1950             uLong
1951             dict_adler(s)
1952             Compress::Raw::Zlib::inflateStream s
1953             CODE:
1954 2           RETVAL = s->dict_adler ;
1955             OUTPUT:
1956             RETVAL
1957              
1958             uLong
1959             total_in(s)
1960             Compress::Raw::Zlib::inflateStream s
1961             CODE:
1962 16           RETVAL = s->stream.total_in ;
1963             OUTPUT:
1964             RETVAL
1965              
1966             uLong
1967             adler32(s)
1968             Compress::Raw::Zlib::inflateStream s
1969             CODE:
1970 0           RETVAL = s->adler32 ;
1971             OUTPUT:
1972             RETVAL
1973              
1974             uLong
1975             total_out(s)
1976             Compress::Raw::Zlib::inflateStream s
1977             CODE:
1978 22           RETVAL = s->stream.total_out ;
1979             OUTPUT:
1980             RETVAL
1981              
1982             char*
1983             msg(s)
1984             Compress::Raw::Zlib::inflateStream s
1985             CODE:
1986 16           RETVAL = (char*)s->stream.msg;
1987             OUTPUT:
1988             RETVAL
1989              
1990              
1991             uLong
1992             get_Bufsize(s)
1993             Compress::Raw::Zlib::inflateStream s
1994             CODE:
1995 0           RETVAL = s->bufsize ;
1996             OUTPUT:
1997             RETVAL
1998              
1999             bool
2000             set_Append(s, mode)
2001             Compress::Raw::Zlib::inflateStream s
2002             bool mode
2003             CODE:
2004 0           RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
2005 0 0         if (mode)
2006 0           s->flags |= FLAG_APPEND ;
2007             else
2008 0           s->flags &= ~FLAG_APPEND ;
2009             OUTPUT:
2010             RETVAL
2011              
2012             MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
2013              
2014             void
2015             DESTROY(s)
2016             Compress::Raw::Zlib::inflateScanStream s
2017             CODE:
2018 1           CRZ_inflateEnd(&s->stream) ;
2019 1 50         if (s->dictionary)
2020 0           SvREFCNT_dec(s->dictionary) ;
2021             #ifndef SETP_BYTE
2022 1 50         if (s->deflateParams_out_buffer)
2023 0           Safefree(s->deflateParams_out_buffer);
2024             #endif
2025             #ifdef MAGIC_APPEND
2026 1 50         if (s->window)
2027 1           Safefree(s->window);
2028             #endif
2029 1           Safefree(s) ;
2030              
2031             void
2032             DispStream(s, message=NULL)
2033             Compress::Raw::Zlib::inflateScanStream s
2034             const char * message
2035              
2036             DualType
2037             inflateReset(s)
2038             Compress::Raw::Zlib::inflateScanStream s
2039             CODE:
2040 0           RETVAL = CRZ_inflateReset(&(s->stream)) ;
2041 0 0         if (RETVAL == Z_OK) {
2042 0           PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
2043             }
2044             OUTPUT:
2045             RETVAL
2046              
2047             DualType
2048             scan(s, buf, out=NULL, eof=FALSE)
2049             Compress::Raw::Zlib::inflateScanStream s
2050             SV * buf
2051             SV * out
2052             bool eof
2053             bool eof_mode = FALSE;
2054             int start_len = NO_INIT
2055             CODE:
2056             PERL_UNUSED_VAR(out);
2057             PERL_UNUSED_VAR(eof);
2058             /* If the input buffer is a reference, dereference it */
2059             #ifndef MAGIC_APPEND
2060             buf = buf;
2061             croak("scan needs zlib 1.2.1 or better");
2062             #else
2063 0           buf = deRef(buf, "inflateScan") ;
2064             #ifdef UTF8_AVAILABLE
2065 0 0         if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
    0          
    0          
2066 0           croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
2067             #endif
2068             /* initialise the input buffer */
2069 0 0         s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
2070 0           s->stream.avail_in = SvCUR(buf) ;
2071 0           start_len = s->stream.avail_in ;
2072 0           s->bytesInflated = 0 ;
2073             do
2074             {
2075 0 0         if (s->stream.avail_in == 0) {
2076 0           RETVAL = Z_OK ;
2077 0           break ;
2078             }
2079              
2080             /* set up output to next available section of sliding window */
2081 0           s->stream.avail_out = WINDOW_SIZE - s->window_have;
2082 0           s->stream.next_out = s->window + s->window_have;
2083              
2084             /* DispStream(s, "before inflate\n"); */
2085              
2086             /* inflate and check for errors */
2087 0           RETVAL = CRZ_inflate(&(s->stream), Z_BLOCK);
2088              
2089 0 0         if (start_len > 1 && ! eof_mode)
    0          
2090 0           s->window_lastByte = *(s->stream.next_in - 1 ) ;
2091              
2092 0 0         if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
    0          
    0          
2093             RETVAL == Z_DATA_ERROR )
2094             break ;
2095              
2096 0 0         if (s->flags & FLAG_CRC32 )
2097 0           s->crc32 = CRZ_crc32(s->crc32, s->window + s->window_have,
2098 0           WINDOW_SIZE - s->window_have - s->stream.avail_out);
2099              
2100 0 0         if (s->flags & FLAG_ADLER32)
2101 0           s->adler32 = CRZ_adler32(s->adler32, s->window + s->window_have,
2102 0           WINDOW_SIZE - s->window_have - s->stream.avail_out);
2103              
2104 0           s->uncompressedBytes =
2105 0           s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
2106              
2107 0 0         if (s->stream.avail_out)
2108 0           s->window_have = WINDOW_SIZE - s->stream.avail_out;
2109             else {
2110 0           s->window_have = 0;
2111 0           s->window_full = 1;
2112             }
2113              
2114             /* process end of block */
2115 0 0         if (s->stream.data_type & 128) {
2116 0 0         if (s->stream.data_type & 64) {
2117 0           s->window_left = s->stream.data_type & 0x1f;
2118             }
2119             else {
2120 0           s->window_lastbit = s->stream.data_type & 0x1f;
2121 0           s->lastBlockOffset = s->stream.total_in;
2122             }
2123             }
2124              
2125 0 0         } while (RETVAL != Z_STREAM_END);
2126              
2127 0           s->last_error = RETVAL ;
2128 0           s->window_lastoff = s->stream.total_in ;
2129 0           s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
2130              
2131 0 0         if (RETVAL == Z_STREAM_END)
2132             {
2133 0           s->matchedEndBlock = 1 ;
2134              
2135             /* save the location of the end of the compressed data */
2136 0           s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
2137 0           s->window_endOffset = s->stream.total_in ;
2138 0 0         if (s->window_left)
2139             {
2140 0           -- s->window_endOffset ;
2141             }
2142              
2143             /* if window wrapped, build dictionary from window by rotating */
2144 0 0         if (s->window_full) {
2145 0           rotate(s->window, WINDOW_SIZE, s->window_have);
2146 0           s->window_have = WINDOW_SIZE;
2147             }
2148              
2149             /* if (s->flags & FLAG_CONSUME_INPUT) { */
2150             if (1) {
2151 0           unsigned in = s->stream.avail_in ;
2152 0           SvCUR_set(buf, in) ;
2153 0 0         if (in)
2154 0           Move(s->stream.next_in, SvPVX(buf), in, char) ;
2155 0           *SvEND(buf) = '\0';
2156 0 0         SvSETMAGIC(buf);
2157             }
2158             }
2159             #endif
2160             OUTPUT:
2161             RETVAL
2162              
2163              
2164             uLong
2165             getEndOffset(s)
2166             Compress::Raw::Zlib::inflateScanStream s
2167             CODE:
2168             #ifndef MAGIC_APPEND
2169             croak("getEndOffset needs zlib 1.2.1 or better");
2170             #else
2171 0           RETVAL = s->window_endOffset;
2172             #endif
2173             OUTPUT:
2174             RETVAL
2175              
2176             uLong
2177             inflateCount(s)
2178             Compress::Raw::Zlib::inflateScanStream s
2179             CODE:
2180             #ifndef MAGIC_APPEND
2181             croak("inflateCount needs zlib 1.2.1 or better");
2182             #else
2183 0           RETVAL = s->bytesInflated;
2184             #endif
2185             OUTPUT:
2186             RETVAL
2187              
2188             uLong
2189             compressedBytes(s)
2190             Compress::Raw::Zlib::inflateScanStream s
2191             CODE:
2192 0           RETVAL = s->compressedBytes;
2193             OUTPUT:
2194             RETVAL
2195              
2196             uLong
2197             uncompressedBytes(s)
2198             Compress::Raw::Zlib::inflateScanStream s
2199             CODE:
2200 0           RETVAL = s->uncompressedBytes;
2201             OUTPUT:
2202             RETVAL
2203              
2204              
2205             uLong
2206             getLastBlockOffset(s)
2207             Compress::Raw::Zlib::inflateScanStream s
2208             CODE:
2209             #ifndef MAGIC_APPEND
2210             croak("getLastBlockOffset needs zlib 1.2.1 or better");
2211             #else
2212 0           RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
2213             #endif
2214             OUTPUT:
2215             RETVAL
2216              
2217             uLong
2218             getLastBufferOffset(s)
2219             Compress::Raw::Zlib::inflateScanStream s
2220             CODE:
2221             #ifndef MAGIC_APPEND
2222             croak("getLastBufferOffset needs zlib 1.2.1 or better");
2223             #else
2224 0           RETVAL = s->window_lastoff;
2225             #endif
2226             OUTPUT:
2227             RETVAL
2228              
2229             void
2230             resetLastBlockByte(s, byte)
2231             Compress::Raw::Zlib::inflateScanStream s
2232             unsigned char* byte
2233             CODE:
2234             #ifndef MAGIC_APPEND
2235             croak("resetLastBlockByte needs zlib 1.2.1 or better");
2236             #else
2237 1 50         if (byte != NULL)
2238 0           *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
2239             #endif
2240              
2241              
2242             void
2243             _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
2244             Compress::Raw::Zlib::inflateScanStream inf_s
2245             int flags
2246             int level
2247             int method
2248             int windowBits
2249             int memLevel
2250             int strategy
2251             uLong bufsize
2252             PPCODE:
2253             {
2254             #ifndef MAGIC_APPEND
2255             flags = flags;
2256             level = level ;
2257             method = method;
2258             windowBits = windowBits;
2259             memLevel = memLevel;
2260             strategy = strategy;
2261             bufsize= bufsize;
2262             croak("_createDeflateStream needs zlib 1.2.1 or better");
2263             #else
2264             int err ;
2265             deflateStream s ;
2266              
2267             if (trace)
2268             warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
2269             level, method, windowBits, memLevel, strategy, bufsize) ;
2270 0 0         if ((s = InitStream() )) {
2271              
2272 0           s->Level = level;
2273 0           s->Method = method;
2274 0           s->WindowBits = windowBits;
2275 0           s->MemLevel = memLevel;
2276 0           s->Strategy = strategy;
2277              
2278 0           err = CRZ_deflateInit2(&(s->stream), level,
2279             method, windowBits, memLevel, strategy);
2280              
2281 0 0         if (err == Z_OK) {
2282 0           err = CRZ_deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
2283 0           s->dict_adler = s->stream.adler ;
2284             }
2285              
2286 0 0         if (err != Z_OK) {
2287 0           Safefree(s) ;
2288 0           s = NULL ;
2289             }
2290             else {
2291 0           PostInitStream(s, flags, bufsize, windowBits) ;
2292 0           s->crc32 = inf_s->crc32;
2293 0           s->adler32 = inf_s->adler32;
2294 0           s->stream.adler = inf_s->stream.adler ;
2295             /* s->stream.total_out = inf_s->bytesInflated ; */
2296 0           s->stream.total_in = inf_s->stream.total_out ;
2297 0 0         if (inf_s->window_left) {
2298             /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
2299 0           CRZ_deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
2300             }
2301             }
2302             }
2303             else
2304 0           err = Z_MEM_ERROR ;
2305              
2306 0 0         XPUSHs(sv_setref_pv(sv_newmortal(),
2307             "Compress::Raw::Zlib::deflateStream", (void*)s));
2308 0 0         if (GIMME_V == G_ARRAY) {
    0          
2309 0           SV * sv = sv_2mortal(newSViv(err)) ;
2310 0 0         setDUALstatus(sv, err);
2311 0 0         XPUSHs(sv) ;
2312             }
2313             #endif
2314             }
2315              
2316             DualType
2317             status(s)
2318             Compress::Raw::Zlib::inflateScanStream s
2319             CODE:
2320 0           RETVAL = s->last_error ;
2321             OUTPUT:
2322             RETVAL
2323              
2324             uLong
2325             crc32(s)
2326             Compress::Raw::Zlib::inflateScanStream s
2327             CODE:
2328 0           RETVAL = s->crc32 ;
2329             OUTPUT:
2330             RETVAL
2331              
2332              
2333             uLong
2334             adler32(s)
2335             Compress::Raw::Zlib::inflateScanStream s
2336             CODE:
2337 0           RETVAL = s->adler32 ;
2338             OUTPUT:
2339             RETVAL