FilteringStream.st
changeset 477 6124ae485dbd
parent 474 61cb199537b5
child 479 9653144c97b4
--- a/FilteringStream.st	Sat Jan 11 19:44:30 1997 +0100
+++ b/FilteringStream.st	Sat Jan 11 19:49:15 1997 +0100
@@ -12,7 +12,7 @@
 
 
 Stream subclass:#FilteringStream
-	instanceVariableNames:'inputStream outputStream filter'
+	instanceVariableNames:'inputStream outputStream filter readAhead'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Streams-Misc'
@@ -41,9 +41,25 @@
     (from which elements are read via the ReadStream protocol),
     and/or to some output (to which elements are written via
     the WriteStream protocol.
-    The FilteringStream itself performs some filtering/processing
-    on the elements as they arrive.
+
+    The FilteringStream itself performs filtering/processing
+    on the elements as they arrive, optionally suppressing
+    elements.
+
+    A FilteringStream can be operated in pull-mode, by asking
+    it for the next element; it will then ask its inputStream for
+    and element, process it and return it.
 
+    Or, in pushMode, by having someone else writing elements via
+    nextPut:; it will then process the element, and send it to its 
+    output stream.
+
+    Mixing modes does not make sense, since if pulled, data will not
+    be written to the outputStream (unless the puller does it).
+
+    The connected streams need not be real streams; anything which
+    responds to the basic Stream protocol can be connected
+    (a Transcript, a RandomNumber generator or even a Plug will do as well).
 
     [instance variables:]
         inputStream     <Stream>  the stream from which elements are read
@@ -142,6 +158,15 @@
     "Modified: 11.1.1997 / 15:33:13 / cg"
 !
 
+on:something
+    "create and return a new filteringStream, which reads from
+     something (which must be convertable to a stream)"
+
+    ^ self readingFrom:something readStream
+
+    "Created: 11.1.1997 / 19:19:34 / cg"
+!
+
 readingFrom:aReadStream
     "create and return a new filteringStream, which reads from
      another stream"
@@ -194,6 +219,15 @@
 
     |input output|
 
+    "/ readAhead input has already been filtered
+    "/ (see #atEnd)
+
+    readAhead notNil ifTrue:[
+        input := readAhead.
+        readAhead := nil.
+        ^ input
+    ].
+
     [inputStream atEnd] whileFalse:[
         "/ get an element
         input := inputStream next.
@@ -211,7 +245,7 @@
     ^ nil
 
     "Created: 2.7.1996 / 21:09:58 / cg"
-    "Modified: 11.1.1997 / 16:12:22 / cg"
+    "Modified: 11.1.1997 / 17:17:27 / cg"
 ! !
 
 !FilteringStream methodsFor:'access - push-writing'!
@@ -307,9 +341,28 @@
 atEnd
     "return true, if the receiver stream is at the end"
 
-    ^ inputStream atEnd
+    |nextElement|
+
+    readAhead notNil ifTrue:[^ false].
+
+    filter isNil ifTrue:[
+        "/ then, its easy
+        ^ inputStream atEnd
+    ].
 
-    "Modified: 11.1.1997 / 16:26:10 / cg"
+    "/ with a filter, things are more complicated, 
+    "/ since we cannot tell, without asking the filter ...
+
+
+    [inputStream atEnd] whileFalse:[
+        nextElement := inputStream next.
+        readAhead := filter value:nextElement.
+        readAhead notNil ifTrue:[^ false].
+    ].
+
+    ^ true
+
+    "Modified: 11.1.1997 / 17:16:45 / cg"
 !
 
 contentsSpecies
@@ -324,5 +377,5 @@
 !FilteringStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/FilteringStream.st,v 1.3 1997-01-11 15:50:52 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/FilteringStream.st,v 1.4 1997-01-11 18:49:15 cg Exp $'
 ! !