All Manuals > LispWorks User Guide and Reference Manual > 20 User Defined Streams > 20.2 An illustrative example of user defined streams


20.2.5 Stream output

The following method for stream-write-char uses write-char to write a character to the stream. If the character written to unicode-ls-stream is a #\Newline , then the method writes a #\Line-Separator to the file stream.

(defmethod stream:stream-write-char ((stream unicode-ls-stream) 
  (write-char (if (eq char #\Newline)
              (ls-stream-file-stream stream)))

The default method for stream-write-string calls stream-write-char repeatedly to write a string to the stream. However, the following is a more efficient implementation for our stream.

(defmethod stream:stream-write-string ((stream unicode-ls-stream)
                                        string &optional (start 0)
                                        (end (length string)))
  (loop with i = start
        until (>= i end)
        do (let* ((newline (position #\Newline 
                            string :start i :end end))
                  (this-end (or newline end)))
             (write-string string (ls-stream-file-stream stream) 
                           :start i :end this-end)
             (incf i this-end)
             (when newline 
                   (stream:stream-terpri stream)
                   (incf i)))
        finally (return string)))

We do not need to define our own method for stream-terpri , as the default uses stream-write-char , and therefore works appropriately

To be useful, the stream-line-column and stream-start-line-p generic functions need to know the number of characters preceding a #\Line-Separator . However, since the LispWorks file stream records line position only by #\Newline characters, this information is not available. Hence we define the two generic functions to return nil :

(defmethod stream:stream-line-column 
  ((stream unicode-ls-stream))
(defmethod stream:stream-start-line-p 
  ((stream unicode-ls-stream))

Finally, the methods for stream-force-output , stream-finish-output and stream-clear-output are "trampolined" from the standard force-output , finish-output and clear-output functions.

(defmethod stream:stream-force-output ((stream 
  (force-output (ls-stream-file-stream stream)))
(defmethod stream:stream-finish-output ((stream 
  (finish-output (ls-stream-file-stream stream)))
(defmethod stream:stream-clear-output ((stream 
  (clear-output (ls-stream-file-stream stream)))

LispWorks User Guide and Reference Manual - 21 Dec 2011