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