of @var{proc}. Return the return values of @var{proc}.
@end deffn
+@deffn {Scheme Procedure} binary-port? port
+Return @code{#t} if @var{port} is a @dfn{binary port}, suitable for
+binary data input/output.
+
+Note that internally Guile does not differentiate between binary and
+textual ports, unlike the R6RS. Thus, this procedure returns true when
+@var{port} does not have an associated encoding---i.e., when
+@code{(port-encoding @var{port})} is @code{#f} (@pxref{Ports,
+port-encoding}). This is the case for ports returned by R6RS procedures
+such as @code{open-bytevector-input-port} and
+@code{make-custom-binary-output-port}.
+
+However, Guile currently does not prevent use of textual I/O procedures
+such as @code{display} or @code{read-char} with binary ports. Doing so
+``upgrades'' the port from binary to textual, under the ISO-8859-1
+encoding. Likewise, Guile does not prevent use of
+@code{set-port-encoding!} on a binary port, which also turns it into a
+``textual'' port.
+@end deffn
+
+@deffn {Scheme Procedure} textual-port? port
+Always return @var{#t}, as all ports can be used for textual I/O in
+Guile.
+@end deffn
+
@node R6RS Binary Input
@subsubsection Binary Input
be appreciated.
@item
-The @code{(rnrs io ports)} module is mostly unimplemented. Work is
+The @code{(rnrs io ports)} module is incomplete. Work is
ongoing to fix this.
+
+@item
+Guile does not prevent use of textual I/O procedures on binary ports.
+More generally, it does not make a sharp distinction between binary and
+textual ports (@pxref{R6RS Port Manipulation, binary-port?}).
@end itemize
@node R6RS Standard Libraries
scm_i_scm_pthread_mutex_lock (&scm_i_port_table_mutex);
port = scm_new_port_table_entry (bytevector_input_port_type);
+ c_port = SCM_PTAB_ENTRY (port);
+
+ /* Match the expectation of `binary-port?'. */
+ c_port->encoding = NULL;
/* Prevent BV from being GC'd. */
SCM_SETSTREAM (port, SCM_UNPACK (bv));
c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
c_len = SCM_BYTEVECTOR_LENGTH (bv);
- c_port = SCM_PTAB_ENTRY (port);
c_port->read_pos = c_port->read_buf = (unsigned char *) c_bv;
c_port->read_end = (unsigned char *) c_bv + c_len;
c_port->read_buf_size = c_len;
scm_i_pthread_mutex_lock (&scm_i_port_table_mutex);
port = scm_new_port_table_entry (custom_binary_input_port_type);
+ c_port = SCM_PTAB_ENTRY (port);
+
+ /* Match the expectation of `binary-port?'. */
+ c_port->encoding = NULL;
/* Attach it the method vector. */
SCM_SETSTREAM (port, SCM_UNPACK (method_vector));
/* Have the port directly access the buffer (bytevector). */
- c_port = SCM_PTAB_ENTRY (port);
c_port->read_pos = c_port->read_buf = (unsigned char *) c_bv;
c_port->read_end = (unsigned char *) c_bv;
c_port->read_buf_size = c_len;
scm_i_pthread_mutex_lock (&scm_i_port_table_mutex);
port = scm_new_port_table_entry (bytevector_output_port_type);
+ c_port = SCM_PTAB_ENTRY (port);
+
+ /* Match the expectation of `binary-port?'. */
+ c_port->encoding = NULL;
buf = (scm_t_bop_buffer *) scm_gc_malloc (sizeof (* buf), SCM_GC_BOP);
bop_buffer_init (buf);
- c_port = SCM_PTAB_ENTRY (port);
c_port->write_buf = c_port->write_pos = c_port->write_end = NULL;
c_port->write_buf_size = 0;
scm_i_pthread_mutex_lock (&scm_i_port_table_mutex);
port = scm_new_port_table_entry (custom_binary_output_port_type);
+ c_port = SCM_PTAB_ENTRY (port);
+
+ /* Match the expectation of `binary-port?'. */
+ c_port->encoding = NULL;
/* Attach it the method vector. */
SCM_SETSTREAM (port, SCM_UNPACK (method_vector));
/* Have the port directly access the buffer (bytevector). */
- c_port = SCM_PTAB_ENTRY (port);
c_port->write_buf = c_port->write_pos = c_port->write_end = NULL;
c_port->write_buf_size = c_port->read_buf_size = 0;
(= (port-column p) 0))))
(pass-if "read-char, wrong encoding, error"
- (let ((p (with-fluids ((%default-port-encoding "UTF-8"))
- (open-bytevector-input-port #vu8(255 65 66 67)))))
+ (let ((p (open-bytevector-input-port #vu8(255 65 66 67))))
(catch 'decoding-error
(lambda ()
+ (set-port-encoding! p "UTF-8")
(set-port-conversion-strategy! p 'error)
(read-char p)
#f)
(pass-if "read-char, wrong encoding, escape"
;; `escape' should behave exactly like `error'.
- (let ((p (with-fluids ((%default-port-encoding "UTF-8"))
- (open-bytevector-input-port #vu8(255 65 66 67)))))
+ (let ((p (open-bytevector-input-port #vu8(255 65 66 67))))
(catch 'decoding-error
(lambda ()
+ (set-port-encoding! p "UTF-8")
(set-port-conversion-strategy! p 'escape)
(read-char p)
#f)
(eof-object? (read-char port)))))))
(pass-if "read-char, wrong encoding, substitute"
- (let ((p (with-fluids ((%default-port-encoding "UTF-8"))
- (open-bytevector-input-port #vu8(255 206 187 206 188)))))
+ (let ((p (open-bytevector-input-port #vu8(255 206 187 206 188))))
+ (set-port-encoding! p "UTF-8")
(set-port-conversion-strategy! p 'substitute)
(equal? (list (read-char p) (read-char p) (read-char p))
'(#\? #\λ #\μ))))
#f)
(lambda (key subr message errno p)
(eq? p port)))))))
- (let ((p (with-fluids ((%default-port-encoding "UTF-8"))
- (open-bytevector-input-port #vu8(255 65 66 67)))))
+ (let ((p (open-bytevector-input-port #vu8(255 65 66 67))))
+ (set-port-encoding! p "UTF-8")
(set-port-conversion-strategy! p 'error)
;; `peek-char' should repeatedly raise an error.
(equal? (read-to-string port) str)))
+ (pass-if "bytevector-input-port is binary"
+ (with-fluids ((%default-port-encoding "UTF-8"))
+ (binary-port? (open-bytevector-input-port #vu8(1 2 3)))))
+
(pass-if-exception "bytevector-input-port is read-only"
exception:wrong-type-arg
(port (make-custom-binary-input-port "the port" read!
#f #f #f)))
- (bytevector=? (get-bytevector-all port) source)))
+ (and (binary-port? port)
+ (input-port? port)
+ (bytevector=? (get-bytevector-all port) source))))
(pass-if "custom binary input port does not support `port-position'"
(let* ((str "Hello Port!")
(put-bytevector port source)
(and (bytevector=? (get-content) source)
(bytevector=? (get-content) (make-bytevector 0))))))
-
+
+ (pass-if "bytevector-output-port is binary"
+ (binary-port? (open-bytevector-output-port)))
+
(pass-if "open-bytevector-output-port [extract after close]"
(let-values (((port get-content)
(open-bytevector-output-port)))
(bytevector=? (get-content) source)
(bytevector=? (get-content) (make-bytevector 0))))))
- (pass-if "make-custom-binary-output"
+ (pass-if "make-custom-binary-output-port"
(let ((port (make-custom-binary-output-port "cbop"
(lambda (x y z) 0)
#f #f #f)))
(eof-object? (read-line p)))))
(pass-if "decoding error"
- (let ((p (with-fluids ((%default-port-encoding "UTF-8"))
- (open-bytevector-input-port #vu8(65 255 66 67 68)))))
+ (let ((p (open-bytevector-input-port #vu8(65 255 66 67 68))))
+ (set-port-encoding! p "UTF-8")
(set-port-conversion-strategy! p 'error)
(catch 'decoding-error
(lambda ()
(eof-object? (read-line p)))))))
(pass-if "decoding error, substitute"
- (let ((p (with-fluids ((%default-port-encoding "UTF-8"))
- (open-bytevector-input-port #vu8(65 255 66 67 68)))))
+ (let ((p (open-bytevector-input-port #vu8(65 255 66 67 68))))
+ (set-port-encoding! p "UTF-8")
(set-port-conversion-strategy! p 'substitute)
(and (string=? (read-line p) "A?BCD")
(eof-object? (read-line p))))))