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