Upgrade to ExtUtils-MakeMaker-6.50
[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);
270 }
271 if (SvROK(sv))
272 croak("%s: buffer parameter is a reference to a reference", string) ;
273 }
274
275 if (!SvOK(sv)) {
276 sv = newSVpv("", 0);
277 }
278
279 return sv ;
280}
281
282static SV*
283#ifdef CAN_PROTOTYPE
284deRef_l(SV * sv, const char * string)
285#else
286deRef_l(sv, string)
287SV * sv ;
288char * string ;
289#endif
290{
291 dTHX;
292 bool wipe = 0 ;
293
294 SvGETMAGIC(sv);
295 wipe = ! SvOK(sv) ;
296
297 if (SvROK(sv)) {
298 sv = SvRV(sv) ;
299 SvGETMAGIC(sv);
300 wipe = ! SvOK(sv) ;
301
302 switch(SvTYPE(sv)) {
303 case SVt_PVAV:
304 case SVt_PVHV:
305 case SVt_PVCV:
306 croak("%s: buffer parameter is not a SCALAR reference", string);
307 }
308 if (SvROK(sv))
309 croak("%s: buffer parameter is a reference to a reference", string) ;
310 }
311
312 if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
313 croak("%s: buffer parameter is read-only", string);
314
315 SvUPGRADE(sv, SVt_PV);
316
317 if (wipe)
318 SvCUR_set(sv, 0);
319
320 SvOOK_off(sv);
321 SvPOK_only(sv);
322
323 return sv ;
324}
325
326
327#include "constants.h"
328
329MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2 PREFIX = Zip_
330
331REQUIRE: 1.924
332PROTOTYPES: DISABLE
333
334INCLUDE: constants.xs
335
336BOOT:
337 /* Check this version of bzip2 is == 1 */
338 if (BZ2_bzlibVersion()[0] != '1')
339 croak(COMPRESS_CLASS " needs bzip2 version 1.x, you have %s\n", BZ2_bzlibVersion()) ;
340
341
342MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2
343
344#define bzlibversion() BZ2_bzlibVersion()
345const char *
346bzlibversion()
347
348void
349new(class, appendOut=1, blockSize100k=1, workfactor=0, verbosity=0)
350 const char * class
351 int appendOut
352 int blockSize100k
353 int workfactor
354 int verbosity
355 PPCODE:
356 {
357 int err ;
358 deflateStream s ;
359#if 0
360 /* if (trace) */
361 warn("in Compress::Raw::Bzip2::_new(items=%d,appendOut=%d, blockSize100k=%d, workfactor=%d, verbosity=%d\n",
362 items, appendOut, blockSize100k, workfactor, verbosity);
363#endif
364 if ((s = InitStream() )) {
365
366 err = BZ2_bzCompressInit ( &(s->stream),
367 blockSize100k,
368 verbosity,
369 workfactor );
370
371 if (err != BZ_OK) {
372 Safefree(s) ;
373 s = NULL ;
374 }
375 else {
376 int flags = 0 ;
377 if (appendOut)
378 flags |= FLAG_APPEND_OUTPUT;
379 PostInitStream(s, appendOut ? FLAG_APPEND_OUTPUT :0) ;
380 }
381 }
382 else
383 err = BZ_MEM_ERROR ;
384
385 {
386 SV* obj = sv_setref_pv(sv_newmortal(), class, (void*)s);
387 XPUSHs(obj);
388 }
389 if(0)
390 {
391 SV* obj = sv_2mortal(newSViv(PTR2IV(s))) ;
392 XPUSHs(obj);
393 }
394 if (GIMME == G_ARRAY) {
395 SV * sv = sv_2mortal(newSViv(err)) ;
396 setDUALstatus(sv, err);
397 XPUSHs(sv) ;
398 }
399 }
400
401MODULE = Compress::Raw::Bunzip2 PACKAGE = Compress::Raw::Bunzip2
402
403void
404new(class, appendOut=1 , consume=1, small=0, verbosity=0)
405 const char* class
406 int appendOut
407 int consume
408 int small
409 int verbosity
410 PPCODE:
411 {
412 int err = BZ_OK ;
413 inflateStream s ;
414#if 0
415 if (trace)
416 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
417 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
418#endif
419 if ((s = InitStream() )) {
420
421 err = BZ2_bzDecompressInit (&(s->stream), verbosity, small);
422 if (err != BZ_OK) {
423 Safefree(s) ;
424 s = NULL ;
425 }
426 if (s) {
427 int flags = 0;
428 if (appendOut)
429 flags |= FLAG_APPEND_OUTPUT;
430 if (consume)
431 flags |= FLAG_CONSUME_INPUT;
432 PostInitStream(s, flags) ;
433 }
434 }
435 else
436 err = BZ_MEM_ERROR ;
437
438 {
439 SV* obj = sv_setref_pv(sv_newmortal(), class, (void*)s);
440 XPUSHs(obj);
441 }
442 if (0)
443 {
444 SV* obj = sv_2mortal(newSViv(PTR2IV(s))) ;
445 XPUSHs(obj);
446 }
447 if (GIMME == G_ARRAY) {
448 SV * sv = sv_2mortal(newSViv(err)) ;
449 setDUALstatus(sv, err);
450 XPUSHs(sv) ;
451 }
452 }
453
454
455
456MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2
457
458void
459DispStream(s, message=NULL)
460 Compress::Raw::Bzip2 s
461 char * message
462
463DualType
464bzdeflate (s, buf, output)
465 Compress::Raw::Bzip2 s
466 SV * buf
467 SV * output
468 uInt cur_length = NO_INIT
469 uInt increment = NO_INIT
470 int RETVAL = 0;
471 uInt bufinc = NO_INIT
472 CODE:
473 bufinc = s->bufsize;
474
475 /* If the input buffer is a reference, dereference it */
476 buf = deRef(buf, "deflate") ;
477
478 /* initialise the input buffer */
479#ifdef UTF8_AVAILABLE
480 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
481 croak("Wide character in " COMPRESS_CLASS "::bzdeflate input parameter");
482#endif
483 s->stream.next_in = (char*)SvPVbyte_nolen(buf) ;
484 s->stream.avail_in = SvCUR(buf) ;
485
486 /* and retrieve the output buffer */
487 output = deRef_l(output, "deflate") ;
488#ifdef UTF8_AVAILABLE
489 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
490 croak("Wide character in " COMPRESS_CLASS "::bzdeflate output parameter");
491#endif
492
493 if((s->flags & FLAG_APPEND_OUTPUT) != FLAG_APPEND_OUTPUT) {
494 SvCUR_set(output, 0);
495 /* sv_setpvn(output, "", 0); */
496 }
497 cur_length = SvCUR(output) ;
498 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
499 increment = SvLEN(output) - cur_length;
500 s->stream.avail_out = increment;
501 while (s->stream.avail_in != 0) {
502
503 if (s->stream.avail_out == 0) {
504 /* out of space in the output buffer so make it bigger */
505 Sv_Grow(output, SvLEN(output) + bufinc) ;
506 cur_length += increment ;
507 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
508 increment = bufinc ;
509 s->stream.avail_out = increment;
510 bufinc *= 2 ;
511 }
512
513 RETVAL = BZ2_bzCompress(&(s->stream), BZ_RUN);
514 if (RETVAL != BZ_RUN_OK)
515 break;
516 }
517
518 s->compressedBytes += cur_length + increment - s->stream.avail_out ;
519 s->uncompressedBytes += SvCUR(buf) - s->stream.avail_in ;
520
521 s->last_error = RETVAL ;
522 if (RETVAL == BZ_RUN_OK) {
523 SvPOK_only(output);
524 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
525 SvSETMAGIC(output);
526 }
527 OUTPUT:
528 RETVAL
529
530
531void
532DESTROY(s)
533 Compress::Raw::Bzip2 s
534 CODE:
535 BZ2_bzCompressEnd(&s->stream) ;
536 Safefree(s) ;
537
538
539DualType
540bzclose(s, output)
541 Compress::Raw::Bzip2 s
542 SV * output
543 uInt cur_length = NO_INIT
544 uInt increment = NO_INIT
545 uInt bufinc = NO_INIT
546 CODE:
547 bufinc = s->bufsize;
548
549 s->stream.avail_in = 0; /* should be zero already anyway */
550
551 /* retrieve the output buffer */
552 output = deRef_l(output, "close") ;
553#ifdef UTF8_AVAILABLE
554 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
555 croak("Wide character in " COMPRESS_CLASS "::bzclose input parameter");
556#endif
557 if(! s->flags & FLAG_APPEND_OUTPUT) {
558 SvCUR_set(output, 0);
559 /* sv_setpvn(output, "", 0); */
560 }
561 cur_length = SvCUR(output) ;
562 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
563 increment = SvLEN(output) - cur_length;
564 s->stream.avail_out = increment;
565
566 for (;;) {
567 if (s->stream.avail_out == 0) {
568 /* consumed all the available output, so extend it */
569 Sv_Grow(output, SvLEN(output) + bufinc) ;
570 cur_length += increment ;
571 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
572 increment = bufinc ;
573 s->stream.avail_out = increment;
574 bufinc *= 2 ;
575 }
576 RETVAL = BZ2_bzCompress(&(s->stream), BZ_FINISH);
577
578 /* deflate has finished flushing only when it hasn't used up
579 * all the available space in the output buffer:
580 */
581 /* if (s->stream.avail_out != 0 || RETVAL < 0 ) */
582 if (RETVAL == BZ_STREAM_END || RETVAL < 0 )
583 break;
584 }
585
586 /* RETVAL = (RETVAL == BZ_STREAM_END ? BZ_OK : RETVAL) ; */
587 s->last_error = RETVAL ;
588
589 s->compressedBytes += cur_length + increment - s->stream.avail_out ;
590
591 if (RETVAL == BZ_STREAM_END) {
592 SvPOK_only(output);
593 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
594 SvSETMAGIC(output);
595 }
596 OUTPUT:
597 RETVAL
598
599
600DualType
601bzflush(s, output)
602 Compress::Raw::Bzip2 s
603 SV * output
604 uInt cur_length = NO_INIT
605 uInt increment = NO_INIT
606 uInt bufinc = NO_INIT
607 CODE:
608 bufinc = s->bufsize;
609
610 s->stream.avail_in = 0; /* should be zero already anyway */
611
612 /* retrieve the output buffer */
613 output = deRef_l(output, "close") ;
614#ifdef UTF8_AVAILABLE
615 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
616 croak("Wide character in " COMPRESS_CLASS "::bzflush input parameter");
617#endif
618 if(! s->flags & FLAG_APPEND_OUTPUT) {
619 SvCUR_set(output, 0);
620 /* sv_setpvn(output, "", 0); */
621 }
622 cur_length = SvCUR(output) ;
623 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
624 increment = SvLEN(output) - cur_length;
625 s->stream.avail_out = increment;
626
627 for (;;) {
628 if (s->stream.avail_out == 0) {
629 /* consumed all the available output, so extend it */
630 Sv_Grow(output, SvLEN(output) + bufinc) ;
631 cur_length += increment ;
632 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
633 increment = bufinc ;
634 s->stream.avail_out = increment;
635 bufinc *= 2 ;
636 }
637 RETVAL = BZ2_bzCompress(&(s->stream), BZ_FLUSH);
638
639 if (RETVAL == BZ_RUN_OK || RETVAL < 0)
640 break;
641
642 /* deflate has finished flushing only when it hasn't used up
643 * all the available space in the output buffer:
644 */
645 /* RETVAL == if (s->stream.avail_out != 0 || RETVAL < 0 )
646 break; */
647 }
648
649 /* RETVAL = (RETVAL == BZ_STREAM_END ? BZ_OK : RETVAL) ; */
650 s->last_error = RETVAL ;
651
652 s->compressedBytes += cur_length + increment - s->stream.avail_out ;
653
654 if (RETVAL == BZ_RUN_OK) {
655 SvPOK_only(output);
656 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
657 SvSETMAGIC(output);
658 }
659 OUTPUT:
660 RETVAL
661
662uLong
663total_in_lo32(s)
664 Compress::Raw::Bzip2 s
665 CODE:
666 RETVAL = s->stream.total_in_lo32 ;
667 OUTPUT:
668 RETVAL
669
670uLong
671total_out_lo32(s)
672 Compress::Raw::Bzip2 s
673 CODE:
674 RETVAL = s->stream.total_out_lo32 ;
675 OUTPUT:
676 RETVAL
677
678uLong
679compressedBytes(s)
680 Compress::Raw::Bzip2 s
681 CODE:
682 RETVAL = s->compressedBytes;
683 OUTPUT:
684 RETVAL
685
686uLong
687uncompressedBytes(s)
688 Compress::Raw::Bzip2 s
689 CODE:
690 RETVAL = s->uncompressedBytes;
691 OUTPUT:
692 RETVAL
693
694
695MODULE = Compress::Raw::Bunzip2 PACKAGE = Compress::Raw::Bunzip2
696
697void
698DispStream(s, message=NULL)
699 Compress::Raw::Bunzip2 s
700 char * message
701
702DualType
703bzinflate (s, buf, output)
704 Compress::Raw::Bunzip2 s
705 SV * buf
706 SV * output
707 uInt cur_length = 0;
708 uInt prefix_length = 0;
709 uInt increment = 0;
710 STRLEN stmp = NO_INIT
711 uInt bufinc = NO_INIT
712 PREINIT:
713#ifdef UTF8_AVAILABLE
714 bool out_utf8 = FALSE;
715#endif
716 CODE:
717 bufinc = s->bufsize;
718 /* If the buffer is a reference, dereference it */
719 buf = deRef(buf, "inflate") ;
720
721 if (s->flags & FLAG_CONSUME_INPUT && SvREADONLY(buf))
722 croak(UNCOMPRESS_CLASS "::bzinflate input parameter cannot be read-only when ConsumeInput is specified");
723#ifdef UTF8_AVAILABLE
724 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
725 croak("Wide character in " UNCOMPRESS_CLASS "::bzinflate input parameter");
726#endif
727
728 /* initialise the input buffer */
729 s->stream.next_in = (char*)SvPVbyte_force(buf, stmp) ;
730 s->stream.avail_in = SvCUR(buf);
731
732 /* and retrieve the output buffer */
733 output = deRef_l(output, "inflate") ;
734#ifdef UTF8_AVAILABLE
735 if (DO_UTF8(output))
736 out_utf8 = TRUE ;
737 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
738 croak("Wide character in " UNCOMPRESS_CLASS "::bzinflate output parameter");
739#endif
740 if((s->flags & FLAG_APPEND_OUTPUT) != FLAG_APPEND_OUTPUT) {
741 SvCUR_set(output, 0);
742 }
743 if (SvLEN(output)) {
744 prefix_length = cur_length = SvCUR(output) ;
745 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length;
746 increment = SvLEN(output) - cur_length - 1;
747 s->stream.avail_out = increment;
748 }
749 else {
750 s->stream.avail_out = 0;
751 }
752 s->bytesInflated = 0;
753
754 while (1) {
755
756 if (s->stream.avail_out == 0) {
757 /* out of space in the output buffer so make it bigger */
758 Sv_Grow(output, SvLEN(output) + bufinc) ;
759 cur_length += increment ;
760 s->stream.next_out = (char*) SvPVbyte_nolen(output) + cur_length ;
761 increment = bufinc ;
762 s->stream.avail_out = increment;
763 bufinc *= 2 ;
764 }
765
766 RETVAL = BZ2_bzDecompress (&(s->stream));
767
768 if (RETVAL != BZ_OK)
769 break ;
770
771 if (s->stream.avail_out == 0)
772 continue ;
773
774 if (s->stream.avail_in == 0) {
775 RETVAL = BZ_OK ;
776 break ;
777 }
778
779 }
780
781 s->last_error = RETVAL ;
782 if (RETVAL == BZ_OK || RETVAL == BZ_STREAM_END) {
783 unsigned in ;
784
785 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
786 s->uncompressedBytes += s->bytesInflated ;
787 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ;
788
789 SvPOK_only(output);
790 SvCUR_set(output, prefix_length + s->bytesInflated) ;
791 *SvEND(output) = '\0';
792#ifdef UTF8_AVAILABLE
793 if (out_utf8)
794 sv_utf8_upgrade(output);
795#endif
796 SvSETMAGIC(output);
797
798 /* fix the input buffer */
799 if (s->flags & FLAG_CONSUME_INPUT) {
800 in = s->stream.avail_in ;
801 SvCUR_set(buf, in) ;
802 if (in)
803 Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ;
804 *SvEND(buf) = '\0';
805 SvSETMAGIC(buf);
806 }
807 }
808 OUTPUT:
809 RETVAL
810
811uLong
812inflateCount(s)
813 Compress::Raw::Bunzip2 s
814 CODE:
815 RETVAL = s->bytesInflated;
816 OUTPUT:
817 RETVAL
818
819
820void
821DESTROY(s)
822 Compress::Raw::Bunzip2 s
823 CODE:
824 BZ2_bzDecompressEnd(&s->stream) ;
825 Safefree(s) ;
826
827
828uLong
829status(s)
830 Compress::Raw::Bunzip2 s
831 CODE:
832 RETVAL = s->last_error ;
833 OUTPUT:
834 RETVAL
835
836uLong
837total_in_lo32(s)
838 Compress::Raw::Bunzip2 s
839 CODE:
840 RETVAL = s->stream.total_in_lo32 ;
841 OUTPUT:
842 RETVAL
843
844uLong
845total_out_lo32(s)
846 Compress::Raw::Bunzip2 s
847 CODE:
848 RETVAL = s->stream.total_out_lo32 ;
849 OUTPUT:
850 RETVAL
851
852uLong
853compressedBytes(s)
854 Compress::Raw::Bunzip2 s
855 CODE:
856 RETVAL = s->compressedBytes;
857 OUTPUT:
858 RETVAL
859
860uLong
861uncompressedBytes(s)
862 Compress::Raw::Bunzip2 s
863 CODE:
864 RETVAL = s->uncompressedBytes;
865 OUTPUT:
866 RETVAL
867
868MODULE = Compress::Raw::Bzip2 PACKAGE = Compress::Raw::Bzip2 PREFIX = Zip_