Extending READ-SEQUENCE and WRITE-SEQUENCE


Table of Contents

Overview
Functional Reference
CCL:STREAM-READ-LIST [Generic Function]
CCL:STREAM-WRITE-LIST [Generic Function]
CCL:STREAM-READ-VECTOR [Generic Function]
CCL:STREAM-WRITE-VECTOR [Generic Function]
Notes
Example

Overview

The “Gray Streams” API is based on an informal proposal that was made before ANSI CL adopted the READ-SEQUENCE and WRITE-SEQUENCE functions; as such, there is no “standard” way for the author of a Gray stream class to improve the performance of these functions by exploiting knowledge of the stream's internals (e.g., the buffering mechanism it uses.)

In the absence of any such knowledge, READ-SEQUENCE and WRITE-SEQUENCE are effectively just convenient shorthand for a loop which calls READ-CHAR/READ-BYTE/WRITE-CHAR/WRITE-BYTE as appropriate. The mechanism described below allows subclasses of FUNDAMENTAL-STREAM to define more specialized (and presumably more efficient) behavior.

Functional Reference

CCL:STREAM-READ-LIST [Generic Function]

Syntax

stream-read-list stream list count

Description

Should try to read up to count elements from stream into the list list, returning the number of elements actually read (which may be less than count in case of a premature end-of-file.)

Arguments

 

stream

a stream, presumably a fundamental-input-stream.

list

a list. When a STREAM-READ-LIST method is called by READ-SEQUENCE, this argument is guaranteed to be a proper list.

count

a non-negative integer. When a STREAM-READ-LIST method is called by READ-SEQUENCE, this argument is guaranteed not to be greater than the length of the list.

CCL:STREAM-WRITE-LIST [Generic Function]

Syntax

stream-write-list stream list count

Description

should try to write the first count elements of list to stream. The return value of this method is ignored.

Arguments

 

stream

a stream, presumably a fundamental-ouput-stream.

list

a list. When a STREAM-WRITE-LIST method is called by WRITE-SEQUENCE, this argument is guaranteed to be a proper list.

count

a non-negative integer. When a STREAM-WRITE-LIST method is called by WRITE-SEQUENCE, this argument is guaranteed not to be greater than the length of the list.

CCL:STREAM-READ-VECTOR [Generic Function]

Syntax

stream-read-vector stream vector start end

Description

should try to read successive elements from stream into vector, starting at element start (inclusive) and continuing through element end (exclusive.) Should return the index of the vector element beyond the last one stored into, which may be less than end in case of premature end-of-file.

Arguments

 

stream

a stream, presumably a fundamental-input-stream

vector

a vector. When a STREAM-READ-VECTOR method is called by READ-SEQUENCE, this argument is guaranteed to be a simple one-dimensional array.

start

a non-negative integer. When a STREAM-READ-VECTOR method is called by READ-SEQUENCE, this argument is guaranteed to be no greater than end and not greater than the length of vector.

end

a non-negative integer. When a STREAM-READ-VECTOR method is called by READ-SEQUENCE, this argument is guaranteed to be no less than end and not greater than the length of vector.

CCL:STREAM-WRITE-VECTOR [Generic Function]

Syntax

stream-write-vector stream vector start end

Description

should try to write successive elements of vector to stream, starting at element start (inclusive) and continuing through element end (exclusive.)

Arguments

 

stream

a stream, presumably a fundamental-output-stream

vector

a vector. When a STREAM-WRITE-VECTOR method is called by WRITE-SEQUENCE, this argument is guaranteed to be a simple one-dimensional array.

start

a non-negative integer. When a STREAM-WRITE-VECTOR method is called by WRITE-SEQUENCE, this argument is guaranteed to be no greater than end and not greater than the length of vector.

end

a non-negative integer. When a STREAM-WRITE-VECTOR method is called by WRITE-SEQUENCE, this argument is guaranteed to be no less than end and not greater than the length of vector.

Notes

READ-SEQUENCE and WRITE-SEQUENCE do a certain amount of sanity-checking and normalization of their arguments before dispatching to one of the methods above. If an individual method can't do anything particularly clever, CALL-NEXT-METHOD can be used to handle the general case.

Example

(defclass my-string-input-stream (fundamental-character-input-stream)
  ((string :initarg :string :accessor my-string-input-stream-string)
   (index :initform 0 :accessor my-string-input-stream-index)
   (length)))
(defmethod stream-read-vector ((stream my-string-input-stream)
                               vector start end)
  (if (not (typep vector 'simple-base-string))
    (call-next-method)
    (with-slots (string index length)
      (do* ((outpos start (1+ outpos)))
           ((or (= outpos end)
                (= index length))
            outpos))
        (setf (schar vector outpos)
              (schar string index))
        (incf index)))))