The blip.tv video of Tom Faulhaber's "Lisp, Functional Programming,
and the State of Flow" talk from Clojure Conj showed me 'fill-queue',
which seems like a good fit here.

'fill-queue' is a way to turn input from any source into a lazy
sequence.  You give it a one-arg function, 'filler-func', which will
be called with an argument 'fill' in a separate thread.  'filler-func'
is expected to use 'fill' to push input onto a queue.  'fill-queue'
returns a lazy sequence of inputs pushed by 'filler-func', and will
block when needed.

Probably easier to just show it in action:

(use '[clojure.contrib.seq-utils :only (fill-queue)])

(defn read-until [prompt input-stream]
  (let [filler-func (fn [fill]
                      (let [x (.read input-stream)]
                        (when-not (= x -1)
                          (fill (char x))
                          (recur fill))))
        input (fill-queue filler-func)]
    (take-while #(not= % prompt) input)))

Here, 'filler-func' repeatedly reads a char from input-stream and
pushes the char onto the queue by calling 'fill' on the char, stopping
when -1 is read (signaling end of stream).  'fill-queue' returns a
lazy seq of the read chars.  'read-until' then just uses 'take-while'
to take the chars up to the prompt (here assuming prompt is a single
char).

Using me typing in the REPL as the input source:

user=> (println (read-until \x *in*))
abcdefgx
(a b c d e f g)
nil

You should be able to use this with telnet by passing in the
InputStream from the TelnetClient.  And if you wish to use a string
prompt instead, just replace the call to 'take-while' in 'read-until'
with a call to Ken's nifty 'take-until-subseq'.

(defn read-until [prompt input-stream]
  (let [filler-func (fn [fill]
                      (let [input (.read input-stream)]
                        (when-not (= input -1)
                          (fill (char input))
                          (recur fill))))
        input-seq (fill-queue filler-func)]
    (take-until-subseq input-seq prompt)))

user=> (println (read-until "hey" *in*))
abcdefghey
(a b c d e f g)
nil

On Feb 7, 6:09 pm, Andreas Kostler <andreas.koestler.le...@gmail.com>
wrote:
> Hi all,
> Is it possible to read from a lazy input sequence? I have a telnet
> connection using commons.telnet and I want to do something like:
> (def telnet (TelnetClient.))
> (def in (. telnet getInputStream))
>
> ; How do I do this?
> (def read-until
>  ; read from a lazy input sequence UNTIL prompt is matched and return
> what's been read
>  [prompt input-stream]
> ...)
>
> Every idea is appreciated :)
> Cheers
> Andreas

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to