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


20.2.6 Instantiating the stream

Now that the stream class has been defined, and all the methods relevant to it have been set up, we can create an instance of our user defined stream to test it. The following function takes a filename and optionally a stream direction as its arguments and makes an instance of unicode-ls-stream . It ensures that the file-stream slot of the stream contains a Common Lisp file-stream capable of reading from or writing to a file given by the filename argument.

(defun open-unicode-ls-file (filename &key (direction :input))
  (make-instance 'unicode-ls-stream :file-stream 
    (open filename 
          :direction direction 
          :external-format :unicode 
          :element-type 'simple-char)))

The following macro uses open-unicode-ls-stream in a similar manner to the Common Lisp macro with-open-file :

(defmacro with-open-unicode-ls-file ((var filename
                                        &key (direction :input)) 
                                        &body body)
  `(let ((,var (open-unicode-ls-file ,filename 
                :direction ,direction)))
         (progn ,@body)
       (close ,var)))

We now have the required functions and macros to test our user defined stream. The following code uses config.sys as a source of input to an instance of our stream, and outputs it to the file unicode-ls.out , changing all occurrences of #\Newline to #\Line-Separator in the process.

(with-open-unicode-ls-file (ss "C:\\unicode-ls.out" 
                              :direction :output)
   (write-line "-*- Encoding: Unicode; -*-" ss)
   (with-open-file (ii "C:\\config.sys")   ; Don't edit this file!
     (loop with line = nil
           while (setf line (read-line ii nil nil))
           do (write-line line ss))))

After running the above code, if your load the file C:\unicode-ls.out into an editor (for example, a LispWorks editor), you can see the line separator used instead of CR/LF. Most editors do not yet recognize the Unicode Line Separator character yet. In some editors it appears as a blank glyph, whereas in the LispWorks editor it appears as <2028> . In LispWorks you can use Alt+X What Cursor Position or Ctrl+X = to identify the unprintable characters.

You can also use the follow code to print out the contents of the new file line by line.

(with-open-unicode-ls-file (ss "C:\\unicode-ls.out")
   (loop while (when-let (line (read-line ss nil nil))
                 (write-line line))))


LispWorks User Guide and Reference Manual - 22 Dec 2009