ZipArchive.st
branchjv
changeset 4213 739af6adeb3a
parent 4014 195df53729d3
parent 4200 089df8914384
child 4215 195c5c496e71
--- a/ZipArchive.st	Fri Nov 18 21:26:37 2016 +0000
+++ b/ZipArchive.st	Fri Nov 18 21:28:24 2016 +0000
@@ -16,8 +16,9 @@
 Object subclass:#ZipArchive
 	instanceVariableNames:'file mode archiveName firstEntry lastEntry centralDirectory
 		startOfArchive endOfArchive zipMembersByName appendTrailingSlash'
-	classVariableNames:'Lobby RecentlyUsedZipArchives FlushBlock ZipFileFormatErrorSignal
-		UnsupportedZipFileFormatErrorSignal DefaultAppendTrailingSlash'
+	classVariableNames:'RecentlyUsedZipArchives FlushBlock ZipFileFormatErrorSignal
+		UnsupportedZipFileFormatErrorSignal DefaultAppendTrailingSlash
+		ZipFileCachingTime'
 	poolDictionaries:'ZipArchiveConstants'
 	category:'System-Support-FileFormats'
 !
@@ -2969,6 +2970,14 @@
     DefaultAppendTrailingSlash := aBoolean
 
     "Created: / 19-11-2012 / 11:53:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+zipFileCachingTime:seconds
+    "by default, zip files are cached for some time, 
+     in case they are reconsulted soon.
+     The defualt time is 60s, but can be changed by this setter"
+     
+    ZipFileCachingTime := seconds
 ! !
 
 !ZipArchive class methodsFor:'class initialization'!
@@ -2984,10 +2993,6 @@
         UnsupportedZipFileFormatErrorSignal notifierString:'unsupported zip file format'.
     ].
 
-    Lobby isNil ifTrue:[
-        Lobby := Registry new.
-    ].
-
     DefaultAppendTrailingSlash := true.
 
     "
@@ -3019,7 +3024,7 @@
     FlushBlock isNil ifTrue:[
         FlushBlock := [RecentlyUsedZipArchives := nil. FlushBlock := nil].
     ].
-    Processor addTimedBlock:FlushBlock for:Processor timeoutHandlerProcess afterSeconds:60.
+    Processor addTimedBlock:FlushBlock for:Processor timeoutHandlerProcess afterSeconds:(ZipFileCachingTime ? 60).
 
     "
      self installFlushBlock
@@ -3253,33 +3258,22 @@
     ZipFileFormatErrorSignal raiseErrorString:anErrorString.
 ! !
 
-!ZipArchive methodsFor:'finalization'!
-
-finalizationLobby
-    "answer the registry used for finalization."
-    ^ Lobby
-!
-
-finalize
-    "some Stream has been collected - close the file if not already done"
-    self closeFile
-! !
-
 !ZipArchive methodsFor:'open & close'!
 
 close
-     self closeFile
+    file notNil ifTrue:[
+        self flush.
+        file close.
+        file := archiveName := centralDirectory := zipMembersByName := nil.
+        firstEntry := lastEntry := nil.
+    ].
 !
 
 flush
     "finish the zip archive, but do not close the underlying stream"
 
-    file notNil ifTrue:[
-        Lobby unregister:self.
-        mode == #write ifTrue: [
-            self addCentralZipDirectory
-        ].
-        file := nil.
+    (file notNil and:[mode == #write]) ifTrue: [
+        self addCentralZipDirectory
     ]
 !
 
@@ -3297,7 +3291,7 @@
     ].
 
     file notNil ifTrue: [
-        self closeFile.
+        self close.
     ].
 
     archiveName := filename name.
