File Coverage

cpan/Compress-Raw-Zlib/Zlib.xs
Criterion Covered Total %
statement 382 541 70.6
branch n/a
condition n/a
subroutine n/a
total 382 541 70.6


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