Add method to check if it is a zip archive
authorab
Tue, 06 May 2008 14:12:38 +0200
changeset 1986 d7a4d1e1fe13
parent 1985 805f1bfff8b9
child 1987 7ffcf0524b4b
Add method to check if it is a zip archive
ZipArchive.st
--- a/ZipArchive.st	Mon May 05 14:42:28 2008 +0200
+++ b/ZipArchive.st	Tue May 06 14:12:38 2008 +0200
@@ -2598,6 +2598,22 @@
 
 !ZipArchive class methodsFor:'instance creation'!
 
+isZipArchive:aFileName
+    |f fn|
+
+    f := aFileName asFilename.
+    f exists ifFalse:[^ false].
+    f isDirectory ifFalse:[^ false].
+
+    fn := f pathName.
+
+    ^ self new checkZipArchive: fn.
+
+
+    "Created: / 29.3.1998 / 17:46:09 / cg"
+    "Modified: / 20.10.1998 / 00:30:02 / cg"
+!
+
 newFileNamed:name
     ^ self new name:name mode:#write
 
@@ -2812,13 +2828,24 @@
     mode ~~ #write ifTrue:[
         self openFile.
         self readDirectory.
-    ] ifFalse:[
+    ] ifFalse:[        
         self openFile.
     ].
 ! !
 
 !ZipArchive methodsFor:'private'!
 
+checkZipArchive:archiveFileName
+    |isValidArchive|
+
+    archiveName := archiveFileName asFilename name.
+    mode := #read.
+    self openFile.
+    isValidArchive := self checkZipArchive.
+    self closeFile.
+    ^ isValidArchive
+!
+
 closeFile
     "close the stream - tell operating system"
 
@@ -3029,6 +3056,54 @@
     "Created: / 9.9.1998 / 20:33:06 / cg"
 !
 
+checkZipArchive
+    "read the zip directory into a linked-list of zipMembers"
+
+    |size count_in foundPK pos0|
+
+    file isNil ifTrue: [
+        ^ false
+    ].
+
+    size := file fileSize.
+    (size == 0) ifTrue:[
+        count_in := 0.
+        ^ false
+    ].
+
+    (size < (ECREC_SIZE+4)) ifTrue:[
+        ^ false.
+    ].
+
+    foundPK := false.
+    file position0Based:(pos0 := size - ECREC_SIZE - 4).
+
+    "/ set position to end of central directory record
+    ((file next ~~ ($P codePoint))
+    or:[file next ~~ ($K codePoint)
+    or:[file next ~~ 8r005
+    or:[file next ~~ 8r006]]]) ifTrue:[
+        "/ search for end of central directory signature, this is 
+        "/ necessary if the archive includes a .ZIP file comment
+        file reset. "/ (pos0 - 100).
+        [file atEnd not and:[foundPK not]] whileTrue:[
+            (file next == ($P codePoint)
+            and:[file next == ($K codePoint)
+            and:[file next == 8r005
+            and:[file next == 8r006]]]) ifTrue:[
+                foundPK := true.
+                pos0 := file position0Based - 4.
+            ]
+        ].
+        foundPK ifTrue:[
+            'ZipArchive includes a .ZIP file comment; resynchronized' infoPrintCR.
+        ] ifFalse:[
+            ^ false.
+        ]
+    ].
+    ^ true
+!
+
 findMember:name
     "find a zipMember by name"
 
@@ -3692,7 +3767,7 @@
 !ZipArchive class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.58 2008-05-05 12:42:28 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/ZipArchive.st,v 1.59 2008-05-06 12:12:38 ab Exp $'
 ! !
 
 ZipArchive initialize!