I always wonder the cost in terms of speed of the wrapping of streams.
Stef
On 3 mai 07, at 14:18, Damien Cassou wrote:
You would like the framework to let you chain the streams,
aren't you?
So that you have a stream which interact with another stream.
Yes, pipes of streams.
I've just created a decoder in a trait and it is highly pluggable :-) Let's see an example:
testCombineWithNumberReader | stream | stream := NSSelectStream selectBlock: [:each | each even] inputStream: (NSNumberReader inputStream: (NSReadableCollectionStream on: '1420 245 211 12')). self deny: stream atEnd. self assert: stream peek = 1420. self assert: stream next = 1420. self deny: stream atEnd. self assert: stream peek = 12. self assert: stream next = 12. self assert: stream atEnd
This code uses three stream:
- NSSelectStream reads its input and only returns elements matching
the selectBlock (http://wiki.cs.uiuc.edu/PatternStories/SelectStream)
- NSNumberReader is waiting for characters on its input and converts
them to numbers. Spaces separate numbers.
- NSReadableCollectionStream is equivalent to ReadStream.
The implementation part is really cool. NSNumberReader is made of:
- a constructor
- 3 getters and 3 setters
- a #realNext method:
NSNumberReader>>realNext |number| [self inputStream peekFor: Character space] whileTrue. self inputStream atEnd ifTrue: [NSStreamAtEndError signal]. number := (self inputStream upTo: Character space) asNumber. ^ number
That's all. Nothing more is needed to create NSNumberReader. The other methods come from a trait.
NSSelectBlock is implemented in exactly the same way. It's #realNext is:
NSSelectBlock>>realNext self inputStream do: [:each | (selectBlock value: each) ifTrue: [^ each]]. NSStreamAtEndError signal.
What do you think?
-- Damien Cassou