@@ -3323,7 +3317,7 @@
                 mode := #write.
             ].
         ] ensure:[
-            mustCloseFile ifTrue:[self closeFile].
+            mustCloseFile ifTrue:[self close].
         ].
     ] ifFalse:[
         zipMembersByName := Dictionary new.
@@ -3346,7 +3340,7 @@
 
     file notNil ifTrue: [
         file ~~ aPositionableStream ifTrue: [
-            self closeFile.
+            self close.
         ].
     ].
 
@@ -3380,7 +3374,7 @@
     "initialize the archive to write to aPositionableStream"
 
     file notNil ifTrue: [
-        self closeFile.
+        self close.
     ].
 
     mode := #write.
@@ -3397,15 +3391,12 @@
 !ZipArchive methodsFor:'private'!
 
 closeFile
-    "finish the zip archive and close the stream"
-
-    |savedFile|
-
-    file notNil ifTrue:[
-        savedFile := file.
-        self flush.
-        savedFile close.
-    ]
+    <resource: #obsolete>
+    "backward compatibility"
+
+    self obsoleteMethodWarning:'use #close'.
+
+    self close.
 !
 
 dataStartOf:zipEntry
@@ -3474,7 +3465,6 @@
             file := fn writeStream
         ].
         file binary.
-        Lobby register:self.
     ].
 
     "Modified: / 31-08-2010 / 12:40:41 / sr"
@@ -3746,7 +3736,7 @@
         "ignore duplicate entries for backward compatibility.
          Argh: expecco once added wrong duplicates to the end of ets files.
                The first entry is valid."
-        Logger info: 'Duplicate entry in ZIP (ignored): %1' with: zmemb fileName.
+        Logger warning:'duplicate entry in ZIP file ignored: %1' with:zmemb fileName.
     ] ifFalse:[
         zipMembersByName at:zmemb fileName put:zmemb.
     ].
@@ -3792,7 +3782,7 @@
     [
         isValidArchive := self checkZipArchive.
     ] ensure:[
-        self closeFile.
+        self close.
     ].
     ^ isValidArchive
 !
@@ -4000,7 +3990,6 @@
     ^ false.
 ! !
 
-
 !ZipArchive methodsFor:'reading'!
 
 extract:fileName
@@ -4110,7 +4099,6 @@
     "Created: / 21-11-2010 / 11:51:41 / cg"
 ! !
 
-
 !ZipArchive methodsFor:'reading - stream'!
 
 extract:fileName intoStream: aWriteStream
