Re: Transliteration operator(tr//)on EBCDIC platform
[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
06edba15 4 * Version : 1.35
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
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
06edba15 351unsigned
352ZLIB_VERNUM()
353 CODE:
354#ifdef ZLIB_VERNUM
355 RETVAL = ZLIB_VERNUM ;
356#else
357 /* 1.1.4 => 0x1140 */
358 RETVAL = (ZLIB_VERSION[0] - '0') << 12 ;
359 RETVAL += (ZLIB_VERSION[2] - '0') << 8 ;
360 RETVAL += (ZLIB_VERSION[4] - '0') << 4 ;
361#endif
362 OUTPUT:
363 RETVAL
364
365
f4c6fd49 366
367void
368DispStream(s, message=NULL)
369 Compress::Zlib::inflateStream s
370 char * message
371
372Compress::Zlib::gzFile
373gzopen_(path, mode)
374 char * path
375 char * mode
376 CODE:
377 gzFile gz ;
378 gz = gzopen(path, mode) ;
379 if (gz) {
380 ZMALLOC(RETVAL, gzType) ;
381 RETVAL->buffer = newSV(SIZE) ;
382 SvPOK_only(RETVAL->buffer) ;
383 SvCUR_set(RETVAL->buffer, 0) ;
384 RETVAL->offset = 0 ;
385 RETVAL->gz = gz ;
386 RETVAL->closed = FALSE ;
387 SetGzErrorNo(0) ;
388 }
389 else {
390 RETVAL = NULL ;
391 SetGzErrorNo(errno ? Z_ERRNO : Z_MEM_ERROR) ;
392 }
393 OUTPUT:
394 RETVAL
395
396
397Compress::Zlib::gzFile
398gzdopen_(fh, mode, offset)
399 int fh
400 char * mode
401 long offset
402 CODE:
403 gzFile gz ;
404 if (offset != -1)
405 lseek(fh, offset, 0) ;
406 gz = gzdopen(fh, mode) ;
407 if (gz) {
408 ZMALLOC(RETVAL, gzType) ;
409 RETVAL->buffer = newSV(SIZE) ;
410 SvPOK_only(RETVAL->buffer) ;
411 SvCUR_set(RETVAL->buffer, 0) ;
412 RETVAL->offset = 0 ;
413 RETVAL->gz = gz ;
414 RETVAL->closed = FALSE ;
415 SetGzErrorNo(0) ;
416 }
417 else {
418 RETVAL = NULL ;
419 SetGzErrorNo(errno ? Z_ERRNO : Z_MEM_ERROR) ;
420 }
421 OUTPUT:
422 RETVAL
423
424
425MODULE = Compress::Zlib PACKAGE = Compress::Zlib::gzFile PREFIX = Zip_
426
427#define Zip_gzread(file, buf, len) gzread(file->gz, bufp, len)
428
429int
430Zip_gzread(file, buf, len=4096)
431 Compress::Zlib::gzFile file
432 unsigned len
433 SV * buf
434 voidp bufp = NO_INIT
435 uLong bufsize = 0 ;
436 int RETVAL = 0 ;
437 CODE:
438 if (SvREADONLY(buf) && PL_curcop != &PL_compiling)
439 croak("gzread: buffer parameter is read-only");
f2e5e569 440 SvUPGRADE(buf, SVt_PV);
f4c6fd49 441 SvPOK_only(buf);
442 SvCUR_set(buf, 0);
443 /* any left over from gzreadline ? */
444 if ((bufsize = SvCUR(file->buffer)) > 0) {
445 uLong movesize ;
446
447 if (bufsize < len) {
448 movesize = bufsize ;
449 len -= movesize ;
450 }
451 else {
452 movesize = len ;
453 len = 0 ;
454 }
455 RETVAL = movesize ;
456
457 sv_catpvn(buf, SvPVX(file->buffer) + file->offset, movesize);
458
459 file->offset += movesize ;
460 SvCUR_set(file->buffer, bufsize - movesize) ;
461 }
462
463 if (len) {
464 bufp = (Byte*)SvGROW(buf, bufsize+len+1);
465 RETVAL = gzread(file->gz, ((Bytef*)bufp)+bufsize, len) ;
466 SetGzError(file->gz) ;
467 if (RETVAL >= 0) {
468 RETVAL += bufsize ;
469 SvCUR_set(buf, RETVAL) ;
470 *SvEND(buf) = '\0';
471 }
472 }
473 OUTPUT:
474 RETVAL
475 buf
476
477int
478gzreadline(file, buf)
479 Compress::Zlib::gzFile file
480 SV * buf
481 int RETVAL = 0;
482 CODE:
483 if (SvREADONLY(buf) && PL_curcop != &PL_compiling)
484 croak("gzreadline: buffer parameter is read-only");
f2e5e569 485 SvUPGRADE(buf, SVt_PV);
f4c6fd49 486 SvPOK_only(buf);
487 /* sv_setpvn(buf, "", SIZE) ; */
488 SvGROW(buf, SIZE) ;
489 SvCUR_set(buf, 0);
490 RETVAL = gzreadline(file, buf) ;
491 SetGzError(file->gz) ;
492 OUTPUT:
493 RETVAL
494 buf
495 CLEANUP:
496 if (RETVAL >= 0) {
497 /* SvCUR(buf) = RETVAL; */
498 /* Don't need to explicitly terminate with '\0', because
499 sv_catpvn aready has */
500 }
501
502#define Zip_gzwrite(file, buf) gzwrite(file->gz, buf, (unsigned)len)
503int
504Zip_gzwrite(file, buf)
505 Compress::Zlib::gzFile file
506 STRLEN len = NO_INIT
507 voidp buf = (voidp)SvPV(ST(1), len) ;
508 CLEANUP:
509 SetGzError(file->gz) ;
510
511#define Zip_gzflush(file, flush) gzflush(file->gz, flush)
512int
513Zip_gzflush(file, flush)
514 Compress::Zlib::gzFile file
515 int flush
516 CLEANUP:
517 SetGzError(file->gz) ;
518
06edba15 519#define Zip_gzclose(file) file->closed ? 0 : gzclose(file->gz)
f4c6fd49 520int
521Zip_gzclose(file)
522 Compress::Zlib::gzFile file
523 CLEANUP:
524 file->closed = TRUE ;
525 SetGzErrorNo(RETVAL) ;
526
527
528#define Zip_gzeof(file) gzeof(file->gz)
529int
530Zip_gzeof(file)
531 Compress::Zlib::gzFile file
532 CODE:
533#ifdef OLD_ZLIB
534 croak("gzeof needs zlib 1.0.6 or better") ;
535#else
536 RETVAL = gzeof(file->gz);
537#endif
538 OUTPUT:
539 RETVAL
540
541
542#define Zip_gzsetparams(file,l,s) gzsetparams(file->gz,l,s)
543int
544Zip_gzsetparams(file, level, strategy)
545 Compress::Zlib::gzFile file
546 int level
547 int strategy
548 CODE:
549#ifdef OLD_ZLIB
550 croak("gzsetparams needs zlib 1.0.6 or better") ;
551#else
552 RETVAL = gzsetparams(file->gz, level, strategy);
553#endif
554 OUTPUT:
555 RETVAL
556
557void
558DESTROY(file)
559 Compress::Zlib::gzFile file
560 CODE:
561 if (! file->closed)
562 Zip_gzclose(file) ;
563 SvREFCNT_dec(file->buffer) ;
564 safefree((char*)file) ;
565
566#define Zip_gzerror(file) (char*)gzerror(file->gz, &errnum)
567
568char *
569Zip_gzerror(file)
570 Compress::Zlib::gzFile file
571 int errnum = NO_INIT
572 CLEANUP:
573 sv_setiv(ST(0), errnum) ;
574 SvPOK_on(ST(0)) ;
575
576
577
578MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_
579
580
581#define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
582
583uLong
584Zip_adler32(buf, adler=adlerInitial)
585 uLong adler = NO_INIT
586 STRLEN len = NO_INIT
587 Bytef * buf = NO_INIT
588 SV * sv = ST(0) ;
589 INIT:
590 /* If the buffer is a reference, dereference it */
591 sv = deRef(sv, "adler32") ;
592 buf = (Byte*)SvPV(sv, len) ;
593
594 if (items < 2)
595 adler = adlerInitial;
596 else if (SvOK(ST(1)))
597 adler = SvUV(ST(1)) ;
598 else
599 adler = adlerInitial;
600
601#define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len)
602
603uLong
604Zip_crc32(buf, crc=crcInitial)
605 uLong crc = 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, "crc32") ;
612 buf = (Byte*)SvPV(sv, len) ;
613
614 if (items < 2)
615 crc = crcInitial;
616 else if (SvOK(ST(1)))
617 crc = SvUV(ST(1)) ;
618 else
619 crc = crcInitial;
620
621MODULE = Compress::Zlib PACKAGE = Compress::Zlib
622
623void
624_deflateInit(level, method, windowBits, memLevel, strategy, bufsize, dictionary)
625 int level
626 int method
627 int windowBits
628 int memLevel
629 int strategy
630 uLong bufsize
631 SV * dictionary
632 PPCODE:
633
634 int err ;
635 deflateStream s ;
636
637 if (trace)
638 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%d\n",
639 level, method, windowBits, memLevel, strategy, bufsize) ;
640 if ((s = InitStream(bufsize)) ) {
641
642 s->Level = level;
643 s->Method = method;
644 s->WindowBits = windowBits;
645 s->MemLevel = memLevel;
646 s->Strategy = strategy;
647
648 err = deflateInit2(&(s->stream), level,
649 method, windowBits, memLevel, strategy);
650
651 /* Check if a dictionary has been specified */
652 if (err == Z_OK && SvCUR(dictionary)) {
653 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary),
654 SvCUR(dictionary)) ;
655 s->dict_adler = s->stream.adler ;
656 }
657
658 if (err != Z_OK) {
659 Safefree(s) ;
660 s = NULL ;
661 }
662
663 }
664 else
665 err = Z_MEM_ERROR ;
666
667 XPUSHs(sv_setref_pv(sv_newmortal(),
668 "Compress::Zlib::deflateStream", (void*)s));
669 if (GIMME == G_ARRAY)
670 XPUSHs(sv_2mortal(newSViv(err))) ;
671
672void
673_inflateInit(windowBits, bufsize, dictionary)
674 int windowBits
675 uLong bufsize
676 SV * dictionary
677 PPCODE:
678
679 int err = Z_OK ;
680 inflateStream s ;
681
682 if (trace)
683 warn("in _inflateInit(windowBits=%d, bufsize=%d, dictionary=%d\n",
684 windowBits, bufsize, SvCUR(dictionary)) ;
685 if ((s = InitStream(bufsize)) ) {
686
687 s->WindowBits = windowBits;
688
689 err = inflateInit2(&(s->stream), windowBits);
690
691 if (err != Z_OK) {
692 Safefree(s) ;
693 s = NULL ;
694 }
695 else if (SvCUR(dictionary)) {
696 /* Dictionary specified - take a copy for use in inflate */
697 s->dictionary = newSVsv(dictionary) ;
698 }
699 }
700 else
701 err = Z_MEM_ERROR ;
702
703 XPUSHs(sv_setref_pv(sv_newmortal(),
704 "Compress::Zlib::inflateStream", (void*)s));
705 if (GIMME == G_ARRAY)
706 XPUSHs(sv_2mortal(newSViv(err))) ;
707
708
709
710MODULE = Compress::Zlib PACKAGE = Compress::Zlib::deflateStream
711
712void
713DispStream(s, message=NULL)
714 Compress::Zlib::deflateStream s
715 char * message
716
717void
718deflate (s, buf)
719 Compress::Zlib::deflateStream s
720 SV * buf
721 uLong outsize = NO_INIT
722 SV * output = NO_INIT
723 int err = 0;
724 PPCODE:
725
726 /* If the buffer is a reference, dereference it */
727 buf = deRef(buf, "deflate") ;
728
729 /* initialise the input buffer */
730 s->stream.next_in = (Bytef*)SvPV(buf, *(STRLEN*)&s->stream.avail_in) ;
731 /* s->stream.next_in = (Bytef*)SvPVX(buf); */
732 s->stream.avail_in = SvCUR(buf) ;
733
734 /* and the output buffer */
735 /* output = sv_2mortal(newSVpv("", s->bufinc)) ; */
736 output = sv_2mortal(newSV(s->bufinc)) ;
737 SvPOK_only(output) ;
738 SvCUR_set(output, 0) ;
739 outsize = s->bufinc ;
740 s->stream.next_out = (Bytef*) SvPVX(output) ;
741 s->stream.avail_out = outsize;
742
743 /* Check for saved output from deflateParams */
744 if (s->deflateParams_out_valid) {
745 *(s->stream.next_out) = s->deflateParams_out_byte;
746 ++ s->stream.next_out;
747 -- s->stream.avail_out ;
748 s->deflateParams_out_valid = FALSE;
749 }
750
751 while (s->stream.avail_in != 0) {
752
753 if (s->stream.avail_out == 0) {
754 s->bufinc *= 2 ;
755 SvGROW(output, outsize + s->bufinc) ;
756 s->stream.next_out = (Bytef*) SvPVX(output) + outsize ;
757 outsize += s->bufinc ;
758 s->stream.avail_out = s->bufinc ;
759 }
760 err = deflate(&(s->stream), Z_NO_FLUSH);
761 if (err != Z_OK)
762 break;
763 }
764
765 if (err == Z_OK) {
766 SvPOK_only(output);
767 SvCUR_set(output, outsize - s->stream.avail_out) ;
768 }
769 else
770 output = &PL_sv_undef ;
771 XPUSHs(output) ;
772 if (GIMME == G_ARRAY)
773 XPUSHs(sv_2mortal(newSViv(err))) ;
774
775
776
777void
778flush(s, f=Z_FINISH)
779 Compress::Zlib::deflateStream s
780 int f
781 uLong outsize = NO_INIT
782 SV * output = NO_INIT
783 int err = Z_OK ;
784 PPCODE:
785
786 s->stream.avail_in = 0; /* should be zero already anyway */
787
788 /* output = sv_2mortal(newSVpv("", s->bufinc)) ; */
789 output = sv_2mortal(newSV(s->bufinc)) ;
790 SvPOK_only(output) ;
791 SvCUR_set(output, 0) ;
792 outsize = s->bufinc ;
793 s->stream.next_out = (Bytef*) SvPVX(output) ;
794 s->stream.avail_out = outsize;
795
796 /* Check for saved output from deflateParams */
797 if (s->deflateParams_out_valid) {
798 *(s->stream.next_out) = s->deflateParams_out_byte;
799 ++ s->stream.next_out;
800 -- s->stream.avail_out ;
801 s->deflateParams_out_valid = FALSE;
802 }
803
804 for (;;) {
805 if (s->stream.avail_out == 0) {
806 /* consumed all the available output, so extend it */
807 s->bufinc *= 2 ;
808 SvGROW(output, outsize + s->bufinc) ;
809 s->stream.next_out = (Bytef*)SvPVX(output) + outsize ;
810 outsize += s->bufinc ;
811 s->stream.avail_out = s->bufinc ;
812 }
813 err = deflate(&(s->stream), f);
814
815 /* deflate has finished flushing only when it hasn't used up
816 * all the available space in the output buffer:
817 */
818 if (s->stream.avail_out != 0 || err != Z_OK )
819 break;
820 }
821
822 err = (err == Z_STREAM_END ? Z_OK : err) ;
823
824 if (err == Z_OK) {
825 SvPOK_only(output);
826 SvCUR_set(output, outsize - s->stream.avail_out) ;
827 }
828 else
829 output = &PL_sv_undef ;
830 XPUSHs(output) ;
831 if (GIMME == G_ARRAY)
832 XPUSHs(sv_2mortal(newSViv(err))) ;
833
834int
835_deflateParams(s, flags, level, strategy, bufsize)
836 Compress::Zlib::deflateStream s
837 int flags
838 int level
839 int strategy
840 uLong bufsize
841 CODE:
842 if (flags & 1)
843 s->Level = level ;
844 if (flags & 2)
845 s->Strategy = strategy ;
846 if (bufsize) {
847 s->bufsize = bufsize;
848 s->bufinc = bufsize;
849 }
850 s->stream.avail_in = 0;
851 s->stream.next_out = &(s->deflateParams_out_byte) ;
852 s->stream.avail_out = 1;
853 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
854 s->deflateParams_out_valid =
855 (RETVAL == Z_OK && s->stream.avail_out == 0) ;
856 OUTPUT:
857 RETVAL
858
859
860int
861get_Level(s)
862 Compress::Zlib::deflateStream s
863 CODE:
864 RETVAL = s->Level ;
865 OUTPUT:
866 RETVAL
867
868int
869get_Strategy(s)
870 Compress::Zlib::deflateStream s
871 CODE:
872 RETVAL = s->Strategy ;
873 OUTPUT:
874 RETVAL
875
876void
877DESTROY(s)
878 Compress::Zlib::deflateStream s
879 CODE:
880 deflateEnd(&s->stream) ;
881 if (s->dictionary)
882 SvREFCNT_dec(s->dictionary) ;
883 Safefree(s) ;
884
885
886uLong
887dict_adler(s)
888 Compress::Zlib::deflateStream s
889 CODE:
890 RETVAL = s->dict_adler ;
891 OUTPUT:
892 RETVAL
893
894uLong
895total_in(s)
896 Compress::Zlib::deflateStream s
897 CODE:
898 RETVAL = s->stream.total_in ;
899 OUTPUT:
900 RETVAL
901
902uLong
903total_out(s)
904 Compress::Zlib::deflateStream s
905 CODE:
906 RETVAL = s->stream.total_out ;
907 OUTPUT:
908 RETVAL
909
910char*
911msg(s)
912 Compress::Zlib::deflateStream s
913 CODE:
914 RETVAL = s->stream.msg;
915 OUTPUT:
916 RETVAL
917
918
919MODULE = Compress::Zlib PACKAGE = Compress::Zlib::inflateStream
920
921void
922DispStream(s, message=NULL)
923 Compress::Zlib::inflateStream s
924 char * message
925
926void
927inflate (s, buf)
928 Compress::Zlib::inflateStream s
929 SV * buf
930 uLong outsize = NO_INIT
931 SV * output = NO_INIT
932 int err = Z_OK ;
933 ALIAS:
934 __unc_inflate = 1
935 PPCODE:
936
937 /* If the buffer is a reference, dereference it */
938 buf = deRef(buf, "inflate") ;
939
940 /* initialise the input buffer */
941 s->stream.next_in = (Bytef*)SvPVX(buf) ;
942 s->stream.avail_in = SvCUR(buf) ;
943
944 /* and the output buffer */
945 output = sv_2mortal(newSV(s->bufinc+1)) ;
946 SvPOK_only(output) ;
947 SvCUR_set(output, 0) ;
948 outsize = s->bufinc ;
949 s->stream.next_out = (Bytef*) SvPVX(output) ;
950 s->stream.avail_out = outsize;
951
952 while (1) {
953
954 if (s->stream.avail_out == 0) {
955 s->bufinc *= 2 ;
956 SvGROW(output, outsize + s->bufinc+1) ;
957 s->stream.next_out = (Bytef*) SvPVX(output) + outsize ;
958 outsize += s->bufinc ;
959 s->stream.avail_out = s->bufinc ;
960 }
961
962 err = inflate(&(s->stream), Z_SYNC_FLUSH);
963 if (err == Z_BUF_ERROR) {
964 if (s->stream.avail_out == 0)
965 continue ;
966 if (s->stream.avail_in == 0) {
967 err = Z_OK ;
968 break ;
969 }
970 }
971
972 if (err == Z_NEED_DICT && s->dictionary) {
973 s->dict_adler = s->stream.adler ;
974 err = inflateSetDictionary(&(s->stream),
975 (const Bytef*)SvPVX(s->dictionary),
976 SvCUR(s->dictionary));
977 }
978
979 if (err != Z_OK)
980 break;
981 }
982
983 if (err == Z_OK || err == Z_STREAM_END || err == Z_DATA_ERROR) {
984 unsigned in ;
985
986 SvPOK_only(output);
987 SvCUR_set(output, outsize - s->stream.avail_out) ;
988 *SvEND(output) = '\0';
989
990 /* fix the input buffer */
991 if (ix == 0) {
992 in = s->stream.avail_in ;
993 SvCUR_set(buf, in) ;
994 if (in)
995 Move(s->stream.next_in, SvPVX(buf), in, char) ;
996 *SvEND(buf) = '\0';
997 SvSETMAGIC(buf);
998 }
999 }
1000 else
1001 output = &PL_sv_undef ;
1002 XPUSHs(output) ;
1003 if (GIMME == G_ARRAY)
1004 XPUSHs(sv_2mortal(newSViv(err))) ;
1005
1006int
1007inflateSync (s, buf)
1008 Compress::Zlib::inflateStream s
1009 SV * buf
1010 CODE:
1011
1012 /* If the buffer is a reference, dereference it */
1013 buf = deRef(buf, "inflateSync") ;
1014
1015 /* initialise the input buffer */
1016 s->stream.next_in = (Bytef*)SvPVX(buf) ;
1017 s->stream.avail_in = SvCUR(buf) ;
1018
1019 /* inflateSync doesn't create any output */
1020 s->stream.next_out = (Bytef*) NULL;
1021 s->stream.avail_out = 0;
1022
1023 RETVAL = inflateSync(&(s->stream));
1024 {
1025 /* fix the input buffer */
1026 unsigned in = s->stream.avail_in ;
1027
1028 SvCUR_set(buf, in) ;
1029 if (in)
1030 Move(s->stream.next_in, SvPVX(buf), in, char) ;
1031 *SvEND(buf) = '\0';
1032 SvSETMAGIC(buf);
1033 }
1034 OUTPUT:
1035 RETVAL
1036
1037void
1038DESTROY(s)
1039 Compress::Zlib::inflateStream s
1040 CODE:
1041 inflateEnd(&s->stream) ;
1042 if (s->dictionary)
1043 SvREFCNT_dec(s->dictionary) ;
1044 Safefree(s) ;
1045
1046
1047uLong
1048dict_adler(s)
1049 Compress::Zlib::inflateStream s
1050 CODE:
1051 RETVAL = s->dict_adler ;
1052 OUTPUT:
1053 RETVAL
1054
1055uLong
1056total_in(s)
1057 Compress::Zlib::inflateStream s
1058 CODE:
1059 RETVAL = s->stream.total_in ;
1060 OUTPUT:
1061 RETVAL
1062
1063uLong
1064total_out(s)
1065 Compress::Zlib::inflateStream s
1066 CODE:
1067 RETVAL = s->stream.total_out ;
1068 OUTPUT:
1069 RETVAL
1070
1071char*
1072msg(s)
1073 Compress::Zlib::inflateStream s
1074 CODE:
1075 RETVAL = s->stream.msg;
1076 OUTPUT:
1077 RETVAL
1078
1079