# HG changeset patch # User Stefan Vogel # Date 1245789536 -7200 # Node ID 2544520347485fdc052ce1e082ef20556cbc809d # Parent 72f7e3be5d17635a84232a2c3d25d308651da6d0 #restoreOsDirectory:fromArchiveDirectory - create subdirectories that are not in the zip atchive diff -r 72f7e3be5d17 -r 254452034748 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!