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 ofunicode-ls-stream
. It ensures that thefile-stream
slot of the stream contains a Common Lispfile-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 usesopen-unicode-ls-stream
in a similar manner to the Common Lisp macrowith-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 usesconfig.sys
as a source of input to an instance of our stream, and outputs it to the fileunicode-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 fileC:\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 useAlt+X What Cursor Position
orCtrl+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))))