2.19 Streams


2.19.1 ANSI Streams


2.19.1.1 Supported types

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.


2.19.1.2 Element types

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.


2.19.1.3 External formats

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.

SymbolsCodepage or encodingUnicode required
:cr#\Newline is Carriage ReturnNo
:crlf#\Newline is Carriage Return followed by LinefeedNo
:lf#\Newline is LinefeedNo
:little-endianModify UCS to use little-endian encoding.No
:big-endianModify UCS to use big-endian encoding.No
:utf-8 :utf8Unicode UTF-8Yes
:ucs-2 :ucs2 :utf-16 :utf16 :unicodeUCS-2 encoding with BOM. Defaults to big-endian when writing or if no BOM is detected when reading.Yes
:ucs-2le :ucs2le :utf-16leUCS-2 with little-endian encodingYes
:ucs-2be :ucs2be :utf-16beUCS-2 with big-endian encodingYes
:ucs-4 :ucs4 :utf-32 :utf32UCS-4 encoding with BOM. Defaults to big-endian when writing or if no BOM is detected when reading.Yes
:ucs-4le :ucs4le :utf-32leUCS-4 with little-endian encodingYes
:ucs-4be :ucs4be :utf-32beUCS-4 with big-endian encodingYes
:iso-8859-1 :iso8859-1 :latin-1 :cp819 :ibm819Latin-1 encodingYes
:iso-8859-2 :iso8859-2 :latin-2 :latin2Latin-2 encodingYes
:iso-8859-3 :iso8859-3 :latin-3 :latin3Latin-3 encodingYes
:iso-8859-4 :iso8859-4 :latin-4 :latin4Latin-4 encodingYes
:iso-8859-5 :cyrillicLatin-5 encodingYes
:iso-8859-6 :arabic :asmo-708 :ecma-114Latin-6 encodingYes
:iso-8859-7 :greek8 :greek :ecma-118Greek encodingYes
:iso-8859-8 :hebrewHebrew encodingYes
:iso-8859-9 :latin-5 :latin5Latin-5 encodingYes
:iso-8859-10 :iso8859-10 :latin-6 :latin6Latin-6 encodingYes
:iso-8859-13 :iso8859-13 :latin-7 :latin7Latin-7 encodingYes
:iso-8859-14 :iso8859-14 :latin-8 :latin8Latin-8 encodingYes
:iso-8859-15 :iso8859-15 :latin-9 :latin9Latin-7 encodingYes
:dos-cp437 :ibm-437IBM CP 437Yes
:dos-cp850 :ibm-850 :cp850Windows CP 850Yes
:dos-cp852 :ibm-852IBM CP 852Yes
:dos-cp855 :ibm-855IBM CP 855Yes
:dos-cp860 :ibm-860IBM CP 860Yes
:dos-cp861 :ibm-861IBM CP 861Yes
:dos-cp862 :ibm-862 :cp862Windows CP 862Yes
:dos-cp863 :ibm-863IBM CP 863Yes
:dos-cp864 :ibm-864IBM CP 864Yes
:dos-cp865 :ibm-865IBM CP 865Yes
:dos-cp866 :ibm-866 :cp866Windows CP 866Yes
:dos-cp869 :ibm-869IBM CP 869Yes
:windows-cp932 :windows-932 :cp932Windows CP 932Yes
:windows-cp936 :windows-936 :cp936Windows CP 936Yes
:windows-cp949 :windows-949 :cp949Windows CP 949Yes
:windows-cp950 :windows-950 :cp950Windows CP 950Yes
:windows-cp1250 :windows-1250 :ms-eeWindows CP 1250Yes
:windows-cp1251 :windows-1251 :ms-cyrlWindows CP 1251Yes
:windows-cp1252 :windows-1252 :ms-ansiWindows CP 1252Yes
:windows-cp1253 :windows-1253 :ms-greekWindows CP 1253Yes
:windows-cp1254 :windows-1254 :ms-turkWindows CP 1254Yes
:windows-cp1255 :windows-1255 :ms-hebrWindows CP 1255Yes
:windows-cp1256 :windows-1256 :ms-arabWindows CP 1256Yes
:windows-cp1257 :windows-1257 :winbaltrimWindows CP 1257Yes
:windows-cp1258 :windows-1258Windows CP 1258Yes

Table 2.10: Stream external formats


2.19.2 Dictionary

2.19.2.1 File Stream Extensions

Function: open filespec &key direction element-type if-exists if-does-not-exist external-format close-on-exec nonblock

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.

Function: ext:set-buffering-mode stream mode

Control the buffering mode of a stream

Synopsis

stream

an ANSI stream

mode

one of nil, :none, :line, :line-buffered, :full or :full-buffered

returns

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.

Function: ext:file-stream-fd file-stream

Return the POSIX file descriptor of file-stream as an integer

2.19.2.2 External Format Extensions

Variable: ext:*default-external-format*

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.

Function: ext:all-encodings

Return a list of all supported external formats

Condition: ext:character-coding-error

Character coding error

Class Precedence List

ext:character-coding-error, error, serious-condition, condition, t

Methods

Function: ext:character-coding-error-external-format condition
returns

The external format of condition

Description

Superclass of ext:character-encoding-error and ext:character-decoding-error.

Condition: ext:character-encoding-error

