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