--- a/PeekableStream.st Mon May 08 15:21:53 2006 +0200
+++ b/PeekableStream.st Mon May 08 18:54:42 2006 +0200
@@ -680,6 +680,53 @@
^ self peek
!
+nextUpTo:anObject
+ "read a collection of all objects up-to anObject and return these
+ elements, but excluding anObject.
+ The next read operation will return anObject.
+ If anObject is not encountered, all elements up to the end are read
+ and returned, and the stream is positioned at the end.
+ Compare this with #upTo: which positions behind anObject"
+
+ |answerStream element|
+
+ answerStream := WriteStream on:(self contentsSpecies new).
+ [self atEnd] whileFalse:[
+ element := self peek.
+ (element = anObject) ifTrue: [
+ ^ answerStream contents
+ ].
+ answerStream nextPut:element.
+ self next.
+ ].
+ ^ answerStream contents
+
+ "
+ |s|
+ s := ReadStream on:#(1 2 3 4 5 6 7 8).
+ Transcript showCR:(s nextUpTo:4).
+ Transcript showCR:s next
+
+ |s|
+ s := ReadStream on:#(1 2 3 4 5 6 7 8).
+ Transcript showCR:(s upTo:4).
+ Transcript showCR:s next
+
+ |s|
+ s := ReadStream on:#(1 2 3 4 5 6 7 8).
+ Transcript showCR:(s nextUpTo:9).
+ Transcript showCR:s next
+
+ |s|
+ s := ReadStream on:#(1 2 3 4 5 6 7 8).
+ Transcript showCR:(s upTo:9).
+ Transcript showCR:s next
+ "
+
+ "Created: 24.1.1997 / 14:08:35 / cg"
+ "Modified: 24.1.1997 / 14:09:49 / cg"
+!
+
peek
"return the next element of the stream without advancing (i.e.
the following send of next will return this element again.)
@@ -699,6 +746,18 @@
^ false
!
+peekOrNil
+ "like #peek, this returns the next readAhead element, if available.
+ However, unlike #peek, this does not raise an atEnd-query signal - even
+ if handled. Instead, nil is returned immediately."
+
+ self atEnd ifTrue:[^ nil].
+ ^ self peek
+
+ "Created: / 5.3.1998 / 02:56:49 / cg"
+ "Modified: / 5.3.1998 / 13:45:07 / cg"
+!
+
upToMatching:aBlock
"Return the next elements up to but not including the next element
for which aBlock returns true.
@@ -753,10 +812,144 @@
"Modified: 4.1.1997 / 23:38:05 / cg"
! !
+!PeekableStream methodsFor:'reading-strings'!
+
+nextAlphaNumericWord
+ "read the next word (i.e. up to non letter-or-digit).
+ Return a string containing those characters.
+ Any leading non-alphaNumeric chars are skipped."
+
+ |s c|
+
+ [self atEnd
+ or:[(c := self peek) isLetterOrDigit]] whileFalse:[
+ self next
+ ].
+
+ self atEnd ifTrue:[^ nil].
+
+ s := ''.
+
+ [self atEnd not
+ and:[(c := self peek) isLetterOrDigit]] whileTrue:[
+ s := s copyWith:c.
+ self next
+ ].
+
+ s size == 0 ifTrue:[^ nil].
+ ^ s.
+
+ "
+ |s|
+
+ s := 'hello world 1234 foo1 foo2' readStream.
+ [s atEnd] whileFalse:[
+ Transcript showCR:(s nextAlphaNumericWord).
+ ].
+ "
+
+ "
+ |s|
+
+ s := 'hello +++ #world ###123###abc### 1234 foo1 foo2' readStream.
+ [s atEnd] whileFalse:[
+ Transcript showCR:(s nextAlphaNumericWord).
+ ].
+ "
+
+ "Modified: 15.5.1996 / 17:51:42 / cg"
+!
+
+nextMatching:matchBlock1 thenMatching:matchBlock2
+ "read the next word. The first character must match matchBlock1,
+ remaining characters must match matchBlock2.
+ Return a string containing those characters."
+
+ |s c|
+
+ self atEnd ifTrue:[^ nil].
+ (matchBlock1 value:self peek) ifFalse:[^ nil].
+
+ s := self next asString.
+
+ [self atEnd not
+ and:[matchBlock2 value:(c := self peek)]] whileTrue:[
+ s := s copyWith:c.
+ self next
+ ].
+
+ s size == 0 ifTrue:[^ nil].
+ ^ s.
+
+ "
+ |s|
+
+ s := 'hello_world_1234 foo1 foo2' readStream.
+ s nextMatching:[:c | c isLetter] thenMatching:[:c | c isLetterOrDigit or:[c == $_]].
+ "
+!
+
+nextSymbol
+ "read the next selector-symbol (i.e. up to non letter-or-digit).
+ Return a string containing those characters.
+ Any leading non-alphaNumeric chars are skipped."
+
+ |symbol c symbolStream|
+
+ [self atEnd
+ or:[(c := self peek) isLetterOrDigit]] whileFalse:[
+ self next
+ ].
+
+ self atEnd ifTrue:[^ nil].
+
+ symbolStream := '' writeStream.
+
+ [self atEnd not
+ and:[(c := self peek) isLetterOrDigit or:[c == $:]]] whileTrue:[
+ symbolStream nextPut:c.
+ self next
+ ].
+
+ symbol := symbolStream contents.
+ symbol size == 0 ifTrue:[^ nil].
+ ^ symbol.
+
+ "
+ |s|
+
+ s := 'hello: world 1234 foo1 foo2:' readStream.
+ [s atEnd] whileFalse:[
+ Transcript showCR:(s nextSymbol).
+ ].
+ "
+
+ "
+ |s|
+
+ s := 'hello +++ #world ###123###abc### 1234 foo1 foo2' readStream.
+ [s atEnd] whileFalse:[
+ Transcript showCR:(s nextAlphaNumericWord).
+ ].
+ "
+
+ "Modified: 15.5.1996 / 17:51:42 / cg"
+!
+
+nextWord
+ "return the next characters which form an alphanumeric word
+ (i.e. everything upTo (but excluding) the next non alphanumeric
+ element)"
+
+ ^ self nextAlphaNumericWord
+
+ "Modified: 15.5.1996 / 17:39:32 / cg"
+! !
+
!PeekableStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/PeekableStream.st,v 1.28 2005-04-25 14:31:26 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/PeekableStream.st,v 1.29 2006-05-08 16:54:42 stefan Exp $'
! !
PeekableStream initialize!