class: LineNumberReadStream
added: #upToAll_positionBefore:
removed: #peekOrNil
changed:
#initialize
#position:
#skip:
category of:
#position:
#skip:
Fix #upToAll_positionBefore:
--- a/LineNumberReadStream.st Sat Jul 26 10:13:10 2014 +0200
+++ b/LineNumberReadStream.st Tue Sep 16 13:05:26 2014 +0200
@@ -129,22 +129,49 @@
lineNumber := 1.
(inputStream isPositionable) ifTrue:[
- lineStartPosition := inputStream position.
+ lineStartPosition := inputStream position.
].
filter := [:char |
-
- char == Character cr ifTrue:[
- lineNumber := lineNumber + 1.
- inputStream isPositionable ifTrue:[
- lineStartPosition := inputStream position.
- ].
- ].
- char
- ].
+ char == Character cr ifTrue:[
+ lineNumber := lineNumber + 1.
+ lineStartPosition notNil ifTrue:[
+ lineStartPosition := inputStream position.
+ ].
+ ].
+ char
+ ].
"Modified: 11.1.1997 / 16:58:42 / cg"
! !
+!LineNumberReadStream methodsFor:'positioning'!
+
+position:aPosition
+ "this method fails if inputStream is not positionable"
+
+ readAhead := nil.
+ inputStream position:aPosition.
+ (lineStartPosition notNil and:[aPosition < lineStartPosition]) ifTrue:[
+ "we detect backPosition over a single line, but not over multiple lines and
+ no forward positioning!!"
+ lineNumber := lineNumber - 1.
+ lineStartPosition := aPosition.
+ ].
+!
+
+skip:numberToSkip
+ "this method fails if inputStream is not positionable"
+
+ readAhead := nil.
+ inputStream skip:numberToSkip.
+ (lineStartPosition notNil and:[numberToSkip < lineStartPosition negated]) ifTrue:[
+ "we detect backPosition over a single line, but not over multiple lines and
+ no forward positioning!!"
+ lineNumber := lineNumber - 1.
+ lineStartPosition := lineStartPosition + numberToSkip.
+ ].
+! !
+
!LineNumberReadStream methodsFor:'queries'!
atEnd
@@ -156,34 +183,48 @@
isLineNumberReadStream
^ true
-!
+! !
+
+!LineNumberReadStream methodsFor:'reading'!
+
+upToAll_positionBefore:aCollection
+ "read until a subcollection consisisting of the elements in aCollection is encountered.
+ Return everything read excluding the elements in aCollection.
+ The position is left before the collection; i.e. the next
+ read operations will return those elements.
+ If no such subcollection is encountered, all elements up to the end
+ are read and returned.
+ See also #throughAll: which also reads up to some objects
+ but positions behind it and DOES include it in the returned
+ collection.
-peekOrNil
- "peek ahead for the next character, or return nil"
+ This is a copy from PositionableStream>>#upToAll_positionBefore:.
+ It fails if inputStream is not positionable"
+
+ |answerStream element last|
- readAhead notNil ifTrue:[
- ^ readAhead
+ last := aCollection last.
+ answerStream := WriteStream on:(self contentsSpecies new:100).
+ [(element := self nextOrNil) notNil] whileTrue:[
+ answerStream nextPut:element.
+ (element = last and:[answerStream endsBeforePositionWith:aCollection]) ifTrue:[
+ |backStep|
+ backStep := aCollection size negated.
+ self skip:backStep.
+ answerStream skip:backStep.
+ ^ answerStream contents
+ ].
].
- ^ inputStream peekOrNil
-!
-
-position:aPosition
- readAhead := nil.
- inputStream position:aPosition
-!
-
-skip:numberToSkip
- readAhead := nil.
- inputStream skip:numberToSkip
+ ^ answerStream contents
! !
!LineNumberReadStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/LineNumberReadStream.st,v 1.10 2014-02-20 07:03:30 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/LineNumberReadStream.st,v 1.11 2014-09-16 11:05:26 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/LineNumberReadStream.st,v 1.10 2014-02-20 07:03:30 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/LineNumberReadStream.st,v 1.11 2014-09-16 11:05:26 stefan Exp $'
! !