21.7. The Streams Dictionary
Prev | Chapter 21. Streams | Next

## 21.7. The Streams Dictionary [sec_the_streams_dictionary]

### 21.7.1. Function `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

- both equivalent to `CHARACTER` or `(`UNSIGNED-BYTE` 8)` or `(`SIGNED-BYTE` 8)`; or
- both equivalent to `(`UNSIGNED-BYTE` `n`)` or `(`SIGNED-BYTE` `n`)`, with the same `n`.

Functions `STREAM-ELEMENT-TYPE` and `(`SETF` `STREAM-ELEMENT-TYPE`)` are `GENERIC-FUNCTION`s, see Chapter 30, Gray streams.

#### 21.7.1.1. Binary input from `*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` on 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 `(`EXT:GETENV` `"CONTENT_LENGTH"`)` to determine how much data you should read from `stdin`. CLISP will detect that `stdin` is not a terminal and create a regular `FILE-STREAM` which can be passed to `(`SETF` `STREAM-ELEMENT-TYPE`)`. To test this functionality interactively, you will need to open the standard input in the binary mode:

    (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)

### 21.7.2. Function `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:

number
  denotes the file descriptor of this value
`:INPUT`
  denotes CLISP process `*STANDARD-INPUT*`
`:OUTPUT`
  denotes CLISP process `*STANDARD-OUTPUT*`
`:ERROR`
  denotes CLISP process `*ERROR-OUTPUT*`
`STREAM`
  denotes the handle of this stream, which should be a `FILE-STREAM` or a `SOCKET:SOCKET-STREAM`

### Beware of buffering!

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

### 21.7.3. Function `FILE-POSITION`

`FILE-POSITION` works on any `FILE-STREAM`.

Platform Dependent: Win32 platform only.
  When a #\Newline is output to (respectively input from) a file stream, its file position is increased by 2 since #\Newline is encoded as CR/LF in the file.

### 21.7.4. Function `EXT:ELASTIC-NEWLINE`

The function `(`EXT:ELASTIC-NEWLINE` [`stream`])` is like `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 Section 21.6, “Newline Convention”.

### 21.7.5. Function `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`)`, `(`SIGNED-BYTE` `n`)`; if the stream is to be un`: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 `(`UNSIGNED-BYTE` 3)` 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.

`: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.

  - for functions that create `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;
  - for functions that open files, `: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 out 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`).

### 21.7.6. Function `CLOSE`

Function `CLOSE` is a `GENERIC-FUNCTION`, see Chapter 30, 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.

### 21.7.7. Function `OPEN-STREAM-P`

Function `OPEN-STREAM-P` is a `GENERIC-FUNCTION`, see Chapter 30, Gray streams.

### 21.7.8. Class `BROADCAST-STREAM`

`INPUT-STREAM-P` and `INTERACTIVE-STREAM-P` return false for `BROADCAST-STREAM`s.

### 21.7.9. Functions `EXT:MAKE-BUFFERED-INPUT-STREAM` and `EXT:MAKE-BUFFERED-OUTPUT-STREAM`

`(EXT:MAKE-BUFFERED-OUTPUT-STREAM `function`)`. Returns a buffered output `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 `function` `mode`)`. Returns a buffered input `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`
  the stream acts like a `FILE-STREAM`, i.e. `function` is called
`T`
  the stream acts like an interactive stream without `end-of-stream`, i.e. one can assume that further characters will always arrive, without calling `function`
`FUNCTION`
  this `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.45 | Last modified: 2008-04-15

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
21.6. Newline Convention | Home | Chapter 22. Printer