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
(
and writes the converted bytes to bytes-open-converter
from-encoding-string to-encoding-string)output-port
. The
convert-stream
procedure returns after reaching
in eof
input-port
.
See section 3.6 in PLT MzScheme: Language Manual for more information on
. If opening the converter fails, the
bytes-open-converter
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-port
s are provided, case data from
input-port
is written to every output-port
. The different
output-port
s 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-port
s 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 limit is re-enabled
after the special value is read from the pipe.
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
. The
input-port
)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
. If eof
input-port
produces a mid-stream
, the eof
is consumed by
the event only if the event is chosen in a synchronization.eof
(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
. Otherwise
the event's result is a byte string of up to eof
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 (
. The event's result is
either bytes-length
mutable-bytes)
or the number of read bytes.eof
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
becomes available.eof
(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
, otherwise the
default is output-port
)'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
(see
section 11.2.1.1 in PLT MzScheme: Language Manual). The port-count-lines!
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). Since #!
followed by a forward slash or space is a comment, this procedure
is not needed before reading Scheme expressions.