doc.txt

I/O

_I/O_
_io_

This collection provides two files:

 _file.ss_: utilities for files and paths
 _io.ss_: utilities for I/O

The I/O library provides a number of utilities for performing binary and
character-based I/O.

======================================================================

file.ss
-------

> relative-path/c :: contract

Contract for string or path values that represent relative paths. The contract
does not access the filesystem.

> relative-file-path/c :: contract

Contract for string or path values that represent relative paths of files that
actually exist. The contract always accesses the filesystem.

> relative-directory-path/c :: contract

Contract for string or path values that represent relative paths of directories
that actuall exist. The contract always accesses the filesystem.

> (path->relative-path path [relative-to]) :: (union string path) [(union string path)] -> relative-path

Converts a path or path string to a relative path, relative to the directory
specified by `relative-to', which defaults to the value of `current-directory'.

> (explode-relative-path path) :: relative-path -> (listof path)

Returns the list of relative directories that constitute `path'. The `path' must
be simplified in the sense of `simplify-path' (e.g., should not contain
up-directory or same-directory indicators) and expanded in the sense of
`expand-path' (e.g., should not contain ``~'').

This procedure does not access the filesystem.

> (collect-subdirectories path) :: relative-path -> (listof relative-path)

Returns a list of paths for all subdirectories containing `path' (and including
it, if it is itself a directory), relative to the current directory.

This procedure accesses the filesystem.

> path=? :: path path ... -> boolean

Compares two or more paths to see if they contain the same elements. The paths
are not simplified or normalized in any way. This procedure never accesses the
filesystem.

> path-normalized=? :: path path ... -> boolean

Compares two or more paths to see if they refer to the same file in the
filesystem. The paths are normalized with `normalize-path' before
comparison. This procedure always accesses the filesystem.

io.ss
-----

The following utilities are defined in io.ss:

> (with-output-to-string e1 e2 ...) :: syntax

Evaluates the expressions e1 e2 ..., capturing all standard output during the
dynamic extent of the evaluation into a string. The entire expression evaluates
to the string.

> (with-temporary-file file (args ...) e1 e2 ...) :: syntax

Creates a temporary file by applying `make-temporary-file' to the list of
argument expressions `args ...' and binds the resulting file path to the
variable given as `file'; the file exists while the expressions `e1 e2 ...' are
evaluated, and is deleted automatically when evaluation of the expressions
terminates or control leaves abnormally (due to an exception or continuation
invocation).

Note that if control leaves and reenters the body of the expression, the
temporary file will no longer exist, because it is deleted the first time
control leaves the body.

> (seekable-port? port) :: port -> boolean

Determines whether a port is seekable, i.e., whether the `file-position'
procedure should succeed on the port. This procedure does perform I/O, but does
not change the current offset in the port.

> (bit-set? i num) :: nat exact-integer -> boolean

Determines whether bit `i' is enabled in the exact integer `num'.

> (stretch-bytes bytes len [big-endian? fill-byte]) :: bytes nat [boolean byte] -> bytes

Produces a byte string of length `len', with enough copies of `fill-byte'
prefixed or appended to the bytes in the given byte string, where the order of
the bytes is determined by the value of `big-endian?'.

The value of `big-endian?' defaults to the value returned by
`system-big-endian?', and the default value of `fill-byte' is 0.

> (bytes->integer bytes signed? [big-endian? start-k end-k]) :: bytes boolean [boolean nat nat] -> exact-integer

Converts a byte string to an exact integer. The byte order is given by the value
of `big-endian?', which defaults to the value returned by
`system-big-endian?'. If `signed?' is true, the integer is decoded with two's
complement, otherwise it is decoded as an unsigned bit stream.

If `start-k' is given, the integer is decoded starting at index `start-k'
(inclusive). If `end-k' is given, the decoding stops at index `end-k'
(exclusive).

