ZipArchive.st
changeset 2003 051486962c69
parent 1995 93f2f08bceb3
child 2007 6659fd3bbfab
--- a/ZipArchive.st	Fri May 30 11:19:16 2008 +0200
+++ b/ZipArchive.st	Tue Jun 03 17:08:52 2008 +0200
@@ -1294,6 +1294,45 @@
 "
 !
 
+examples3
+"
+    add to new zip archive a entry which is located in memory using selector
+        addFile:'crcTest_resume_compressed.txt' withContents:
+    and real file contents from disk identified by a readStream using selector
+        addFile:rdStreamFile fromStream:
+                                                        [exBegin]
+    |zipwr testDirectory testFileWr zipDirectory |
+
+    testDirectory := 'C:\Dokumente und Einstellungen\stefan\Eigene Dateien\tmp\'.
+    testFileWr := 'zipDirectoryTest.zip'.
+    zipDirectory := 'abc'.
+
+    zipwr := ZipArchive newFileNamed:(testDirectory, testFileWr).
+
+    zipwr addArchiveDirectory: 'attachments' fromOsDirectory: (testDirectory,zipDirectory).
+
+    zipwr closeFile.
+                                                        [exEnd]
+
+    read from zip archive a entry which into memory using selector
+        extract:'crcTest_resume_compressed.txt'
+    and store real file contents from disk using a readStream on archive contents entry
+        readStreamFor: rdStreamFile 
+                                                        [exBegin]
+    |ziprd testDirectory testFileRd zipDirectory|
+
+    testDirectory := 'C:\Dokumente und Einstellungen\stefan\Eigene Dateien\tmp\'.
+    testFileRd := 'zipDirectoryTest.zip'.
+    zipDirectory := 'xxx'.
+
+    ziprd := ZipArchive oldFileNamed:(testDirectory, testFileRd).
+    ziprd restoreOsDirectory: (testDirectory,zipDirectory) fromArchiveDirectory: 'attachments'.
+    ziprd closeFile.
+                                                        [exEnd]
+
+"
+!
+
 fileFormatDescription
 
 "/File:    APPNOTE.TXT - .ZIP File Format Specification
@@ -3778,13 +3817,32 @@
                  endOfArchive:(zmemb fileStart + startOfArchive + (zmemb compressedSize)).
 !
 
