BZip2Stream.st
author Claus Gittinger <cg@exept.de>
Fri, 29 Aug 2003 21:31:33 +0200
changeset 1308 d7bea6d0b3b6
parent 1196 bba6d37ed88b
child 1564 c3409f17ded6
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 2002 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

"{ Package: 'stx:libbasic2' }"

CompressionStream subclass:#BZip2Stream
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'System-Compress'
!

!BZip2Stream primitiveDefinitions!
%{

/*
 * includes, defines, structure definitions
 * and typedefs come here.
 */

#include "bz2lib/bzlib.h"

typedef enum {
	  e_opmode_unspecified          /* processing done */
	, e_opmode_deflate              /* running deflate */
	, e_opmode_inflate              /* running inflate */
} e_opmode;

typedef struct {
	bz_stream       stream;         /* pointer to the external in -stream */
	char *          in_ref;         /* size    of the external in -stream */
	char *          out_ref;        /* pointer to the external out-stream */
	unsigned int    out_total;      /* size    of the external out-stream */

	e_opmode        op_mode;        /* current operational mode */
} zstream_s;

%}
! !

!BZip2Stream class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2002 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
! !

!BZip2Stream methodsFor:'low level'!

zclose
    "low level close of the zip stream
    "
%{
    OBJ _zstreamObj = __INST( zstream );

    if( _zstreamObj != nil )
    {
	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	__INST(zstream) = nil;

	if( _zstream->stream.state != NULL )
	{
	    if( _zstream->op_mode == e_opmode_inflate )
		BZ2_bzDecompressEnd( & _zstream->stream );
	    else
		BZ2_bzCompressEnd( & _zstream->stream );
	}
	free( _zstream );
    }
%}.
!

zdeflate
    "low level - deflate
    "
    |errorNo|

    errorNo := nil.

%{
    OBJ _zstreamObj = __INST( zstream );

    if( _zstreamObj != nil )
    {
	int          _errorNo, _action;
	unsigned int _bfsize;
	zstream_s *  _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	if( _zstream->op_mode != e_opmode_deflate )
	    RETURN( nil );

	_bfsize = _zstream->out_total;

	if( _zstream->stream.state == NULL )
	{
	    _zstream->op_mode = e_opmode_unspecified;
	    RETURN( nil );
	}
	_action = (__INST(hitEOF) == true) ? BZ_FINISH : BZ_RUN;        

	_zstream->stream.avail_out = _bfsize;
	_zstream->stream.next_out  = _zstream->out_ref;
        
	_errorNo = BZ2_bzCompress( & _zstream->stream, _action );

	if( _errorNo == BZ_STREAM_END )
	{
	    _zstream->stream.avail_in = 0;
	    _zstream->stream.next_in  = NULL;
	    _errorNo = BZ2_bzCompressEnd( & _zstream->stream );
	}

	if(   (_errorNo == BZ_OK)
	   || (_errorNo == BZ_RUN_OK)
	   || (_errorNo == BZ_FINISH_OK)
	  )
	{
	    if(   (_zstream->stream.avail_out != _bfsize)
	       || (_zstream->stream.avail_in  != 0)
	      )
	      RETURN( true );

	    RETURN( false );
	}
	errorNo = __MKSMALLINT( _errorNo );
    }
%}.
    errorNo ifNil:[
	zstream ifNil:[self errorNotOpen].
	self invalidArguments.
    ].
    self zerror:errorNo.
!

zdeflateInit
    "low level - open for reading
    "
    |errorNo blockSize100k workFactor|

    errorNo       := nil.
    blockSize100k := BlockSize.
    workFactor    := 30.
%{
    OBJ _zstreamObj = __INST( zstream );

    if( (_zstreamObj != nil) && __bothSmallInteger(blockSize100k, workFactor) )
    {
	int         _errorNo;
	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	_zstream->op_mode = e_opmode_deflate;

	_errorNo = BZ2_bzCompressInit( & _zstream->stream
				     , __intVal( blockSize100k ), 0, __intVal( workFactor ) );

	if( _errorNo == BZ_OK )
	    RETURN( self );

	errorNo = __MKSMALLINT( _errorNo );
    }
%}.
    errorNo ifNil:[
	zstream ifNil:[ self errorNotOpen ].
	self invalidArguments .
    ].
    self zerror:errorNo.
!

zget_avail_out
    "low level - get the number of available out bytes
    "
