# HG changeset patch # User Claus Gittinger # Date 1055416820 -7200 # Node ID 1eefc3a60863113a47147e0e09e36bd59582a500 # Parent 99e070f7c351a58d00420d3cc1485e4841cefe71 output parsing refactored; diff -r 99e070f7c351 -r 1eefc3a60863 Archiver.st --- a/Archiver.st Wed Jun 11 10:37:18 2003 +0200 +++ b/Archiver.st Thu Jun 12 13:20:20 2003 +0200 @@ -8,6 +8,13 @@ category:'System-Support-FileFormats' ! +Object subclass:#ArchiverOutputParser + instanceVariableNames:'firstLineRead archiver' + classVariableNames:'' + poolDictionaries:'' + privateIn:Archiver +! + Archiver subclass:#GZipArchive instanceVariableNames:'' classVariableNames:'' @@ -113,6 +120,22 @@ ^ ZipArchive ! ! +!Archiver class methodsFor:'columns'! + +columns + self subclassResponsibility +! ! + +!Archiver class methodsFor:'commandOutputReader'! + +commandOutputParser + ^ self commandOutputParserClass new +! + +commandOutputParserClass + ^ ArchiverOutputParser +! ! + !Archiver class methodsFor:'queries'! canAddFiles @@ -299,6 +322,20 @@ ] ! +isValidOutputLine:line + "return true, if line contains a valid list-files output line" + + self subclassResponsibility +! + +listFilesReader + |reader| + + reader := ArchiverOutputParser new. + reader archiver:self. + ^ reader +! + outStream:aOutStream errorStream:aErrorStream outStream := aOutStream. @@ -320,20 +357,84 @@ self removeTemporaryDirectory. ! ! -!Archiver::GZipArchive class methodsFor:'columns'! +!Archiver::ArchiverOutputParser class methodsFor:'instance creation'! + +new + ^ self basicNew initialize. +! ! + +!Archiver::ArchiverOutputParser methodsFor:'accessing'! + +archiver:something + "set the value of the instance variable 'archiver' (automatically generated)" + + archiver := something. +! ! + +!Archiver::ArchiverOutputParser methodsFor:'initialization'! -columns +initialize + firstLineRead := false. +! ! + +!Archiver::ArchiverOutputParser methodsFor:'parsing'! + +parseLine:line forItemClass:itemClass + |words archiverColumns item index key| + + (firstLineRead not and:[archiver class hasTitleLine]) ifTrue:[ + firstLineRead := true. + ^ nil. + ]. + + (archiver isValidOutputLine:line) ifFalse:[ + ^ nil. + ]. + + words := line asCollectionOfWords. + archiverColumns := archiver columns. + item := itemClass new. + index := 1. - "/ columns in stream order - "/ colums id words to read - ^ #( #(#method 1) - #(#crc 1) - #(#dateAndTime 3) - #(#compressSize 1) - #(#size 1) - #(#ratio 1) - #(#fileName #rest) - ) + archiverColumns do:[:colDescr | + | itemWordCount itemStream itemFieldSelector itemWriter | + + itemWordCount := colDescr second. + itemFieldSelector := colDescr first. + itemFieldSelector notNil ifTrue:[ + itemWriter := (itemFieldSelector , ':') asSymbol. + ]. + itemStream := WriteStream on:''. + itemWordCount == #rest ifTrue:[ + index to:(words size) do:[:i| + itemStream nextPutAll:(words at:i). + itemStream space. + ]. + ] ifFalse:[ + index to:(index + itemWordCount - 1) do:[:i| + itemStream nextPutAll:(words at:i). + itemStream space. + ]. + index := index + itemWordCount. + ]. + itemWriter notNil ifTrue:[ + item perform:itemWriter with:(itemStream contents). + ]. + itemStream close. + ]. + ((archiverColumns collect:[:el| el first]) includes:#permissions) ifTrue:[ + (item permissions startsWith:$d) ifTrue:[ + key := #directory. + item isDirectory:true. + ] ifFalse:[ + key := MIMETypes mimeTypeForFilename:(item fileName asFilename baseName). + item isDirectory:false. + ]. + ] ifFalse:[ + key := MIMETypes mimeTypeForFilename:(item fileName asFilename baseName). + ]. + item icon:(FileBrowser iconForKeyMatching:key). + ^ item ! ! !Archiver::GZipArchive class methodsFor:'command strings'! @@ -408,6 +509,22 @@ ]. ! ! +!Archiver::GZipArchive methodsFor:'columns'! + +columns + + "/ columns in stream order + "/ colums id words to read + ^ #( #(#method 1) + #(#crc 1) + #(#dateAndTime 3) + #(#compressSize 1) + #(#size 1) + #(#ratio 1) + #(#fileName #rest) + ) +! ! + !Archiver::GZipArchive methodsFor:'command strings'! getCommandToGZip:aFile asNew:newFile @@ -432,23 +549,31 @@ tempDir := self temporaryDirectory. archivInTemp := tempDir construct:(archivFile baseName). - "/ copy files to be added to tempDir - colOfFiles do:[:file | - file recursiveCopyTo:(tempDir construct:(file asFilename baseName)) - ]. "/ copy archiv to tempDir archivFile copyTo:archivInTemp. - - "/ addFiles to the tar archive - cmd := self getCommandToAdd:colOfFiles toArchive:archivInTemp. - self executeCommand:cmd directory:tempDir. + "/ keep a save copy + archivFile renameTo:(archivFile withSuffix:'sav'). + [ + "/ copy files to be added to tempDir + colOfFiles do:[:file | + file recursiveCopyTo:(tempDir construct:(file asFilename baseName)) + ]. - "/ copy tar archiv back - archivInTemp copyTo:(self fileName). + "/ addFiles to the tar archive + cmd := self getCommandToAdd:colOfFiles toArchive:archivInTemp. + self executeCommand:cmd directory:tempDir. - "/ cg: remove the tempFile - archivInTemp remove. + "/ copy tar archiv back + archivInTemp copyTo:archivFile. + ] ensure:[ + "/ cg: remove the tempFile + archivInTemp remove. + "/ cg: remove copied files + colOfFiles do:[:file | + (tempDir construct:(file asFilename baseName)) remove. + ]. + ]. ! extractFiles:aColOfFilesOrNil to:aDirectory @@ -513,19 +638,6 @@ self subclassResponsibility ! ! -!Archiver::TarArchive class methodsFor:'columns'! - -columns - - "/ colums id words to read - ^ #( #(#permissions 1) - #(#ownerGroup 1) - #(#size 1) - #(#dateAndTime 2) - #(#fileName #rest) - ) -! ! - !Archiver::TarArchive class methodsFor:'command strings'! stringWithQuotedFileBaseNames:aColOfFiles @@ -563,6 +675,24 @@ ^ true ! ! +!Archiver::TarArchive methodsFor:'columns'! + +columns + + "/ colums id words to read + ^ #( #(#permissions 1) + #(#ownerGroup 1) + #(#size 1) + #(#dateAndTime 2) + #(#fileName #rest) + ) +! + +isValidOutputLine:line + ('[-d][-r][-w][-x]' match:(line copyTo:4)) ifTrue:[^ true]. + ^ false. +! ! + !Archiver::TarArchive methodsFor:'command strings'! getCommandToAdd:aColOfFiles toArchive:archiveFile @@ -574,7 +704,7 @@ "/ 'r' TarArchivAddOption "/ 'f' TarArchivFileOption - stream nextPutAll:('%1 -rf "%2"' + stream nextPutAll:('%1 rf "%2"' bindWith:self class tarCommand with:archiveFile asString string). @@ -638,13 +768,6 @@ ^ stream contents ! ! -!Archiver::TarGZipArchive class methodsFor:'columns'! - -columns - - ^ Archiver tarArchive columns -! ! - !Archiver::TarGZipArchive class methodsFor:'queries'! canAddFiles @@ -699,10 +822,10 @@ tarArchiver extractFiles:aColOfFiles to:aDirectory. ! -extractFiles:aColOfFiles withOutDirectoryTo:aDirectory +extractFiles:aColOfFiles withoutDirectoryTo:aDirectory self setCommandOptions. - tarArchiver extractFiles:aColOfFiles withOutDirectoryTo:aDirectory. + tarArchiver extractFiles:aColOfFiles withoutDirectoryTo:aDirectory. ! listFiles:aColOfFiles @@ -734,6 +857,16 @@ gzipArchiver zipFile:(tarArchiver fileName) to:(self fileName). ! ! +!Archiver::TarGZipArchive methodsFor:'columns'! + +columns + ^ tarArchiver columns +! + +isValidOutputLine:line + ^ tarArchiver isValidOutputLine:line +! ! + !Archiver::TarGZipArchive methodsFor:'initialization & release'! release @@ -742,22 +875,6 @@ tarArchiver release. ! ! -!Archiver::ZipArchive class methodsFor:'columns'! - -columns - - "/ colums id words to read - ^ #( (#permissions 1) - (#version 2) - (#size 1) - (#type 1) - (#ratio 1) - (nil 1) - (#dateAndTime 2) - (#fileName #rest) - ) -! ! - !Archiver::ZipArchive class methodsFor:'command strings'! unzipCommand @@ -793,8 +910,39 @@ ^ true ! ! +!Archiver::ZipArchive methodsFor:'columns'! + +columns + + "/ colums id words to read + ^ #( (#permissions 1) + (#version 2) + (#size 1) + (#type 1) + (#ratio 1) + (nil 1) + (#dateAndTime 2) + (#fileName #rest) + ) +! + +isValidOutputLine:line + ('[-d][-r][-w][-x]' match:(line copyTo:4)) ifTrue:[^ true]. + ^ false. +! ! + !Archiver::ZipArchive methodsFor:'command strings'! +addDoubleQuotedFilenames:collectionOfFilenames toStream:aStream + collectionOfFilenames notNil ifTrue:[ + collectionOfFilenames do:[:el | + aStream nextPutAll:' "'. + aStream nextPutAll:(el asString). + aStream nextPutAll:'"' + ]. + ]. +! + getCommandToAdd:aColOfFiles toArchive:archiveFile |stream| @@ -806,16 +954,14 @@ bindWith:self class zipCommand with:archiveFile asString string). - aColOfFiles do:[:el | - stream nextPutAll:' "'. - stream nextPutAll:(el asFilename baseName). - stream nextPutAll:'"' - ]. + self + addDoubleQuotedFilenames:(aColOfFiles collect:[:each | each asFilename baseName]) + toStream:stream. ^ stream contents ! -getCommandToExtractFiles:sel intoDirectory:dir +getCommandToExtractFiles:aColOfFiles intoDirectory:dir |stream| stream := WriteStream on:''. @@ -828,13 +974,7 @@ with:dir asString string with:self fileName asString). - sel notNil ifTrue:[ - sel do:[:el | - stream nextPutAll:' "'. - stream nextPutAll:(el asString). - stream nextPutAll:'"' - ]. - ]. + self addDoubleQuotedFilenames:aColOfFiles toStream:stream. ^ stream contents. ! @@ -850,12 +990,10 @@ bindWith:self class unzipCommand with:self fileName asString string). - aColOfFiles notNil ifTrue:[ - aColOfFiles do:[:el | - stream nextPutAll:' "'. - stream nextPutAll:(el baseName). - stream nextPutAll:'"' - ] + aColOfFiles notNil ifTrue:[ self halt. + self + addDoubleQuotedFilenames:(aColOfFiles collect:[:each | each asFilename baseName]) + toStream:stream. ]. ^ stream contents. ! @@ -869,16 +1007,12 @@ bindWith:self class zipCommand with:self fileName asString string). - aColOfFiles do:[:el | - stream nextPutAll:' "'. - stream nextPutAll:(el asString). - stream nextPutAll:'"' - ]. + self addDoubleQuotedFilenames:aColOfFiles toStream:stream. ^ stream contents. ! ! !Archiver class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic2/Archiver.st,v 1.16 2003-05-16 18:16:36 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic2/Archiver.st,v 1.17 2003-06-12 11:20:20 cg Exp $' ! !