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)))
(unwind-protect
(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))))