'From Smalltalk/X, Version:3.4.3 on 29-mar-1998 at 9:59:17 pm' !
Object subclass:#ZipArchive
instanceVariableNames:'file archiveName firstEntry lastEntry'
classVariableNames:'ECREC_SIZE LREC_SIZE CREC_SIZE SIZE_CENTRAL_DIRECTORY
TOTAL_ENTRIES_CENTRAL_DIR C_COMPRESSED_SIZE
C_RELATIVE_OFFSET_LOCAL_HEADER C_FILENAME_LENGTH
C_UNCOMPRESSED_SIZE ZipFileFormatErrorSignal COMPR_STORED
COMPR_SHRUNK COMPR_REDUCED1 COMPR_REDUCED2 COMPR_REDUCED3
COMPR_REDUCED4 COMPR_IMPLODED COMPR_TOKENIZED COMPR_DEFLATED'
poolDictionaries:''
category:'System-Support-FileFormats'
!
Object subclass:#ZipMember
instanceVariableNames:'next relative_offset_local_header compressed_size
uncompressed_size name crc32 compression_method'
classVariableNames:''
poolDictionaries:''
privateIn:ZipArchive
!
!ZipArchive class methodsFor:'documentation'!
history
"Created: / 29.3.1998 / 17:45:14 / cg"
"Created: #oldFileNamed: / 29.3.1998 / 17:46:09 / cg"
"Created: #newFileNamed: / 29.3.1998 / 17:46:16 / cg"
"Created: #name: / 29.3.1998 / 17:46:47 / cg"
"Created: #name:mode: / 29.3.1998 / 17:47:40 / cg"
"Modified: #name:mode: / 29.3.1998 / 17:48:05 / cg"
"Created: #readDirectory / 29.3.1998 / 17:59:21 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:01:54 / cg"
"Created: #initialize / 29.3.1998 / 18:02:52 / cg"
"Modified: #initialize / 29.3.1998 / 18:03:51 / cg"
"Modified: #initialize / 29.3.1998 / 18:04:19 / cg"
"Modified: #initialize / 29.3.1998 / 18:05:44 / cg"
"Modified: #initialize / 29.3.1998 / 18:06:00 / cg"
"Modified: #initialize / 29.3.1998 / 18:06:20 / cg"
"Created: #readu2 / 29.3.1998 / 18:08:17 / cg"
"Modified: #readu2 / 29.3.1998 / 18:09:05 / cg"
"Created: #read4 / 29.3.1998 / 18:10:25 / cg"
"Modified: #readu2 / 29.3.1998 / 18:10:53 / cg"
"Modified: #read4 / 29.3.1998 / 18:11:03 / cg"
"Created: #addMember / 29.3.1998 / 18:22:26 / cg"
"Modified: #addMember / 29.3.1998 / 18:22:47 / cg"
"Modified: #name:mode: / 29.3.1998 / 18:23:26 / cg"
"Modified: #initialize / 29.3.1998 / 18:24:37 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:25:05 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:25:14 / cg"
"Deleted: #name: / 29.3.1998 / 18:25:45 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:26:38 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:27:05 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:33:22 / cg"
"Modified: #readDirectory / 29.3.1998 / 18:34:14 / cg"
"Created: #extract: / 29.3.1998 / 19:09:51 / cg"
"Created: #LREC_SIZE / 29.3.1998 / 19:11:21 / cg"
"Created: #findMember: / 29.3.1998 / 19:13:21 / cg"
"Modified: #findMember: / 29.3.1998 / 19:13:55 / cg"
"Created: #entries / 29.3.1998 / 19:14:32 / cg"
"Created: #zipMembersDo: / 29.3.1998 / 19:15:16 / cg"
"Modified: #findMember: / 29.3.1998 / 19:15:39 / cg"
"Modified: #entries / 29.3.1998 / 19:16:21 / cg"
"Modified: #name:mode: / 29.3.1998 / 19:16:35 / cg"
"Modified: #name:mode: / 29.3.1998 / 19:57:01 / cg"
"Modified: #readDirectory / 29.3.1998 / 20:02:00 / cg"
"Modified: #readDirectory / 29.3.1998 / 20:02:16 / cg"
"Modified: #entries / 29.3.1998 / 20:08:39 / cg"
"Modified: #extract: / 29.3.1998 / 20:08:49 / cg"
"Created: #members / 29.3.1998 / 20:09:28 / cg"
"Modified: #members / 29.3.1998 / 20:10:23 / cg"
"Modified: #extract: / 29.3.1998 / 20:12:13 / cg"
"Created: #decode:method: / 29.3.1998 / 20:14:46 / cg"
"Modified: #initialize / 29.3.1998 / 20:17:19 / cg"
"Modified: #decode:method: / 29.3.1998 / 20:20:21 / cg"
! !
!ZipArchive class methodsFor:'instance creation'!
newFileNamed:name
^ self new name:name mode:#write
"Created: / 29.3.1998 / 17:46:16 / cg"
!
oldFileNamed:name
^ self new name:name mode:#read
"Created: / 29.3.1998 / 17:46:09 / cg"
! !
!ZipArchive class methodsFor:'class initialization'!
initialize
ECREC_SIZE := 18.
LREC_SIZE := 26.
CREC_SIZE := 42.
TOTAL_ENTRIES_CENTRAL_DIR := 10.
SIZE_CENTRAL_DIRECTORY := 12.
C_COMPRESSED_SIZE := 16.
C_UNCOMPRESSED_SIZE := 20.
C_FILENAME_LENGTH := 24.
C_RELATIVE_OFFSET_LOCAL_HEADER := 38.
"/ compression methods
COMPR_STORED := 0.
COMPR_SHRUNK := 1.
COMPR_REDUCED1 := 2.
COMPR_REDUCED2 := 3.
COMPR_REDUCED3 := 4.
COMPR_REDUCED4 := 5.
COMPR_IMPLODED := 6.
COMPR_TOKENIZED := 7.
COMPR_DEFLATED := 8.
ZipFileFormatErrorSignal := Signal new.
"
self initialize
"
"Modified: / 29.3.1998 / 20:17:18 / cg"
! !
!ZipArchive class methodsFor:'constants'!
LREC_SIZE
^ LREC_SIZE
"Created: / 29.3.1998 / 19:11:20 / cg"
! !
!ZipArchive methodsFor:'accessing'!
entries
"return a collection of fileName entries"
|names|
names := OrderedCollection new.
self zipMembersDo:[:zipd |
names add:(zipd name)
].
^ names
"
(ZipArchive oldFileNamed:'/usr/lib/java/lib/classes.zip') entries
"
"Modified: / 29.3.1998 / 20:08:38 / cg"
!
extract:fileName
|zmemb rawContents|
zmemb := self findMember:fileName.
file position:(zmemb fileStart + 1).
rawContents := file nextBytes:(zmemb compressed_size).
^ self decode:rawContents method:(zmemb compression_method)
"
(ZipArchive oldFileNamed:'/usr/lib/java/lib/classes.zip') extract:'java/io/UTFDataFormatException.class'
"
"Modified: / 29.3.1998 / 20:12:12 / cg"
!
members
"return a collection of members"
|members|
members := OrderedCollection new.
self zipMembersDo:[:zipd |
members add:zipd
].
^ members
"
(ZipArchive oldFileNamed:'/usr/lib/java/lib/classes.zip') members
"
"Created: / 29.3.1998 / 20:09:27 / cg"
"Modified: / 29.3.1998 / 20:10:21 / cg"
! !
!ZipArchive methodsFor:'private'!
name:nm mode:mode
archiveName := nm.
mode == #read ifTrue:[
file := nm asFilename readStream.
self readDirectory.
] ifFalse:[
file := nm asFilename writeStream
]
"
ZipArchive oldFileNamed:'/usr/lib/java/lib/classes.zip'
(ZipArchive oldFileNamed:'/usr/lib/java/lib/classes.zip') entries
(ZipArchive oldFileNamed:'/usr/lib/java/lib/classes.zip') extract:'java/io/UTFDataFormatException.class'
"
"Modified: / 29.3.1998 / 19:57:00 / cg"
! !
!ZipArchive methodsFor:'private - decompression'!
decode:rawBytes method:compressionMethod
compressionMethod == COMPR_STORED ifTrue:[
"/ uncompressed
^ rawBytes
].
compressionMethod == COMPR_SHRUNK ifTrue:[
self error:'unsupported compression method: SHRUNK'.
^ nil
].
compressionMethod == COMPR_REDUCED1 ifTrue:[
self error:'unsupported compression method: REDUCED1'.
^ nil
].
compressionMethod == COMPR_REDUCED2 ifTrue:[
self error:'unsupported compression method: REDUCED2'.
^ nil
].
compressionMethod == COMPR_REDUCED3 ifTrue:[
self error:'unsupported compression method: REDUCED3'.
^ nil
].
compressionMethod == COMPR_REDUCED4 ifTrue:[
self error:'unsupported compression method: REDUCED4'.
^ nil
].
compressionMethod == COMPR_IMPLODED ifTrue:[
self error:'unsupported compression method: IMPLODED'.
^ nil
].
compressionMethod == COMPR_TOKENIZED ifTrue:[
self error:'unsupported compression method: TOKENIZED'.
^ nil
].
compressionMethod == COMPR_DEFLATED ifTrue:[
self error:'unsupported compression method: DEFLATED'.
^ nil
].
self error:'unsupported compression method'.
^ nil
"Created: / 29.3.1998 / 20:14:45 / cg"
"Modified: / 29.3.1998 / 20:20:20 / cg"
! !
!ZipArchive methodsFor:'private - directory stuff'!
addMember
|zmemb |
zmemb := ZipMember new.
(firstEntry == nil) ifTrue:[
firstEntry := zmemb
] ifFalse:[
lastEntry next:zmemb.
].
lastEntry := zmemb.
^ zmemb.
"Created: / 29.3.1998 / 18:22:25 / cg"
"Modified: / 29.3.1998 / 18:22:47 / cg"
!
findMember:name
self zipMembersDo:[:zipd |
(zipd name = name) ifTrue:[^ zipd].
].
^ nil
"Modified: / 29.3.1998 / 19:15:38 / cg"
!
readDirectory
|size count_in dir_size|
size := file fileSize.
(size == 0) ifTrue:[
count_in := 0.
^ self
].
(size < (ECREC_SIZE+4)) ifTrue:[
^ ZipFileFormatErrorSignal raiseWith:'zipfile too short'.
].
file position:(size - (ECREC_SIZE+4) + 1).
((file next ~~ $P)
or:[file next ~~ $K
or:[file next ~~ (Character value:8r005)
or:[file next ~~ (Character value:8r006)]]]) ifTrue:[
^ ZipFileFormatErrorSignal raiseWith:'not a valid zipfile'.
].
file skip: (TOTAL_ENTRIES_CENTRAL_DIR - 4).
count_in := self readu2. "/ Get TOTAL_ENTRIES_CENTRAL_DIR
dir_size := self read4. "/ Get SIZE_CENTRAL_DIRECTORY
file position:(size - (dir_size + ECREC_SIZE+4) + 1).
0 to:(count_in-1) do:[:i |
|zipd filename_length|
zipd := self addMember.
file skip:(4+C_COMPRESSED_SIZE-4-2-2-2).
zipd compression_method:(self readu2)."/ Get compression method
self readu2. "/ skip last_mod_file_time
self readu2. "/ skip last_mod_file_date
zipd crc32:(self read4). "/ Get crc32
zipd compressed_size:(self read4). "/ Get C_COMPRESSED_SIZE
zipd uncompressed_size:(self read4). "/ Get C_UNCOMPRESSED_SIZE
filename_length := self readu2. "/ Get C_FILENAME_LENGTH
file skip:(C_RELATIVE_OFFSET_LOCAL_HEADER-(C_FILENAME_LENGTH+2)).
zipd relative_offset_local_header:(self read4).
zipd name:(String new:filename_length).
file nextBytes:filename_length into:(zipd name).
]
"Modified: / 29.3.1998 / 20:02:15 / cg"
!
zipMembersDo:aBlock
|zipd|
zipd := firstEntry.
[zipd notNil] whileTrue:[
aBlock value:zipd.
zipd := zipd next
].
"Modified: / 29.3.1998 / 19:13:54 / cg"
"Created: / 29.3.1998 / 19:15:15 / cg"
! !
!ZipArchive methodsFor:'private - io'!
read4
^ file nextLongMSB:false
"Created: / 29.3.1998 / 18:10:25 / cg"
"Modified: / 29.3.1998 / 18:11:03 / cg"
!
readu2
^ file nextUnsignedShortMSB:false
"Modified: / 29.3.1998 / 18:10:53 / cg"
! !
!ZipArchive::ZipMember methodsFor:'accessing'!
compressed_size
"return the value of the instance variable 'compressed_size' (automatically generated)"
^ compressed_size
"Created: / 29.3.1998 / 18:28:03 / cg"
!
compressed_size:something
"set the value of the instance variable 'compressed_size' (automatically generated)"
compressed_size := something.
"Created: / 29.3.1998 / 18:28:03 / cg"
!
compression_method
"return the value of the instance variable 'compression_method' (automatically generated)"
^ compression_method
"Created: / 29.3.1998 / 20:02:57 / cg"
!
compression_method:something
"set the value of the instance variable 'compression_method' (automatically generated)"
compression_method := something.
"Created: / 29.3.1998 / 20:02:57 / cg"
!
crc32
"return the value of the instance variable 'crc32' (automatically generated)"
^ crc32
"Created: / 29.3.1998 / 20:03:00 / cg"
!
crc32:something
"set the value of the instance variable 'crc32' (automatically generated)"
crc32 := something.
"Created: / 29.3.1998 / 20:03:00 / cg"
!
name
"return the value of the instance variable 'name' (automatically generated)"
^ name
"Created: / 29.3.1998 / 18:29:22 / cg"
!
name:something
"set the value of the instance variable 'name' (automatically generated)"
name := something.
"Created: / 29.3.1998 / 18:29:22 / cg"
!
next
"return the value of the instance variable 'next' (automatically generated)"
^ next
"Created: / 29.3.1998 / 18:29:42 / cg"
!
next:something
"set the value of the instance variable 'next' (automatically generated)"
next := something.
"Created: / 29.3.1998 / 18:29:42 / cg"
!
relative_offset_local_header
"return the value of the instance variable 'relative_offset_local_header' (automatically generated)"
^ relative_offset_local_header
"Created: / 29.3.1998 / 18:28:40 / cg"
!
relative_offset_local_header:something
"set the value of the instance variable 'relative_offset_local_header' (automatically generated)"
relative_offset_local_header := something.
"Created: / 29.3.1998 / 18:28:40 / cg"
!
uncompressed_size
"return the value of the instance variable 'uncompressed_size' (automatically generated)"
^ uncompressed_size
"Created: / 29.3.1998 / 18:28:21 / cg"
!
uncompressed_size:something
"set the value of the instance variable 'uncompressed_size' (automatically generated)"
uncompressed_size := something.
"Created: / 29.3.1998 / 18:28:21 / cg"
! !
!ZipArchive::ZipMember methodsFor:'printing & storing'!
displayString
^ 'ZipMember(' , name , ')'
"Created: / 29.3.1998 / 20:10:07 / cg"
! !
!ZipArchive::ZipMember methodsFor:'queries'!
fileStart
^ relative_offset_local_header + ZipArchive LREC_SIZE + 4 + name size
"Created: / 29.3.1998 / 19:10:57 / cg"
! !
ZipArchive initialize!