Hi,
I think you don't handle the switching of streams correctly. You have to
keep track with atoms. But then you run into thread-safety issues.
(defn concat-input-stream
"Gets one or many input streams and returns a new input stream that
concatenates the given streams."
[is & streams]
(let [is (atom is)
streams (atom streams)
switch! (fn []
(locking is
(.close @is)
(reset! is (first streams))
(swap! streams rest)))
do-read (fn
([is] (if is (.read is) -1))
([is arr] (if is (.read is arr) -1))
([is arr off len] (if is (.read is arr off len) -1)))]
(proxy [java.io.InputStream] []
(close
[]
(when @is
(.close @is)
(doseq [s @streams] (.close s))))
(read
([]
(let [ch (do-read @is)]
(if (neg? ch)
(do
(switch!)
(if @is
(.read this)
-1))
ch)))
([arr]
(let [n (do-read @is arr)]
(if (neg? n)
(do
(switch!)
(if @is
(.read this arr)
-1))
n)))
([arr off len]
(let [n (do-read @is arr off len)]
(if (neg? n)
(do
(switch!)
(if @is
(.read this arr off len)
-1))
n)))))))
You could also use java.io.SequenceInputStream with a small helper.
(defn coll->enumeration
[coll]
(let [s (atom coll)]
(reify [java.util.Enumeration] []
(hasMoreElements [this]
(boolean (swap! s seq)))
(nextElement [this]
(locking this
(if-let [sq (seq @s)]
(let [e (first sq)]
(reset! s (rest sq))
e)
(throw (java.util.NoSuchElementException.))))))))
(defn concat-input-stream
"Gets one or many input streams and returns a new input stream that
concatenates the given streams."
[is & streams]
(java.io.SequenceInputStream. (coll->enumeration (cons is streams))))
All code untested.
Kind regards
Meikel
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en