ZipStream.st
changeset 1439 134b4620d6d0
parent 1308 d7bea6d0b3b6
child 1565 ed95bd664ace
equal deleted inserted replaced
1438:e05970898f67 1439:134b4620d6d0
     1 "
     1 "
     2  COPYRIGHT (c) 2002 by eXept Software AG
     2  COPYRIGHT (c) 2002 by eXept Software AG
     3               All Rights Reserved
     3 	      All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    56 !ZipStream class methodsFor:'documentation'!
    56 !ZipStream class methodsFor:'documentation'!
    57 
    57 
    58 copyright
    58 copyright
    59 "
    59 "
    60  COPYRIGHT (c) 2002 by eXept Software AG
    60  COPYRIGHT (c) 2002 by eXept Software AG
    61               All Rights Reserved
    61 	      All Rights Reserved
    62 
    62 
    63  This software is furnished under a license and may be used
    63  This software is furnished under a license and may be used
    64  only in accordance with the terms of that license and with the
    64  only in accordance with the terms of that license and with the
    65  inclusion of the above copyright notice.   This software may not
    65  inclusion of the above copyright notice.   This software may not
    66  be provided or otherwise made available to, or used by, any
    66  be provided or otherwise made available to, or used by, any
    72 documentation
    72 documentation
    73 "
    73 "
    74     Zip compression and decompression (used in gzip and zip)
    74     Zip compression and decompression (used in gzip and zip)
    75 
    75 
    76     [author:]
    76     [author:]
    77         Claus Atzkern
    77 	Claus Atzkern
    78 
    78 
    79     [instance variables:]
    79     [instance variables:]
    80 
    80 
    81     [class variables:]
    81     [class variables:]
    82 
    82 
    86 !
    86 !
    87 
    87 
    88 examples
    88 examples
    89 "
    89 "
    90 
    90 
    91                                                                 [exBegin]
    91 								[exBegin]
    92     |compressed zipStream|
    92     |compressed zipStream|
    93 
    93 
    94     compressed := #[] writeStream.
    94     compressed := #[] writeStream.
    95     zipStream := self writeOpenOn:compressed.
    95     zipStream := self writeOpenOn:compressed.
    96     zipStream nextPutAll:'This is some text 1234567890'.
    96     zipStream nextPutAll:'This is some text 1234567890'.
    98     self information:compressed contents size printString.
    98     self information:compressed contents size printString.
    99 
    99 
   100 self halt.
   100 self halt.
   101     zipStream := self readOpenOn:compressed contents readStream.
   101     zipStream := self readOpenOn:compressed contents readStream.
   102     self information:zipStream contents.
   102     self information:zipStream contents.
   103                                                                 [exEnd]
   103 								[exEnd]
   104 "
   104 "
   105 ! !
   105 ! !
   106 
   106 
   107 !ZipStream class methodsFor:'initialization'!
   107 !ZipStream class methodsFor:'initialization'!
   108 
   108 
   126 
   126 
   127     GZ_MAGIC_ID           := #[ 16r1f 16r8b ]
   127     GZ_MAGIC_ID           := #[ 16r1f 16r8b ]
   128 
   128 
   129 ! !
   129 ! !
   130 
   130 
       
   131 !ZipStream class methodsFor:'ZipInterface compatibility - compress/uncompress'!
       
   132 
       
   133 compress: aUncompressedByteArray into: aCompressedByteArray
       
   134     ""
       
   135     ^ self flatBytesIn: aUncompressedByteArray
       
   136 		  from: 1
       
   137 		    to: (aUncompressedByteArray size)
       
   138 		  into: aCompressedByteArray
       
   139 	    doCompress: true.
       
   140 !
       
   141 
       
   142 flatBytesIn:bytesIn from:start to:stop into:bytesOut doCompress:doCompress
       
   143     "compress or uncompress the bytesIn buffer into the bytesOut buffer; returns
       
   144      the un/compressed size; on error an exception is raised
       
   145     "
       
   146     |errorNr size|
       
   147 
       
   148      size := stop - start + 1.
       
   149 
       
   150      (    (start between:1 and:stop)
       
   151       and:[size > 0
       
   152       and:[bytesIn  size >= stop
       
   153       and:[bytesOut size >  0]]]
       
   154      ) ifFalse:[
       
   155         ^ self error:'invalid argument size'
       
   156     ].
       
   157 
       
   158 %{
       
   159     char *  __bytesIn  = 0;
       
   160     uLong   __countIn  = 0;
       
   161     char *  __bytesOut = 0;
       
   162     uLong   __countOut = 0;
       
   163 
       
   164     if( (__isSmallInteger(start)) && (__isSmallInteger(stop)) && (__isSmallInteger(size)) )
       
   165     {
       
   166         __countIn = __intVal( size );
       
   167 
       
   168         if (__isBytes(bytesIn)) {
       
   169             __bytesIn = __ByteArrayInstPtr(bytesIn)->ba_element;
       
   170         } else {
       
   171             if (__isString(bytesIn)) {
       
   172                 __bytesIn = __stringVal( bytesIn );
       
   173             }
       
   174         }
       
   175 
       
   176         if (__isBytes(bytesOut)) {
       
   177             __bytesOut = __ByteArrayInstPtr(bytesOut)->ba_element;
       
   178             __countOut = __byteArraySize( bytesOut );
       
   179         } else {
       
   180             if (__isString(bytesOut)) {
       
   181                 __bytesOut = __stringVal( bytesOut );
       
   182                 __countOut = __stringSize( bytesOut );
       
   183             }
       
   184         }
       
   185     }
       
   186 
       
   187     if( __bytesOut && __bytesIn )
       
   188     {
       
   189         int __result = Z_OK;
       
   190 
       
   191         __bytesIn += (__intVal( start)) - 1;
       
   192 
       
   193         if( doCompress == true )
       
   194             __result   = compress  ( (Byte *) __bytesOut, & __countOut, (Byte *) __bytesIn, __countIn );
       
   195         else
       
   196             __result   = uncompress( (Byte *) __bytesOut, & __countOut, (Byte *) __bytesIn, __countIn );
       
   197 
       
   198         if( __result == Z_OK )
       
   199             { RETURN(__MKSMALLINT(__countOut)); }
       
   200 
       
   201         errorNr = __MKSMALLINT( __result );
       
   202     }
       
   203 %}.
       
   204 
       
   205     errorNr isNil ifTrue:[ ^ self error:'invalid arguments' ].
       
   206     errorNr ==  1 ifTrue:[ ^ self error:'stream at end' ].
       
   207     errorNr == -3 ifTrue:[ ^ self error:'input data are corrupted' ].
       
   208     errorNr == -4 ifTrue:[ ^ self error:'not enough memory' ].
       
   209     errorNr == -5 ifTrue:[ ^ self error:'not enough memory in the output stream' ].
       
   210 
       
   211     self error:('compressing error: ', errorNr printString).
       
   212 !
       
   213 
       
   214 uncompress: aCompressedByteArray into: aUncompressedByteArray
       
   215     ""
       
   216     ^ self flatBytesIn: aCompressedByteArray
       
   217 		  from: 1
       
   218 		    to: (aCompressedByteArray size)
       
   219 		  into: aUncompressedByteArray
       
   220 	    doCompress: false.
       
   221 ! !
       
   222 
       
   223 !ZipStream class methodsFor:'ZipInterface compatibility - crc'!
       
   224 
       
   225 crc32BytesIn:bytesIn
       
   226     "compute crc with the bytes buf[1.. bytesIn size]
       
   227      and return the crc
       
   228     "
       
   229     ^ self crc32BytesIn:bytesIn from:1
       
   230 !
       
   231 
       
   232 crc32BytesIn:bytesIn crc:aCrc
       
   233     "Update a running crc with the bytes buf[1.. bytesIn size]
       
   234      and return the updated
       
   235     "
       
   236     ^ self crc32BytesIn:bytesIn from:1 crc:aCrc
       
   237 !
       
   238 
       
   239 crc32BytesIn:bytesIn from:start
       
   240     "compute crc with the bytes buf[start.. bytesIn size]
       
   241      and return the crc
       
   242     "
       
   243     ^ self crc32BytesIn:bytesIn from:start to:(bytesIn size)
       
   244 !
       
   245 
       
   246 crc32BytesIn:bytesIn from:start crc:aCrc
       
   247     "Update a running crc with the bytes buf[start.. bytesIn size]
       
   248      and return the updated
       
   249     "
       
   250     ^ self crc32BytesIn:bytesIn from:start to:(bytesIn size) crc:aCrc
       
   251 !
       
   252 
       
   253 crc32BytesIn:bytesIn from:start to:stop
       
   254     "compute crc with the bytes buf[start.. stop]
       
   255      and return the crc
       
   256     "
       
   257     ^ self crc32BytesIn:bytesIn from:start to:stop crc:0
       
   258 !
       
   259 
       
   260 crc32BytesIn:bytesIn from:start to:stop crc:crc
       
   261     "Update a running crc with the bytes buf[start.. stop]
       
   262      and return the updated
       
   263     "
       
   264     |size|
       
   265 
       
   266      size := stop - start + 1.
       
   267 
       
   268      (    (start between:1 and:stop)
       
   269       and:[size > 0
       
   270       and:[bytesIn size >= stop]]
       
   271      ) ifFalse:[
       
   272 	^ self error:'invalid argument size'
       
   273     ].
       
   274 %{
       
   275     if( (__isInteger(crc)) && (__isSmallInteger(start)) && (__isSmallInteger(size)) )
       
   276     {
       
   277 	char * __bytes  = 0;
       
   278 
       
   279 	if (__isBytes(bytesIn)) {
       
   280 	    __bytes = __ByteArrayInstPtr(bytesIn)->ba_element;
       
   281 	} else {
       
   282 	    if (__isString(bytesIn)) {
       
   283 		__bytes = __stringVal( bytesIn );
       
   284 	    }
       
   285 	}
       
   286 
       
   287 	if( __bytes )
       
   288 	{
       
   289 	    uLong  __crc  = __longIntVal( crc );
       
   290 	    uInt   __size = __intVal( size );
       
   291 
       
   292 	    __bytes += (__intVal( start)) - 1;
       
   293 	    __crc = crc32(__crc, (Byte *) __bytes, __size );
       
   294 
       
   295 	    RETURN( __MKUINT(__crc) );
       
   296 	}
       
   297     }
       
   298 %}.
       
   299 
       
   300     ^ self error:'invalid argument size'
       
   301 ! !
       
   302 
   131 !ZipStream methodsFor:'low level'!
   303 !ZipStream methodsFor:'low level'!
   132 
   304 
   133 zclose
   305 zclose
   134     "low level close of the zip stream
   306     "low level close of the zip stream
   135     "
   307     "
   136 %{
   308 %{
   137     OBJ _zstreamObj = __INST( zstream );
   309     OBJ _zstreamObj = __INST( zstream );
   138 
   310 
   139     if( _zstreamObj != nil )
   311     if( _zstreamObj != nil )
   140     {
   312     {
   141 	zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   313         zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj );
   142 
   314 
   143 	__INST(zstream) = nil;
   315         __INST(zstream) = nil;
   144 
   316 
   145 	if( _zstream->stream.state != NULL )
   317         if( _zstream->stream.state != NULL )
   146 	{
   318         {
   147 	    if( _zstream->op_mode == e_opmode_inflate )
   319             if( _zstream->op_mode == e_opmode_inflate )
   148 		inflateEnd( & _zstream->stream );
   320                 inflateEnd( & _zstream->stream );
   149 	    else
   321             else
   150 		deflateEnd( & _zstream->stream );
   322                 deflateEnd( & _zstream->stream );
   151 	}
   323         }
   152 	free( _zstream );
   324         free( _zstream );
   153     }
   325     }
   154 %}.
   326 %}.
   155 !
   327 !
   156 
   328 
   157 zdeflate
   329 zdeflate
   195 	    RETURN( true );
   367 	    RETURN( true );
   196 	}
   368 	}
   197 	_zstream->stream.avail_out = _bfsize;
   369 	_zstream->stream.avail_out = _bfsize;
   198 	_zstream->stream.next_out  = _zstream->out_ref;
   370 	_zstream->stream.next_out  = _zstream->out_ref;
   199 
   371 
   200 	_action  = (__INST(hitEOF) == true) ? Z_FINISH : Z_NO_FLUSH;        
   372 	_action  = (__INST(hitEOF) == true) ? Z_FINISH : Z_NO_FLUSH;
   201 	_errorNo = deflate( & _zstream->stream, _action );
   373 	_errorNo = deflate( & _zstream->stream, _action );
   202 
   374 
   203 	if( _errorNo == Z_STREAM_END )
   375 	if( _errorNo == Z_STREAM_END )
   204 	{
   376 	{
   205 	    _zstream->stream.avail_in = 0;
   377 	    _zstream->stream.avail_in = 0;
   488 
   660 
   489 openWithMode:aMode on:aStream
   661 openWithMode:aMode on:aStream
   490 
   662 
   491     super openWithMode:aMode on:aStream.
   663     super openWithMode:aMode on:aStream.
   492     self isReadable ifTrue:[
   664     self isReadable ifTrue:[
   493         "Check for the gzip magic id"
   665 	"Check for the gzip magic id"
   494         |flags|
   666 	|flags|
   495 
   667 
   496         GZ_MAGIC_ID do:[:b|
   668 	GZ_MAGIC_ID do:[:b|
   497             onStream nextByte ~~ b ifTrue:[ self zerror:'version error' ]
   669 	    onStream nextByte ~~ b ifTrue:[ self zerror:'version error' ]
   498         ].
   670 	].
   499 
   671 
   500         onStream nextByte ~~ Z_DEFLATED ifTrue:[
   672 	onStream nextByte ~~ Z_DEFLATED ifTrue:[
   501             self zerror:'invalid method (not deflated)'
   673 	    self zerror:'invalid method (not deflated)'
   502         ].
   674 	].
   503 
   675 
   504         flags := onStream nextByte.
   676 	flags := onStream nextByte.
   505         (flags bitAnd:HEAD_RESERVED) ~~ 0 ifTrue:[
   677 	(flags bitAnd:HEAD_RESERVED) ~~ 0 ifTrue:[
   506             self zerror:'wrong data format'
   678 	    self zerror:'wrong data format'
   507         ].
   679 	].
   508 
   680 
   509         "discard time, xflags and OS code"
   681 	"discard time, xflags and OS code"
   510         onStream skip:6.
   682 	onStream skip:6.
   511 
   683 
   512         (flags bitAnd:HEAD_EXTRA_FIELD) ~~ 0 ifTrue:[|len|
   684 	(flags bitAnd:HEAD_EXTRA_FIELD) ~~ 0 ifTrue:[|len|
   513             "skip the extra field"
   685 	    "skip the extra field"
   514             len := onStream nextByte + (onStream nextByte bitShift:8).
   686 	    len := onStream nextByte + (onStream nextByte bitShift:8).
   515             len timesRepeat:[ onStream nextByte ].
   687 	    len timesRepeat:[ onStream nextByte ].
   516         ].
   688 	].
   517 
   689 
   518         (flags bitAnd:HEAD_ORIG_NAME) ~~ 0 ifTrue:[|b|
   690 	(flags bitAnd:HEAD_ORIG_NAME) ~~ 0 ifTrue:[|b|
   519             "skip the original file name"
   691 	    "skip the original file name"
   520             [ (b := onStream nextByte) ~~ 0 ] whileTrue.
   692 	    [ (b := onStream nextByte) ~~ 0 ] whileTrue.
   521         ].
   693 	].
   522 
   694 
   523         (flags bitAnd:HEAD_CRC) ~~ 0 ifTrue:[
   695 	(flags bitAnd:HEAD_CRC) ~~ 0 ifTrue:[
   524             "skip the header crc"
   696 	    "skip the header crc"
   525             onStream skip:2.
   697 	    onStream skip:2.
   526         ].
   698 	].
   527     ] ifFalse:[
   699     ] ifFalse:[
   528         "write the gzip magic id
   700 	"write the gzip magic id
   529         "
   701 	"
   530         GZ_MAGIC_ID do:[:b| onStream nextPutByte:b ].
   702 	GZ_MAGIC_ID do:[:b| onStream nextPutByte:b ].
   531 
   703 
   532         "write the method"
   704 	"write the method"
   533         onStream nextPutByte:Z_DEFLATED.
   705 	onStream nextPutByte:Z_DEFLATED.
   534 
   706 
   535         "write the flags"
   707 	"write the flags"
   536         onStream nextPutByte:0.
   708 	onStream nextPutByte:0.
   537 
   709 
   538         "write time"
   710 	"write time"
   539         4 timesRepeat:[ onStream nextPutByte:0 ].
   711 	4 timesRepeat:[ onStream nextPutByte:0 ].
   540 
   712 
   541         "write xflags"
   713 	"write xflags"
   542         onStream nextPutByte:0.
   714 	onStream nextPutByte:0.
   543 
   715 
   544         "write OS code"
   716 	"write OS code"
   545         onStream nextPutByte:HEAD_OS_CODE.
   717 	onStream nextPutByte:HEAD_OS_CODE.
   546     ].    
   718     ].
   547 ! !
   719 ! !
   548 
   720 
   549 !ZipStream class methodsFor:'documentation'!
   721 !ZipStream class methodsFor:'documentation'!
   550 
   722 
   551 version
   723 version
   552     ^ '$Header: /cvs/stx/stx/libbasic2/ZipStream.st,v 1.21 2003-08-29 19:31:33 cg Exp $'
   724     ^ '$Header: /cvs/stx/stx/libbasic2/ZipStream.st,v 1.22 2004-03-23 11:52:44 ab Exp $'
   553 ! !
   725 ! !
   554 
   726 
   555 ZipStream initialize!
   727 ZipStream initialize!