Chris Muller uploaded a new version of Files to project The Trunk:
http://source.squeak.org/trunk/Files-cmm.68.mcz ==================== Summary ==================== Name: Files-cmm.68 Author: cmm Time: 15 February 2010, 4:12:35.172 pm UUID: f9b9cd83-3ec3-4f1e-b93e-160b60039ff9 Ancestors: Files-ul.67 Refactored DirectoryEntry. Highlights: - Moved DirectoryEntry from a subclass of ArrayedCollection to a subclass of Object. - Each DirectoryEntry now knows its 'directory' (a FileDirectory). At last, DirectoryEntry's are useful enough to serve as first-class "file reference" objects that have otherwise, thus far, been relegated to platform-specific Strings. - Behaviors exclusive to DirectoryEntry's representing files have been moved to DirectoryEntryFile. Behaviors exclusive to DirectoryEntry's representing directory's have been moved into DirectoryEntryDirectory. The DirectoryEntry>>'dirFlag' variable has been removed. - Added a terse, platform-independent way of expressing FileDirectory concatenation via the #/ operator: myFileDirectory / 'subDir' / 'sub-subDir' =============== Diff against Files-ul.67 =============== Item was added: + ----- Method: DirectoryEntry>>creationDateAndTime (in category 'access') ----- + creationDateAndTime + "The DateAndTime my entry in the file system was created." + ^DateAndTime fromSeconds: creationTime! Item was added: + ----- Method: DirectoryEntryDirectory>>copyHere: (in category 'file operations') ----- + copyHere: aDirectoryEntryFile + "Copy aDirectoryFileEntry, which represents a file, to the directory I represent." + ^ self asFileDirectory copyHere: aDirectoryEntryFile! Item was added: + ----- Method: DirectoryEntry>>printOn: (in category 'access') ----- + printOn: aStream + super printOn: aStream. + aStream + space ; + nextPutAll: self name! Item was added: + ----- Method: DirectoryEntryFile>>copyTo: (in category 'file operations') ----- + copyTo: targetDirectory + "Make a copy of me in targetDirectory. targetDirectory can be a FileDirectory, ServerDirectory or a DirectoryEntryDirectory. If a file with my name already exists in targetDirectory, signal a FileExistsException." + ^ targetDirectory copyHere: self! Item was changed: ----- Method: FileDirectory>>directoryNames (in category 'enumeration') ----- directoryNames "Return a collection of names for the subdirectories of this directory." "FileDirectory default directoryNames" + ^ (self entries select: [:entry | entry isDirectory ]) + collect: [:entry | entry name] - ^ (self entries select: [:entry | entry at: 4]) - collect: [:entry | entry first] ! Item was added: + ----- Method: DirectoryEntry>>modificationDateAndTime (in category 'access') ----- + modificationDateAndTime + "The DateAndTime my entry in the file system was last modified." + ^ DateAndTime fromSeconds: modificationTime! Item was added: + ----- Method: DirectoryEntry>>setDirectory: (in category 'private-initialization') ----- + setDirectory: aFileOrServerDirectory + "Set only my (containing) directory. This is only needed because I couldn't factor ServerDirectory class>>#parseFTPEntry: to the instance-side (because HTTPClient utility uses it). Therefore, they pass a nil and then set my 'directory' immediately after.." + directory := aFileOrServerDirectory! Item was added: + ----- Method: FileDirectory>>copyHere: (in category 'file operations') ----- + copyHere: aDirectoryEntryFile + "Copy aDirectoryEntryFile, which represents a file, to the directory I represent." + aDirectoryEntryFile readStream in: + [ : readStream | + [ self + putFile: readStream + named: aDirectoryEntryFile name ] ensure: [ readStream close ] ]! Item was added: + ----- Method: DirectoryEntryFile>>contentsFrom:to: (in category 'stream access') ----- + contentsFrom: startPosition to: endPosition + "Answer my contents from startPosition to endPosition." + ^ FileStream + detectFile: [ self readStream ] + do: + [ : stream | + stream + position: startPosition ; + next: endPosition - startPosition + 1 ]! Item was changed: ----- Method: DirectoryEntry>>isDirectory (in category 'access') ----- isDirectory "whether this entry represents a directory" + self subclassResponsibility! - ^dirFlag! Item was changed: ----- Method: FileDirectory>>fileNames (in category 'enumeration') ----- fileNames "Return a collection of names for the files (but not directories) in this directory." "FileDirectory default fileNames" + ^ (self entries reject: [ : entry | entry isDirectory ]) + collect: [ : entry | entry name ]! - - ^ (self entries select: [:entry | (entry at: 4) not]) - collect: [:entry | entry first] - ! Item was added: + ----- Method: DirectoryEntry class>>fromArray:directory: (in category 'instance creation') ----- + fromArray: array directory: aFileDirectoryOrServerDirectory + | entryType | + entryType := (array at: 4) + ifTrue: [ DirectoryEntryDirectory ] + ifFalse: [ DirectoryEntryFile ]. + ^ entryType + directory: aFileDirectoryOrServerDirectory + name: (array at: 1) + creationTime: (array at: 2) + modificationTime: (array at: 3) + fileSize: (array at: 5)! Item was added: + ----- Method: DirectoryEntryFile>>delete (in category 'file operations') ----- + delete + directory deleteFileNamed: self name! Item was added: + ----- Method: DirectoryEntryFile>>readStream (in category 'stream access') ----- + readStream + "Answer a FileStream on my contents that can be read, but not written." + ^ directory readOnlyFileNamed: self name! Item was changed: + Object subclass: #DirectoryEntry + instanceVariableNames: 'directory name creationTime modificationTime fileSize' - ArrayedCollection subclass: #DirectoryEntry - instanceVariableNames: 'name creationTime modificationTime dirFlag fileSize' classVariableNames: '' poolDictionaries: '' category: 'Files-Directories'! !DirectoryEntry commentStamp: '<historical>' prior: 0! an entry in a directory; a reference to either a file or a directory.! Item was added: + ----- Method: Integer>>asBytesDescription (in category '*files') ----- + asBytesDescription + "Answer a terse, easily-readable representation of this Integer reprsenting a number of bytes. Useful for file-browsers." + | suffixes | + suffixes := { 'k'"ilobytes". 'M'"egabytes". 'G'"igabytes". 'T'"erabytes". 'P'"etabytes". 'E'"xabytes". 'Z'"ettabytes". 'Y'"ottabytes"}. + suffixes size to: 1 by: -1 do: + [ : index | | units | + units := 1000 raisedTo: index. + self > units ifTrue: [ ^ ((self / units) asFloat roundTo: 0.01) asString, (suffixes at: index) ] ]. + ^ self asString! Item was added: + DirectoryEntry subclass: #DirectoryEntryFile + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'Files-Directories'! Item was added: + ----- Method: DirectoryEntry>>containingDirectory (in category 'access') ----- + containingDirectory + "Answer the FileDirectory in which I reside." + ^ directory! Item was added: + ----- Method: DirectoryEntry>>copyTo: (in category 'file operations') ----- + copyTo: fileOrServerDirectory + "Copy me to fileOrServerDirectory." + self subclassResponsibility! Item was added: + ----- Method: DirectoryEntry>>services (in category 'services') ----- + services + "Answer the same collection of SimpleServiceEntry's accessed by the FileList." + ^ FileList itemsForFile: self fullName! Item was changed: ----- Method: FileDirectory>>directoryContentsFor: (in category 'private') ----- directoryContentsFor: fullPath "Return a collection of directory entries for the files and directories in the directory with the given path. See primLookupEntryIn:index: for further details." "FileDirectory default directoryContentsFor: ''" | entries index done entryArray f | entries := OrderedCollection new: 200. index := 1. done := false. f := fullPath asVmPathName. [done] whileFalse: [ entryArray := self primLookupEntryIn: f index: index. #badDirectoryPath = entryArray ifTrue: [ ^(InvalidDirectoryError pathName: pathName asSqueakPathName) signal]. entryArray == nil ifTrue: [done := true] + ifFalse: [entries addLast: (DirectoryEntry fromArray: entryArray directory: self)]. - ifFalse: [entries addLast: (DirectoryEntry fromArray: entryArray)]. index := index + 1]. ^ entries asArray collect: [:s | s convertFromSystemName]. ! Item was added: + ----- Method: DirectoryEntryFile>>isDirectory (in category 'testing') ----- + isDirectory + "whether this entry represents a directory, it does not." + ^ false! Item was added: + ----- Method: DirectoryEntry>>fullName (in category 'access') ----- + fullName + "The fully-qualified name." + ^ directory fullNameFor: self name! Item was added: + ----- Method: DirectoryEntry class>>directory:name:creationTime:modificationTime:fileSize: (in category 'instance creation') ----- + directory: aFileDirectoryOrServerDirectory name: name0 creationTime: creationTime modificationTime: modificationTime fileSize: fileSize + ^ self new + setDirectory: aFileDirectoryOrServerDirectory + name: name0 + creationTime: creationTime + modificationTime: modificationTime + fileSize: fileSize! Item was added: + ----- Method: DirectoryEntry>>fileSizeString (in category 'access') ----- + fileSizeString + "Answer my file size as an easy-to-read String." + ^ self fileSize asBytesDescription! Item was added: + ----- Method: DirectoryEntryDirectory>>asFileDirectory (in category 'convert') ----- + asFileDirectory + "Answer a FileDirectory representing the same directory I represent." + ^ self containingDirectory in: [ : cd | cd on: (cd fullNameFor: self name) ]! Item was added: + ----- Method: DirectoryEntry>>delete (in category 'file operations') ----- + delete + "Physically remove from the disk." + self subclassResponsibility! Item was changed: ----- Method: FileDirectory>>entries (in category 'enumeration') ----- entries + "Return a collection of DirectoryEntry's for the files and directories in this directory. See primLookupEntryIn:index: for further details." - "Return a collection of directory entries for the files and directories in this directory. Each entry is a five-element array: (<name><creationTime><modificationTime><dirFlag><fileSize>). See primLookupEntryIn:index: for further details." "FileDirectory default entries" - ^ self directoryContentsFor: pathName ! Item was changed: + ----- Method: DirectoryEntry class>>name:creationTime:modificationTime:isDirectory:fileSize: (in category 'deprecated') ----- - ----- Method: DirectoryEntry class>>name:creationTime:modificationTime:isDirectory:fileSize: (in category 'instance creation') ----- name: name0 creationTime: creationTime modificationTime: modificationTime isDirectory: isDirectory fileSize: fileSize + "This is the legacy creation method we are trying to phase out. Please use #directory: name: creationTime: modificationTime: fileSize:." + | type | + type := isDirectory + ifTrue: [ DirectoryEntryDirectory ] + ifFalse: [ DirectoryEntryFile ]. + ^ type + directory: nil + name: name0 + creationTime: creationTime + modificationTime: modificationTime + fileSize: fileSize! - ^self new privateName: name0 creationTime: creationTime modificationTime: modificationTime isDirectory: isDirectory fileSize: fileSize! Item was added: + ----- Method: DirectoryEntry>>setDirectory:name:creationTime:modificationTime:fileSize: (in category 'private-initialization') ----- + setDirectory: aFileDirectoryOrServerDirectory name: name0 creationTime: creationTime0 modificationTime: modificationTime0 fileSize: fileSize0 + directory := aFileDirectoryOrServerDirectory. + name := name0. + creationTime := creationTime0. + modificationTime := modificationTime0. + fileSize := fileSize0! Item was changed: + ----- Method: DirectoryEntry>>at: (in category 'access') ----- - ----- Method: DirectoryEntry>>at: (in category 'access-compatibility') ----- at: index "compatibility interface" + self deprecated: 'old-style access to DirectoryEntry'. - "self halt: 'old-style access to DirectoryEntry'" index = 1 ifTrue: [ ^self name ]. index = 2 ifTrue: [ ^self creationTime ]. index = 3 ifTrue: [ ^self modificationTime ]. index = 4 ifTrue:[ ^self isDirectory ]. index = 5 ifTrue:[ ^self fileSize ]. + self error: 'invalid index specified'. + ! - self error: 'invalid index specified'.! Item was changed: ----- Method: DirectoryEntry>>creationTime (in category 'access') ----- creationTime + "The time the entry was created, as an Integer number of seconds offset from the DateAndTime epoch." - "time the entry was created. (what's its type?)" ^creationTime! Item was changed: ----- Method: FileDirectory>>fileAndDirectoryNames (in category 'enumeration') ----- fileAndDirectoryNames "FileDirectory default fileAndDirectoryNames" + ^ self entries collect: [ : entry | entry name ]! - - ^ self entries collect: [:entry | entry first] - ! Item was added: + ----- Method: DirectoryEntryFile>>readWriteStream (in category 'stream access') ----- + readWriteStream + "Answer a FileStream on my contents that can be read and written." + ^ directory fileNamed: self name! Item was changed: ----- Method: AcornFileDirectory>>directoryContentsFor: (in category 'private') ----- directoryContentsFor: fullPath "Return a collection of directory entries for the files and directories in the directory with the given path. See primLookupEntryIn:index: for further details." "FileDirectory default directoryContentsFor: ''" | entries extraPath | entries := super directoryContentsFor: fullPath. fullPath isNullPath ifTrue: [ "For Acorn we also make sure that at least the parent of the current dir is added - sometimes this is in a filing system that has not been (or cannot be) polled for disc root names" extraPath := self class default containingDirectory. "Only add the extra path if we haven't already got the root of the current dir in the list" entries detect: [:ent | extraPath fullName beginsWith: ent name] ifNone: [entries := entries + copyWith: (DirectoryEntryDirectory + directory: self - copyWith: (DirectoryEntry name: extraPath fullName creationTime: 0 modificationTime: 0 - isDirectory: true fileSize: 0)]]. ^ entries ! Item was added: + DirectoryEntry subclass: #DirectoryEntryDirectory + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'Files-Directories'! + + !DirectoryEntryDirectory commentStamp: 'cmm 9/13/2007 12:24' prior: 0! + an entry in a directory; a reference to a directory.! Item was added: + ----- Method: DirectoryEntryFile>>contentsTo: (in category 'stream access') ----- + contentsTo: endPosition + "Answer my contents up to endPosition." + ^ self + contentsFrom: 0 + to: endPosition! Item was added: + ----- Method: FileDirectory>>/ (in category 'path access') ----- + / aString + "Answer a FileDirectory on a subdirectory named aString, of the receiver." + ^ FileDirectory on: (self fullNameFor: aString)! Item was added: + ----- Method: DirectoryEntryDirectory>>isDirectory (in category 'testing') ----- + isDirectory + "whether this entry represents a directory, it does." + ^ true! Item was changed: ----- Method: FileDirectory>>entryAt:ifAbsent: (in category 'file status') ----- entryAt: fileName ifAbsent: aBlock "Find the entry with local name fileName and answer it. If not found, answer the result of evaluating aBlock." - | comparisonBlock | self isCaseSensitive + ifTrue: [comparisonBlock := [:entry | entry name = fileName]] + ifFalse: [comparisonBlock := [:entry | entry name sameAs: fileName]]. - ifTrue: [comparisonBlock := [:entry | (entry at: 1) = fileName]] - ifFalse: [comparisonBlock := [:entry | (entry at: 1) sameAs: fileName]]. ^ self entries detect: comparisonBlock ifNone: [aBlock value]! Item was removed: - ----- Method: DirectoryEntry>>privateName:creationTime:modificationTime:isDirectory:fileSize: (in category 'private-initialization') ----- - privateName: name0 creationTime: creationTime0 modificationTime: modificationTime0 isDirectory: isDirectory0 fileSize: fileSize0 - name := name0. - creationTime := creationTime0. - modificationTime := modificationTime0. - dirFlag := isDirectory0. - fileSize := fileSize0.! Item was removed: - ----- Method: DirectoryEntry class>>fromArray: (in category 'instance creation') ----- - fromArray: array - ^self name: (array at: 1) creationTime: (array at: 2) modificationTime: (array at: 3) isDirectory: (array at: 4) fileSize: (array at: 5) ! Item was removed: - ----- Method: DirectoryEntry>>size (in category 'access-compatibility') ----- - size - ^5! |
Free forum by Nabble | Edit this page |