-restoreContentsFromZipDirectory:zipDirectoryName intoDirectory:intoDirectory
-    "restore the contents of a file or directory (recursive) from zip archive -> zipDirectoryName 
-     into directory -> intoDirectory"
-    intoDirectory exists ifFalse: [
-        ^ false
+restoreOsDirectory:osDirectoryName fromArchiveDirectory: archiveDirectoryName
+    |osDirectory fileNameOrDirectoryEntry|
+    osDirectory := osDirectoryName asFilename.
+    (osDirectory exists and: [osDirectory isDirectory not]) ifTrue:[
+        ^ self
+    ].
+
+    osDirectory exists ifFalse:[
+        osDirectory recursiveMakeDirectory
     ].
-    ^ true
+
+    self members do: [:aMember|
+        (aMember fileName startsWith: archiveDirectoryName) ifTrue: [
+            fileNameOrDirectoryEntry := osDirectory construct: (aMember fileName copyFrom: (archiveDirectoryName size +1)).
+            fileNameOrDirectoryEntry notEmptyOrNil ifTrue: [
+                aMember compressedSize == 0 ifTrue: [
+                    fileNameOrDirectoryEntry recursiveMakeDirectory.
+                ] ifFalse: [
+                    fileNameOrDirectoryEntry writingFileDo: [:aStream|
+                        self extract: aMember fileName 
+                          intoStream: aStream.
+                    ].
+                ].
+            ].
+        ]
+    ].
 ! !
 
 !ZipArchive methodsFor:'reading - stream'!
@@ -3816,23 +3874,43 @@
 "/    ^ zs
 ! !
 
-!ZipArchive methodsFor:'writing'!
-
-addContentsFromFileOrDirectory:realFileOrDirectoryName toZipDirectory:zipDirectoryName
-    "add the contents of a file or directory (recursive) -> realFileOrDirectoryName 
-     to the zip archive into the zip archive directory -> zipDirectoryName"
-    |zipFileName|
-    realFileOrDirectoryName exists ifFalse: [
-        ^ false
+!ZipArchive methodsFor:'testing'!
+
+isValidPath: anArchivePathName
+    self members do: [:aMember|
+        (aMember fileName startsWith:anArchivePathName) ifTrue:[
+            ^ true
+        ].
     ].
-
-    self addDirectory: zipDirectoryName.
-
-    realFileOrDirectoryName isDirectory ifFalse: [
-        zipFileName := zipDirectoryName, '/', realFileOrDirectoryName baseName.
-        ^ self addContentsToArchiveFrom: realFileOrDirectoryName to: zipFileName compress: false.
+    ^ false
+! !
+
+!ZipArchive methodsFor:'writing'!
+
+addArchiveDirectory: archiveDirectoryName fromOsDirectory: osDirectoryName
+    ^ self addArchiveDirectory: archiveDirectoryName fromOsDirectory: osDirectoryName compressMethod: 0
+!
+
+addArchiveDirectory: archiveDirectoryName fromOsDirectory: osDirectoryName compressMethod: theCompressMethod
+    |osDirectory fileNameOrDirectoryEntry|
+    osDirectory := osDirectoryName asFilename.
+    (osDirectory exists not or:[osDirectory exists not]) ifTrue:[
+        ^ self
     ].
-    ^ true
+
+    self addDirectory: archiveDirectoryName.
+    osDirectory recursiveDirectoryContentsDo: [:entry|
+        fileNameOrDirectoryEntry := osDirectory construct: entry.
+        fileNameOrDirectoryEntry isDirectory ifTrue: [
+            self addDirectory: (archiveDirectoryName, '/', entry).
+        ] ifFalse: [
+            fileNameOrDirectoryEntry readingFileDo: [:aStream|
+                self addFile: (archiveDirectoryName, '/', entry) 
+                     fromStream: aStream 
+                     compressMethod: theCompressMethod.
+            ].
+        ].
+    ].
 !
 
 addDirectory: aDirectoryName
@@ -3845,7 +3923,8 @@
 
 addFile: aFileName fromStream: aStream compressMethod: theCompressMethod
     |zipEntry curTime curDate crc32Pos crc32 unCompressedDataSize
-      compressedDataSize buffer rdSize nextBlockSize streamBufferSize|
+      compressedDataSize buffer rdSize nextBlockSize streamBufferSize
+      tmpCompressedData tmpCompressedDataSize myZipStream|
 
     (file isNil or: [mode ~~ #write]) ifTrue: [
         ^ self error: 'Archiv not open for writing ...'.
@@ -3895,36 +3974,43 @@
         file nextPutAll:zipEntry extraField.
     ].
 
-    (theCompressMethod == 8) ifTrue: [
-        self shouldImplement.
-"/        |tmpCompressedData tmpCompressedDataSize|
-"/        tmpCompressedData := ByteArray new:(data size + 16). "/ if the compression is less then the additional overhead we need more space in buffer
-"/        tmpCompressedDataSize := ZipStream compress:data into:tmpCompressedData.
+    crc32 := 0.
+    streamBufferSize := self class streamBufferSize.    
+    buffer := ByteArray new: streamBufferSize.
+    rdSize := aStream size.
+    unCompressedDataSize := rdSize.
+    compressedDataSize   := 0.
+
+    [rdSize > 0] whileTrue: [
+        rdSize > (self class streamBufferSize) ifTrue: [
+            nextBlockSize := streamBufferSize.
+        ] ifFalse: [
+            (nextBlockSize := rdSize) > 0 ifTrue:[
+                buffer := ByteArray new: nextBlockSize.
+            ].
+        ].
+
+        nextBlockSize > 0 ifTrue: [
+            (theCompressMethod == 8) ifTrue: [
+                self shouldImplement.
+                myZipStream isNil ifTrue: [
+                    myZipStream := ZipStream writeOpenOn: file.
+                ].
+                ZipStream
+"/                aStream nextBytes:nextBlockSize into:buffer startingAt:1.
+"/                tmpCompressedData := ByteArray new:(nextBlockSize + 16). "/ if the compression is less then the additional overhead we need more space in buffer
+"/                tmpCompressedDataSize := ZipStream compress:buffer into:tmpCompressedData.
 "/
 "/        zipEntry compressedSize: (tmpCompressedDataSize - 6). "/6 = the zlib specific data 2 bytes in front and 4 bytes behind the real data
 "/        theCompressedData := tmpCompressedData copyFrom: 3. "/ 2 bytes before the real data
-    ] ifFalse: [
-        crc32 := 0.
-        streamBufferSize := self class streamBufferSize.    
-        buffer := ByteArray new: streamBufferSize.
-        rdSize := aStream size.
-        unCompressedDataSize := rdSize.
-        [rdSize > 0] whileTrue: [
-            rdSize > (self class streamBufferSize) ifTrue: [
-                nextBlockSize := streamBufferSize.
             ] ifFalse: [
-                (nextBlockSize := rdSize) > 0 ifTrue:[
-                    buffer := ByteArray new: nextBlockSize.
-                ].
-            ].
-            nextBlockSize > 0 ifTrue: [
                 aStream nextBytes:nextBlockSize into:buffer startingAt:1.
                 file nextPutBytes:nextBlockSize from:buffer startingAt:1.
                 crc32 := (ZipStream crc32BytesIn: buffer crc: crc32).
             ].
-            rdSize := rdSize - nextBlockSize.
+            compressedDataSize := compressedDataSize + nextBlockSize.
         ].
-        compressedDataSize := unCompressedDataSize.
+        rdSize := rdSize - nextBlockSize.
     ].
 
     zipEntry crc32: crc32.
@@ -4540,7 +4626,7 @@
 !ZipArchive class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.63 2008-05-30 08:59:59 ab Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.64 2008-06-03 15:08:52 ab Exp $'
 ! !
 
 ZipArchive initialize!