ZipArchive.st
branchjv
changeset 4213 739af6adeb3a
parent 4014 195df53729d3
parent 4200 089df8914384
child 4215 195c5c496e71
equal deleted inserted replaced
4212:532eccd8b51b 4213:739af6adeb3a
    14 "{ NameSpace: Smalltalk }"
    14 "{ NameSpace: Smalltalk }"
    15 
    15 
    16 Object subclass:#ZipArchive
    16 Object subclass:#ZipArchive
    17 	instanceVariableNames:'file mode archiveName firstEntry lastEntry centralDirectory
    17 	instanceVariableNames:'file mode archiveName firstEntry lastEntry centralDirectory
    18 		startOfArchive endOfArchive zipMembersByName appendTrailingSlash'
    18 		startOfArchive endOfArchive zipMembersByName appendTrailingSlash'
    19 	classVariableNames:'Lobby RecentlyUsedZipArchives FlushBlock ZipFileFormatErrorSignal
    19 	classVariableNames:'RecentlyUsedZipArchives FlushBlock ZipFileFormatErrorSignal
    20 		UnsupportedZipFileFormatErrorSignal DefaultAppendTrailingSlash'
    20 		UnsupportedZipFileFormatErrorSignal DefaultAppendTrailingSlash
       
    21 		ZipFileCachingTime'
    21 	poolDictionaries:'ZipArchiveConstants'
    22 	poolDictionaries:'ZipArchiveConstants'
    22 	category:'System-Support-FileFormats'
    23 	category:'System-Support-FileFormats'
    23 !
    24 !
    24 
    25 
    25 PeekableStream subclass:#AbstractZipStream
    26 PeekableStream subclass:#AbstractZipStream
  2967     "Sets the default trailing slash behavior, For details,
  2968     "Sets the default trailing slash behavior, For details,
  2968      see class documentation"
  2969      see class documentation"
  2969     DefaultAppendTrailingSlash := aBoolean
  2970     DefaultAppendTrailingSlash := aBoolean
  2970 
  2971 
  2971     "Created: / 19-11-2012 / 11:53:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2972     "Created: / 19-11-2012 / 11:53:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
  2973 !
       
  2974 
       
  2975 zipFileCachingTime:seconds
       
  2976     "by default, zip files are cached for some time, 
       
  2977      in case they are reconsulted soon.
       
  2978      The defualt time is 60s, but can be changed by this setter"
       
  2979      
       
  2980     ZipFileCachingTime := seconds
  2972 ! !
  2981 ! !
  2973 
  2982 
  2974 !ZipArchive class methodsFor:'class initialization'!
  2983 !ZipArchive class methodsFor:'class initialization'!
  2975 
  2984 
  2976 initialize
  2985 initialize
  2982         UnsupportedZipFileFormatErrorSignal := ZipFileFormatErrorSignal newSignal.
  2991         UnsupportedZipFileFormatErrorSignal := ZipFileFormatErrorSignal newSignal.
  2983         UnsupportedZipFileFormatErrorSignal nameClass:self message:#unsupportedZipFileFormatErrorSignal.
  2992         UnsupportedZipFileFormatErrorSignal nameClass:self message:#unsupportedZipFileFormatErrorSignal.
  2984         UnsupportedZipFileFormatErrorSignal notifierString:'unsupported zip file format'.
  2993         UnsupportedZipFileFormatErrorSignal notifierString:'unsupported zip file format'.
  2985     ].
  2994     ].
  2986 
  2995 
  2987     Lobby isNil ifTrue:[
       
  2988         Lobby := Registry new.
       
  2989     ].
       
  2990 
       
  2991     DefaultAppendTrailingSlash := true.
  2996     DefaultAppendTrailingSlash := true.
  2992 
  2997 
  2993     "
  2998     "
  2994      self initialize
  2999      self initialize
  2995     "
  3000     "
  3017     "forget about cached zipArchives"
  3022     "forget about cached zipArchives"
  3018 
  3023 
  3019     FlushBlock isNil ifTrue:[
  3024     FlushBlock isNil ifTrue:[
  3020         FlushBlock := [RecentlyUsedZipArchives := nil. FlushBlock := nil].
  3025         FlushBlock := [RecentlyUsedZipArchives := nil. FlushBlock := nil].
  3021     ].
  3026     ].
  3022     Processor addTimedBlock:FlushBlock for:Processor timeoutHandlerProcess afterSeconds:60.
  3027     Processor addTimedBlock:FlushBlock for:Processor timeoutHandlerProcess afterSeconds:(ZipFileCachingTime ? 60).
  3023 
  3028 
  3024     "
  3029     "
  3025      self installFlushBlock
  3030      self installFlushBlock
  3026     "
  3031     "
  3027 
  3032 
  3251     "redefined, to raise ZipFileFormatErrorSignal"
  3256     "redefined, to raise ZipFileFormatErrorSignal"
  3252 
  3257 
  3253     ZipFileFormatErrorSignal raiseErrorString:anErrorString.
  3258     ZipFileFormatErrorSignal raiseErrorString:anErrorString.
  3254 ! !
  3259 ! !
  3255 
  3260 
  3256 !ZipArchive methodsFor:'finalization'!
       
  3257 
       
  3258 finalizationLobby
       
  3259     "answer the registry used for finalization."
       
  3260     ^ Lobby
       
  3261 !
       
  3262 
       
  3263 finalize
       
  3264     "some Stream has been collected - close the file if not already done"
       
  3265     self closeFile
       
  3266 ! !
       
  3267 
       
  3268 !ZipArchive methodsFor:'open & close'!
  3261 !ZipArchive methodsFor:'open & close'!
  3269 
  3262 
  3270 close
  3263 close
  3271      self closeFile
  3264     file notNil ifTrue:[
       
  3265         self flush.
       
  3266         file close.
       
  3267         file := archiveName := centralDirectory := zipMembersByName := nil.
       
  3268         firstEntry := lastEntry := nil.
       
  3269     ].
  3272 !
  3270 !
  3273 
  3271 
  3274 flush
  3272 flush
  3275     "finish the zip archive, but do not close the underlying stream"
  3273     "finish the zip archive, but do not close the underlying stream"
  3276 
  3274 
  3277     file notNil ifTrue:[
  3275     (file notNil and:[mode == #write]) ifTrue: [
  3278         Lobby unregister:self.
  3276         self addCentralZipDirectory
  3279         mode == #write ifTrue: [
       
  3280             self addCentralZipDirectory
       
  3281         ].
       
  3282         file := nil.
       
  3283     ]
  3277     ]
  3284 !
  3278 !
  3285 
  3279 
  3286 name:name mode:readOrWriteMode
  3280 name:name mode:readOrWriteMode
  3287     "open read or writestream on archiveFileName"
  3281     "open read or writestream on archiveFileName"
  3295     filename isDirectory ifTrue:[
  3289     filename isDirectory ifTrue:[
  3296         ^ OpenError raiseRequestWith:filename errorString:' - file is a directory'.
  3290         ^ OpenError raiseRequestWith:filename errorString:' - file is a directory'.
  3297     ].
  3291     ].
  3298 
  3292 
  3299     file notNil ifTrue: [
  3293     file notNil ifTrue: [
  3300         self closeFile.
  3294         self close.
  3301     ].
  3295     ].
  3302 
  3296 
  3303     archiveName := filename name.
  3297     archiveName := filename name.
  3304     mode := readOrWriteMode.
  3298     mode := readOrWriteMode.
  3305 
  3299 
  3321 
  3315 
  3322                 file position:(startOfArchive + lastMember dataStart + lastMember compressedSize).
  3316                 file position:(startOfArchive + lastMember dataStart + lastMember compressedSize).
  3323                 mode := #write.
  3317                 mode := #write.
  3324             ].
  3318             ].
  3325         ] ensure:[
  3319         ] ensure:[
  3326             mustCloseFile ifTrue:[self closeFile].
  3320             mustCloseFile ifTrue:[self close].
  3327         ].
  3321         ].
  3328     ] ifFalse:[
  3322     ] ifFalse:[
  3329         zipMembersByName := Dictionary new.
  3323         zipMembersByName := Dictionary new.
  3330     ].
  3324     ].
  3331 
  3325 
  3344 readingFrom:aPositionableStream
  3338 readingFrom:aPositionableStream
  3345     "initialize the archive to read from aPositionableStream"
  3339     "initialize the archive to read from aPositionableStream"
  3346 
  3340 
  3347     file notNil ifTrue: [
  3341     file notNil ifTrue: [
  3348         file ~~ aPositionableStream ifTrue: [
  3342         file ~~ aPositionableStream ifTrue: [
  3349             self closeFile.
  3343             self close.
  3350         ].
  3344         ].
  3351     ].
  3345     ].
  3352 
  3346 
  3353     mode := #read.
  3347     mode := #read.
  3354     aPositionableStream binary.
  3348     aPositionableStream binary.
  3378 
  3372 
  3379 writingTo:aPositionableStream
  3373 writingTo:aPositionableStream
  3380     "initialize the archive to write to aPositionableStream"
  3374     "initialize the archive to write to aPositionableStream"
  3381 
  3375 
  3382     file notNil ifTrue: [
  3376     file notNil ifTrue: [
  3383         self closeFile.
  3377         self close.
  3384     ].
  3378     ].
  3385 
  3379 
  3386     mode := #write.
  3380     mode := #write.
  3387     aPositionableStream binary.
  3381     aPositionableStream binary.
  3388     file := aPositionableStream.
  3382     file := aPositionableStream.
  3395 ! !
  3389 ! !
  3396 
  3390 
  3397 !ZipArchive methodsFor:'private'!
  3391 !ZipArchive methodsFor:'private'!
  3398 
  3392 
  3399 closeFile
  3393 closeFile
  3400     "finish the zip archive and close the stream"
  3394     <resource: #obsolete>
  3401 
  3395     "backward compatibility"
  3402     |savedFile|
  3396 
  3403 
  3397     self obsoleteMethodWarning:'use #close'.
  3404     file notNil ifTrue:[
  3398 
  3405         savedFile := file.
  3399     self close.
  3406         self flush.
       
  3407         savedFile close.
       
  3408     ]
       
  3409 !
  3400 !
  3410 
  3401 
  3411 dataStartOf:zipEntry
  3402 dataStartOf:zipEntry
  3412     "fetch the absolute start address of the data of a given zipEntry.
  3403     "fetch the absolute start address of the data of a given zipEntry.
  3413      Note: extra field and extra field length may be different from that in
  3404      Note: extra field and extra field length may be different from that in
  3472             ].
  3463             ].
  3473         ] ifFalse:[
  3464         ] ifFalse:[
  3474             file := fn writeStream
  3465             file := fn writeStream
  3475         ].
  3466         ].
  3476         file binary.
  3467         file binary.
  3477         Lobby register:self.
       
  3478     ].
  3468     ].
  3479 
  3469 
  3480     "Modified: / 31-08-2010 / 12:40:41 / sr"
  3470     "Modified: / 31-08-2010 / 12:40:41 / sr"
  3481 !
  3471 !
  3482 
  3472 
  3744     lastEntry := zmemb.
  3734     lastEntry := zmemb.
  3745     (zipMembersByName includesKey:zmemb fileName) ifTrue:[
  3735     (zipMembersByName includesKey:zmemb fileName) ifTrue:[
  3746         "ignore duplicate entries for backward compatibility.
  3736         "ignore duplicate entries for backward compatibility.
  3747          Argh: expecco once added wrong duplicates to the end of ets files.
  3737          Argh: expecco once added wrong duplicates to the end of ets files.
  3748                The first entry is valid."
  3738                The first entry is valid."
  3749         Logger info: 'Duplicate entry in ZIP (ignored): %1' with: zmemb fileName.
  3739         Logger warning:'duplicate entry in ZIP file ignored: %1' with:zmemb fileName.
  3750     ] ifFalse:[
  3740     ] ifFalse:[
  3751         zipMembersByName at:zmemb fileName put:zmemb.
  3741         zipMembersByName at:zmemb fileName put:zmemb.
  3752     ].
  3742     ].
  3753     ^ zmemb.
  3743     ^ zmemb.
  3754 
  3744 
  3790     self openFile.
  3780     self openFile.
  3791 
  3781 
  3792     [
  3782     [
  3793         isValidArchive := self checkZipArchive.
  3783         isValidArchive := self checkZipArchive.
  3794     ] ensure:[
  3784     ] ensure:[
  3795         self closeFile.
  3785         self close.
  3796     ].
  3786     ].
  3797     ^ isValidArchive
  3787     ^ isValidArchive
  3798 !
  3788 !
  3799 
  3789 
  3800 findMember:name
  3790 findMember:name
  3997              or:[eachMemberName = anArchivePathName]) ifTrue:[^ true]
  3987              or:[eachMemberName = anArchivePathName]) ifTrue:[^ true]
  3998         ].
  3988         ].
  3999 
  3989 
  4000     ^ false.
  3990     ^ false.
  4001 ! !
  3991 ! !
  4002 
       
  4003 
  3992 
  4004 !ZipArchive methodsFor:'reading'!
  3993 !ZipArchive methodsFor:'reading'!
  4005 
  3994 
  4006 extract:fileName
  3995 extract:fileName
  4007     "extract an entry identified by fileName as a byteArray;
  3996     "extract an entry identified by fileName as a byteArray;
  4108     aBlock value:zmemb value:dataStart.
  4097     aBlock value:zmemb value:dataStart.
  4109 
  4098 
  4110     "Created: / 21-11-2010 / 11:51:41 / cg"
  4099     "Created: / 21-11-2010 / 11:51:41 / cg"
  4111 ! !
  4100 ! !
  4112 
  4101 
  4113 
       
  4114 !ZipArchive methodsFor:'reading - stream'!
  4102 !ZipArchive methodsFor:'reading - stream'!
  4115 
  4103 
  4116 extract:fileName intoStream: aWriteStream
  4104 extract:fileName intoStream: aWriteStream
  4117     "extract an entry indentified by filename into aWriteStream"
  4105     "extract an entry indentified by filename into aWriteStream"
  4118 
  4106 
  4134                     ].
  4122                     ].
  4135 
  4123 
  4136                     compressionMethod == COMPRESSION_DEFLATED ifTrue:[
  4124                     compressionMethod == COMPRESSION_DEFLATED ifTrue:[
  4137                         myZipStream isNil ifTrue: [
  4125                         myZipStream isNil ifTrue: [
  4138                             file binary.
  4126                             file binary.
  4139                             myZipStream := ZipStream readOpenAsZipStreamOn: file.
  4127                             myZipStream := ZipStream readOpenAsZipStreamOn:file suppressHeaderAndChecksum:true.
  4140                         ].
  4128                         ].
  4141                         myZipStream next:nextBlockSize into:buffer startingAt:1.
  4129                         myZipStream next:nextBlockSize into:buffer startingAt:1.
  4142                     ] ifFalse:[compressionMethod == COMPRESSION_STORED ifTrue:[
  4130                     ] ifFalse:[compressionMethod == COMPRESSION_STORED ifTrue:[
  4143                         file nextBytes:nextBlockSize into:buffer startingAt:1.
  4131                         file nextBytes:nextBlockSize into:buffer startingAt:1.
  4144                     ] ifFalse:[
  4132                     ] ifFalse:[
  4271 
  4259 
  4272     zipEntry := ZipMember new default.
  4260     zipEntry := ZipMember new default.
  4273     theZipFileName := self validZipFileNameFrom:aFileName. 
  4261     theZipFileName := self validZipFileNameFrom:aFileName. 
  4274 
  4262 
  4275     zipEntry fileName: theZipFileName.
  4263     zipEntry fileName: theZipFileName.
  4276     zipEntry fileNameLength: theZipFileName size.
       
  4277     zipEntry uncompressedSize: 0.
  4264     zipEntry uncompressedSize: 0.
  4278 
  4265 
  4279     isDirectory ifTrue: [
  4266     isDirectory ifTrue: [
  4280         theCompressMethod := COMPRESSION_STORED.
  4267         theCompressMethod := COMPRESSION_STORED.
  4281         zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISDIRECTORY.
  4268         zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISDIRECTORY.
  4306             nextBlockSize > 0 ifTrue: [
  4293             nextBlockSize > 0 ifTrue: [
  4307                 unCompressedDataSize := unCompressedDataSize + nextBlockSize.
  4294                 unCompressedDataSize := unCompressedDataSize + nextBlockSize.
  4308                 crc32 := ZipStream crc32BytesIn: buffer from:1 to:nextBlockSize crc:crc32.
  4295                 crc32 := ZipStream crc32BytesIn: buffer from:1 to:nextBlockSize crc:crc32.
  4309                 theCompressMethod == COMPRESSION_DEFLATED ifTrue: [
  4296                 theCompressMethod == COMPRESSION_DEFLATED ifTrue: [
  4310                     myZipStream isNil ifTrue: [
  4297                     myZipStream isNil ifTrue: [
  4311                         myZipStream := ZipStream writeOpenAsZipStreamOn:file.
  4298                         myZipStream := ZipStream writeOpenAsZipStreamOn:file suppressHeaderAndChecksum:true.
  4312                     ].
  4299                     ].
  4313                     myZipStream nextPutBytes:nextBlockSize from:buffer startingAt:1.
  4300                     myZipStream nextPutBytes:nextBlockSize from:buffer startingAt:1.
  4314                 ] ifFalse: [theCompressMethod == COMPRESSION_STORED ifTrue: [
  4301                 ] ifFalse: [theCompressMethod == COMPRESSION_STORED ifTrue: [
  4315                     file nextPutBytes:nextBlockSize from:buffer startingAt:1.
  4302                     file nextPutBytes:nextBlockSize from:buffer startingAt:1.
  4316                 ] ifFalse:[
  4303                 ] ifFalse:[
  4324         ].
  4311         ].
  4325     ].
  4312     ].
  4326 
  4313 
  4327     zipEntry compressedSize:(file position) - startDataPosition.
  4314     zipEntry compressedSize:(file position) - startDataPosition.
  4328 
  4315 
  4329     "/ crc32 is allways reqired (not as written in docu to be zero in case of uncompressed mode)
  4316     "/ crc32 is always required (not as written in docu to be zero in case of uncompressed mode)
  4330     zipEntry crc32:crc32.
  4317     zipEntry crc32:crc32.
  4331     zipEntry uncompressedSize: unCompressedDataSize.
  4318     zipEntry uncompressedSize: unCompressedDataSize.
  4332 
  4319 
  4333     zipEntry rewriteCrcAndSizeTo:file.
  4320     zipEntry rewriteCrcAndSizeTo:file.
  4334     self addMember:zipEntry.
  4321     self addMember:zipEntry.
  4371 !
  4358 !
  4372 
  4359 
  4373 basicAddFile:aFileName withContents:data compressMethod:theCompressMethodArg asDirectory:isDirectory 
  4360 basicAddFile:aFileName withContents:data compressMethod:theCompressMethodArg asDirectory:isDirectory 
  4374     "do not create directories (isDirectory = true) - they are not compatible between operating systems"
  4361     "do not create directories (isDirectory = true) - they are not compatible between operating systems"
  4375     
  4362     
  4376     | zipEntry  theCompressedData theZipFileName  theCompressMethod |
  4363     | zipEntry theCompressedData theZipFileName theCompressMethod  compressedDataOffset|
  4377 
  4364 
  4378     (file isNil or:[ mode ~~ #write ]) ifTrue:[
  4365     (file isNil or:[ mode ~~ #write ]) ifTrue:[
  4379         ^ self error:'ZipArchive not open for writing ...'.
  4366         ^ self error:'ZipArchive not open for writing ...'.
  4380     ].
  4367     ].
  4381     theCompressMethod := theCompressMethodArg.
  4368     theCompressMethod := theCompressMethodArg.
  4382     ((theCompressMethod == COMPRESSION_DEFLATED) 
  4369     ((theCompressMethod ~~ COMPRESSION_DEFLATED) 
  4383         or:[ theCompressMethod == COMPRESSION_STORED ]) 
  4370       and:[theCompressMethod ~~ COMPRESSION_STORED]) ifTrue:[
  4384             ifFalse:[
  4371         UnsupportedZipFileFormatErrorSignal 
  4385                 UnsupportedZipFileFormatErrorSignal 
  4372             raiseRequestErrorString:'unsupported compressMethod'.
  4386                     raiseRequestErrorString:'unsupported compressMethod'.
  4373         "/ if proceeded, write as uncompressed
  4387                 
  4374         theCompressMethod := COMPRESSION_STORED
  4388                 "/ if proceeded, write as uncompressed
  4375     ].
  4389                 
  4376 
  4390                 theCompressMethod := COMPRESSION_STORED
       
  4391             ].
       
  4392     zipEntry := ZipMember new default.
  4377     zipEntry := ZipMember new default.
  4393     theZipFileName := self validZipFileNameFrom:aFileName.
  4378     theZipFileName := self validZipFileNameFrom:aFileName.
  4394     zipEntry fileName:theZipFileName.
  4379     zipEntry fileName:theZipFileName.
  4395     zipEntry fileNameLength:theZipFileName size.
       
  4396 
  4380 
  4397     (self appendTrailingSlash and:[isDirectory]) ifTrue:[
  4381     (self appendTrailingSlash and:[isDirectory]) ifTrue:[
  4398         theZipFileName last == $/ ifFalse:[
  4382         theZipFileName last == $/ ifFalse:[
  4399             zipEntry fileName:theZipFileName , $/.
  4383             zipEntry fileName:theZipFileName , $/.
  4400             zipEntry fileNameLength:theZipFileName size + 1.
  4384             zipEntry fileNameLength:theZipFileName size + 1.
  4412     
  4396     
  4413     "/ data and time in msdos format
  4397     "/ data and time in msdos format
  4414     zipEntry setModificationTimeAndDateToNow.
  4398     zipEntry setModificationTimeAndDateToNow.
  4415 
  4399 
  4416     data notEmptyOrNil ifTrue:[
  4400     data notEmptyOrNil ifTrue:[
  4417         "/ crc32 is allways reqired (not as written in docu to be zero in case of uncompressed mode)
  4401         "/ crc32 is always required (not as written in docu to be zero in case of uncompressed mode)
  4418         zipEntry crc32:(ZipStream crc32BytesIn:data).
  4402         zipEntry crc32:(ZipStream crc32BytesIn:data from:1 to:data size crc:0).
  4419     ].
  4403     ].
  4420     (isDirectory not and:[ theCompressMethod == COMPRESSION_DEFLATED ]) ifTrue:[
  4404     (isDirectory not and:[ theCompressMethod == COMPRESSION_DEFLATED ]) ifTrue:[
  4421         | tmpCompressedData  tmpCompressedDataSize |
  4405         |tmpCompressedDataSize|
  4422 
  4406 
  4423         tmpCompressedData := ByteArray new:(data size + 16).
  4407         theCompressedData := ByteArray new:(data size + 16).
  4424         tmpCompressedDataSize := ZipStream compress:data into:tmpCompressedData.
  4408         tmpCompressedDataSize := ZipStream compress:data into:theCompressedData.
  4425         zipEntry compressedSize:(tmpCompressedDataSize - 6).
  4409         zipEntry compressedSize:tmpCompressedDataSize - 6.
  4426         theCompressedData := tmpCompressedData copyFrom:3.
  4410         compressedDataOffset := 3.
  4427     ] ifFalse:[
  4411     ] ifFalse:["theCompressMethod == COMPRESSION_STORED"
  4428         theCompressMethod == COMPRESSION_STORED ifTrue:[
  4412         zipEntry compressedSize:zipEntry uncompressedSize.
  4429             zipEntry compressedSize:zipEntry uncompressedSize.
  4413         theCompressedData := data.
  4430             theCompressedData := data.
  4414         compressedDataOffset := 1.
  4431         ] ifFalse:[
       
  4432             self error
       
  4433             "/ cannot happen
       
  4434         ].
       
  4435     ].
  4415     ].
  4436     
  4416     
  4437     "/ ensure that the file position is at the end
  4417     "/ ensure that the file position is at the end
  4438     
       
  4439     file setToEnd.
  4418     file setToEnd.
  4440     zipEntry writeTo:file.
  4419     zipEntry writeTo:file.
  4441     theCompressedData notNil ifTrue:[
  4420     theCompressedData notNil ifTrue:[
  4442         file nextPutBytes:zipEntry compressedSize from:theCompressedData.
  4421         file nextPutBytes:zipEntry compressedSize from:theCompressedData startingAt:compressedDataOffset.
  4443     ].
  4422     ].
  4444     self addMember:zipEntry.
  4423     self addMember:zipEntry.
  4445 
  4424 
  4446     "Created: / 18-11-2010 / 19:31:10 / cg"
  4425     "Created: / 18-11-2010 / 19:31:10 / cg"
  4447     "Modified: / 19-11-2010 / 17:47:01 / cg"
  4426     "Modified: / 19-11-2010 / 17:47:01 / cg"
  4468     ].
  4447     ].
  4469 
  4448 
  4470     theCompressMethod := theCompressMethodArg.
  4449     theCompressMethod := theCompressMethodArg.
  4471 
  4450 
  4472     ((theCompressMethod == COMPRESSION_DEFLATED) 
  4451     ((theCompressMethod == COMPRESSION_DEFLATED) 
  4473     or:[ theCompressMethod == COMPRESSION_STORED ]) ifFalse:[
  4452      or:[theCompressMethod == COMPRESSION_STORED]) ifFalse:[
  4474         UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
  4453         UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
  4475         "/ if proceeded, write as uncompressed
  4454         "/ if proceeded, write as uncompressed
  4476         theCompressMethod := COMPRESSION_STORED
  4455         theCompressMethod := COMPRESSION_STORED
  4477     ].
  4456     ].
  4478 
  4457 
  4479     zipEntry := ZipMember new default.
  4458     zipEntry := ZipMember new default.
  4480     theZipFileName := self validZipFileNameFrom:nameOfFileInArchive. 
  4459     theZipFileName := self validZipFileNameFrom:nameOfFileInArchive. 
  4481 
  4460 
  4482     zipEntry fileName: theZipFileName.
  4461     zipEntry fileName: theZipFileName.
  4483     zipEntry fileNameLength: theZipFileName size.
       
  4484     zipEntry uncompressedSize: 0.
  4462     zipEntry uncompressedSize: 0.
  4485 
  4463 
  4486     zipEntry compressionMethod: theCompressMethod.
  4464     zipEntry compressionMethod: theCompressMethod.
  4487     zipEntry internalFileAttributes: 1.
  4465     zipEntry internalFileAttributes: 1.
  4488     zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISFILE.
  4466     zipEntry externalFileAttributes: EXTERNALFILEATTRIBUTES_ISFILE.
  4805 fileName:something
  4783 fileName:something
  4806     fileName := something.
  4784     fileName := something.
  4807 !
  4785 !
  4808 
  4786 
  4809 fileNameLength
  4787 fileNameLength
       
  4788     fileNameLength isNil ifTrue:[
       
  4789         ^ fileName size.
       
  4790     ].
  4810     ^ fileNameLength
  4791     ^ fileNameLength
  4811 !
  4792 !
  4812 
  4793 
  4813 fileNameLength:something
  4794 fileNameLength:something
  4814     fileNameLength := something.
  4795     fileNameLength := something.
  4914     lastModFileTime := 0.
  4895     lastModFileTime := 0.
  4915     lastModFileDate := 0.
  4896     lastModFileDate := 0.
  4916     crc32 := 0.
  4897     crc32 := 0.
  4917     compressedSize := 0.
  4898     compressedSize := 0.
  4918     uncompressedSize := 0.
  4899     uncompressedSize := 0.
  4919     fileNameLength := 0.
       
  4920     extraFieldLength := 0.
  4900     extraFieldLength := 0.
  4921     fileCommentLength := 0.
  4901     fileCommentLength := 0.
  4922     diskNumberStart := 0.
  4902     diskNumberStart := 0.
  4923     internalFileAttributes := 0.
  4903     internalFileAttributes := 0.
  4924     externalFileAttributes := 0.
  4904     externalFileAttributes := 0.
  4925     relativeLocalHeaderOffset := 0.
  4905     relativeLocalHeaderOffset := 0.
  4926     fileName := nil.
  4906     fileName := fileNameLength := nil.
  4927     extraField := nil.
  4907     extraField := nil.
  4928     fileComment := nil.
  4908     fileComment := nil.
  4929     dataStart := 0.
  4909     dataStart := 0.
  4930     data := nil.
  4910     data := nil.
  4931 ! !
  4911 ! !
  5021         nextPutInt16LSB:lastModFileTime;
  5001         nextPutInt16LSB:lastModFileTime;
  5022         nextPutInt16LSB:lastModFileDate;
  5002         nextPutInt16LSB:lastModFileDate;
  5023         nextPutInt32LSB:crc32;
  5003         nextPutInt32LSB:crc32;
  5024         nextPutInt32LSB:compressedSize;
  5004         nextPutInt32LSB:compressedSize;
  5025         nextPutInt32LSB:uncompressedSize;
  5005         nextPutInt32LSB:uncompressedSize;
  5026         nextPutInt16LSB:fileNameLength;
  5006         nextPutInt16LSB:self fileNameLength;
  5027         nextPutInt16LSB:extraFieldLength;
  5007         nextPutInt16LSB:extraFieldLength;
  5028         nextPutAll:fileName.
  5008         nextPutAll:fileName.
  5029 
  5009 
  5030     extraField notNil ifTrue: [
  5010     extraField notNil ifTrue: [
  5031         self assert:(extraField size = extraFieldLength).
  5011         self assert:(extraField size = extraFieldLength).
  5051     crc32 := 0.
  5031     crc32 := 0.
  5052     uncompressedDataSize := zipEntry uncompressedSize.
  5032     uncompressedDataSize := zipEntry uncompressedSize.
  5053     readPosition := 0.
  5033     readPosition := 0.
  5054 
  5034 
  5055     zipEntry compressionMethod == COMPRESSION_DEFLATED ifTrue:[
  5035     zipEntry compressionMethod == COMPRESSION_DEFLATED ifTrue:[
  5056         compressingStream := ZipStream readOpenAsZipStreamOn:zipFileStream.
  5036         compressingStream := ZipStream readOpenAsZipStreamOn:zipFileStream suppressHeaderAndChecksum:true.
  5057     ] ifFalse:[
  5037     ] ifFalse:[
  5058         compressingStream := zipFileStream.
  5038         compressingStream := zipFileStream.
  5059         compressingStream text.
  5039         compressingStream text.
  5060     ].
  5040     ].
  5061 
  5041 
  5140     ].
  5120     ].
  5141     compressingStream := nil.
  5121     compressingStream := nil.
  5142 
  5122 
  5143     zipEntry compressedSize:(zipFileStream position) - startDataPosition.
  5123     zipEntry compressedSize:(zipFileStream position) - startDataPosition.
  5144 
  5124 
  5145     "/ crc32 is allways reqired (not as written in docu to be zero in case of uncompressed mode)
  5125     "/ crc32 is always reqired (not as written in docu to be zero in case of uncompressed mode)
  5146     zipEntry crc32:crc32.
  5126     zipEntry crc32:crc32.
  5147     zipEntry uncompressedSize:uncompressedDataSize.
  5127     zipEntry uncompressedSize:uncompressedDataSize.
  5148 
  5128 
  5149     zipEntry rewriteCrcAndSizeTo:zipFileStream.
  5129     zipEntry rewriteCrcAndSizeTo:zipFileStream.
  5150 
  5130 
  5160     startDataPosition := zipFileStream position.
  5140     startDataPosition := zipFileStream position.
  5161     crc32 := 0.
  5141     crc32 := 0.
  5162     uncompressedDataSize := 0.
  5142     uncompressedDataSize := 0.
  5163 
  5143 
  5164     zipEntry compressionMethod == COMPRESSION_DEFLATED ifTrue:[
  5144     zipEntry compressionMethod == COMPRESSION_DEFLATED ifTrue:[
  5165         compressingStream := ZipStream writeOpenAsZipStreamOn:zipFileStream.
  5145         compressingStream := ZipStream writeOpenAsZipStreamOn:zipFileStream suppressHeaderAndChecksum:true.
  5166     ] ifFalse:[
  5146     ] ifFalse:[
  5167         compressingStream := zipFileStream.
  5147         compressingStream := zipFileStream.
  5168     ].
  5148     ].
  5169 
  5149 
  5170     "Modified: / 19-11-2010 / 15:46:57 / cg"
  5150     "Modified: / 19-11-2010 / 15:46:57 / cg"