summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2016-04-03 21:54:37 +0200
committerAndy Wingo <wingo@pobox.com>2016-04-04 16:30:56 +0200
commitb538a96f927d5a0079655bd6df8f019c008930ee (patch)
tree5d6e4d5b9aebea44c2a6a7e04e21f0aba6ab19e9
parent693359cb3de8918e4f5151426c34104429d8fc3e (diff)
downloadguile-b538a96f927d5a0079655bd6df8f019c008930ee.tar.gz
Custom binary port internals refactor
* libguile/r6rs-ports.c (struct custom_binary_port): Use a struct instead of a vector as the state for a custom binary port. Adapt all callers. Some whitespace fixes as well.
-rw-r--r--libguile/r6rs-ports.c142
1 files changed, 70 insertions, 72 deletions
diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c
index 6d0e3ec00..12e0cc7db 100644
--- a/libguile/r6rs-ports.c
+++ b/libguile/r6rs-ports.c
@@ -38,6 +38,7 @@
+
/* Unimplemented features. */
@@ -51,7 +52,9 @@ transcoders_not_implemented (void)
PACKAGE_NAME);
}
+
+
/* End-of-file object. */
SCM_DEFINE (scm_eof_object, "eof-object", 0, 0, 0,
@@ -63,7 +66,9 @@ SCM_DEFINE (scm_eof_object, "eof-object", 0, 0, 0,
}
#undef FUNC_NAME
+
+
/* Input ports. */
#ifndef MIN
@@ -186,33 +191,35 @@ SCM_DEFINE (scm_open_bytevector_input_port,
}
#undef FUNC_NAME
+
+
/* Custom binary ports. The following routines are shared by input and
output custom binary ports. */
-#define SCM_CUSTOM_BINARY_PORT_GET_POSITION_PROC(_port) \
- SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 1)
-#define SCM_CUSTOM_BINARY_PORT_SET_POSITION_PROC(_port) \
- SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 2)
-#define SCM_CUSTOM_BINARY_PORT_CLOSE_PROC(_port) \
- SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 3)
+struct custom_binary_port {
+ SCM read_buffer;
+ SCM read;
+ SCM write;
+ SCM get_position;
+ SCM set_position_x;
+ SCM close;
+};
static scm_t_off
custom_binary_port_seek (SCM port, scm_t_off offset, int whence)
#define FUNC_NAME "custom_binary_port_seek"
{
SCM result;
+ struct custom_binary_port *stream = (void *) SCM_STREAM (port);
scm_t_off c_result = 0;
switch (whence)
{
case SEEK_CUR:
{
- SCM get_position_proc;
-
- get_position_proc = SCM_CUSTOM_BINARY_PORT_GET_POSITION_PROC (port);
- if (SCM_LIKELY (scm_is_true (get_position_proc)))
- result = scm_call_0 (get_position_proc);
+ if (SCM_LIKELY (scm_is_true (stream->get_position)))
+ result = scm_call_0 (stream->get_position);
else
scm_wrong_type_arg_msg (FUNC_NAME, 0, port,
"R6RS custom binary port with "
@@ -228,11 +235,8 @@ custom_binary_port_seek (SCM port, scm_t_off offset, int whence)
case SEEK_SET:
{
- SCM set_position_proc;
-
- set_position_proc = SCM_CUSTOM_BINARY_PORT_SET_POSITION_PROC (port);
- if (SCM_LIKELY (scm_is_true (set_position_proc)))
- result = scm_call_1 (set_position_proc, scm_from_int (offset));
+ if (SCM_LIKELY (scm_is_true (stream->set_position_x)))
+ result = scm_call_1 (stream->set_position_x, scm_from_int (offset));
else
scm_wrong_type_arg_msg (FUNC_NAME, 0, port,
"seekable R6RS custom binary port");
@@ -256,36 +260,25 @@ custom_binary_port_seek (SCM port, scm_t_off offset, int whence)
static int
custom_binary_port_close (SCM port)
{
- SCM close_proc;
+ struct custom_binary_port *stream = (void *) SCM_STREAM (port);
- close_proc = SCM_CUSTOM_BINARY_PORT_CLOSE_PROC (port);
- if (scm_is_true (close_proc))
+ if (scm_is_true (stream->close))
/* Invoke the `close' thunk. */
- scm_call_0 (close_proc);
+ scm_call_0 (stream->close);
return 1;
}
+
-/* Custom binary input port. */
+
+/* Custom binary input ports. */
static scm_t_bits custom_binary_input_port_type = 0;
/* Initial size of the buffer embedded in custom binary input ports. */
#define CUSTOM_BINARY_INPUT_PORT_BUFFER_SIZE 8192
-/* Return the bytevector associated with PORT. */
-#define SCM_CUSTOM_BINARY_INPUT_PORT_BYTEVECTOR(_port) \
- SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 4)
-
-/* Set BV as the bytevector associated with PORT. */
-#define SCM_SET_CUSTOM_BINARY_INPUT_PORT_BYTEVECTOR(_port, _bv) \
- SCM_SIMPLE_VECTOR_SET (SCM_PACK (SCM_STREAM (_port)), 4, (_bv))
-
-/* Return the various procedures of PORT. */
-#define SCM_CUSTOM_BINARY_INPUT_PORT_READ_PROC(_port) \
- SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 0)
-
/* Set PORT's internal buffer according to READ_SIZE. */
static void
@@ -293,9 +286,10 @@ custom_binary_input_port_setvbuf (SCM port, long read_size, long write_size)
{
SCM bv;
scm_t_port *pt;
+ struct custom_binary_port *stream = (void *) SCM_STREAM (port);
pt = SCM_PTAB_ENTRY (port);
- bv = SCM_CUSTOM_BINARY_INPUT_PORT_BYTEVECTOR (port);
+ bv = stream->read_buffer;
switch (read_size)
{
@@ -317,7 +311,7 @@ custom_binary_input_port_setvbuf (SCM port, long read_size, long write_size)
default:
/* Fully buffered: allocate a buffer of READ_SIZE bytes. */
bv = scm_c_make_bytevector (read_size);
- SCM_SET_CUSTOM_BINARY_INPUT_PORT_BYTEVECTOR (port, bv);
+ stream->read_buffer = bv;
pt->read_buf = (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv);
pt->read_buf_size = read_size;
}
@@ -329,10 +323,11 @@ static inline SCM
make_custom_binary_input_port (SCM read_proc, SCM get_position_proc,
SCM set_position_proc, SCM close_proc)
{
- SCM port, bv, method_vector;
+ SCM port, bv;
char *c_bv;
unsigned c_len;
scm_t_port *c_port;
+ struct custom_binary_port *stream;
const unsigned long mode_bits = SCM_OPN | SCM_RDNG;
/* Use a bytevector as the underlying buffer. */
@@ -340,19 +335,19 @@ make_custom_binary_input_port (SCM read_proc, SCM get_position_proc,
bv = scm_c_make_bytevector (c_len);
c_bv = (char *) SCM_BYTEVECTOR_CONTENTS (bv);
- /* Store the various methods and bytevector in a vector. */
- method_vector = scm_c_make_vector (5, SCM_BOOL_F);
- SCM_SIMPLE_VECTOR_SET (method_vector, 4, bv);
- SCM_SIMPLE_VECTOR_SET (method_vector, 0, read_proc);
- SCM_SIMPLE_VECTOR_SET (method_vector, 1, get_position_proc);
- SCM_SIMPLE_VECTOR_SET (method_vector, 2, set_position_proc);
- SCM_SIMPLE_VECTOR_SET (method_vector, 3, close_proc);
+ stream = scm_gc_typed_calloc (struct custom_binary_port);
+ stream->read_buffer = bv;
+ stream->read = read_proc;
+ stream->write = SCM_BOOL_F;
+ stream->get_position = get_position_proc;
+ stream->set_position_x = set_position_proc;
+ stream->close = close_proc;
port = scm_c_make_port_with_encoding (custom_binary_input_port_type,
mode_bits,
NULL, /* encoding */
SCM_FAILED_CONVERSION_ERROR,
- SCM_UNPACK (method_vector));
+ (scm_t_bits) stream);
c_port = SCM_PTAB_ENTRY (port);
@@ -370,18 +365,18 @@ custom_binary_input_port_fill_input (SCM port)
{
int result;
scm_t_port *c_port = SCM_PTAB_ENTRY (port);
+ struct custom_binary_port *stream = (void *) SCM_STREAM (port);
if (c_port->read_pos >= c_port->read_end)
{
/* Invoke the user's `read!' procedure. */
int buffered;
size_t c_octets, c_requested;
- SCM bv, read_proc, octets;
+ SCM bv, octets;
c_requested = c_port->read_buf_size;
- read_proc = SCM_CUSTOM_BINARY_INPUT_PORT_READ_PROC (port);
- bv = SCM_CUSTOM_BINARY_INPUT_PORT_BYTEVECTOR (port);
+ bv = stream->read_buffer;
buffered =
(c_port->read_buf == (unsigned char *) SCM_BYTEVECTOR_CONTENTS (bv));
@@ -401,16 +396,13 @@ custom_binary_input_port_fill_input (SCM port)
are passed the caller-provided buffer, so we need to check its
size. */
if (SCM_BYTEVECTOR_LENGTH (bv) < c_requested)
- {
- /* Bad luck: we have to make another allocation. Save that
- bytevector for later reuse, in the hope that the application
- has regular access patterns. */
- bv = scm_c_make_bytevector (c_requested);
- SCM_SET_CUSTOM_BINARY_INPUT_PORT_BYTEVECTOR (port, bv);
- }
+ /* Bad luck: we have to make another allocation. Save that
+ nbytevector for later reuse, in the hope that the application
+ has regular access patterns. */
+ stream->read_buffer = bv = scm_c_make_bytevector (c_requested);
}
- octets = scm_call_3 (read_proc, bv, SCM_INUM0,
+ octets = scm_call_3 (stream->read, bv, SCM_INUM0,
scm_from_size_t (c_requested));
c_octets = scm_to_size_t (octets);
if (SCM_UNLIKELY (c_octets > c_requested))
@@ -479,6 +471,7 @@ initialize_custom_binary_input_ports (void)
+
/* Binary input. */
/* We currently don't support specific binary input ports. */
@@ -603,7 +596,6 @@ SCM_DEFINE (scm_get_bytevector_n_x, "get-bytevector-n!", 4, 0, 0,
}
#undef FUNC_NAME
-
SCM_DEFINE (scm_get_bytevector_some, "get-bytevector-some", 1, 0, 0,
(SCM port),
"Read from @var{port}, blocking as necessary, until bytes "
@@ -706,6 +698,7 @@ SCM_DEFINE (scm_get_bytevector_all, "get-bytevector-all", 1, 0, 0,
+
/* Binary output. */
/* We currently don't support specific binary input ports. */
@@ -816,6 +809,7 @@ SCM_DEFINE (scm_unget_bytevector, "unget-bytevector", 2, 2, 0,
+
/* Bytevector output port. */
/* Implementation of "bytevector output ports".
@@ -1022,36 +1016,38 @@ initialize_bytevector_output_ports (void)
scm_set_port_seek (bytevector_output_port_type, bytevector_output_port_seek);
}
+
-/* Custom binary output port. */
-static scm_t_bits custom_binary_output_port_type;
+/* Custom binary output ports. */
-/* Return the various procedures of PORT. */
-#define SCM_CUSTOM_BINARY_OUTPUT_PORT_WRITE_PROC(_port) \
- SCM_SIMPLE_VECTOR_REF (SCM_PACK (SCM_STREAM (_port)), 0)
+static scm_t_bits custom_binary_output_port_type;
static inline SCM
make_custom_binary_output_port (SCM write_proc, SCM get_position_proc,
SCM set_position_proc, SCM close_proc)
{
- SCM port, method_vector;
+ SCM port;
scm_t_port *c_port;
+ struct custom_binary_port *stream;
const unsigned long mode_bits = SCM_OPN | SCM_WRTNG;
/* Store the various methods and bytevector in a vector. */
- method_vector = scm_c_make_vector (4, SCM_BOOL_F);
- SCM_SIMPLE_VECTOR_SET (method_vector, 0, write_proc);
- SCM_SIMPLE_VECTOR_SET (method_vector, 1, get_position_proc);
- SCM_SIMPLE_VECTOR_SET (method_vector, 2, set_position_proc);
- SCM_SIMPLE_VECTOR_SET (method_vector, 3, close_proc);
+ stream = scm_gc_typed_calloc (struct custom_binary_port);
+
+ stream->read_buffer = SCM_BOOL_F;
+ stream->read = SCM_BOOL_F;
+ stream->write = write_proc;
+ stream->get_position = get_position_proc;
+ stream->set_position_x = set_position_proc;
+ stream->close = close_proc;
port = scm_c_make_port_with_encoding (custom_binary_output_port_type,
mode_bits,
NULL, /* encoding */
SCM_FAILED_CONVERSION_ERROR,
- SCM_UNPACK (method_vector));
+ (scm_t_bits) stream);
c_port = SCM_PTAB_ENTRY (port);
@@ -1069,7 +1065,8 @@ custom_binary_output_port_write (SCM port, const void *data, size_t size)
{
long int c_result;
size_t c_written;
- SCM bv, write_proc, result;
+ struct custom_binary_port *stream = (void *) SCM_STREAM (port);
+ SCM bv, result;
/* XXX: Allocating a new bytevector at each `write' call is inefficient,
but necessary since (1) we don't control the lifetime of the buffer
@@ -1078,8 +1075,6 @@ custom_binary_output_port_write (SCM port, const void *data, size_t size)
bv = scm_c_make_bytevector (size);
memcpy (SCM_BYTEVECTOR_CONTENTS (bv), data, size);
- write_proc = SCM_CUSTOM_BINARY_OUTPUT_PORT_WRITE_PROC (port);
-
/* Since the `write' procedure of Guile's ports has type `void', it must
try hard to write exactly SIZE bytes, regardless of how many bytes the
sink can handle. */
@@ -1087,7 +1082,7 @@ custom_binary_output_port_write (SCM port, const void *data, size_t size)
c_written < size;
c_written += c_result)
{
- result = scm_call_3 (write_proc, bv,
+ result = scm_call_3 (stream->write, bv,
scm_from_size_t (c_written),
scm_from_size_t (size - c_written));
@@ -1141,8 +1136,11 @@ initialize_custom_binary_output_ports (void)
scm_set_port_close (custom_binary_output_port_type, custom_binary_port_close);
}
+
+
/* Transcoded ports. */
+
static scm_t_bits transcoded_port_type = 0;
#define TRANSCODED_PORT_INPUT_BUFFER_SIZE 4096