@@ -4136,7 +4124,7 @@
                     compressionMethod == COMPRESSION_DEFLATED ifTrue:[
                         myZipStream isNil ifTrue: [
                             file binary.
-                            myZipStream := ZipStream readOpenAsZipStreamOn: file.
+                            myZipStream := ZipStream readOpenAsZipStreamOn:file suppressHeaderAndChecksum:true.
                         ].
                         myZipStream next:nextBlockSize into:buffer startingAt:1.
                     ] ifFalse:[compressionMethod == COMPRESSION_STORED ifTrue:[
@@ -4273,7 +4261,6 @@
     theZipFileName := self validZipFileNameFrom:aFileName. 
 
     zipEntry fileName: theZipFileName.
-    zipEntry fileNameLength: theZipFileName size.
     zipEntry uncompressedSize: 0.
 
     isDirectory ifTrue: [
@@ -4308,7 +4295,7 @@
                 crc32 := ZipStream crc32BytesIn: buffer from:1 to:nextBlockSize crc:crc32.
                 theCompressMethod == COMPRESSION_DEFLATED ifTrue: [
                     myZipStream isNil ifTrue: [
-                        myZipStream := ZipStream writeOpenAsZipStreamOn:file.
+                        myZipStream := ZipStream writeOpenAsZipStreamOn:file suppressHeaderAndChecksum:true.
                     ].
                     myZipStream nextPutBytes:nextBlockSize from:buffer startingAt:1.
                 ] ifFalse: [theCompressMethod == COMPRESSION_STORED ifTrue: [
@@ -4326,7 +4313,7 @@
 
     zipEntry compressedSize:(file position) - startDataPosition.
 
-    "/ crc32 is allways reqired (not as written in docu to be zero in case of uncompressed mode)
+    "/ crc32 is always required (not as written in docu to be zero in case of uncompressed mode)
     zipEntry crc32:crc32.
     zipEntry uncompressedSize: unCompressedDataSize.
 
@@ -4373,26 +4360,23 @@
 basicAddFile:aFileName withContents:data compressMethod:theCompressMethodArg asDirectory:isDirectory 
     "do not create directories (isDirectory = true) - they are not compatible between operating systems"
     
-    | zipEntry  theCompressedData theZipFileName  theCompressMethod |
+    | zipEntry theCompressedData theZipFileName theCompressMethod  compressedDataOffset|
 
     (file isNil or:[ mode ~~ #write ]) ifTrue:[
         ^ self error:'ZipArchive not open for writing ...'.
     ].
     theCompressMethod := theCompressMethodArg.
-    ((theCompressMethod == COMPRESSION_DEFLATED) 
-        or:[ theCompressMethod == COMPRESSION_STORED ]) 
-            ifFalse:[
-                UnsupportedZipFileFormatErrorSignal 
-                    raiseRequestErrorString:'unsupported compressMethod'.
-                
-                "/ if proceeded, write as uncompressed
-                
-                theCompressMethod := COMPRESSION_STORED
-            ].
+    ((theCompressMethod ~~ COMPRESSION_DEFLATED) 
+      and:[theCompressMethod ~~ COMPRESSION_STORED]) ifTrue:[
+        UnsupportedZipFileFormatErrorSignal 
+            raiseRequestErrorString:'unsupported compressMethod'.
+        "/ if proceeded, write as uncompressed
+        theCompressMethod := COMPRESSION_STORED
+    ].
+
     zipEntry := ZipMember new default.
     theZipFileName := self validZipFileNameFrom:aFileName.
     zipEntry fileName:theZipFileName.
-    zipEntry fileNameLength:theZipFileName size.
 
     (self appendTrailingSlash and:[isDirectory]) ifTrue:[
         theZipFileName last == $/ ifFalse:[
@@ -4414,32 +4398,27 @@
     zipEntry setModificationTimeAndDateToNow.
 
     data notEmptyOrNil ifTrue:[
-        "/ crc32 is allways reqired (not as written in docu to be zero in case of uncompressed mode)
-        zipEntry crc32:(ZipStream crc32BytesIn:data).
+        "/ crc32 is always required (not as written in docu to be zero in case of uncompressed mode)
+        zipEntry crc32:(ZipStream crc32BytesIn:data from:1 to:data size crc:0).
     ].
     (isDirectory not and:[ theCompressMethod == COMPRESSION_DEFLATED ]) ifTrue:[
-        | tmpCompressedData  tmpCompressedDataSize |
-
-        tmpCompressedData := ByteArray new:(data size + 16).
-        tmpCompressedDataSize := ZipStream compress:data into:tmpCompressedData.
-        zipEntry compressedSize:(tmpCompressedDataSize - 6).
-        theCompressedData := tmpCompressedData copyFrom:3.
-    ] ifFalse:[
-        theCompressMethod == COMPRESSION_STORED ifTrue:[
-            zipEntry compressedSize:zipEntry uncompressedSize.
-            theCompressedData := data.
-        ] ifFalse:[
-            self error
-            "/ cannot happen
-        ].
+        |tmpCompressedDataSize|
+
+        theCompressedData := ByteArray new:(data size + 16).
+        tmpCompressedDataSize := ZipStream compress:data into:theCompressedData.
+        zipEntry compressedSize:tmpCompressedDataSize - 6.
+        compressedDataOffset := 3.
+    ] ifFalse:["theCompressMethod == COMPRESSION_STORED"
+        zipEntry compressedSize:zipEntry uncompressedSize.
+        theCompressedData := data.
+        compressedDataOffset := 1.
     ].
     
     "/ ensure that the file position is at the end
-    
     file setToEnd.
     zipEntry writeTo:file.
     theCompressedData notNil ifTrue:[
-        file nextPutBytes:zipEntry compressedSize from:theCompressedData.
+        file nextPutBytes:zipEntry compressedSize from:theCompressedData startingAt:compressedDataOffset.
     ].
     self addMember:zipEntry.
 
@@ -4470,7 +4449,7 @@
     theCompressMethod := theCompressMethodArg.
 
     ((theCompressMethod == COMPRESSION_DEFLATED) 
-    or:[ theCompressMethod == COMPRESSION_STORED ]) ifFalse:[
+     or:[theCompressMethod == COMPRESSION_STORED]) ifFalse:[
         UnsupportedZipFileFormatErrorSignal raiseRequestErrorString:'unsupported compressMethod'.
         "/ if proceeded, write as uncompressed
         theCompressMethod := COMPRESSION_STORED
@@ -4480,7 +4459,6 @@
     theZipFileName := self validZipFileNameFrom:nameOfFileInArchive. 
 
     zipEntry fileName: theZipFileName.
-    zipEntry fileNameLength: theZipFileName size.
     zipEntry uncompressedSize: 0.
 
     zipEntry compressionMethod: theCompressMethod.
@@ -4807,6 +4785,9 @@
 !
 
 fileNameLength
+    fileNameLength isNil ifTrue:[
+        ^ fileName size.
+    ].
     ^ fileNameLength
 !
 
@@ -4916,14 +4897,13 @@
     crc32 := 0.
     compressedSize := 0.
     uncompressedSize := 0.
-    fileNameLength := 0.
     extraFieldLength := 0.
     fileCommentLength := 0.
     diskNumberStart := 0.
     internalFileAttributes := 0.
     externalFileAttributes := 0.
     relativeLocalHeaderOffset := 0.
-    fileName := nil.
+    fileName := fileNameLength := nil.
     extraField := nil.
     fileComment := nil.
     dataStart := 0.
@@ -5023,7 +5003,7 @@
         nextPutInt32LSB:crc32;
         nextPutInt32LSB:compressedSize;
         nextPutInt32LSB:uncompressedSize;
-        nextPutInt16LSB:fileNameLength;
+        nextPutInt16LSB:self fileNameLength;
         nextPutInt16LSB:extraFieldLength;
         nextPutAll:fileName.
 
@@ -5053,7 +5033,7 @@
     readPosition := 0.
 
     zipEntry compressionMethod == COMPRESSION_DEFLATED ifTrue:[
-        compressingStream := ZipStream readOpenAsZipStreamOn:zipFileStream.
+        compressingStream := ZipStream readOpenAsZipStreamOn:zipFileStream suppressHeaderAndChecksum:true.
     ] ifFalse:[
         compressingStream := zipFileStream.
         compressingStream text.
@@ -5142,7 +5122,7 @@
 
     zipEntry compressedSize:(zipFileStream position) - startDataPosition.
 
-    "/ crc32 is allways reqired (not as written in docu to be zero in case of uncompressed mode)
+    "/ crc32 is always reqired (not as written in docu to be zero in case of uncompressed mode)
     zipEntry crc32:crc32.
     zipEntry uncompressedSize:uncompressedDataSize.
 
@@ -5162,7 +5142,7 @@
     uncompressedDataSize := 0.
 
     zipEntry compressionMethod == COMPRESSION_DEFLATED ifTrue:[
-        compressingStream := ZipStream writeOpenAsZipStreamOn:zipFileStream.
+        compressingStream := ZipStream writeOpenAsZipStreamOn:zipFileStream suppressHeaderAndChecksum:true.
     ] ifFalse:[
         compressingStream := zipFileStream.
     ].