> (integer->bytes n signed? [big-endian? size-n]) :: exact-integer boolean [boolean (union #f nat)] -> bytes

Converts an exact integer to a byte string. The byte order is given by the value
of `big-endian?', which defaults to the value returned by
`system-big-endian?'. If `signed?' is true, the integer is encoded with two's
complement, otherwise it is encoded as an unsigned bit stream.

If `size-n' is not #f, then the integer is encoded in a byte string of length
`size-n', if it fits. If `n' cannot be encoded in a string of the requested size
and format, the exn:fail:contract exception is raised.

INPUT ----------------------------------------------------------------

> (skip-bytes k [in]) :: nat [input-port] -> any

Skips `k' bytes from the input port `in'. The value of the `current-input-port'
parameter is used by default.

> (read-integer k signed? [in big-endian?]) :: nat boolean [input-port boolean] -> exact-integer

Reads a `k'-byte integer from the input port `in', with the byte order given by
`big-endian?'. If `signed?' is true, the integer is decoded with two's
complement, otherwise it is decoded as an unsigned bit stream. The value of the
`current-input-port' parameter is used as the default value of `in', and the
value returned by `system-big-endian?' is used as the default byte order.

> (read-chars k [in]) :: nat [input-port] -> (listof char)

Reads `k' characters from the input port `in' and returns them in a list. The
value of the `current-input-port' parameter is used as the default value of
`in'.

> (read-c-string [in]) :: [input-port] -> bytes

Reads a C-style byte string from the input port `in', which defaults to the
value of the parameter `current-input-port'. A C-style string is terminated by a
null character or EOF.

> (read-c-string! bytes [in start-k end-k]) :: bytes input-port nat nat -> eof or nat

Reads a C-style byte string from the input port `in', and stores the bytes in
the given byte string starting at byte number `start-k' and until reaching a
null character, EOF, or byte number `end-k', whichever comes first.

If no characters are read before reaching EOF, the eof-object is
returned. Otherwise the total number of bytes read is returned.

The value of `in' defaults to the value of the parameter `current-input-port',
and the values of `start-k' and `end-k' default to 0 and the length of the given
byte string, respectively.

> (peek-chars k [in]) :: nat [input-port] -> (listof char)
> (peek-integer k [in big-endian?]) :: nat [input-port boolean] -> exact-integer

Same as their read-* counterparts, but do not advance the input port cursor.

OUTPUT ---------------------------------------------------------------

> (write-c-string s [out start-k end-k]) :: bytes [output-port nat nat] -> any

Writes a C-style (#\nul-terminated) byte string to an output port.

The substring from `start-k' (inclusive) to `end-k' (exclusive) is written to
the output port. By default, the entire string is written.

> (write-integer n signed? [out big-endian? size-n]) :: exact-integer boolean [output-port boolean (union #f nat)] -> any

Writes the integer `n' to the output port `out', with the byte order given by
`big-endian?'. If `signed?' is true, the integer is encoded with two's
complement, otherwise it is encoded as an unsigned bit stream. The value of the
`current-output-port' parameter is used as the default value of `out', and the
value returned by `system-big-endian?' is used as the default byte order.

If `size-n' is #f, the integer is written with the minimum number of bytes
required, rounded up to the nearest power of 2. Otherwise the value of `size-n'
is used as the number of bytes. If the integer cannot be encoded in `size-n'
bytes, an exn:fail:contract is raised.

> (write-chars chars [out]) :: (listof char) [output-port] -> any

Writes a sequence of characters to the specified output port, which defaults to
the value of the parameter `current-output-port'.

EXAMPLES -------------------------------------------------------------

The following code snippet demonstrates a common usage pattern for the binary
I/O utilities in this library. A simple local procedure abstracts the byte order
and input port for the local code, and the LET* block presumably follows the
specification for the binary layout of some file format. Note how the use of
LET* allows elements to be read with content length specified by previous
elements.

...
(let ([read-int (lambda (k) (read-integer k #f in #t))])
 (let* ([magic (read-int   4)]
        [len   (read-int   4)]
        [str   (read-bytes len in)])
   str))
...