Add lack.util.writer-stream for treating delayed responding writer as a stream.

This commit is contained in:
Eitaro Fukamachi 2016-09-27 12:35:57 +09:00
parent 82dd7c4b24
commit 6159d4a5ff
3 changed files with 90 additions and 0 deletions

View file

@ -0,0 +1,12 @@
(in-package :cl-user)
(defpackage :lack-util-writer-stream-asd
(:use :cl :asdf))
(in-package :lack-util-writer-stream-asd)
(defsystem lack-util-writer-stream
:version "0.1"
:author "Eitaro Fukamachi"
:license "LLGPL"
:depends-on (:trivial-gray-streams
:babel)
:components ((:file "src/util/writer-stream")))

View file

@ -0,0 +1,50 @@
(in-package :cl-user)
(defpackage lack.util.writer-stream
(:use :cl)
(:import-from :trivial-gray-streams
:fundamental-output-stream
:stream-write-byte
:stream-write-sequence
:stream-write-char
:stream-write-string
:stream-finish-output
:open-stream-p)
(:import-from :babel
:string-to-octets)
(:export :writer-stream
:make-writer-stream))
(in-package :lack.util.writer-stream)
(defclass writer-stream (fundamental-output-stream)
((writer :type function
:initarg :writer
:accessor writer-stream-writer)
(closed-p :type boolean
:initform nil
:accessor writer-stream-closed-p)))
(defun make-writer-stream (writer)
(check-type writer function)
(make-instance 'writer-stream :writer writer))
(defmethod stream-write-byte ((stream writer-stream) byte)
(funcall (writer-stream-writer stream)
(make-array 1 :element-type '(unsigned-byte 8) :initial-contents (list byte))))
(defmethod stream-write-sequence ((stream writer-stream) sequence start end &key)
(funcall (writer-stream-writer stream) sequence :start start :end end))
(defmethod stream-write-char ((stream writer-stream) char)
(let ((string (make-string 1 :initial-element char)))
(funcall (writer-stream-writer stream) (babel:string-to-octets string))))
(defmethod stream-write-string ((stream writer-stream) string &optional (start 0) (end (length string)))
(funcall (writer-stream-writer stream) (babel:string-to-octets string :start start :end end)))
(defmethod stream-finish-output ((stream writer-stream))
(funcall (writer-stream-writer stream) nil :close t)
(setf (writer-stream-closed-p stream) t)
nil)
(defmethod open-stream-p ((stream writer-stream))
(not (writer-stream-closed-p stream)))

28
t/util/writer-stream.lisp Normal file
View file

@ -0,0 +1,28 @@
(in-package :cl-user)
(defpackage t-lack.util.writer-stream
(:use :cl
:lack.util.writer-stream
:prove))
(in-package :t-lack.util.writer-stream)
(plan 6)
(let* ((bodies '())
(writer
(lambda (body &key &allow-other-keys)
(push body bodies)))
(stream (make-writer-stream writer)))
(is-type stream 'writer-stream)
(ok (open-stream-p stream))
(write-sequence #(72 101 108 108 111) stream)
(write-string "World" stream)
(is bodies '(#(87 111 114 108 100) #(72 101 108 108 111))
:test #'equalp)
(write-char #\! stream)
(is bodies '(#(33) #(87 111 114 108 100) #(72 101 108 108 111))
:test #'equalp)
(ok (open-stream-p stream))
(finish-output stream)
(ok (not (open-stream-p stream))))
(finalize)