(defn coll->enumeration [coll]
  (clojure.lang.SeqEnumeration. coll))

On Friday, July 13, 2012 7:13:54 AM UTC-7, Meikel Brandmeyer (kotarak) 
wrote:
>
> 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 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