fix smoke issues with the compression modules
[p5sagit/p5-mst-13.2.git] / ext / Compress-Raw-Bzip2 / Bzip2.xs
CommitLineData
bdb7fd9f 1/* Filename: Bzip2.xs
2 * Author : Paul Marquess, <pmqs@cpan.org>
3 * Created : 5th October 2005
4 * Version : 2.000
5 *
6 * Copyright (c) 2005-2007 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
13#include "EXTERN.h"
14#include "perl.h"
15#include "XSUB.h"
16
17#include "bzlib.h"
18
19#ifdef USE_PPPORT_H
20# define NEED_sv_2pv_nolen
21# include "ppport.h"
22#endif
23
24#if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
25
26# ifdef SvPVbyte_force
27# undef SvPVbyte_force
28# endif
29
30# define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
31
32#endif
33
34#ifndef SvPVbyte_nolen
35# define SvPVbyte_nolen SvPV_nolen
36#endif
37
38
39#if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
40# define UTF8_AVAILABLE
41#endif
42
43typedef int DualType ;
44typedef int int_undef ;
45
46typedef unsigned long uLong;
47typedef unsigned int uInt;
48
49typedef struct di_stream {
50 int flags ;
51#define FLAG_APPEND_OUTPUT 1
52#define FLAG_CONSUME_INPUT 8
53 bz_stream stream;
54 uInt bufsize;
55 int last_error ;
56 uLong bytesInflated ;
57 uLong compressedBytes ;
58 uLong uncompressedBytes ;
59
60} di_stream;
61
62typedef di_stream * deflateStream ;
63typedef di_stream * Compress__Raw__Bzip2 ;
64
65typedef di_stream * inflateStream ;
66typedef di_stream * Compress__Raw__Bunzip2 ;
67
68#define COMPRESS_CLASS "Compress::Raw::Bzip2"
69#define UNCOMPRESS_CLASS "Compress::Raw::Bunzip2"
70
71#define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
72 Zero(to,1,typ))
73
74
75/* static const char * const my_z_errmsg[] = { */
76static const char my_z_errmsg[][32] = {
77 "End of Stream", /* BZ_STREAM_END 4 */
78 "Finish OK", /* BZ_FINISH_OK 3 */
79 "Flush OK", /* BZ_FLUSH_OK 2 */
80 "Run OK", /* BZ_RUN_OK 1 */
81 "", /* BZ_OK 0 */
82 "Sequence Error", /* BZ_SEQUENCE_ERROR (-1) */
83 "Param Error", /* BZ_PARAM_ERROR (-2) */
84 "Memory Error", /* BZ_MEM_ERROR (-3) */
85 "Data Error", /* BZ_DATA_ERROR (-4) */
86 "Magic Error", /* BZ_DATA_ERROR_MAGIC (-5) */
87 "IO Error", /* BZ_IO_ERROR (-6) */
88 "Unexpected EOF", /* BZ_UNEXPECTED_EOF (-7) */
89 "Output Buffer Full", /* BZ_OUTBUFF_FULL (-8) */
90 "Config Error", /* BZ_CONFIG_ERROR (-9) */
91 ""};
92
93#define setDUALstatus(var, err) \
94 sv_setnv(var, (double)err) ; \
95 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \
96 SvNOK_on(var);
97
98
99#if defined(__SYMBIAN32__)
100# define NO_WRITEABLE_DATA
101#endif
102
103#define TRACE_DEFAULT 0
104
105#ifdef NO_WRITEABLE_DATA
106# define trace TRACE_DEFAULT
107#else
108 static int trace = TRACE_DEFAULT ;
109#endif
110
111/* Dodge PerlIO hiding of these functions. */
112#undef printf
113
114#if 1
115#define getInnerObject(x) (*av_fetch((AV*)SvRV(x), 0, FALSE))
116#else
117#define getInnerObject(x) ((SV*)SvRV(sv))
118#endif
119
120#ifdef BZ_NO_STDIO
121void bz_internal_error(int errorcode)
122{
123 croak("bz_internal_error %d\n", errorcode);
124}
125#endif
126
127static char *
128#ifdef CAN_PROTOTYPE
129GetErrorString(int error_no)
130#else
131GetErrorString(error_no)
132int error_no ;
133#endif
134{
135 dTHX;
136 char * errstr ;
137
138#if 0
139 if (error_no == BZ_ERRNO) {
140 errstr = Strerror(errno) ;
141 }
142 else
143#endif
144 errstr = (char*) my_z_errmsg[4 - error_no];
145
146 return errstr ;
147}
148
149static void
150#ifdef CAN_PROTOTYPE
151DispHex(void * ptr, int length)
152#else
153DispHex(ptr, length)
154 void * ptr;
155 int length;
156#endif
157{
158 char * p = (char*)ptr;
159 int i;
160 for (i = 0; i < length; ++i) {
161 printf(" %02x", 0xFF & *(p+i));
162 }
163}
164
165
166static void
167#ifdef CAN_PROTOTYPE
168DispStream(di_stream * s, char * message)
169#else
170DispStream(s, message)
171 di_stream * s;
172 char * message;
173#endif
174{
175
176#if 0
177 if (! trace)
178 return ;
179#endif
180
181#define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
182
183 printf("DispStream 0x%p", s) ;
184 if (message)
185 printf("- %s \n", message) ;
186 printf("\n") ;
187
188 if (!s) {
189 printf(" stream pointer is NULL\n");
190 }
191 else {
192 printf(" stream 0x%p\n", &(s->stream));
193 printf(" opaque 0x%p\n", s->stream.opaque);
194 printf(" next_in 0x%p", s->stream.next_in);
195 if (s->stream.next_in){
196 printf(" =>");
197 DispHex(s->stream.next_in, 4);
198 }
199 printf("\n");
200
201 printf(" next_out 0x%p", s->stream.next_out);
202 if (s->stream.next_out){
203 printf(" =>");
204 DispHex(s->stream.next_out, 4);
205 }
206 printf("\n");
207
208 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in);
209 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out);
210 printf(" bufsize %lu\n", (unsigned long)s->bufsize);
211 printf(" flags 0x%x\n", s->flags);
212 printf(" APPEND %s\n", EnDis(FLAG_APPEND_OUTPUT));
213 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT));
214
215 printf("\n");
216
217 }
218}
219
220static di_stream *
221#ifdef CAN_PROTOTYPE
222InitStream(void)
223#else
224InitStream()
225#endif
226{
227 di_stream *s ;
228
229 ZMALLOC(s, di_stream) ;
230
231 return s ;
232
233}
234
235static void
236#ifdef CAN_PROTOTYPE
237PostInitStream(di_stream * s, int flags)
238#else
239PostInitStream(s, flags)
240 di_stream *s ;
241 int flags ;
242#endif
243{
244 s->bufsize = 1024 * 16 ;
245 s->last_error = 0 ;
246 s->flags = flags ;
247}
248
249
250static SV*
251#ifdef CAN_PROTOTYPE
252deRef(SV * sv, const char * string)
253#else
254deRef(sv, string)
255SV * sv ;
256char * string;
257#endif
258{
259 dTHX;
260 SvGETMAGIC(sv);
261
262 if (SvROK(sv)) {
263 sv = SvRV(sv) ;
264 SvGETMAGIC(sv);
265 switch(SvTYPE(sv)) {
266 case SVt_PVAV:
267 case SVt_PVHV:
268 case SVt_PVCV:
269 croak("%s: buffer parameter is not a SCALAR reference", string);
776304fb 270 default:
271 break;
bdb7fd9f 272 }
273 if (SvROK(sv))
274 croak("%s: buffer parameter is a reference to a reference", string) ;
275 }
276
277 if (!SvOK(sv)) {
278 sv = newSVpv("", 0);
279 }
280
281 return sv ;
282}
283
284static SV*
285#ifdef CAN_PROTOTYPE
286deRef_l(SV * sv, const char * string)
287#else
288deRef_l(sv, string)
289SV * sv ;
290char * string ;
291#endif
292{
293 dTHX;
294 bool wipe = 0 ;
295
296 SvGETMAGIC(sv);
297 wipe = ! SvOK(sv) ;
298
299 if (SvROK(sv)) {
300 sv = SvRV(sv) ;
301 SvGETMAGIC(sv);
302 wipe = ! SvOK(sv) ;
303
304 switch(SvTYPE(sv)) {
305 case SVt_PVAV:
306 case SVt_PVHV:
307 case SVt_PVCV:
308 croak("%s: buffer parameter is not a SCALAR reference", string);
776304fb 309 default:
310 break;
bdb7fd9f 311 }
312 if (SvROK(sv))
313 croak("%s: buffer parameter is a reference to a reference", string) ;
314 }
315
316 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
317 croak("%s: buffer parameter is read-only", string);
318
319 SvUPGRADE(sv, SVt_PV);
320
321 if (wipe)
322 SvCUR_set(sv, 0);
323
324 SvOOK_off(sv);
325 SvPOK_only(sv);
326
327 return sv ;
328}
329
330
331#include "constants.h"
332
333MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2 PREFIX = Zip_
334
335REQUIRE: 1.924
336PROTOTYPES: DISABLE
337
338INCLUDE: constants.xs
339
340BOOT:
341 /* Check this version of bzip2 is == 1 */
342 if (BZ2_bzlibVersion()[0] != '1')
343 croak(COMPRESS_CLASS " needs bzip2 version 1.x, you have %s\n", BZ2_bzlibVersion()) ;
344
345
346MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2
347
348#define bzlibversion() BZ2_bzlibVersion()
349const char *
350bzlibversion()
351
352void
353new(class, appendOut=1, blockSize100k=1, workfactor=0, verbosity=0)
354 const char * class
355 int appendOut
356 int blockSize100k
357 int workfactor
358 int verbosity
359 PPCODE:
360 {
361 int err ;
362 deflateStream s ;
363#if 0
364 /* if (trace) */
365 warn("in Compress::Raw::Bzip2::_new(items=%d,appendOut=%d, blockSize100k=%d, workfactor=%d, verbosity=%d\n",
366 items, appendOut, blockSize100k, workfactor, verbosity);
367#endif
368 if ((s = InitStream() )) {
369
370 err = BZ2_bzCompressInit ( &(s->stream),
371 blockSize100k,
372 verbosity,
373 workfactor );
374
375 if (err != BZ_OK) {
376 Safefree(s) ;
377 s = NULL ;
378 }
379 else {
380 int flags = 0 ;
381 if (appendOut)
382 flags |= FLAG_APPEND_OUTPUT;
383 PostInitStream(s, appendOut ? FLAG_APPEND_OUTPUT :0) ;
384 }
385 }
386 else
387 err = BZ_MEM_ERROR ;
388
389 {
390 SV* obj = sv_setref_pv(sv_newmortal(), class, (void*)s);
391 XPUSHs(obj);
392 }
393 if(0)
394 {
395 SV* obj = sv_2mortal(newSViv(PTR2IV(s))) ;
396 XPUSHs(obj);
397 }
398 if (GIMME == G_ARRAY) {
399 SV * sv = sv_2mortal(newSViv(err)) ;
400 setDUALstatus(sv, err);
401 XPUSHs(sv) ;
402 }
403 }
404
405MODULE = Compress::Raw::Bunzip2 PACKAGE = Compress::Raw::Bunzip2
406
407void
408new(class, appendOut=1 , consume=1, small=0, verbosity=0)
409 const char* class
410 int appendOut
411 int consume
412 int small
413 int verbosity
414 PPCODE:
415 {
416 int err = BZ_OK ;
417 inflateStream s ;
418#if 0
419 if (trace)
420 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
421 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
422#endif
423 if ((s = InitStream() )) {
424
425 err = BZ2_bzDecompressInit (&(s->stream), verbosity, small);
426 if (err != BZ_OK) {
427 Safefree(s) ;
428 s = NULL ;
429 }
430 if (s) {
431 int flags = 0;
432 if (appendOut)
433 flags |= FLAG_APPEND_OUTPUT;
434 if (consume)
435 flags |= FLAG_CONSUME_INPUT;
436 PostInitStream(s, flags) ;
437 }
438 }
439 else
440 err = BZ_MEM_ERROR ;
441
442 {
443 SV* obj = sv_setref_pv(sv_newmortal(), class, (void*)s);
444 XPUSHs(obj);
445 }
446 if (0)
447 {
448 SV* obj = sv_2mortal(newSViv(PTR2IV(s))) ;
449 XPUSHs(obj);
450 }
451 if (GIMME == G_ARRAY) {
452 SV * sv = sv_2mortal(newSViv(err)) ;
453 setDUALstatus(sv, err);
454 XPUSHs(sv) ;
455 }
456 }
457
458
459
460MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2
461
462void
463DispStream(s, message=NULL)
464 Compress::Raw::Bzip2 s
465 char * message
466
467DualType
468bzdeflate (s, buf, output)
469 Compress::Raw::Bzip2 s
470 SV * buf
471 SV * output
472 uInt cur_length = NO_INIT
473 uInt increment = NO_INIT
474 int RETVAL = 0;
475 uInt bufinc = NO_INIT
476 CODE:
477 bufinc = s->bufsize;
478
479 /* If the input buffer is a reference, dereference it */
480 buf = deRef(buf, "deflate") ;
481
482 /* initialise the input buffer */
483#ifdef UTF8_AVAILABLE
484 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
485 croak("Wide character in " COMPRESS_CLASS "::bzdeflate input parameter");
486#endif
487 s->stream.next_in = (char*)SvPVbyte_nolen(buf) ;
488 s->stream.avail_in = SvCUR(buf) ;
489
490 /* and retrieve the output buffer */
491 output = deRef_l(output, "deflate") ;
492#ifdef UTF8_AVAILABLE
493 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
494 croak("Wide character in " COMPRESS_CLASS "::bzdeflate output parameter");
495#endif
496
497 if((s->flags & FLAG_APPEND_OUTPUT) != FLAG_APPEND_OUTPUT) {
498 SvCUR_set(output, 0);
499 /* sv_setpvn(output, "", 0); */
500 }
501 cur_length = SvCUR(output) ;
502 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
503 increment = SvLEN(output) - cur_length;
504 s->stream.avail_out = increment;
505 while (s->stream.avail_in != 0) {
506
507 if (s->stream.avail_out == 0) {
508 /* out of space in the output buffer so make it bigger */
509 Sv_Grow(output, SvLEN(output) + bufinc) ;
510 cur_length += increment ;
511 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
512 increment = bufinc ;
513 s->stream.avail_out = increment;
514 bufinc *= 2 ;
515 }
516
517 RETVAL = BZ2_bzCompress(&(s->stream), BZ_RUN);
518 if (RETVAL != BZ_RUN_OK)
519 break;
520 }
521
522 s->compressedBytes += cur_length + increment - s->stream.avail_out ;
523 s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
524
525 s->last_error = RETVAL ;
526 if (RETVAL == BZ_RUN_OK) {
527 SvPOK_only(output);
528 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
529 SvSETMAGIC(output);
530 }
531 OUTPUT:
532 RETVAL
533
534
535void
536DESTROY(s)
537 Compress::Raw::Bzip2 s
538 CODE:
539 BZ2_bzCompressEnd(&s->stream) ;
540 Safefree(s) ;
541
542
543DualType
544bzclose(s, output)
545 Compress::Raw::Bzip2 s
546 SV * output
547 uInt cur_length = NO_INIT
548 uInt increment = NO_INIT
549 uInt bufinc = NO_INIT
550 CODE:
551 bufinc = s->bufsize;
552
553 s->stream.avail_in = 0; /* should be zero already anyway */
554
555 /* retrieve the output buffer */
556 output = deRef_l(output, "close") ;
557#ifdef UTF8_AVAILABLE
558 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
559 croak("Wide character in " COMPRESS_CLASS "::bzclose input parameter");
560#endif
561 if(! s->flags & FLAG_APPEND_OUTPUT) {
562 SvCUR_set(output, 0);
563 /* sv_setpvn(output, "", 0); */
564 }
565 cur_length = SvCUR(output) ;
566 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
567 increment = SvLEN(output) - cur_length;
568 s->stream.avail_out = increment;
569
570 for (;;) {
571 if (s->stream.avail_out == 0) {
572 /* consumed all the available output, so extend it */
573 Sv_Grow(output, SvLEN(output) + bufinc) ;
574 cur_length += increment ;
575 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
576 increment = bufinc ;
577 s->stream.avail_out = increment;
578 bufinc *= 2 ;
579 }
580 RETVAL = BZ2_bzCompress(&(s->stream), BZ_FINISH);
581
582 /* deflate has finished flushing only when it hasn't used up
583 * all the available space in the output buffer:
584 */
585 /* if (s->stream.avail_out != 0 || RETVAL < 0 ) */
586 if (RETVAL == BZ_STREAM_END || RETVAL < 0 )
587 break;
588 }
589
590 /* RETVAL = (RETVAL == BZ_STREAM_END ? BZ_OK : RETVAL) ; */
591 s->last_error = RETVAL ;
592
593 s->compressedBytes += cur_length + increment - s->stream.avail_out ;
594
595 if (RETVAL == BZ_STREAM_END) {
596 SvPOK_only(output);
597 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
598 SvSETMAGIC(output);
599 }
600 OUTPUT:
601 RETVAL
602
603
604DualType
605bzflush(s, output)
606 Compress::Raw::Bzip2 s
607 SV * output
608 uInt cur_length = NO_INIT
609 uInt increment = NO_INIT
610 uInt bufinc = NO_INIT
611 CODE:
612 bufinc = s->bufsize;
613
614 s->stream.avail_in = 0; /* should be zero already anyway */
615
616 /* retrieve the output buffer */
617 output = deRef_l(output, "close") ;
618#ifdef UTF8_AVAILABLE
619 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
620 croak("Wide character in " COMPRESS_CLASS "::bzflush input parameter");
621#endif
622 if(! s->flags & FLAG_APPEND_OUTPUT) {
623 SvCUR_set(output, 0);
624 /* sv_setpvn(output, "", 0); */
625 }
626 cur_length = SvCUR(output) ;
627 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
628 increment = SvLEN(output) - cur_length;
629 s->stream.avail_out = increment;
630
631 for (;;) {
632 if (s->stream.avail_out == 0) {
633 /* consumed all the available output, so extend it */
634 Sv_Grow(output, SvLEN(output) + bufinc) ;
635 cur_length += increment ;
636 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
637 increment = bufinc ;
638 s->stream.avail_out = increment;
639 bufinc *= 2 ;
640 }
641 RETVAL = BZ2_bzCompress(&(s->stream), BZ_FLUSH);
642
643 if (RETVAL == BZ_RUN_OK || RETVAL < 0)
644 break;
645
646 /* deflate has finished flushing only when it hasn't used up
647 * all the available space in the output buffer:
648 */
649 /* RETVAL == if (s->stream.avail_out != 0 || RETVAL < 0 )
650 break; */
651 }
652
653 /* RETVAL = (RETVAL == BZ_STREAM_END ? BZ_OK : RETVAL) ; */
654 s->last_error = RETVAL ;
655
656 s->compressedBytes += cur_length + increment - s->stream.avail_out ;
657
658 if (RETVAL == BZ_RUN_OK) {
659 SvPOK_only(output);
660 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
661 SvSETMAGIC(output);
662 }
663 OUTPUT:
664 RETVAL
665
666uLong
667total_in_lo32(s)
668 Compress::Raw::Bzip2 s
669 CODE:
670 RETVAL = s->stream.total_in_lo32 ;
671 OUTPUT:
672 RETVAL
673
674uLong
675total_out_lo32(s)
676 Compress::Raw::Bzip2 s
677 CODE:
678 RETVAL = s->stream.total_out_lo32 ;
679 OUTPUT:
680 RETVAL
681
682uLong
683compressedBytes(s)
684 Compress::Raw::Bzip2 s
685 CODE:
686 RETVAL = s->compressedBytes;
687 OUTPUT:
688 RETVAL
689
690uLong
691uncompressedBytes(s)
692 Compress::Raw::Bzip2 s
693 CODE:
694 RETVAL = s->uncompressedBytes;
695 OUTPUT:
696 RETVAL
697
698
699MODULE = Compress::Raw::Bunzip2 PACKAGE = Compress::Raw::Bunzip2
700
701void
702DispStream(s, message=NULL)
703 Compress::Raw::Bunzip2 s
704 char * message
705
706DualType
707bzinflate (s, buf, output)
708 Compress::Raw::Bunzip2 s
709 SV * buf
710 SV * output
711 uInt cur_length = 0;
712 uInt prefix_length = 0;
713 uInt increment = 0;
714 STRLEN stmp = NO_INIT
715 uInt bufinc = NO_INIT
716 PREINIT:
717#ifdef UTF8_AVAILABLE
718 bool out_utf8 = FALSE;
719#endif
720 CODE:
721 bufinc = s->bufsize;
722 /* If the buffer is a reference, dereference it */
723 buf = deRef(buf, "inflate") ;
724
725 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
726 croak(UNCOMPRESS_CLASS "::bzinflate input parameter cannot be read-only when ConsumeInput is specified");
727#ifdef UTF8_AVAILABLE
728 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
729 croak("Wide character in " UNCOMPRESS_CLASS "::bzinflate input parameter");
730#endif
731
732 /* initialise the input buffer */
733 s->stream.next_in = (char*)SvPVbyte_force(buf, stmp) ;
734 s->stream.avail_in = SvCUR(buf);
735
736 /* and retrieve the output buffer */
737 output = deRef_l(output, "inflate") ;
738#ifdef UTF8_AVAILABLE
739 if (DO_UTF8(output))
740 out_utf8 = TRUE ;
741 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
742 croak("Wide character in " UNCOMPRESS_CLASS "::bzinflate output parameter");
743#endif
744 if((s->flags & FLAG_APPEND_OUTPUT) != FLAG_APPEND_OUTPUT) {
745 SvCUR_set(output, 0);
746 }
747 if (SvLEN(output)) {
748 prefix_length = cur_length = SvCUR(output) ;
749 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
750 increment = SvLEN(output) - cur_length - 1;
751 s->stream.avail_out = increment;
752 }
753 else {
754 s->stream.avail_out = 0;
755 }
756 s->bytesInflated = 0;
757
758 while (1) {
759
760 if (s->stream.avail_out == 0) {
761 /* out of space in the output buffer so make it bigger */
762 Sv_Grow(output, SvLEN(output) + bufinc) ;
763 cur_length += increment ;
764 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
765 increment = bufinc ;
766 s->stream.avail_out = increment;
767 bufinc *= 2 ;
768 }
769
770 RETVAL = BZ2_bzDecompress (&(s->stream));
771
772 if (RETVAL != BZ_OK)
773 break ;
774
775 if (s->stream.avail_out == 0)
776 continue ;
777
778 if (s->stream.avail_in == 0) {
779 RETVAL = BZ_OK ;
780 break ;
781 }
782
783 }
784
785 s->last_error = RETVAL ;
786 if (RETVAL == BZ_OK || RETVAL == BZ_STREAM_END) {
787 unsigned in ;
788
789 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
790 s->uncompressedBytes += s->bytesInflated ;
791 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
792
793 SvPOK_only(output);
794 SvCUR_set(output, prefix_length + s->bytesInflated) ;
795 *SvEND(output) = '\0';
796#ifdef UTF8_AVAILABLE
797 if (out_utf8)
798 sv_utf8_upgrade(output);
799#endif
800 SvSETMAGIC(output);
801
802 /* fix the input buffer */
803 if (s->flags & FLAG_CONSUME_INPUT) {
804 in = s->stream.avail_in ;
805 SvCUR_set(buf, in) ;
806 if (in)
807 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
808 *SvEND(buf) = '\0';
809 SvSETMAGIC(buf);
810 }
811 }
812 OUTPUT:
813 RETVAL
814
815uLong
816inflateCount(s)
817 Compress::Raw::Bunzip2 s
818 CODE:
819 RETVAL = s->bytesInflated;
820 OUTPUT:
821 RETVAL
822
823
824void
825DESTROY(s)
826 Compress::Raw::Bunzip2 s
827 CODE:
828 BZ2_bzDecompressEnd(&s->stream) ;
829 Safefree(s) ;
830
831
832uLong
833status(s)
834 Compress::Raw::Bunzip2 s
835 CODE:
836 RETVAL = s->last_error ;
837 OUTPUT:
838 RETVAL
839
840uLong
841total_in_lo32(s)
842 Compress::Raw::Bunzip2 s
843 CODE:
844 RETVAL = s->stream.total_in_lo32 ;
845 OUTPUT:
846 RETVAL
847
848uLong
849total_out_lo32(s)
850 Compress::Raw::Bunzip2 s
851 CODE:
852 RETVAL = s->stream.total_out_lo32 ;
853 OUTPUT:
854 RETVAL
855
856uLong
857compressedBytes(s)
858 Compress::Raw::Bunzip2 s
859 CODE:
860 RETVAL = s->compressedBytes;
861 OUTPUT:
862 RETVAL
863
864uLong
865uncompressedBytes(s)
866 Compress::Raw::Bunzip2 s
867 CODE:
868 RETVAL = s->uncompressedBytes;
869 OUTPUT:
870 RETVAL
871
872MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2 PREFIX = Zip_