initial checkin
authorClaus Gittinger <cg@exept.de>
Fri, 21 May 2010 14:35:52 +0200
changeset 2449 1401dd52e200
parent 2448 f21170d2e545
child 2450 ffafc2eb3364
initial checkin
MultiReadStream.st
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MultiReadStream.st	Fri May 21 14:35:52 2010 +0200
@@ -0,0 +1,118 @@
+"{ Package: 'stx:libbasic2' }"
+
+PeekableStream subclass:#MultiReadStream
+	instanceVariableNames:'streamStack'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Streams-Misc'
+!
+
+!MultiReadStream class methodsFor:'documentation'!
+
+documentation
+"
+    Stacked streams. At any time, another stream can be stacked onto
+    a stream stack. Making this streams contents to be returned before the
+    rest. To the stream reader, this looks like a bunch of embedded streams.
+
+    Useful when reading files which include each other, or to handle
+    define-macro expansion in a c-parser.
+
+    [instance variables:]
+"
+
+    "Created: / 21-05-2010 / 14:34:48 / cg"
+!
+
+examples
+"
+    |s|
+
+    s := MultiReadStream on:('abcd' readStream).
+    self assert:(s peek == $a).
+    self assert:(s next == $a).
+    s pushInputStream:('1234' readStream).
+    self assert:(s next == $1).
+    self assert:(s next == $2).
+    s pushInputStream:('aa' readStream).
+    self assert:(s next == $a).
+    self assert:(s next == $a).
+    self assert:(s atEnd not).
+    self assert:(s next == $3).
+    self assert:(s next == $4).
+    self assert:(s next == $b).
+    self assert:(s next == $c).
+    self assert:(s next == $d).
+    self assert:(s atEnd).
+    self assert:(s peek == nil).
+    self assert:(s next == nil).
+"
+
+    "Created: / 21-05-2010 / 14:27:53 / cg"
+! !
+
+!MultiReadStream class methodsFor:'instance creation'!
+
+on:aReadStream
+    ^ self basicNew pushInputStream:aReadStream
+
+    "Created: / 21-05-2010 / 14:26:03 / cg"
+! !
+
+!MultiReadStream methodsFor:'private'!
+
+checkCurrentStreamAtEnd
+    [streamStack notEmpty and:[streamStack last atEnd]] whileTrue:[
+        self popInputStream
+    ].
+
+    "Created: / 21-05-2010 / 14:30:20 / cg"
+! !
+
+!MultiReadStream methodsFor:'stream protocol'!
+
+atEnd
+    self checkCurrentStreamAtEnd.
+    ^ streamStack isEmpty
+
+    "Created: / 21-05-2010 / 14:31:48 / cg"
+!
+
+next
+    self checkCurrentStreamAtEnd.
+    streamStack isEmpty ifTrue:[^ self pastEndRead].
+    ^ streamStack last next
+
+    "Created: / 21-05-2010 / 14:31:23 / cg"
+!
+
+peek
+    self checkCurrentStreamAtEnd.
+    streamStack isEmpty ifTrue:[^ self pastEndRead].
+    ^ streamStack last peek
+
+    "Created: / 21-05-2010 / 14:29:06 / cg"
+! !
+
+!MultiReadStream methodsFor:'stream stacking'!
+
+popInputStream
+    streamStack removeLast
+
+    "Created: / 21-05-2010 / 14:25:30 / cg"
+!
+
+pushInputStream:aReadStream
+    streamStack isNil ifTrue:[
+        streamStack := OrderedCollection new.
+    ].
+    streamStack add:aReadStream
+
+    "Created: / 21-05-2010 / 14:25:17 / cg"
+! !
+
+!MultiReadStream class methodsFor:'documentation'!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/libbasic2/MultiReadStream.st,v 1.1 2010-05-21 12:35:52 cg Exp $'
+! !