slurp: add SLURP
[cl-slurp.git] / slurp.lisp
blobffcaaeb9711dc6eeeab07d6cb11be7a075cdf4c7
1 (defpackage "SLURP"
2 (:use "CL")
3 (:export "SLURP"
4 "STREAM-LENGTH"))
6 (in-package "SLURP")
8 (defun stream-length (stream)
9 "Returns the length of STREAM, or NIL if the length can't be determined."
10 (check-type stream stream)
11 (handler-case (file-length stream)
12 (type-error () nil)))
14 (defgeneric slurp (arg))
16 (defmethod slurp ((string string))
17 (slurp (parse-namestring string)))
19 (defmethod slurp ((pathname pathname))
20 (with-open-file (stream pathname :direction :input)
21 (slurp stream)))
23 (defmethod slurp ((stream stream))
24 (let ((stream-element-type (stream-element-type stream)))
25 (cond ((subtypep stream-element-type 'character)
26 (coerce (loop for c = (read-char stream nil nil)
27 while c
28 collect c) 'string))
30 ((subtypep stream-element-type 'unsigned-byte)
31 (let ((stream-length (stream-length stream)))
32 (if stream-length
33 (let ((seq (make-array stream-length :element-type stream-element-type)))
34 (if (= (read-sequence seq stream) stream-length)
35 seq
36 (error "short read")))
37 (let ((byte-list (loop for b = (read-byte stream nil nil)
38 while b
39 collect b)))
40 (make-array (length byte-list) :element-type stream-element-type :initial-contents byte-list)))))
42 (t (error "Unexpected stream element type ~S." stream-element-type)))))