Upgrade to Compress::Zlib 1.40
[p5sagit/p5-mst-13.2.git] / ext / Compress / Zlib / Zlib.xs
CommitLineData
f4c6fd49 1/* Filename: Zlib.xs
2 * Author : Paul Marquess, <pmqs@cpan.org>
3 * Created : 30 January 2005
667342e9 4 * Version : 1.40
f4c6fd49 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/* Part of this code is based on the file gzio.c */
13
14/* gzio.c -- IO on .gz files
15 * Copyright (C) 1995 Jean-loup Gailly.
16 * For conditions of distribution and use, see copyright notice in zlib.h
17 */
18
19
20
21#include "EXTERN.h"
22#include "perl.h"
23#include "XSUB.h"
24
25#include <zlib.h>
26
27#ifndef PERL_VERSION
28#include "patchlevel.h"
29#define PERL_REVISION 5
30#define PERL_VERSION PATCHLEVEL
31#define PERL_SUBVERSION SUBVERSION
32#endif
33
34#if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))
35
36# define PL_sv_undef sv_undef
37# define PL_na na
38# define PL_curcop curcop
39# define PL_compiling compiling
40
41#endif
42
43#ifndef newSVuv
44# define newSVuv newSViv
45#endif
46
47typedef struct di_stream {
48 z_stream stream;
49 uLong bufsize;
50 uLong bufinc;
51 SV * dictionary ;
52 uLong dict_adler ;
53 bool deflateParams_out_valid ;
54 Bytef deflateParams_out_byte;
55 int Level;
56 int Method;
57 int WindowBits;
58 int MemLevel;
59 int Strategy;
60} di_stream;
61
62typedef di_stream * deflateStream ;
63typedef di_stream * Compress__Zlib__deflateStream ;
64typedef di_stream * inflateStream ;
65typedef di_stream * Compress__Zlib__inflateStream ;
66
67/* typedef gzFile Compress__Zlib__gzFile ; */
68typedef struct gzType {
69 gzFile gz ;
70 SV * buffer ;
71 uLong offset ;
72 bool closed ;
73} gzType ;
74
75typedef gzType* Compress__Zlib__gzFile ;
76
77
78
79#define GZERRNO "Compress::Zlib::gzerrno"
80
81#define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
82 Zero(to,1,typ))
83
84#define adlerInitial adler32(0L, Z_NULL, 0)
85#define crcInitial crc32(0L, Z_NULL, 0)
86
87#if 1
c042ae3a 88static const char * const my_z_errmsg[] = {
f4c6fd49 89 "need dictionary", /* Z_NEED_DICT 2 */
90 "stream end", /* Z_STREAM_END 1 */
91 "", /* Z_OK 0 */
92 "file error", /* Z_ERRNO (-1) */
93 "stream error", /* Z_STREAM_ERROR (-2) */
94 "data error", /* Z_DATA_ERROR (-3) */
95 "insufficient memory", /* Z_MEM_ERROR (-4) */
96 "buffer error", /* Z_BUF_ERROR (-5) */
97 "incompatible version",/* Z_VERSION_ERROR(-6) */
98 ""};
99#endif
100
c042ae3a 101#if defined(__SYMBIAN32__)
102# define NO_WRITEABLE_DATA
103#endif
104
105#define TRACE_DEFAULT 0
106
107#ifdef NO_WRITEABLE_DATA
108#define trace TRACE_DEFAULT
109#else
110static int trace = TRACE_DEFAULT ;
111#endif
f4c6fd49 112
c042ae3a 113/* Dodge PerlIO hiding of these functions. */
114#undef printf
f4c6fd49 115
116static void
117#ifdef CAN_PROTOTYPE
118SetGzErrorNo(int error_no)
119#else
120SetGzErrorNo(error_no)
121int error_no ;
122#endif
123{
5e282033 124#ifdef dTHX
c042ae3a 125 dTHX;
5e282033 126#endif
f4c6fd49 127 char * errstr ;
128 SV * gzerror_sv = perl_get_sv(GZERRNO, FALSE) ;
129
130 if (error_no == Z_ERRNO) {
131 error_no = errno ;
132 errstr = Strerror(errno) ;
133 }
134 else
135 /* errstr = gzerror(fil, &error_no) ; */
136 errstr = (char*) my_z_errmsg[2 - error_no];
137
138 if (SvIV(gzerror_sv) != error_no) {
139 sv_setiv(gzerror_sv, error_no) ;
140 sv_setpv(gzerror_sv, errstr) ;
141 SvIOK_on(gzerror_sv) ;
142 }
143
144}
145
146static void
147#ifdef CAN_PROTOTYPE
148SetGzError(gzFile file)
149#else
150SetGzError(file)
151gzFile file ;
152#endif
153{
154 int error_no ;
155
156 (void)gzerror(file, &error_no) ;
157 SetGzErrorNo(error_no) ;
158}
159
160static void
161#ifdef CAN_PROTOTYPE
162DispHex(void * ptr, int length)
163#else
164DispHex(ptr, length)
165 void * ptr;
166 int length;
167#endif
168{
169 char * p = (char*)ptr;
170 int i;
171 for (i = 0; i < length; ++i) {
172 printf(" %02x", 0xFF & *(p+i));
173 }
174}
175
176
177static void
178#ifdef CAN_PROTOTYPE
179DispStream(di_stream * s, char * message)
180#else
181DispStream(s, message)
182 di_stream * s;
183 char * message;
184#endif
185{
186
187#if 0
188 if (! trace)
189 return ;
190#endif
191
192 printf("DispStream 0x%p - %s \n", s, message) ;
193
194 if (!s) {
195 printf(" stream pointer is NULL\n");
196 }
197 else {
198 printf(" stream 0x%p\n", &(s->stream));
199 printf(" zalloc 0x%p\n", s->stream.zalloc);
200 printf(" zfree 0x%p\n", s->stream.zfree);
201 printf(" opaque 0x%p\n", s->stream.opaque);
202 if (s->stream.msg)
203 printf(" msg %s\n", s->stream.msg);
204 else
205 printf(" msg \n");
206 printf(" next_in 0x%p", s->stream.next_in);
207 if (s->stream.next_in) {
208 printf(" =>");
209 DispHex(s->stream.next_in, 4);
210 }
211 printf("\n");
212
213 printf(" next_out 0x%p", s->stream.next_out);
214 if (s->stream.next_out){
215 printf(" =>");
216 DispHex(s->stream.next_out, 4);
217 }
218 printf("\n");
219
220 printf(" avail_in %ld\n", s->stream.avail_in);
221 printf(" avail_out %ld\n", s->stream.avail_out);
222 printf(" total_in %ld\n", s->stream.total_in);
223 printf(" total_out %ld\n", s->stream.total_out);
224 printf(" adler 0x%lx\n", s->stream.adler);
225 printf(" reserved 0x%lx\n", s->stream.reserved);
226 printf(" bufsize %ld\n", s->bufsize);
227 printf(" dictionary 0x%p\n", s->dictionary);
228 printf(" dict_adler 0x%ld\n", s->dict_adler);
229 printf("\n");
230
231 }
232}
233
234
235static di_stream *
236#ifdef CAN_PROTOTYPE
237InitStream(uLong bufsize)
238#else
239InitStream(bufsize)
240 uLong bufsize ;
241#endif
242{
243 di_stream *s ;
244
245 ZMALLOC(s, di_stream) ;
246
247 if (s) {
248 s->bufsize = bufsize ;
249 s->bufinc = bufsize ;
250 }
251
252 return s ;
253
254}
255
256#define SIZE 4096
257
258static int
259#ifdef CAN_PROTOTYPE
260gzreadline(Compress__Zlib__gzFile file, SV * output)
261#else
262gzreadline(file, output)
263 Compress__Zlib__gzFile file ;
264 SV * output ;
265#endif
266{
5e282033 267#ifdef dTHX
c042ae3a 268 dTHX;
5e282033 269#endif
f4c6fd49 270 SV * store = file->buffer ;
271 char *nl = "\n";
272 char *p;
273 char *out_ptr = SvPVX(store) ;
274 int n;
275
276 while (1) {
277
278 /* anything left from last time */
279 if ((n = SvCUR(store))) {
280
281 out_ptr = SvPVX(store) + file->offset ;
282 if ((p = ninstr(out_ptr, out_ptr + n - 1, nl, nl))) {
283 /* if (rschar != 0777 && */
284 /* p = ninstr(out_ptr, out_ptr + n - 1, rs, rs+rslen-1)) { */
285
286 sv_catpvn(output, out_ptr, p - out_ptr + 1);
287
288 file->offset += (p - out_ptr + 1) ;
289 n = n - (p - out_ptr + 1);
290 SvCUR_set(store, n) ;
291 return SvCUR(output);
292 }
293 else /* no EOL, so append the complete buffer */
294 sv_catpvn(output, out_ptr, n);
295
296 }
297
298
299 SvCUR_set(store, 0) ;
300 file->offset = 0 ;
301 out_ptr = SvPVX(store) ;
302
303 n = gzread(file->gz, out_ptr, SIZE) ;
304
305 if (n <= 0)
306 /* Either EOF or an error */
307 /* so return what we have so far else signal eof */
308 return (SvCUR(output)>0) ? SvCUR(output) : n ;
309
310 SvCUR_set(store, n) ;
311 }
312}
313
314static SV*
315#ifdef CAN_PROTOTYPE
316deRef(SV * sv, char * string)
317#else
318deRef(sv, string)
319SV * sv ;
320char * string;
321#endif
322{
5e282033 323#ifdef dTHX
c042ae3a 324 dTHX;
5e282033 325#endif
f4c6fd49 326 if (SvROK(sv)) {
327 sv = SvRV(sv) ;
328 switch(SvTYPE(sv)) {
329 case SVt_PVAV:
330 case SVt_PVHV:
331 case SVt_PVCV:
332 croak("%s: buffer parameter is not a SCALAR reference", string);
333 }
334 if (SvROK(sv))
335 croak("%s: buffer parameter is a reference to a reference", string) ;
336 }
337
338 if (!SvOK(sv)) {
339 sv = newSVpv("", 0);
340 }
341 return sv ;
342}
343
344#include "constants.h"
345
346MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_
347
348REQUIRE: 1.924
349PROTOTYPES: DISABLE
350
351INCLUDE: constants.xs
352
353BOOT:
354 /* Check this version of zlib is == 1 */
355 if (zlibVersion()[0] != '1')
356 croak("Compress::Zlib needs zlib version 1.x\n") ;
357
358 {
359 /* Create the $gzerror scalar */
360 SV * gzerror_sv = perl_get_sv(GZERRNO, GV_ADDMULTI) ;
361 sv_setiv(gzerror_sv, 0) ;
362 sv_setpv(gzerror_sv, "") ;
363 SvIOK_on(gzerror_sv) ;
364 }
365
366
367#define Zip_zlib_version() (char*)zlib_version
368char*
369Zip_zlib_version()
370
06edba15 371unsigned
372ZLIB_VERNUM()
373 CODE:
374#ifdef ZLIB_VERNUM
375 RETVAL = ZLIB_VERNUM ;
376#else
377 /* 1.1.4 => 0x1140 */
378 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
379 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
380 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
381#endif
382 OUTPUT:
383 RETVAL
384
385
f4c6fd49 386
387void
388DispStream(s, message=NULL)
389 Compress::Zlib::inflateStream s
390 char * message
391
392Compress::Zlib::gzFile
393gzopen_(path, mode)
394 char * path
395 char * mode
396 CODE:
397 gzFile gz ;
398 gz = gzopen(path, mode) ;
399 if (gz) {
400 ZMALLOC(RETVAL, gzType) ;
401 RETVAL->buffer = newSV(SIZE) ;
402 SvPOK_only(RETVAL->buffer) ;
403 SvCUR_set(RETVAL->buffer, 0) ;
404 RETVAL->offset = 0 ;
405 RETVAL->gz = gz ;
406 RETVAL->closed = FALSE ;
407 SetGzErrorNo(0) ;
408 }
409 else {
410 RETVAL = NULL ;
411 SetGzErrorNo(errno ? Z_ERRNO : Z_MEM_ERROR) ;
412 }
413 OUTPUT:
414 RETVAL
415
416
417Compress::Zlib::gzFile
418gzdopen_(fh, mode, offset)
419 int fh
420 char * mode
421 long offset
422 CODE:
423 gzFile gz ;
424 if (offset != -1)
425 lseek(fh, offset, 0) ;
426 gz = gzdopen(fh, mode) ;
427 if (gz) {
428 ZMALLOC(RETVAL, gzType) ;
429 RETVAL->buffer = newSV(SIZE) ;
430 SvPOK_only(RETVAL->buffer) ;
431 SvCUR_set(RETVAL->buffer, 0) ;
432 RETVAL->offset = 0 ;
433 RETVAL->gz = gz ;
434 RETVAL->closed = FALSE ;
435 SetGzErrorNo(0) ;
436 }
437 else {
438 RETVAL = NULL ;
439 SetGzErrorNo(errno ? Z_ERRNO : Z_MEM_ERROR) ;
440 }
441 OUTPUT:
442 RETVAL
443
444
445MODULE = Compress::Zlib PACKAGE = Compress::Zlib::gzFile PREFIX = Zip_
446
447#define Zip_gzread(file, buf, len) gzread(file->gz, bufp, len)
448
449int
450Zip_gzread(file, buf, len=4096)
451 Compress::Zlib::gzFile file
452 unsigned len
453 SV * buf
454 voidp bufp = NO_INIT
455 uLong bufsize = 0 ;
456 int RETVAL = 0 ;
457 CODE:
458 if (SvREADONLY(buf) && PL_curcop != &PL_compiling)
459 croak("gzread: buffer parameter is read-only");
f2e5e569 460 SvUPGRADE(buf, SVt_PV);
f4c6fd49 461 SvPOK_only(buf);
462 SvCUR_set(buf, 0);
463 /* any left over from gzreadline ? */
464 if ((bufsize = SvCUR(file->buffer)) > 0) {
465 uLong movesize ;
466
467 if (bufsize < len) {
468 movesize = bufsize ;
469 len -= movesize ;
470 }
471 else {
472 movesize = len ;
473 len = 0 ;
474 }
475 RETVAL = movesize ;
476
477 sv_catpvn(buf, SvPVX(file->buffer) + file->offset, movesize);
478
479 file->offset += movesize ;
480 SvCUR_set(file->buffer, bufsize - movesize) ;
481 }
482
483 if (len) {
484 bufp = (Byte*)SvGROW(buf, bufsize+len+1);
485 RETVAL = gzread(file->gz, ((Bytef*)bufp)+bufsize, len) ;
486 SetGzError(file->gz) ;
487 if (RETVAL >= 0) {
488 RETVAL += bufsize ;
489 SvCUR_set(buf, RETVAL) ;
490 *SvEND(buf) = '\0';
491 }
492 }
493 OUTPUT:
494 RETVAL
495 buf
496
497int
498gzreadline(file, buf)
499 Compress::Zlib::gzFile file
500 SV * buf
501 int RETVAL = 0;
502 CODE:
503 if (SvREADONLY(buf) && PL_curcop != &PL_compiling)
504 croak("gzreadline: buffer parameter is read-only");
f2e5e569 505 SvUPGRADE(buf, SVt_PV);
f4c6fd49 506 SvPOK_only(buf);
507 /* sv_setpvn(buf, "", SIZE) ; */
508 SvGROW(buf, SIZE) ;
509 SvCUR_set(buf, 0);
510 RETVAL = gzreadline(file, buf) ;
511 SetGzError(file->gz) ;
512 OUTPUT:
513 RETVAL
514 buf
515 CLEANUP:
516 if (RETVAL >= 0) {
517 /* SvCUR(buf) = RETVAL; */
518 /* Don't need to explicitly terminate with '\0', because
519 sv_catpvn aready has */
520 }
521
522#define Zip_gzwrite(file, buf) gzwrite(file->gz, buf, (unsigned)len)
523int
524Zip_gzwrite(file, buf)
525 Compress::Zlib::gzFile file
526 STRLEN len = NO_INIT
527 voidp buf = (voidp)SvPV(ST(1), len) ;
528 CLEANUP:
529 SetGzError(file->gz) ;
530
531#define Zip_gzflush(file, flush) gzflush(file->gz, flush)
532int
533Zip_gzflush(file, flush)
534 Compress::Zlib::gzFile file
535 int flush
536 CLEANUP:
537 SetGzError(file->gz) ;
538
06edba15 539#define Zip_gzclose(file) file->closed ? 0 : gzclose(file->gz)
f4c6fd49 540int
541Zip_gzclose(file)
542 Compress::Zlib::gzFile file
543 CLEANUP:
544 file->closed = TRUE ;
545 SetGzErrorNo(RETVAL) ;
546
547
548#define Zip_gzeof(file) gzeof(file->gz)
549int
550Zip_gzeof(file)
551 Compress::Zlib::gzFile file
552 CODE:
553#ifdef OLD_ZLIB
554 croak("gzeof needs zlib 1.0.6 or better") ;
555#else
556 RETVAL = gzeof(file->gz);
557#endif
558 OUTPUT:
559 RETVAL
560
561
562#define Zip_gzsetparams(file,l,s) gzsetparams(file->gz,l,s)
563int
564Zip_gzsetparams(file, level, strategy)
565 Compress::Zlib::gzFile file
566 int level
567 int strategy
568 CODE:
569#ifdef OLD_ZLIB
570 croak("gzsetparams needs zlib 1.0.6 or better") ;
571#else
572 RETVAL = gzsetparams(file->gz, level, strategy);
573#endif
574 OUTPUT:
575 RETVAL
576
577void
578DESTROY(file)
579 Compress::Zlib::gzFile file
580 CODE:
581 if (! file->closed)
582 Zip_gzclose(file) ;
583 SvREFCNT_dec(file->buffer) ;
584 safefree((char*)file) ;
585
586#define Zip_gzerror(file) (char*)gzerror(file->gz, &errnum)
587
588char *
589Zip_gzerror(file)
590 Compress::Zlib::gzFile file
591 int errnum = NO_INIT
592 CLEANUP:
593 sv_setiv(ST(0), errnum) ;
594 SvPOK_on(ST(0)) ;
595
596
597
598MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_
599
600
601#define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
602
603uLong
604Zip_adler32(buf, adler=adlerInitial)
605 uLong adler = NO_INIT
606 STRLEN len = NO_INIT
607 Bytef * buf = NO_INIT
608 SV * sv = ST(0) ;
609 INIT:
610 /* If the buffer is a reference, dereference it */
611 sv = deRef(sv, "adler32") ;
612 buf = (Byte*)SvPV(sv, len) ;
613
614 if (items < 2)
615 adler = adlerInitial;
616 else if (SvOK(ST(1)))
617 adler = SvUV(ST(1)) ;
618 else
619 adler = adlerInitial;
620
621#define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
622
623uLong
624Zip_crc32(buf, crc=crcInitial)
625 uLong crc = NO_INIT
626 STRLEN len = NO_INIT
627 Bytef * buf = NO_INIT
628 SV * sv = ST(0) ;
629 INIT:
630 /* If the buffer is a reference, dereference it */
631 sv = deRef(sv, "crc32") ;
632 buf = (Byte*)SvPV(sv, len) ;
633
634 if (items < 2)
635 crc = crcInitial;
636 else if (SvOK(ST(1)))
637 crc = SvUV(ST(1)) ;
638 else
639 crc = crcInitial;
640
641MODULE = Compress::Zlib PACKAGE = Compress::Zlib
642
643void
644_deflateInit(level, method, windowBits, memLevel, strategy, bufsize, dictionary)
645 int level
646 int method
647 int windowBits
648 int memLevel
649 int strategy
650 uLong bufsize
651 SV * dictionary
652 PPCODE:
653
654 int err ;
655 deflateStream s ;
656
657 if (trace)
658 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%d\n",
659 level, method, windowBits, memLevel, strategy, bufsize) ;
660 if ((s = InitStream(bufsize)) ) {
661
662 s->Level = level;
663 s->Method = method;
664 s->WindowBits = windowBits;
665 s->MemLevel = memLevel;
666 s->Strategy = strategy;
667
668 err = deflateInit2(&(s->stream), level,
669 method, windowBits, memLevel, strategy);
670
671 /* Check if a dictionary has been specified */
672 if (err == Z_OK && SvCUR(dictionary)) {
673 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary),
674 SvCUR(dictionary)) ;
675 s->dict_adler = s->stream.adler ;
676 }
677
678 if (err != Z_OK) {
679 Safefree(s) ;
680 s = NULL ;
681 }
682
683 }
684 else
685 err = Z_MEM_ERROR ;
686
687 XPUSHs(sv_setref_pv(sv_newmortal(),
688 "Compress::Zlib::deflateStream", (void*)s));
689 if (GIMME == G_ARRAY)
690 XPUSHs(sv_2mortal(newSViv(err))) ;
691
692void
693_inflateInit(windowBits, bufsize, dictionary)
694 int windowBits
695 uLong bufsize
696 SV * dictionary
697 PPCODE:
698
699 int err = Z_OK ;
700 inflateStream s ;
701
702 if (trace)
703 warn("in _inflateInit(windowBits=%d, bufsize=%d, dictionary=%d\n",
704 windowBits, bufsize, SvCUR(dictionary)) ;
705 if ((s = InitStream(bufsize)) ) {
706
707 s->WindowBits = windowBits;
708
709 err = inflateInit2(&(s->stream), windowBits);
710
711 if (err != Z_OK) {
712 Safefree(s) ;
713 s = NULL ;
714 }
715 else if (SvCUR(dictionary)) {
716 /* Dictionary specified - take a copy for use in inflate */
717 s->dictionary = newSVsv(dictionary) ;
718 }
719 }
720 else
721 err = Z_MEM_ERROR ;
722
723 XPUSHs(sv_setref_pv(sv_newmortal(),
724 "Compress::Zlib::inflateStream", (void*)s));
725 if (GIMME == G_ARRAY)
726 XPUSHs(sv_2mortal(newSViv(err))) ;
727
728
729
730MODULE = Compress::Zlib PACKAGE = Compress::Zlib::deflateStream
731
732void
733DispStream(s, message=NULL)
734 Compress::Zlib::deflateStream s
735 char * message
736
737void
738deflate (s, buf)
739 Compress::Zlib::deflateStream s
740 SV * buf
741 uLong outsize = NO_INIT
742 SV * output = NO_INIT
743 int err = 0;
744 PPCODE:
745
746 /* If the buffer is a reference, dereference it */
747 buf = deRef(buf, "deflate") ;
748
749 /* initialise the input buffer */
750 s->stream.next_in = (Bytef*)SvPV(buf, *(STRLEN*)&s->stream.avail_in) ;
751 /* s->stream.next_in = (Bytef*)SvPVX(buf); */
752 s->stream.avail_in = SvCUR(buf) ;
753
754 /* and the output buffer */
755 /* output = sv_2mortal(newSVpv("", s->bufinc)) ; */
756 output = sv_2mortal(newSV(s->bufinc)) ;
757 SvPOK_only(output) ;
758 SvCUR_set(output, 0) ;
759 outsize = s->bufinc ;
760 s->stream.next_out = (Bytef*) SvPVX(output) ;
761 s->stream.avail_out = outsize;
762
763 /* Check for saved output from deflateParams */
764 if (s->deflateParams_out_valid) {
765 *(s->stream.next_out) = s->deflateParams_out_byte;
766 ++ s->stream.next_out;
767 -- s->stream.avail_out ;
768 s->deflateParams_out_valid = FALSE;
769 }
770
771 while (s->stream.avail_in != 0) {
772
773 if (s->stream.avail_out == 0) {
774 s->bufinc *= 2 ;
775 SvGROW(output, outsize + s->bufinc) ;
776 s->stream.next_out = (Bytef*) SvPVX(output) + outsize ;
777 outsize += s->bufinc ;
778 s->stream.avail_out = s->bufinc ;
779 }
780 err = deflate(&(s->stream), Z_NO_FLUSH);
781 if (err != Z_OK)
782 break;
783 }
784
785 if (err == Z_OK) {
786 SvPOK_only(output);
787 SvCUR_set(output, outsize - s->stream.avail_out) ;
788 }
789 else
790 output = &PL_sv_undef ;
791 XPUSHs(output) ;
792 if (GIMME == G_ARRAY)
793 XPUSHs(sv_2mortal(newSViv(err))) ;
794
795
796
797void
798flush(s, f=Z_FINISH)
799 Compress::Zlib::deflateStream s
800 int f
801 uLong outsize = NO_INIT
802 SV * output = NO_INIT
803 int err = Z_OK ;
804 PPCODE:
805
806 s->stream.avail_in = 0; /* should be zero already anyway */
807
808 /* output = sv_2mortal(newSVpv("", s->bufinc)) ; */
809 output = sv_2mortal(newSV(s->bufinc)) ;
810 SvPOK_only(output) ;
811 SvCUR_set(output, 0) ;
812 outsize = s->bufinc ;
813 s->stream.next_out = (Bytef*) SvPVX(output) ;
814 s->stream.avail_out = outsize;
815
816 /* Check for saved output from deflateParams */
817 if (s->deflateParams_out_valid) {
818 *(s->stream.next_out) = s->deflateParams_out_byte;
819 ++ s->stream.next_out;
820 -- s->stream.avail_out ;
821 s->deflateParams_out_valid = FALSE;
822 }
823
824 for (;;) {
825 if (s->stream.avail_out == 0) {
826 /* consumed all the available output, so extend it */
827 s->bufinc *= 2 ;
828 SvGROW(output, outsize + s->bufinc) ;
829 s->stream.next_out = (Bytef*)SvPVX(output) + outsize ;
830 outsize += s->bufinc ;
831 s->stream.avail_out = s->bufinc ;
832 }
833 err = deflate(&(s->stream), f);
834
835 /* deflate has finished flushing only when it hasn't used up
836 * all the available space in the output buffer:
837 */
838 if (s->stream.avail_out != 0 || err != Z_OK )
839 break;
840 }
841
842 err = (err == Z_STREAM_END ? Z_OK : err) ;
843
844 if (err == Z_OK) {
845 SvPOK_only(output);
846 SvCUR_set(output, outsize - s->stream.avail_out) ;
847 }
848 else
849 output = &PL_sv_undef ;
850 XPUSHs(output) ;
851 if (GIMME == G_ARRAY)
852 XPUSHs(sv_2mortal(newSViv(err))) ;
853
854int
855_deflateParams(s, flags, level, strategy, bufsize)
856 Compress::Zlib::deflateStream s
857 int flags
858 int level
859 int strategy
860 uLong bufsize
861 CODE:
862 if (flags & 1)
863 s->Level = level ;
864 if (flags & 2)
865 s->Strategy = strategy ;
866 if (bufsize) {
867 s->bufsize = bufsize;
868 s->bufinc = bufsize;
869 }
870 s->stream.avail_in = 0;
871 s->stream.next_out = &(s->deflateParams_out_byte) ;
872 s->stream.avail_out = 1;
873 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
874 s->deflateParams_out_valid =
875 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
876 OUTPUT:
877 RETVAL
878
879
880int
881get_Level(s)
882 Compress::Zlib::deflateStream s
883 CODE:
884 RETVAL = s->Level ;
885 OUTPUT:
886 RETVAL
887
888int
889get_Strategy(s)
890 Compress::Zlib::deflateStream s
891 CODE:
892 RETVAL = s->Strategy ;
893 OUTPUT:
894 RETVAL
895
896void
897DESTROY(s)
898 Compress::Zlib::deflateStream s
899 CODE:
900 deflateEnd(&s->stream) ;
901 if (s->dictionary)
902 SvREFCNT_dec(s->dictionary) ;
903 Safefree(s) ;
904
905
906uLong
907dict_adler(s)
908 Compress::Zlib::deflateStream s
909 CODE:
910 RETVAL = s->dict_adler ;
911 OUTPUT:
912 RETVAL
913
914uLong
915total_in(s)
916 Compress::Zlib::deflateStream s
917 CODE:
918 RETVAL = s->stream.total_in ;
919 OUTPUT:
920 RETVAL
921
922uLong
923total_out(s)
924 Compress::Zlib::deflateStream s
925 CODE:
926 RETVAL = s->stream.total_out ;
927 OUTPUT:
928 RETVAL
929
930char*
931msg(s)
932 Compress::Zlib::deflateStream s
933 CODE:
934 RETVAL = s->stream.msg;
935 OUTPUT:
936 RETVAL
937
938
939MODULE = Compress::Zlib PACKAGE = Compress::Zlib::inflateStream
940
941void
942DispStream(s, message=NULL)
943 Compress::Zlib::inflateStream s
944 char * message
945
946void
947inflate (s, buf)
948 Compress::Zlib::inflateStream s
949 SV * buf
950 uLong outsize = NO_INIT
951 SV * output = NO_INIT
952 int err = Z_OK ;
953 ALIAS:
954 __unc_inflate = 1
955 PPCODE:
956
957 /* If the buffer is a reference, dereference it */
958 buf = deRef(buf, "inflate") ;
959
960 /* initialise the input buffer */
961 s->stream.next_in = (Bytef*)SvPVX(buf) ;
962 s->stream.avail_in = SvCUR(buf) ;
963
964 /* and the output buffer */
965 output = sv_2mortal(newSV(s->bufinc+1)) ;
966 SvPOK_only(output) ;
967 SvCUR_set(output, 0) ;
968 outsize = s->bufinc ;
969 s->stream.next_out = (Bytef*) SvPVX(output) ;
970 s->stream.avail_out = outsize;
971
972 while (1) {
973
974 if (s->stream.avail_out == 0) {
975 s->bufinc *= 2 ;
976 SvGROW(output, outsize + s->bufinc+1) ;
977 s->stream.next_out = (Bytef*) SvPVX(output) + outsize ;
978 outsize += s->bufinc ;
979 s->stream.avail_out = s->bufinc ;
980 }
981
982 err = inflate(&(s->stream), Z_SYNC_FLUSH);
983 if (err == Z_BUF_ERROR) {
984 if (s->stream.avail_out == 0)
985 continue ;
986 if (s->stream.avail_in == 0) {
987 err = Z_OK ;
988 break ;
989 }
990 }
991
992 if (err == Z_NEED_DICT && s->dictionary) {
993 s->dict_adler = s->stream.adler ;
994 err = inflateSetDictionary(&(s->stream),
995 (const Bytef*)SvPVX(s->dictionary),
996 SvCUR(s->dictionary));
997 }
998
999 if (err != Z_OK)
1000 break;
1001 }
1002
1003 if (err == Z_OK || err == Z_STREAM_END || err == Z_DATA_ERROR) {
1004 unsigned in ;
1005
1006 SvPOK_only(output);
1007 SvCUR_set(output, outsize - s->stream.avail_out) ;
1008 *SvEND(output) = '\0';
1009
1010 /* fix the input buffer */
1011 if (ix == 0) {
1012 in = s->stream.avail_in ;
1013 SvCUR_set(buf, in) ;
1014 if (in)
1015 Move(s->stream.next_in, SvPVX(buf), in, char) ;
1016 *SvEND(buf) = '\0';
1017 SvSETMAGIC(buf);
1018 }
1019 }
1020 else
1021 output = &PL_sv_undef ;
1022 XPUSHs(output) ;
1023 if (GIMME == G_ARRAY)
1024 XPUSHs(sv_2mortal(newSViv(err))) ;
1025
1026int
1027inflateSync (s, buf)
1028 Compress::Zlib::inflateStream s
1029 SV * buf
1030 CODE:
1031
1032 /* If the buffer is a reference, dereference it */
1033 buf = deRef(buf, "inflateSync") ;
1034
1035 /* initialise the input buffer */
1036 s->stream.next_in = (Bytef*)SvPVX(buf) ;
1037 s->stream.avail_in = SvCUR(buf) ;
1038
1039 /* inflateSync doesn't create any output */
1040 s->stream.next_out = (Bytef*) NULL;
1041 s->stream.avail_out = 0;
1042
1043 RETVAL = inflateSync(&(s->stream));
1044 {
1045 /* fix the input buffer */
1046 unsigned in = s->stream.avail_in ;
1047
1048 SvCUR_set(buf, in) ;
1049 if (in)
1050 Move(s->stream.next_in, SvPVX(buf), in, char) ;
1051 *SvEND(buf) = '\0';
1052 SvSETMAGIC(buf);
1053 }
1054 OUTPUT:
1055 RETVAL
1056
1057void
1058DESTROY(s)
1059 Compress::Zlib::inflateStream s
1060 CODE:
1061 inflateEnd(&s->stream) ;
1062 if (s->dictionary)
1063 SvREFCNT_dec(s->dictionary) ;
1064 Safefree(s) ;
1065
1066
1067uLong
1068dict_adler(s)
1069 Compress::Zlib::inflateStream s
1070 CODE:
1071 RETVAL = s->dict_adler ;
1072 OUTPUT:
1073 RETVAL
1074
1075uLong
1076total_in(s)
1077 Compress::Zlib::inflateStream s
1078 CODE:
1079 RETVAL = s->stream.total_in ;
1080 OUTPUT:
1081 RETVAL
1082
1083uLong
1084total_out(s)
1085 Compress::Zlib::inflateStream s
1086 CODE:
1087 RETVAL = s->stream.total_out ;
1088 OUTPUT:
1089 RETVAL
1090
1091char*
1092msg(s)
1093 Compress::Zlib::inflateStream s
1094 CODE:
1095 RETVAL = s->stream.msg;
1096 OUTPUT:
1097 RETVAL
1098
1099