transcoded-port(3scm) Scheme Programmer's Manual transcoded-port(3scm)

transcoded-port - convert a binary port to a textual port

(import (rnrs))                     ;R6RS
(import (rnrs io ports))            ;R6RS

(transcoded-port binary-port transcoder)

Returns a new textual port with the specified transcoder.

The new textual port's state is largely the same as that of binary-port.

The binary-port is closed in a special way that allows the new textual port to continue to use the byte source and/or sink represented by binary-port, even though binary-port itself is closed and cannot be used anymore for input and output.

Returns a single value, which is a textual port.

;; This is like utf8->string
(let* ((p (open-bytevector-input-port #vu8(194 169)))
       (tc (make-transcoder (utf-8-codec)))
       (tp (transcoded-port p tc)))
  (get-string-all tp))
        => "©"

This is used in applications that initially operate on a port in binary mode before switching to textual mode, such as programs that detect a file's encoding or that write a binary header. It is also used when an API provides a binary port, such as in networking libraries, but the port is passed to a library designed for textual ports.

Transcoding is more efficient when performed on a buffer. If the underlying port was still directly usable then it would be in conflict with such buffering. Therefore the binary port is closed, while the underlying sink and/or source is kept open.

Compatible with R6RS and semi-compatible with Scheme implementations that provide SRFI-181. The latter attempted to remove textual input/output ports but does not say what happens when a binary input/output port is passed to transcoded-port. It also makes it an error to read from or write to the binary-port before calling transcoded-port.

This procedure can raise exceptions with the following condition types:
&assertion (R6RS)
The wrong number of arguments was passed or an argument was outside its domain. May be raised if binary-port is closed.

make-transcoder(3scm), open-input-file(3scm), ports(7scm)

R6RS, SRFI-181

The transcoded-port procedure first appeared in R6RS as part of the reworked I/O system. It was much later the subject of SRFI-186, which was withdrawn and superseded by the somewhat earlier SRFI-181 (an instance of the "twin paradox" in special relativity).

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://weinholt.se/scheme/manpages/.

How to close the port in the "special way" is not obvious and has been interpreted differently, but the intention is clearly just to stop the sink and/or source from being used through passing binary-port to an I/O procedure.

Ports can be both input and output ports. This gives rise to some tricky situations, and gets worse in combination with transcoders. Implementors should be careful to get the edge cases right.

2022-04-04