Compress-Bzip2

 view release on metacpan or  search on metacpan

Bzip2.xs  view on Meta::CPAN

	  }
	}
	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:

Bzip2.xs  view on Meta::CPAN

    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: $

Bzip2.xs  view on Meta::CPAN


      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 )