'From Squeak3.0 of 4 February 2001 [latest update: #3545] on 21 May 2001 at 1:04:09 pm'! Stream subclass: #SocketStream instanceVariableNames: 'socket inStream outStream inDataCount outDataCount autoFlush binary ' classVariableNames: '' poolDictionaries: '' category: 'Kom-kernel'! !SocketStream commentStamp: '' prior: 0! Kom48 (Comanche beta 4.8) bolot 4/2/2001 18:47 SocketStream - some changes to gradually enable client-side work Comment from kom46: SocketStream - stream interface to Socket - HttpRequest (and other users) don't know anything about sockets bolot 12/16/1999 15:01 - re-doing the interface - inStream will replace buffer - outStream will be the buffer for sending data - nextPut:/nextPutAll: will write to outStream - flush will be required to send data - TODO - stop using buffer, eventually remove it ! !SocketStream methodsFor: 'initialize-release' stamp: 'bolot 2/5/2001 15:46'! close self flush. self socket closeAndDestroy: 30! ! !SocketStream methodsFor: 'initialize-release' stamp: 'rew 5/18/2001 17:03'! initialize self resetStatus. self autoFlushOn. self text. self resetInStream. self resetOutStream! ! !SocketStream methodsFor: 'initialize-release' stamp: 'bolot 12/16/2000 01:46'! initialize: aSocket self initialize. self socket: aSocket! ! !SocketStream methodsFor: 'initialize-release' stamp: 'rew 5/18/2001 16:39'! resetInStream inStream _ BufferStream on: (self bufferSized: 0)! ! !SocketStream methodsFor: 'initialize-release' stamp: 'rew 5/18/2001 16:39'! resetOutStream outStream _ BufferStream on: (self bufferSized: 0)! ! !SocketStream methodsFor: 'initialize-release' stamp: 'rew 5/18/2001 16:43'! resetStatus inDataCount _ 0. outDataCount _ 0! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 17:02'! autoFlushOff "Output is sent only when flush method is called" autoFlush _ false! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 17:06'! autoFlushOn "Have nextPutAll:, cr, crlf flush output buffer" autoFlush _ true! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 13:35'! binary "Set the stream to read/write binary data" self setBinary: true! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 16:45'! localAddress ^socket localAddress! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 16:45'! localPort ^socket localPort! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 16:45'! remoteAddress ^socket remoteAddress! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 16:46'! remotePort ^socket remotePort! ! !SocketStream methodsFor: 'accessing' stamp: 'bolot 2/5/2001 15:44'! socket ^socket! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 16:47'! socket: aSocket socket _ aSocket. ! ! !SocketStream methodsFor: 'accessing' stamp: 'rew 5/18/2001 13:36'! text "Set the stream to read/write text data" self setBinary: false! ! !SocketStream methodsFor: 'stream in' stamp: 'bolot 12/16/2000 03:04'! match: aString "position past the next occurrence of aString" "bolot 12/13/2000 00:49 - must begin with it" "answer if aString is found" inStream size < aString size ifTrue: [self flag: #todo. "should try to read in more, unless #atEnd" "but since atEnd is somewhat broken, don't use it yet" ^false]. (inStream contents beginsWith: aString) ifTrue: [inStream next: aString size. ^true]. ^false! ! !SocketStream methodsFor: 'stream in' stamp: 'bolot 1/4/2000 20:31'! next self atEnd ifTrue: [^nil]. inStream isEmpty ifTrue: [self pvtGetData]. ^inStream next! ! !SocketStream methodsFor: 'stream in' stamp: 'bolot 1/4/2000 20:30'! next: n | limit | [(inStream size < n) and: [ self isConnected ]] whileTrue: [self pvtGetData]. limit _ n min: inStream size. ^inStream next: limit! ! !SocketStream methodsFor: 'stream in' stamp: 'bolot 1/5/2000 15:59'! nextChunk "getData front - retrieve all data available now" inStream isEmpty ifTrue: [self pvtGetData]. ^inStream upToEnd! ! !SocketStream methodsFor: 'stream in' stamp: 'bolot 12/22/1999 17:06'! putDataBack: string | tempString | tempString _ inStream contents. self resetInStream. inStream nextPutAll: string; nextPutAll: tempString! ! !SocketStream methodsFor: 'stream in' stamp: 'rew 5/20/2001 13:29'! upTo: delim | string | (inStream includes: delim) ifTrue: ["Found the delimiter part way into buffer" string _ inStream upTo: delim. inStream next. ^string]. self isConnected not & self isDataAvailable not ifTrue: ["Never found it, and hit end of file" string _ inStream contents. self resetInStream. ^string]. "Never found it, but there's more..." self pvtGetData. ^self upTo: delim! ! !SocketStream methodsFor: 'stream in' stamp: 'rew 5/20/2001 19:24'! upToAll: delims | string | (inStream includesAll: delims) ifTrue: ["Found the delimiter part way into buffer" string _ inStream upToAll: delims. inStream next: delims size. ^string]. self isConnected not & self isDataAvailable not ifTrue: ["Never found it, and hit end of file" ^inStream upToEnd]. "Never found it, but there's more..." self pvtGetData. ^self upToAll: delims! ! !SocketStream methodsFor: 'stream in' stamp: 'rew 5/18/2001 12:27'! upToEnd | rest | [self isConnected or: [self isDataAvailable]] whileTrue:[self pvtGetData]. rest _ inStream contents. self resetInStream. ^rest ! ! !SocketStream methodsFor: 'stream out' stamp: 'bolot 12/27/1999 12:17'! cr self nextPutAll: String cr! ! !SocketStream methodsFor: 'stream out' stamp: 'bolot 8/11/1999 22:13'! crlf self nextPutAll: String crlf! ! !SocketStream methodsFor: 'stream out' stamp: 'rew 5/21/2001 12:22'! flush socket isOtherEndClosed ifFalse: [socket sendData: (outStream contents)]. "isOtherEndConnected does not exist in 2.8 image" "socket isOtherEndConnected ifTrue: [socket sendData: outStream contents]." self incOutDataCountBy: outStream contents size. self resetOutStream! ! !SocketStream methodsFor: 'stream out' stamp: 'rew 5/18/2001 18:09'! lf self nextPutAll: (String with: Character lf)! ! !SocketStream methodsFor: 'stream out' stamp: 'rew 5/19/2001 11:24'! nextPut: char self nextPutAll: (self bufferClass with: char)! ! !SocketStream methodsFor: 'stream out' stamp: 'rew 5/18/2001 17:07'! nextPutAll: string outStream nextPutAll: string. self isAutoFlushOn ifTrue: [self flush]! ! !SocketStream methodsFor: 'private' stamp: 'rew 5/18/2001 16:40'! bufferClass ^self isBinary ifTrue:[ByteArray] ifFalse:[String]! ! !SocketStream methodsFor: 'private' stamp: 'rew 5/18/2001 16:40'! bufferSized: anInteger ^self bufferClass new: anInteger! ! !SocketStream methodsFor: 'private' stamp: 'rew 5/18/2001 18:34'! pvtGetData | data buffer bytesRead| buffer _ self bufferSized: 4000. (socket isConnected and: [socket dataAvailable not]) ifTrue:[socket waitForDataUntil: 100]. bytesRead _ socket receiveDataInto: buffer. data _ buffer copyFrom: 1 to: bytesRead. inStream nextPutAll: data. self incInDataCountBy: bytesRead. ^data! ! !SocketStream methodsFor: 'private' stamp: 'rew 5/18/2001 17:11'! setBinary: aBoolean "Set the stream to handle binary or text" binary _ aBoolean. self resetInStream. self resetOutStream! ! !SocketStream methodsFor: 'testing' stamp: 'bolot 12/16/2000 01:50'! atEnd ^self isConnected not and: [inStream isEmpty and: [self isDataAvailable not]]! ! !SocketStream methodsFor: 'testing' stamp: 'rew 5/18/2001 17:05'! isAutoFlushOn ^autoFlush! ! !SocketStream methodsFor: 'testing' stamp: 'rew 5/18/2001 17:11'! isBinary ^binary! ! !SocketStream methodsFor: 'testing' stamp: 'bolot 2/5/2001 15:47'! isConnected ^self socket isConnected! ! !SocketStream methodsFor: 'testing' stamp: 'bolot 2/5/2001 15:47'! isDataAvailable ^self socket dataAvailable! ! !SocketStream methodsFor: 'testing' stamp: 'bolot 2/5/2001 15:48'! isOtherEndConnected ^self socket isOtherEndConnected! ! !SocketStream methodsFor: 'testing' stamp: 'rew 5/18/2001 13:23'! isText ^self isBinary not! ! !SocketStream methodsFor: 'statistics' stamp: 'bolot 12/16/2000 03:03'! inBytes "actual number of bytes read by the app" ^self inDataCount - inStream size! ! !SocketStream methodsFor: 'statistics' stamp: 'rew 5/18/2001 17:08'! inDataCount ^inDataCount! ! !SocketStream methodsFor: 'statistics' stamp: 'rew 5/18/2001 17:09'! incInDataCountBy: increment "increment inDataCount by" inDataCount _ inDataCount + increment! ! !SocketStream methodsFor: 'statistics' stamp: 'rew 5/18/2001 17:09'! incOutDataCountBy: increment "increment outDataCount by" outDataCount _ outDataCount + increment! ! !SocketStream methodsFor: 'statistics' stamp: 'rew 5/18/2001 17:10'! outDataCount ^outDataCount! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! SocketStream class instanceVariableNames: ''! !SocketStream class methodsFor: 'instance creation' stamp: 'bolot 12/16/1999 18:06'! on: socket "create a socket stream on a server socket" "for HTTP style header must call readHeader explicitly" ^self basicNew initialize: socket! !