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