#restoreOsDirectory:fromArchiveDirectory
authorStefan Vogel <sv@exept.de>
Tue, 23 Jun 2009 22:38:56 +0200
changeset 2173 254452034748
parent 2172 72f7e3be5d17
child 2174 d1022a910535
#restoreOsDirectory:fromArchiveDirectory - create subdirectories that are not in the zip atchive
ZipArchive.st
--- a/ZipArchive.st	Wed Jun 17 18:26:18 2009 +0200
+++ b/ZipArchive.st	Tue Jun 23 22:38:56 2009 +0200
@@ -3830,8 +3830,8 @@
 
     |zmemb rawContents data|
 
-    (file isNil or: [mode ~~ #read]) ifTrue: [
-        ^ self error: 'Archiv not open for reading ...'.
+    (file isNil or:[mode ~~ #read]) ifTrue:[
+        ^ self error: 'ZipArchive not open for reading ...'.
     ].    
 
     zmemb := self findMember:fileName.
@@ -3857,13 +3857,12 @@
 
 extract:fileName intoStream: aWriteStream
     "extract an entry indentified by filename into aWriteStream
-     return false on error
-    "
+     return false on error"
 
     |zmemb buffer rdSize nextBlockSize streamBufferSize myZipStream|
 
-    (file isNil or: [mode ~~ #read]) ifTrue: [
-        self error: 'Archiv not open for reading ...'.
+    (file isNil or:[mode ~~ #read]) ifTrue:[
+        self error:'ZipArchive not open for reading ...'.
         ^ false
     ].    
 
@@ -3945,7 +3944,7 @@
     ].
 
     "/ open archive and set bounds for the requested archive
-    "/ this can now be handled like an ordenary archive
+    "/ this can now be handled like an ordinary archive
 
     ^ self class oldFileNamed:archiveName 
                startOfArchive:(zmemb fileStart + startOfArchive) 
@@ -3953,47 +3952,54 @@
 !
 
 restoreOsDirectory:osDirectoryName fromArchiveDirectory: archiveDirectoryName
-    |osDirectory fileNameOrDirectoryEntry directoryAlreadyCreated|
+    |osDirectory directoryAlreadyCreated archiveDirectoryNameSize|
 
     osDirectory := osDirectoryName asFilename.
-    (osDirectory exists and: [osDirectory isDirectory not]) ifTrue:[
-        ^ self
+    directoryAlreadyCreated := osDirectory exists.
+    (directoryAlreadyCreated and: [osDirectory isDirectory not]) ifTrue:[
+        "no way to create the base directory - done"
+        OperatingSystem accessDeniedErrorSignal
+            raiseRequestWith:osDirectory
+            errorString:(' - ZipArchive - cannot create base directory: ' , osDirectory asString).
+        ^ self.
     ].
 
-    directoryAlreadyCreated := false.
-
-    self members do: [:aMember|
-        |baseName|
-
-        "/ cg: was wrong - was wrong about (isValidPath:'foo), if there is a file named 'foobar' ?!!
-        ((aMember fileName = archiveDirectoryName) 
-        or:[ aMember fileName startsWith: (archiveDirectoryName,'/') ]) ifTrue: [
+    archiveDirectoryNameSize := archiveDirectoryName size.
+
+    self members do: [:eachZipArchiveMember|
+        |eachZipArchiveMemberName baseName directory fileNameOrDirectoryEntry|
+
+        eachZipArchiveMemberName := eachZipArchiveMember fileName.
+
+        ((eachZipArchiveMemberName startsWith:archiveDirectoryName)
+         and:[eachZipArchiveMemberName size = archiveDirectoryNameSize
+              or:[(eachZipArchiveMemberName at:archiveDirectoryNameSize+1) == $/]]) ifTrue: [
+
             directoryAlreadyCreated ifFalse:[
-                osDirectory exists ifFalse:[
-                    osDirectory recursiveMakeDirectory.
-                    directoryAlreadyCreated := true.
-                ]
+                osDirectory recursiveMakeDirectory.
+                directoryAlreadyCreated := true.
             ].
-            baseName := aMember fileName copyFrom: (archiveDirectoryName size+1).
-            baseName size > 0 ifTrue:[
-                baseName first == $/ ifTrue:[
-                    baseName := (baseName from:2) asString.
-                ].
+            baseName := eachZipArchiveMemberName copyFrom:(archiveDirectoryNameSize+1).
+            (baseName notEmpty and:[baseName first == $/]) ifTrue:[
+                baseName := baseName copyFrom:2.
             ].
 
-            fileNameOrDirectoryEntry := osDirectory construct:baseName.
-            "/ cg - hugh ??? will never be false, because Filename does not implement isEmpty/notEmpty !!!!!!!!
-            fileNameOrDirectoryEntry notEmptyOrNil ifTrue: [
-                "/ sr&cg:
-                "/ size==0 is not aq valid indicator of the entry  being a directory.
-                "/ use the externalFileAttributes instead
-                "/ aMember compressedSize == 0 ifTrue: [
-                (aMember externalFileAttributes bitTest:EXTERNALFILEATTRIBUTES_ISDIRECTORY) ifTrue:[
+            baseName notEmpty ifTrue:[
+                fileNameOrDirectoryEntry := osDirectory construct:baseName.
+
+                "Note, that a ZipArchive usually does not contain entries for directories!!"
+                (eachZipArchiveMember externalFileAttributes bitTest:EXTERNALFILEATTRIBUTES_ISDIRECTORY) ifTrue:[
                     fileNameOrDirectoryEntry recursiveMakeDirectory.
-                ] ifFalse: [                
+                ] ifFalse: [
+                    "make sure, that the directory exists"
+                    directory := fileNameOrDirectoryEntry directory.
+                    directory isDirectory ifFalse:[
+                        directory recursiveMakeDirectory.
+                    ].
+                    
                     fileNameOrDirectoryEntry writingFileDo:[:aStream|
                         self 
-                            extract: aMember fileName 
+                            extract:eachZipArchiveMemberName 
                             intoStream: aStream.
                     ].
                 ].
@@ -4681,7 +4687,7 @@
 !ZipArchive class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.74 2009-06-10 12:53:07 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.75 2009-06-23 20:38:56 stefan Exp $'
 ! !
 
 ZipArchive initialize!