BZip2Stream.st
changeset 1059 b47e4eff5543
child 1060 a59e60d44eb4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BZip2Stream.st	Tue Jun 25 10:27:34 2002 +0200
@@ -0,0 +1,330 @@
+"{ Package: 'ca:Compress' }"
+
+CompressionStream subclass:#BZipStream
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'A-Compress'
+!
+
+!BZipStream primitiveDefinitions!
+%{
+
+/*
+ * includes, defines, structure definitions
+ * and typedefs come here.
+ */
+
+#include "bzip/bzlib.h"
+
+typedef enum {
+          e_opmode_unspecified
+        , e_opmode_deflate
+        , e_opmode_inflate
+} e_opmode;
+
+typedef struct {
+        bz_stream       stream;
+        char *          in_ref;
+        char *          out_ref;
+        unsigned int    out_total;
+
+        e_opmode        op_mode;
+} zstream_s;
+
+%}
+! !
+
+!BZipStream methodsFor:'low level'!
+
+zclose
+    "low level close of the zip stream
+    "
+    onStream := mode := nil.
+    hitEOF   := true.
+
+    zstream ifNil:[^ self].
+    self unregisterForFinalization.
+%{
+    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 );
+    }
+%}.
+    zstream := nil.
+!
+
+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' and compute the crc
+    "
+%{
+    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.
+! !
+