guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 01/01: Implement R6RS custom binary input/output ports


From: Andy Wingo
Subject: [Guile-commits] 01/01: Implement R6RS custom binary input/output ports
Date: Thu, 4 Aug 2016 20:35:48 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 1a1c3bbe597f3682066266ce44bf9bbed2481ad2
Author: Andy Wingo <address@hidden>
Date:   Thu Aug 4 22:29:51 2016 +0200

    Implement R6RS custom binary input/output ports
    
    * NEWS: Add new feature.
    * doc/ref/r6rs.texi (rnrs io ports):
    * doc/ref/api-io.texi (Custom Ports): Document new procedure.
    * libguile/r6rs-ports.h:
    * libguile/r6rs-ports.c (make_custom_binary_input_output_port)
      (scm_make_custom_binary_input_output_port)
      (custom_binary_input_output_port_random_access_p)
      (initialize_custom_binary_input_output_ports)
      (scm_init_r6rs_ports): Implement custom binary input/output ports.
    * module/rnrs/io/ports.scm (rnrs):
    * module/ice-9/binary-ports.scm (ice-9): Export
      make-custom-binary-input/output-port.
---
 NEWS                          |    1 +
 doc/ref/api-io.texi           |   12 ++++++
 doc/ref/r6rs.texi             |    1 +
 libguile/r6rs-ports.c         |   86 +++++++++++++++++++++++++++++++++++++++++
 libguile/r6rs-ports.h         |    2 +
 module/ice-9/binary-ports.scm |    3 +-
 module/rnrs/io/ports.scm      |    1 +
 7 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 5286a43..75e0988 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ Changes in 2.1.4 (changes since the 2.1.3 alpha release):
 * New interfaces
 
 ** Implement R6RS output-buffer-mode
+** Implement R6RS custom binary input/output ports
 ** Implement R6RS bytevector->string, string->bytevector
 
 * New deprecations
diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
index 2362053..76c8db8 100644
--- a/doc/ref/api-io.texi
+++ b/doc/ref/api-io.texi
@@ -1299,6 +1299,18 @@ though an end-of-file was sent to the byte sink.
 The other arguments are as for @code{make-custom-binary-input-port}.
 @end deffn
 
