Add get-bytevector-some!.
authorMark H Weaver <mhw@netris.org>
Wed, 17 Apr 2019 03:13:06 +0000 (23:13 -0400)
committerMark H Weaver <mhw@netris.org>
Tue, 18 Jun 2019 06:05:20 +0000 (02:05 -0400)
* libguile/r6rs-ports.c (scm_get_bytevector_some_x): New procedure.
* libguile/r6rs-ports.h (scm_get_bytevector_some_x): Add prototype.
(scm_unget_bytevector): Move prototype next to 'scm_get_bytevector_some_x'.
* module/ice-9/binary-ports.scm: Export 'get-bytevector-some!'.
* doc/ref/api-io.texi (Binary I/O): Document it.

doc/ref/api-io.texi
libguile/r6rs-ports.c
libguile/r6rs-ports.h
module/ice-9/binary-ports.scm

index 24890a12e374514754e297d2b13039759f5ba81e..270a97075c03f6e896568980c06bc259fbaa4cd5 100644 (file)
@@ -1,7 +1,7 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
 @c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009,
-@c   2010, 2011, 2013, 2016  Free Software Foundation, Inc.
+@c   2010, 2011, 2013, 2016, 2019  Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
 @node Input and Output
@@ -194,6 +194,14 @@ new bytevector containing some of the available bytes (at least one),
 and update the port position to point just past these bytes.
 @end deffn
 
+@deffn {Scheme Procedure} get-bytevector-some! port bv start count
+@deffnx {C Function} scm_get_bytevector_some_x (port, bv, start, count)
+Read up to @var{count} bytes from @var{port}, blocking as necessary
+until at least one byte is available or an end-of-file is reached.
+Store them in @var{bv} starting at index @var{start}.  Return the number
+of bytes actually read, or an end-of-file object.
+@end deffn
+
 @deffn {Scheme Procedure} get-bytevector-all port
 @deffnx {C Function} scm_get_bytevector_all (port)
 Read from @var{port}, blocking as necessary, until the end-of-file is
index 90387e82ce74ae1893364d6162a8a50c8a89cead..84038022c338ac1cd04eb08ecdd94e06568660a1 100644 (file)
@@ -514,6 +514,49 @@ SCM_DEFINE (scm_get_bytevector_some, "get-bytevector-some", 1, 0, 0,
 }
 #undef FUNC_NAME
 
+SCM_DEFINE (scm_get_bytevector_some_x, "get-bytevector-some!", 4, 0, 0,
+           (SCM port, SCM bv, SCM start, SCM count),
+            "Read up to @var{count} bytes from @var{port}, blocking "
+            "as necessary until at least one byte is available or an "
+            "end-of-file is reached.  Store them in @var{bv} starting "
+            "at index @var{start}.  Return the number of bytes actually "
+            "read, or an end-of-file object.")
+#define FUNC_NAME s_scm_get_bytevector_some_x
+{
+  SCM buf;
+  size_t c_start, c_count, c_len;
+  size_t cur, avail, transfer_size;
+
+  SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
+  SCM_VALIDATE_BYTEVECTOR (2, bv);
+  c_start = scm_to_size_t (start);
+  c_count = scm_to_size_t (count);
+
+  c_len = SCM_BYTEVECTOR_LENGTH (bv);
+
+  if (SCM_UNLIKELY (c_len < c_start
+                    || c_len - c_start < c_count))
+    scm_out_of_range (FUNC_NAME, count);
+
+  if (c_count == 0)
+    return SCM_INUM0;
+
+  buf = scm_fill_input (port, 0, &cur, &avail);
+  if (avail == 0)
+    {
+      scm_port_buffer_set_has_eof_p (buf, SCM_BOOL_F);
+      return SCM_EOF_VAL;
+    }
+
+  transfer_size = min (avail, c_count);
+  scm_port_buffer_take (buf,
+                        (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (bv) + c_start,
+                        transfer_size, cur, avail);
+
+  return scm_from_size_t (transfer_size);
+}
+#undef FUNC_NAME
+
 SCM_DEFINE (scm_get_bytevector_all, "get-bytevector-all", 1, 0, 0,
            (SCM port),
            "Read from @var{port}, blocking as necessary, until "
index a2c63c7f44d7c4b71d80d2a5ab9f78516313240e..51dec41858a5119651c95a3c2ade9f4568d4cc0c 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SCM_R6RS_PORTS_H
 #define SCM_R6RS_PORTS_H
 
-/* Copyright (C) 2009, 2010, 2011, 2013 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2011, 2013, 2019 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -34,7 +34,6 @@ SCM_API SCM scm_get_bytevector_n (SCM, SCM);
 SCM_API SCM scm_get_bytevector_n_x (SCM, SCM, SCM, SCM);
 SCM_API SCM scm_get_bytevector_some (SCM);
 SCM_API SCM scm_get_bytevector_all (SCM);
-SCM_API SCM scm_unget_bytevector (SCM, SCM, SCM, SCM);
 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);
@@ -46,4 +45,8 @@ SCM_API SCM scm_get_string_n_x (SCM, SCM, SCM, SCM);
 SCM_API void scm_init_r6rs_ports (void);
 SCM_INTERNAL void scm_register_r6rs_ports (void);
 
+/* Guile extensions, not in R6RS.  */
+SCM_API SCM scm_unget_bytevector (SCM, SCM, SCM, SCM);
+SCM_API SCM scm_get_bytevector_some_x (SCM, SCM, SCM, SCM);
+
 #endif /* SCM_R6RS_PORTS_H */
index e0da3df1a6ff25ed8d130ea32507cba2ab2d6232..62fd9786f7b650213de37287b1b079a22dc154b8 100644 (file)
@@ -36,6 +36,7 @@
             get-bytevector-n
             get-bytevector-n!
             get-bytevector-some
+            get-bytevector-some!  ; Guile extension, not in R6RS
             get-bytevector-all
             get-string-n!
             put-u8