## Streams

### ANSI Streams

#### Supported types

&ECL; implements all stream types described in &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.

#### 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

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.

#### 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.

##### Stream 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. | Yes
:ucs-2le :ucs2le :utf-16le | UCS-2 with big-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. | Yes
:ucs-4le :ucs4le :utf-32le | UCS-4 with big-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