summaryrefslogtreecommitdiff
path: root/libguile
diff options
context:
space:
mode:
Diffstat (limited to 'libguile')
-rw-r--r--libguile/r6rs-ports.c50
-rw-r--r--libguile/r6rs-ports.h7
2 files changed, 50 insertions, 7 deletions
diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c
index 255ba6212..445ae5464 100644
--- a/libguile/r6rs-ports.c
+++ b/libguile/r6rs-ports.c
@@ -86,9 +86,8 @@ SCM_DEFINE (scm_eof_object, "eof-object", 0, 0, 0,
/* Input ports. */
-#ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
+#define MAX(A, B) ((A) >= (B) ? (A) : (B))
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
/* Bytevector input ports. */
static scm_t_port_type *bytevector_input_port_type = 0;
@@ -521,6 +520,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,
+ (uint8_t *) 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 "
@@ -732,8 +774,6 @@ bytevector_output_port_buffer_init (scm_t_bytevector_output_port_buffer *buf)
/* Don't clear the port. */
}
-#define MAX(A, B) ((A) >= (B) ? (A) : (B))
-
static inline void
bytevector_output_port_buffer_grow (scm_t_bytevector_output_port_buffer *buf,
size_t min_size)
diff --git a/libguile/r6rs-ports.h b/libguile/r6rs-ports.h
index 780acf063..56a535e8e 100644
--- a/libguile/r6rs-ports.h
+++ b/libguile/r6rs-ports.h
@@ -1,7 +1,7 @@
#ifndef SCM_R6RS_PORTS_H
#define SCM_R6RS_PORTS_H
-/* Copyright 2009-2011,2013,2018
+/* Copyright 2009-2011,2013,2018-2019
Free Software Foundation, Inc.
This file is part of Guile.
@@ -35,7 +35,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);
@@ -47,4 +46,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 */