port.ss: Port Utilities

To load: (require (lib "port.ss"))

(convert-stream from-encoding-string input-port from-encoding-string output-port)      PROCEDURE

Reads data from input-port, converts it using (bytes-open-converter from-encoding-string to-encoding-string) and writes the converted bytes to output-port. The convert-stream procedure returns after reaching eof in input-port.

See section 3.6 in PLT MzScheme: Language Manual for more information on bytes-open-converter. If opening the converter fails, the exn:fail exception is raised. Similarly, if a conversion error occurs at any point while reading input-port, then exn:fail exception is raised.

(copy-port input-port output-port ···1)      PROCEDURE

Reads data from input-port and writes it back out to output-port, returning when input-port produces eof. The copy is efficient, and it is without significant buffer delays (i.e., a byte that becomes available on input-port is immediately transferred to output-port, even if future reads on input-port must block). If input-port produces a special non-byte value, it is transferred to output-port using write-special.

This function is often called from a ``background'' thread to continuously pump data from one stream to another.

If multiple output-ports are provided, case data from input-port is written to every output-port. The different output-ports block output to each other, because each quantum of data read from input-port is written completely to one output-port before moving to the next output-port. The output-ports are written in the provided order, so non-blocking ports (e.g., to a file) should be placed first in the argument list.

(input-port-append close-at-eof? input-port ···)      PROCEDURE

Takes any number of input ports and returns an input port. Reading from the input port draws bytes (and special non-byte values) from the given input ports in order. If close-at-eof? is true, then each port is closed when an end-of-file is encountered from the port, or when the result input port is closed. Otherwise, data not read from the returned input port remains available for reading in its original input port.

See also merge-input, which interleaves data from multiple input ports as it becomes available.

(make-input-port/read-to-peek name read-proc optional-fast-peek-proc close-proc)      PROCEDURE

Similar to make-input-port, but the given read procedure must never block, and if it returns an event, the event's value must be 0. The resulting port's peek operation is implemented automatically (in terms of read-proc) in a way that can handle special non-byte values. The progress-event and commit operations are also implemented automatically. The resulting port is thread-safe, but not kill-safe (i.e., if a thread is terminated or suspended while using the port, the port may become damaged).

The read-proc and close-proc procedures are the same as for make-input-port. The optional-fast-peek-proc argument can be either #f or a procedure of three arguments: a byte string to receive a peek, a skip count, and a procedure of two arguments. The optional-fast-peek-proc can either implement the requested peek, or it can dispatch to its third argument to implement the peek. The optional-fast-peek-proc is not used when a peek request has an associated progress event.

(make-limited-input-port input-port limit-k [close-orig?])      PROCEDURE

Returns a port whose content is drawn from input-port, but where an end-of-file is reported after limit-k bytes (and non-byte special values) are read. If close-orig? is true, then the original port is closed if the returned port is closed.

Bytes are consumed from input-port only when they are consumed from the returned port. In particular, peeking into the returned port peeks into the original port.

If input-port is used directly while the resulting port is also used, then the limit-k bytes provided by the port need not be contiguous parts of the original port's stream.

(make-pipe-with-specials [limit-k in-name-v out-name-v])      PROCEDURE

Returns two ports: an input port and an output port. The pipes behave like those returned by make-pipe, except that the ports support non-byte values written with procedures such as write-special and read with procedures such as get-byte-or-special.

The limit-k argument determines the maximum capacity of the pipe in bytes, but this limit is disabled if special values are written to the pipe before limit-k is reached.

The optional in-name-v and out-name-v arguments determine the names of the result ports, and both names default to 'pipe.

(merge-input a-input-port b-input-port [limit-k])      PROCEDURE

Accepts two input ports and returns a new input port. The new port merges the data from two original ports, so data can be read from the new port whenever it is available from either original port. The data from the original ports are interleaved. When EOF has been read from an original port, it no longer contributes characters to the new port. After EOF has been read from both original ports, the new port returns EOF. Closing the merged port does not close the original ports.

The optional limit-k argument limits the number of bytes to be buffered from a-input-port and b-input-port, so that the merge process does not advance arbitrarily beyond the rate of consumption of the merged data. A #f value disables the limit; the default is 4096. As for make-pipe-with-specials, limit-k does not apply when a special value is produced by one of the input ports before the limit is reached.

See also input-port-append, which concatenates input streams instead of interleaving them.

(open-output-nowhere [name special-ok?])      PROCEDURE

