'From Squeak3.8alpha of ''17 July 2004'' [latest update: #5976] on 18 August 2004 at 2:27:40 pm'! "Change Set: UTF8Preamble Date: 17 August 2004 Author: Yoshiki Ohshima "! !ChangeList class methodsFor: 'public access' stamp: 'yo 8/17/2004 09:52'! browseRecent: charCount on: origChangesFile "Opens a changeList on the end of the specified changes log file" | changeList end changesFile | changesFile _ origChangesFile readOnlyCopy. changesFile setConverterForCode. end _ changesFile size. Cursor read showWhile: [changeList _ self new scanFile: changesFile from: (0 max: end - charCount) to: end]. changesFile close. self open: changeList name: 'Recent changes' multiSelect: true! ! !ChangeList class methodsFor: 'public access' stamp: 'yo 8/17/2004 18:49'! browseRecentLogOn: origChangesFile startingFrom: initialPos "Prompt with a menu of how far back to go when browsing a changes file." | end banners positions pos chunk i changesFile | changesFile _ origChangesFile readOnlyCopy. banners _ OrderedCollection new. positions _ OrderedCollection new. end _ changesFile size. changesFile setConverterForCode. pos _ initialPos. [pos = 0 or: [banners size > 20]] whileFalse: [changesFile position: pos. chunk _ changesFile nextChunk. i _ chunk indexOfSubCollection: 'priorSource: ' startingAt: 1. i > 0 ifTrue: [positions addLast: pos. banners addLast: (chunk copyFrom: 5 to: i - 2). pos _ Number readFrom: (chunk copyFrom: i + 13 to: chunk size)] ifFalse: [pos _ 0]]. changesFile close. banners size == 0 ifTrue: [^ self inform: 'this image has never been saved since changes were compressed']. pos _ (SelectionMenu labelList: banners selections: positions) startUpWithCaption: 'Browse as far back as...'. pos == nil ifTrue: [^ self]. self browseRecent: end - pos on: origChangesFile! ! !ChangeList class methodsFor: 'public access' stamp: 'yo 8/17/2004 09:59'! browseStream: changesFile "Opens a changeList on a fileStream" | changeList charCount | changesFile readOnly. changesFile setConverterForCode. charCount _ changesFile size. charCount > 1000000 ifTrue: [(self confirm: 'The file ', changesFile name , ' is really long (' , charCount printString , ' characters). Would you prefer to view only the last million characters?') ifTrue: [charCount _ 1000000]]. "changesFile setEncoderForSourceCodeNamed: changesFile name." Cursor read showWhile: [changeList _ self new scanFile: changesFile from: changesFile size-charCount to: changesFile size]. changesFile close. self open: changeList name: changesFile localName , ' log' multiSelect: true! ! !ChangeSorter class methodsFor: 'adding' stamp: 'yo 8/17/2004 10:07'! newChangesFromStream: aStream named: aName "File in the code from the stream into a new change set whose name is derived from aName. Leave the 'current change set' unchanged. Return the new change set or nil on failure." | oldChanges newName newSet newStream | oldChanges _ ChangeSet current. PreviousSet _ oldChanges name. "so a Bumper update can find it" newName _ aName sansPeriodSuffix. newSet _ self basicNewChangeSet: newName. [newSet ifNotNil: [ (aStream respondsTo: #converter:) ifFalse: [ newStream _ MultiByteBinaryOrTextStream with: (aStream contentsOfEntireFile). newStream reset. ] ifTrue: [ newStream _ aStream. ]. ChangeSet newChanges: newSet. newStream setConverterForCode. newStream fileInAnnouncing: 'Loading ', newName, '...'. Transcript cr; show: 'File ', aName, ' successfully filed in to change set ', newName]. aStream close] ensure: [ ChangeSet newChanges: oldChanges]. ^ newSet! ! !FileContentsBrowser class methodsFor: 'instance creation' stamp: 'yo 8/17/2004 10:17'! browseStream: aStream named: aString | package organizer packageDict browser | Cursor wait showWhile: [ packageDict _ Dictionary new. organizer _ SystemOrganizer defaultList: Array new. (aStream respondsTo: #converter:) ifTrue: [ aStream setConverterForCode. ]. package _ (FilePackage new fullName: aString; fileInFrom: aStream). packageDict at: package packageName put: package. organizer classifyAll: package classes keys under: package packageName. (browser := self new) systemOrganizer: organizer; packages: packageDict]. self openBrowserView: browser createViews label: 'File Contents Browser'. ! ! !FilePackage methodsFor: 'initialize' stamp: 'yo 8/17/2004 09:53'! fromFileNamed: aName | stream | fullName := aName. stream := FileStream readOnlyFileNamed: aName. stream setConverterForCode. [self fileInFrom: stream] ensure:[stream close].! ! !FilePackage methodsFor: 'initialize' stamp: 'yo 8/17/2004 09:54'! fromFileNamed: aName encoding: encodingName | stream | fullName := aName. stream := FileStream readOnlyFileNamed: aName. stream converter: (TextConverter newForEncoding: encodingName). self fileInFrom: stream.! ! !FileStream methodsFor: 'fileIn/Out' stamp: 'sw 11/19/1998 16:42'! fileIn "Guarantee that the receiver is readOnly before fileIn for efficiency and to eliminate remote sharing conflicts." self readOnly. self fileInAnnouncing: 'Loading ', self localName! ! !FileStream class methodsFor: 'file reader services' stamp: 'yo 8/17/2004 18:37'! writeUTF8PreambleOn: aStream aStream binary. aStream nextPut: 16rEF. aStream nextPut: 16rBB. aStream nextPut: 16rBF. aStream text. " aStream nextPutAll: ' | me ctx | ctx _ thisContext. [ctx == nil or:[ctx receiver isKindOf: FileStream]] whileFalse:[ctx _ ctx sender]. ctx ifNotNil:[me _ ctx receiver]. me ifNotNil: [me converter: UTF8TextConverter new.]!! ' "! ! !MczInstaller methodsFor: 'as yet unclassified' stamp: 'yo 8/17/2004 10:03'! installMember: member | str | self useNewChangeSetDuring: [str _ member contentStream text. str setConverterForCode. str fileInAnnouncing: 'loading ', member fileName]! ! !MultiByteBinaryOrTextStream methodsFor: 'as yet unclassified' stamp: 'yo 8/17/2004 10:02'! fileIn self setConverterForCode. super fileIn. ! ! !MultiByteBinaryOrTextStream methodsFor: 'as yet unclassified' stamp: 'yo 8/18/2004 09:36'! setConverterForCode | current | current _ converter saveStateOf: self. self position: 0. self binary. ((self next: 3) = (ByteArray with: 16rEF with: 16rBB with: 16rBF)) ifTrue: [ self converter: UTF8TextConverter new ] ifFalse: [ self converter: MacRomanTextConverter new. ]. converter restoreStateOf: self with: current. self text. ! ! !MultiByteFileStream methodsFor: 'private' stamp: 'yo 8/17/2004 18:42'! setConverterForCode | current | self fullName = (SourceFiles at: 2) fullName ifTrue: [^ self]. current _ converter saveStateOf: self. self position: 0. self binary. ((self next: 3) = (ByteArray with: 16rEF with: 16rBB with: 16rBF)) ifTrue: [ self converter: UTF8TextConverter new ] ifFalse: [ self converter: MacRomanTextConverter new. ]. converter restoreStateOf: self with: current. self text. ! ! !MultiByteFileStream methodsFor: 'as yet unclassified' stamp: 'yo 8/17/2004 10:03'! fileIn self setConverterForCode. super fileIn. ! ! !SARInstaller methodsFor: 'client services' stamp: 'yo 8/17/2004 10:01'! fileInMemberNamed: csName "This is to be used from preamble/postscript code to file in zip members as ChangeSets." | cs | cs _ self memberNamed: csName. cs ifNil: [ ^self errorNoSuchMember: csName ]. self class fileIntoChangeSetNamed: csName fromStream: cs contentStream text setConverterForCode. self installed: cs. ! ! !SARInstaller methodsFor: 'client services' stamp: 'yo 8/17/2004 10:05'! fileInPackageNamed: memberName "This is to be used from preamble/postscript code to file in zip members as DVS packages." | member current new baseName imagePackageLoader packageInfo streamPackageLoader packageManager | member _ self zip memberNamed: memberName. member ifNil: [ ^self errorNoSuchMember: memberName ]. imagePackageLoader _ Smalltalk at: #ImagePackageLoader ifAbsent: []. streamPackageLoader _ Smalltalk at: #StreamPackageLoader ifAbsent: []. packageInfo _ Smalltalk at: #PackageInfo ifAbsent: []. packageManager _ Smalltalk at: #FilePackageManager ifAbsent: []. "If DVS isn't present, do a simple file-in" (packageInfo isNil or: [imagePackageLoader isNil or: [streamPackageLoader isNil]]) ifTrue: [ ^ self fileInMemberNamed: memberName ]. baseName _ memberName copyReplaceAll: '.st' with: '' asTokens: false. (packageManager allManagers anySatisfy: [ :pm | pm packageName = baseName ]) ifTrue: [ current _ imagePackageLoader new package: (packageInfo named: baseName). new _ streamPackageLoader new stream: member contentStream ascii. (new changesFromBase: current) fileIn ] ifFalse: [ self class fileIntoChangeSetNamed: baseName fromStream: member contentStream ascii setConverterForCode. ]. packageManager registerPackage: baseName. self installed: member.! ! !SARInstaller methodsFor: 'fileIn' stamp: 'yo 8/17/2004 00:33'! fileInFrom: stream "The zip has been saved already by the download. Read the zip into my instvar, then file in the correct members" | preamble postscript | [ stream position: 0. zip _ ZipArchive new readFrom: stream. preamble _ zip memberNamed: 'install/preamble'. preamble ifNotNil: [ preamble contentStream text setConverterForCode fileInFor: self announcing: 'Preamble'. self class currentChangeSet preambleString: preamble contents. ]. postscript _ zip memberNamed: 'install/postscript'. postscript ifNotNil: [ postscript contentStream text setConverterForCode fileInFor: self announcing: 'Postscript'. self class currentChangeSet postscriptString: postscript contents. ]. preamble isNil & postscript isNil ifTrue: [ (self confirm: 'No install/preamble or install/postscript member were found. Install all the members automatically?') ifTrue: [ self installAllMembers ] ]. ] ensure: [ stream close ]. ! ! !SARInstaller class methodsFor: 'change set utilities' stamp: 'yo 8/17/2004 10:04'! fileIntoChangeSetNamed: aString fromStream: stream "We let the user confirm filing into an existing ChangeSet or specify another ChangeSet name if the name derived from the filename already exists. Duplicated from SMSimpleInstaller. Should be a class-side method." ^self withCurrentChangeSetNamed: aString do: [ :cs | | newName | newName := cs name. stream setConverterForCode. stream fileInAnnouncing: 'Loading ' , newName , ' into change set ''' , newName, ''''. stream close]! ! !SMDefaultInstaller methodsFor: 'private' stamp: 'yo 8/17/2004 10:04'! fileIn "Installing in the standard installer is simply filing in. Both .st and .cs files will file into a ChangeSet of their own. We let the user confirm filing into an existing ChangeSet or specify another ChangeSet name if the name derived from the filename already exists." | fileStream | ((unpackedFileName endsWith: (FileDirectory dot, FileStream st)) or: [unpackedFileName endsWith: (FileDirectory dot, FileStream cs)]) ifTrue:[ fileStream _ dir readOnlyFileNamed: unpackedFileName. fileStream setConverterForCode. self fileIntoChangeSetNamed: (fileStream localName sansPeriodSuffix) fromStream: fileStream. ^ self]. " ((unpackedFileName endsWith: (FileDirectory dot, FileStream multiSt)) or: [unpackedFileName endsWith: (FileDirectory dot, FileStream multiCs)]) ifTrue:[ fileStream _ dir readOnlyFileNamed: unpackedFileName. fileStream converter: UTF8TextConverter new. self fileIntoChangeSetNamed: (fileStream localName sansPeriodSuffix) fromStream: fileStream. ^ self]. " self error: 'Filename should end with a proper extension'. ! ! SARInstaller removeSelector: #fileInMemberNamedAsUTF8:!