+
+(defgeneric stream-read-sequence (stream seq &optional start end)
+ (:documentation
+ "This is like CL:READ-SEQUENCE, but for Gray streams."))
+
+;;; Destructively modify SEQ by reading elements from STREAM. That
+;;; part of SEQ bounded by START and END is destructively modified by
+;;; copying successive elements into it from STREAM. If the end of
+;;; file for STREAM is reached before copying all elements of the
+;;; subsequence, then the extra elements near the end of sequence are
+;;; not updated, and the index of the next element is returned.
+(defun basic-io-type-stream-read-sequence (stream seq start end read-fun)
+ (declare (type sequence seq)
+ (type stream stream)
+ (type index start)
+ (type sequence-end end)
+ (type function read-fun)
+ (values index))
+ (let ((end (or end (length seq))))
+ (declare (type index end))
+ (etypecase seq
+ (list
+ (do ((rem (nthcdr start seq) (rest rem))
+ (i start (1+ i)))
+ ((or (endp rem) (>= i end)) i)
+ (declare (type list rem)
+ (type index i))
+ (let ((el (funcall read-fun stream)))
+ (when (eq el :eof)
+ (return i))
+ (setf (first rem) el))))
+ (vector
+ (with-array-data ((data seq) (offset-start start) (offset-end end))
+ (do ((i offset-start (1+ i)))
+ ((>= i offset-end) end)
+ (declare (type index i))
+ (let ((el (funcall read-fun stream)))
+ (when (eq el :eof)
+ (return (+ start (- i offset-start))))
+ (setf (aref data i) el))))))))
+
+(defmethod stream-read-sequence ((stream fundamental-character-input-stream)
+ (seq sequence)
+ &optional (start 0) (end nil))
+ (basic-io-type-stream-read-sequence stream seq start end
+ #'stream-read-char))