Skip to content

Commit 3f4076e

Browse files
authored
Rope from stream (#2)
Make a rope from streams or pathnames
1 parent 39b2817 commit 3f4076e

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

rope.lisp

+14-1
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,22 @@
3636
;;-------;;
3737

3838
(defgeneric make-rope (source)
39-
(:documentation "Create a new rope from a string.")
39+
(:documentation "Create a new rope from a string, stream, or pathname.")
4040
(:method ((source rope))
4141
source)
42+
(:method ((source stream))
43+
(labels ((read-leaves (&optional acc)
44+
(let* ((string (make-string *long-leaf*))
45+
(length (read-sequence string source))
46+
(leaf (make-instance 'leaf :length length :string (subseq string 0 length))))
47+
(if (= *long-leaf* length)
48+
(read-leaves (cons leaf acc))
49+
(cons leaf acc)))))
50+
(let ((leaves (nreverse (read-leaves))))
51+
(merge-leaves leaves 0 (length leaves)))))
52+
(:method ((source pathname))
53+
(with-open-file (s source)
54+
(make-rope s)))
4255
(:method ((source string))
4356
(let ((length (length source)))
4457
(if (<= *long-leaf* length)

test/basic.lisp

+9
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,12 @@ can be done efficiently.")
4545
(let* ((rope (rope:make-rope "0123456789")))
4646
(is (string= #\1 (rope:index-rope rope 1)))
4747
(is (string= #\9 (rope:index-rope rope 9)))))
48+
49+
(deftest read-files-and-streams ()
50+
"Test reading a file to a rope."
51+
(let* ((pathname (merge-pathnames "README.md" (asdf:system-source-directory :rope)))
52+
(rope (rope:make-rope pathname)))
53+
(is (string= (uiop:read-file-string pathname) (rope:write-rope rope nil))))
54+
(let* ((stream (make-string-input-stream *string-2*))
55+
(rope (rope:make-rope stream)))
56+
(is (string= *string-2* (rope:write-rope rope nil)))))

0 commit comments

Comments
 (0)