Character encoding error

Class Precedence List

ext:character-encoding-error, ext:character-coding-error, error, serious-condition, condition, t

Methods

Function: ext:character-encoding-error-code condition
returns

The character code of the character, which can’t be encoded

Description

Condition for characters, which can’t be encoded with some external format.

Condition: ext:character-decoding-error

Character decoding error

Class Precedence List

ext:character-decoding-error, ext:character-coding-error, error, serious-condition, condition, t

Methods

Function: ext:character-decoding-error-octects condition
returns

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.

Condition: ext:stream-encoding-error

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.

Condition: ext:stream-decoding-error

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.

Function: ext:encoding-error stream external-format code

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.

Function: ext:decoding-error stream external-format octects

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.

2.19.2.3 Sequence Streams

System Class: ext:sequence-stream

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-codes will be equal to the values of the bytes comprising the character in the given external format.

Function: ext:make-sequence-input-stream vector &key (start 0) (end nil) (external-format nil)

Create a sequence input stream with the subsequence bounded by start and end of the given vector.

Function: ext:make-sequence-output-stream vector &key (external-format nil)

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'"

2.19.3 C Reference

2.19.3.1 ANSI dictionary

Common Lisp and C equivalence

Lisp symbolC function
broadcast-stream-streamscl_object cl_broadcast_stream_streams(cl_object broadcast_stream)
clear-inputcl_object cl_clear_input(cl_narg narg, ...)
clear-outputcl_object cl_clear_output(cl_narg narg, ...)
closecl_object cl_close(cl_narg narg, cl_object stream, ...)
concatenated-stream-streamscl_object cl_concatenated_stream_streams(cl_object concatenated_stream)
echo-stream-input-streamcl_object cl_echo_stream_input_stream(cl_object echo_stream)
echo-stream-output-streamcl_object cl_echo_stream_output_stream(cl_object echo_stream)
file-lengthcl_object cl_file_position(cl_narg narg, cl_object file_stream, ...)
file-positioncl_object cl_file_position(cl_object stream)
file-string-lengthcl_object cl_file_string_length(cl_object stream, cl_object object)
finish-outputcl_object cl_finish_output(cl_narg narg, ...)
force-outputcl_object cl_force_output(cl_narg narg, ...)
fresh-linecl_object cl_fresh_line(cl_narg narg, ...)
get-output-stream-stringcl_object cl_get_output_stream_string(cl_object string_output_stream)
input-stream-pcl_object cl_input_stream_p(cl_object stream)
interactive-stream-pcl_object cl_interactive_stream_p(cl_object stream)
listencl_object cl_listen(cl_narg narg, cl_object stream, ...)
make-broadcast-streamcl_object cl_make_broadcast_stream(cl_narg narg, ...)
make-concatenated-streamcl_object cl_make_concatenated_stream(cl_narg narg, ....)
make-echo-streamcl_object cl_make_echo_stream(cl_object input, cl_object output)
make-string-input-streamcl_object cl_make_string_input_stream(cl_narg narg, cl_object string, ...)
make-string-output-streamcl_object cl_make_string_output_stream(cl_narg narg, ...)
make-two-way-streamcl_object cl_make_two_way_stream(cl_object input, cl_object output)
make-synonym-streamcl_object cl_make_synonym_stream(cl_object symbol)
opencl_object cl_open(cl_narg narg, cl_object filespec, ...)
open-stream-pcl_object cl_open_stream_p(cl_object stream)
output-stream-pcl_object cl_output_stream_p(cl_object stream)
peek-charcl_object cl_peek_char(cl_narg narg, ...)
read-bytecl_object cl_read_byte(cl_narg narg, cl_object stream, ...)
read-charcl_object cl_read_char(cl_narg narg, ...)
read-char-no-hangcl_object cl_read_char_no_hang(cl_narg narg, ...)
read-linecl_object cl_read_line(cl_narg narg, ...)
read-sequencecl_object cl_read_sequence(cl_narg narg, cl_object sequence, cl_object stream, ...)
stream-element-typecl_object cl_stream_element_type(cl_object stream)
stream-error-stream[Only in Common Lisp]
stream-external-formatcl_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)
streampcl_object cl_streamp(cl_object object)
synonym-stream-symbolcl_object cl_synonym_stream_symbol(cl_object synonym_stream)
terpricl_object cl_terpri(cl_narg narg, ...)
two-way-stream-input-streamcl_object cl_two_way_stream_input_stream(cl_object two_way_stream)
two-way-stream-output-streamcl_object cl_two_way_stream_output_stream(cl_object two_way_stream)
unread-charcl_object cl_unread_char(cl_narg narg, cl_object character, ...)
write-bytecl_object cl_write_byte(cl_object byte, cl_object stream)
write-charcl_object cl_write_char(cl_narg narg, cl_object character, ...)
write-linecl_object cl_write_line(cl_narg narg, cl_object string, ...)
write-stringcl_object cl_write_string(cl_narg narg, cl_object string, ...)
write-sequencecl_object cl_write_sequence(cl_narg narg, cl_object sequence, cl_object stream, ...)
y-or-n-pcl_object cl_y_or_n_p(cl_narg narg, ...)
yes-or-no-pcl_object cl_yes_or_no_p(cl_narg narg, ...)