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