%{
    OBJ _zstreamObj = __INST( zstream );

    if( _zstreamObj != nil )
    {
	unsigned int _count;
	zstream_s *  _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	_count = _zstream->out_total - _zstream->stream.avail_out;

	RETURN( __MKSMALLINT (_count) );
    }
%}.
    self errorNotOpen.
!

zinflate
    "low level - inflate
    "
    |errorNo|

    errorNo := nil.
%{
    OBJ _zstreamObj = __INST( zstream );

    if( _zstreamObj != nil )
    {
	int         _errorNo, _count;
	zstream_s * _zstream;

	_zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	if( _zstream->op_mode != e_opmode_inflate )
	    RETURN( nil );

	if( _zstream->stream.state == NULL )
	{
	    _zstream->op_mode = e_opmode_unspecified;
	    RETURN( nil );
	}
	if( _zstream->stream.avail_in == 0 )
	    RETURN( __MKSMALLINT (0) );

	_zstream->stream.avail_out = _zstream->out_total;
	_zstream->stream.next_out  = _zstream->out_ref;

	_errorNo = BZ2_bzDecompress( & _zstream->stream );

	if( _errorNo == BZ_STREAM_END )
	    _errorNo = BZ2_bzDecompressEnd( & _zstream->stream );

	if( _errorNo == BZ_OK )
	{
	    _count = _zstream->out_total - _zstream->stream.avail_out;

	    RETURN( __MKSMALLINT (_count) );
	}
	errorNo = __MKSMALLINT( _errorNo );
    }
%}.
    errorNo ifNil:[ self errorNotOpen ].
    self zerror:errorNo.
!

zinflateInit
    "low level - inflateInit
    "
    |errorNo|

    errorNo := nil.

%{
    OBJ _zstreamObj = __INST( zstream );

    if( _zstreamObj != nil )
    {
	int         _errorNo;
	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	_zstream->op_mode = e_opmode_inflate;
	_errorNo = BZ2_bzDecompressInit( & _zstream->stream, 0, 1 );

	if( _errorNo == BZ_OK )
	    RETURN( self );

	_zstream->stream.avail_in = 0;
	errorNo = __MKSMALLINT( _errorNo );
    }
%}.
    errorNo ifNil:[ self errorNotOpen ].
    self zerror:errorNo.
!

zopen
    "low level - opens the zip stream
    "
    |outTotal|

    outTotal := outputBytes size.
%{
    zstream_s * _zstream = (zstream_s *) malloc( sizeof(zstream_s) );

    if( _zstream )
    {
	OBJ     _zobj   = __MKEXTERNALADDRESS( _zstream );
	OBJ     _outObj = __INST( outputBytes );
	OBJ     _inpObj = __INST( inputBytes  );

	_zstream->in_ref           = (char *) __externalBytesAddress( _inpObj );
	_zstream->stream.next_in   = NULL;
	_zstream->stream.avail_in  = 0;
	_zstream->stream.total_in_lo32  = 0;
	_zstream->stream.total_in_hi32  = 0;

	_zstream->out_total        = __intVal( outTotal );
	_zstream->out_ref          = (char *) __externalBytesAddress( _outObj );
	_zstream->stream.next_out  = _zstream->out_ref;
	_zstream->stream.avail_out = _zstream->out_total;

	_zstream->stream.total_out_lo32 = 0;
	_zstream->stream.total_out_hi32 = 0;

	_zstream->stream.bzalloc   = 0;
	_zstream->stream.bzfree    = 0;
	_zstream->stream.opaque    = 0;

	_zstream->op_mode          = e_opmode_unspecified;

	__INST (zstream) = _zobj;
	__STORE(self, _zobj);
    }
%}.
!

zset_avail_in:count
    "set the 'avail_in'
    "
%{
    OBJ _zstreamObj = __INST( zstream );

    if( (_zstreamObj != nil) && __isSmallInteger(count) )
    {
	int         _count;
	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );

	if( (_count = __intVal( count )) > 0 )
	{
	    char * _in_ref = _zstream->in_ref;

	    _zstream->stream.avail_in = _count;
	    _zstream->stream.next_in  = _in_ref;
	} else {
	    _zstream->stream.avail_in = 0;
	    _zstream->stream.next_in  = NULL;
	}
	RETURN( self );
    }
%}.
    zstream ifNil:[ self errorNotOpen ].
    self invalidArguments.
! !

!BZip2Stream class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic2/BZip2Stream.st,v 1.7 2003-08-29 19:31:11 cg Exp $'
! !