This interface permits the definition of new classes of streams, and programming their behavior by defining methods for the elementary stream operations. It is based on the proposal STREAM-DEFINITION-BY-USER:GENERIC-FUNCTIONS of David N. Gray to X3J13 and is supported by most Common Lisp implementations currently in use.
All symbols defined by this interface, starting with the prefix
FUNDAMENTAL-
or STREAM-
,
are exported from the package “GRAY”
and EXT:RE-EXPORT
ed from “EXT”.
Defined classes
GRAY:FUNDAMENTAL-STREAM
STREAM
and of STANDARD-OBJECT
.
Its metaclass is STANDARD-CLASS
.GRAY:FUNDAMENTAL-INPUT-STREAM
STREAM
s.
It is a subclass of GRAY:FUNDAMENTAL-STREAM
. The built-in function INPUT-STREAM-P
returns true on instances of this class. This means that when you
define a new stream class capable of doing input, you have to make it
a subclass of GRAY:FUNDAMENTAL-INPUT-STREAM
.GRAY:FUNDAMENTAL-OUTPUT-STREAM
STREAM
s.
It is a subclass of GRAY:FUNDAMENTAL-STREAM
. The built-in function OUTPUT-STREAM-P
returns true on instances of this class. This means that when you
define a new stream class capable of doing output, you have to make
it a subclass of GRAY:FUNDAMENTAL-OUTPUT-STREAM
.GRAY:FUNDAMENTAL-CHARACTER-STREAM
STREAM-ELEMENT-TYPE
is CHARACTER
. It is a subclass of
GRAY:FUNDAMENTAL-STREAM
. It defines a method on STREAM-ELEMENT-TYPE
that returns
CHARACTER
.GRAY:FUNDAMENTAL-BINARY-STREAM
STREAM-ELEMENT-TYPE
is a subtype of INTEGER
. It is a
subclass of GRAY:FUNDAMENTAL-STREAM
. When you define a subclass of GRAY:FUNDAMENTAL-BINARY-STREAM
,
you have to provide a method on STREAM-ELEMENT-TYPE
.
GRAY:FUNDAMENTAL-CHARACTER-INPUT-STREAM
GRAY:FUNDAMENTAL-CHARACTER-STREAM
and GRAY:FUNDAMENTAL-INPUT-STREAM
.GRAY:FUNDAMENTAL-CHARACTER-OUTPUT-STREAM
GRAY:FUNDAMENTAL-CHARACTER-STREAM
and GRAY:FUNDAMENTAL-OUTPUT-STREAM
.GRAY:FUNDAMENTAL-BINARY-INPUT-STREAM
GRAY:FUNDAMENTAL-BINARY-STREAM
and GRAY:FUNDAMENTAL-INPUT-STREAM
.GRAY:FUNDAMENTAL-BINARY-OUTPUT-STREAM
GRAY:FUNDAMENTAL-BINARY-STREAM
and GRAY:FUNDAMENTAL-OUTPUT-STREAM
.General generic functions defined on streams
(STREAM-ELEMENT-TYPE
stream
)
Returns the stream's element type, normally a
subtype of CHARACTER
or INTEGER
.
The method for GRAY:FUNDAMENTAL-CHARACTER-STREAM
returns CHARACTER
.
((SETF
STREAM-ELEMENT-TYPE
)
new-element-type
stream
)
Changes the stream's element type.
The default method SIGNAL
s an ERROR
.
This function is a CLISP extension (see Section 21.3.1, “Function STREAM-ELEMENT-TYPE
”).
(CLOSE
stream
&KEY
:ABORT
)
Closes the stream and flushes any associated buffers.
When you define a primary method on this
function, do not forget to CALL-NEXT-METHOD
.
(OPEN-STREAM-P
stream
)
Returns true before the stream has been closed, and
NIL
after the stream has been closed.
You do not need to add methods to this function.
(GRAY:STREAM-POSITION
stream
position
)
Just like FILE-POSITION
, but NIL
position
means inquire.
You must define a method for this function.
generic functions for character input
(GRAY:STREAM-READ-CHAR
stream
)
If a character was pushed back using GRAY:STREAM-UNREAD-CHAR
,
returns and consumes it. Otherwise returns and consumes the next
character from the stream. Returns :EOF
if the end-of-stream
is reached.
You must define a method for this function.
(GRAY:STREAM-UNREAD-CHAR
stream
char
)
Pushes char
, which must be the last character
read from the stream
, back onto the front of the stream
.
You must define a method for this function.
(GRAY:STREAM-READ-CHAR-NO-HANG
stream
)
Returns a character or :EOF
, like GRAY:STREAM-READ-CHAR
, if
that would return immediately. If GRAY:STREAM-READ-CHAR
's value is not available
immediately, returns NIL
instead of waiting.
The default method simply calls GRAY:STREAM-READ-CHAR
; this is sufficient for streams
whose GRAY:STREAM-READ-CHAR
method never blocks.
(GRAY:STREAM-PEEK-CHAR
stream
)
If a character was pushed back using GRAY:STREAM-UNREAD-CHAR
,
returns it. Otherwise returns the next character from the stream,
avoiding any side effects GRAY:STREAM-READ-CHAR
would do. Returns :EOF
if the
end-of-stream
is reached.
The default method calls GRAY:STREAM-READ-CHAR
and GRAY:STREAM-UNREAD-CHAR
; this is
sufficient for streams whose GRAY:STREAM-READ-CHAR
method has no
side-effects.
(GRAY:STREAM-LISTEN
stream
)
If a character was pushed back using GRAY:STREAM-UNREAD-CHAR
,
returns it. Otherwise returns the next character from the stream, if
already available. If no character is available immediately, or if
end-of-stream
is reached, returns NIL
.
The default method calls GRAY:STREAM-READ-CHAR-NO-HANG
and GRAY:STREAM-UNREAD-CHAR
; this is
sufficient for streams whose GRAY:STREAM-READ-CHAR
method has no
side-effects.
(GRAY:STREAM-READ-CHAR-WILL-HANG-P
stream
)
Returns NIL
if GRAY:STREAM-READ-CHAR
will return immediately.
Otherwise it returns true.
The default method calls GRAY:STREAM-READ-CHAR-NO-HANG
and GRAY:STREAM-UNREAD-CHAR
; this is
sufficient for streams whose GRAY:STREAM-READ-CHAR
method has no side-effects.
This function is a CLISP extension (see EXT:READ-CHAR-WILL-HANG-P
).
(GRAY:STREAM-READ-CHAR-SEQUENCE
stream
sequence
&OPTIONAL
[start
[end
]])
Fills the subsequence of sequence
specified by
:START
and :END
with characters consecutively read from stream
.
Returns the index of the first element of sequence
that was not
updated (=
end
, or <
end
if the stream reached its end).
sequence
is an ARRAY
of CHARACTER
s, i.e. a STRING
.
start
is a nonnegative INTEGER
and defaults to 0
.
end
is a nonnegative INTEGER
or NIL
and defaults to NIL
,
which stands for (
.
LENGTH
sequence
)
The default method repeatedly calls GRAY:STREAM-READ-CHAR
; this
is always sufficient if speed does not matter.
This function is a CLISP extension (see
EXT:READ-CHAR-SEQUENCE
).
(GRAY:STREAM-READ-LINE
stream
)
Reads a line of characters, and return two values:
the line (a STRING
, without the terminating #\Newline character),
and a BOOLEAN
value which is true if the line was terminated by
end-of-stream
instead of #\Newline.
The default method repeatedly calls GRAY:STREAM-READ-CHAR
; this
is always sufficient.
(GRAY:STREAM-CLEAR-INPUT
stream
)
Clears all pending interactive input from the
stream
, and returns true if some pending input was removed.
The default method does nothing and returns NIL
; this is
sufficient for non-interactive streams.
generic functions for character output
(GRAY:STREAM-WRITE-CHAR
stream
char
)
Writes char
.
You must define a method for this function.
(GRAY:STREAM-LINE-COLUMN
stream
)
Returns the column number where the next character
would be written (0
stands for the first column),
or NIL
if that is not meaningful for this stream.
You must define a method for this function.
(GRAY:STREAM-START-LINE-P
stream
)
Returns true if the next character would be written at the start of a new line.
The default method calls GRAY:STREAM-LINE-COLUMN
and compares its result with
0; this is sufficient for streams whose GRAY:STREAM-LINE-COLUMN
never returns NIL
.
(GRAY:STREAM-WRITE-CHAR-SEQUENCE
stream
sequence
&OPTIONAL
[start
[end
]])
Outputs the subsequence of sequence
specified
by :START
and :END
to stream
.
sequence
is an ARRAY
of CHARACTER
s, i.e. a STRING
.
start
is a nonnegative INTEGER
and defaults to 0.
end
is a nonnegative integer or NIL
and defaults to NIL
,
which stands for (
.
LENGTH
sequence
)
The default method repeatedly calls GRAY:STREAM-WRITE-CHAR
; this
is always sufficient if speed does not matter.
This function is a CLISP extension
(see EXT:WRITE-CHAR-SEQUENCE
).
(GRAY:STREAM-WRITE-STRING
stream
string
&OPTIONAL
[start
[end
]])
Outputs the subsequence of string
specified by
:START
and :END
to stream
. Returns string
.
string
is a string. start
is a nonnegative integer
and default to 0. end
is a nonnegative integer or NIL
and
defaults to NIL
, which stands for (
.
LENGTH
string
)
The default method calls
GRAY:STREAM-WRITE-CHAR-SEQUENCE
;
this is always sufficient.
(GRAY:STREAM-TERPRI
stream
)
Outputs a #\Newline character.
The default method calls GRAY:STREAM-WRITE-CHAR
; this is always
sufficient.
(GRAY:STREAM-FRESH-LINE
stream
)
Possibly outputs a #\Newline character, so as to ensure that the next character would be written at the start of a new line. Returns true if it did output a #\Newline character.
The default method calls
GRAY:STREAM-START-LINE-P
and then
GRAY:STREAM-TERPRI
if necessary; this is always
sufficient.
(GRAY:STREAM-FINISH-OUTPUT
stream
)
Ensures that any buffered output has reached its destination, and then returns.
The default method does nothing.
(GRAY:STREAM-FORCE-OUTPUT
stream
)
Brings any buffered output on its way towards its destination, and returns without waiting until it has reached its destination.
The default method does nothing.
(GRAY:STREAM-CLEAR-OUTPUT
stream
)
Attempts to discard any buffered output which has not yet reached its destination.
The default method does nothing.
(GRAY:STREAM-ADVANCE-TO-COLUMN
stream
column
)
Ensures that the next character will be written at
least at column
.
The default method outputs an appropriate amount of space characters; this is sufficient for non-proportional output.
generic functions for binary input
(GRAY:STREAM-READ-BYTE
stream
)
Returns and consumes the next integer from the
stream. Returns :EOF
if the end-of-stream
is reached.
You must define a method for this function.
(GRAY:STREAM-READ-BYTE-LOOKAHEAD
stream
)
To be called only if stream
's
STREAM-ELEMENT-TYPE
is (
or UNSIGNED-BYTE
8)(
.
Returns SIGNED-BYTE
8)T
if GRAY:STREAM-READ-BYTE
would return immediately with an
INTEGER
result. Returns :EOF
if the end-of-stream
is already
known to be reached. If GRAY:STREAM-READ-BYTE
's value is not available
immediately, returns NIL
instead of waiting.
You must define a method for this function.
This function is a CLISP extension (see
EXT:READ-BYTE-LOOKAHEAD
).
(GRAY:STREAM-READ-BYTE-WILL-HANG-P
stream
)
To be called only if stream
's
STREAM-ELEMENT-TYPE
is (
or UNSIGNED-BYTE
8)(
.
Returns SIGNED-BYTE
8)NIL
if GRAY:STREAM-READ-BYTE
will return immediately.
Otherwise it returns true.
The default method calls GRAY:STREAM-READ-BYTE-LOOKAHEAD
; this is always sufficient.
This function is a CLISP extension (see EXT:READ-BYTE-WILL-HANG-P
).
(GRAY:STREAM-READ-BYTE-NO-HANG
stream
)
To be called only if stream
's
STREAM-ELEMENT-TYPE
is (
or UNSIGNED-BYTE
8)(
.
Returns an SIGNED-BYTE
8)INTEGER
or :EOF
, like GRAY:STREAM-READ-BYTE
, if that would
return immediately. If GRAY:STREAM-READ-BYTE
's value is not available immediately,
returns NIL
instead of waiting.
The default method calls GRAY:STREAM-READ-BYTE
if GRAY:STREAM-READ-BYTE-LOOKAHEAD
returns true;
this is always sufficient.
This function is a CLISP extension (see EXT:READ-BYTE-NO-HANG
).
(GRAY:STREAM-READ-BYTE-SEQUENCE
stream
sequence
&OPTIONAL
[start
[end
[no-hang
[interactive
]]]])
Fills the subsequence of sequence
specified by
:START
and :END
with integers consecutively read from stream
.
Returns the index of the first element of sequence
that was not
updated (=
end
, or <
end
if the stream reached its end).
sequence
is an ARRAY
of INTEGER
s.
start
is a nonnegative INTEGER
and defaults to 0.
end
is a nonnegative INTEGER
or NIL
and defaults to NIL
,
which stands for (
.
If LENGTH
sequence
)no-hang
is true, the function should avoid blocking and instead fill
only as many elements as are immediately available. If no-hang
is false
and interactive
is true, the function can block for reading the first
byte but should avoid blocking for any further bytes.
The default method repeatedly calls GRAY:STREAM-READ-BYTE
; this
is always sufficient if speed does not matter.
This function is a CLISP extension (see
EXT:READ-BYTE-SEQUENCE
).
generic functions for binary output
(GRAY:STREAM-WRITE-BYTE
stream
integer
)
Writes integer
.
You must define a method for this function.
(GRAY:STREAM-WRITE-BYTE-SEQUENCE
stream
sequence
&OPTIONAL
[start
[end
[no-hang
[interactive
]]]])
Outputs the subsequence of sequence
specified
by :START
and :END
to stream
sequence
is an ARRAY
of INTEGER
s.
start
is a nonnegative INTEGER
and defaults to 0.
end
is a nonnegative INTEGER
or NIL
and defaults to NIL
,
which stands for (
.
If LENGTH
sequence
)no-hang
is true, the function should avoid blocking and instead output
only as many elements as it can immediately proceed. If no-hang
is false
and interactive
is true, the function can block for writing the first
byte but should avoid blocking for any further bytes.
The default method repeatedly calls
GRAY:STREAM-WRITE-BYTE
; this is always
sufficient if speed does not matter.
This function is a CLISP extension (see
EXT:WRITE-BYTE-SEQUENCE
).
EXT:FILL-STREAM
As an example of the use of “GRAY” STREAM
s, CLISP
offers an additional class, EXT:FILL-STREAM
. An instance of this class
is a “formatting” STREAM
, which makes the final
output to the underlying stream look neat: indented and filled.
An instance of EXT:FILL-STREAM
is created like this:
(MAKE-INSTANCE
'EXT:FILL-STREAM
:streamstream
[:text-indent symbol-or-number] [:sexp-indent symbol-or-number-or-function])
where
stream
STREAM
where the output actually
goes.symbol-or-number
INTEGER
text
indentation or the indentation itself (defaults to 0).
symbol-or-number-or-function
When FORMAT
writes an S-expression to a
EXT:FILL-STREAM
using ~S
, and the expression's printed
representation does not fit on the current line, it is printed on
separate lines, ignoring the prescribed text indentation and
preserving spacing. When this argument is non-NIL
, the
S-expression is indented by:
Defaults to CUSTOM:*FILL-INDENT-SEXP*
, whose initial value is 1+
.
Note that, due to buffering, one must call FORCE-OUTPUT
when done with the EXT:FILL-STREAM
(and before changing the indent variable).
The former is done automatically by the macro
(with-fill-stream (fill target-stream ...) ...)
.
Example 29.1. Example of EXT:FILL-STREAM
usage
(defvar *my-indent-level*)
(with-output-to-string (out)
(let ((*print-right-margin* 20)
(*print-pretty* t)
(*my-indent-level* 2))
(with-fill-stream (fill out :text-indent '*my-indent-level*)
(format fill "~%this is some long sentence which will be broken at spaces")
(force-output fill)
(let ((*my-indent-level* 5))
(format fill "~%and properly indented to the level specified by the ~S argument which can be a ~S or an ~S - cool!"
:TEXT-INDENT 'symbol 'integer))
(format fill "~%Don't forget to call ~S on it, and/or use ~S Pretty formatting of the S-expressions printed with ~~S is preserved: ~S"
'force-output 'with-fill-stream '(defun foo (x y z) (if x (+ y z) (* y z)))))))
⇒ "
this is some long
sentence which
will be broken at
spaces
and properly
indented to
the level
specified by
the :TEXT-INDENT
argument which
can be a
SYMBOL
or an INTEGER
- cool!
Don't forget to
call FORCE-OUTPUT
on it, and/or use
WITH-FILL-STREAM
Pretty formatting
of the
S-expressions
printed with ~S
is preserved:
(DEFUN FOO (X Y Z)
(IF X (+ Y Z)
(* Y Z)))
"
These notes document CLISP version 2.41 | Last modified: 2006-10-13 |