Creates and returns an output port that discards all output sent to it (without blocking). The name argument is used as the port's name, and it defaults to 'nowhere. If the special-ok? argument is true (the default), then the resulting port supports write-special, otherwise it does not.

(peeking-input-port input-port [name skip-k])      PROCEDURE

Returns an input port whose content is determined by peeking into input-port. In other words, the resulting port contains an internal skip count, and each read of the port peeks into input-port with the internal skip count, and then increments the skip count according to the amount of data successfully peeked.

The optional name argument is the name of the resulting port, and it defaults to (object-name input-port). The skip-k argument is the port initial skip count, and it defaults to 0.

(eof-evt input-port)      PROCEDURE

Returns a synchronizable event (see section 7.7 in PLT MzScheme: Language Manual) is that is ready when input-port produces an eof. If input-port produces a mid-stream eof, the eof is consumed by the event only if the event is chosen in a synchronization.

(read-bytes-evt k input-port)      PROCEDURE

Returns a synchronizable event (see section 7.7 in PLT MzScheme: Language Manual) is that is ready when k bytes can be read from input-port, or when an end-of-file is encountered in input-port. If k is 0, then the event is ready immediately with "". For non-zero k, if no bytes are available before an end-of-file, the event's result is eof. Otherwise the event's result is a byte string of up to k bytes, which contains as many bytes as are available (up to k) before an available end-of-file. (The result is a string on less than k bytes only when an end-of-file is encountered.)

Bytes are read from the port if and only if the event is chosen in a synchronization, and the returned bytes always represent contiguous bytes in the port's stream.

The event can be synchronized multiple times -- event concurrently -- and each synchronization corresponds to a distinct read request.

The input-port must support progress events, and it must not produce a special non-byte value during the read attempt.

(read-bytes!-evt mutable-bytes input-port)      PROCEDURE

Like read-bytes-evt, except that the read bytes are placed into mutable-bytes, and the number of bytes to read corresponds to (bytes-length mutable-bytes). The event's result is either eof or the number of read bytes.

The mutable-bytes string may be mutated any time after the first synchronization attempt on the event. If the event is not synchronized multiple times concurrently, mutable-bytes is never mutated by the event after it is chosen in a synchronization (no matter how many synchronization attempts preceded the choice). Thus, the event may be sensibly used multiple times until a successful choice, but should not be used in multiple concurrent synchronizations.

(read-bytes-avail!-evt mutable-bytes input-port)      PROCEDURE

Like read-bytes!-evt, except that the event reads only as many bytes as are immediately available, after at least one byte or one eof becomes available.

(read-string-evt k input-port)      PROCEDURE

Like read-bytes-evt, but for character strings instead of byte strings.

(read-string!-evt mutable-string input-port)      PROCEDURE

Like read-bytes!-evt, but for a character string instead of a byte string.

(read-line-evt input-port [mode-symbol])      PROCEDURE

Returns a synchronizable event (see section 7.7 in PLT MzScheme: Language Manual) that is ready when a line of characters or end-of-file can be read from inport. The meaning of mode-symbol is the same as for read-line (see section 11.2.1 in PLT MzScheme: Language Manual). The event result is the read line of characters (not including the line separator).

A line is read from the port if and only if the event is chosen in a synchronization, and the returned line always represents contiguous bytes in the port's stream.

(read-bytes-line-evt input-port [mode-symbol])      PROCEDURE

Like read-line, but returns a byte string instead of a string.

(peek-bytes-evt k skip-k progress-evt input-port)      PROCEDURE

(peek-bytes-bytes!-evt mutable-bytes skip-k progress-evt input-port)      PROCEDURE

(peek-bytes-avail!-evt mutable-bytes skip-k progress-evt input-port)      PROCEDURE

(peek-string-evt k input-port)      PROCEDURE

(peek-string!-evt mutable-string input-port)      PROCEDURE

Like the read-...-evt functions, but for peeking. The skip-k argument indicates the number of bytes to skip, and progress-evt indicates an event that effectively cancels the peek (so that the event never becomes ready). The progress-evt argument can be #f, in which case the event is never cancelled.

(reencode-input-port input-port encoding-str [error-bytes close? name-v])      PROCEDURE

Produces an input port that draws bytes from input-port, but converts the byte stream using (bytes-open-converter encoding-str "UTF-8").

If error-bytes is provided and not #f, then the given byte sequence is used in place of bytes from input-port that trigger conversion errors. Otherwise, if a conversion is encountered, the exn:fail exception is raised.

If close? is true, then closing the result input port also closes input-port.

