Commit e1c8ede0 authored by Attila Lendvai's avatar Attila Lendvai
Browse files

Added support for copy-stream for START and END keyword arguments.

parent 485544d4
......@@ -47,7 +47,7 @@ the following constraints:
(:file "strings" :depends-on ("package"))
(:file "conditions" :depends-on ("package"))
(:file "hash-tables" :depends-on ("package"))
(:file "io" :depends-on ("package" "macros" "lists"))
(:file "io" :depends-on ("package" "macros" "lists" "types"))
(:file "macros" :depends-on ("package" "strings" "symbols"))
(:file "control-flow" :depends-on ("package" "definitions" "macros"))
(:file "symbols" :depends-on ("package"))
......@@ -107,17 +107,45 @@ unless it's NIL, which means the system default."
(defun copy-stream (input output &key (element-type (stream-element-type input))
(buffer-size 4096)
(buffer (make-array buffer-size :element-type element-type))
(start 0) end
"Reads data from INPUT and writes it to OUTPUT. Both INPUT and OUTPUT must
be streams, they will be passed to READ-SEQUENCE and WRITE-SEQUENCE and must have
compatible element-types."
(let ((bytes-written 0))
(check-type start non-negative-integer)
(check-type end (or null non-negative-integer))
(check-type buffer-size positive-integer)
(when (< end start)
(error "END is smaller than START in ~S" 'copy-stream))
(let ((output-position 0)
(input-position 0))
(unless (zerop start)
;; FIXME add platform specific optimization to skip seekable streams
:while (< input-position start)
:for bytes-read = (read-sequence buffer input
:end (min (length buffer)
(- start input-position)))
:do (progn
(when (zerop bytes-read)
(error "Could not read enough bytes from the input to fulfill the START requirement in ~S" 'copy-stream))
(incf input-position bytes-read))))
(assert (= input-position start))
:for bytes-read = (read-sequence buffer input)
:until (zerop bytes-read)
:while (or (null end)
(< input-position end))
:for bytes-read = (read-sequence buffer input
:end (when end
(min (length buffer)
(- end input-position))))
:do (progn
(when (zerop bytes-read)
(if end
(error "Could not read enough bytes from the input to fulfill the END requirement in ~S" 'copy-stream)
(incf input-position bytes-read)
(write-sequence buffer output :end bytes-read)
(incf bytes-written bytes-read)))
(incf output-position bytes-read)))
(when finish-output
(finish-output output))
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment