ZipStream.st
changeset 1047 1cd99e473c08
parent 1046 79d5f461a3ad
child 1048 75c7cc52082c
equal deleted inserted replaced
1046:79d5f461a3ad 1047:1cd99e473c08
       
     1 'From Smalltalk/X, Version:4.1.4 on 20-jun-2002 at 06:09:31 am'                 !
       
     2 
     1 "{ Package: 'ca:Compress' }"
     3 "{ Package: 'ca:Compress' }"
     2 
     4 
     3 Object subclass:#ZipStream
     5 Object subclass:#ZipStream
     4 	instanceVariableNames:'onStream hitEOF binary isReadOpen inputBytes outputBytes zstream'
     6         instanceVariableNames:'onStream hitEOF binary isReadOpen inputBytes outputBytes zstream'
     5 	classVariableNames:'Z_FINISH Z_NO_FLUSH Z_SYNC_FLUSH Z_FULL_FLUSH Z_DEFLATED
     7         classVariableNames:'Z_FINISH Z_NO_FLUSH Z_SYNC_FLUSH Z_FULL_FLUSH Z_DEFLATED
     6 		Z_DEFAULT_COMPRESSION Z_DEFAULT_LEVEL Z_BEST_COMPRESSION
     8                 Z_DEFAULT_COMPRESSION Z_DEFAULT_LEVEL Z_BEST_COMPRESSION
     7 		Z_DEF_MEM_LEVEL Z_DEFAULT_STRATEGY Z_FILTERED Z_HUFFMAN_ONLY
     9                 Z_DEF_MEM_LEVEL Z_DEFAULT_STRATEGY Z_FILTERED Z_HUFFMAN_ONLY
     8 		HEAD_OS_CODE HEAD_RESERVED HEAD_EXTRA_FIELD HEAD_ORIG_NAME
    10                 HEAD_OS_CODE HEAD_RESERVED HEAD_EXTRA_FIELD HEAD_ORIG_NAME
     9 		HEAD_COMMENT HEAD_CRC GZ_MAGIC_ID'
    11                 HEAD_COMMENT HEAD_CRC GZ_MAGIC_ID'
    10 	poolDictionaries:''
    12         poolDictionaries:''
    11 	category:'A-Compress'
    13         category:'A-Compress'
    12 !
    14 !
    13 
    15 
    14 !ZipStream primitiveDefinitions!
    16 !ZipStream primitiveDefinitions!
    15 %{
    17 %{
    16 
    18 
    21 
    23 
    22 #include "compress/zlib.h"
    24 #include "compress/zlib.h"
    23 #include "compress/zutil.h"
    25 #include "compress/zutil.h"
    24 
    26 
    25 typedef struct {
    27 typedef struct {
    26 	z_stream        stream;
    28         z_stream        stream;
    27 	Bytef *         in_ref;
    29         Bytef *         in_ref;
    28 	uLong           in_total;
    30         uLong           in_position;
    29 
    31         uLong           in_total;
    30 	Bytef *         out_ref;
    32 
    31 	uLong           out_used;
    33         Bytef *         out_ref;
    32 	uLong           out_total;
    34         uLong           out_position;
    33 
    35         uLong           out_total;
    34 	uLong           crc_32;
    36         uLong           out_limit;
       
    37         uLong           out_atStreamEnd;
       
    38 
       
    39         uLong           crc_32;
    35 } zstream_s;
    40 } zstream_s;
    36 
    41 
    37 %}
    42 %}
    38 ! !
    43 ! !
    39 
    44 
    92 
    97 
    93     GZ_MAGIC_ID           := #[ 16r1f 16r8b ]
    98     GZ_MAGIC_ID           := #[ 16r1f 16r8b ]
    94 
    99 
    95 ! !
   100 ! !
    96 
   101 
    97 
       
    98 !ZipStream class methodsFor:'instance creation'!
   102 !ZipStream class methodsFor:'instance creation'!
    99 
   103 
   100 readOpenOn:aStream
   104 readOpenOn:aStream
   101     ^ self new readOpenOn:aStream
   105     ^ self new readOpenOn:aStream
   102 !
   106 !
   103 
   107 
   104 writeOpenOn:aStream
   108 writeOpenOn:aStream
   105     ^ self writeOpenOn:aStream level:Z_DEFAULT_LEVEL
   109     ^ self writeOpenOn:aStream level:Z_DEFAULT_LEVEL
   106 			    memLevel:Z_DEF_MEM_LEVEL
   110                             memLevel:Z_DEF_MEM_LEVEL
   107 			    strategy:Z_DEFAULT_STRATEGY.
   111                             strategy:Z_DEFAULT_STRATEGY.
   108 !
   112 !
   109 
   113 
   110 writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy
   114 writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy
   111     |z|
   115     |z|
   112 
   116 
   113     z := self new.
   117     z := self new.
   114     z writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy.
   118     z writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy.
   115   ^ z
   119   ^ z
   116 ! !
   120 ! !
   117 
       
   118 
   121 
   119 !ZipStream class methodsFor:'test'!
   122 !ZipStream class methodsFor:'test'!
   120 
   123 
   121 test
   124 test
   122 "
   125 "
   130    out := #[] writeStream.
   133    out := #[] writeStream.
   131 
   134 
   132    [ zip := self writeOpenOn:out.
   135    [ zip := self writeOpenOn:out.
   133 
   136 
   134      [in atEnd] whileFalse:[ |buf|
   137      [in atEnd] whileFalse:[ |buf|
   135 	buf := in nextAvailable:512.
   138         buf := in nextAvailable:512.
   136 	zip nextPutAll:buf.
   139         zip nextPutAll:buf.
   137      ].
   140      ].
   138    ] valueNowOrOnUnwindDo:[ zip ifNotNil:[ zip close ] ].
   141    ] valueNowOrOnUnwindDo:[ zip ifNotNil:[ zip close ] ].
   139 
   142 
   140    compContents := out contents.
   143    compContents := out contents.
   141    in := compContents readStream.
   144    in := compContents readStream.
   143    [ zip := self readOpenOn:in.
   146    [ zip := self readOpenOn:in.
   144      uncompContents := zip contents.
   147      uncompContents := zip contents.
   145    ] valueNowOrOnUnwindDo:[ zip ifNotNil:[ zip close ] ].
   148    ] valueNowOrOnUnwindDo:[ zip ifNotNil:[ zip close ] ].
   146 
   149 
   147    fileContents = uncompContents ifFalse:[
   150    fileContents = uncompContents ifFalse:[
   148 	self halt:'contents differs'.
   151         self halt:'contents differs'.
   149       ^ self
   152       ^ self
   150    ].
   153    ].
   151    Transcript showCR:'uncompressed size: ', fileContents size printString.
   154    Transcript showCR:'uncompressed size: ', fileContents size printString.
   152    Transcript showCR:'compressed   size: ', compContents size printString.
   155    Transcript showCR:'compressed   size: ', compContents size printString.
   153 
   156 
   154    Transcript showCR:'OK'.
   157    Transcript showCR:'OK'.
   155 
   158 !
       
   159 
       
   160 testFile
       
   161 "
       
   162 ZipStream testFile
       
   163 "
       
   164    |fileContents in zip out gzipCmd|
       
   165 
       
   166    fileContents := 'smalltalk.rc' asFilename contentsOfEntireFile.
       
   167 
       
   168    in  := fileContents readStream.
       
   169    out := FileStream newFileNamed:'YYY.gz'.
       
   170    out ifNil:[ ^ self ].
       
   171 
       
   172    [ zip := self writeOpenOn:out.
       
   173 
       
   174      [in atEnd] whileFalse:[ |buf|
       
   175         buf := in nextAvailable:512.
       
   176         buf do:[:n|
       
   177             zip nextPut:n
       
   178         ]
       
   179         "/ zip nextPutAll:buf.
       
   180      ].
       
   181    ] valueNowOrOnUnwindDo:[
       
   182         zip ifNotNil:[ zip close ].
       
   183         out close.
       
   184    ].
       
   185    gzipCmd := 'gzip -dc YYY.gz > YYY; diff YYY smalltalk.rc'.
       
   186 
       
   187    Transcript showCR:gzipCmd.
       
   188    gzipCmd printCR.
   156 ! !
   189 ! !
   157 
   190 
   158 !ZipStream methodsFor:'accessing'!
   191 !ZipStream methodsFor:'accessing'!
   159 
   192 
   160 binary
   193 binary
   191     self error:( 'error: ', anErrorOrNumber printString ).
   224     self error:( 'error: ', anErrorOrNumber printString ).
   192 ! !
   225 ! !
   193 
   226 
   194 !ZipStream methodsFor:'low level'!
   227 !ZipStream methodsFor:'low level'!
   195 
   228 
       
   229 zFlushInputBuffer
       
   230 %{
       
   231     OBJ _zstreamObj = __INST( zstream );
       
   232 
       
   233     if( _zstreamObj != nil  )
       
   234     {
       
   235         zstream_s * _zstream;
       
   236         uInt        _inpos;
       
   237         Bytef     * _in_ref;
       
   238 
       
   239         _zstream  = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   240         _inpos    = _zstream->in_position;
       
   241 
       
   242         if( _inpos == 0 )
       
   243         {
       
   244             _zstream->stream.avail_in = 0;
       
   245             _zstream->stream.next_in  = Z_NULL;
       
   246             RETURN( self );
       
   247         }
       
   248         _in_ref = _zstream->in_ref;
       
   249 
       
   250         _zstream->stream.avail_in = _inpos;
       
   251         _zstream->stream.next_in  = _in_ref;
       
   252         _zstream->crc_32 = crc32( _zstream->crc_32, _in_ref, _inpos );
       
   253     }
       
   254 %}.
       
   255     zstream ifNil:[ self errorNotOpen ].
       
   256 
       
   257     [
       
   258         self zflush:false.
       
   259         self zdeflate:Z_NO_FLUSH.
       
   260         self zinputAvailable
       
   261 
       
   262     ] whileTrue.
       
   263 !
       
   264 
       
   265 zFlushOutPutBuffer
       
   266     |errorNo|
       
   267 
       
   268     errorNo := nil.
       
   269 "    hitEOF == true ifTrue:[^ 0].
       
   270 "
       
   271 %{
       
   272     OBJ _zstreamObj = __INST( zstream );
       
   273 
       
   274     if( _zstreamObj != nil  )
       
   275     {
       
   276         zstream_s * _zstream;
       
   277         int         _errorNo;
       
   278 
       
   279         _zstream               = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   280         _zstream->out_position = 0;
       
   281 
       
   282         if( _zstream->out_atStreamEnd )
       
   283         {
       
   284             _zstream->out_limit = 0;
       
   285             __INST(hitEOF) = true;
       
   286 
       
   287             RETURN( __MKSMALLINT (0) )
       
   288          }
       
   289         _zstream->stream.avail_out = _zstream->out_total;
       
   290         _zstream->stream.next_out  = _zstream->out_ref;
       
   291 
       
   292         _errorNo = inflate( & _zstream->stream, Z_NO_FLUSH );
       
   293 
       
   294         if( _errorNo == Z_STREAM_END )
       
   295         {
       
   296             _errorNo = inflateEnd( & _zstream->stream );
       
   297             _zstream->out_atStreamEnd = 1;
       
   298         }
       
   299         if( _errorNo == Z_OK )
       
   300         {
       
   301             uInt _limit = _zstream->out_total - _zstream->stream.avail_out;
       
   302 
       
   303             _zstream->out_limit        = _limit;
       
   304             _zstream->out_position     = 0;
       
   305             _zstream->stream.avail_out = 0;
       
   306             _zstream->stream.next_out  = Z_NULL;
       
   307 
       
   308             RETURN( __MKSMALLINT (_limit) );
       
   309         }
       
   310         errorNo = __MKSMALLINT( _errorNo );
       
   311     }
       
   312 %}.
       
   313     zstream ifNil:[ self errorNotOpen ].
       
   314     self zerror:errorNo.
       
   315 !
       
   316 
       
   317 zNextAvailableBytes:count into:inBytes startingAt:start
       
   318 %{
       
   319     OBJ _zstreamObj = __INST( zstream );
       
   320 
       
   321     if( (_zstreamObj != nil) && __bothSmallInteger(count, start) )
       
   322     {
       
   323         char *      _bytes;
       
   324         zstream_s * _zstream;
       
   325         int         _count, _offs, _capacity;
       
   326         uInt        _outpos;
       
   327         uInt        _limit;
       
   328 
       
   329         _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   330 
       
   331         _limit   = _zstream->out_limit;
       
   332         _outpos  = _zstream->out_position;
       
   333         _count   = __intVal( count );
       
   334 
       
   335         if( (_outpos >= _limit) || (_count <= 0) )
       
   336             RETURN( __MKSMALLINT (0) );
       
   337 
       
   338         if( (_offs = __intVal (start) - 1) < 0 )
       
   339             goto bad;
       
   340 
       
   341         if (__isBytes (inBytes)) {
       
   342             _bytes = __ByteArrayInstPtr(inBytes)->ba_element;
       
   343         } else if ( __isString(inBytes) ) {
       
   344             _bytes = __stringVal( inBytes );
       
   345         } else
       
   346             goto bad;
       
   347 
       
   348         _capacity = (int) _limit - _outpos;
       
   349 
       
   350         if(_count > _capacity )
       
   351             _count = _capacity;
       
   352 
       
   353         zmemcpy( (Bytef *) & _bytes[_offs], _zstream->out_ref + _outpos, _count );
       
   354         _zstream->out_position += _count;
       
   355         RETURN( __MKSMALLINT (_count) );
       
   356     }
       
   357 bad:;
       
   358 %}.
       
   359     zstream ifNil:[ self errorNotOpen ].
       
   360     self invalidArguments .
       
   361 !
       
   362 
       
   363 zNextPutByte:aByte
       
   364 %{
       
   365     OBJ _zstreamObj = __INST( zstream );
       
   366 
       
   367     if( _zstreamObj != nil )
       
   368     {
       
   369         zstream_s * _zstream;
       
   370         uInt        _inpos;
       
   371         int         _theByte;
       
   372 
       
   373         _zstream  = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   374         _inpos    = _zstream->in_position;
       
   375 
       
   376         if( _inpos >= _zstream->in_total )
       
   377             RETURN( __MKSMALLINT (0) );
       
   378 
       
   379         _theByte = -1;
       
   380 
       
   381         if( __isCharacter(aByte) )
       
   382             _theByte = __intVal(__characterVal(aByte)) & 0xFF;
       
   383         else if( __isSmallInteger(aByte) )
       
   384         {
       
   385             _theByte = __intVal( aByte );
       
   386 
       
   387             if( (_theByte < 0) || (_theByte > 255) )
       
   388                 goto bad;
       
   389         }
       
   390         else
       
   391             goto bad;
       
   392         
       
   393         _zstream->in_ref[_inpos] = (Byte) _theByte;
       
   394         _zstream->in_position   += 1;
       
   395         RETURN( __MKSMALLINT (1) );
       
   396     }
       
   397 bad:;
       
   398 %}.
       
   399     zstream ifNil:[ self errorNotOpen ].
       
   400     self invalidArguments.
       
   401 !
       
   402 
       
   403 zNextPutBytes:count from:inBytes startingAt:start
       
   404 %{
       
   405     OBJ _zstreamObj = __INST( zstream );
       
   406 
       
   407     if( (_zstreamObj != nil) && __bothSmallInteger(count, start) )
       
   408     {
       
   409         int         _count, _offs, _bsize;
       
   410         char      * _bytes;
       
   411         zstream_s * _zstream;
       
   412         uInt        _inpos;
       
   413         uInt        _total;
       
   414 
       
   415         _zstream  = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   416         _inpos    = _zstream->in_position;
       
   417         _total    = _zstream->in_total;
       
   418         _count    = __intVal( count );
       
   419 
       
   420         if( (_inpos >= _total) || (_count <= 0) )
       
   421             RETURN( __MKSMALLINT (0) );
       
   422 
       
   423         if( (_offs = __intVal (start) - 1) < 0 )
       
   424             goto bad;
       
   425 
       
   426         if (__isBytes (inBytes)) {
       
   427             _bytes = __ByteArrayInstPtr(inBytes)->ba_element;
       
   428             _bsize = __byteArraySize( inBytes );
       
   429         }
       
   430         else if (__isString(inBytes)) {
       
   431             _bytes = __stringVal ( inBytes );
       
   432             _bsize = __stringSize( inBytes );
       
   433         } else
       
   434             goto bad;
       
   435 
       
   436         if( (_count + _offs) < _bsize )
       
   437         {
       
   438             int _capacity = (int) _total - _inpos;
       
   439 
       
   440             if(_count > _capacity )
       
   441                 _count = _capacity;
       
   442 
       
   443             zmemcpy( _zstream->in_ref + _inpos, (Bytef *) & _bytes[_offs], _count );
       
   444             _zstream->in_position += _count;
       
   445             RETURN( __MKSMALLINT (_count) );
       
   446         }
       
   447     }
       
   448 bad:;
       
   449 %}.
       
   450     zstream ifNil:[ self errorNotOpen ].
       
   451     self invalidArguments.
       
   452 !
       
   453 
   196 zclose
   454 zclose
   197 
   455 
   198     onStream := nil.
   456     onStream := nil.
   199     hitEOF   := true.
   457     hitEOF   := true.
   200     zstream ifNil:[^ self].
   458     zstream ifNil:[^ self].
   202 %{
   460 %{
   203     OBJ _zstreamObj = __INST( zstream );
   461     OBJ _zstreamObj = __INST( zstream );
   204 
   462 
   205     if( _zstreamObj != nil )
   463     if( _zstreamObj != nil )
   206     {
   464     {
   207 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   465         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   208 
   466 
   209 	__INST(zstream) = nil;
   467         __INST(zstream) = nil;
   210 
   468 
   211 	if( _zstream->stream.state != NULL )
   469         if( _zstream->stream.state != NULL )
   212 	{
   470         {
   213 	    if( __INST(isReadOpen) == true )
   471             if( __INST(isReadOpen) == true )
   214 		inflateEnd( & _zstream->stream );
   472                 inflateEnd( & _zstream->stream );
   215 	    else
   473             else
   216 		deflateEnd( & _zstream->stream );
   474                 deflateEnd( & _zstream->stream );
   217 	}
   475         }
   218 	free( _zstream );
   476         free( _zstream );
   219     }
   477     }
   220 %}.
   478 %}.
   221     zstream := nil.
   479     zstream := nil.
   222 !
   480 !
   223 
   481 
   229 %{
   487 %{
   230     OBJ _zstreamObj = __INST( zstream );
   488     OBJ _zstreamObj = __INST( zstream );
   231 
   489 
   232     if( (_zstreamObj != nil) && (__isSmallInteger(aLevel)) )
   490     if( (_zstreamObj != nil) && (__isSmallInteger(aLevel)) )
   233     {
   491     {
   234 	int _errorNo, _level;
   492         int _errorNo, _level;
   235 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   493         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   236 
   494 
   237 	_level   = __intVal( aLevel );
   495         _level   = __intVal( aLevel );
   238 	_errorNo = deflate( & _zstream->stream, __intVal(aLevel) );
   496         _errorNo = deflate( & _zstream->stream, __intVal(aLevel) );
   239 
   497 
   240 	if( _errorNo == Z_STREAM_END ) RETURN( true  );
   498         if( _zstream->stream.avail_in == 0 )
   241 	if( _errorNo == Z_OK )         RETURN( false );
   499         {
   242 
   500             _zstream->in_position    = 0;
   243 	errorNo = __MKSMALLINT( _errorNo );
   501             _zstream->stream.next_in = Z_NULL;
       
   502         }
       
   503         if( _errorNo == Z_STREAM_END ) RETURN( true  );
       
   504         if( _errorNo == Z_OK )         RETURN( false );
       
   505 
       
   506         errorNo = __MKSMALLINT( _errorNo );
   244     }
   507     }
   245 %}.
   508 %}.
   246     errorNo ifNil:[
   509     errorNo ifNil:[
   247 	zstream ifNil:[self errorNotOpen].
   510         zstream ifNil:[self errorNotOpen].
   248 	self invalidArguments.
   511         self invalidArguments.
   249     ].
   512     ].
   250     self zerror:errorNo.
   513     self zerror:errorNo.
   251 !
   514 !
   252 
   515 
   253 zdeflateEnd
   516 zdeflateEnd
   258 %{
   521 %{
   259     OBJ _zstreamObj = __INST( zstream );
   522     OBJ _zstreamObj = __INST( zstream );
   260 
   523 
   261     if( _zstreamObj != nil )
   524     if( _zstreamObj != nil )
   262     {
   525     {
   263 	int         _errorNo;
   526         int         _errorNo;
   264 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   527         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   265 
   528 
   266 	_errorNo = deflateEnd( & _zstream->stream );
   529         _errorNo = deflateEnd( & _zstream->stream );
   267 
   530 
   268 	if( _errorNo == Z_OK )
   531         if( _errorNo == Z_OK )
   269 	    RETURN( self );
   532             RETURN( self );
   270 
   533 
   271 	errorNo = __MKSMALLINT( _errorNo );
   534         errorNo = __MKSMALLINT( _errorNo );
   272     }
   535     }
   273 %}.
   536 %}.
   274     errorNo ifNil:[ self errorNotOpen ].
   537     errorNo ifNil:[ self errorNotOpen ].
   275     self zerror:errorNo.
   538     self zerror:errorNo.
   276 !
   539 !
   287        && __isSmallInteger(aLevel)
   550        && __isSmallInteger(aLevel)
   288        && __isSmallInteger(memLevel)
   551        && __isSmallInteger(memLevel)
   289        && __isSmallInteger(strategy)
   552        && __isSmallInteger(strategy)
   290       )
   553       )
   291     {
   554     {
   292 	int         _errorNo;
   555         int         _errorNo;
   293 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   556         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   294 
   557 
   295 	_errorNo = deflateInit2( & _zstream->stream
   558         _errorNo = deflateInit2( & _zstream->stream
   296 			       , __intVal( aLevel )
   559                                , __intVal( aLevel )
   297 			       , Z_DEFLATED
   560                                , Z_DEFLATED
   298 			       , -MAX_WBITS
   561                                , -MAX_WBITS
   299 			       , __intVal( memLevel )
   562                                , __intVal( memLevel )
   300 			       , __intVal( strategy )
   563                                , __intVal( strategy )
   301 			       );
   564                                );
   302 
   565 
   303 	if( _errorNo == Z_OK )
   566         if( _errorNo == Z_OK )
   304 	    RETURN( self );
   567             RETURN( self );
   305 
   568 
   306 	errorNo = __MKSMALLINT( _errorNo );
   569         errorNo = __MKSMALLINT( _errorNo );
   307     }
   570     }
   308 %}.
   571 %}.
   309     errorNo ifNil:[
   572     errorNo ifNil:[
   310 	zstream ifNil:[ self errorNotOpen ].
   573         zstream ifNil:[ self errorNotOpen ].
   311 	self invalidArguments .
   574         self invalidArguments .
   312     ].
   575     ].
   313     self zerror:errorNo.
   576     self zerror:errorNo.
   314 !
   577 !
   315 
   578 
   316 zflush:forced
   579 zflush:forced
   321 %{
   584 %{
   322     OBJ _zstreamObj = __INST( zstream );
   585     OBJ _zstreamObj = __INST( zstream );
   323 
   586 
   324     if( _zstreamObj != nil )
   587     if( _zstreamObj != nil )
   325     {
   588     {
   326 	uInt        _max, _len;
   589         uInt        _max, _len;
   327 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   590         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   328 
   591 
   329 	_max = _zstream->out_total;
   592         _max = _zstream->out_total;
   330 	_len = _max - _zstream->stream.avail_out;
   593         _len = _max - _zstream->stream.avail_out;
   331 
   594 
   332 	if( (_len == 0) || ((forced == false) && (_len != _max)) )
   595         if( (_len == 0) || ((forced == false) && (_len != _max)) )
   333 	    RETURN( __MKSMALLINT(0) );
   596             RETURN( __MKSMALLINT(0) );
   334 
   597 
   335 	_zstream->stream.avail_out = _max;
   598         _zstream->stream.avail_out = _max;
   336 	_zstream->stream.next_out  = _zstream->out_ref;
   599         _zstream->stream.next_out  = _zstream->out_ref;
   337 
   600 
   338 	len = __MKSMALLINT( _len );
   601         len = __MKSMALLINT( _len );
   339     }
   602     }
   340 %}.
   603 %}.
   341     zstream ifNil:[ self errorNotOpen ].
   604     zstream ifNil:[ self errorNotOpen ].
   342     self onStreamPutBytes:len from:outputBytes.
   605     self onStreamPutBytes:len from:outputBytes.
   343 !
   606 !
   344 
   607 
   345 zgetAvailableOutBufferInto:inBytes startingAt:start
   608 zgetCrc32
   346 
   609 
   347 %{
   610 %{
   348     OBJ _zstreamObj = __INST( zstream );
   611     OBJ _zstreamObj = __INST( zstream );
   349 
   612 
   350     if( (_zstreamObj != nil) && __isSmallInteger(start) )
   613     if( _zstreamObj != nil )
   351     {
   614     {
   352 	char *      _bytes;
   615         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   353 	zstream_s * _zstream;
   616         RETURN ( __MKUINT(_zstream->crc_32) );
   354 	int         _count, _offs, _bsize;
   617     }
   355 
   618 %}.
   356 	if (__isBytes (inBytes)) {
   619     self errorNotOpen
   357 	    _bytes = __ByteArrayInstPtr(inBytes)->ba_element;
   620 !
   358 	    _bsize = __byteArraySize( inBytes );
   621 
   359 	} else if ( __isString(inBytes) ) {
   622 zgetTotalIn
   360 	    _bytes = __stringVal( inBytes );
   623 %{
   361 	    _bsize = __stringSize( inBytes );
   624     OBJ _zstreamObj = __INST( zstream );
   362 	} else
   625 
   363 	    goto bad;
   626     if( _zstreamObj != nil )
   364 
   627     {
   365 	_zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   628         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   366 	_count   = _zstream->out_used - _zstream->stream.avail_out;
   629         RETURN ( __MKUINT(_zstream->stream.total_in) );
   367 
   630     }
   368 	_zstream->stream.avail_out = _zstream->out_used = 0;
   631 %}.
   369 	_zstream->stream.next_out  = Z_NULL;
   632     self errorNotOpen
   370 
   633 !
   371 	if( _count < 1 ) { RETURN( __MKSMALLINT(0) ); }
   634 
   372 
   635 zinflateInit
   373 	_offs = __intVal( start ) - 1;
   636     |errorNo|
   374 
   637 
   375 	if( (_count + _offs) <= _bsize )
   638     errorNo := nil.
   376 	{
   639 
   377 	    zmemcpy( (Bytef *) & _bytes[_offs], _zstream->out_ref, _count );
   640 %{
   378 	    RETURN ( __MKSMALLINT(_count) );
   641     OBJ _zstreamObj = __INST( zstream );
   379 	}
   642 
   380     }
   643     if( _zstreamObj != nil )
   381 bad:;
   644     {
       
   645         int         _errorNo;
       
   646         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   647 
       
   648         _errorNo = inflateInit2( & _zstream->stream, -MAX_WBITS );
       
   649 
       
   650         if( _errorNo == Z_OK )
       
   651             RETURN( self );
       
   652 
       
   653         _zstream->stream.avail_in = 0;
       
   654         errorNo = __MKSMALLINT( _errorNo );
       
   655     }
       
   656 %}.
       
   657     errorNo ifNil:[ self errorNotOpen ].
       
   658     self zerror:errorNo.
       
   659 !
       
   660 
       
   661 zinputAvailable
       
   662 %{
       
   663     OBJ _zstreamObj = __INST( zstream );
       
   664 
       
   665     if( _zstreamObj != nil )
       
   666     {
       
   667         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   668 
       
   669         if( _zstream->stream.avail_in != 0 )
       
   670             RETURN( true );
       
   671 
       
   672         RETURN( false );
       
   673     }
       
   674 %}.
       
   675     self errorNotOpen
       
   676 !
       
   677 
       
   678 zinputPosition:count
       
   679 %{
       
   680     OBJ _zstreamObj = __INST( zstream );
       
   681 
       
   682     if( (_zstreamObj != nil) && __isSmallInteger(count) )
       
   683     {
       
   684         int         _count;
       
   685         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   686 
       
   687         _count = __intVal( count );
       
   688 
       
   689         if( _count < 0 )
       
   690         {
       
   691             _zstream->stream.next_in  = Z_NULL;
       
   692             _count = 0;
       
   693         }
       
   694         else
       
   695             _zstream->stream.next_in  = _zstream->in_ref;
       
   696 
       
   697         _zstream->stream.avail_in = _count;
       
   698         RETURN( __MKSMALLINT (_count) );
       
   699     }
   382 %}.
   700 %}.
   383     zstream ifNil:[ self errorNotOpen ].
   701     zstream ifNil:[ self errorNotOpen ].
   384     self invalidArguments .
   702     self invalidArguments .
   385 !
       
   386 
       
   387 zgetCrc32
       
   388 
       
   389 %{
       
   390     OBJ _zstreamObj = __INST( zstream );
       
   391 
       
   392     if( _zstreamObj != nil )
       
   393     {
       
   394 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   395 	RETURN ( __MKUINT(_zstream->crc_32) );
       
   396     }
       
   397 %}.
       
   398     self errorNotOpen
       
   399 !
       
   400 
       
   401 zgetTotalIn
       
   402 %{
       
   403     OBJ _zstreamObj = __INST( zstream );
       
   404 
       
   405     if( _zstreamObj != nil )
       
   406     {
       
   407 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   408 	RETURN ( __MKUINT(_zstream->stream.total_in) );
       
   409     }
       
   410 %}.
       
   411     self errorNotOpen
       
   412 !
       
   413 
       
   414 zinflate
       
   415     |errorNo|
       
   416 
       
   417     errorNo := nil.
       
   418 
       
   419 %{
       
   420     OBJ _zstreamObj = __INST( zstream );
       
   421 
       
   422     if( _zstreamObj != nil )
       
   423     {
       
   424 	int _errorNo;
       
   425 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   426 
       
   427 	_errorNo = inflate( & _zstream->stream, Z_NO_FLUSH );
       
   428 
       
   429 	if( _errorNo == Z_STREAM_END )
       
   430 	{
       
   431 	    __INST(hitEOF) = true;
       
   432 	    _errorNo = inflateEnd( & _zstream->stream );
       
   433 	}
       
   434 	if( _errorNo == Z_OK )
       
   435 	    RETURN( self );
       
   436 
       
   437 	errorNo = __MKSMALLINT( _errorNo );
       
   438     }
       
   439 %}.
       
   440     errorNo ifNil:[ self errorNotOpen ].
       
   441     self zerror:errorNo.
       
   442 !
       
   443 
       
   444 zinflateInit
       
   445     |errorNo|
       
   446 
       
   447     errorNo := nil.
       
   448 
       
   449 %{
       
   450     OBJ _zstreamObj = __INST( zstream );
       
   451 
       
   452     if( _zstreamObj != nil )
       
   453     {
       
   454 	int         _errorNo;
       
   455 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   456 
       
   457 	_errorNo = inflateInit2( & _zstream->stream, -MAX_WBITS );
       
   458 
       
   459 	if( _errorNo == Z_OK )
       
   460 	    RETURN( self );
       
   461 
       
   462 	errorNo = __MKSMALLINT( _errorNo );
       
   463     }
       
   464 %}.
       
   465     errorNo ifNil:[ self errorNotOpen ].
       
   466     self zerror:errorNo.
       
   467 !
       
   468 zinputAvailable
       
   469 %{
       
   470     OBJ _zstreamObj = __INST( zstream );
       
   471 
       
   472     if( _zstreamObj != nil )
       
   473     {
       
   474 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   475 
       
   476 	if( _zstream->stream.avail_in != 0 )
       
   477 	    RETURN( true );
       
   478 
       
   479 	RETURN( false );
       
   480     }
       
   481 %}.
       
   482     self errorNotOpen
       
   483 !
       
   484 
       
   485 zinputPosition:count
       
   486 %{
       
   487     OBJ _zstreamObj = __INST( zstream );
       
   488 
       
   489     if( (_zstreamObj != nil) && __isSmallInteger(count) )
       
   490     {
       
   491 	int         _count;
       
   492 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   493 
       
   494 	_count = __intVal( count );
       
   495 
       
   496 	if( _count < 0 )
       
   497 	{
       
   498 	    _zstream->stream.next_in  = Z_NULL;
       
   499 	    _count = 0;
       
   500 	}
       
   501 	else
       
   502 	    _zstream->stream.next_in  = _zstream->in_ref;
       
   503 
       
   504 	_zstream->stream.avail_in = _count;
       
   505 	RETURN( __MKSMALLINT (_count) );
       
   506     }
       
   507 %}.
       
   508     zstream ifNil:[ self errorNotOpen ].
       
   509     self invalidArguments .
       
   510 !
       
   511 
       
   512 znextPutBytes:count from:inBytes startingAt:start
       
   513 %{
       
   514     OBJ _zstreamObj = __INST( zstream );
       
   515 
       
   516     if( (_zstreamObj != nil) && __bothSmallInteger(count, start) )
       
   517     {
       
   518 	int         _count, _offs, _bsize;
       
   519 	char      * _bytes;
       
   520 	Bytef     * _in_ref;
       
   521 	zstream_s * _zstream;
       
   522 
       
   523 	_zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   524 	_in_ref  = _zstream->in_ref;
       
   525 
       
   526 	if( (_count = __intVal (count)) <= 0 )
       
   527 	{
       
   528 	    uInt _b;
       
   529 
       
   530 	    if( _count < 0 ) goto bad;
       
   531 
       
   532 	    if( __isCharacter(inBytes) )
       
   533 		_b = __intVal(__characterVal(inBytes)) & 0xFF;
       
   534 	    else if( __isSmallInteger(inBytes) )
       
   535 	    {
       
   536 		_b = __intVal( inBytes );
       
   537 
       
   538 		if( (_b < 0) || (_b > 255) ) goto bad;
       
   539 	    }
       
   540 	    else
       
   541 		{ RETURN(__MKSMALLINT (0) ); }
       
   542 
       
   543 	    _in_ref[0] = (Byte) _b;
       
   544 	    _zstream->stream.avail_in = 1;
       
   545 	    _zstream->stream.next_in  = _in_ref;
       
   546 	    _zstream->crc_32 = crc32( _zstream->crc_32, _in_ref, 1 );
       
   547 
       
   548 	    RETURN(__MKSMALLINT (1) );
       
   549 	}
       
   550 
       
   551 	if( (_offs = __intVal (start) - 1) < 0 )
       
   552 	    goto bad;
       
   553 
       
   554 	if (__isBytes (inBytes)) {
       
   555 	    _bytes = __ByteArrayInstPtr(inBytes)->ba_element;
       
   556 	    _bsize = __byteArraySize( inBytes );
       
   557 	}
       
   558 	else if (__isString(inBytes)) {
       
   559 	    _bytes = __stringVal ( inBytes );
       
   560 	    _bsize = __stringSize( inBytes );
       
   561 	} else
       
   562 	    goto bad;
       
   563 
       
   564 	if( (_count + _offs) < _bsize )
       
   565 	{
       
   566 	    if(_count > _zstream->in_total )
       
   567 		_count = _zstream->in_total;
       
   568 
       
   569 	    _zstream->stream.avail_in = _count;
       
   570 	    _zstream->stream.next_in  = _in_ref;
       
   571 
       
   572 	    zmemcpy( _in_ref, (Bytef *) & _bytes[_offs], _count );
       
   573 	    _zstream->crc_32 = crc32( _zstream->crc_32, _in_ref, _count );
       
   574 
       
   575 	    RETURN( __MKSMALLINT (_count) );
       
   576 	}
       
   577     }
       
   578 bad:;
       
   579 %}.
       
   580     zstream ifNil:[ self errorNotOpen ].
       
   581     self invalidArguments.
       
   582 !
   703 !
   583 
   704 
   584 zopen:aStream
   705 zopen:aStream
   585     |outTotal inTotal|
   706     |outTotal inTotal|
   586 
   707 
   595 %{
   716 %{
   596     zstream_s * _zstream = (zstream_s *) malloc( sizeof(zstream_s) );
   717     zstream_s * _zstream = (zstream_s *) malloc( sizeof(zstream_s) );
   597 
   718 
   598     if( _zstream )
   719     if( _zstream )
   599     {
   720     {
   600 	OBJ     _zobj   = __MKEXTERNALADDRESS( _zstream );
   721         OBJ     _zobj   = __MKEXTERNALADDRESS( _zstream );
   601 	OBJ     _outObj = __INST( outputBytes );
   722         OBJ     _outObj = __INST( outputBytes );
   602 	OBJ     _inpObj = __INST( inputBytes  );
   723         OBJ     _inpObj = __INST( inputBytes  );
   603 
   724 
   604 	zmemzero( _zstream, sizeof(zstream_s) );
   725         zmemzero( _zstream, sizeof(zstream_s) );
   605 
   726 
   606 	_zstream->in_total         = __intVal( inTotal );
   727         _zstream->in_total         = __intVal( inTotal );
   607 	_zstream->in_ref           = (Bytef *) __externalBytesAddress( _inpObj );
   728         _zstream->in_position      = 0;
   608 	_zstream->stream.next_in   = Z_NULL;
   729         _zstream->in_ref           = (Bytef *) __externalBytesAddress( _inpObj );
   609 	_zstream->stream.avail_in  = 0;
   730         _zstream->stream.next_in   = Z_NULL;
   610 	_zstream->stream.total_in  = 0;
   731         _zstream->stream.avail_in  = 0;
   611 
   732         _zstream->stream.total_in  = 0;
   612 	_zstream->out_used         = 0;
   733 
   613 	_zstream->out_total        = __intVal( outTotal );
   734         _zstream->out_position     = 0;
   614 	_zstream->out_ref          = (Bytef *) __externalBytesAddress( _outObj );
   735         _zstream->out_limit        = 0;
   615 	_zstream->stream.next_out  = _zstream->out_ref;
   736         _zstream->out_atStreamEnd  = 0;
   616 	_zstream->stream.avail_out = _zstream->out_total;
   737         _zstream->out_total        = __intVal( outTotal );
   617 	_zstream->stream.total_out = 0;
   738         _zstream->out_ref          = (Bytef *) __externalBytesAddress( _outObj );
   618 
   739         _zstream->stream.next_out  = _zstream->out_ref;
   619 	_zstream->stream.zalloc    = (alloc_func)0;
   740         _zstream->stream.avail_out = _zstream->out_total;
   620 	_zstream->stream.zfree     = (free_func) 0;
   741         _zstream->stream.total_out = 0;
   621 	_zstream->stream.opaque    = (voidpf)    0;
   742 
   622 
   743         _zstream->stream.zalloc    = (alloc_func)0;
   623 	_zstream->crc_32           = crc32( 0L, Z_NULL, 0 );
   744         _zstream->stream.zfree     = (free_func) 0;
   624 
   745         _zstream->stream.opaque    = (voidpf)    0;
   625 	__INST (zstream) = _zobj;
   746 
   626 	__STORE(self, _zobj);
   747         _zstream->crc_32           = crc32( 0L, Z_NULL, 0 );
       
   748 
       
   749         __INST (zstream) = _zobj;
       
   750         __STORE(self, _zobj);
   627     }
   751     }
   628 %}.
   752 %}.
   629     zstream ifNil:[ self zerror:'cannot allocate zbuffer' ].
   753     zstream ifNil:[ self zerror:'cannot allocate zbuffer' ].
   630     hitEOF := false.
   754     hitEOF := false.
   631 !
       
   632 
       
   633 zoutputLimit:count
       
   634 %{
       
   635     OBJ _zstreamObj = __INST( zstream );
       
   636 
       
   637     if( (_zstreamObj != nil) && __isSmallInteger(count) )
       
   638     {
       
   639 	int         _usedSz;
       
   640 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   641 
       
   642 	_usedSz = __intVal (count);
       
   643 
       
   644 	if( _usedSz > 0 )
       
   645 	{
       
   646 	    if( _usedSz > _zstream->out_total )
       
   647 		_usedSz = _zstream->out_total;
       
   648 	}
       
   649 	else
       
   650 	    _usedSz = 0;
       
   651 
       
   652 	_zstream->stream.next_out  = _zstream->out_ref;
       
   653 	_zstream->stream.avail_out = _zstream->out_used = _usedSz;
       
   654 
       
   655 	RETURN( __MKSMALLINT(_usedSz) );
       
   656     }
       
   657 %}.
       
   658     zstream ifNil:[ self errorNotOpen ].
       
   659     self invalidArguments .
       
   660 !
       
   661 
       
   662 zoutputLimitReached
       
   663     "returns true if the write limit is reached; must flush the buffer
       
   664     "
       
   665 %{
       
   666     OBJ _zstreamObj = __INST( zstream );
       
   667 
       
   668     if( _zstreamObj != nil )
       
   669     {
       
   670 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
       
   671 
       
   672 	if( _zstream->stream.avail_out == 0 )
       
   673 	    RETURN( true );
       
   674 
       
   675 	RETURN( false );
       
   676     }
       
   677 %}.
       
   678     self errorNotOpen
       
   679 ! !
   755 ! !
   680 
   756 
   681 !ZipStream methodsFor:'private'!
   757 !ZipStream methodsFor:'private'!
   682 
   758 
   683 onStreamPutBytes:count from:data
   759 onStreamPutBytes:count from:data
   691 
   767 
   692     bytes := ByteArray new:4.
   768     bytes := ByteArray new:4.
   693     value := aLong.
   769     value := aLong.
   694 
   770 
   695     1 to:4 do:[:i|
   771     1 to:4 do:[:i|
   696 	bytes at:i put:(value bitAnd:16rff).
   772         bytes at:i put:(value bitAnd:16rff).
   697 	value := value bitShift:-8.
   773         value := value bitShift:-8.
   698     ].
   774     ].
   699     self onStreamPutBytes:(bytes size) from:bytes
   775     self onStreamPutBytes:(bytes size) from:bytes
   700 !
   776 !
   701 
   777 
   702 onStreamReadBytesInto:data
   778 onStreamReadBytesInto:data
   713     self isReadOpen ifFalse:[ self pastEnd ].
   789     self isReadOpen ifFalse:[ self pastEnd ].
   714 
   790 
   715     "Check the gzip magic id
   791     "Check the gzip magic id
   716     "
   792     "
   717     GZ_MAGIC_ID do:[:b|
   793     GZ_MAGIC_ID do:[:b|
   718 	onStream nextByte ~~ b ifTrue:[ self zerror:'version error' ]
   794         onStream nextByte ~~ b ifTrue:[ self zerror:'version error' ]
   719     ].
   795     ].
   720 
   796 
   721     method := onStream nextByte.
   797     method := onStream nextByte.
   722     method ~~ Z_DEFLATED ifTrue:[
   798     method ~~ Z_DEFLATED ifTrue:[
   723 	self zerror:'invalid method (not deflated)'
   799         self zerror:'invalid method (not deflated)'
   724     ].
   800     ].
   725 
   801 
   726     flags := onStream nextByte.
   802     flags := onStream nextByte.
   727     (flags bitAnd:HEAD_RESERVED) ~~ 0 ifTrue:[
   803     (flags bitAnd:HEAD_RESERVED) ~~ 0 ifTrue:[
   728 	self zerror:'wrong data format'
   804         self zerror:'wrong data format'
   729     ].
   805     ].
   730 
   806 
   731     "discard time, xflags and OS code
   807     "discard time, xflags and OS code
   732     "
   808     "
   733     onStream skip:6.
   809     onStream skip:6.
   734 
   810 
   735     (flags bitAnd:HEAD_EXTRA_FIELD) ~~ 0 ifTrue:[|len|
   811     (flags bitAnd:HEAD_EXTRA_FIELD) ~~ 0 ifTrue:[|len|
   736 	"skip the extra field"
   812         "skip the extra field"
   737 	len := onStream nextByte + (onStream nextByte bitShift:8).
   813         len := onStream nextByte + (onStream nextByte bitShift:8).
   738 	len timesRepeat:[ onStream nextByte ].
   814         len timesRepeat:[ onStream nextByte ].
   739     ].
   815     ].
   740 
   816 
   741     (flags bitAnd:HEAD_ORIG_NAME) ~~ 0 ifTrue:[|b|
   817     (flags bitAnd:HEAD_ORIG_NAME) ~~ 0 ifTrue:[|b|
   742 	"skip the original file name"
   818         "skip the original file name"
   743 	Transcript show:'header name: '.
   819         Transcript show:'header name: '.
   744 	[ (b := onStream nextByte) ~~ 0 ] whileTrue:[
   820         [ (b := onStream nextByte) ~~ 0 ] whileTrue:[
   745 	    Transcript show:(Character value:b)
   821             Transcript show:(Character value:b)
   746 	].
   822         ].
   747 	Transcript cr.
   823         Transcript cr.
   748     ].
   824     ].
   749 
   825 
   750     (flags bitAnd:HEAD_CRC) ~~ 0 ifTrue:[
   826     (flags bitAnd:HEAD_CRC) ~~ 0 ifTrue:[
   751 	"skip the header crc"
   827         "skip the header crc"
   752 	onStream skip:2.
   828         onStream skip:2.
   753     ].
   829     ].
   754 
   830 
   755 !
   831 !
   756 
   832 
   757 writeHeader
   833 writeHeader
   781     "
   857     "
   782     onStream nextPutByte:HEAD_OS_CODE.
   858     onStream nextPutByte:HEAD_OS_CODE.
   783 
   859 
   784 ! !
   860 ! !
   785 
   861 
   786 
       
   787 !ZipStream methodsFor:'queries'!
   862 !ZipStream methodsFor:'queries'!
   788 
   863 
   789 atEnd
   864 atEnd
   790     ^ hitEOF ~~ false
   865     ^ hitEOF ~~ false
   791 !
   866 !
   810 ! !
   885 ! !
   811 
   886 
   812 !ZipStream methodsFor:'reading'!
   887 !ZipStream methodsFor:'reading'!
   813 
   888 
   814 contents
   889 contents
   815    |out buf bsz|
   890    |out buf bufSize count|
   816 
   891 
   817    self isReadOpen ifFalse:[self pastEnd].
   892    self isReadOpen ifFalse:[self pastEnd].
   818 
   893 
   819    bsz := inputBytes size.
   894    "use the maximum size read at time
       
   895    "
       
   896    bufSize := outputBytes size.
   820 
   897 
   821    binary ifFalse:[
   898    binary ifFalse:[
   822 	out := (String new:bsz) writeStream.
   899         out := (String new:bufSize) writeStream.
   823 	buf := String new:bsz.
   900         buf := String new:bufSize.
   824    ] ifTrue:[
   901    ] ifTrue:[
   825 	out := (ByteArray new:bsz) writeStream.
   902         out := (ByteArray new:bufSize) writeStream.
   826 	buf := ByteArray new:bsz.
   903         buf := ByteArray new:bufSize.
   827    ].
   904    ].
   828 
   905 
   829    [self atEnd ] whileFalse:[ |n|
   906    [    count := self nextAvailableBytes:bufSize into:buf startingAt:1.
   830 	n := self nextAvailableBytes:bsz into:buf startingAt:1.
   907         count ~~ 0
   831 
   908    ] whileTrue:[
   832 	n ~~ 0 ifTrue:[
   909         out nextPutAll:buf startingAt:1 to:count
   833 	    out nextPutAll:buf startingAt:1 to:n
       
   834 	]
       
   835    ].
   910    ].
   836    ^ out contents
   911    ^ out contents
   837 
   912 
   838 "
   913 "
   839    |gzFile zip contents|
   914    |gzFile zip contents|
   841    gzFile := FileStream readonlyFileNamed:'/home/ca/C/Compress/zlib-1.1.4/Test/YYY.gz'.
   916    gzFile := FileStream readonlyFileNamed:'/home/ca/C/Compress/zlib-1.1.4/Test/YYY.gz'.
   842    [
   917    [
   843      zip := self new readOpenOn:gzFile.
   918      zip := self new readOpenOn:gzFile.
   844      contents := zip contents.
   919      contents := zip contents.
   845    ] valueNowOrOnUnwindDo:[
   920    ] valueNowOrOnUnwindDo:[
   846 	zip ifNotNil:[ zip close ].
   921         zip ifNotNil:[ zip close ].
   847 	gzFile close.
   922         gzFile close.
   848    ].
   923    ].
   849    ^ contents
   924    ^ contents
   850 "
   925 "
   851 
   926 
   852 !
   927 !
   855     |b|
   930     |b|
   856 
   931 
   857     b := self nextByte.
   932     b := self nextByte.
   858 
   933 
   859     b ifNotNil:[
   934     b ifNotNil:[
   860 	binary ifTrue:[^ b ].
   935         binary ifTrue:[^ b ].
   861       ^ Character value:b
   936       ^ Character value:b
   862     ].
   937     ].
   863     ^ nil
   938     ^ nil
   864 !
   939 !
   865 
   940 
   866 next:count
   941 next:count
   867     ^ self nextAvailable:count
   942     ^ self nextAvailable:count
   868 !
   943 !
       
   944 
   869 nextAvailable:count
   945 nextAvailable:count
   870     |n buffer|
   946     |n buffer|
   871 
   947 
   872     self isReadOpen ifFalse:[ self pastEnd ].
   948     self isReadOpen ifFalse:[ self pastEnd ].
   873 
   949 
   874     binary ifTrue:[
   950     binary ifTrue:[
   875 	buffer := ByteArray uninitializedNew:count
   951         buffer := ByteArray uninitializedNew:count
   876     ] ifFalse:[
   952     ] ifFalse:[
   877 	buffer := String new:count
   953         buffer := String new:count
   878     ].
   954     ].
   879 
   955 
   880     n := self nextAvailableBytes:count into:buffer startingAt:1.
   956     n := self nextAvailableBytes:count into:buffer startingAt:1.
   881 
   957 
   882     n == 0 ifTrue:[
   958     n == 0 ifTrue:[
   883 	binary ifTrue:[
   959         binary ifTrue:[
   884 	    ^ #[]
   960             ^ #[]
   885 	].
   961         ].
   886 	^ ''
   962         ^ ''
   887     ].
   963     ].
   888     n ~~ count ifTrue:[ ^ buffer copyTo:n ].
   964     n ~~ count ifTrue:[ ^ buffer copyTo:n ].
   889   ^ buffer.
   965   ^ buffer.
   890 !
   966 !
   891 
   967 
   892 nextAvailableBytes:count into:buffer startingAt:start
   968 nextAvailableBytes:aCount into:inBytes startingAt:start
   893     |eoStream|
   969     |count offs|
   894 
   970 
   895     self isReadOpen ifFalse:[ self pastEnd ].
   971     self isReadOpen ifFalse:[ self pastEnd ].
   896 
   972 
   897     (self zoutputLimit:count) < 0 ifTrue:[^ 0].
   973     count := aCount.
   898 
   974     offs  := start.
   899     eoStream := false.
   975 
   900 
   976     [count > 0] whileTrue:[ |n|
   901     [ self atEnd or:[self zoutputLimitReached] ] whileFalse:[
   977         n := self zNextAvailableBytes:count into:inBytes startingAt:offs.
   902 	self zinputAvailable ifFalse:[ |n|
   978 
   903 	    n := self onStreamReadBytesInto:inputBytes.
   979         n == 0 ifTrue:[
   904 
   980             n := self zFlushOutPutBuffer.
   905 	    n == 0 ifTrue:[
   981 
   906 		eoStream ifTrue:[ self pastEnd ].
   982             n == 0 ifTrue:[
   907 		eoStream := true.
   983                 self atEnd ifTrue:[ ^ offs - 1 ].
   908 	    ].
   984 
   909 	    self zinputPosition:n.
   985                 n := self onStreamReadBytesInto:inputBytes.
   910 	].
   986                 n == 0 ifTrue:[
   911 	self zinflate.
   987                     self pastEnd
   912     ].
   988                 ].
   913     ^ self zgetAvailableOutBufferInto:buffer startingAt:start.
   989                 self zinputPosition:n.
       
   990             ]
       
   991         ] ifFalse:[
       
   992             count := count - n.
       
   993             offs  := offs  + n.
       
   994         ]
       
   995     ].
       
   996     ^ aCount
   914 !
   997 !
   915 
   998 
   916 nextByte
   999 nextByte
   917     |buff size|
  1000     |buff size|
   918 
  1001 
   919     buff := ByteArray new:1.
  1002     buff := ByteArray new:1.
   920     size := self nextAvailableBytes:1 into:buff startingAt:1.
  1003     size := self nextAvailableBytes:1 into:buff startingAt:1.
   921 
  1004 
   922     size ~~ 0 ifTrue:[
  1005     size ~~ 0 ifTrue:[
   923 	^ buff at:1
  1006         ^ buff at:1
   924     ].
  1007     ].
   925     ^ nil
  1008     ^ nil
   926 ! !
  1009 ! !
   927 
  1010 
   928 !ZipStream methodsFor:'startup & release'!
  1011 !ZipStream methodsFor:'startup & release'!
   929 
  1012 
   930 close
  1013 close
   931     zstream ifNil:[^ self].
  1014     zstream ifNil:[^ self].
   932 
  1015 
   933     self isWriteOpen ifTrue:[
  1016     self isWriteOpen ifTrue:[
   934 	[   self zflush:true.
  1017         self zFlushInputBuffer.
   935 	    self zdeflate:Z_FINISH
  1018 
   936 	] whileFalse.
  1019         [   self zflush:true.
   937 
  1020             self zdeflate:Z_FINISH
   938 	self zflush:true.
  1021         ] whileFalse.
   939 	self zdeflateEnd.
  1022 
   940 
  1023         self zflush:true.
   941 	self onStreamPutLong:(self zgetCrc32  ).    " write crc "
  1024         self zdeflateEnd.
   942 	self onStreamPutLong:(self zgetTotalIn).    " write total size "
  1025 
       
  1026         self onStreamPutLong:(self zgetCrc32  ).    " write crc "
       
  1027         self onStreamPutLong:(self zgetTotalIn).    " write total size "
   943     ].
  1028     ].
   944     self zclose.
  1029     self zclose.
   945 !
  1030 !
   946 
  1031 
   947 readOpenOn:aStream
  1032 readOpenOn:aStream
       
  1033     |n|
   948 
  1034 
   949     isReadOpen := true.
  1035     isReadOpen := true.
   950 
  1036 
   951     self zopen:aStream.
  1037     self zopen:aStream.
   952     self zinflateInit.
  1038     self zinflateInit.
   953     self readHeader.
  1039     self readHeader.
       
  1040 
       
  1041     n := self onStreamReadBytesInto:inputBytes.
       
  1042     n == 0 ifTrue:[ self pastEnd ].
       
  1043     self zinputPosition:n.
   954 !
  1044 !
   955 
  1045 
   956 writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy
  1046 writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy
   957 
  1047 
   958     isReadOpen := false.
  1048     isReadOpen := false.
   963 ! !
  1053 ! !
   964 
  1054 
   965 !ZipStream methodsFor:'writing'!
  1055 !ZipStream methodsFor:'writing'!
   966 
  1056 
   967 flush
  1057 flush
   968     "force flush output
  1058     "flush output buffer
   969     "
  1059     "
   970     self flush:true
  1060     self flush:true
   971 !
  1061 !
   972 
  1062 
   973 flush:forced
  1063 flush:forced
   974 
  1064 
   975     self isWriteOpen ifTrue:[
  1065     self isWriteOpen ifTrue:[
   976 	self zflush:forced
  1066         self zflush:forced
   977     ] ifFalse:[
  1067     ] ifFalse:[
   978 	onStream ifNil:[self pastEnd]
  1068         onStream ifNil:[self pastEnd]
   979     ].
  1069     ].
   980 !
  1070 !
   981 
  1071 
   982 nextPut:aCharacter
  1072 nextPut:aCharacter
   983     |count|
       
   984 
  1073 
   985     self isWriteOpen ifFalse:[ self pastEnd ].
  1074     self isWriteOpen ifFalse:[ self pastEnd ].
   986 
  1075 
   987     count := self znextPutBytes:0 from:aCharacter startingAt:0.
  1076     [ (self zNextPutByte:aCharacter) == 0 ] whileTrue:[
   988 
  1077         self zFlushInputBuffer
   989     [
  1078     ].
   990 	self zflush:false.
  1079 !
   991 	self zdeflate:Z_NO_FLUSH.
  1080 
   992 	self zinputAvailable
  1081 nextPutAll:buffer
   993     ] whileTrue.
  1082     self nextPutBytes:(buffer size) from:buffer startingAt:1
       
  1083 !
       
  1084 
       
  1085 nextPutAll:aCollection startingAt:start to:stop
       
  1086     self nextPutBytes:(stop - start + 1) from:aCollection startingAt:start
   994 !
  1087 !
   995 
  1088 
   996 nextPutByte:aByte
  1089 nextPutByte:aByte
   997     self nextPut:aByte.
  1090     self nextPut:aByte.
   998 !
  1091 !
   999 
  1092 
  1000 nextPutAll:buffer
  1093 nextPutBytes:aCount from:inBytes startingAt:start
  1001     |count offset|
  1094     |count offs|
  1002 
       
  1003     count  := buffer size.
       
  1004     offset := 1.
       
  1005 
       
  1006     [ count > 0 ] whileTrue:[ |n|
       
  1007 	n := self nextPutBytes:count from:buffer startingAt:offset.
       
  1008 	offset := offset + n.
       
  1009 	count  := count  - n.
       
  1010     ].
       
  1011 !
       
  1012 
       
  1013 nextPutBytes:count from:inBytes startingAt:start
       
  1014     |n|
       
  1015 
  1095 
  1016     self isWriteOpen ifFalse:[ self pastEnd ].
  1096     self isWriteOpen ifFalse:[ self pastEnd ].
  1017 
  1097 
  1018     n := self znextPutBytes:count from:inBytes startingAt:start.
  1098     count := aCount.
  1019 
  1099     offs  := start.
  1020     n ~~ 0 ifTrue:[
  1100 
  1021 	[
  1101     [count > 0] whileTrue:[ |n|
  1022 	    self zflush:false.
  1102         n := self zNextPutBytes:count from:inBytes startingAt:offs.
  1023 	    self zdeflate:Z_NO_FLUSH.
  1103 
  1024 	    self zinputAvailable
  1104         n == 0 ifTrue:[
  1025 	] whileTrue.
  1105             self zFlushInputBuffer
  1026     ].
  1106         ] ifFalse:[
  1027     ^ n
  1107             count := count - n.
       
  1108             offs  := offs  + n.
       
  1109         ]
       
  1110     ].
       
  1111     ^ aCount
  1028 ! !
  1112 ! !
  1029 
  1113 
  1030 !ZipStream class methodsFor:'documentation'!
  1114 !ZipStream class methodsFor:'documentation'!
  1031 
  1115 
  1032 version
  1116 version
  1033     ^ '$Header: /cvs/stx/stx/libbasic2/ZipStream.st,v 1.3 2002-06-19 15:04:58 ca Exp $'
  1117     ^ '$Header: /cvs/stx/stx/libbasic2/ZipStream.st,v 1.4 2002-06-20 08:57:17 ca Exp $'
  1034 ! !
  1118 ! !
       
  1119 ZipStream initialize!