STREAM-ELEMENT-TYPE
EXT:MAKE-STREAM
READ-BYTE
,
EXT:READ-INTEGER
& EXT:READ-FLOAT
WRITE-BYTE
,
EXT:WRITE-INTEGER
& EXT:WRITE-FLOAT
FILE-POSITION
EXT:ELASTIC-NEWLINE
OPEN
CLOSE
OPEN-STREAM-P
BROADCAST-STREAM
EXT:MAKE-BUFFERED-INPUT-STREAM
and
EXT:MAKE-BUFFERED-OUTPUT-STREAM
STREAM-ELEMENT-TYPE
STREAM-ELEMENT-TYPE
is SETF
able. The STREAM-ELEMENT-TYPE
of
STREAM
s created by the functions OPEN
, EXT:MAKE-PIPE-INPUT-STREAM
EXT:MAKE-PIPE-OUTPUT-STREAM
, EXT:MAKE-PIPE-IO-STREAM
, SOCKET:SOCKET-ACCEPT
, SOCKET:SOCKET-CONNECT
can be modified, if the old and the new STREAM-ELEMENT-TYPE
s are either
CHARACTER
or
(UNSIGNED-BYTE
8)
or (SIGNED-BYTE
8)
; or(UNSIGNED-BYTE
n
)
or (SIGNED-BYTE
n
)
, with the
same n
.Functions STREAM-ELEMENT-TYPE
and (
are SETF
STREAM-ELEMENT-TYPE
)GENERIC-FUNCTION
s, see
Section 29.2, “Gray streams”.
*STANDARD-INPUT*
Note that you cannot change STREAM-ELEMENT-TYPE
for some
built-in streams, such as terminal streams,
which is normally the value of *TERMINAL-IO*
.
Since *STANDARD-INPUT*
normally is a SYNONYM-STREAM
pointing
to *TERMINAL-IO*
, you cannot use READ-BYTE
in the it.
Since CGI
(Common Gateway Interface) provides the form data for
METHOD="POST" on the stdin,
and the server will not send you an end-of-stream
on the end of the data,
you will need to use
(
to determine how much data you should read from stdin.
CLISP will detect that stdin is not a terminal and create a regular
EXT:GETENV
"CONTENT_LENGTH"
)FILE-STREAM
which can be passed to (
.
To test this functionality interactively,
you will need to open the standard input in the binary mode:
SETF
STREAM-ELEMENT-TYPE
)
(let ((buf (MAKE-ARRAY
(PARSE-INTEGER
(EXT:GETENV
"CONTENT_LENGTH")) :element-type '(
))) (UNSIGNED-BYTE
8)WITH-OPEN-STREAM
(in (EXT:MAKE-STREAM
:INPUT
:ELEMENT-TYPE
'(
)) (UNSIGNED-BYTE
8)READ-SEQUENCE
buf in)) buf)
EXT:MAKE-STREAM
Function EXT:MAKE-STREAM
creates a Lisp stream out of an OS file descriptor:
(
EXT:MAKE-STREAM
object
&KEY
:DIRECTION
:ELEMENT-TYPE
:EXTERNAL-FORMAT
:BUFFERED
)
object
designates an OS handle (a file descriptor),
and should be one of the following:
:INPUT
:OUTPUT
:ERROR
STREAM
FILE-STREAM
or a SOCKET:SOCKET-STREAM
When there are several Lisp STREAM
s backed by the same OS
file descriptor, the behavior may be highly confusing when some of the
Lisp streams are :BUFFERED
. Use FORCE-OUTPUT
for output STREAM
s,
and bulk input for input STREAM
s.
The handle is duplicated (with dup
),
so it is safe to CLOSE
a STREAM
returned by EXT:MAKE-STREAM
.
READ-BYTE
,
EXT:READ-INTEGER
& EXT:READ-FLOAT
The function (
reads a multi-byte EXT:READ-INTEGER
stream
element-type
&OPTIONAL
ENDIANNESS
eof-error-p
eof-value
)INTEGER
from stream
, which should be a
STREAM
with STREAM-ELEMENT-TYPE
(
.
UNSIGNED-BYTE
8)element-type
should be type equivalent to (
,
where UNSIGNED-BYTE
n
)n
is a multiple of 8.
(
is like
EXT:READ-INTEGER
stream
element-type
)(
if READ-BYTE
stream
)stream
's
STREAM-ELEMENT-TYPE
were set to element-type
,
except that stream
's FILE-POSITION
will increase by
n
/8
instead of 1.
Together with (
, this
function permits mixed character/binary input from a stream.SETF
STREAM-ELEMENT-TYPE
)
The function (
reads a
floating-point number in IEEE 754 binary representation from
EXT:READ-FLOAT
stream
element-type
&OPTIONAL
ENDIANNESS
eof-error-p
eof-value
)stream
, which should be a STREAM
with
STREAM-ELEMENT-TYPE
(
. UNSIGNED-BYTE
8)element-type
should be
type equivalent to SINGLE-FLOAT
or DOUBLE-FLOAT
.
Endianness. ENDIANNESS
can be :LITTLE
or :BIG
.
The default is :LITTLE
, which corresponds
to the READ-BYTE
behavior in CLISP.
WRITE-BYTE
,
EXT:WRITE-INTEGER
& EXT:WRITE-FLOAT
The function (
writes a multi-byte EXT:WRITE-INTEGER
integer
stream
element-type
&OPTIONAL
ENDIANNESS
)INTEGER
to
stream
, which should be a STREAM
with
STREAM-ELEMENT-TYPE
(
. UNSIGNED-BYTE
8)element-type
should be
type equivalent to (
, where UNSIGNED-BYTE
n
)n
is a multiple of 8.
(
is
like EXT:WRITE-INTEGER
integer
stream
element-type
)(
if WRITE-BYTE
integer
stream
)stream
's
STREAM-ELEMENT-TYPE
were set to element-type
, except that stream
's
FILE-POSITION
will increase by
n
/8
instead of 1.
Together with (
, this
function permits mixed character/binary output to a SETF
STREAM-ELEMENT-TYPE
)STREAM
.
The function (
writes a
floating-point number in IEEE 754 binary representation to
EXT:WRITE-FLOAT
float
stream
element-type
&OPTIONAL
ENDIANNESS
)stream
, which should be a STREAM
with STREAM-ELEMENT-TYPE
(
. UNSIGNED-BYTE
8)element-type
should be
type equivalent to SINGLE-FLOAT
or DOUBLE-FLOAT
.
Function READ-SEQUENCE
. In addition to READ-SEQUENCE
, the following two
functions are provided:
EXT:READ-BYTE-SEQUENCE
performs multiple READ-BYTE
operations:(
fills the subsequence of EXT:READ-BYTE-SEQUENCE
sequence
stream
&KEY
:START
:END
:NO-HANG :INTERACTIVE)sequence
specified by :START
and :END
with INTEGER
s consecutively read from stream
. It returns the
index of the first element of sequence
that was not updated (=
end
or < end
if the stream
reached its end).
When no-hang
is non-NIL
, it does not block: it treats input
unavailability as end-of-stream
. When no-hang
is NIL
and interactive
is
non-NIL
, it can block for reading the first byte but does not block
for any further bytes.
This function is especially efficient if sequence
is a
(
and VECTOR
(UNSIGNED-BYTE
8))stream
is a file/pipe/socket STREAM
with STREAM-ELEMENT-TYPE
(
.
UNSIGNED-BYTE
8)
EXT:READ-CHAR-SEQUENCE
performs multiple READ-CHAR
operations:(
fills the subsequence of EXT:READ-CHAR-SEQUENCE
sequence
stream
&KEY
:START
:END
)sequence
specified by :START
and :END
with characters consecutively read
from stream
. It returns the index of the first element of
sequence
that was not updated (= end
or < end
if the
stream
reached its end).
This function is especially efficient if sequence
is a
STRING
and stream
is a file/pipe/socket STREAM
with
STREAM-ELEMENT-TYPE
CHARACTER
or an input STRING-STREAM
.
Function WRITE-SEQUENCE
. In addition to WRITE-SEQUENCE
, the following two
functions are provided:
EXT:WRITE-BYTE-SEQUENCE
performs multiple WRITE-BYTE
operations:(
outputs
the EXT:WRITE-BYTE-SEQUENCE
sequence
stream
&KEY
:START
:END
:NO-HANG :INTERACTIVE)INTEGER
s of the subsequence of sequence
specified by
:START
and :END
to stream
.
When no-hang
is non-NIL
, does not block.
When no-hang
is NIL
and interactive
is non-NIL
, it can
block for writing the first byte but does not block for any further
bytes. Returns two values: sequence
and the index of the first
byte that was not output.
This function is especially efficient if sequence
is a
(
and VECTOR
(UNSIGNED-BYTE
8))stream
is a file/pipe/socket STREAM
with
STREAM-ELEMENT-TYPE
(
.UNSIGNED-BYTE
8)
EXT:WRITE-CHAR-SEQUENCE
performs multiple WRITE-CHAR
operations:(
outputs the characters of the subsequence of
EXT:WRITE-CHAR-SEQUENCE
sequence
stream
&KEY
:START
:END
)sequence
specified by :START
and :END
to stream
.
Returns the sequence
argument.
This function is especially efficient if sequence
is a
STRING
and stream
is a file/pipe/socket STREAM
with
STREAM-ELEMENT-TYPE
CHARACTER
.
Rationale. The rationale for EXT:READ-CHAR-SEQUENCE
, EXT:READ-BYTE-SEQUENCE
, EXT:WRITE-CHAR-SEQUENCE
and
EXT:WRITE-BYTE-SEQUENCE
is that some STREAM
s support both character and binary
i/o, and when you read into a SEQUENCE
that can hold both (e.g.,
LIST
or SIMPLE-VECTOR
) you cannot determine which kind of
input to use. In such situation READ-SEQUENCE
and WRITE-SEQUENCE
SIGNAL
an ERROR
, while EXT:READ-CHAR-SEQUENCE
, EXT:READ-BYTE-SEQUENCE
, EXT:WRITE-CHAR-SEQUENCE
and
EXT:WRITE-BYTE-SEQUENCE
work just fine.
In addition to the standard functions LISTEN
and
READ-CHAR-NO-HANG
, CLISP provides the following functionality
facilitating non-blocking input and output, both binary and
character.
(EXT:READ-CHAR-WILL-HANG-P
stream
)
EXT:READ-CHAR-WILL-HANG-P
queries the stream's input status.
It returns NIL
if READ-CHAR
and PEEK-CHAR
with a
peek-type
of NIL
will return immediately.
Otherwise it returns T
. (In the latter case the standard
LISTEN
function would return NIL
.)
Note the difference with (
: When the NOT
(LISTEN
stream
))end-of-stream
is reached, LISTEN
returns
NIL
, whereas EXT:READ-CHAR-WILL-HANG-P
returns NIL
.
Note also that EXT:READ-CHAR-WILL-HANG-P
is not a good way to test for end-of-stream
:
If EXT:READ-CHAR-WILL-HANG-P
returns T
, this does not mean that the stream
will
deliver more characters. It only means that it is not known at this
moment whether the stream
is already at end-of-stream
, or will deliver
more characters.
(EXT:READ-BYTE-LOOKAHEAD
stream
)
stream
's
STREAM-ELEMENT-TYPE
is (UNSIGNED-BYTE
8)
or (SIGNED-BYTE
8)
.
Returns T
if READ-BYTE
would return immediately with an
INTEGER
result.
Returns :EOF
if the end-of-stream
is already known to be reached.
If READ-BYTE
's value is not available immediately, returns NIL
instead of waiting.(EXT:READ-BYTE-WILL-HANG-P
stream
)
stream
's
STREAM-ELEMENT-TYPE
is (UNSIGNED-BYTE
8)
or (SIGNED-BYTE
8)
.
Returns NIL
if READ-BYTE
will return immediately.
Otherwise it returns true.(EXT:READ-BYTE-NO-HANG
stream
&OPTIONAL
eof-error-p
eof-value
)
stream
's
STREAM-ELEMENT-TYPE
is (UNSIGNED-BYTE
8)
or (SIGNED-BYTE
8)
.
Returns an INTEGER
or does end-of-stream
handling, like READ-BYTE
,
if that would return immediately.
If READ-BYTE
's value is not available immediately, returns NIL
instead of waiting.FILE-POSITION
FILE-POSITION
works on any :BUFFERED
FILE-STREAM
.
EXT:ELASTIC-NEWLINE
The function (
is like
EXT:ELASTIC-NEWLINE
[stream
])FRESH-LINE
but the other way around: It outputs a conditional newline
on stream
, which is canceled if the next
output on stream
happens to be a newline. More precisely, it
causes a newline to be output right before the next character is
written on stream
, if this character is not a newline.
The newline is also output if the next operation on the stream is
FRESH-LINE
, FINISH-OUTPUT
, FORCE-OUTPUT
or CLOSE
.
The functionality of EXT:ELASTIC-NEWLINE
is also available through
the FORMAT
directive ~..
A technique for avoiding unnecessary blank lines in output is to
begin each chunk of output with a call to FRESH-LINE
and to terminate it
with a call to EXT:ELASTIC-NEWLINE
.
See also
doc/Newline-Convention.txt
.
OPEN
OPEN
accepts an additional keyword :BUFFERED
.
The acceptable values for the arguments to the
file/pipe/socket STREAM
functions
:ELEMENT-TYPE
types equivalent to CHARACTER
or
(
, UNSIGNED-BYTE
n
)(
; if the stream is to be
unSIGNED-BYTE
n
):BUFFERED
, n
must be a multiple of 8.
If n
is not a multiple of 8, CLISP will use the
specified number of bits for i/o, and write the file length
(as a number of n
-bit bytes) in the preamble.
This is done to ensure the input/output consistency:
suppose you open a file with :ELEMENT-TYPE
of (
and write 7 bytes
(i.e., 21 bit) there.
The underlying OS can do input/output only in whole 8-bit bytes.
Thus the OS will report the size of the file as 3 (8-bit) bytes.
Without the preamble CLISP will have no way to know how many
3-bit bytes to read from this file - 6, 7 or 8.
UNSIGNED-BYTE
3)
:EXTERNAL-FORMAT
EXT:ENCODING
s, (constant) SYMBOL
s in the
“CHARSET” package, STRING
s (denoting iconv
-based encodings),
the symbol :DEFAULT
, and the line terminator keywords
:UNIX
, :MAC
, :DOS
. The default encoding is CUSTOM:*DEFAULT-FILE-ENCODING*
.
This argument determines how the lisp CHARACTER
data is
converted to/from the 8-bit bytes that the underlying OS uses.
:BUFFERED
NIL
, T
, or :DEFAULT
.
Have CLISP manage an internal buffer for input or output (in
addition to the buffering that might be used by the underlying OS).
Buffering is a known general technique to significantly speed up i/o.
SOCKET:SOCKET-STREAM
s and
pipes, :DEFAULT
is equivalent to
T
on the input side and to NIL
on the output side; it you are
transmitting a lot of data then using buffering
will significantly speed up your i/o;:DEFAULT
means that buffered file streams will be returned
for regular files and (on UNIX) block-devices, and unbuffered file
streams for special files.
Note that some files, notably those on the /proc
filesystem (on UNIX systems), are actually, despite their innocuous
appearance, special files, so you might need to supply an explicit
:BUFFERED
NIL
argument for them. Actually, CLISP detects that
the file is a /proc
file, so that one is covered,
but there are probably more strange beasts there!
When an already opened file is opened again, a continuable ERROR
is
SIGNAL
ed, unless both the existing and the new STREAM
s are read-only
(i.e., :DIRECTION
is :INPUT
or :INPUT-IMMUTABLE
).
CLOSE
Function CLOSE
is a GENERIC-FUNCTION
, see
Section 29.2, “Gray streams”.
When the :ABORT
argument is non-NIL
, CLOSE
will not
SIGNAL
s an ERROR
even when the underlying OS call fails.
GET-OUTPUT-STREAM-STRING
returns the same value after
CLOSE
as it would before it.
CLOSE
on an already closed STREAM
does nothing and returns
T
.
If you do not CLOSE
your STREAM
explicitly, it will be
closed at garbage-collection time automatically.
This is not recommended though because garbage-collection is not deterministic.
Please use WITH-OPEN-STREAM
etc.
OPEN-STREAM-P
Function OPEN-STREAM-P
is a GENERIC-FUNCTION
, see
Section 29.2, “Gray streams”.
BROADCAST-STREAM
INPUT-STREAM-P
and INTERACTIVE-STREAM-P
return false for
BROADCAST-STREAM
s.
(EXT:MAKE-BUFFERED-OUTPUT-STREAM
. Returns a buffered output function
)STREAM
.
function
is a FUNCTION
expecting one argument, a SIMPLE-STRING
.
WRITE-CHAR
collects the CHARACTER
s in a STRING
, until a
newline character is written or FORCE-OUTPUT
/FINISH-OUTPUT
is called.
Then function
is called with a SIMPLE-STRING
as argument,
that contains the characters collected so far.
CLEAR-OUTPUT
discards the characters collected so far.
(EXT:MAKE-BUFFERED-INPUT-STREAM
. Returns a buffered input function
mode
)STREAM
.
function
is a FUNCTION
of 0 arguments that returns
either NIL
(stands for end-of-stream
) or up to three values
string
, start
, end
.
READ-CHAR
returns the CHARACTER
s of the current string
one
after another, as delimited by start
and end
, which default to
0
and NIL
, respectively.
When the string
is consumed, function
is called again.
The string
returned by function
should not be changed by the user.
function
should copy the string
with COPY-SEQ
or SUBSEQ
before
returning if the original string
is to be modified.
mode
determines the behavior of LISTEN
when the current string
buffer is empty:
NIL
FILE-STREAM
,
i.e. function
is calledT
end-of-stream
, i.e. one can assume that further characters will always
arrive, without calling function
FUNCTION
FUNCTION
tells, upon call, if further
non-empty string
s are to be expected.
CLEAR-INPUT
discards the rest of the current string
,
so function
will be called upon the next READ-CHAR
operation.
These notes document CLISP version 2.41 | Last modified: 2006-10-13 |