This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
amigaos4: cpan/Compress-Raw-Zlib: also __amigaos4__
[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
88534e79 186#if defined(AMIGA) || defined(AMIGAOS) || defined(__amigaos4__)
25f0751f
PM
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{
62c6b566 502 PERL_UNUSED_VAR(opaque);
589c1691
CBW
503 return safemalloc(items * size);
504}
505
506
507void my_zcfree (voidpf opaque, voidpf ptr)
508{
62c6b566 509 PERL_UNUSED_VAR(opaque);
7c8257d9
CBW
510 safefree(ptr);
511 return;
589c1691
CBW
512}
513
514#endif
515
25f0751f
PM
516static di_stream *
517#ifdef CAN_PROTOTYPE
518InitStream(void)
519#else
520InitStream()
521#endif
522{
523 di_stream *s ;
524
525 ZMALLOC(s, di_stream) ;
526
589c1691
CBW
527#ifdef AT_LEAST_ZLIB_1_2_5_2
528 s->stream.zalloc = my_zcalloc;
529 s->stream.zfree = my_zcfree;
530#endif
531
25f0751f 532 return s ;
25f0751f
PM
533}
534
535static void
536#ifdef CAN_PROTOTYPE
537PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
538#else
539PostInitStream(s, flags, bufsize, windowBits)
540 di_stream *s ;
541 int flags ;
542 int bufsize ;
543 int windowBits ;
544#endif
545{
546 s->bufsize = bufsize ;
25f0751f
PM
547 s->compressedBytes =
548 s->uncompressedBytes =
549 s->last_error = 0 ;
550 s->flags = flags ;
551 s->zip_mode = (windowBits < 0) ;
552 if (flags & FLAG_CRC32)
553 s->crc32 = crcInitial ;
554 if (flags & FLAG_ADLER32)
555 s->adler32 = adlerInitial ;
556}
557
558
559static SV*
560#ifdef CAN_PROTOTYPE
92905b42 561deRef(SV * sv, const char * string)
25f0751f
PM
562#else
563deRef(sv, string)
564SV * sv ;
565char * string;
566#endif
567{
568 dTHX;
569 SvGETMAGIC(sv);
570
571 if (SvROK(sv)) {
572 sv = SvRV(sv) ;
573 SvGETMAGIC(sv);
574 switch(SvTYPE(sv)) {
575 case SVt_PVAV:
576 case SVt_PVHV:
577 case SVt_PVCV:
578 croak("%s: buffer parameter is not a SCALAR reference", string);
776304fb
PM
579 default:
580 break;
25f0751f
PM
581 }
582 if (SvROK(sv))
583 croak("%s: buffer parameter is a reference to a reference", string) ;
584 }
585
4bac9ae4
CS
586 if (!SvOK(sv))
587 sv = sv_2mortal(newSVpv("", 0));
25f0751f
PM
588
589 return sv ;
590}
591
592static SV*
593#ifdef CAN_PROTOTYPE
92905b42 594deRef_l(SV * sv, const char * string)
25f0751f
PM
595#else
596deRef_l(sv, string)
597SV * sv ;
598char * string ;
599#endif
600{
601 dTHX;
602 bool wipe = 0 ;
4bac9ae4 603 STRLEN na;
25f0751f
PM
604
605 SvGETMAGIC(sv);
606 wipe = ! SvOK(sv) ;
607
608 if (SvROK(sv)) {
609 sv = SvRV(sv) ;
610 SvGETMAGIC(sv);
611 wipe = ! SvOK(sv) ;
612
613 switch(SvTYPE(sv)) {
614 case SVt_PVAV:
615 case SVt_PVHV:
616 case SVt_PVCV:
617 croak("%s: buffer parameter is not a SCALAR reference", string);
776304fb
PM
618 default:
619 break;
25f0751f
PM
620 }
621 if (SvROK(sv))
622 croak("%s: buffer parameter is a reference to a reference", string) ;
623 }
624
625 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
626 croak("%s: buffer parameter is read-only", string);
627
9d90bd60
P
628 SvUPGRADE(sv, SVt_PV);
629
25f0751f 630 if (wipe)
9d90bd60 631 sv_setpv(sv, "") ;
4bac9ae4
CS
632 else
633 (void)SvPVbyte_force(sv, na) ;
9d90bd60 634
25f0751f
PM
635 return sv ;
636}
637
638
639#include "constants.h"
640
641MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
642
643REQUIRE: 1.924
644PROTOTYPES: DISABLE
645
646INCLUDE: constants.xs
647
648BOOT:
649 /* Check this version of zlib is == 1 */
650 if (zlibVersion()[0] != '1')
651 croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
652
653 {
654 /* Create the $os_code scalar */
655 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
656 sv_setiv(os_code_sv, GZIP_OS_CODE) ;
657 }
658
659
d56f7e4c
PM
660#define Zip_zlib_version() (const char*)zlib_version
661const char*
25f0751f
PM
662Zip_zlib_version()
663
664unsigned
665ZLIB_VERNUM()
666 CODE:
667#ifdef ZLIB_VERNUM
668 RETVAL = ZLIB_VERNUM ;
669#else
670 /* 1.1.4 => 0x1140 */
671 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
672 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
673 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
589c1691
CBW
674 if (strlen(ZLIB_VERSION) > 5)
675 RETVAL += (ZLIB_VERSION[6] - '0') ;
25f0751f
PM
676#endif
677 OUTPUT:
678 RETVAL
679
589c1691
CBW
680
681#ifndef AT_LEAST_ZLIB_1_2_1
682#define zlibCompileFlags() 0
683#endif
684uLong
685zlibCompileFlags()
686
25f0751f
PM
687MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_
688
689#define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
690
691uLong
692Zip_adler32(buf, adler=adlerInitial)
693 uLong adler = NO_INIT
694 STRLEN len = NO_INIT
695 Bytef * buf = NO_INIT
696 SV * sv = ST(0) ;
697 INIT:
698 /* If the buffer is a reference, dereference it */
699 sv = deRef(sv, "adler32") ;
700#ifdef UTF8_AVAILABLE
701 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
702 croak("Wide character in Compress::Raw::Zlib::adler32");
703#endif
704 buf = (Byte*)SvPVbyte(sv, len) ;
705
706 if (items < 2)
707 adler = adlerInitial;
708 else if (SvOK(ST(1)))
709 adler = SvUV(ST(1)) ;
710 else
711 adler = adlerInitial;
d56f7e4c
PM
712 OUTPUT:
713 RETVAL
25f0751f 714
bc771c2e 715#define Zip_crc32(buf, crc, offset) crc32(crc, buf+offset, (uInt)len-offset)
25f0751f
PM
716
717uLong
bc771c2e 718Zip_crc32(buf, crc=crcInitial, offset=0)
25f0751f
PM
719 uLong crc = NO_INIT
720 STRLEN len = NO_INIT
721 Bytef * buf = NO_INIT
bc771c2e 722 int offset
25f0751f
PM
723 SV * sv = ST(0) ;
724 INIT:
725 /* If the buffer is a reference, dereference it */
726 sv = deRef(sv, "crc32") ;
727#ifdef UTF8_AVAILABLE
728 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
729 croak("Wide character in Compress::Raw::Zlib::crc32");
730#endif
731 buf = (Byte*)SvPVbyte(sv, len) ;
732
733 if (items < 2)
734 crc = crcInitial;
735 else if (SvOK(ST(1)))
736 crc = SvUV(ST(1)) ;
737 else
738 crc = crcInitial;
bc771c2e 739
25f0751f
PM
740uLong
741crc32_combine(crc1, crc2, len2)
742 uLong crc1
743 uLong crc2
744 z_off_t len2
745 CODE:
746#ifndef AT_LEAST_ZLIB_1_2_2_1
747 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
748 croak("crc32_combine needs zlib 1.2.3 or better");
749#else
750 RETVAL = crc32_combine(crc1, crc2, len2);
751#endif
752 OUTPUT:
753 RETVAL
754
755
756uLong
757adler32_combine(adler1, adler2, len2)
758 uLong adler1
759 uLong adler2
760 z_off_t len2
761 CODE:
762#ifndef AT_LEAST_ZLIB_1_2_2_1
763 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
764 croak("adler32_combine needs zlib 1.2.3 or better");
765#else
766 RETVAL = adler32_combine(adler1, adler2, len2);
767#endif
768 OUTPUT:
769 RETVAL
770
771
772MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
773
774void
775_deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
776 int flags
777 int level
778 int method
779 int windowBits
780 int memLevel
781 int strategy
782 uLong bufsize
783 SV* dictionary
784 PPCODE:
785 int err ;
786 deflateStream s ;
787
d56f7e4c
PM
788 if (trace)
789 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n",
790 level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
25f0751f
PM
791 if ((s = InitStream() )) {
792
793 s->Level = level;
794 s->Method = method;
795 s->WindowBits = windowBits;
796 s->MemLevel = memLevel;
797 s->Strategy = strategy;
798
799 err = deflateInit2(&(s->stream), level,
800 method, windowBits, memLevel, strategy);
801
c788e059
CBW
802 if (trace) {
803 warn(" _deflateInit2 returned %d (state %p)\n", err, s);
804 DispStream(s, "INIT");
805 }
589c1691 806
25f0751f 807 /* Check if a dictionary has been specified */
4bac9ae4
CS
808 SvGETMAGIC(dictionary);
809 if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) {
25f0751f 810#ifdef UTF8_AVAILABLE
4bac9ae4
CS
811 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
812 croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
25f0751f 813#endif
4bac9ae4 814 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ;
c788e059
CBW
815 if (trace)
816 warn("deflateSetDictionary returned %d\n", err);
25f0751f
PM
817 s->dict_adler = s->stream.adler ;
818 }
819
820 if (err != Z_OK) {
821 Safefree(s) ;
822 s = NULL ;
823 }
824 else
825 PostInitStream(s, flags, bufsize, windowBits) ;
826
827 }
828 else
829 err = Z_MEM_ERROR ;
830
d56f7e4c
PM
831 {
832 SV* obj = sv_setref_pv(sv_newmortal(),
833 "Compress::Raw::Zlib::deflateStream", (void*)s);
834 XPUSHs(obj);
835 }
25f0751f
PM
836 if (GIMME == G_ARRAY) {
837 SV * sv = sv_2mortal(newSViv(err)) ;
838 setDUALstatus(sv, err);
839 XPUSHs(sv) ;
840 }
841
842void
843_inflateInit(flags, windowBits, bufsize, dictionary)
844 int flags
845 int windowBits
846 uLong bufsize
847 SV * dictionary
848 ALIAS:
849 _inflateScanInit = 1
850 PPCODE:
851
852 int err = Z_OK ;
853 inflateStream s ;
854#ifndef MAGIC_APPEND
855 if (ix == 1)
856 croak("inflateScanInit needs zlib 1.2.1 or better");
857#endif
858 if (trace)
859 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
860 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
861 if ((s = InitStream() )) {
862
863 s->WindowBits = windowBits;
864
865 err = inflateInit2(&(s->stream), windowBits);
866 if (err != Z_OK) {
867 Safefree(s) ;
868 s = NULL ;
869 }
f3d3633e 870 else if (sv_len(dictionary)) {
e11a3f9e
PM
871#ifdef AT_LEAST_ZLIB_1_2_2_1
872 /* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */
873 if (s->WindowBits < 0) {
f3d3633e
CBW
874 STRLEN dlen;
875 const Bytef* b = (const Bytef*)SvPVbyte(dictionary, dlen);
e11a3f9e 876 err = inflateSetDictionary(&(s->stream),
f3d3633e 877 b, dlen);
e11a3f9e
PM
878 if (err != Z_OK) {
879 Safefree(s) ;
880 s = NULL ;
881 }
882 }
883 else
c788e059 884#endif
25f0751f
PM
885 /* Dictionary specified - take a copy for use in inflate */
886 s->dictionary = newSVsv(dictionary) ;
887 }
888 if (s) {
889 PostInitStream(s, flags, bufsize, windowBits) ;
890#ifdef MAGIC_APPEND
891 if (ix == 1)
892 {
893 s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
894 }
895#endif
896 }
897 }
898 else
899 err = Z_MEM_ERROR ;
900
d56f7e4c
PM
901 {
902 SV* obj = sv_setref_pv(sv_newmortal(),
25f0751f
PM
903 ix == 1
904 ? "Compress::Raw::Zlib::inflateScanStream"
905 : "Compress::Raw::Zlib::inflateStream",
d56f7e4c
PM
906 (void*)s);
907 XPUSHs(obj);
908 }
25f0751f
PM
909 if (GIMME == G_ARRAY) {
910 SV * sv = sv_2mortal(newSViv(err)) ;
911 setDUALstatus(sv, err);
912 XPUSHs(sv) ;
913 }
914
915
916
917MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
918
919void
920DispStream(s, message=NULL)
921 Compress::Raw::Zlib::deflateStream s
1cae2293 922 const char * message
25f0751f
PM
923
924DualType
925deflateReset(s)
926 Compress::Raw::Zlib::deflateStream s
927 CODE:
928 RETVAL = deflateReset(&(s->stream)) ;
929 if (RETVAL == Z_OK) {
930 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
931 }
932 OUTPUT:
933 RETVAL
934
935DualType
936deflate (s, buf, output)
937 Compress::Raw::Zlib::deflateStream s
938 SV * buf
939 SV * output
9d90bd60
P
940 uInt cur_length = NO_INIT
941 uInt increment = NO_INIT
942 uInt prefix = NO_INIT
943 int RETVAL = 0;
944 uLong bufinc = NO_INIT
f3d3633e 945 STRLEN origlen = NO_INIT
25f0751f 946 CODE:
258133d1 947 bufinc = s->bufsize;
25f0751f
PM
948
949 /* If the input buffer is a reference, dereference it */
950 buf = deRef(buf, "deflate") ;
951
952 /* initialise the input buffer */
953#ifdef UTF8_AVAILABLE
954 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
955 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
956#endif
f3d3633e
CBW
957 s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
958 s->stream.avail_in = origlen;
25f0751f
PM
959
960 if (s->flags & FLAG_CRC32)
961 s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
962
963 if (s->flags & FLAG_ADLER32)
964 s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
965
966 /* and retrieve the output buffer */
967 output = deRef_l(output, "deflate") ;
968#ifdef UTF8_AVAILABLE
969 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
970 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
971#endif
972
973 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
974 SvCUR_set(output, 0);
975 /* sv_setpvn(output, "", 0); */
976 }
977 prefix = cur_length = SvCUR(output) ;
4bac9ae4 978 s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
25f0751f
PM
979 increment = SvLEN(output) - cur_length;
980 s->stream.avail_out = increment;
981#ifdef SETP_BYTE
982 /* Check for saved output from deflateParams */
983 if (s->deflateParams_out_valid) {
984 *(s->stream.next_out) = s->deflateParams_out_byte;
985 ++ s->stream.next_out;
986 -- s->stream.avail_out ;
987 s->deflateParams_out_valid = FALSE;
988 }
989#else
990 /* Check for saved output from deflateParams */
991 if (s->deflateParams_out_length) {
992 uLong plen = s->deflateParams_out_length ;
993 /* printf("Copy %d bytes saved data\n", plen);*/
994 if (s->stream.avail_out < plen) {
995 /*printf("GROW from %d to %d\n", s->stream.avail_out,
996 SvLEN(output) + plen - s->stream.avail_out); */
997 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
998 }
999
1000 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1001 cur_length = cur_length + plen;
1002 SvCUR_set(output, cur_length);
1003 s->stream.next_out += plen ;
1004 s->stream.avail_out = SvLEN(output) - cur_length ;
1005 increment = s->stream.avail_out;
1006 s->deflateParams_out_length = 0;
1007 }
1008#endif
4bac9ae4 1009 RETVAL = Z_OK ;
25f0751f
PM
1010 while (s->stream.avail_in != 0) {
1011
1012 if (s->stream.avail_out == 0) {
1013 /* out of space in the output buffer so make it bigger */
9ffe0f2e 1014 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
25f0751f 1015 cur_length += increment ;
9d90bd60 1016 s->stream.next_out += cur_length ;
258133d1 1017 increment = bufinc ;
25f0751f 1018 s->stream.avail_out = increment;
258133d1 1019 bufinc *= 2 ;
25f0751f
PM
1020 }
1021
c788e059
CBW
1022 if (trace) {
1023 printf("DEFLATE Avail In %d, Out %d\n", s->stream.avail_in, s->stream.avail_out);
1024 DispStream(s, "BEFORE");
1025 /* Perl_sv_dump(output); */
1026 }
1027
25f0751f 1028 RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
c788e059
CBW
1029
1030 if (trace) {
1031 printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1032 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
1033 DispStream(s, "AFTER");
1034 }
1035
25f0751f
PM
1036 if (RETVAL != Z_OK)
1037 break;
1038 }
1039
1040 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
f3d3633e 1041 s->uncompressedBytes += origlen - s->stream.avail_in ;
25f0751f
PM
1042
1043 s->last_error = RETVAL ;
1044 if (RETVAL == Z_OK) {
1045 SvPOK_only(output);
1046 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
4e7676c7 1047 SvSETMAGIC(output);
25f0751f
PM
1048 }
1049 OUTPUT:
1050 RETVAL
25f0751f
PM
1051
1052
1053void
1054DESTROY(s)
1055 Compress::Raw::Zlib::deflateStream s
1056 CODE:
c788e059
CBW
1057 if (trace)
1058 printf("Compress::Raw::Zlib::deflateStream::DESTROY %p\n", s);
25f0751f
PM
1059 deflateEnd(&s->stream) ;
1060 if (s->dictionary)
1061 SvREFCNT_dec(s->dictionary) ;
1062#ifndef SETP_BYTE
1063 if (s->deflateParams_out_buffer)
1064 Safefree(s->deflateParams_out_buffer);
1065#endif
1066 Safefree(s) ;
1067
1068
1069DualType
1070flush(s, output, f=Z_FINISH)
1071 Compress::Raw::Zlib::deflateStream s
1072 SV * output
1073 int f
1074 uInt cur_length = NO_INIT
1075 uInt increment = NO_INIT
1076 uInt prefix = NO_INIT
258133d1 1077 uLong bufinc = NO_INIT
589c1691 1078 uLong availableout = NO_INIT
25f0751f 1079 CODE:
258133d1 1080 bufinc = s->bufsize;
25f0751f
PM
1081
1082 s->stream.avail_in = 0; /* should be zero already anyway */
1083
1084 /* retrieve the output buffer */
1085 output = deRef_l(output, "flush") ;
1086#ifdef UTF8_AVAILABLE
1087 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1088 croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
1089#endif
1090 if(! s->flags & FLAG_APPEND) {
1091 SvCUR_set(output, 0);
1092 /* sv_setpvn(output, "", 0); */
1093 }
1094 prefix = cur_length = SvCUR(output) ;
4bac9ae4 1095 s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
25f0751f
PM
1096 increment = SvLEN(output) - cur_length;
1097 s->stream.avail_out = increment;
1098#ifdef SETP_BYTE
1099 /* Check for saved output from deflateParams */
1100 if (s->deflateParams_out_valid) {
1101 *(s->stream.next_out) = s->deflateParams_out_byte;
1102 ++ s->stream.next_out;
1103 -- s->stream.avail_out ;
1104 s->deflateParams_out_valid = FALSE;
1105 }
1106#else
1107 /* Check for saved output from deflateParams */
1108 if (s->deflateParams_out_length) {
1109 uLong plen = s->deflateParams_out_length ;
1110 /* printf("Copy %d bytes saved data\n", plen); */
1111 if (s->stream.avail_out < plen) {
1112 /* printf("GROW from %d to %d\n", s->stream.avail_out,
1113 SvLEN(output) + plen - s->stream.avail_out); */
1114 Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
1115 }
1116
1117 Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
1118 cur_length = cur_length + plen;
1119 SvCUR_set(output, cur_length);
1120 s->stream.next_out += plen ;
1121 s->stream.avail_out = SvLEN(output) - cur_length ;
1122 increment = s->stream.avail_out;
1123 s->deflateParams_out_length = 0;
1124 }
1125#endif
1126
1127 for (;;) {
589c1691
CBW
1128 if (s->stream.avail_out == 0) {
1129 /* consumed all the available output, so extend it */
9ffe0f2e 1130 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
25f0751f 1131 cur_length += increment ;
9d90bd60 1132 s->stream.next_out += cur_length ;
258133d1 1133 increment = bufinc ;
25f0751f 1134 s->stream.avail_out = increment;
258133d1 1135 bufinc *= 2 ;
25f0751f 1136 }
589c1691
CBW
1137
1138 availableout = s->stream.avail_out ;
1139
c788e059
CBW
1140 if (trace) {
1141 printf("flush (%d) DEFLATE Avail In %d, Out %d\n", f, s->stream.avail_in, s->stream.avail_out);
1142 DispStream(s, "BEFORE");
1143 /* Perl_sv_dump(output); */
1144 }
1145
25f0751f
PM
1146 RETVAL = deflate(&(s->stream), f);
1147
c788e059
CBW
1148 if (trace) {
1149 printf("flush DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1150 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
1151 DispStream(s, "AFTER");
1152 }
1153
589c1691
CBW
1154 /* Ignore the second of two consecutive flushes: */
1155 if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR)
1156 RETVAL = Z_OK;
1157
25f0751f
PM
1158 /* deflate has finished flushing only when it hasn't used up
1159 * all the available space in the output buffer:
1160 */
1161 if (s->stream.avail_out != 0 || RETVAL != Z_OK )
1162 break;
1163 }
1164
1165 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
1166 s->last_error = RETVAL ;
1167
1168 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
1169
1170 if (RETVAL == Z_OK) {
1171 SvPOK_only(output);
1172 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
4e7676c7 1173 SvSETMAGIC(output);
25f0751f
PM
1174 }
1175 OUTPUT:
1176 RETVAL
25f0751f
PM
1177
1178
1179DualType
1180_deflateParams(s, flags, level, strategy, bufsize)
1181 Compress::Raw::Zlib::deflateStream s
1182 int flags
1183 int level
1184 int strategy
1185 uLong bufsize
1186 CODE:
1187 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
1188 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
1189 if (flags & 1)
1190 s->Level = level ;
1191 if (flags & 2)
1192 s->Strategy = strategy ;
1193 if (flags & 4) {
1194 s->bufsize = bufsize;
25f0751f
PM
1195 }
1196 /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
1197#ifdef SETP_BYTE
1198 s->stream.avail_in = 0;
1199 s->stream.next_out = &(s->deflateParams_out_byte) ;
1200 s->stream.avail_out = 1;
1201 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1202 s->deflateParams_out_valid =
1203 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
1204 /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
1205#else
1206 /* printf("Level %d Strategy %d, Prev Len %d\n",
1207 s->Level, s->Strategy, s->deflateParams_out_length); */
1208 s->stream.avail_in = 0;
1209 if (s->deflateParams_out_buffer == NULL)
1210 s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
1211 s->stream.next_out = s->deflateParams_out_buffer ;
1212 s->stream.avail_out = deflateParams_BUFFER_SIZE;
1213
1214 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
1215 s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
1216 /* printf("RETVAL %d, length out %d, avail %d\n",
1217 RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
1218#endif
1219 OUTPUT:
1220 RETVAL
1221
1222
1223int
1224get_Level(s)
1225 Compress::Raw::Zlib::deflateStream s
1226 CODE:
1227 RETVAL = s->Level ;
1228 OUTPUT:
1229 RETVAL
1230
1231int
1232get_Strategy(s)
1233 Compress::Raw::Zlib::deflateStream s
1234 CODE:
1235 RETVAL = s->Strategy ;
1236 OUTPUT:
1237 RETVAL
1238
1239
1240uLong
1241get_Bufsize(s)
1242 Compress::Raw::Zlib::deflateStream s
1243 CODE:
1244 RETVAL = s->bufsize ;
1245 OUTPUT:
1246 RETVAL
1247
1248
1249int
1250status(s)
1251 Compress::Raw::Zlib::deflateStream s
1252 CODE:
1253 RETVAL = s->last_error ;
1254 OUTPUT:
1255 RETVAL
1256
1257uLong
1258crc32(s)
1259 Compress::Raw::Zlib::deflateStream s
1260 CODE:
1261 RETVAL = s->crc32 ;
1262 OUTPUT:
1263 RETVAL
1264
1265uLong
1266dict_adler(s)
1267 Compress::Raw::Zlib::deflateStream s
1268 CODE:
1269 RETVAL = s->dict_adler ;
1270 OUTPUT:
1271 RETVAL
1272
1273uLong
1274adler32(s)
1275 Compress::Raw::Zlib::deflateStream s
1276 CODE:
1277 RETVAL = s->adler32 ;
1278 OUTPUT:
1279 RETVAL
1280
1281uLong
1282compressedBytes(s)
1283 Compress::Raw::Zlib::deflateStream s
1284 CODE:
1285 RETVAL = s->compressedBytes;
1286 OUTPUT:
1287 RETVAL
1288
1289uLong
1290uncompressedBytes(s)
1291 Compress::Raw::Zlib::deflateStream s
1292 CODE:
1293 RETVAL = s->uncompressedBytes;
1294 OUTPUT:
1295 RETVAL
1296
1297uLong
1298total_in(s)
1299 Compress::Raw::Zlib::deflateStream s
1300 CODE:
1301 RETVAL = s->stream.total_in ;
1302 OUTPUT:
1303 RETVAL
1304
1305uLong
1306total_out(s)
1307 Compress::Raw::Zlib::deflateStream s
1308 CODE:
1309 RETVAL = s->stream.total_out ;
1310 OUTPUT:
1311 RETVAL
1312
1313char*
1314msg(s)
1315 Compress::Raw::Zlib::deflateStream s
1316 CODE:
1317 RETVAL = s->stream.msg;
1318 OUTPUT:
1319 RETVAL
1320
1321int
1322deflateTune(s, good_length, max_lazy, nice_length, max_chain)
1323 Compress::Raw::Zlib::deflateStream s
1324 int good_length
1325 int max_lazy
1326 int nice_length
1327 int max_chain
1328 CODE:
1329#ifndef AT_LEAST_ZLIB_1_2_2_3
1330 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
1331 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
1332 croak("deflateTune needs zlib 1.2.2.3 or better");
1333#else
1334 RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
1335#endif
1336 OUTPUT:
1337 RETVAL
1338
1339
1340MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
1341
1342void
1343DispStream(s, message=NULL)
1344 Compress::Raw::Zlib::inflateStream s
1cae2293 1345 const char * message
25f0751f
PM
1346
1347DualType
1348inflateReset(s)
1349 Compress::Raw::Zlib::inflateStream s
1350 CODE:
1351 RETVAL = inflateReset(&(s->stream)) ;
1352 if (RETVAL == Z_OK) {
1353 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1354 }
1355 OUTPUT:
1356 RETVAL
1357
1358DualType
1359inflate (s, buf, output, eof=FALSE)
1360 Compress::Raw::Zlib::inflateStream s
1361 SV * buf
1362 SV * output
1363 bool eof
1364 uInt cur_length = 0;
1365 uInt prefix_length = 0;
319fab50 1366 int increment = 0;
2f54119d
CBW
1367 uLong bufinc = NO_INIT
1368 STRLEN na = NO_INIT ;
9d90bd60 1369 PREINIT:
25f0751f
PM
1370#ifdef UTF8_AVAILABLE
1371 bool out_utf8 = FALSE;
1372#endif
f3d3633e 1373 STRLEN origlen;
2f54119d 1374 CODE:
258133d1 1375 bufinc = s->bufsize;
25f0751f
PM
1376 /* If the buffer is a reference, dereference it */
1377 buf = deRef(buf, "inflate") ;
1378
2f54119d
CBW
1379 if (s->flags & FLAG_CONSUME_INPUT) {
1380 if (SvREADONLY(buf))
1381 croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
1382 SvPV_force(buf, na);
1383 }
25f0751f
PM
1384#ifdef UTF8_AVAILABLE
1385 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1386 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
1387#endif
1388
1389 /* initialise the input buffer */
f3d3633e
CBW
1390 s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
1391 s->stream.avail_in = origlen ;
25f0751f
PM
1392
1393 /* and retrieve the output buffer */
1394 output = deRef_l(output, "inflate") ;
1395#ifdef UTF8_AVAILABLE
1396 if (DO_UTF8(output))
1397 out_utf8 = TRUE ;
1398 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
1399 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
1400#endif
1401 if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
1402 SvCUR_set(output, 0);
1403 }
319fab50
PM
1404
1405 /* Assume no output buffer - the code below will update if there is any available */
1406 s->stream.avail_out = 0;
1407
1408
25f0751f
PM
1409 if (SvLEN(output)) {
1410 prefix_length = cur_length = SvCUR(output) ;
319fab50
PM
1411
1412 if (s->flags & FLAG_LIMIT_OUTPUT && SvLEN(output) - cur_length - 1 < bufinc)
1413 {
1414 Sv_Grow(output, bufinc + cur_length + 1) ;
1415 }
1416
1417 /* Only setup the stream output pointers if there is spare
1418 capacity in the outout SV
1419 */
1420 if (SvLEN(output) > cur_length + 1)
1421 {
5c314eab 1422 s->stream.next_out = (Bytef*) SvPV_nomg_nolen(output) + cur_length;
319fab50
PM
1423 increment = SvLEN(output) - cur_length - 1;
1424 s->stream.avail_out = increment;
1425 }
25f0751f 1426 }
319fab50
PM
1427
1428
25f0751f
PM
1429 s->bytesInflated = 0;
1430
e11a3f9e 1431 RETVAL = Z_OK;
25f0751f 1432
e11a3f9e 1433 while (RETVAL == Z_OK) {
319fab50 1434 if (s->stream.avail_out == 0) {
25f0751f 1435 /* out of space in the output buffer so make it bigger */
9ffe0f2e 1436 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc +1) ;
25f0751f 1437 cur_length += increment ;
9d90bd60 1438 s->stream.next_out += cur_length ;
258133d1 1439 increment = bufinc ;
25f0751f 1440 s->stream.avail_out = increment;
258133d1 1441 bufinc *= 2 ;
25f0751f
PM
1442 }
1443
319fab50
PM
1444 /* printf("INFLATE Availl In %d, Out %d\n", s->stream.avail_in,
1445 s->stream.avail_out);
1446DispStream(s, "BEFORE");
1447Perl_sv_dump(output); */
25f0751f 1448 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
319fab50
PM
1449 /* printf("INFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
1450 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); */
25f0751f 1451
9253672d
SH
1452
1453 if (RETVAL == Z_NEED_DICT && s->dictionary) {
f3d3633e 1454 STRLEN dlen;
a69492f5 1455 const Bytef* b = (const Bytef*)SvPV(s->dictionary, dlen) ;
9253672d
SH
1456 s->dict_adler = s->stream.adler ;
1457 RETVAL = inflateSetDictionary(&(s->stream),
f3d3633e 1458 b, dlen);
319fab50
PM
1459 if (RETVAL == Z_OK)
1460 continue;
9253672d
SH
1461 }
1462
319fab50 1463 if (s->flags & FLAG_LIMIT_OUTPUT &&
f3d3633e
CBW
1464 (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) {
1465 if (s->stream.avail_out == 0)
1466 RETVAL = Z_BUF_ERROR;
1467 break;
1468 }
1469 if (s->flags & FLAG_LIMIT_OUTPUT &&
319fab50
PM
1470 (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR ))
1471 break;
1472
1473 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1474 RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END )
25f0751f
PM
1475 break ;
1476
1477 if (RETVAL == Z_BUF_ERROR) {
1478 if (s->stream.avail_out == 0)
1479 continue ;
1480 if (s->stream.avail_in == 0) {
1481 RETVAL = Z_OK ;
1482 break ;
1483 }
1484 }
25f0751f
PM
1485 }
1486#ifdef NEED_DUMMY_BYTE_AT_END
9253672d 1487 if (eof && RETVAL == Z_OK && s->flags & FLAG_LIMIT_OUTPUT == 0) {
25f0751f
PM
1488 Bytef* nextIn = s->stream.next_in;
1489 uInt availIn = s->stream.avail_in;
1490 s->stream.next_in = (Bytef*) " ";
1491 s->stream.avail_in = 1;
1492 if (s->stream.avail_out == 0) {
1493 /* out of space in the output buffer so make it bigger */
9d90bd60 1494 s->stream.next_out = Sv_Grow(output, SvLEN(output) + bufinc) ;
25f0751f 1495 cur_length += increment ;
9d90bd60 1496 s->stream.next_out += cur_length ;
258133d1 1497 increment = bufinc ;
25f0751f 1498 s->stream.avail_out = increment;
258133d1 1499 bufinc *= 2 ;
25f0751f
PM
1500 }
1501 RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
1502 s->stream.next_in = nextIn ;
1503 s->stream.avail_in = availIn ;
1504 }
10ccd91b
CBW
1505#else
1506 PERL_UNUSED_VAR(eof);
25f0751f
PM
1507#endif
1508
1509 s->last_error = RETVAL ;
319fab50
PM
1510 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_BUF_ERROR || RETVAL == Z_DATA_ERROR) {
1511 unsigned in ;
25f0751f
PM
1512
1513 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
1514 s->uncompressedBytes += s->bytesInflated ;
f3d3633e 1515 s->compressedBytes += origlen - s->stream.avail_in ;
25f0751f
PM
1516
1517 SvPOK_only(output);
1518 SvCUR_set(output, prefix_length + s->bytesInflated) ;
1519 *SvEND(output) = '\0';
1520#ifdef UTF8_AVAILABLE
1521 if (out_utf8)
1522 sv_utf8_upgrade(output);
1523#endif
4e7676c7 1524 SvSETMAGIC(output);
25f0751f
PM
1525
1526 if (s->flags & FLAG_CRC32 )
1527 s->crc32 = crc32(s->crc32,
4bac9ae4 1528 (const Bytef*)SvPVX(output)+prefix_length,
25f0751f
PM
1529 SvCUR(output)-prefix_length) ;
1530
1531 if (s->flags & FLAG_ADLER32)
1532 s->adler32 = adler32(s->adler32,
4bac9ae4 1533 (const Bytef*)SvPVX(output)+prefix_length,
25f0751f
PM
1534 SvCUR(output)-prefix_length) ;
1535
1536 /* fix the input buffer */
9253672d 1537 if (s->flags & FLAG_CONSUME_INPUT || s->flags & FLAG_LIMIT_OUTPUT) {
25f0751f
PM
1538 in = s->stream.avail_in ;
1539 SvCUR_set(buf, in) ;
1540 if (in)
4bac9ae4 1541 Move(s->stream.next_in, SvPVX(buf), in, char) ;
25f0751f
PM
1542 *SvEND(buf) = '\0';
1543 SvSETMAGIC(buf);
1544 }
319fab50 1545
25f0751f
PM
1546 }
1547 OUTPUT:
1548 RETVAL
25f0751f
PM
1549
1550uLong
1551inflateCount(s)
1552 Compress::Raw::Zlib::inflateStream s
1553 CODE:
1554 RETVAL = s->bytesInflated;
1555 OUTPUT:
1556 RETVAL
1557
1558uLong
1559compressedBytes(s)
1560 Compress::Raw::Zlib::inflateStream s
1561 CODE:
1562 RETVAL = s->compressedBytes;
1563 OUTPUT:
1564 RETVAL
1565
1566uLong
1567uncompressedBytes(s)
1568 Compress::Raw::Zlib::inflateStream s
1569 CODE:
1570 RETVAL = s->uncompressedBytes;
1571 OUTPUT:
1572 RETVAL
1573
1574
1575DualType
1576inflateSync (s, buf)
1577 Compress::Raw::Zlib::inflateStream s
1578 SV * buf
1579 CODE:
1580
1581 /* If the buffer is a reference, dereference it */
1582 buf = deRef(buf, "inflateSync") ;
1583#ifdef UTF8_AVAILABLE
1584 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1585 croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
1586#endif
1587
1588 /* initialise the input buffer */
f3d3633e 1589 s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
25f0751f
PM
1590 s->stream.avail_in = SvCUR(buf) ;
1591
1592 /* inflateSync doesn't create any output */
1593 s->stream.next_out = (Bytef*) NULL;
1594 s->stream.avail_out = 0;
1595
1596 RETVAL = inflateSync(&(s->stream));
1597 s->last_error = RETVAL ;
1598
1599 /* fix the input buffer */
1600 {
1601 unsigned in = s->stream.avail_in ;
1602 SvCUR_set(buf, in) ;
1603 if (in)
4bac9ae4 1604 Move(s->stream.next_in, SvPVX(buf), in, char) ;
25f0751f
PM
1605 *SvEND(buf) = '\0';
1606 SvSETMAGIC(buf);
1607 }
1608 OUTPUT:
1609 RETVAL
25f0751f
PM
1610
1611void
1612DESTROY(s)
1613 Compress::Raw::Zlib::inflateStream s
1614 CODE:
1615 inflateEnd(&s->stream) ;
1616 if (s->dictionary)
1617 SvREFCNT_dec(s->dictionary) ;
1618#ifndef SETP_BYTE
1619 if (s->deflateParams_out_buffer)
1620 Safefree(s->deflateParams_out_buffer);
1621#endif
1622#ifdef MAGIC_APPEND
1623 if (s->window)
1624 Safefree(s->window);
1625#endif
1626 Safefree(s) ;
1627
1628
1629uLong
1630status(s)
1631 Compress::Raw::Zlib::inflateStream s
1632 CODE:
1633 RETVAL = s->last_error ;
1634 OUTPUT:
1635 RETVAL
1636
1637uLong
1638crc32(s)
1639 Compress::Raw::Zlib::inflateStream s
1640 CODE:
1641 RETVAL = s->crc32 ;
1642 OUTPUT:
1643 RETVAL
1644
1645uLong
1646dict_adler(s)
1647 Compress::Raw::Zlib::inflateStream s
1648 CODE:
1649 RETVAL = s->dict_adler ;
1650 OUTPUT:
1651 RETVAL
1652
1653uLong
1654total_in(s)
1655 Compress::Raw::Zlib::inflateStream s
1656 CODE:
1657 RETVAL = s->stream.total_in ;
1658 OUTPUT:
1659 RETVAL
1660
1661uLong
1662adler32(s)
1663 Compress::Raw::Zlib::inflateStream s
1664 CODE:
1665 RETVAL = s->adler32 ;
1666 OUTPUT:
1667 RETVAL
1668
1669uLong
1670total_out(s)
1671 Compress::Raw::Zlib::inflateStream s
1672 CODE:
1673 RETVAL = s->stream.total_out ;
1674 OUTPUT:
1675 RETVAL
1676
1677char*
1678msg(s)
1679 Compress::Raw::Zlib::inflateStream s
1680 CODE:
1681 RETVAL = s->stream.msg;
1682 OUTPUT:
1683 RETVAL
1684
1685
1686uLong
1687get_Bufsize(s)
1688 Compress::Raw::Zlib::inflateStream s
1689 CODE:
1690 RETVAL = s->bufsize ;
1691 OUTPUT:
1692 RETVAL
1693
1694bool
1695set_Append(s, mode)
1696 Compress::Raw::Zlib::inflateStream s
1697 bool mode
1698 CODE:
1699 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
1700 if (mode)
1701 s->flags |= FLAG_APPEND ;
1702 else
1703 s->flags &= ~FLAG_APPEND ;
1704 OUTPUT:
1705 RETVAL
1706
1707MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
1708
1709void
1710DESTROY(s)
1711 Compress::Raw::Zlib::inflateScanStream s
1712 CODE:
1713 inflateEnd(&s->stream) ;
1714 if (s->dictionary)
1715 SvREFCNT_dec(s->dictionary) ;
1716#ifndef SETP_BYTE
1717 if (s->deflateParams_out_buffer)
1718 Safefree(s->deflateParams_out_buffer);
1719#endif
1720#ifdef MAGIC_APPEND
1721 if (s->window)
1722 Safefree(s->window);
1723#endif
1724 Safefree(s) ;
1725
1726void
1727DispStream(s, message=NULL)
1728 Compress::Raw::Zlib::inflateScanStream s
1cae2293 1729 const char * message
25f0751f
PM
1730
1731DualType
1732inflateReset(s)
1733 Compress::Raw::Zlib::inflateScanStream s
1734 CODE:
1735 RETVAL = inflateReset(&(s->stream)) ;
1736 if (RETVAL == Z_OK) {
1737 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
1738 }
1739 OUTPUT:
1740 RETVAL
1741
1742DualType
1743scan(s, buf, out=NULL, eof=FALSE)
1744 Compress::Raw::Zlib::inflateScanStream s
1745 SV * buf
1746 SV * out
1747 bool eof
1748 bool eof_mode = FALSE;
1749 int start_len = NO_INIT
25f0751f 1750 CODE:
10ccd91b
CBW
1751 PERL_UNUSED_VAR(out);
1752 PERL_UNUSED_VAR(eof);
25f0751f
PM
1753 /* If the input buffer is a reference, dereference it */
1754#ifndef MAGIC_APPEND
1755 buf = buf;
1756 croak("scan needs zlib 1.2.1 or better");
1757#else
1758 buf = deRef(buf, "inflateScan") ;
1759#ifdef UTF8_AVAILABLE
1760 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
1761 croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
1762#endif
1763 /* initialise the input buffer */
1590a345 1764 s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
25f0751f
PM
1765 s->stream.avail_in = SvCUR(buf) ;
1766 start_len = s->stream.avail_in ;
1767 s->bytesInflated = 0 ;
1768 do
1769 {
1770 if (s->stream.avail_in == 0) {
1771 RETVAL = Z_OK ;
1772 break ;
1773 }
1774
1775 /* set up output to next available section of sliding window */
1776 s->stream.avail_out = WINDOW_SIZE - s->window_have;
1777 s->stream.next_out = s->window + s->window_have;
1778
1779 /* DispStream(s, "before inflate\n"); */
1780
1781 /* inflate and check for errors */
1782 RETVAL = inflate(&(s->stream), Z_BLOCK);
1783
1784 if (start_len > 1 && ! eof_mode)
1785 s->window_lastByte = *(s->stream.next_in - 1 ) ;
1786
1787 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
1788 RETVAL == Z_DATA_ERROR )
1789 break ;
1790
1791 if (s->flags & FLAG_CRC32 )
1792 s->crc32 = crc32(s->crc32, s->window + s->window_have,
1793 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1794
1795 if (s->flags & FLAG_ADLER32)
1796 s->adler32 = adler32(s->adler32, s->window + s->window_have,
1797 WINDOW_SIZE - s->window_have - s->stream.avail_out);
1798
1799 s->uncompressedBytes =
1800 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
1801
1802 if (s->stream.avail_out)
1803 s->window_have = WINDOW_SIZE - s->stream.avail_out;
1804 else {
1805 s->window_have = 0;
1806 s->window_full = 1;
1807 }
1808
1809 /* process end of block */
1810 if (s->stream.data_type & 128) {
1811 if (s->stream.data_type & 64) {
1812 s->window_left = s->stream.data_type & 0x1f;
1813 }
1814 else {
1815 s->window_lastbit = s->stream.data_type & 0x1f;
1816 s->lastBlockOffset = s->stream.total_in;
1817 }
1818 }
1819
1820 } while (RETVAL != Z_STREAM_END);
1821
1822 s->last_error = RETVAL ;
1823 s->window_lastoff = s->stream.total_in ;
1824 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
1825
1826 if (RETVAL == Z_STREAM_END)
1827 {
1828 s->matchedEndBlock = 1 ;
1829
1830 /* save the location of the end of the compressed data */
1831 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
1832 s->window_endOffset = s->stream.total_in ;
1833 if (s->window_left)
1834 {
1835 -- s->window_endOffset ;
1836 }
1837
1838 /* if window wrapped, build dictionary from window by rotating */
1839 if (s->window_full) {
1840 rotate(s->window, WINDOW_SIZE, s->window_have);
1841 s->window_have = WINDOW_SIZE;
1842 }
1843
1844 /* if (s->flags & FLAG_CONSUME_INPUT) { */
1845 if (1) {
1846 unsigned in = s->stream.avail_in ;
1847 SvCUR_set(buf, in) ;
1848 if (in)
4bac9ae4 1849 Move(s->stream.next_in, SvPVX(buf), in, char) ;
1590a345
CBW
1850 *SvEND(buf) = '\0';
1851 SvSETMAGIC(buf);
25f0751f
PM
1852 }
1853 }
1854#endif
1855 OUTPUT:
1856 RETVAL
1857
1858
1859uLong
1860getEndOffset(s)
1861 Compress::Raw::Zlib::inflateScanStream s
1862 CODE:
1863#ifndef MAGIC_APPEND
1864 croak("getEndOffset needs zlib 1.2.1 or better");
1865#else
1866 RETVAL = s->window_endOffset;
1867#endif
1868 OUTPUT:
1869 RETVAL
1870
1871uLong
1872inflateCount(s)
1873 Compress::Raw::Zlib::inflateScanStream s
1874 CODE:
1875#ifndef MAGIC_APPEND
1876 croak("inflateCount needs zlib 1.2.1 or better");
1877#else
1878 RETVAL = s->bytesInflated;
1879#endif
1880 OUTPUT:
1881 RETVAL
1882
1883uLong
1884compressedBytes(s)
1885 Compress::Raw::Zlib::inflateScanStream s
1886 CODE:
1887 RETVAL = s->compressedBytes;
1888 OUTPUT:
1889 RETVAL
1890
1891uLong
1892uncompressedBytes(s)
1893 Compress::Raw::Zlib::inflateScanStream s
1894 CODE:
1895 RETVAL = s->uncompressedBytes;
1896 OUTPUT:
1897 RETVAL
1898
1899
1900uLong
1901getLastBlockOffset(s)
1902 Compress::Raw::Zlib::inflateScanStream s
1903 CODE:
1904#ifndef MAGIC_APPEND
1905 croak("getLastBlockOffset needs zlib 1.2.1 or better");
1906#else
1907 RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
1908#endif
1909 OUTPUT:
1910 RETVAL
1911
1912uLong
1913getLastBufferOffset(s)
1914 Compress::Raw::Zlib::inflateScanStream s
1915 CODE:
1916#ifndef MAGIC_APPEND
1917 croak("getLastBufferOffset needs zlib 1.2.1 or better");
1918#else
1919 RETVAL = s->window_lastoff;
1920#endif
1921 OUTPUT:
1922 RETVAL
1923
1924void
1925resetLastBlockByte(s, byte)
1926 Compress::Raw::Zlib::inflateScanStream s
1927 unsigned char* byte
1928 CODE:
1929#ifndef MAGIC_APPEND
1930 croak("resetLastBlockByte needs zlib 1.2.1 or better");
1931#else
cb7abd7f
PM
1932 if (byte != NULL)
1933 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
25f0751f
PM
1934#endif
1935
1936
1937void
1938_createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
1939 Compress::Raw::Zlib::inflateScanStream inf_s
1940 int flags
1941 int level
1942 int method
1943 int windowBits
1944 int memLevel
1945 int strategy
1946 uLong bufsize
1947 PPCODE:
1948 {
1949#ifndef MAGIC_APPEND
1950 flags = flags;
1951 level = level ;
1952 method = method;
1953 windowBits = windowBits;
1954 memLevel = memLevel;
1955 strategy = strategy;
1956 bufsize= bufsize;
1957 croak("_createDeflateStream needs zlib 1.2.1 or better");
1958#else
1959 int err ;
1960 deflateStream s ;
1961
1962 if (trace)
1963 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
1964 level, method, windowBits, memLevel, strategy, bufsize) ;
1965 if ((s = InitStream() )) {
1966
1967 s->Level = level;
1968 s->Method = method;
1969 s->WindowBits = windowBits;
1970 s->MemLevel = memLevel;
1971 s->Strategy = strategy;
1972
1973 err = deflateInit2(&(s->stream), level,
1974 method, windowBits, memLevel, strategy);
1975
1976 if (err == Z_OK) {
1977 err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
1978 s->dict_adler = s->stream.adler ;
1979 }
1980
1981 if (err != Z_OK) {
1982 Safefree(s) ;
1983 s = NULL ;
1984 }
1985 else {
1986 PostInitStream(s, flags, bufsize, windowBits) ;
1987 s->crc32 = inf_s->crc32;
1988 s->adler32 = inf_s->adler32;
1989 s->stream.adler = inf_s->stream.adler ;
1990 /* s->stream.total_out = inf_s->bytesInflated ; */
1991 s->stream.total_in = inf_s->stream.total_out ;
1992 if (inf_s->window_left) {
1993 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
1994 deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
1995 }
1996 }
1997 }
1998 else
1999 err = Z_MEM_ERROR ;
2000
2001 XPUSHs(sv_setref_pv(sv_newmortal(),
2002 "Compress::Raw::Zlib::deflateStream", (void*)s));
2003 if (GIMME == G_ARRAY) {
2004 SV * sv = sv_2mortal(newSViv(err)) ;
2005 setDUALstatus(sv, err);
2006 XPUSHs(sv) ;
2007 }
2008#endif
2009 }
2010
2011DualType
2012status(s)
2013 Compress::Raw::Zlib::inflateScanStream s
2014 CODE:
2015 RETVAL = s->last_error ;
2016 OUTPUT:
2017 RETVAL
2018
2019uLong
2020crc32(s)
2021 Compress::Raw::Zlib::inflateScanStream s
2022 CODE:
2023 RETVAL = s->crc32 ;
2024 OUTPUT:
2025 RETVAL
2026
2027
2028uLong
2029adler32(s)
2030 Compress::Raw::Zlib::inflateScanStream s
2031 CODE:
2032 RETVAL = s->adler32 ;
2033 OUTPUT:
2034 RETVAL
2035