by The R6RS editors; John Cowan (shepherd); Shiro Kawai (implementation; requires a hook)
This SRFI is currently in final status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-192@nospamsrfi.schemers.org
. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This is an extract from the R6RS that documents its support for positioning ports. Binary ports can be positioned to read or write at a specific byte; textual ports at a specific character, although character positions can't be synthesized portably. It has been lightly edited to fit R7RS style.
The procedures documented in this SRFI allow reading bytes or characters from a port, especially a port associated with a file, in arbitrary order. By setting the port position before reading or writing, it is possible to jump to the nth record in a flat file of fixed-length records, or to rewind a file and process it repeatedly, or to discover the length of a file, or to append to it (though in the presence of multiple writers, this technique for appending is not reliable). While these abilities are not as important as they once were, they still have their uses.
Note that transcoded ports
do not always support the port-position
and
set-port-position!
operations.
The position of a transcoded port may not be well-defined,
and may be hard to calculate even when defined,
especially when transcoding operations are done in bulk.
Similarly, although custom ports have provisions for supporting port positioning, it is not appropriate for all custom ports to do so.
(port-has-port-position? port)
(port-position port)
The port-has-port-position?
procedure returns #t
if the
port supports the port-position
operation, and #f
otherwise. If the port does not support the operation, port-position
signals
an error.
The port-position
procedure returns some implementation-dependent
object representing as much of the state of the port at its current position
as is necessary to save and restore that position. This is at a minimum the position itself.
This value may be useful only as
the pos argument to set-port-position!
, if the latter is
even supported on the port (see below).
However, if the port is binary and the object is an exact integer,
then it is the position measured in bytes,
and can be used to compute a new position some
specified number of bytes away.
(port-has-set-port-position!? port)
(set-port-position! port pos)
For a textual port, it is implementation-defined what happens if pos is not
the return value of a call to port-position
on port.
However, a binary port will also accept an exact integer,
in which case the port position is set to the specified number of bytes
from the beginning of the port data.
If this is not sufficient information to specify the port state,
or the specified position is uninterpretable by the port,
an error satisfying i/o-invalid-position-error?
is signaled.
The port-has-set-port-position!?
procedure returns #t
if the port
supports the set-port-position!
operation, and #f
otherwise.
If set-port-position!
procedure is invoked on
a port that does not support the operation
or if pos is not in the range of valid positions of port,
set-port-position!
signals an error.
Otherwise, it sets the current position
of the port to pos. If port is an output
port, set-port-position!
first flushes port
(even if the port position will not change).
If port is a binary output port and the current position is set
beyond the current end of the data in the underlying data sink, the object is
not extended until new data is written at that position.
The contents of any intervening positions are unspecified.
It is also possible to set the position of a binary input port
beyond the end of the data in the data source,
but a read will fail unless the data has been extended by other means.
File ports can always be extended in this manner
within the limits of the underlying operating system.
In other types of ports, if an attempt is made to set the position beyond the
current end of data in the underlying object,
and the object does not support extension,
an error satisfying i/o-invalid-position-error?
is signaled.
(make-i/o-invalid-position-error pos)
Returns a condition object which satisfies
i/o-invalid-position-error?
. The pos argument
represents a position passed to set-position!
.
(i/o-invalid-position-error? obj)
Returns #t
if obj is an object created by
make-i/o-invalid-position-error?
or an object raised in the
circumstances described in this SRFI, or #f
if it is not.
Every conforming R6RS implementation, including at least Chez,
Guile, IronScheme, Larceny, Racket, and Vicare, provides these
procedures in the (rnrs io ports)
library.
R6RS binary ports always return the port position as an exact integer.
There is a sample implementation for R7RS that depends on overriding the built-in port procedures. It illustrates both SRFI 181 and SRFI 192, and it can be found in the Git repository for SRFI 192.
There is also a second sample implementation for Gauche using its native facilities, though it is incomplete.
This would have been much more difficult without the R6RS team, who produced a good-enough (as opposed to perfect) design that John was happy to adopt.
Much of the content of this SRFI is drawn from R6RS, which does not have a copyright notice. It does, however, contain the following copyright license:
We intend this report to belong to the entire Scheme community, and so we grant permission to copy it in whole or in part without fee.
For the remaining content, the standard SRFI license applies:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.