Version 1 (modified by alexshinn, 6 years ago) (diff)

adding a new binary I/O proposal

We specify the two ports types - binary and character - as in PortsCowan, but make them distinct. The following procedures are provided as in the draft, but whether or not they are disjoint is implementation-dependent:

  • (character-port? <obj>)
  • (binary-port? <obj>)
Rationale: Many existing languages, including some of the most popular
such as C/C++ and Java, enforce a strict distinction between binary
and textual ports.  Allowing programs to freely shift between binary
and textual operations is error-prone and difficult to implement
efficiently, especially if buffered encoding conversions are desired.

All ports described in the R5RS are character by default. New binary ports may be opened on files with the following procedures:

  • (open-binary-input-file <path>)
  • (open-binary-output-file <path>)
Rationale: The current draft follows Gambit's convention of using
property lists to specify additional file options, such as binary or
textual encoding.  This allows for extensibility, but we do not use
any of this flexibility in WG1, and it is unclear if this is the best
way to specify file options.  It also doesn't address the fact that we
need separate procedures for creating new ports anyway, such as for
TCP/IP ports, and our APIs should be consistent and reflect this.

The standard input and output ports which current-input-port and current-output-port are bound to are not opened explicitly, so they present some difficulty. They default to character, but can be converted to binary with the following procedures:

  • (standard-input-is-binary!)
  • (standard-output-is-binary!)

It is an error to call either of these if the corresponding current-in/output-port is not the original value, or if any I/O has been performed on them.

The following operations can be performed on binary ports as in the current draft:

  • (read-u8 [<input-port>])
  • (peek-u8 [<input-port>])
  • (u8-ready? [<input-port>])
  • (write-u8 <octet> [<output-port>])

The following utility is also provided for the common idiom of opening a port from some arbitrary source, performing some work on it, then closing the port:

  • (call-with-port <port> <proc>)
Note that `current-in/output-port` are parameters, and can be
parameterized as such, obviating the need for `with-in/output-port`

To work with mixed binary/textual I/O, the following R6RS-compatible procedures are provided:

  • (read-blob <length> [<input-port>])
  • (read-blob! <blob> <length> [<input-port>])
  • (utf8->string <blob>)
  • (string->utf8 <string>)