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