Compress-Bzip2
view release on metacpan or search on metacpan
}
}
else {
if (obj->verbosity>=4) PerlIO_printf(PerlIO_stderr(), "debug: bzfile_write: file write took in %d, put out %d\n", n, n2);
obj->compressedOffset_takeout += n2;
obj->nCompressed -= n2;
n -= n2;
obj->total_out += n2;
}
}
obj->nCompressed = 0;
obj->compressedOffset_takeout = 0;
obj->compressedOffset_addmore = 0;
}
if (bytes_compressed_count == nUncompressed) {
BZ_SETERR(obj, BZ_OK, NULL);
return nUncompressed;
}
}
}
/***********************************************************************
* XSUB start
***********************************************************************/
MODULE = Compress::Bzip2 PACKAGE = Compress::Bzip2 PREFIX = MY_
INCLUDE: const-xs.inc
REQUIRE: 0.0
PROTOTYPES: ENABLE
BOOT:
if (BZ2_bzlibVersion()[0] != '1')
croak("Compress::Bzip2 needs bzlib version 1.x, not %s\n", BZ2_bzlibVersion()) ;
{
/* Create the $bzerror scalar */
SV * bzerror_sv = perl_get_sv(BZERRNO, GV_ADDMULTI) ;
sv_setiv(bzerror_sv, 0) ;
sv_setpv(bzerror_sv, "") ;
SvIOK_on(bzerror_sv) ;
}
void
MY_new(...)
PROTOTYPE: @
INIT:
bzFile* obj;
SV *perlobj;
char *class, *param;
STRLEN lnclass, lnparam;
int setting;
PPCODE:
{
int i;
perlobj = NULL;
obj = NULL;
if ( items == 0 ) {
class = "Compress::Bzip2";
}
else if ( SvPOK( ST(0) ) ) {
/* this is the name of a class */
class = (char *) SvPV( ST(0), lnclass );
}
else if ( SvROK( ST(0) ) ) {
if (sv_derived_from(ST(0), "Compress::Bzip2")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
perlobj = ST(0);
obj = INT2PTR(bzFile*, tmp);
}
}
if ( obj == NULL ) {
obj = bzfile_new( 0, 0, 9, 0 );
perlobj = newSV(0);
sv_setref_iv( perlobj, class, PTR2IV(obj) );
sv_2mortal(perlobj);
}
if ( obj == NULL )
XSRETURN_UNDEF;
for (i=1; i<items-1; i+=2) {
param = (char*) SvPV( ST(i), lnparam );
setting = SvIV( ST(i+1) );
bzfile_setparams( obj, param, setting );
}
PUSHs(perlobj);
}
void
DESTROY(obj)
Compress::Bzip2 obj
CODE:
{
if (!obj)
XSRETURN_UNDEF;
if (obj->verbosity >= 1)
PerlIO_printf(PerlIO_stderr(), "debug: DESTROY on %p\n", obj);
bzfile_close( obj, 0 );
bzfile_free( obj );
}
char *
MY_bzlibversion()
PROTOTYPE:
CODE:
sv = deRef(sv, ix==1 ? "decompress" : "memBunzip");
in = (unsigned char*)SvPV(sv, len);
if (len < 5 + 3 || in[0] < 0xf0 || in[0] > 0xf1) {
if (len > 16 && in[0] == 'B' && in[1] == 'Z' && in[2] == 'h') {
in_len = len;
out_len = len * 5; /* guess uncompressed size */
noprefix = 1;
RETVAL = newSV(len * 10);
} else {
warn("invalid buffer (too short %ld or bad marker %d)",(long)len,in[0]);
XSRETURN_UNDEF;
}
} else {
in_len = len - 5;
out_len = (in[1] << 24) | (in[2] << 16) | (in[3] << 8) | in[4];
RETVAL = newSV(out_len > 0 ? out_len : 1);
}
SvPOK_only(RETVAL);
out = (unsigned char*)SvPVX(RETVAL);
new_len = out_len;
err = BZ2_bzBuffToBuffDecompress((char*)out,&new_len,
noprefix ? (char*)in:(char *)in+5, in_len,0,0);
while (noprefix && (err == BZ_OUTBUFF_FULL)) {
new_len = SvLEN(RETVAL) * 2;
SvGROW(RETVAL, new_len);
err = BZ2_bzBuffToBuffDecompress((char*)out,&new_len,
(char *)in,in_len,0,0);
}
if (err != BZ_OK) {
SvREFCNT_dec(RETVAL);
BZ_SETERR(NULL, err, ix==1 ? "decompress" : "memBunzip");
XSRETURN_UNDEF;
}
if (!noprefix && new_len != out_len) {
SvREFCNT_dec(RETVAL);
BZ_SETERR(NULL, err, ix==1 ? "decompress" : "memBunzip");
XSRETURN_UNDEF;
}
SvCUR_set(RETVAL, new_len);
}
OUTPUT:
RETVAL
void
MY_bzopen(...)
## xxx->bzopen( $filename or filehandle, $mode )
PROTOTYPE: $$;$
INIT:
PerlIO *io;
char *filename, *mode, *class;
STRLEN ln, lnfilename, lnclass;
bzFile* obj;
SV *perlobj;
PPCODE:
{
int i;
perlobj=NULL;
obj=NULL;
if ( items == 2 ) {
class = "Compress::Bzip2";
}
else if ( SvPOK( ST(0) ) ) {
/* this is the name of a class */
class = (char *) SvPV( ST(0), lnclass );
}
else if ( SvROK( ST(0) ) ) {
if (sv_derived_from(ST(0), "Compress::Bzip2")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
perlobj = ST(0);
obj = INT2PTR(bzFile*, tmp);
}
}
i = items==3 ? 2 : 1;
mode = (char *) SvPV(ST(i), ln);
if (ln==0) {
BZ_SETERR(obj, BZ_PARAM_ERROR, NULL);
if ( obj && obj->verbosity>1 ) warn( "Error: invalid file mode for bzopen %s", mode );
XSRETURN_UNDEF;
}
i = items==3 ? 1 : 0;
if ( SvPOK( ST(i) ) ) {
/* is the first argument a filename string or a filehandle?? */
filename = (char *) SvPV(ST(i), lnfilename);
if (lnfilename==0)
XSRETURN_UNDEF;
filename[lnfilename]=0;
obj = bzfile_open( filename, mode, obj );
}
else if ( SvROK( ST(i) ) || SVt_PVIO == SvTYPE( ST(i) ) ) {
/* a reference or an IO handle */
if ( mode && mode[0] == 'w' ) {
io = IoOFP(sv_2io( ST(i) ));
}
else {
io = IoIFP(sv_2io( ST(i) ));
}
obj = bzfile_fdopen( io, mode, obj );
}
else {
BZ_SETERR(obj, BZ_PARAM_ERROR, NULL);
if ( obj && obj->verbosity>1 ) warn( "Error: invalid file or handle for bzopen" );
XSRETURN_UNDEF;
}
if ( obj == NULL )
XSRETURN_UNDEF;
if ( perlobj == NULL ) {
perlobj = newSV(0);
sv_setref_iv( perlobj, class, PTR2IV(obj) );
sv_2mortal(perlobj);
}
PUSHs(perlobj);
}
void
MY_bzclose(obj, abandon=0)
Compress::Bzip2 obj
int abandon
PROTOTYPE: $;$
PPCODE:
{
int i, ret, amt_collected;
char *inp;
int error_flag = 0;
if ( obj->open_status != OPEN_STATUS_READSTREAM && obj->open_status != OPEN_STATUS_WRITESTREAM ) {
ret = bzfile_close( obj, abandon );
XPUSHs(sv_2mortal(newSViv(ret)));
}
else {
char *firstp, *outp;
SV *outbuf = NULL;
STRLEN outbufl = 0;
char collect_buffer[10000];
while ( !error_flag ) {
ret = bzfile_close( obj, abandon );
if ( obj->open_status == OPEN_STATUS_READSTREAM ) break;
if ( ret == -1 && errno != EAGAIN ) {
error_flag =1;
break;
}
if ( obj->verbosity>=4 )
PerlIO_printf(PerlIO_stderr(), "debug: bzstreamclose, bzfile_close returned %d, errno is %d %s\n", ret, errno, Strerror(errno));
while ( -1 != ( amt_collected = bzfile_streambuf_collect( obj, collect_buffer, sizeof(collect_buffer) ) ) ) {
if ( obj->verbosity>=4 )
PerlIO_printf(PerlIO_stderr(), "debug: bzstreamclose, bzfile_streambuf_collect returned %d bytes\n", amt_collected);
/* put the stuff into the SV output buffer */
if ( outbuf == NULL ) {
outbuf = newSVpv( collect_buffer, amt_collected );
outbufl = amt_collected;
firstp = SvPV_nolen( outbuf );
outp = firstp;
}
else {
outbufl += amt_collected;
SvGROW( outbuf, outbufl );
firstp = SvPV_nolen( outbuf );
outp = SvEND( outbuf );
}
for ( inp=collect_buffer, i=0; i<amt_collected; i++ ) *outp++ = *inp++;
SvCUR_set( outbuf, outp-firstp) ;
}
if ( errno != EAGAIN )
error_flag = 1;
if ( ret == 0 ) break;
}
if (outbuf==NULL) {
if ( error_flag )
XPUSHs(sv_newmortal());
else
XPUSHs(sv_2mortal(newSVpv("",0)));
}
else
XPUSHs(sv_2mortal(outbuf));
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
}
void
MY_bzflush(obj, flag=0)
Compress::Bzip2 obj
int flag
PROTOTYPE: $;$
PPCODE:
{
int i, ret, amt_collected;
char *inp;
if ( obj->open_status != OPEN_STATUS_READSTREAM && obj->open_status != OPEN_STATUS_WRITESTREAM ) {
ret = !flag || flag!=BZ_FINISH ? bzfile_flush( obj ) : bzfile_close( obj, 0 );
XPUSHs(sv_2mortal(newSViv(ret)));
}
else {
char *firstp, *outp;
SV *outbuf = NULL;
STRLEN outbufl = 0;
char collect_buffer[10000];
while ( True ) {
ret = !flag || flag!=BZ_FLUSH ? bzfile_flush( obj ) : bzfile_close( obj, 0 );
if ( obj->open_status == OPEN_STATUS_READSTREAM ) break;
while ( -1 != ( amt_collected = bzfile_streambuf_collect( obj, collect_buffer, sizeof(collect_buffer) ) ) ) {
if ( obj->verbosity>=4 )
PerlIO_printf(PerlIO_stderr(), "debug: bzstreamflush, bzfile_streambuf_collect returned %d bytes\n", amt_collected);
/* put the stuff into the SV output buffer */
if ( outbuf == NULL ) {
outbuf = newSVpv( collect_buffer, amt_collected );
outbufl = amt_collected;
firstp = SvPV_nolen( outbuf );
outp = firstp;
}
else {
outbufl += amt_collected;
SvGROW( outbuf, outbufl );
firstp = SvPV_nolen( outbuf );
outp = SvEND( outbuf );
}
for ( inp=collect_buffer, i=0; i<amt_collected; i++ ) *outp++ = *inp++;
SvCUR_set( outbuf, outp-firstp) ;
}
if ( ret != -1 ) break;
}
if (outbuf==NULL)
XPUSHs(sv_newmortal());
else
XPUSHs(sv_2mortal(outbuf));
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
}
SV*
MY_bzerror(obj)
Compress::Bzip2 obj
PROTOTYPE: $
if (RETVAL >= 0) {
SvCUR_set(buf, RETVAL) ;
*SvEND(buf) = '\0';
}
}
else {
RETVAL = 0;
}
}
OUTPUT:
RETVAL
buf
int
MY_bzwrite(obj, buf, limit=0)
Compress::Bzip2 obj
SV *buf
SV *limit
PROTOTYPE: $$;$
CODE:
{
char *bufp;
STRLEN len;
if ( SvTRUE(limit) ) {
len = SvUV(limit);
SvGROW( buf, len );
bufp = SvPV_nolen(buf);
}
else
bufp = SvPV(buf, len);
RETVAL = bzfile_write( obj, bufp, len);
if ( RETVAL >= 0 )
SvCUR_set( buf, RETVAL );
}
OUTPUT:
RETVAL
void
bzdeflateInit(...)
PROTOTYPE: @
ALIAS:
compress_init = 1
INIT:
bzFile* obj = NULL;
SV *perlobj = NULL;
char *param;
STRLEN lnparam;
int setting;
PPCODE:
{
int i;
if (items % 2) croak("Compress::Bzip2::%s has odd parameter count", ix==0 ? "bzdeflateInit" : "compress_init");
obj = bzfile_new( 0, 0, 1, 0 );
bzfile_openstream( "w", obj );
perlobj = newSV(0);
sv_setref_iv( perlobj, "Compress::Bzip2", PTR2IV(obj) );
sv_2mortal(perlobj);
if ( obj == NULL ) {
XPUSHs(sv_newmortal());
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
else {
for (i=0; i<items-1; i+=2) {
param = (char*) SvPV( ST(i), lnparam );
setting = SvIV( ST(i+1) );
bzfile_setparams( obj, param, setting );
}
bzfile_streambuf_set( obj, (char*) obj->bufferOfHolding, sizeof( obj->bufferOfHolding ) );
XPUSHs(perlobj);
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
}
void
MY_bzdeflate(obj, buffer)
Compress::Bzip2 obj
SV *buffer
PROTOTYPE: $$
PPCODE:
{
char *firstp, *outp;
SV *outbuf = NULL;
STRLEN outbufl = 0;
char *bufp, *inp;
STRLEN bufl;
STRLEN bytes_to_go;
char collect_buffer[1000];
int i, amt_written, amt_collected;
int error_flag = 0;
bufp = (char*) SvPV( buffer, bufl );
for ( bytes_to_go = bufl; bytes_to_go>0; ) {
amt_written = bzfile_write( obj, bufp, bytes_to_go );
if ( amt_written == -1 ) {
if ( errno != EAGAIN )
error_flag =1;
else {
while ( -1 != ( amt_collected = bzfile_streambuf_collect( obj, collect_buffer, sizeof(collect_buffer) ) ) ) {
/* put the stuff into the SV output buffer */
if ( outbuf == NULL ) {
outbuf = newSVpv( collect_buffer, amt_collected );
outbufl = amt_collected;
firstp = SvPV_nolen( outbuf );
outp = firstp;
}
else {
outbufl += amt_collected;
SvGROW( outbuf, outbufl );
firstp = SvPV_nolen( outbuf );
outp = SvEND( outbuf );
}
for ( inp=collect_buffer, i=0; i<amt_collected; i++ ) *outp++ = *inp++;
SvCUR_set( outbuf, outp-firstp) ;
if ( obj->verbosity>=4 )
PerlIO_printf(PerlIO_stderr(), "debug: bzdeflate collected %d, outbuf is now %ld\n",
amt_collected, (long)(outp-firstp));
}
if ( errno != EAGAIN ) error_flag = 1;
}
}
else {
bytes_to_go -= amt_written;
bufp += amt_written;
}
}
while ( -1 != ( amt_collected = bzfile_streambuf_collect( obj, collect_buffer, sizeof(collect_buffer) ) ) ) {
/* put the stuff into the SV output buffer */
if ( outbuf == NULL ) {
outbuf = newSVpv( collect_buffer, amt_collected );
outbufl = amt_collected;
firstp = SvPV_nolen( outbuf );
outp = firstp;
}
else {
outbufl += amt_collected;
SvGROW( outbuf, outbufl );
firstp = SvPV_nolen( outbuf );
outp = SvEND( outbuf );
}
for ( inp=collect_buffer, i=0; i<amt_collected; i++ ) *outp++ = *inp++;
SvCUR_set( outbuf, outp-firstp) ;
if ( obj->verbosity>=4 )
PerlIO_printf(PerlIO_stderr(), "debug: bzdeflate collected %d, outbuf is now %ld\n",
amt_collected, (long)(outp-firstp));
}
if ( errno != EAGAIN ) error_flag = 1;
if (outbuf==NULL) {
if ( error_flag )
XPUSHs(sv_newmortal());
else
XPUSHs(sv_2mortal(newSVpv("",0)));
}
else
XPUSHs(sv_2mortal(outbuf));
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
void
bzinflateInit(...)
PROTOTYPE: @
ALIAS:
decompress_init = 1
INIT:
bzFile* obj = NULL;
SV *perlobj = NULL;
char *param;
STRLEN lnparam;
int setting;
PPCODE:
{
int i;
if (items % 2)
croak("Compress::Bzip2::%s has odd parameter count", ix==0 ? "bzinflateInit" : "decompress_init");
obj = bzfile_new( 0, 0, 1, 0 );
bzfile_openstream( "r", obj );
if ( obj == NULL ) {
XPUSHs(sv_newmortal());
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
perlobj = newSV(0);
sv_setref_iv( perlobj, "Compress::Bzip2", PTR2IV(obj) );
for (i=0; i < items; i+=2) {
param = (char*) SvPV( ST(i), lnparam );
setting = SvIV( ST(i+1) );
bzfile_setparams( obj, param, setting );
}
XPUSHs(sv_2mortal(perlobj));
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
void
MY_bzinflate(obj, buffer)
Compress::Bzip2 obj
SV *buffer
PROTOTYPE: $$
PPCODE:
{
char *firstp, *outp;
SV *outbuf = NULL;
STRLEN outbufl = 0;
STRLEN bufl;
char collect_buffer[1000];
int i, amt_collected;
char *bufp, *inp;
int error_flag = 0;
if (SvTYPE(buffer) == SVt_RV)
buffer = SvRV(buffer);
bufp = (char*) SvPV( buffer, bufl );
bzfile_streambuf_deposit( obj, bufp, bufl );
while ( ( amt_collected = bzfile_read( obj, collect_buffer, sizeof(collect_buffer) ) ) >= 0 ) {
if ( obj->verbosity>=4 )
PerlIO_printf(PerlIO_stderr(), "debug: bzinflate, bzfile_read returned %d bytes\n", amt_collected);
/* put the stuff into the SV output buffer */
if ( outbuf == NULL ) {
outbuf = newSVpv( collect_buffer, amt_collected );
outbufl = amt_collected;
firstp = SvPV_nolen( outbuf );
outp = firstp;
}
else {
outbufl += amt_collected;
SvGROW( outbuf, outbufl );
firstp = SvPV_nolen( outbuf );
outp = SvEND( outbuf );
}
for ( inp=collect_buffer, i=0; i<amt_collected; i++ ) *outp++ = *inp++;
SvCUR_set( outbuf, outp-firstp) ;
}
if ( errno != EAGAIN ) error_flag = 1;
if (outbuf==NULL) {
if ( error_flag )
XPUSHs(sv_newmortal());
else
XPUSHs(sv_2mortal(newSVpv("",0)));
}
else
XPUSHs(sv_2mortal(outbuf));
if (GIMME == G_ARRAY)
XPUSHs(sv_2mortal(newSViv(global_bzip_errno)));
}
## $stream->prefix: Compress::Bzip2 1.03 compatibility function
## ... only call this for a compress/deflate stream
SV*
MY_prefix(obj)
Compress::Bzip2 obj
( run in 0.558 second using v1.01-cache-2.11-cpan-71847e10f99 )