ECL implements all stream types described in ANSI [see ANSI]. Additionally, when configured with option --enable-clos-streams
, ECL includes a version of Gray streams where any object that implements the appropriate methods (stream-input-p
, stream-read-char
, etc) is a valid argument for the functions that expect streams, such as read
, print
, etc.
ECL distinguishes between two kinds of streams: character streams and byte streams. Character streams only accept and produce characters, written or read one by one, with write-char
or read-char
, or in chunks, with write-sequence
or any of the Lisp printer functions. Character operations are conditioned by the external format, as described in External formats.
ANSI Common Lisp also supports binary streams. Here input and output is performed in chunks of bits. Binary streams are created with the function open passing as argument a subtype of integer and the implementation is free to round up that integer type to the closest size it supports. In particular ECL rounds up the size to a multiple of a byte. For example, the form (open "foo.bin" :direction :output :element-type '(unsigned-byte 13))
, will open the file foo.bin
for writing, using 16-bit words as the element type.
An external format is an encoding for characters that maps character codes to a sequence of bytes, in a one-to-one or one-to-many fashion. External formats are also known as "character encodings" in the programming world and are an essential ingredient to be able to read and write text in different languages and alphabets.
ECL has one of the most complete supports for external formats, covering all of the usual codepages from the Windows and Unix world, up to the more recent UTF-8, UCS-2 and UCS-4 formats, all of them with big and small endian variants, and considering different encodings for the newline character.
However, the set of supported external formats depends on the size of the space of character codes. When ECL is built with Unicode support (the default option), it can represent all known characters from all known codepages, and thus all external formats are supported. However, when ECL is built with the restricted character set, it can only use one codepage (the one provided by the C library), with a few variants for the representation of end-of-line characters.
In ECL, an external format designator is defined recursively as either a symbol or a list of symbols. The grammar is as follows
external-format-designator := symbol | ( {symbol}+ )
and the table of known symbols is shown below. Note how some symbols (:cr
, :little-endian
, etc.) just modify other external formats.
Symbols | Codepage or encoding | Unicode required |
---|---|---|
:cr | #\Newline is Carriage Return | No |
:crlf | #\Newline is Carriage Return followed by Linefeed | No |
:lf | #\Newline is Linefeed | No |
:little-endian | Modify UCS to use little-endian encoding. | No |
:big-endian | Modify UCS to use big-endian encoding. | No |
:utf-8 :utf8 | Unicode UTF-8 | Yes |
:ucs-2 :ucs2 :utf-16 :utf16 :unicode | UCS-2 encoding with BOM. Defaults to big-endian when writing or if no BOM is detected when reading. | Yes |
:ucs-2le :ucs2le :utf-16le | UCS-2 with little-endian encoding | Yes |
:ucs-2be :ucs2be :utf-16be | UCS-2 with big-endian encoding | Yes |
:ucs-4 :ucs4 :utf-32 :utf32 | UCS-4 encoding with BOM. Defaults to big-endian when writing or if no BOM is detected when reading. | Yes |
:ucs-4le :ucs4le :utf-32le | UCS-4 with little-endian encoding | Yes |
:ucs-4be :ucs4be :utf-32be | UCS-4 with big-endian encoding | Yes |
:iso-8859-1 :iso8859-1 :latin-1 :cp819 :ibm819 | Latin-1 encoding | Yes |
:iso-8859-2 :iso8859-2 :latin-2 :latin2 | Latin-2 encoding | Yes |
:iso-8859-3 :iso8859-3 :latin-3 :latin3 | Latin-3 encoding | Yes |
:iso-8859-4 :iso8859-4 :latin-4 :latin4 | Latin-4 encoding | Yes |
:iso-8859-5 :cyrillic | Latin-5 encoding | Yes |
:iso-8859-6 :arabic :asmo-708 :ecma-114 | Latin-6 encoding | Yes |
:iso-8859-7 :greek8 :greek :ecma-118 | Greek encoding | Yes |
:iso-8859-8 :hebrew | Hebrew encoding | Yes |
:iso-8859-9 :latin-5 :latin5 | Latin-5 encoding | Yes |
:iso-8859-10 :iso8859-10 :latin-6 :latin6 | Latin-6 encoding | Yes |
:iso-8859-13 :iso8859-13 :latin-7 :latin7 | Latin-7 encoding | Yes |
:iso-8859-14 :iso8859-14 :latin-8 :latin8 | Latin-8 encoding | Yes |
:iso-8859-15 :iso8859-15 :latin-9 :latin9 | Latin-7 encoding | Yes |
:dos-cp437 :ibm-437 | IBM CP 437 | Yes |
:dos-cp850 :ibm-850 :cp850 | Windows CP 850 | Yes |
:dos-cp852 :ibm-852 | IBM CP 852 | Yes |
:dos-cp855 :ibm-855 | IBM CP 855 | Yes |
:dos-cp860 :ibm-860 | IBM CP 860 | Yes |
:dos-cp861 :ibm-861 | IBM CP 861 | Yes |
:dos-cp862 :ibm-862 :cp862 | Windows CP 862 | Yes |
:dos-cp863 :ibm-863 | IBM CP 863 | Yes |
:dos-cp864 :ibm-864 | IBM CP 864 | Yes |
:dos-cp865 :ibm-865 | IBM CP 865 | Yes |
:dos-cp866 :ibm-866 :cp866 | Windows CP 866 | Yes |
:dos-cp869 :ibm-869 | IBM CP 869 | Yes |
:windows-cp932 :windows-932 :cp932 | Windows CP 932 | Yes |
:windows-cp936 :windows-936 :cp936 | Windows CP 936 | Yes |
:windows-cp949 :windows-949 :cp949 | Windows CP 949 | Yes |
:windows-cp950 :windows-950 :cp950 | Windows CP 950 | Yes |
:windows-cp1250 :windows-1250 :ms-ee | Windows CP 1250 | Yes |
:windows-cp1251 :windows-1251 :ms-cyrl | Windows CP 1251 | Yes |
:windows-cp1252 :windows-1252 :ms-ansi | Windows CP 1252 | Yes |
:windows-cp1253 :windows-1253 :ms-greek | Windows CP 1253 | Yes |
:windows-cp1254 :windows-1254 :ms-turk | Windows CP 1254 | Yes |
:windows-cp1255 :windows-1255 :ms-hebr | Windows CP 1255 | Yes |
:windows-cp1256 :windows-1256 :ms-arab | Windows CP 1256 | Yes |
:windows-cp1257 :windows-1257 :winbaltrim | Windows CP 1257 | Yes |
:windows-cp1258 :windows-1258 | Windows CP 1258 | Yes |
Additional options for open include:
:close-on-exec
Child processes don’t inherit a copy of this stream: new processes
created by fork
and exec
(for example by calling
ext:run-program
) close the stream after calling exec
.
Defaults to t
.
:nonblock
Open fifos or device files in nonblocking mode. Defaults to nil
.
These options are ignored on operating systems which do not support them.
Control the buffering mode of a stream
Synopsis
an ANSI stream
one of nil
, :none
, :line
, :line-buffered
, :full
or :full-buffered
The supplied stream
Description
If mode is nil
or :none
, stream will not be
buffered, if it is :line
or :line-buffered
resp.
:full
or :fully-buffered
, stream will be line resp.
fully buffered. If the stream does not support buffering, nothing will
happen.
Return the POSIX file descriptor of file-stream as an integer
Default external format to use for reading from streams, dealing with filenames, etc. The default is to use utf-8 encoding if ECL is built with Unicode support.
Return a list of all supported external formats
Character coding error
Class Precedence List
ext:character-coding-error
, error
, serious-condition
, condition
, t
Methods
The external format of condition
Description
Superclass of ext:character-encoding-error
and ext:character-decoding-error
.
Character encoding error
Class Precedence List
ext:character-encoding-error
, ext:character-coding-error
, error
, serious-condition
, condition
, t
Methods
The character code of the character, which can’t be encoded
Description
Condition for characters, which can’t be encoded with some external format.
Character decoding error
Class Precedence List
ext:character-decoding-error
, ext:character-coding-error
, error
, serious-condition
, condition
, t
Methods
A list of integers with the values of the unsigned char
’s which
can’t be decoded.
Description
Condition for characters, which can’t be decoded with some external format.
Stream encoding error
Class Precedence List
ext:stream-encoding-error
, ext:character-encoding-error
, ext:character-coding-error
, stream-error
, error
, serious-condition
, condition
, t
Description
This condition is signaled when trying to write a character to a stream, which can’t be encoded with the streams external format.
Stream decoding error
Class Precedence List
ext:stream-decoding-error
, ext:character-decoding-error
, ext:character-coding-error
, stream-error
, error
, serious-condition
, condition
, t
Description
This condition is signaled when trying to read a character from a stream, which can’t be decoded with the streams external format.
Signal a ext:stream-encoding-error
with the given
external-format and code. Make a restart available so
that the error can be ignored or the character can be replaced with a
different one.
Signal a ext:stream-decoding-error
with the given
external-format and octets. Make a restart available so
that the error can be ignored or the octets can be replaced with a
character.
Class Precedence List
ext:sequence-stream
, stream
, t
Description
Sequence streams work similar to string streams for vectors. The
supplied vectors that the streams read from or write to must have a
byte sized element type, i.e. (signed-byte 8)
,
(unsigned-byte 8)
or base-char
.
The semantics depend on the vector element type and the external
format of the stream. If no external format is supplied and the
element type is an integer type, the stream is a binary stream and
accepts only integers of the same type as the element type of the
vector. Otherwise, the stream accepts both characters and integers and
converts them using the given external format. If the element type is
base-char
, the elements of the vectors are treated as bytes.
This means that writing a character may use multiple elements of the
vector, whose char-code
s will be equal to the values of the
bytes comprising the character in the given external format.
Create a sequence input stream with the subsequence bounded by start and end of the given vector.
Create a sequence output stream.
Example:
Using sequence streams to convert to a UTF8 encoded base string
CL-USER> (defvar *output* (make-array 20 :element-type 'base-char :adjustable t :fill-pointer 0)) *OUTPUT* CL-USER> (defvar *stream* (ext:make-sequence-output-stream *output* :external-format :utf-8)) *STREAM* CL-USER> (write-string "Spätzle mit Soß'" *stream*) "Spätzle mit Soß'" CL-USER> *output* "Spätzle mit SoÃ\237'"
Common Lisp and C equivalence
Lisp symbol | C function |
---|---|
broadcast-stream-streams | cl_object cl_broadcast_stream_streams(cl_object broadcast_stream) |
clear-input | cl_object cl_clear_input(cl_narg narg, ...) |
clear-output | cl_object cl_clear_output(cl_narg narg, ...) |
close | cl_object cl_close(cl_narg narg, cl_object stream, ...) |
concatenated-stream-streams | cl_object cl_concatenated_stream_streams(cl_object concatenated_stream) |
echo-stream-input-stream | cl_object cl_echo_stream_input_stream(cl_object echo_stream) |
echo-stream-output-stream | cl_object cl_echo_stream_output_stream(cl_object echo_stream) |
file-length | cl_object cl_file_position(cl_narg narg, cl_object file_stream, ...) |
file-position | cl_object cl_file_position(cl_object stream) |
file-string-length | cl_object cl_file_string_length(cl_object stream, cl_object object) |
finish-output | cl_object cl_finish_output(cl_narg narg, ...) |
force-output | cl_object cl_force_output(cl_narg narg, ...) |
fresh-line | cl_object cl_fresh_line(cl_narg narg, ...) |
get-output-stream-string | cl_object cl_get_output_stream_string(cl_object string_output_stream) |
input-stream-p | cl_object cl_input_stream_p(cl_object stream) |
interactive-stream-p | cl_object cl_interactive_stream_p(cl_object stream) |
listen | cl_object cl_listen(cl_narg narg, cl_object stream, ...) |
make-broadcast-stream | cl_object cl_make_broadcast_stream(cl_narg narg, ...) |
make-concatenated-stream | cl_object cl_make_concatenated_stream(cl_narg narg, ....) |
make-echo-stream | cl_object cl_make_echo_stream(cl_object input, cl_object output) |
make-string-input-stream | cl_object cl_make_string_input_stream(cl_narg narg, cl_object string, ...) |
make-string-output-stream | cl_object cl_make_string_output_stream(cl_narg narg, ...) |
make-two-way-stream | cl_object cl_make_two_way_stream(cl_object input, cl_object output) |
make-synonym-stream | cl_object cl_make_synonym_stream(cl_object symbol) |
open | cl_object cl_open(cl_narg narg, cl_object filespec, ...) |
open-stream-p | cl_object cl_open_stream_p(cl_object stream) |
output-stream-p | cl_object cl_output_stream_p(cl_object stream) |
peek-char | cl_object cl_peek_char(cl_narg narg, ...) |
read-byte | cl_object cl_read_byte(cl_narg narg, cl_object stream, ...) |
read-char | cl_object cl_read_char(cl_narg narg, ...) |
read-char-no-hang | cl_object cl_read_char_no_hang(cl_narg narg, ...) |
read-line | cl_object cl_read_line(cl_narg narg, ...) |
read-sequence | cl_object cl_read_sequence(cl_narg narg, cl_object sequence, cl_object stream, ...) |
stream-element-type | cl_object cl_stream_element_type(cl_object stream) |
stream-error-stream | [Only in Common Lisp] |
stream-external-format | cl_object cl_stream_external_format(cl_object stream) |
(setf stream-external-format) | cl_object si_stream_external_format_set(cl_object stream, cl_object format) |
streamp | cl_object cl_streamp(cl_object object) |
synonym-stream-symbol | cl_object cl_synonym_stream_symbol(cl_object synonym_stream) |
terpri | cl_object cl_terpri(cl_narg narg, ...) |
two-way-stream-input-stream | cl_object cl_two_way_stream_input_stream(cl_object two_way_stream) |
two-way-stream-output-stream | cl_object cl_two_way_stream_output_stream(cl_object two_way_stream) |
unread-char | cl_object cl_unread_char(cl_narg narg, cl_object character, ...) |
write-byte | cl_object cl_write_byte(cl_object byte, cl_object stream) |
write-char | cl_object cl_write_char(cl_narg narg, cl_object character, ...) |
write-line | cl_object cl_write_line(cl_narg narg, cl_object string, ...) |
write-string | cl_object cl_write_string(cl_narg narg, cl_object string, ...) |
write-sequence | cl_object cl_write_sequence(cl_narg narg, cl_object sequence, cl_object stream, ...) |
y-or-n-p | cl_object cl_y_or_n_p(cl_narg narg, ...) |
yes-or-no-p | cl_object cl_yes_or_no_p(cl_narg narg, ...) |