Skip to content

Instantly share code, notes, and snippets.

@angerman
Created December 4, 2009 22:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save angerman/249422 to your computer and use it in GitHub Desktop.
Save angerman/249422 to your computer and use it in GitHub Desktop.
(use 'clojure.contrib.duck-streams)
(in-ns 'clojure.contrib.duck-streams)
(import '(java.io File RandomAccessFile))
(import 'BufferedRandomAccessFile)
;; copied and adapted from c.c.ds
(defmulti #^{:arglist '([x])} random-access-reader class)
(defmethod random-access-reader File [#^File x]
(BufferedRandomAccessFile. x "r"))
(defmethod random-access-reader String [#^String x]
(random-access-reader (file-str x)))
(defmethod random-access-reader :default [x]
(throw (Exception. (str "Cannot open " (pr-str x) " as a reader."))))
(defn next-line [raf]
(.readLine2 raf))
(defn pos [raf]
(.getFilePointer raf))
(defn seek [raf pos]
(.seek raf pos))
(defn repeatedly-while [pred f]
"returns a lazy-seq of repeated calles to function f
while predicate pred holds."
(let [v (f)]
(if (pred v)
(lazy-seq (cons v (repeatedly-while pred f))))))
(defn lines-while [pred rar]
"returns a lazy-seq of lines, starting at the current point or rar
while the predicate pred holds"
(repeatedly-while pred (partial next-line rar)))
(defn lines [rar]
"returns a lazy-seq to lines from the current point of rar till the end"
(lines-while (comp not nil?) rar))
(defmacro save-excursion [ raf & body]
"saves the raf's current point and resets raf after execution of the body"
`(let [pos# (pos ~raf)
ret# (do ~@body)]
(seek ~raf pos#)
ret#))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment