Skip to content

Commit 99c7040

Browse files
committed
Make a rope from streams or pathnames
1 parent 39b2817 commit 99c7040

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

rope.lisp

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(in-package #:rope)
22

33
(defparameter *short-leaf* 16)
4+
(defparameter *target-leaf* 80)
45
(defparameter *long-leaf* 128)
56

67
(defclass rope ()
@@ -36,9 +37,22 @@
3637
;;-------;;
3738

3839
(defgeneric make-rope (source)
39-
(:documentation "Create a new rope from a string.")
40+
(:documentation "Create a new rope from a string, stream, or pathname.")
4041
(:method ((source rope))
4142
source)
43+
(:method ((source stream))
44+
(labels ((read-leaves (&optional acc)
45+
(let* ((string (make-string *long-leaf*))
46+
(length (read-sequence string source))
47+
(leaf (make-instance 'leaf :length length :string (subseq string 0 length))))
48+
(if (= *long-leaf* length)
49+
(read-leaves (cons leaf acc))
50+
(cons leaf acc)))))
51+
(let ((leaves (nreverse (read-leaves))))
52+
(merge-leaves leaves 0 (length leaves)))))
53+
(:method ((source pathname))
54+
(with-open-file (s source)
55+
(make-rope s)))
4256
(:method ((source string))
4357
(let ((length (length source)))
4458
(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)