File Coverage

cpan/Compress-Raw-Bzip2/Bzip2.xs
Criterion Covered Total %
statement 199 249 79.9
branch n/a
condition n/a
subroutine n/a
total 199 249 79.9


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