@node Streams
@comment  node-name,  next,  previous,  up
@chapter Streams

Streams which read or write Lisp character data from or to the outside
world -- files, sockets or other external entities -- require the
specification of a conversion between the external, binary data and the
Lisp characters.  In ANSI Common Lisp, this is done by specifying the
@code{:external-format} argument when the stream is created.  The major
information required is an @emph{encoding}, specified by a keyword
naming that encoding; however, it is also possible to specify
refinements to that encoding as additional options to the external
format designator.

In addition, SBCL supports various extensions of ANSI Common Lisp
streams:

@table @strong
@item Bivalent Streams
A type of stream that can read and write both @code{character} and
@code{(unsigned-byte 8)} values.

@item Gray Streams
User-overloadable CLOS classes whose instances can be used as Lisp
streams (e.g. passed as the first argument to @code{format}).

@item Simple Streams
The bundled contrib module @dfn{sb-simple-streams} implements a subset
of the Franz Allegro simple-streams proposal.

@end table

@menu
* External Formats::
* Bivalent Streams::
* Gray Streams::
* Simple Streams::
@end menu

@node External Formats
@section External Formats
@cindex External formats

@findex @cl{stream-external-format}
The encodings supported by SBCL as external formats are named by
keyword.  Each encoding has a canonical name, which will be encoding
returned by @code{stream-external-format}, and a number of aliases for
convenience, as shown in the table below:

@include encodings.texi-temp

@findex @cl{open}
@findex @cl{with-open-file}
In situations where an external file format designator is required, such
as the @code{:external-format} argument in calls to @code{open} or
@code{with-open-file}, users may supply the name of an encoding to
denote the external format which is applying that encoding to Lisp
characters.

In addition to the basic encoding for an external format, options
controlling various special cases may be passed, by using a list (whose
first element must be an encoding name and whose rest is a plist) as an
external file format designator.  At present, the only supported key in
the plist is @code{:replacement}, where the corresponding value is a
string designator which is used as a replacement when an encoding or
decoding error happens, handling those errors without user intervention;
for example:
@lisp
(with-open-file (i pathname :external-format '(:utf-8 :replacement #\?))
  (read-line i))
@end lisp
will read the first line of @var{pathname}, replacing any invalid utf-8
sequences with question marks.

@node Bivalent Streams
@section Bivalent Streams

A @dfn{bivalent stream} can be used to read and write both
@code{character} and @code{(unsigned-byte 8)} values.  A bivalent
stream is created by calling @code{open} with the argument @code{:element-type
:default}.  On such a stream, both binary and character data can be
read and written with the usual input and output functions.

@c Horrible visual markup
@quotation
Streams are @emph{not} created bivalent by default for performance
reasons.  Bivalent streams are incompatible with
@code{fast-read-char}, an internal optimization in SBCL's stream
machinery that bulk-converts octets to characters and implements a
fast path through @code{read-char}.
@end quotation

@node Gray Streams
@section Gray Streams


The Gray Streams interface is a widely supported extension that
provides for definition of CLOS-extensible stream classes.  Gray
stream classes are implemented by adding methods to generic functions
analogous to Common Lisp's standard I/O functions.  Instances of Gray
stream classes may be used with any I/O operation where a non-Gray
stream can, provided that all required methods have been implemented
suitably.

@menu
* Gray Streams classes::
* Methods common to all streams::
* Input stream methods::
* Character input stream methods::
* Output stream methods::
* Character output stream methods::
* Binary stream methods::
* Gray Streams examples::
@end menu

@node Gray Streams classes
@subsection Gray Streams classes

The defined Gray Stream classes are these:

@include class-sb-gray-fundamental-stream.texinfo
@include class-sb-gray-fundamental-input-stream.texinfo

@noindent
The function input-stream-p will return true of any generalized
instance of fundamental-input-stream.

@include class-sb-gray-fundamental-output-stream.texinfo

@noindent
The function output-stream-p will return true of any generalized
instance of fundamental-output-stream.

@include class-sb-gray-fundamental-binary-stream.texinfo

@noindent
Note that instantiable subclasses of fundamental-binary-stream should
provide (or inherit) an applicable method for the generic function
stream-element-type.

@include class-sb-gray-fundamental-character-stream.texinfo
@include class-sb-gray-fundamental-binary-input-stream.texinfo
@include class-sb-gray-fundamental-binary-output-stream.texinfo
@include class-sb-gray-fundamental-character-input-stream.texinfo
@include class-sb-gray-fundamental-character-output-stream.texinfo

@node Methods common to all streams
@subsection Methods common to all streams

These generic functions can be specialized on any generalized instance
of fundamental-stream.

@include fun-common-lisp-stream-element-type.texinfo
@include fun-common-lisp-close.texinfo
@include fun-sb-gray-stream-file-position.texinfo



@node Input stream methods
@subsection Input stream methods

These generic functions may be specialized on any generalized instance
of fundamental-input-stream.

@include fun-sb-gray-stream-clear-input.texinfo
@include fun-sb-gray-stream-read-sequence.texinfo

@node Character input stream methods
@subsection Character input stream methods

These generic functions are used to implement subclasses of
fundamental-input-stream:

@include fun-sb-gray-stream-peek-char.texinfo
@include fun-sb-gray-stream-read-char-no-hang.texinfo
@include fun-sb-gray-stream-read-char.texinfo
@include fun-sb-gray-stream-read-line.texinfo
@include fun-sb-gray-stream-listen.texinfo
@include fun-sb-gray-stream-unread-char.texinfo

@node Output stream methods
@subsection Output stream methods

These generic functions are used to implement subclasses of
fundamental-output-stream:

@include fun-sb-gray-stream-clear-output.texinfo
@include fun-sb-gray-stream-finish-output.texinfo
@include fun-sb-gray-stream-force-output.texinfo
@include fun-sb-gray-stream-write-sequence.texinfo

@node Character output stream methods
@subsection Character output stream methods

These generic functions are used to implement subclasses of
fundamental-character-output-stream:

@include fun-sb-gray-stream-advance-to-column.texinfo
@include fun-sb-gray-stream-fresh-line.texinfo
@include fun-sb-gray-stream-line-column.texinfo
@include fun-sb-gray-stream-line-length.texinfo
@include fun-sb-gray-stream-start-line-p.texinfo
@include fun-sb-gray-stream-terpri.texinfo
@include fun-sb-gray-stream-write-char.texinfo
@include fun-sb-gray-stream-write-string.texinfo

@node Binary stream methods
@subsection Binary stream methods

The following generic functions are available for subclasses of
fundamental-binary-stream:

@include fun-sb-gray-stream-read-byte.texinfo
@include fun-sb-gray-stream-write-byte.texinfo

@include gray-streams-examples.texinfo

@node Simple Streams
@comment  node-name,  next,  previous,  up
@section Simple Streams
@include sb-simple-streams/sb-simple-streams.texinfo