address@hidden custom binary input/output ports
address@hidden {Scheme Procedure} make-custom-binary-input/output-port id read! 
write! get-position set-position! close
+Return a new custom binary input/output port named @var{id} (a string).
+The various arguments are the same as for The other arguments are as for
address@hidden and
address@hidden  If buffering is enabled on the
+port, as is the case by default, input will be buffered in both
+directions; @xref{Buffering}.  If the @var{set-position!} function is
+provided and not @code{#f}, then the port will also be marked as
+random-access, causing the buffer to be flushed between reads and
+writes.
address@hidden deffn
 
 @node Soft Ports
 @subsubsection Soft Ports
diff --git a/doc/ref/r6rs.texi b/doc/ref/r6rs.texi
index eaee821..fa8d7d2 100644
--- a/doc/ref/r6rs.texi
+++ b/doc/ref/r6rs.texi
@@ -1757,6 +1757,7 @@ respectively.  Whether the port supports the 
@code{port-position} and
 
 @deffn {Scheme Procedure} make-custom-binary-input-port id read! get-position 
set-position! close
 @deffnx {Scheme Procedure} make-custom-binary-output-port id write! 
get-position set-position! close
address@hidden {Scheme Procedure} make-custom-binary-input/output-port id read! 
write! get-position set-position! close
 @xref{Custom Ports}.
 @end deffn
 
diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c
index c53b53b..b52eb85 100644
--- a/libguile/r6rs-ports.c
+++ b/libguile/r6rs-ports.c
@@ -948,6 +948,91 @@ initialize_custom_binary_output_ports (void)
 
 
 
+/* Custom binary input_output ports.  */
+
+static scm_t_port_type *custom_binary_input_output_port_type;
+
+
+static inline SCM
+make_custom_binary_input_output_port (SCM read_proc, SCM write_proc,
+                                      SCM get_position_proc,
+                                      SCM set_position_proc, SCM close_proc)
+{
+  struct custom_binary_port *stream;
+  const unsigned long mode_bits = SCM_WRTNG | SCM_RDNG;
+
+  stream = scm_gc_typed_calloc (struct custom_binary_port);
+  stream->read = read_proc;
+  stream->write = write_proc;
+  stream->get_position = get_position_proc;
+  stream->set_position_x = set_position_proc;
+  stream->close = close_proc;
+
+  return scm_c_make_port_with_encoding (custom_binary_input_output_port_type,
+                                        mode_bits, sym_ISO_8859_1, sym_error,
+                                        (scm_t_bits) stream);
+}
+
+SCM_DEFINE (scm_make_custom_binary_input_output_port,
+           "make-custom-binary-input/output-port", 6, 0, 0,
+           (SCM id, SCM read_proc, SCM write_proc, SCM get_position_proc,
+            SCM set_position_proc, SCM close_proc),
+           "Return a new custom binary input/output port.  The port's input\n"
+            "is drained by invoking @var{read_proc} and passing it a\n"
+            "bytevector, an index where octets should be written, and an\n"
+            "octet count.  The output is drained by invoking 
@var{write_proc}\n"
+            "and passing it a bytevector, an index where octets should be\n"
+            "written, and an octet count.")
+#define FUNC_NAME s_scm_make_custom_binary_input_output_port
+{
+  SCM_VALIDATE_STRING (1, id);
+  SCM_VALIDATE_PROC (2, read_proc);
+  SCM_VALIDATE_PROC (3, write_proc);
+
+  if (!scm_is_false (get_position_proc))
+    SCM_VALIDATE_PROC (4, get_position_proc);
+
+  if (!scm_is_false (set_position_proc))
+    SCM_VALIDATE_PROC (5, set_position_proc);
+
+  if (!scm_is_false (close_proc))
+    SCM_VALIDATE_PROC (6, close_proc);
+
+  return make_custom_binary_input_output_port
+    (read_proc, write_proc, get_position_proc, set_position_proc, close_proc);
+}
+#undef FUNC_NAME
+
+
+static int
+custom_binary_input_output_port_random_access_p (SCM port)
+{
+  struct custom_binary_port *stream = (void *) SCM_STREAM (port);
+
+  return scm_is_true (stream->set_position_x);
+}
+
+
+/* Instantiate the custom binary input_output port type.  */
+static inline void
+initialize_custom_binary_input_output_ports (void)
+{
+  custom_binary_input_output_port_type =
+    scm_make_port_type ("r6rs-custom-binary-input/output-port",
+                       custom_binary_input_port_read,
+                       custom_binary_output_port_write);
+
+  scm_set_port_seek (custom_binary_input_output_port_type,
+                     custom_binary_port_seek);
+  scm_set_port_random_access_p (custom_binary_input_output_port_type,
+                                
custom_binary_input_output_port_random_access_p);
+  scm_set_port_close (custom_binary_input_output_port_type,
+                      custom_binary_port_close);
+}
+
+
+
+
 /* Transcoded ports.  */
 
 static scm_t_port_type *transcoded_port_type = 0;
@@ -1082,5 +1167,6 @@ scm_init_r6rs_ports (void)
   initialize_custom_binary_input_ports ();
   initialize_bytevector_output_ports ();
   initialize_custom_binary_output_ports ();
+  initialize_custom_binary_input_output_ports ();
   initialize_transcoded_ports ();
 }
diff --git a/libguile/r6rs-ports.h b/libguile/r6rs-ports.h
index 3dde4d5..a2c63c7 100644
--- a/libguile/r6rs-ports.h
+++ b/libguile/r6rs-ports.h
@@ -39,6 +39,8 @@ SCM_API SCM scm_put_u8 (SCM, SCM);
 SCM_API SCM scm_put_bytevector (SCM, SCM, SCM, SCM);
 SCM_API SCM scm_open_bytevector_output_port (SCM);
 SCM_API SCM scm_make_custom_binary_output_port (SCM, SCM, SCM, SCM, SCM);
+SCM_API SCM scm_make_custom_binary_input_output_port (SCM, SCM, SCM,
+                                                      SCM, SCM, SCM);
 SCM_API SCM scm_get_string_n_x (SCM, SCM, SCM, SCM);
 
 SCM_API void scm_init_r6rs_ports (void);
diff --git a/module/ice-9/binary-ports.scm b/module/ice-9/binary-ports.scm
index 9d6c945..e0da3df 100644
--- a/module/ice-9/binary-ports.scm
+++ b/module/ice-9/binary-ports.scm
@@ -42,7 +42,8 @@
             put-bytevector
             unget-bytevector
             open-bytevector-output-port
-            make-custom-binary-output-port))
+            make-custom-binary-output-port
+            make-custom-binary-input/output-port))
 
 ;; Note that this extension also defines %make-transcoded-port, which is
 ;; not exported but is used by (rnrs io ports).
diff --git a/module/rnrs/io/ports.scm b/module/rnrs/io/ports.scm
index 5ddc3d5..e924ad8 100644
--- a/module/rnrs/io/ports.scm
+++ b/module/rnrs/io/ports.scm
@@ -71,6 +71,7 @@
 
           ;; input/output ports
           open-file-input/output-port
+          make-custom-binary-input/output-port
 
           ;; binary output
           put-u8 put-bytevector



reply via email to

[Prev in Thread] Current Thread [Next in Thread]