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