If name-v is provided, it is used as the name of the result input port, otherwise the port is named by (object-name input-port).

In non-buffered mode, the resulting input port attempts to draw bytes from input-port only as needed to satisfy requests. Toward that end, the input port assumes that at least n bytes must be read to satisfy a request for n bytes. (This is true even if the port has already drawn some bytes, as long as those bytes form an incomplete encoding sequence.)

(reencode-output-port output-port encoding-str [error-bytes close? name-v buffer-sym])      PROCEDURE

Produces an output port that direct bytes to output-port, but converts its byte stream using (bytes-open-converter encoding-str "UTF-8").

If error-bytes is provided and not #f, then the given byte sequence is used in place of bytes send to the output port that trigger conversion errors. Otherwise, if a conversion is encountered, the exn:fail exception is raised.

If close? is true, then closing the result output port also closes output-port.

If name-v is provided, it is used as the name of the result output port, otherwise the port is named by (object-name output-port).

The buffer-sym argument determines the buffer mode of the output port, and it must be 'block, 'line, or 'none. If output-port is a file-stream port, the default is (file-stream-buffer-mode output-port), otherwise the default is 'block. In 'block mode, the port's buffer is flushed only when it is full or a flush is requested explicitly. In 'line mode, the buffer is flushed whenever a newline or carriage-return byte is written to the port. In 'none mode, the port's buffer is flushed after every write. Implicit flushes for 'line or 'none leave bytes in the buffer when they are part of an incomplete encoding sequence.

The resulting output port does not support atomic writes. An explicit flush or special-write to the output port can hang if the most recently written bytes form an incomplete encoding sequence.

(regexp-match-evt pattern input-port)      PROCEDURE

Returns a synchronizable event (see section 7.7 in PLT MzScheme: Language Manual) that is ready when pattern matches the stream of bytes/characters from input-port (see also section 10 in PLT MzScheme: Language Manual). The event's value is the result of the match, in the same form as the result of regexp-match.

If pattern does not require a start-of-stream match, then bytes skipped to complete the match are read and discarded when the event is chosen in a synchronization.

Bytes are read from the port if and only if the event is chosen in a synchronization, and the returned match always represents contiguous bytes in the port's stream. If not-yet-available bytes from the port might contribute to the match, the event is not ready. Similarly, if pattern begins with a start-of-string caret (``^'') and the pattern does not initially match, then the event cannot become ready until bytes have been read from the port.

The event can be synchronized multiple times -- even concurrently -- and each synchronization corresponds to a distinct match request.

The input-port must support progress events. If input-port returns a special non-byte value during the match attempt, it is treated like eof.

(relocate-input-port input-port line-k column-k position-k [close?])      PROCEDURE

Produces an input port that is equivalent to input-port except in how it reports location information. The resulting port's content starts with the remaining content of input-port, and it starts at the given line, column, and position. The line-k argument must be a positive exact integer or #f, column-k must be a non-negative exact integer or #f, and position-k must be a positive exact integer (#f is not allowed for position-k). A #f for the line or column means that the line and column will always be reported as #f.

The line-k and column-k values are used only if line counting is enabled for input-port and for the resulting port, typically through port-count-lines! (see section 11.2.1.1 in PLT MzScheme: Language Manual). The column-k value determines the column for the first line (i.e., the one numbered line-k), and later lines start at column 0. The given position-k is used even if line counting is not enabled.

When line counting is on for the resulting port, reading from input-port instead of the resulting port increments location reports from the resulting port. Otherwise, the resulting port's position does not increment when data is read from input-port.

If close? is true (the default), then closing the resulting port also closes input-port. If close? is #f, then closing the resulting port does not close input-port.

(relocate-output-port output-port line-k column-k position-k [close?])      PROCEDURE

Like relocate-input-port, but for output ports.

(transplant-input-port input-port position-thunk position-k [close? count-lines!-proc])      PROCEDURE

Like relocate-input-port, except that arbitrary position information can be produced (when line counting is enabled) via position-thunk. If position-thunk is #f, then the port counts lines in the usual way, independent of locations reported by input-port.

If count-lines!-proc is supplied, it is called when line counting is enabled for the resulting port. The default is void.

(transplant-output-port input-port position-thunk position-k [close? count-lines!-proc])      PROCEDURE

Like transplant-input-port, but for output ports.

(strip-shell-command-start input-port)      PROCEDURE

Reads and discards a leading #! in input-port (plus continuing lines if the line ends with a backslash) in the same way as the default load handler.