SystemOrganization addCategory: #'Filesystem-Core'! SystemOrganization addCategory: #'Filesystem-Resolvers'! SystemOrganization addCategory: #'Filesystem-Disk'! SystemOrganization addCategory: #'Filesystem-Memory'! SystemOrganization addCategory: #'Filesystem-Streams'! SystemOrganization addCategory: #'Filesystem-Tests'! SystemOrganization addCategory: #'Filesystem-Zip'! !String methodsFor: '*filesystem-converting' stamp: 'cwp 10/10/2009 18:05'! asPathWith: anObject ^ anObject stringToPath: self! ! !String methodsFor: '*filesystem-converting' stamp: 'cwp 10/10/2009 17:29'! asResolvedBy: anObject ^ anObject resolveString: self! ! Object subclass: #FSFilePluginPrims instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Disk'! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:26'! atEnd: id "Answer true if the file position is at the end of the file." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:27'! close: id "Close this file." ! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:20'! createDirectory: fullPath "Create a directory named by the given path. Fail if the path is bad or if a file or directory by that name already exists." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:21'! deleteDirectory: fullPath "Delete the directory named by the given path. Fail if the path is bad or if a directory by that name does not exist." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:22'! deleteFile: aFileName "Delete the file of the given name. Return self if the primitive succeeds, nil otherwise." ^ nil ! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 10/11/2009 11:02'! delimiter "Return the path delimiter for the underlying platform's file system." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:27'! flush: id "Flush pending changes to the disk" | p | "In some OS's seeking to 0 and back will do a flush" p := self position. self position: 0; position: p! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:23'! getMacFile: fileName type: typeString creator: creatorString "Get the Macintosh file type and creator info for the file with the given name. Fails if the file does not exist or if the type and creator type arguments are not strings of length 4. This primitive is Mac specific; it is a noop on other platforms." ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:27'! getPosition: id "Get this files current position." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 10/11/2009 11:02'! imageFile "Answer the full path name for the current image." self primitiveFailed! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:24'! lookupEntryIn: fullPath index: index "Look up the index-th entry of the directory with the given fully-qualified path (i.e., starting from the root of the file hierarchy) and return an array containing: The empty string enumerates the top-level files or drives. (For example, on Unix, the empty path enumerates the contents of '/'. On Macs and PCs, it enumerates the mounted volumes/drives.) The creation and modification times are in seconds since the start of the Smalltalk time epoch. DirFlag is true if the entry is a directory. FileSize the file size in bytes or zero for directories. The primitive returns nil when index is past the end of the directory. It fails if the given path is bad." ^ #badDirectoryPath ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:27'! open: fileName writable: writableFlag "Open a file of the given name, and return the file ID obtained. If writableFlag is true, then if there is none with this name, then create one else prepare to overwrite the existing from the beginning otherwise if the file exists, open it read-only else return nil" ^ nil ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:28'! read: id into: byteArray startingAt: startIndex count: count "Read up to count bytes of data from this file into the given string or byte array starting at the given index. Answer the number of bytes actually read." self primitiveFailed! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:24'! rename: oldFileFullName to: newFileFullName "Rename the file of the given name to the new name. Fail if there is no file of the old name or if there is an existing file with the new name." ^nil! ! !FSFilePluginPrims methodsFor: 'path primitives' stamp: 'cwp 7/20/2009 17:25'! setMacFileNamed: fileName type: typeString creator: creatorString "Set the Macintosh file type and creator info for the file with the given name. Fails if the file does not exist or if the type and creator type arguments are not strings of length 4. This primitive is Mac specific; it is a noop on other platforms." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:30'! setPosition: id to: anInteger "Set this file to the given position." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:30'! size: id "Answer the size of this file." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/22/2009 07:10'! sizeOrNil: id "Answer the size of this file." ^ nil! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:33'! truncate: id to: anInteger "Truncate this file to the given position." self primitiveFailed ! ! !FSFilePluginPrims methodsFor: 'file primitives' stamp: 'cwp 7/20/2009 17:33'! write: id from: stringOrByteArray startingAt: startIndex count: count "Write count bytes onto this file from the given string or byte array starting at the given index. Answer the number of bytes written." self primitiveFailed! ! Object subclass: #FSFilesystem instanceVariableNames: 'workingDirectory' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Core'! FSFilesystem subclass: #FSDiskFilesystem instanceVariableNames: '' classVariableNames: 'Primitives' poolDictionaries: '' category: 'Filesystem-Disk'! FSDiskFilesystem class instanceVariableNames: 'default'! FSDiskFilesystem class instanceVariableNames: 'default'! !FSDiskFilesystem classSide methodsFor: 'accessing' stamp: 'cwp 9/22/2009 09:41'! / anObject ^ self current root / anObject! ! !FSDiskFilesystem classSide methodsFor: 'instance creation' stamp: 'cwp 10/10/2009 18:25'! createDefault ^ self new! ! !FSDiskFilesystem classSide methodsFor: 'instance creation' stamp: 'cwp 10/10/2009 18:22'! current ^ self currentClass default! ! !FSDiskFilesystem classSide methodsFor: 'instance creation' stamp: 'cwp 10/11/2009 12:02'! currentClass ^ SmalltalkImage current platformName = 'Win32' ifTrue: [FSWindowsFilesystem] ifFalse: [FSUnixFilesystem]! ! !FSDiskFilesystem classSide methodsFor: 'instance creation' stamp: 'cwp 10/10/2009 18:25'! default ^ default ifNil: [default := self createDefault]! ! !FSDiskFilesystem classSide methodsFor: 'references' stamp: 'cwp 10/11/2009 20:13'! imageDirectory ^ self imageFile parent! ! !FSDiskFilesystem classSide methodsFor: 'references' stamp: 'cwp 10/11/2009 20:21'! imageFile ^ self current stringToReference: Primitives imageFile! ! !FSDiskFilesystem classSide methodsFor: 'initialize-release' stamp: 'cwp 7/20/2009 17:46'! initialize self useFilePlugin! ! !FSDiskFilesystem classSide methodsFor: 'accessing' stamp: 'cwp 10/11/2009 11:11'! root ^ self current root! ! !FSDiskFilesystem classSide methodsFor: 'initialize-release' stamp: 'cwp 7/20/2009 17:39'! useFilePlugin Primitives := FSFilePluginPrims new! ! !FSDiskFilesystem classSide methodsFor: 'references' stamp: 'cwp 10/26/2009 11:22'! vmDirectory ^ self vmFile parent! ! !FSDiskFilesystem classSide methodsFor: 'references' stamp: 'cwp 10/26/2009 11:22'! vmFile ^ self current stringToReference: (SmalltalkImage current getSystemAttribute: 0)! ! !FSDiskFilesystem methodsFor: 'comparing' stamp: 'cwp 7/24/2009 00:41'! = other ^ self species = other species! ! !FSDiskFilesystem methodsFor: 'private' stamp: 'cwp 7/18/2009 01:26'! basicIsDirectory: anEntry ^ anEntry at: 4! ! !FSDiskFilesystem methodsFor: 'private' stamp: 'cwp 7/18/2009 01:29'! basicIsFile: anEntry ^ (anEntry at: 4) not! ! !FSDiskFilesystem methodsFor: 'public' stamp: 'cwp 7/22/2009 22:30'! basicOpen: aPath writable: aBoolean ^ Primitives open: (self pathToString: aPath) writable: aBoolean! ! !FSDiskFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 17:33'! createDirectory: anObject | parent path | path := self resolve: anObject. parent := path parent. (self isDirectory: parent) ifFalse: [self createDirectory: parent]. Primitives createDirectory: (self pathToString: path)! ! !FSDiskFilesystem methodsFor: 'public' stamp: 'cwp 7/20/2009 17:48'! delete: anObject | path pathString | path := self resolve: anObject. pathString := self pathToString: path. (self isDirectory: path) ifTrue: [Primitives deleteDirectory: (self pathToString: path)] ifFalse: [StandardFileStream retryWithGC:[Primitives deleteFile: pathString] until: [:result | result notNil] forFileNamed: pathString]! ! !FSDiskFilesystem methodsFor: 'private' stamp: 'cwp 7/20/2009 17:46'! directoryAt: aPath ifAbsent: absentBlock entriesDo: aBlock | index pathString entry | index := 1. pathString := self pathToString: aPath. entry := Primitives lookupEntryIn: pathString index: index. entry = #badDirectoryPath ifTrue: [ ^ absentBlock value ]. [entry isNil] whileFalse: [aBlock value: entry. index := index + 1. entry := Primitives lookupEntryIn: pathString index: index]! ! !FSDiskFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 17:33'! entriesAt: anObject | path | path := self resolve: anObject. ^ Array streamContents: [:out | self directoryAt: path ifAbsent: [self invalidDirectory: path] entriesDo: [:entry | out nextPut: (self referenceTo: path / entry first)]]! ! !FSDiskFilesystem methodsFor: 'private' stamp: 'cwp 10/10/2009 00:35'! entryAt: aPath ifPresent: presentBlock ifAbsent: absentBlock | name | aPath isRoot ifTrue: [^ presentBlock value: self rootEntry]. name := aPath basename. self directoryAt: aPath parent ifAbsent: absentBlock entriesDo: [ :entry | (self entryName: (entry at: 1) matches: name) ifTrue: [ ^ presentBlock value: entry ] ]. ^ absentBlock value! ! !FSDiskFilesystem methodsFor: 'comparing' stamp: 'cwp 7/24/2009 00:41'! hash ^ self species hash! ! !FSDiskFilesystem methodsFor: 'public' stamp: 'cwp 10/11/2009 21:21'! open: anObject writable: aBoolean | path | path := self resolve: anObject. ^ FSFileHandle open: (FSReference filesystem: self path: path) writable: aBoolean ! ! !FSDiskFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 17:34'! openFileStream: anObject writable: aBoolean | fullPath | fullPath := self pathToString: (self resolve: anObject). ^ StandardFileStream new open: fullPath forWrite: aBoolean! ! !FSDiskFilesystem methodsFor: 'private' stamp: 'cwp 10/10/2009 00:41'! rootEntry ^ #('' 0 0 true 0)! ! FSDiskFilesystem subclass: #FSUnixFilesystem instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Disk'! !FSUnixFilesystem methodsFor: 'public' stamp: 'cwp 1/13/2009 21:35'! delimiter ^ $/! ! !FSUnixFilesystem methodsFor: 'private' stamp: 'cwp 10/11/2009 22:33'! forReferencePrintOn: aStream ! ! !FSUnixFilesystem methodsFor: 'private' stamp: 'cwp 10/11/2009 22:28'! initialize workingDirectory := (self stringToPath: Primitives imageFile) parent! ! FSDiskFilesystem subclass: #FSWindowsFilesystem instanceVariableNames: 'disk' classVariableNames: 'Disks' poolDictionaries: '' category: 'Filesystem-Disk'! !FSWindowsFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 10/11/2009 12:52'! createDefault ^ self newForDisk: 'C'! ! !FSWindowsFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 10/11/2009 12:51'! disk: aString ^ Disks at: aString! ! !FSWindowsFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 10/11/2009 12:51'! disks ^ Disks values! ! !FSWindowsFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 10/11/2009 12:52'! initializeDisks | index entry letter | Disks := Dictionary new. index := 1. entry := Primitives lookupEntryIn: '' index: index. [ entry isNil ] whileFalse: [ letter := entry first allButLast. Disks at: letter put: (self newForDisk: letter). index := index + 1. entry := Primitives lookupEntryIn: '' index: index ]! ! !FSWindowsFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 10/11/2009 12:52'! newForDisk: aString ^ self new setDisk: aString! ! !FSWindowsFilesystem methodsFor: 'public' stamp: 'cwp 7/17/2009 19:19'! delimiter ^ $\! ! !FSWindowsFilesystem methodsFor: 'printing' stamp: 'cwp 10/11/2009 22:33'! forReferencePrintOn: aStream aStream nextPutAll: disk; nextPut: $:! ! !FSWindowsFilesystem methodsFor: 'converting' stamp: 'cwp 10/11/2009 12:49'! pathToString: aPath ^ String streamContents: [ :out | out nextPutAll: disk; nextPut: $:. aPath printOn: out delimiter: self delimiter ]! ! !FSWindowsFilesystem methodsFor: 'printing' stamp: 'cwp 10/11/2009 12:49'! printOn: aStream aStream nextPutAll: disk. aStream nextPut: $:! ! !FSWindowsFilesystem methodsFor: 'initialize-release' stamp: 'cwp 10/11/2009 22:20'! setDisk: aString | pathString | disk := aString. pathString := Primitives imageFile. (pathString first: 1) = disk ifTrue: [workingDirectory := (self stringToPath: pathString) parent] ifFalse: [workingDirectory := FSPath root]! ! !FSWindowsFilesystem methodsFor: 'converting' stamp: 'cwp 10/11/2009 16:36'! stringToPath: aString | in | in := aString readStream. (aString at: 2) = $: ifTrue: [in skip: 2]. ^ FSPath readFrom: in delimiter: self delimiter! ! !FSWindowsFilesystem methodsFor: 'converting' stamp: 'cwp 10/11/2009 21:01'! stringToReference: aString | in fs letter | in := aString readStream. (aString at: 2) = $: ifFalse: [fs := self] ifTrue: [letter := in next: 1. in skip: 1. fs := Disks at: letter ifAbsentPut: [self class newForDisk: letter]]. ^ FSReference filesystem: fs path: (FSPath readFrom: in delimiter: self delimiter) ! ! !FSFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 9/22/2009 09:41'! / anObject ^ self new root / anObject! ! !FSFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 09:47'! basicCopy: source ifAbsent: aBlock to: destination ifPresent: pBlock | in out buffer | [in := self readStreamOn: source. in ifNil: [aBlock value]. (self exists: destination) ifTrue: pBlock. out := self writeStreamOn: destination. buffer := ByteArray new: 1024. [in atEnd] whileFalse: [buffer := in nextInto: buffer. out nextPutAll: buffer]] ensure: [in ifNotNil: [in close]. out ifNotNil: [out close]]! ! !FSFilesystem methodsFor: 'accessing' stamp: 'cwp 7/18/2009 00:53'! changeDirectory: aPath self workingDirectory: (self resolve: aPath)! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 9/21/2009 15:18'! close "Some kinds of filesystems need to open connections to external resources"! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 17:34'! copy: sourcePath ifAbsent: aBlock to: destPath ifPresent: pBlock | source destination | source := self resolve: sourcePath. destination := self resolve: destPath. self basicCopy: source ifAbsent: aBlock to: destination ifPresent: pBlock! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/24/2009 00:27'! copy: sourcePath to: destPath self copy: sourcePath ifAbsent: [self fileDoesNotExist: sourcePath] to: destPath ifPresent: [self fileExists: destPath]! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/18/2009 01:15'! createDirectory: aPath self subclassResponsibility! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/20/2009 08:39'! delete: aPath self subclassResponsibility ! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/17/2009 19:20'! delimiter self subclassResponsibility! ! !FSFilesystem methodsFor: 'private' stamp: 'cwp 7/17/2009 19:20'! directoryAt: aPath ifAbsent: absentBlock entriesDo: aBlock self subclassResponsibility! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/17/2009 19:22'! ensureDirectory: aPath (self isDirectory: aPath) ifFalse: [self createDirectory: aPath]! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/8/2009 23:49'! entriesAt: anObject self subclassResponsibility! ! !FSFilesystem methodsFor: 'private' stamp: 'cwp 7/17/2009 19:20'! entryAt: aPath ifPresent: presentBlock ifAbsent: absentBlock self subclassResponsibility! ! !FSFilesystem methodsFor: 'private' stamp: 'cwp 7/17/2009 19:24'! entryName: aByteString matches: aByteString2 ^ aByteString = aByteString2! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 00:34'! exists: anObject | path | path := self resolve: anObject. self entryAt: path ifPresent: [ :entry | ^ true ] ifAbsent: [ ^ false ]! ! !FSFilesystem methodsFor: 'error handling' stamp: 'cwp 7/24/2009 00:26'! fileDoesNotExist: path ^ (FileDoesNotExistException fileName: path asString) signal! ! !FSFilesystem methodsFor: 'error handling' stamp: 'cwp 7/24/2009 00:27'! fileExists: path ^ (FileExistsException fileName: path asString) signal! ! !FSFilesystem methodsFor: 'printing' stamp: 'cwp 7/17/2009 19:20'! forReferencePrintOn: aStream self subclassResponsibility! ! !FSFilesystem methodsFor: 'initialize-release' stamp: 'cwp 7/18/2009 00:54'! initialize workingDirectory := FSPath root! ! !FSFilesystem methodsFor: 'error handling' stamp: 'cwp 8/29/2009 10:20'! invalidDirectory: path ^ (InvalidDirectoryError pathName: (self pathToString: path)) signal! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 17:38'! isDirectory: anObject | path | path := self resolve: anObject. path isRoot ifTrue: [^ true]. self entryAt: path ifPresent: [ :entry | ^ self basicIsDirectory: entry ] ifAbsent: [ ^ false ]! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 00:31'! isFile: anObject | path | path := self resolve: anObject. self entryAt: path ifPresent: [ :entry | ^ self basicIsFile: entry ] ifAbsent: [ ^ false ]! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 9/21/2009 15:17'! open "Some kinds of filesystems need to open connections to external resources"! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/22/2009 08:21'! open: aPath writable: aBoolean self subclassResponsibility! ! !FSFilesystem methodsFor: 'converting' stamp: 'cwp 7/17/2009 19:24'! pathToString: aPath ^ aPath printWithDelimiter: self delimiter! ! !FSFilesystem methodsFor: 'printing' stamp: 'cwp 7/17/2009 19:21'! printPath: aPath on: aStream aPath printOn: aStream delimiter: self delimiter! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/31/2009 00:26'! readStreamOn: anObject ^ (self open: anObject writable: false) readStream.! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 18:03'! referenceTo: anObject ^ FSReference filesystem: self path: (self toPath: anObject)! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 10/10/2009 17:28'! resolve: anObject ^ anObject asResolvedBy: self! ! !FSFilesystem methodsFor: 'navigating' stamp: 'cwp 10/10/2009 17:29'! resolvePath: aPath ^ workingDirectory resolve: aPath! ! !FSFilesystem methodsFor: 'navigating' stamp: 'cwp 10/10/2009 17:32'! resolveReference: aReference ^ aReference filesystem = self ifTrue: [workingDirectory resolvePath: aReference path]! ! !FSFilesystem methodsFor: 'navigating' stamp: 'cwp 10/10/2009 17:32'! resolveString: aString ^ workingDirectory resolvePath: (self stringToPath: aString)! ! !FSFilesystem methodsFor: 'accessing' stamp: 'cwp 9/20/2009 22:27'! root ^ self referenceTo: FSPath root! ! !FSFilesystem methodsFor: 'converting' stamp: 'cwp 10/11/2009 16:38'! stringToPath: aString ^ FSPath readFrom: aString readStream delimiter: self delimiter! ! !FSFilesystem methodsFor: 'converting' stamp: 'cwp 10/11/2009 21:41'! stringToReference: aString ^ FSReference filesystem: self path: (self stringToPath: aString)! ! !FSFilesystem methodsFor: 'converting' stamp: 'cwp 10/10/2009 18:04'! toPath: anObject ^ anObject asPathWith: self! ! !FSFilesystem methodsFor: 'accessing' stamp: 'cwp 7/18/2009 00:53'! workingDirectory ^ workingDirectory! ! !FSFilesystem methodsFor: 'accessing' stamp: 'cwp 7/18/2009 00:59'! workingDirectory: aPath aPath isAbsolute ifFalse: [self error: 'Cannot set the working directory to a relative path']. workingDirectory := aPath! ! !FSFilesystem methodsFor: 'public' stamp: 'cwp 7/28/2009 22:59'! writeStreamOn: anObject ^ (self open: anObject writable: true) writeStream.! ! FSFilesystem subclass: #FSMemoryFilesystem instanceVariableNames: 'root' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Memory'! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/24/2009 00:37'! basicCopy: source ifAbsent: aBlock to: destination ifPresent: pBlock self entryAt: source ifPresent: [:bytes | (self basicIsFile: bytes) ifFalse: aBlock. self entryAt: destination parent ifPresent: [:dict | (self basicIsDirectory: dict) ifFalse: [self invalidDirectory: destination parent]. (dict includesKey: destination basename) ifTrue: pBlock. dict at: destination basename put: bytes copy] ifAbsent: [self invalidDirectory: destination parent]] ifAbsent: aBlock! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/18/2009 01:31'! basicIsDirectory: entry ^ entry isDictionary! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/18/2009 01:31'! basicIsFile: entry ^ entry isDictionary not! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/26/2009 13:14'! basicOpen: anObject writable: aBoolean | path | path := self resolve: anObject. ^ self entryAt: path ifPresent: [:bytes | bytes] ifAbsent: [aBoolean ifFalse: [self fileDoesNotExist: path] ifTrue: [self createFile: path]]! ! !FSMemoryFilesystem methodsFor: 'public' stamp: 'cwp 7/18/2009 01:22'! createDirectory: anObject | parent path | path := self resolve: anObject. parent := path parent. self entryAt: parent ifPresent: [:dict | dict at: path basename put: Dictionary new] ifAbsent: [self createDirectory: parent. self createDirectory: path]! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/26/2009 13:13'! createFile: path ^ self entryAt: path parent ifPresent: [ :dict | (self basicIsDirectory: dict) ifTrue: [ dict at: path basename put: ByteArray new ] ] ifAbsent: [ self invalidDirectory: path parent ]! ! !FSMemoryFilesystem methodsFor: 'public' stamp: 'cwp 7/18/2009 01:24'! delete: anObject | path | path := self resolve: anObject. self entryAt: path parent ifPresent: [:dict | dict removeKey: path basename] ifAbsent: []! ! !FSMemoryFilesystem methodsFor: 'public' stamp: 'cwp 7/17/2009 19:29'! delimiter ^ $/! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 8/29/2009 10:21'! directoryAt: aPath ifAbsent: absentBlock entriesDo: aBlock self entryAt: aPath ifPresent: [:directory | directory isDictionary ifFalse: [^ absentBlock value]. directory keysAndValuesDo: [:name :entry | aBlock value: name -> entry]] ifAbsent: aBlock! ! !FSMemoryFilesystem methodsFor: 'public' stamp: 'cwp 8/23/2009 22:26'! entriesAt: anObject | path entry | path := self resolve: anObject. ^ Array streamContents: [:out | self directoryAt: path ifAbsent: [self invalidDirectory: path] entriesDo: [:association | entry := self referenceTo: path / association key. out nextPut: entry]]! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/17/2009 23:33'! entryAt: aPath ifPresent: presentBlock ifAbsent: absentBlock | current | current := root. aPath do: [:segment | current isDictionary ifTrue: [current := current at: segment ifAbsent: [^ absentBlock value]] ifFalse: [^ absentBlock value]]. ^ presentBlock value: current! ! !FSMemoryFilesystem methodsFor: 'printing' stamp: 'cwp 10/11/2009 22:37'! forReferencePrintOn: aStream aStream nextPutAll: 'memory:'! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/19/2009 22:12'! growFile: anObject to: anInteger ^ self replaceFile: anObject in: [:bytes | (bytes class new: anInteger) replaceFrom: 1 to: bytes size with: bytes startingAt: 1; yourself]! ! !FSMemoryFilesystem methodsFor: 'initialize-release' stamp: 'cwp 7/18/2009 01:11'! initialize super initialize. root := Dictionary new! ! !FSMemoryFilesystem methodsFor: 'public' stamp: 'cwp 8/29/2009 10:15'! open: anObject writable: aBoolean | path | path := self resolve: anObject. ^ FSMemoryHandle open: (self referenceTo: path) writable: aBoolean ! ! !FSMemoryFilesystem methodsFor: 'public' stamp: 'cwp 7/26/2009 13:13'! openFileStream: aPath writable: aBoolean | path bytes | path := self resolve: aPath. bytes := self entryAt: path ifPresent: [ :array | array ] ifAbsent: [ self createFile: path ]. ^ FSMemoryFileStream on: bytes filesystem: self path: path! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 10/10/2009 17:44'! replaceFile: anObject in: aBlock | path | path := self resolve: anObject. ^ self entryAt: path parent ifPresent: [:dict || old new | (self basicIsDirectory: dict) ifFalse: [self fileDoesNotExist: path]. old := dict at: path basename ifAbsent: [self fileDoesNotExist: path]. new := aBlock value: old. dict at: path basename put: new] ifAbsent: [self fileDoesNotExist: path]! ! !FSMemoryFilesystem methodsFor: 'private' stamp: 'cwp 7/19/2009 22:13'! truncateFile: anObject to: anInteger ^ self replaceFile: anObject in: [ :bytes | bytes first: anInteger ]! ! FSFilesystem subclass: #FSZipFilesystem instanceVariableNames: 'reference archive directories' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Zip'! !FSZipFilesystem classSide methodsFor: 'as yet unclassified' stamp: 'cwp 9/21/2009 15:12'! atReference: aReference ^ self new setReference: aReference! ! !FSZipFilesystem methodsFor: 'accessing' stamp: 'cwp 9/20/2009 23:38'! archive ^ archive! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 8/30/2009 13:54'! basicCopy: source ifAbsent: aBlock to: destination ifPresent: pBlock | destname copy | self entryAt: source ifPresent: [:smember | destname := self pathToString: destination. copy := self copyFile: smember as: destname. self entryAt: destination ifPresent: [:dmember | pBlock value ] ifAbsent: [archive addMember: copy]] ifAbsent: aBlock! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 13:12'! basicIsDirectory: aPath ^ directories includes: aPath! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 13:31'! basicIsFile: anObject ^ (anObject isKindOf: ArchiveMember) and: [anObject isDirectory not]! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 8/30/2009 13:23'! basicOpen: anObject writable: aBoolean | path stream | path := self resolve: anObject. ^ self entryAt: path ifPresent: [:member | stream := RWBinaryOrTextStream on: (ByteArray new: member uncompressedSize). member extractTo: stream. stream binary; contents] ifAbsent: [aBoolean ifFalse: [self fileDoesNotExist: path] ifTrue: [self createFile: path]]! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 9/21/2009 15:20'! close archive writeToFileNamed: reference pathString. archive close. archive := nil! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 8/30/2009 15:39'! copyFile: aZipMember as: aString ^ aZipMember class newFromString: aZipMember contents named: aString! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 9/22/2009 13:10'! createDirectory: anObject directories add: (self resolve: anObject) ! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/21/2009 18:22'! createFile: aPath archive addDeflateString: '' as: (self pathToString: aPath). ^ ByteArray new! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 9/22/2009 13:40'! delete: anObject | path | path := self resolve: anObject. (directories includes: path) ifTrue: [directories remove: path] ifFalse: [self entryAt: path ifPresent: [:member | archive removeMember: member] ifAbsent: []]! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 8/29/2009 11:36'! delimiter ^ $/! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 14:47'! directoriesAt: aPath | paths | paths := directories select: [:ea | ea size = (aPath size + 1) and: [aPath contains: ea]]. ^ paths collect: [:ea | self referenceTo: ea] ! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 10/10/2009 00:42'! directoryAt: aPath ifPresent: presentBlock ifAbsent: absentBlock ^ (aPath isRoot or: [directories includes: aPath]) ifTrue: presentBlock ifFalse: absentBlock! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 9/22/2009 14:44'! entriesAt: anObject | path | path := self resolve: anObject. ^ (self filesAt: path) addAll: (self directoriesAt: path)! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 13:43'! entryAt: aPath ifPresent: presentBlock ifAbsent: absentBlock | name | ^ self directoryAt: aPath ifPresent: [ presentBlock value: aPath ] ifAbsent: [ name := self pathToString: aPath. (archive memberNamed: name) ifNotNil: [ presentBlock value: (archive memberNamed: name) ] ifNil: absentBlock ]! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 10/10/2009 17:57'! filesAt: aPath | all | all := archive members collect: [:ea | self stringToPath: ea fileName]. all := all select: [:ea | ea size = (aPath size + 1) and: [aPath contains: ea]]. ^ all collect: [:ea | self referenceTo: ea] ! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 10/11/2009 22:38'! forReferencePrintOn: aStream aStream nextPutAll: 'zip:'! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 23:31'! initializeArchive (archive members select: [ :ea | ea isDirectory ]) do: [ :ea | directories add: (self pathFromMember: ea). archive removeMember: ea ]. archive members do: [ :ea | directories add: (self pathFromMember: ea) parent ]! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 13:41'! memberAt: aPath ifPresent: presentBlock ifAbsent: absentBlock | name | name := self pathToString: aPath. ^ (archive memberNamed: name) ifNotNil: [ presentBlock value: (archive memberNamed: name) ] ifNil: absentBlock! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 9/22/2009 23:21'! open archive := ZipArchive new. reference exists ifTrue: [reference fileStreamDo: [:in | archive readFrom: in]. self initializeArchive]! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 8/30/2009 10:28'! open: anObject writable: aBoolean | path | path := self resolve: anObject. ^ FSZipHandle open: (self referenceTo: path) writable: aBoolean ! ! !FSZipFilesystem methodsFor: 'public' stamp: 'cwp 9/21/2009 22:47'! openFileStream: anObject writable: aBoolean | path member name | path := self resolve: anObject. member := self entryAt: path ifPresent: [:entry | entry] ifAbsent: [name := self pathToString: path. archive addDeflateString: '' as: name]. ^ FSZipFileStream on: member contents filesystem: self path: path! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/22/2009 23:29'! pathFromMember: anArchiveMember | path | path := FSPath root resolve: anArchiveMember fileName. ^ path basename isEmpty ifTrue: [path parent] ifFalse: [path]! ! !FSZipFilesystem methodsFor: 'accessing' stamp: 'cwp 9/21/2009 17:48'! reference ^ reference! ! !FSZipFilesystem methodsFor: 'private' stamp: 'cwp 9/21/2009 18:22'! setFile: aPath to: bytes | path | path := self resolve: aPath. self entryAt: path ifPresent: [:member | (archive member: member) contents: bytes] ifAbsent: [ archive addDeflateString: bytes as: (self pathToString: path) ]! ! !FSZipFilesystem methodsFor: 'initialize-release' stamp: 'cwp 9/22/2009 13:10'! setReference: aReference directories := Set new. reference := aReference.! ! Object subclass: #FSHandle instanceVariableNames: 'reference writable' classVariableNames: 'Primitives' poolDictionaries: '' category: 'Filesystem-Core'! FSHandle subclass: #FSFileHandle instanceVariableNames: 'id' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Disk'! !FSFileHandle classSide methodsFor: 'class initialization' stamp: 'cwp 7/22/2009 07:11'! initialize self useFilePlugin! ! !FSFileHandle classSide methodsFor: 'class initialization' stamp: 'cwp 7/22/2009 07:11'! useFilePlugin Primitives := FSFilePluginPrims new! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 7/31/2009 00:05'! at: index read: buffer startingAt: start count: count ^ Primitives setPosition: id to: index - 1; read: id into: buffer startingAt: start count: count ! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 14:15'! at: index write: buffer startingAt: start count: count Primitives setPosition: id to: index - 1; write: id from: buffer startingAt: start count: count ! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 7/22/2009 07:12'! close Primitives close: id! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 7/22/2009 07:49'! flush Primitives flush: id! ! !FSFileHandle methodsFor: 'testing' stamp: 'cwp 7/22/2009 07:10'! isOpen ^ (Primitives sizeOrNil: id) notNil! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 9/21/2009 23:07'! open id := reference filesystem basicOpen: reference path writable: writable. id ifNil: [(writable or: [reference exists]) ifTrue: [self error: 'Unable to open file ', reference printString] ifFalse: [(FileDoesNotExistException fileName: reference path) signal]]! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 7/22/2009 07:44'! size ^ Primitives size: id! ! !FSFileHandle methodsFor: 'public' stamp: 'cwp 7/22/2009 08:17'! truncateTo: anInteger Primitives truncate: id to: anInteger. self reopen! ! !FSHandle classSide methodsFor: 'instance creation' stamp: 'cwp 7/26/2009 12:52'! on: aReference writable: aBoolean ^ self new setReference: aReference writable: aBoolean! ! !FSHandle classSide methodsFor: 'instance creation' stamp: 'cwp 7/26/2009 12:52'! open: aReference writable: aBoolean ^ (self on: aReference writable: aBoolean) open! ! !FSHandle classSide methodsFor: 'class initialization' stamp: 'cwp 7/26/2009 12:50'! useFilePlugin self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/29/2009 22:19'! at: index | buffer | buffer := ByteArray new: 1. self at: index read: buffer startingAt: 1 count: 1. ^ buffer at: 1! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/29/2009 22:19'! at: index put: anObject | buffer | buffer := ByteArray with: anObject. self at: index write: buffer startingAt: 1 count: 1. ! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:50'! at: offset read: buffer startingAt: start count: count self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:50'! at: offset write: buffer startingAt: start count: count self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:50'! close self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:50'! flush self subclassResponsibility! ! !FSHandle methodsFor: 'testing' stamp: 'cwp 7/26/2009 12:50'! isOpen self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:50'! open self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/31/2009 00:32'! readStream ^ self isOpen ifTrue: [FSReadStream onHandle: self]! ! !FSHandle methodsFor: 'accessing' stamp: 'cwp 7/26/2009 12:51'! reference ^ reference! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:51'! reopen self close. self open! ! !FSHandle methodsFor: 'initialize-release' stamp: 'cwp 7/26/2009 12:51'! setReference: aReference writable: aBoolean reference := aReference. writable := aBoolean! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 12:50'! truncateTo: anInteger self subclassResponsibility! ! !FSHandle methodsFor: 'public' stamp: 'cwp 7/28/2009 23:06'! writeStream ^ FSWriteStream onHandle: self! ! FSHandle subclass: #FSMemoryHandle instanceVariableNames: 'bytes size' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Memory'! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/29/2009 22:07'! at: index ^ bytes at: index! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/31/2009 00:18'! at: index put: anObject index > bytes size ifTrue: [self grow]. bytes at: index put: anObject. size := size max: index! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/31/2009 00:16'! at: index read: aCollection startingAt: start count: count | stop | stop := (start + count - 1) min: (start + size - 1). aCollection replaceFrom: start to: stop with: bytes startingAt: index. ^ stop - start + 1! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/29/2009 22:17'! at: first write: aCollection startingAt: start count: count | last | writable ifFalse: [ self primitiveFailed ]. last := first + count - 1. last > bytes size ifTrue: [self grow]. bytes replaceFrom: first to: last with: aCollection startingAt: start. size := last! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/28/2009 23:10'! close self truncateTo: size. bytes := nil! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/29/2009 22:23'! flush self truncateTo: size! ! !FSMemoryHandle methodsFor: 'private' stamp: 'cwp 8/30/2009 10:29'! grow bytes := reference filesystem growFile: reference path to: self newSize! ! !FSMemoryHandle methodsFor: 'testing' stamp: 'cwp 7/26/2009 14:08'! isOpen ^ bytes notNil! ! !FSMemoryHandle methodsFor: 'private' stamp: 'cwp 8/30/2009 10:29'! newSize ^ (bytes size min: 20) max: 1024! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 14:26'! open bytes := reference filesystem basicOpen: reference path writable: writable. size := bytes size.! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 14:27'! size ^ size! ! !FSMemoryHandle methodsFor: 'public' stamp: 'cwp 7/26/2009 14:29'! truncateTo: anInteger bytes := reference filesystem truncateFile: reference path to: anInteger. size := anInteger! ! FSMemoryHandle subclass: #FSZipHandle instanceVariableNames: 'archive' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Zip'! !FSZipHandle methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 15:37'! close reference filesystem setFile: reference path to: (bytes first: size)! ! !FSZipHandle methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 10:37'! grow | grown | grown := bytes class new: self newSize. grown replaceFrom: 1 to: bytes size with: bytes. bytes := grown! ! Object subclass: #FSLocator instanceVariableNames: 'origin path' classVariableNames: 'Resolver' poolDictionaries: '' category: 'Filesystem-Core'! !FSLocator classSide methodsFor: 'locations' stamp: 'cwp 10/25/2009 09:54'! image ^ self origin: #image ! ! !FSLocator classSide methodsFor: 'class initialization' stamp: 'cwp 10/25/2009 10:01'! initialize ^ self useInteractiveResolver! ! !FSLocator classSide methodsFor: 'instance creation' stamp: 'cwp 10/25/2009 09:55'! origin: aSymbol ^ self origin: aSymbol path: FSPath empty! ! !FSLocator classSide methodsFor: 'instance creation' stamp: 'cwp 10/25/2009 09:56'! origin: aSymbol path: aPath ^ self basicNew initializeWithOrigin: aSymbol path: aPath! ! !FSLocator classSide methodsFor: 'class initialization' stamp: 'cwp 10/25/2009 10:02'! useInteractiveResolver Resolver := FSInteractiveResolver new! ! !FSLocator classSide methodsFor: 'locations' stamp: 'cwp 10/26/2009 11:37'! vmBinary ^ self origin: #vmBinary! ! !FSLocator classSide methodsFor: 'locations' stamp: 'cwp 10/26/2009 13:49'! vmDirectory ^ self origin: #vmDirectory! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 11:12'! , extension ^ self withPath: path, extension! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 11:03'! / aString ^ self withPath: (path / aString)! ! !FSLocator methodsFor: 'comparing' stamp: 'cwp 10/26/2009 10:28'! = other ^ self species = other species and: [origin = other origin and: [path = other path]]! ! !FSLocator methodsFor: 'converting' stamp: 'cwp 10/25/2009 10:30'! asAbsolute ^ self ! ! !FSLocator methodsFor: 'converting' stamp: 'cwp 10/26/2009 02:09'! asPathWith: anObject ^ self resolve asPathWith: anObject! ! !FSLocator methodsFor: 'accessing' stamp: 'cwp 10/25/2009 11:09'! basename ^ self resolve basename! ! !FSLocator methodsFor: 'comparing' stamp: 'cwp 10/25/2009 22:26'! contains: anObject ^ self resolve contains: anObject! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:02'! copyTo: aReference ^ self resolve copyTo: aReference resolve! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:03'! delete ^ self resolve delete! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:03'! ensureDirectory ^ self resolve ensureDirectory! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:03'! entries ^ self resolve entries! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:03'! exists ^ self resolve exists! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:04'! fileStreamDo: aBlock ^ self resolve fileStreamDo: aBlock! ! !FSLocator methodsFor: 'accessing' stamp: 'cwp 10/25/2009 22:12'! filesystem ^ self resolve filesystem! ! !FSLocator methodsFor: 'comparing' stamp: 'cwp 10/25/2009 11:05'! hash ^ origin hash bitXor: path hash! ! !FSLocator methodsFor: 'initialize-release' stamp: 'cwp 10/25/2009 09:56'! initializeWithOrigin: aSymbol path: aPath self initialize. origin := aSymbol. path := aPath.! ! !FSLocator methodsFor: 'testing' stamp: 'cwp 10/25/2009 10:30'! isAbsolute ^ true! ! !FSLocator methodsFor: 'comparing' stamp: 'cwp 10/25/2009 23:05'! isContainedBy: anObject ^ self resolve isContainedBy: anObject! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:04'! isDirectory ^ self resolve isDirectory! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:04'! isFile ^ self resolve isFile! ! !FSLocator methodsFor: 'testing' stamp: 'cwp 10/25/2009 11:15'! isRelative ^ false! ! !FSLocator methodsFor: 'testing' stamp: 'cwp 10/25/2009 11:22'! isRoot ^ self resolve isRoot! ! !FSLocator methodsFor: 'accessing' stamp: 'cwp 10/25/2009 21:31'! origin ^ origin! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 11:27'! parent ^ self withPath: path parent! ! !FSLocator methodsFor: 'accessing' stamp: 'cwp 10/25/2009 21:31'! path ^ path! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:05'! pathString ^ self resolve pathString! ! !FSLocator methodsFor: 'as yet unclassified' stamp: 'cwp 10/26/2009 10:38'! printOn: aStream | fs | fs := self filesystem. aStream nextPut: ${; nextPutAll: origin; nextPut: $}. path isWorkingDirectory ifFalse: [aStream nextPut: fs delimiter. self filesystem printPath: path on: aStream]! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:05'! readStream ^ self resolve readStream! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:05'! readStreamDo: aBlock ^ self resolve readStreamDo: aBlock! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 09:59'! resolve ^ (Resolver resolve: origin) resolve: path! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/26/2009 01:03'! resolve: anObject ^ anObject asResolvedBy: self! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 21:36'! resolvePath: aPath ^ self withPath: (path resolvePath: aPath)! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 21:53'! resolveReference: aReference ^ aReference isAbsolute ifTrue: [aReference] ifFalse: [self withPath: aReference path]! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 22:02'! resolveString: aString | filesystem thePath | filesystem := (Resolver resolve: origin) filesystem. thePath := filesystem stringToPath: aString. ^ self withPath: (path resolvePath: thePath)! ! !FSLocator methodsFor: 'navigating' stamp: 'cwp 10/25/2009 11:03'! withPath: newPath ^ path == newPath ifTrue: [self] ifFalse: [self class origin: origin path: newPath]! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:05'! writeStream ^ self resolve writeStream! ! !FSLocator methodsFor: 'public' stamp: 'cwp 10/26/2009 02:06'! writeStreamDo: aBlock ^ self resolve writeStreamDo: aBlock! ! Object variableSubclass: #FSPath instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Core'! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 12/23/2008 14:15'! / aString ^ self root / aString! ! !FSPath classSide methodsFor: 'private' stamp: 'cwp 10/26/2009 13:42'! addElement: element to: result element = '..' ifTrue: [^ self addParentElementTo: result]. element = '' ifTrue: [^ self addEmptyElementTo: result]. element = '.' ifFalse: [result add: element]! ! !FSPath classSide methodsFor: 'private' stamp: 'cwp 10/26/2009 13:41'! addEmptyElementTo: result result isEmpty ifTrue: [result add: ''] ! ! !FSPath classSide methodsFor: 'private' stamp: 'cwp 10/26/2009 13:39'! addParentElementTo: result result isEmpty ifTrue: [result add: '..'] ifFalse: [result removeLast] ! ! !FSPath classSide methodsFor: 'private' stamp: 'cwp 10/26/2009 13:30'! canonicalizeElements: aCollection | result | result := OrderedCollection new. aCollection do: [:element | self addElement: element to: result]. ^ result! ! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 10/11/2009 13:09'! empty ^ self new! ! !FSPath classSide methodsFor: 'accessing' stamp: 'cwp 12/23/2008 11:23'! extensionDelimiter ^ $.! ! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 10/10/2009 17:51'! parent ^ self with: '..'! ! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 10/11/2009 16:39'! readFrom: aStream delimiter: aCharacter | elements out ch | elements := OrderedCollection new. out := (String new: 10) writeStream. [ aStream atEnd ] whileFalse: [ ch := aStream next. ch = aCharacter ifFalse: [ out nextPut: ch ] ifTrue: [ elements add: out contents. out := (String new: 10) writeStream ] ]. elements add: out contents. ^ FSPath withAll: (self canonicalizeElements: elements)! ! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 10/11/2009 13:04'! root ^ self with: ''! ! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 10/10/2009 17:43'! with: aString | inst | inst := self new: 1. inst at: 1 put: aString. ^ inst! ! !FSPath classSide methodsFor: 'instance creation' stamp: 'cwp 12/13/2008 13:33'! withAll: aCollection | inst | inst := self new: aCollection size. aCollection withIndexDo: [:segment :index | inst at: index put: segment]. ^ inst! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 12/15/2008 14:05'! , extension | base path | base := (self at: self size) copyUpToLast: self extensionDelimiter. path := self copy. path at: self size put: base , '.' , extension. ^ path! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 12/13/2008 21:11'! / aString | path | path := self class new: self size + 1. path copyFrom: self. path at: path size put: aString. ^ path! ! !FSPath methodsFor: 'comparing' stamp: 'cwp 12/14/2008 17:36'! = other ^ self species = other species and: [self size = other size and: [(1 to: self size) allSatisfy: [:i | (self at: i) = (other at: i)]]]! ! !FSPath methodsFor: 'converting' stamp: 'cwp 10/10/2009 18:04'! asPathWith: anObject ^ self! ! !FSPath methodsFor: 'converting' stamp: 'cwp 9/21/2009 22:58'! asReference ^ FSDiskFilesystem current referenceTo: self! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 9/22/2009 09:08'! asResolvedBy: anObject ^ anObject resolvePath: self! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 7/17/2009 05:15'! assureExtension: aString | extension | extension := (aString first = self extensionDelimiter) ifTrue: [aString] ifFalse: [aString copyWithFirst: self extensionDelimiter]. ^ (self basename endsWith: extension) ifTrue: [self] ifFalse: [self copy at: self size put: (self basename, extension); yourself]! ! !FSPath methodsFor: 'accessing' stamp: 'cwp 12/15/2008 14:02'! basename ^ self at: self size! ! !FSPath methodsFor: 'comparing' stamp: 'cwp 10/26/2009 01:03'! contains: anObject ^ anObject isContainedBy: self! ! !FSPath methodsFor: 'comparing' stamp: 'cwp 10/25/2009 22:59'! containsPath: aPath self size < aPath size ifFalse: [^ false]. 1 to: self size do: [:i | (self at: i) = (aPath at: i) ifFalse: [^ false]]. ^ true! ! !FSPath methodsFor: 'comparing' stamp: 'cwp 10/25/2009 23:05'! containsReference: aReference ^ false! ! !FSPath methodsFor: 'private' stamp: 'cwp 12/13/2008 21:08'! copyFrom: aPath | size | size := aPath size min: self size. 1 to: size do: [:i | self at: i put: (aPath at: i)]. ! ! !FSPath methodsFor: 'accessing' stamp: 'cwp 10/11/2009 11:05'! delimiter ^ $/! ! !FSPath methodsFor: 'accessing' stamp: 'cwp 7/18/2009 01:13'! do: aBlock 1 to: self size do: [ :index || segment | segment := self at: index. segment isEmpty ifFalse: [ aBlock value: segment ] ]! ! !FSPath methodsFor: 'accessing' stamp: 'cwp 12/23/2008 11:25'! extensionDelimiter ^ self class extensionDelimiter! ! !FSPath methodsFor: 'comparing' stamp: 'cwp 12/14/2008 17:06'! hash | hash | hash := self class identityHash. 1 to: self size do: [:i | hash := String stringHash: (self at: i) initialHash: hash]. ^ hash! ! !FSPath methodsFor: 'testing' stamp: 'cwp 7/18/2009 01:03'! isAbsolute ^ self size > 0 and: [(self at: 1) = '']! ! !FSPath methodsFor: 'private' stamp: 'cwp 10/25/2009 19:53'! isAllParents 1 to: self size do: [:i | (self at: i) = '..' ifFalse: [^ false]]. ^ true! ! !FSPath methodsFor: 'comparing' stamp: 'cwp 10/25/2009 23:01'! isContainedBy: anObject ^ anObject containsPath: self! ! !FSPath methodsFor: 'testing' stamp: 'cwp 12/13/2008 21:00'! isRelative ^ self isAbsolute not! ! !FSPath methodsFor: 'testing' stamp: 'cwp 7/18/2009 00:41'! isRoot ^ self size = 1 and: [self isAbsolute]! ! !FSPath methodsFor: 'testing' stamp: 'cwp 7/18/2009 00:42'! isWorkingDirectory ^ self size = 0! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 10/25/2009 19:53'! parent | size parent | self isRoot ifTrue: [^ self]. self isAllParents ifTrue: [^ self / '..']. size := self size - 1. parent := self class new: size. 1 to: size do: [:i | parent at: i put: (self at: i)]. ^ parent! ! !FSPath methodsFor: 'printing' stamp: 'cwp 10/11/2009 22:31'! printOn: aStream aStream nextPut: $[. self printOn: aStream delimiter: self delimiter. aStream nextPut: $]! ! !FSPath methodsFor: 'printing' stamp: 'cwp 7/18/2009 01:07'! printOn: aStream delimiter: aCharacter self isRoot ifTrue: [aStream nextPut: $/. ^ self]. self isWorkingDirectory ifTrue: [aStream nextPut: $.. ^ self]. (1 to: self size) do: [:index | aStream nextPutAll: (self at: index)] separatedBy: [aStream nextPut: aCharacter]! ! !FSPath methodsFor: 'printing' stamp: 'cwp 1/13/2009 21:27'! printWithDelimiter: aCharacter ^ String streamContents: [:out | self printOn: out delimiter: aCharacter]! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 10/26/2009 01:03'! resolve: anObject ^ anObject asResolvedBy: self! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 9/22/2009 09:04'! resolvePath: aPath | elements | aPath isAbsolute ifTrue: [^ aPath]. elements := Array new: self size + aPath size. 1 to: self size do: [:i | elements at: i put: (self at: i)]. 1 to: aPath size do: [:i | elements at: self size + i put: (aPath at: i)]. ^ self class withAll: (self class canonicalizeElements: elements)! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 9/22/2009 09:06'! resolveReference: aReference ^ aReference! ! !FSPath methodsFor: 'navigating' stamp: 'cwp 10/25/2009 21:42'! resolveString: aString ^ self / aString! ! Object subclass: #FSReference instanceVariableNames: 'filesystem path' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Core'! !FSReference classSide methodsFor: 'instance creation' stamp: 'cwp 1/13/2009 21:11'! filesystem: aFilesystem path: aPath ^ self new setFilesystem: aFilesystem path: aPath! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 7/20/2009 09:20'! , aString ^ self navigateWith: [path, aString]! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 7/20/2009 09:36'! / anObject ^ self navigateWith: [path / anObject]! ! !FSReference methodsFor: 'comparing' stamp: 'cwp 7/20/2009 09:22'! = other ^ self species = other species and: [self path = other path and: [self filesystem = other filesystem]]! ! !FSReference methodsFor: 'converting' stamp: 'cwp 7/22/2009 08:33'! asAbsolute ^ self isAbsolute ifTrue: [self] ifFalse: [filesystem referenceTo: (filesystem resolve: path)]! ! !FSReference methodsFor: 'converting' stamp: 'cwp 10/10/2009 18:04'! asPathWith: anObject ^ path! ! !FSReference methodsFor: 'converting' stamp: 'cwp 7/20/2009 09:08'! asReference ^ self! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 9/22/2009 09:03'! asResolvedBy: anObject ^ anObject resolveReference: self! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 7/20/2009 09:19'! assureExtension: aString ^ self navigateWith: [path assureExtension: aString]! ! !FSReference methodsFor: 'accessing' stamp: 'cwp 7/20/2009 09:17'! basename ^ path basename! ! !FSReference methodsFor: 'private' stamp: 'cwp 9/22/2009 09:56'! basicCopyTo: aReference | in out buffer | [in := filesystem readStreamOn: (filesystem resolve: path). in ifNil: [filesystem fileDoesNotExist: path]. aReference exists ifTrue: [aReference filesystem fileExists: path]. out := aReference writeStream. buffer := ByteArray new: 1024. [in atEnd] whileFalse: [buffer := in nextInto: buffer. out nextPutAll: buffer]] ensure: [in ifNotNil: [in close]. out ifNotNil: [out close]]! ! !FSReference methodsFor: 'comparing' stamp: 'cwp 10/26/2009 01:03'! contains: anObject ^ anObject isContainedBy: self! ! !FSReference methodsFor: 'comparing' stamp: 'cwp 10/26/2009 00:54'! containsPath: aPath ^ self path containsPath: aPath! ! !FSReference methodsFor: 'comparing' stamp: 'cwp 10/25/2009 23:02'! containsReference: aReference ^ aReference filesystem = filesystem and: [path contains: aReference path]! ! !FSReference methodsFor: 'public' stamp: 'cwp 9/22/2009 09:48'! copyTo: aReference filesystem = aReference filesystem ifTrue: [filesystem copy: path to: aReference path] ifFalse: [self basicCopyTo: aReference]! ! !FSReference methodsFor: 'private' stamp: 'cwp 7/22/2009 06:56'! createHandle ^ filesystem createHandleFor: self! ! !FSReference methodsFor: 'public' stamp: 'cwp 7/22/2009 07:42'! delete filesystem delete: path! ! !FSReference methodsFor: 'public' stamp: 'cwp 1/13/2009 22:04'! ensureDirectory filesystem ensureDirectory: path ! ! !FSReference methodsFor: 'public' stamp: 'cwp 10/8/2009 23:50'! entries ^ filesystem entriesAt: self! ! !FSReference methodsFor: 'public' stamp: 'cwp 1/13/2009 20:52'! exists ^ filesystem exists: path! ! !FSReference methodsFor: 'public' stamp: 'cwp 7/24/2009 00:47'! fileStreamDo: aBlock | stream | [stream := filesystem openFileStream: path writable: true. aBlock value: stream] ensure: [stream ifNotNil: [stream close]] ! ! !FSReference methodsFor: 'accessing' stamp: 'cwp 7/18/2009 22:53'! filesystem ^ filesystem! ! !FSReference methodsFor: 'comparing' stamp: 'cwp 9/16/2009 23:54'! hash ^ path hash bitXor: filesystem hash! ! !FSReference methodsFor: 'testing' stamp: 'cwp 7/20/2009 09:24'! isAbsolute ^ path isAbsolute! ! !FSReference methodsFor: 'comparing' stamp: 'cwp 10/25/2009 23:03'! isContainedBy: anObject ^ anObject containsReference: self! ! !FSReference methodsFor: 'public' stamp: 'cwp 1/13/2009 21:39'! isDirectory ^ filesystem isDirectory: path! ! !FSReference methodsFor: 'public' stamp: 'cwp 1/13/2009 21:57'! isFile ^ filesystem isFile: path! ! !FSReference methodsFor: 'testing' stamp: 'cwp 7/20/2009 09:25'! isRelative ^ path isRelative! ! !FSReference methodsFor: 'testing' stamp: 'cwp 7/20/2009 09:26'! isRoot ^ path isRoot! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 7/20/2009 09:19'! navigateWith: aBlock | newPath | newPath := aBlock value. ^ path == newPath ifTrue: [self] ifFalse: [filesystem referenceTo: newPath]! ! !FSReference methodsFor: 'private' stamp: 'cwp 7/22/2009 22:05'! openWritable: aBoolean ^ filesystem open: path writable: aBoolean! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 7/20/2009 09:28'! parent ^ self navigateWith: [path parent]! ! !FSReference methodsFor: 'accessing' stamp: 'cwp 7/18/2009 22:53'! path ^ path! ! !FSReference methodsFor: 'public' stamp: 'cwp 7/22/2009 08:24'! pathString ^ filesystem pathToString: (filesystem resolve: path)! ! !FSReference methodsFor: 'printing' stamp: 'cwp 10/11/2009 22:32'! printOn: aStream filesystem forReferencePrintOn: aStream. filesystem printPath: path on: aStream! ! !FSReference methodsFor: 'public' stamp: 'cwp 9/22/2009 09:55'! readStream ^ filesystem readStreamOn: path! ! !FSReference methodsFor: 'public' stamp: 'cwp 10/15/2009 21:30'! readStreamDo: aBlock | stream | stream := self readStream. ^ [aBlock value: stream] ensure: [stream ifNotNil: [stream close]]! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 10/26/2009 02:02'! resolve ^ self! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 10/26/2009 01:03'! resolve: anObject ^ anObject asResolvedBy: self! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 9/22/2009 09:03'! resolvePath: anObject ^ self navigateWith: [path resolve: anObject]! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 9/22/2009 09:23'! resolveReference: aReference ^ (filesystem = aReference filesystem or: [aReference isRelative]) ifTrue: [filesystem referenceTo: (path resolvePath: aReference path)] ifFalse: [aReference]! ! !FSReference methodsFor: 'navigating' stamp: 'cwp 10/12/2009 19:00'! resolveString: aString | thePath | thePath := filesystem stringToPath: aString. ^ filesystem referenceTo: (path resolve: thePath)! ! !FSReference methodsFor: 'initialize-release' stamp: 'cwp 1/13/2009 21:12'! setFilesystem: aFilesystem path: aPath filesystem := aFilesystem. path := aPath! ! !FSReference methodsFor: 'public' stamp: 'cwp 7/28/2009 23:01'! writeStream ^ filesystem writeStreamOn: path! ! !FSReference methodsFor: 'public' stamp: 'cwp 9/22/2009 20:33'! writeStreamDo: aBlock | stream | stream := self writeStream. [aBlock value: stream] ensure: [stream ifNotNil: [stream close]]! ! Object subclass: #FSResolver instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Resolvers'! FSResolver subclass: #FSInteractiveResolver instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Resolvers'! !FSResolver methodsFor: 'origins' stamp: 'cwp 10/26/2009 13:15'! image ^ self resolveString: self primImagePath! ! !FSResolver methodsFor: 'primitives' stamp: 'cwp 10/26/2009 13:10'! primImagePath "Answer the full path name for the current image." self primitiveFailed! ! !FSResolver methodsFor: 'primitives' stamp: 'cwp 10/26/2009 13:10'! primVmDirectoryPath "Answer the full path name for the current image." self primitiveFailed! ! !FSResolver methodsFor: 'resolving' stamp: 'cwp 10/25/2009 10:05'! resolve: aSymbol ^ (self supportedOrigins includes: aSymbol) ifTrue: [self perform: aSymbol] ifFalse: [self unknownOrigin: aSymbol]! ! !FSResolver methodsFor: 'resolving' stamp: 'cwp 10/26/2009 13:16'! resolveString: aString | decoded | decoded := (FilePath pathName: aString isEncoded: true) asSqueakPathName. ^ FSDiskFilesystem current stringToReference: decoded.! ! !FSResolver methodsFor: 'resolving' stamp: 'cwp 10/26/2009 12:59'! supportedOrigins ^ #(image vmBinary vmDirectory)! ! !FSResolver methodsFor: 'resolving' stamp: 'cwp 10/25/2009 10:06'! unknownOrigin: aSymbol self error: 'Unable to resolve origin #', aSymbol! ! !FSResolver methodsFor: 'origins' stamp: 'cwp 10/26/2009 13:17'! vmBinary ^ self resolveString: (SmalltalkImage current getSystemAttribute: 0)! ! !FSResolver methodsFor: 'origins' stamp: 'cwp 10/26/2009 13:22'! vmDirectory ^ self resolveString: self primVmDirectoryPath. ! ! Object subclass: #FSStream instanceVariableNames: 'handle position' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Streams'! FSStream subclass: #FSReadStream instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Streams'! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/29/2009 22:45'! atEnd ^ position - 1 = handle size! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/29/2009 22:58'! do: aBlock [self atEnd] whileFalse: [aBlock value: self next]! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/29/2009 22:59'! next | result | result := handle at: position. position := position + 1. ^ result! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/29/2009 23:03'! next: count | result | result := ByteArray new: count. handle at: position read: result startingAt: 1 count: count. position := position + 1. ^ result! ! !FSReadStream methodsFor: 'squeak' stamp: 'cwp 7/31/2009 00:24'! nextInto: aCollection | count | count := handle at: position read: aCollection startingAt: 1 count: aCollection size. position := position + count. ^ count < aCollection size ifTrue: [aCollection first: count] ifFalse: [aCollection]! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/29/2009 23:31'! nextLine | char | ^ ByteArray streamContents: [:out | [self atEnd or: [#(13 10) includes: (char := self next)]] whileFalse: [out nextPut: char]. (char = 13 and: [self peek = 10]) ifTrue: [position := position + 1]]. ! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/30/2009 23:03'! nextMatchFor: anObject ^ self next = anObject! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/29/2009 23:27'! peek ^ handle at: position! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/30/2009 23:06'! peekFor: anObject ^ self peek = anObject! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/30/2009 23:19'! skip: anInteger position := position + anInteger min: handle size + 1! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/30/2009 23:27'! skipTo: anObject | result | [self atEnd or: [result := (self next = anObject)]] whileFalse. ^ result! ! !FSReadStream methodsFor: 'ansi' stamp: 'cwp 7/30/2009 23:37'! upTo: anObject | byte | ^ ByteArray streamContents: [:out | [self atEnd or: [(byte := self next) = anObject]] whileFalse: [out nextPut: byte]] ! ! !FSStream classSide methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 22:30'! onHandle: aHandle ^ self new setHandle: aHandle ! ! !FSStream methodsFor: 'public' stamp: 'cwp 7/29/2009 22:29'! close handle close! ! !FSStream methodsFor: 'public' stamp: 'cwp 7/29/2009 22:29'! contents | size contents | size := handle size. contents := ByteArray new: size. handle at: 1 read: contents startingAt: 1 count: size. ^ contents! ! !FSStream methodsFor: 'public' stamp: 'cwp 7/29/2009 22:32'! position ^ position! ! !FSStream methodsFor: 'public' stamp: 'cwp 7/29/2009 22:32'! position: anInteger position := anInteger! ! !FSStream methodsFor: 'initialize-release' stamp: 'cwp 7/29/2009 22:30'! setHandle: aHandle handle := aHandle. position := 1! ! FSStream subclass: #FSWriteStream instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Streams'! !FSWriteStream methodsFor: 'ansi puttable' stamp: 'cwp 7/28/2009 22:25'! cr self nextPut: 13! ! !FSWriteStream methodsFor: 'ansi puttable' stamp: 'cwp 7/28/2009 22:22'! flush handle flush! ! !FSWriteStream methodsFor: 'ansi puttable' stamp: 'cwp 7/23/2009 17:03'! nextPut: anObject handle at: position put: anObject. position := position + 1. ^ anObject! ! !FSWriteStream methodsFor: 'ansi puttable' stamp: 'cwp 7/23/2009 22:51'! nextPutAll: aCollection handle at: position write: aCollection startingAt: 1 count: aCollection size. position := position + aCollection size. ^ aCollection! ! !FSWriteStream methodsFor: 'ansi puttable' stamp: 'cwp 7/28/2009 22:26'! space self nextPut: 32! ! !FSWriteStream methodsFor: 'ansi puttable' stamp: 'cwp 7/28/2009 22:28'! tab self nextPut: 9! ! !FSWriteStream methodsFor: 'file' stamp: 'cwp 10/15/2009 22:05'! truncate handle truncateTo: position - 1! ! !FSWriteStream methodsFor: 'file' stamp: 'cwp 10/15/2009 21:49'! truncateTo: anInteger handle truncateTo: anInteger! ! RWBinaryOrTextStream subclass: #FSFileStream instanceVariableNames: 'reference' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Streams'! !FSFileStream classSide methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 18:28'! on: aCollection filesystem: aFilesystem path: aPath ^ self on: aCollection reference: (FSReference filesystem: aFilesystem path: aPath)! ! !FSFileStream classSide methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 18:28'! on: aCollection reference: aFileReference ^ (self on: aCollection) reference: aFileReference yourself! ! !FSFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 18:28'! on: aCollection super on: aCollection. readLimit := collection size.! ! !FSFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 18:14'! reference: aFileReference reference := aFileReference! ! FSFileStream subclass: #FSMemoryFileStream instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Memory'! !FSMemoryFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 7/19/2009 22:21'! close reference filesystem truncateFile: reference path to: position. ! ! !FSMemoryFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 7/19/2009 22:11'! growTo: anInteger collection := reference filesystem growFile: reference path to: anInteger. writeLimit := collection size. ! ! !FSMemoryFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 7/19/2009 09:56'! pastEndPut: anObject | oldSize newSize | oldSize := collection size. newSize := oldSize + ((oldSize max: 20) min: 1000000). collection := reference filesystem growFile: reference path to: newSize. writeLimit := collection size. collection at: (position := position + 1) put: anObject. ^ anObject! ! FSFileStream subclass: #FSZipFileStream instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Zip'! !FSZipFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 18:31'! close self flush! ! !FSZipFileStream methodsFor: 'as yet unclassified' stamp: 'cwp 8/30/2009 18:30'! flush reference filesystem setFile: reference path to: self contents! ! TestCase subclass: #FSFilesystemTest instanceVariableNames: 'filesystem toDelete' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! FSFilesystemTest subclass: #FSDiskFilesystemTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSDiskFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 10/11/2009 21:45'! createFilesystem ^ FSDiskFilesystem currentClass createDefault! ! !FSDiskFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:23'! testDefaultWorkingDirectory | ref | ref := filesystem referenceTo: filesystem workingDirectory. self assert: (SmalltalkImage current imagePath beginsWith: ref asString)! ! !FSDiskFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/24/2009 00:40'! testEqual | other | other := self createFilesystem. self assert: filesystem = other! ! !FSDiskFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 20:13'! testIsDirectory self assert: (filesystem isDirectory: FSDiskFilesystem imageDirectory path)! ! !FSFilesystemTest classSide methodsFor: 'as yet unclassified' stamp: 'cwp 7/20/2009 08:56'! isAbstract ^ self name = #FSFilesystemTest! ! !FSFilesystemTest classSide methodsFor: 'as yet unclassified' stamp: 'cwp 7/20/2009 08:56'! shouldInheritSelectors ^ true ! ! !FSFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 7/20/2009 07:31'! createFilesystem self subclassResponsibility ! ! !FSFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 10/10/2009 17:35'! delete: anObject toDelete add: (filesystem resolve: anObject)! ! !FSFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 8/23/2009 23:10'! setUp filesystem := self createFilesystem. toDelete := OrderedCollection new.! ! !FSFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 8/23/2009 23:09'! tearDown toDelete do: [:path | filesystem delete: path]! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:15'! testChangeDirectory filesystem workingDirectory: (FSPath / 'plonk'). filesystem changeDirectory: 'griffle'. self assert: (filesystem workingDirectory printWithDelimiter: $/) = '/plonk/griffle'! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:14'! testChangeDirectoryString filesystem workingDirectory: (FSPath / 'plonk'). filesystem changeDirectory: 'griffle'. self assert: (filesystem workingDirectory printWithDelimiter: $/) = '/plonk/griffle'! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/30/2009 23:49'! testCopy | out in contents | [out := filesystem writeStreamOn: 'gooly'. [out nextPutAll: 'gooly'] ensure: [out close]. filesystem copy: 'gooly' to: 'plonk'. in := filesystem readStreamOn: 'plonk'. [contents := in contents asString] ensure: [in close]. self assert: contents = 'gooly'] ensure: [filesystem delete: 'gooly'; delete: 'plonk']! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/28/2009 22:53'! testCopyDestExists | out | [out := (filesystem open: 'gooly' writable: true) writeStream. [out nextPutAll: 'gooly'] ensure: [out close]. out := filesystem open: 'plonk' writable: true. out close. self should: [filesystem copy: 'gooly' to: 'plonk'] raise: FileExistsException] ensure: [filesystem delete: 'gooly'; delete: 'plonk']! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/24/2009 00:29'! testCopySourceDoesntExist self should: [filesystem copy: 'plonk' to: 'griffle'] raise: FileDoesNotExistException! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 07:30'! testDefaultWorkingDirectory self assert: filesystem workingDirectory isRoot! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 07:30'! testDelimiter self assert: filesystem delimiter isCharacter! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:43'! testDirectory | path | path := FSPath with: 'plonk'. filesystem createDirectory: path. self assert: (filesystem exists: path). self assert: (filesystem isDirectory: path). self deny: (filesystem isFile: path). filesystem delete: path. self deny: (filesystem exists: path)! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:43'! testEntries | directory entries | directory := FSPath with: 'plonk'. filesystem createDirectory: directory. filesystem createDirectory: directory / 'griffle'. filesystem createDirectory: directory / 'bint'. self delete: directory / 'griffle'. self delete: directory / 'bint'. self delete: directory. entries := filesystem entriesAt: directory. self assert: entries size = 2. entries do: [:ea | self assert: (ea isKindOf: FSReference). self assert: ea parent path = (filesystem resolve: directory). self assert: (#('griffle' 'bint') includes: ea basename)]! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:43'! testFile | path out | path := FSPath with: 'gooly'. out := filesystem open: path writable: true. out close. self assert: (filesystem exists: path). self deny: (filesystem isDirectory: path). self assert: (filesystem isFile: path). filesystem delete: path. self deny: (filesystem exists: path)! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:44'! testFileStream | path out | path := FSPath with: 'gooly'. out := filesystem openFileStream: path writable: true. out close. self assert: (filesystem exists: path). self deny: (filesystem isDirectory: path). self assert: (filesystem isFile: path). filesystem delete: path. self deny: (filesystem exists: path)! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:42'! testFileStreamContents | path out in contents | path := FSPath with: 'gooly'. self delete: path. out := filesystem openFileStream: path writable: true. [out nextPutAll: 'gooly'] ensure: [out close]. in := filesystem openFileStream: path writable: false. [contents := in ascii; contentsOfEntireFile] ensure: [in close]. self assert: contents = 'gooly'! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 00:33'! testRootExists self assert: (filesystem exists: FSPath root)! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 00:25'! testRootIsDirectory self assert: (filesystem isDirectory: FSPath root)! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 00:33'! testRootIsNotAFile self deny: (filesystem isFile: FSPath root)! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:14'! testSetRelativeWorkingDirectory self should: [filesystem workingDirectory: (FSPath with: 'plonk')] raise: Error ! ! !FSFilesystemTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:13'! testSetWorkingDirectory filesystem workingDirectory: (FSPath / 'plonk'). self assert: (filesystem workingDirectory printWithDelimiter: $/) = '/plonk'.! ! FSFilesystemTest subclass: #FSMemoryFilesystemTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSMemoryFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 7/20/2009 07:29'! createFilesystem ^ FSMemoryFilesystem new! ! !FSMemoryFilesystemTest methodsFor: 'tests' stamp: 'cwp 7/24/2009 00:41'! testEqual | other | other := self createFilesystem. self deny: filesystem = other! ! FSFilesystemTest subclass: #FSZipFilesystemTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSZipFilesystemTest methodsFor: 'initialize-release' stamp: 'cwp 9/21/2009 22:59'! createFilesystem | ref | ref := FSDiskFilesystem current referenceTo: 'fs.zip'. ^ (FSZipFilesystem atReference: ref) open; yourself! ! TestCase subclass: #FSHandleTest instanceVariableNames: 'filesystem handle reference' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! FSHandleTest subclass: #FSFileHandleTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSFileHandleTest methodsFor: 'running' stamp: 'cwp 10/11/2009 22:25'! createFilesystem ^ FSDiskFilesystem currentClass createDefault! ! !FSHandleTest classSide methodsFor: 'as yet unclassified' stamp: 'cwp 7/26/2009 12:46'! isAbstract ^ self name = #FSHandleTest! ! !FSHandleTest classSide methodsFor: 'as yet unclassified' stamp: 'cwp 7/26/2009 12:46'! shouldInheritSelectors ^ true! ! !FSHandleTest methodsFor: 'running' stamp: 'cwp 7/26/2009 12:22'! setUp filesystem := self createFilesystem. reference := filesystem referenceTo: 'plonk'. handle := reference openWritable: true! ! !FSHandleTest methodsFor: 'running' stamp: 'cwp 7/26/2009 12:23'! tearDown handle close. reference delete! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 22:06'! testAt handle at: 1 write: (ByteArray with: 3) startingAt: 1 count: 1. self assert: (handle at: 1) = 3! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 22:03'! testAtPut | in | handle at: 1 put: 3. in := ByteArray new: 1. handle at: 1 read: in startingAt: 1 count: 1. self assert: in first = 3! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/26/2009 12:23'! testClose handle close. self deny: handle isOpen ! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/26/2009 12:23'! testCreatedOpen self assert: handle isOpen! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/26/2009 14:15'! testIO | out in | out := #(1 2 3) asByteArray. in := ByteArray new: 3. handle at: 1 write: out startingAt: 1 count: 3. handle at: 1 read: in startingAt: 1 count: 3. self assert: out = in.! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/31/2009 00:13'! testReadBufferTooLarge | out in result | out := #(1 2 3) asByteArray. in := ByteArray new: 5. in atAllPut: 9. handle at: 1 write: out startingAt: 1 count: 3. result := handle at: 1 read: in startingAt: 2 count: 4. self assert: result = 3. self assert: in = #(9 1 2 3 9) asByteArray.! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/26/2009 14:16'! testReadOnly handle close. handle := reference openWritable: false. self should: [ handle at: 1 write: #(1 2 3 ) startingAt: 1 count: 3 ] raise: Error! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/26/2009 12:45'! testReference self assert: handle reference = reference asAbsolute! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 22:11'! testSizeAfterGrow | out | out := #(1 2 3) asByteArray. handle at: 1 write: out startingAt: 1 count: 3. self assert: handle size = 3! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 22:13'! testSizeNoGrow | bytes | bytes := #(1 2 3 4) asByteArray. handle at: 1 write: bytes startingAt: 1 count: 3. handle at: 4 write: bytes startingAt: 4 count: 1. self assert: handle size = 4! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/26/2009 14:16'! testTruncate | out | out := #(1 2 3 4 5) asByteArray. handle at: 1 write: out startingAt: 1 count: 5. handle truncateTo: 3. self assert: handle size = 3! ! !FSHandleTest methodsFor: 'tests' stamp: 'cwp 7/28/2009 22:40'! testWriteStream | stream | stream := handle writeStream. self assert: (stream respondsTo: #nextPut:)! ! FSHandleTest subclass: #FSMemoryHandleTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSMemoryHandleTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/26/2009 12:47'! createFilesystem ^ FSMemoryFilesystem new! ! TestCase subclass: #FSInteractiveResolverTest instanceVariableNames: 'resolver' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSInteractiveResolverTest methodsFor: 'as yet unclassified' stamp: 'cwp 10/26/2009 13:21'! assertOriginResolves: aSymbol | reference | reference := resolver resolve: aSymbol. self assert: (reference isKindOf: FSReference). self assert: reference isAbsolute. self assert: reference exists! ! !FSInteractiveResolverTest methodsFor: 'as yet unclassified' stamp: 'cwp 10/26/2009 13:19'! setUp resolver := FSInteractiveResolver new.! ! !FSInteractiveResolverTest methodsFor: 'as yet unclassified' stamp: 'cwp 10/26/2009 13:21'! testImage self assertOriginResolves: #image! ! !FSInteractiveResolverTest methodsFor: 'as yet unclassified' stamp: 'cwp 10/26/2009 13:21'! testVmBinary self assertOriginResolves: #vmBinary! ! !FSInteractiveResolverTest methodsFor: 'as yet unclassified' stamp: 'cwp 10/26/2009 13:21'! testVmDirectory self assertOriginResolves: #vmDirectory! ! TestCase subclass: #FSLocatorTest instanceVariableNames: 'locator' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 10:29'! testAsAbsolute | locator | locator := FSLocator image. self assert: locator asAbsolute = locator! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:07'! testBasename | locator | locator := FSLocator image / 'griffle'. self assert: locator basename = 'griffle'! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:11'! testCommaAddsExtension | locator | locator := FSLocator image / 'griffle'. self assert: (locator , 'plonk') basename = 'griffle.plonk'! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:13'! testCommaReplacesExtension | locator | locator := FSLocator image / 'griffle.plonk'. self assert: (locator , 'nurp') basename = 'griffle.nurp'! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 22:24'! testContainsLocator locator := FSLocator image. self assert: (locator contains: locator / 'griffle').! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 22:39'! testContainsPath locator := FSLocator image. self assert: (locator contains: (locator resolve / 'griffle') path).! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 22:40'! testContainsReference locator := FSLocator image. self assert: (locator contains: (locator resolve / 'griffle')).! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:14'! testEqual | a b | a := FSLocator image. b := FSLocator image. self deny: a == b. self assert: a = b.! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 22:12'! testFilesystem locator := FSLocator image. self assert: (locator filesystem isKindOf: FSDiskFilesystem)! ! !FSLocatorTest methodsFor: 'resolution tests' stamp: 'cwp 10/26/2009 13:46'! testImageDirectory | locator | locator := FSLocator image. self assert: locator resolve = FSDiskFilesystem imageFile! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 10:28'! testIsAbsolute | locator | locator := FSLocator image. self assert: locator isAbsolute! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:17'! testIsNotRoot locator := FSLocator image. self deny: locator isRoot! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:15'! testIsRelative | locator | locator := FSLocator image. self deny: locator isRelative! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:24'! testIsRoot locator := FSLocator image. (locator resolve path size - 1) timesRepeat: [locator := locator / '..']. self assert: locator isRoot! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/26/2009 13:46'! testOriginBasename | locator | locator := FSLocator image. self assert: locator basename = (FSDiskFilesystem imageFile basename)! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/26/2009 13:45'! testParent locator := FSLocator image. self assert: locator parent resolve = FSDiskFilesystem imageDirectory! ! !FSLocatorTest methodsFor: 'resolution tests' stamp: 'cwp 10/25/2009 21:58'! testResolveAbsoluteReference | result reference | locator := FSLocator image / 'plonk'. reference := FSMemoryFilesystem new root / 'griffle'. result := locator resolve: reference.. self assert: result == reference! ! !FSLocatorTest methodsFor: 'resolution tests' stamp: 'cwp 10/25/2009 22:00'! testResolveCompoundString | result | locator := FSLocator image / 'plonk'. result := locator resolve: 'griffle/nurp'. self assert: result class = locator class. self assert: result origin = locator origin. self assert: result path = ((FSPath with: 'plonk') / 'griffle' / 'nurp')! ! !FSLocatorTest methodsFor: 'resolution tests' stamp: 'cwp 10/25/2009 21:43'! testResolvePath | result path | locator := FSLocator image / 'plonk'. result := locator resolve: (FSPath with: 'griffle'). path := (FSPath with: 'plonk') / 'griffle'. self assert: result class= locator class. self assert: result origin = locator origin. self assert: result path = path.! ! !FSLocatorTest methodsFor: 'resolution tests' stamp: 'cwp 10/25/2009 21:50'! testResolveRelativeReference | result reference | locator := FSLocator image / 'plonk'. reference := FSMemoryFilesystem new referenceTo: 'griffle'. result := locator resolve: reference.. self assert: result class= locator class. self assert: result origin = locator origin. self assert: result path = reference path.! ! !FSLocatorTest methodsFor: 'resolution tests' stamp: 'cwp 10/25/2009 21:43'! testResolveString | result path | locator := FSLocator image / 'plonk'. result := locator resolve: 'griffle'. path := (FSPath with: 'plonk') / 'griffle'. self assert: result class= locator class. self assert: result origin = locator origin. self assert: result path = path.! ! !FSLocatorTest methodsFor: 'compatibility tests' stamp: 'cwp 10/25/2009 11:03'! testSlash | locator | locator := FSLocator image / 'griffle'. self assert: locator = (FSLocator image / 'griffle')! ! TestCase variableSubclass: #FSPathTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 18:11'! testAsReference | path reference | path := FSPath with: 'plonk'. reference := path asReference. self assert: reference class = FSReference. self assert: reference path = path! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:34'! testAssureExtentionAddsExtension | path result | path := FSPath with: 'plonk'. result := path assureExtension: 'griffle'. self assert: result asString = '[plonk.griffle]'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:34'! testAssureExtentionNoDuplicates | path result | path := FSPath with: 'plonk.griffle'. result := path assureExtension: 'griffle'. self assert: result asString = '[plonk.griffle]'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:34'! testAssureExtentionWithDot | path result | path := FSPath with: 'plonk'. result := path assureExtension: '.griffle'. self assert: result asString = '[plonk.griffle]'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:48'! testBasename | path | path := (FSPath with: 'plonk') / 'griffle'. self assert: path basename = 'griffle'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:34'! testCommaAddsExtension | path result | path := FSPath with: 'plonk' . result := path, 'griffle'. self assert: result asString = '[plonk.griffle]'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:35'! testCommaReplacesExtension | path result | path := FSPath with: 'plonk.griffle'. result := path, 'nurp'. self assert: result asString = '[plonk.nurp]'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 8/30/2009 15:07'! testContains | ancestor descendent | ancestor := FSPath / 'plonk'. descendent := FSPath / 'plonk' / 'griffle' / 'bork'. self assert: (ancestor contains: descendent). self deny: (descendent contains: ancestor)! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/25/2009 22:48'! testContainsLocator | ancestor descendent | ancestor := FSDiskFilesystem imageDirectory path. descendent := FSLocator image / 'griffle'. self deny: (ancestor contains: descendent). self deny: (descendent contains: ancestor)! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:49'! testEqual | a b | a := FSPath with: 'plonk'. b := FSPath with: 'plonk'. self deny: a == b. self assert: a = b.! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:49'! testIsAbsolute self assert: (FSPath / 'plonk') isAbsolute! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:49'! testIsNotAbsolute self deny: (FSPath with: 'plonk') isAbsolute! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:49'! testIsNotRelative self deny: (FSPath / 'plonk') isRelative! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 7/17/2009 05:23'! testIsNotRoot self deny: (FSPath root / 'plonk') isRoot! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:50'! testIsRelative self assert: (FSPath with: 'plonk') isRelative! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 7/17/2009 05:23'! testIsRoot self assert: FSPath root isRoot! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:35'! testParent | path parent | path := (FSPath with: 'plonk') / 'griffle'. parent := path parent. self assert: parent class = path class. self assert: parent asString = '[plonk]'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/25/2009 19:49'! testParentParent | path | path := (FSPath with: '..') parent. self assert: path size = 2. self assert: (path at: 1) = '..'. self assert: (path at: 2) = '..'.! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:51'! testParentResolution | base relative absolute | base := FSPath / 'plonk' / 'pinto'. relative := FSPath parent / 'griffle' / 'zonk'. absolute := base resolve: relative. self assert: (absolute printWithDelimiter: $/) = '/plonk/griffle/zonk'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 13:27'! testParseTrailingSlash | path | path := FSPath readFrom: 'griffle/' readStream delimiter: $/. self assert: path size = 1. self assert: (path at: 1) = 'griffle'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:52'! testPrintWithDelimiter | path | path := (FSPath with: 'plonk') / 'griffle'. self assert: (path printWithDelimiter: $%) = 'plonk%griffle'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 13:08'! testRelativeWithParent | path | path := FSPath withAll: #('..' 'foo'). self assert: (path printWithDelimiter: $/) = '../foo'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/25/2009 21:40'! testResolveString | path result | path := FSPath with: 'plonk'. result := path resolve: 'griffle'. self assert: result class = path class. self assert: result size = 2. self assert: (result at: 1) = 'plonk'. self assert: (result at: 2) = 'griffle'.! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 7/17/2009 23:40'! testRootParent | root | root := FSPath root. self assert: root parent == root! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:53'! testSimpleResolution | base relative absolute | base := FSPath / 'plonk'. relative := (FSPath with: 'griffle') / 'zonk'. absolute := base resolve: relative. self assert: (absolute printWithDelimiter: $/) = '/plonk/griffle/zonk'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:53'! testSlash | path actual | path := FSPath with: 'plonk'. actual := path / 'griffle'. self assert: actual class = FSPath. self assert: (actual printWithDelimiter: $/) = 'plonk/griffle'! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:54'! testUnequalContent | a b | a := FSPath with: 'plonk'. b := FSPath with: 'griffle'. self deny: a = b.! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:54'! testUnequalSize | a b | a := FSPath with: 'plonk'. b := (FSPath with: 'plonk') / 'griffle'. self deny: a = b.! ! !FSPathTest methodsFor: 'tests' stamp: 'cwp 10/25/2009 19:44'! testWorkingDirectoryParent | path | path := FSPath empty parent. self assert: path size = 1. self assert: (path at: 1) = '..'! ! TestCase subclass: #FSReadStreamTest instanceVariableNames: 'filesystem stream' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 22:43'! contents: aByteArray stream := filesystem writeStreamOn: 'griffle'. stream nextPutAll: aByteArray. stream close. stream := filesystem readStreamOn: 'griffle'! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 22:40'! setUp filesystem := FSMemoryFilesystem new. ! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 22:38'! testAtEnd self contents: #(). self assert: stream atEnd! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 22:57'! testDo | contents | self contents: #(1 2 3). contents := Array streamContents: [:out | stream do: [:ea | out nextPut: ea]]. self assert: contents = #(1 2 3)! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 23:00'! testNext self contents: #(1 2 3). self assert: stream next = 1! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 23:07'! testNextColon | result | self contents: #(1 2 3 4 5). result := stream next: 3. self assert: result = #(1 2 3) asByteArray.! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:54'! testNextInto | result buffer | self contents: #(1 2 3 4 5). buffer := ByteArray new: 3. result := stream nextInto: buffer. self assert: result == buffer. self assert: result = #(1 2 3) asByteArray! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 23:30'! testNextLineCR | result tail | self contents: #(97 97 97 13 98 98 98). result := stream nextLine. self assert: result = #(97 97 97) asByteArray. tail := stream next: 3. self assert: tail = #(98 98 98) asByteArray! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 23:31'! testNextLineCRLF | line tail | self contents: #(97 97 97 13 10 98 98 98). line := stream nextLine. self assert: line = #(97 97 97) asByteArray. tail := stream next: 3. self assert: tail = #(98 98 98) asByteArray! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 23:31'! testNextLineLF | result tail | self contents: #(97 97 97 10 98 98 98). result := stream nextLine. self assert: result = #(97 97 97) asByteArray. tail := stream next: 3. self assert: tail = #(98 98 98) asByteArray! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:04'! testNextMatchFalse self contents: #(1 2 3). self deny: (stream nextMatchFor: 5)! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:01'! testNextMatchTrue self contents: #(1 2 3). self assert: (stream nextMatchFor: 1)! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/29/2009 22:46'! testNotAtEnd self contents: #(1 2 3). self deny: stream atEnd! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:05'! testPeek self contents: #(1 2 3). self assert: stream peek = 1. self assert: stream next = 1.! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:06'! testPeekForFalse self contents: #(1 2 3). self deny: (stream peekFor: 5) ! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:06'! testPeekForTrue self contents: #(1 2 3). self assert: (stream peekFor: 1) ! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:17'! testSkip self contents: #(1 2 3 4 5). stream skip: 3. self assert: stream position = 4! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:18'! testSkipPastEnd self contents: #(1 2 3 4 5). stream skip: 10. self assert: stream atEnd! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:20'! testSkipTo self contents: #(1 2 3 4 5). stream skipTo: 3. self assert: stream position = 4! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:24'! testSkipToEnd self contents: #(1 2 3 4 5). stream skipTo: 10. self assert: stream atEnd! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:27'! testSkipToFalse self contents: #(1 2 3 4 5). self deny: (stream skipTo: 10). ! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:25'! testSkipToTrue self contents: #(1 2 3 4 5). self assert: (stream skipTo: 4). ! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:38'! testUpTo | result | self contents: #(1 2 3 4 5). result := stream upTo: 4. self assert: result = #(1 2 3) asByteArray! ! !FSReadStreamTest methodsFor: 'as yet unclassified' stamp: 'cwp 7/30/2009 23:38'! testUpToEnd | result | self contents: #(1 2 3 4 5). result := stream upTo: 7. self assert: result = #(1 2 3 4 5) asByteArray! ! TestCase variableSubclass: #FSReferenceTest instanceVariableNames: 'filesystem' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSReferenceTest methodsFor: 'running' stamp: 'cwp 7/20/2009 09:06'! setUp filesystem := FSMemoryFilesystem new.! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 22:38'! testAsAbsoluteConverted | ref absolute | ref := filesystem referenceTo: 'plonk'. absolute := ref asAbsolute. self assert: absolute isAbsolute. self assert: absolute asString = 'memory:/plonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/22/2009 08:30'! testAsAbsoluteIdentity | ref | ref := filesystem referenceTo: '/plonk'. self assert: ref asAbsolute == ref! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:08'! testAsReference | ref | ref := filesystem referenceTo: 'plonk'. self assert: ref asReference == ref! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:10'! testAssureExtentionAddsExtension | ref result | ref := filesystem referenceTo: 'plonk'. result := ref assureExtension: 'griffle'. self assert: result asString = 'memory:plonk.griffle'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:16'! testAssureExtentionNoDuplicates | ref result | ref := filesystem referenceTo: 'plonk.griffle'. result := ref assureExtension: 'griffle'. self assert: result asString = 'memory:plonk.griffle'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:16'! testAssureExtentionWithDot | ref result | ref := filesystem referenceTo: 'plonk.griffle'. result := ref assureExtension: '.griffle'. self assert: result asString = 'memory:plonk.griffle'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:17'! testBasename | ref | ref := filesystem referenceTo: 'plonk/griffle'. self assert: ref basename = 'griffle'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/25/2009 11:11'! testCommaAddsExtension | ref result | ref := filesystem referenceTo: 'plonk'. result := ref, 'griffle'. self assert: result basename = 'plonk.griffle'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:20'! testCommaReplacesExtension | ref result | ref := filesystem referenceTo: 'plonk.griffle'. result := ref, 'nurp'. self assert: result asString = 'memory:plonk.nurp'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:55'! testContainsLocator | ref | ref := FSDiskFilesystem imageDirectory parent. self assert: (ref contains: FSLocator image)! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:53'! testContainsPath | ref | ref := filesystem referenceTo: (FSPath with: 'griffle'). self assert: (ref contains: (ref / 'nurp') path)! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:50'! testContainsReference | ref | ref := filesystem referenceTo: (FSPath with: 'griffle'). self assert: (ref contains: ref / 'nurp')! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:56'! testDoesntContainLocator | ref | ref := filesystem referenceTo: 'griffle'. self deny: (ref contains: FSLocator image)! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:54'! testDoesntContainPath | ref | ref := filesystem referenceTo: (FSPath with: 'griffle'). self deny: (ref contains: (FSPath with: 'nurp'))! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:52'! testDoesntContainReferenceFilesystem | ref other | ref := filesystem referenceTo: (FSPath with: 'griffle'). other := FSMemoryFilesystem new referenceTo: 'griffle/nurp'. self deny: (ref contains: other)! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/26/2009 00:52'! testDoesntContainReferencePath | ref other | ref := filesystem referenceTo: (FSPath with: 'griffle'). other := filesystem referenceTo: (FSPath with: 'nurp'). self deny: (ref contains: other)! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:21'! testEqual | a b | a := filesystem referenceTo: 'plonk'. b := filesystem referenceTo: 'plonk'. self deny: a == b. self assert: a = b.! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:23'! testIsAbsolute self assert: (filesystem referenceTo: '/plonk') isAbsolute! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:24'! testIsNotAbsolute self deny: (filesystem referenceTo: 'plonk') isAbsolute! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:25'! testIsNotRelative self deny: (filesystem referenceTo: '/plonk') isRelative! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:26'! testIsNotRoot self deny: (filesystem referenceTo: FSPath root / 'plonk') isRoot! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:26'! testIsRelative self assert: (filesystem referenceTo: 'plonk') isRelative! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:27'! testIsRoot self assert: (filesystem referenceTo: FSPath root) isRoot! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:27'! testParent | ref parent | ref := (filesystem referenceTo: 'plonk/griffle'). parent := ref parent. self assert: parent class = ref class. self assert: parent asString = 'memory:plonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 16:55'! testParentResolutionWithAbsoluteReference | base relative absolute | base := (filesystem referenceTo: '/plonk/pinto'). relative := (FSMemoryFilesystem new referenceTo: '/griffle/zonk'). absolute := base resolve: relative. self assert: absolute filesystem == relative filesystem. self assert: (absolute path printWithDelimiter: $/) = '/griffle/zonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 17:55'! testParentResolutionWithPath | base relative absolute | base := filesystem referenceTo: (FSPath / 'plonk' / 'pinto'). relative := FSPath parent / 'griffle' / 'zonk'. absolute := base resolve: relative. self assert: absolute asString = 'memory:/plonk/griffle/zonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:31'! testParentResolutionWithReference | base relative absolute | base := (filesystem referenceTo: '/plonk/pinto'). relative := (filesystem referenceTo: '../griffle/zonk'). absolute := base resolve: relative. self assert: absolute asString = 'memory:/plonk/griffle/zonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/11/2009 16:59'! testParentResolutionWithRemoteReference | base relative absolute | base := (filesystem referenceTo: '/plonk/pinto'). relative := (FSMemoryFilesystem new referenceTo: '../griffle/zonk'). absolute := base resolve: relative. self assert: absolute asString = 'memory:/plonk/griffle/zonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:34'! testRootParent | root | root := filesystem referenceTo: FSPath root. self assert: root parent == root! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/10/2009 18:06'! testSimpleResolution | base relative absolute | base := filesystem referenceTo: FSPath / 'plonk'. relative := (FSPath with: 'griffle') / 'zonk'. absolute := base resolve: relative. self assert: absolute asString = 'memory:/plonk/griffle/zonk'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:36'! testSlash | ref result | ref := filesystem referenceTo: 'plonk'. result := ref / 'griffle'. self assert: result class = FSReference. self assert: result asString = 'memory:plonk/griffle'! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:37'! testUnequalContent | a b | a := filesystem referenceTo: 'plonk'. b := filesystem referenceTo: 'griffle'. self deny: a = b.! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/20/2009 09:56'! testUnequalSize | a b | a := filesystem referenceTo: 'plonk'. b := filesystem referenceTo: 'plonk/griffle'. self deny: a = b.! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 10/25/2009 19:56'! testWorkingDirectoryParent | wd | wd := filesystem referenceTo: FSPath new. self assert: wd parent path size = 1. self assert: (wd parent path at: 1) = '..'.! ! !FSReferenceTest methodsFor: 'tests' stamp: 'cwp 7/28/2009 23:05'! testWriteStream | ref stream | ref := filesystem referenceTo: 'plonk'. [stream := ref writeStream. self assert: (stream respondsTo: #nextPut:)] ensure: [stream ifNotNil: [stream close]]! ! TestCase subclass: #FSWriteStreamTest instanceVariableNames: 'filesystem stream' classVariableNames: '' poolDictionaries: '' category: 'Filesystem-Tests'! !FSWriteStreamTest methodsFor: 'accessing' stamp: 'cwp 7/29/2009 22:21'! contents ^ filesystem entryAt: FSPath / 'giffle' ifPresent: [:bytes | bytes] ifAbsent: [self signalFailure: 'No file!!']! ! !FSWriteStreamTest methodsFor: 'running' stamp: 'cwp 7/29/2009 21:57'! setUp filesystem := FSMemoryFilesystem new. stream := filesystem writeStreamOn: 'giffle'! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/28/2009 22:48'! testClose self shouldnt: [stream close] raise: Error! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 21:55'! testContents stream nextPutAll: #(42 43 44). self assert: stream contents = #(42 43 44) asByteArray! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 21:55'! testCr stream cr. self assert: self contents first = 13! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/28/2009 22:21'! testFlush self shouldnt: [stream flush] raise: Error! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 21:55'! testNextPut stream nextPut: 42. self assert: self contents first = 42! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 22:23'! testNextPutAll stream nextPutAll: #(42 43 44). stream flush. self assert: self contents = #(42 43 44) asByteArray! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 21:55'! testSpace stream space. self assert: self contents first = 32! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 7/29/2009 21:56'! testTab stream tab. self assert: self contents first = 9! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 10/15/2009 22:04'! testTruncate stream nextPutAll: #(42 43 44 45 46); flush; position: 4; truncate. self assert: self contents = #(42 43 44) asByteArray! ! !FSWriteStreamTest methodsFor: 'tests' stamp: 'cwp 10/15/2009 21:50'! testTruncateTo stream nextPutAll: #(42 43 44 45 46). stream flush. stream truncateTo: 3. self assert: self contents = #(42 43 44) asByteArray! ! FSDiskFilesystem initialize! FSFileHandle initialize! FSLocator initialize!