summaryrefslogtreecommitdiff
path: root/vim/bundle/slimv/swank-clojure/swank/util/io.clj
blob: 6247eec6e6047ec925f152bfc80e620fee1466a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
(ns swank.util.io
  (:use [swank util]
        [swank.util.concurrent thread])
  (:import [java.io StringWriter Reader PrintWriter]))

(defn read-chars
  ([rdr n] (read-chars rdr n false))
  ([#^Reader rdr n throw-exception]
     (let [cbuf (make-array Character/TYPE n)]
       (loop [i 0]
	 (let [size (.read rdr cbuf i (- n i))]
	   (cond
	    (neg? size) (if throw-exception
			  (throw throw-exception)
			  (String. cbuf 0 i))
	    (= (+ i size) n) (String. cbuf)
	    :else (recur (+ i size))))))))

(defn call-on-flush-stream
  "Creates a stream that will call a given function when flushed."
  ([flushf]
     (let [closed? (atom false)
           #^PrintWriter stream
           (PrintWriter.
            (proxy [StringWriter] []
              (close [] (reset! closed? true))
              (flush []
                     (let [#^StringWriter me this
                           len (.. me getBuffer length)]
                       (when (> len 0)
                         (flushf (.. me getBuffer (substring 0 len)))
                         (.. me getBuffer (delete 0 len)))))))]
       (dothread
        (thread-set-name "Call-on-write Stream")
        (continuously
         (Thread/sleep 200)
         (when-not @closed?
           (.flush stream))))
       stream))
  {:tag PrintWriter})