Joshua Gargus uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-jcg.124.mcz
==================== Summary ====================
Name: Collections-jcg.124
Author: jcg
Time: 1 September 2009, 12:53:11 pm
UUID: f670aae4-19f6-429c-a828-8b20b372baec
Ancestors: Collections-ar.123
#mimeEncode: no longer resets the input-stream position before encoding; that was just silly. See updated tests in CollectionsTests.
Add #base64Encoded to ByteArray (for symmetry with String).
=============== Diff against Collections-ar.123 ===============
Item was changed:
----- Method: Base64MimeConverter class>>mimeEncode: (in category 'as yet unclassified') -----
mimeEncode: aStream
"Return a ReadWriteStream of characters. The data of aStream is encoded as 65 innocuous characters. (See class comment). 3 bytes in aStream goes to 4 bytes in output."
| me |
- aStream position: 0.
me := self new dataStream: aStream.
me mimeStream: (ReadWriteStream on: (String new: aStream size + 20 * 4 // 3)).
me mimeEncode.
me mimeStream position: 0.
^ me mimeStream!
Item was added:
+ ----- Method: ByteArray>>base64Encoded (in category 'converting') -----
+ base64Encoded
+ "Encode the receiver as base64"
+ "'Hello World' asByteArray base64Encoded"
+ ^(Base64MimeConverter mimeEncode: self readStream) contents!
Joshua Gargus uploaded a new version of Network to project The Trunk:
http://source.squeak.org/trunk/Network-jcg.35.mcz
==================== Summary ====================
Name: Network-jcg.35
Author: jcg
Time: 1 September 2009, 12:46:48 pm
UUID: 03bb9532-5287-40b1-bb29-ea33c8c3d4fd
Ancestors: Network-ar.34
Use 'foo base64Encoded' instead of '(Base64MimeConverter mimeEncode: foo readStream) contents'.
=============== Diff against Network-ar.34 ===============
Item was changed:
----- Method: HTTPSocket class>>httpPost:args:user:passwd: (in category 'get the page') -----
httpPost: url args: args user: user passwd: passwd
| authorization |
+ authorization := (user , ':' , passwd) base64Encoded.
- authorization := (Base64MimeConverter mimeEncode: (user , ':' , passwd) readStream) contents.
^self
httpPostDocument: url args: args accept: '*/*'
request: 'Authorization: Basic ' , authorization , CrLf!
Item was changed:
----- Method: HTTPSocket class>>proxyUser:password: (in category 'proxy settings') -----
proxyUser: userName password: password
"Store HTTP 1.0 basic authentication credentials
Note: this is an ugly hack that stores your password
in your image. It's just enought to get you going
if you use a firewall that requires authentication"
+ | encoded |
+ encoded := (userName, ':', password) base64Encoded.
+ HTTPProxyCredentials := 'Proxy-Authorization: Basic ' , encoded, String crlf!
-
- | stream encodedStream |
- stream := ReadWriteStream on: (String new: 16).
- stream nextPutAll: userName ,':' , password.
- encodedStream := Base64MimeConverter mimeEncode: stream.
- HTTPProxyCredentials := 'Proxy-Authorization: Basic ' , (encodedStream contents) , String crlf!
Item was changed:
Stream subclass: #MailAddressTokenizer
instanceVariableNames: 'cachedToken text pos'
+ classVariableNames: 'CSNonAtom CSNonSeparators CSParens CSSpecials'
- classVariableNames: 'CSSpecials CSNonSeparators CSParens CSNonAtom'
poolDictionaries: ''
category: 'Network-RFC822'!
!MailAddressTokenizer commentStamp: '<historical>' prior: 0!
Divides an address into tokens, as specified in RFC 822. Used by MailAddressParser.!
Item was changed:
----- Method: HTTPSocket class>>httpGet:args:user:passwd: (in category 'get the page') -----
httpGet: url args: args user: user passwd: passwd
| authorization |
+ authorization := (user , ':' , passwd) base64Encoded.
- authorization := (Base64MimeConverter mimeEncode: (user , ':' , passwd) readStream) contents.
^self
httpGet: url args: args accept: '*/*'
request: 'Authorization: Basic ' , authorization , CrLf!
Item was changed:
Object subclass: #ServerDirectory
instanceVariableNames: 'server directory type user passwordHolder group moniker altURL urlObject client loaderUrl eToyUserListUrl eToyUserList keepAlive encodingName'
+ classVariableNames: 'LocalEToyBaseFolderSpecs LocalEToyUserListUrls LocalProjectDirectories Servers'
- classVariableNames: 'LocalEToyUserListUrls LocalProjectDirectories LocalEToyBaseFolderSpecs Servers'
poolDictionaries: ''
category: 'Network-RemoteDirectory'!
!ServerDirectory commentStamp: '<historical>' prior: 0!
Holds all the information needed to read or write on a directory of an internet server. I am used for FTP and HTTP (and STMP? NNTP?). The password policy is: unless it is a public password (like annomyous), clear all passwords before any snapshot. There is a way to store passwords on the disk.
server 'www.disney.com' or '123.34.56.08' or the ServerDirectory above me
(if I am a subdirectory sharing the info in a master directory)
directory 'ftp/pubs/' name of my directory within the server or superdirectory.
(for file://, directory is converted to local delimiters.)
type #ftp what you can do in this directory
user 'Jones45'
password an instance of Password.
group an Association ('group name' -> an array of ServerDirectorys)
If this first one is down, try the next one. Store on all of them. I am in the list.
moniker 'Main Squeak Directory' Description of this directory.
altURL When a FTP server holds some web pages, the altURL of those pages is often
different from the FTP directory. Put the altURL here. If the directory is
'public_html/Squeak/', the altURL might be 'www.webPage.com/~kaehler2/
Squeak/'.
urlObject An instance of a subclass of Url. It is very good at parsing complex urls.
Relative references. file:// uses this. Use this in the future instead of
server and directory inst vars.
socket nil or an FTPSocket. Only non-nil if the connection is being kept open
for multiple stores or retrievals.
loaderUrl a partial url that is ised to invoke squeak in a browser and load a project.
A normal call on some command like (aServer getFileNamed: 'foo') does not set 'socket'. Socket being nil tells it to close the connection and destroy the socket after this one transcation. If the caller stores into 'socket', then the same command does NOT close the
connection.
Call 'openKeepFTP' or 'openGroup' to store into socket and keep the connection open. It is up to the user to call 'quit' or 'closeGroup' later.
DD openKeepFTP.
Transcript cr; show: ((DD getFileNamed: '1198misc-tkKG.cs') next: 100).
Transcript cr; show: ((DD getFileNamed: '1192multFinder-tkKF.cs') next: 100).
DD quit.!
Item was changed:
----- Method: HTTPSocket class>>httpPut:to:user:passwd: (in category 'get the page') -----
httpPut: contents to: url user: user passwd: passwd
"Upload the contents of the stream to a file on the server"
| bare serverName specifiedServer port page serverAddr authorization s list header firstData length aStream command |
Socket initializeNetwork.
"parse url"
bare := (url asLowercase beginsWith: 'http://')
ifTrue: [url copyFrom: 8 to: url size]
ifFalse: [url].
serverName := bare copyUpTo: $/.
specifiedServer := serverName.
(serverName includes: $:) ifFalse: [ port := self defaultPort ] ifTrue: [
port := (serverName copyFrom: (serverName indexOf: $:) + 1
to: serverName size) asNumber.
serverName := serverName copyUpTo: $:.
].
page := bare copyFrom: (bare indexOf: $/) to: bare size.
page size = 0 ifTrue: [page := '/'].
(self shouldUseProxy: serverName) ifTrue: [
page := 'http://', serverName, ':', port printString, page. "put back together"
serverName := self httpProxyServer.
port := self httpProxyPort].
"make the request"
serverAddr := NetNameResolver addressForName: serverName timeout: 20.
serverAddr ifNil: [
^ 'Could not resolve the server named: ', serverName].
+ authorization := (user , ':' , passwd) base64Encoded.
- authorization := (Base64MimeConverter mimeEncode: (user , ':' , passwd) readStream) contents.
s := HTTPSocket new.
s connectTo: serverAddr port: port.
s waitForConnectionUntil: self standardDeadline.
Transcript cr; show: url; cr.
command :=
'PUT ', page, ' HTTP/1.0', CrLf,
self userAgentString, CrLf,
'Host: ', specifiedServer, CrLf,
'ACCEPT: */*', CrLf,
HTTPProxyCredentials,
'Authorization: Basic ' , authorization , CrLf ,
'Content-length: ', contents size printString, CrLf , CrLf ,
contents.
s sendCommand: command.
"get the header of the reply"
list := s getResponseUpTo: CrLf, CrLf ignoring: (String with: CR). "list = header, CrLf, CrLf, beginningOfData"
header := list at: 1.
"Transcript show: page; cr; show: argsStream contents; cr; show: header; cr."
firstData := list at: 3.
"dig out some headers"
s header: header.
length := s getHeader: 'content-length'.
length ifNotNil: [ length := length asNumber ].
aStream := s getRestOfBuffer: firstData totalLength: length.
s destroy. "Always OK to destroy!!"
^ header, aStream contents!
Item was changed:
OldSimpleClientSocket subclass: #HTTPSocket
instanceVariableNames: 'headerTokens headers responseCode'
+ classVariableNames: 'HTTPBlabEmail HTTPPort HTTPProxyCredentials HTTPProxyExceptions LogToTranscript ParamDelimiters'
- classVariableNames: 'LogToTranscript HTTPProxyCredentials HTTPPort HTTPBlabEmail ParamDelimiters HTTPProxyExceptions'
poolDictionaries: ''
category: 'Network-Protocols'!
!HTTPSocket commentStamp: '<historical>' prior: 0!
HTTPSockets support HTTP requests, either directly or via an HTTP proxy server. An HTTPSocket saves the parse of the last ASCII header it saw, to avoid having to parse it repeatedly.
The real action is in httpGet:accept:. See the examples in the class, especially httpFileInNewChangeSet: and httpShowGif:.!
Item was changed:
Object subclass: #OldSocket
instanceVariableNames: 'semaphore socketHandle readSemaphore writeSemaphore primitiveOnlySupportsOneSemaphore'
+ classVariableNames: 'Connected DeadServer InvalidSocket OtherEndClosed Registry RegistryThreshold TCPSocketType ThisEndClosed UDPSocketType Unconnected WaitingForConnection'
- classVariableNames: 'InvalidSocket ThisEndClosed WaitingForConnection UDPSocketType Registry TCPSocketType OtherEndClosed Connected Unconnected RegistryThreshold DeadServer'
poolDictionaries: ''
category: 'Network-Kernel'!
!OldSocket commentStamp: '<historical>' prior: 0!
A Socket represents a network connection point. Current sockets are designed to support the TCP/IP and UDP protocols
Subclasses of socket provide support for network protocols such as POP, NNTP, HTTP, and FTP. Sockets also allow you to implement your own custom services and may be used to support Remote Procedure Call or Remote Method Invocation some day.
JMM June 2nd 2000 Macintosh UDP support was added if you run open transport.
!
Item was changed:
Object subclass: #NetNameResolver
instanceVariableNames: ''
+ classVariableNames: 'DefaultHostName HaveNetwork ResolverBusy ResolverError ResolverMutex ResolverReady ResolverSemaphore ResolverUninitialized'
- classVariableNames: 'ResolverReady DefaultHostName ResolverUninitialized ResolverMutex ResolverSemaphore ResolverError ResolverBusy HaveNetwork'
poolDictionaries: ''
category: 'Network-Kernel'!
!NetNameResolver commentStamp: '<historical>' prior: 0!
This class implements TCP/IP style network name lookup and translation facilities.
Attempt to keep track of whether there is a network available.
HaveNetwork true if last attempt to contact the network was successful.
LastContact Time of that contact (totalSeconds).
haveNetwork returns true, false, or #expired. True means there was contact in the last 30 minutes. False means contact failed or was false last time we asked. Get out of false state by making contact with a server in some way (FileList or updates).!
Item was changed:
OldSocket subclass: #OldSimpleClientSocket
instanceVariableNames: 'buffer bufferPos'
+ classVariableNames: 'CR CrLf LF'
- classVariableNames: 'CrLf LF CR'
poolDictionaries: ''
category: 'Network-Kernel'!
!OldSimpleClientSocket commentStamp: '<historical>' prior: 0!
This class supports client for simple network protocols based on sending textual commands and responses. Examples of such protocols include POP3 (mail retrieval), SMTP (mail posting), HTTP (web browsing), and NTTP (network news). Some simple examples are presented as class methods, but a full-service client of some service should be implemented as a subclass.
The basic services provided by this class are:
sendCommand: -- sends a command line terminate with <CR><LF>
getResponse -- gets a single-line response to a command
getMultilineResponse -- gets a multiple line response terminated by a period
-- on a line by itself
There are variants of the getResponse commands that display lines on the screen as they are being received. Linefeeds are stripped out of all responses.
The 'get' commands above make use of an internal buffer. So intermixing these two commands and regular Socket recieve commands can cause problems.!
Item was changed:
Object subclass: #Socket
instanceVariableNames: 'semaphore socketHandle readSemaphore writeSemaphore primitiveOnlySupportsOneSemaphore'
+ classVariableNames: 'Connected DeadServer InvalidSocket OtherEndClosed Registry RegistryThreshold TCPSocketType ThisEndClosed UDPSocketType Unconnected WaitingForConnection'
- classVariableNames: 'InvalidSocket ThisEndClosed WaitingForConnection UDPSocketType Registry Unconnected Connected OtherEndClosed TCPSocketType RegistryThreshold DeadServer'
poolDictionaries: ''
category: 'Network-Kernel'!
!Socket commentStamp: 'gk 12/13/2005 00:43' prior: 0!
A Socket represents a network connection point. Current sockets are designed to support the TCP/IP and UDP protocols. Sockets are the lowest level of networking object in Squeak and are not normally used directly. SocketStream is a higher level object wrapping a Socket in a stream like protocol.
ProtocolClient and subclasses are in turn wrappers around a SocketStream to provide support for specific network protocols such as POP, NNTP, HTTP, and FTP.!
Andreas Raab uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ar.123.mcz
==================== Summary ====================
Name: Collections-ar.123
Author: ar
Time: 1 September 2009, 12:38:06 pm
UUID: e7432274-e18a-1e43-a002-f3ab261bd465
Ancestors: Collections-tfel.122
Some fixes for RWBinaryOrTextStream which was too agressive optimizing some paths. Also fixes Character>>codePoint: which has no reason to raise an exception for values > 256.
=============== Diff against Collections-tfel.122 ===============
Item was added:
+ ----- Method: RWBinaryOrTextStream>>upTo: (in category 'accessing') -----
+ upTo: anObject
+ "Answer a subcollection from the current access position to the
+ occurrence (if any, but not inclusive) of anObject in the receiver. If
+ anObject is not in the collection, answer the entire rest of the receiver."
+ | newStream element species |
+ species := isBinary ifTrue:[ByteArray] ifFalse:[String].
+ newStream := WriteStream on: (species new: 100).
+ [self atEnd or: [(element := self next) = anObject]]
+ whileFalse: [newStream nextPut: element].
+ ^newStream contents!
Item was changed:
----- Method: RWBinaryOrTextStream>>next:putAll:startingAt: (in category 'writing') -----
next: anInteger putAll: aCollection startingAt: startIndex
+ "Optimized for ByteArrays"
+ aCollection class == ByteArray
+ ifTrue:[^super next: anInteger putAll: aCollection asString startingAt: startIndex].
+ ^super next: anInteger putAll: aCollection startingAt: startIndex!
- ^super next: anInteger putAll: aCollection asString startingAt: startIndex!
Item was changed:
----- Method: RWBinaryOrTextStream>>nextPutAll: (in category 'writing') -----
nextPutAll: aCollection
+ "Optimized for ByteArrays"
+ aCollection class == ByteArray
+ ifTrue:[^super nextPutAll: aCollection asString].
+ ^super nextPutAll: aCollection!
- ^super nextPutAll: aCollection asString!
Item was changed:
----- Method: Character class>>codePoint: (in category 'instance creation') -----
codePoint: integer
+ "Return a character whose encoding value is integer.
+ For ansi compability."
+ ^self value: integer!
- "Return a character whose encoding value is integer."
- #Fundmntl.
- (0 > integer or: [255 < integer])
- ifTrue: [self error: 'parameter out of range 0..255'].
- ^ CharacterTable at: integer + 1!
Andreas Raab uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-ar.165.mcz
==================== Summary ====================
Name: Morphic-ar.165
Author: ar
Time: 31 August 2009, 8:14:46 am
UUID: 2f9b8fc0-01c7-6942-98bd-ce0775a45e9f
Ancestors: Morphic-ar.164
Disable style choices in the font chooser dialog for now since its users don't expect the font to be emphasized already. This will need more work and is too confusing at this point (and too easy to break).
=============== Diff against Morphic-ar.164 ===============
Item was changed:
----- Method: FontChooserTool>>buildWith: (in category 'toolbuilder') -----
buildWith: builder
"Create the ui for the browser"
"ToolBuilder open: self"
| windowSpec |
+ self offerStyleList ifTrue:[
+ windowSpec := self buildWindowWith: builder specs: {
+ (0@0 corner: 0.4(a)0.4) -> [self buildFontListWith: builder].
+ (0.4@0 corner: 0.8(a)0.4) -> [self buildStyleListWith: builder].
+ (0.8@0 corner: 1.0(a)0.4) -> [self buildPointSizeListWith: builder].
+ (0.0(a)0.4 corner: 1.0(a)0.88) -> [self buildPreviewPaneWith: builder].
+ (0.0(a)0.88 corner: 1@1) -> [self buildButtonBarWith: builder].
+ }.
+ ] ifFalse:[
+ windowSpec := self buildWindowWith: builder specs: {
+ (0@0 corner: 0.7(a)0.4) -> [self buildFontListWith: builder].
+ " (0.4@0 corner: 0.8(a)0.4) -> [self buildStyleListWith: builder]."
+ (0.7@0 corner: 1.0(a)0.4) -> [self buildPointSizeListWith: builder].
+ (0.0(a)0.4 corner: 1.0(a)0.8) -> [self buildPreviewPaneWith: builder].
+ (0.0(a)0.8 corner: 1@1) -> [self buildButtonBarWith: builder].
+ }.
+ ].
+ windowSpec extent: self initialExtent.
- windowSpec := self buildWindowWith: builder specs: {
- (0@0 corner: 0.4(a)0.4) -> [self buildFontListWith: builder].
- (0.4@0 corner: 0.8(a)0.4) -> [self buildStyleListWith: builder].
- (0.8@0 corner: 1.0(a)0.4) -> [self buildPointSizeListWith: builder].
- (0.0(a)0.4 corner: 1.0(a)0.88) -> [self buildPreviewPaneWith: builder].
- (0.0(a)0.88 corner: 1@1) -> [self buildButtonBarWith: builder].
- }.
- windowSpec extent: 400@300.
window := builder build: windowSpec.
+ "Yes, that's a hack. But it looks ugly with line breaks."
+ (builder widgetAt: #preview) textMorph wrapFlag: false.
^window!
Item was added:
+ ----- Method: FontChooserTool>>offerStyleList (in category 'initialize') -----
+ offerStyleList
+ "Whether to offer a choice of styles with the font.
+ Currently disabled since most of the text machinery doesn't like emphasis
+ already being applied to the font. Would have to decompose font/emphasis
+ in order for that to work."
+ ^false!
Item was changed:
----- Method: FontChooserTool>>contents (in category 'toolbuilder') -----
contents
| sample i c f |
sample := WriteStream on: ''.
f := self selectedFont ifNil:[^Text new].
f isSymbolFont ifFalse:[
sample
nextPutAll: 'the quick brown fox jumps over the lazy dog' ;cr;
nextPutAll: 'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.' ;cr;cr;
nextPutAll: '0123456789'; cr; cr;
+ nextPutAll:
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+ sed do eiusmod tempor incididunt ut labore et dolore
+ magna aliqua. Ut enim ad minim veniam, quis nostrud
+ exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ consequat. Duis aute irure dolor in reprehenderit in voluptate
+ velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ sint occaecat cupidatat non proident, sunt in culpa qui
+ officia deserunt mollit anim id est laborum.';
- nextPutAll: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.';
yourself.
] ifTrue:[
i := 0.
33 to: 255 do:[:ci |
sample nextPut: (c:=Character value: ci).
i := i + 1.
(('@Z`z' includes:c) or:[i = 30])
ifTrue:[i :=0. sample cr]].
].
sample := sample contents asText.
sample addAttribute: (TextFontReference toFont: f).
^sample!
Item was changed:
----- Method: FontChooserTool>>buildPreviewPaneWith: (in category 'toolbuilder') -----
buildPreviewPaneWith: builder
"Build the preview panel"
| textSpec |
textSpec := builder pluggableTextSpec new.
textSpec
+ name: #preview;
model: self;
getText: #contents.
^textSpec!
Item was changed:
----- Method: FontChooserTool>>initialExtent (in category 'initialize') -----
initialExtent
+ ^self offerStyleList ifTrue:[400@300] ifFalse:[300@200].!
- ^400@300!