diff options
author | Andy Wingo <wingo@pobox.com> | 2016-04-17 19:38:44 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2016-04-17 19:38:44 +0200 |
commit | b869344a4f238ad66ab33e08de5c7b66ed823fc3 (patch) | |
tree | fdf0c47f6413a63034aad0050a1720c6aafdcb4a /libguile | |
parent | f62974000f74c2e6e160b02137ab037466812014 (diff) | |
download | guile-b869344a4f238ad66ab33e08de5c7b66ed823fc3.tar.gz |
Remove size field from port buffers
* libguile/ports.h (scm_t_port_buffer): Remove size field. Instead use
bytevector size.
* libguile/ports-internal.h (scm_port_buffer_size)
(scm_port_buffer_reset)
(scm_port_buffer_can_take, scm_port_buffer_can_put)
(scm_port_buffer_did_take, scm_port_buffer_did_put)
(scm_port_buffer_take_pointer, scm_port_buffer_put_pointer)
(scm_port_buffer_take, scm_port_buffer_put): New helpers.
* libguile/filesys.c (set_element): Use new helpers.
* libguile/poll.c (scm_primitive_poll): Use new helpers.
* libguile/ports.c (scm_c_make_port_buffer): No more "size" field.
(scm_i_read_unlocked, scm_c_read_bytes_unlocked)
(scm_c_read_unlocked, scm_i_unget_bytes_unlocked)
(scm_unget_bytes, scm_setvbuf, scm_take_from_input_buffers)
(scm_drain_input, scm_end_input_unlocked, scm_flush_unlocked)
(scm_fill_input_unlocked, scm_i_write_unlocked)
(scm_c_write_bytes_unlocked, scm_c_write_unlocked)
(scm_char_ready_p): Use new helpers.
* libguile/r6rs-ports.c (scm_get_bytevector_some): Use new helpers.
* libguile/rw.c (scm_write_string_partial): Use new helpers.
Diffstat (limited to 'libguile')
-rw-r--r-- | libguile/filesys.c | 5 | ||||
-rw-r--r-- | libguile/poll.c | 11 | ||||
-rw-r--r-- | libguile/ports-internal.h | 71 | ||||
-rw-r--r-- | libguile/ports.c | 172 | ||||
-rw-r--r-- | libguile/ports.h | 3 | ||||
-rw-r--r-- | libguile/r6rs-ports.c | 4 | ||||
-rw-r--r-- | libguile/rw.c | 3 |
7 files changed, 157 insertions, 112 deletions
diff --git a/libguile/filesys.c b/libguile/filesys.c index 03a0b069c..5e0a2321c 100644 --- a/libguile/filesys.c +++ b/libguile/filesys.c @@ -47,6 +47,7 @@ #include "libguile/strings.h" #include "libguile/vectors.h" #include "libguile/dynwind.h" +#include "libguile/ports-internal.h" #include "libguile/validate.h" #include "libguile/filesys.h" @@ -652,7 +653,7 @@ set_element (fd_set *set, SCM *ports_ready, SCM element, int pos) /* check whether port has buffered input. */ scm_t_port *pt = SCM_PTAB_ENTRY (element); - if (pt->read_buf->cur < pt->read_buf->end) + if (scm_port_buffer_can_take (pt->read_buf) > 0) use_buf = 1; } else if (pos == SCM_ARG2) @@ -661,7 +662,7 @@ set_element (fd_set *set, SCM *ports_ready, SCM element, int pos) scm_t_port *pt = SCM_PTAB_ENTRY (element); /* > 1 since writing the last byte in the buffer causes flush. */ - if (pt->write_buf->size - pt->write_buf->end > 1) + if (scm_port_buffer_can_put (pt->write_buf) > 1) use_buf = 1; } fd = use_buf ? -1 : SCM_FPORT_FDES (element); diff --git a/libguile/poll.c b/libguile/poll.c index 1e8fa7a3b..9557339c2 100644 --- a/libguile/poll.c +++ b/libguile/poll.c @@ -29,8 +29,9 @@ #include "libguile/_scm.h" #include "libguile/bytevectors.h" -#include "libguile/numbers.h" #include "libguile/error.h" +#include "libguile/numbers.h" +#include "libguile/ports-internal.h" #include "libguile/validate.h" #include "libguile/poll.h" @@ -108,11 +109,11 @@ scm_primitive_poll (SCM pollfds, SCM nfds, SCM ports, SCM timeout) { scm_t_port *pt = SCM_PTAB_ENTRY (port); - if (pt->read_buf->cur < pt->read_buf->end) + if (scm_port_buffer_can_take (pt->read_buf) > 0) /* Buffered input waiting to be read. */ revents |= POLLIN; if (SCM_OUTPUT_PORT_P (port) - && pt->write_buf->size - pt->write_buf->end > 1) + && scm_port_buffer_can_put (pt->write_buf) > 1) /* Buffered output possible. The "> 1" is because writing the last byte would flush the port. */ revents |= POLLOUT; @@ -146,11 +147,11 @@ scm_primitive_poll (SCM pollfds, SCM nfds, SCM ports, SCM timeout) { scm_t_port *pt = SCM_PTAB_ENTRY (port); - if (pt->read_buf->cur < pt->read_buf->end) + if (scm_port_buffer_can_take (pt->read_buf) > 0) /* Buffered input waiting to be read. */ revents |= POLLIN; if (SCM_OUTPUT_PORT_P (port) - && pt->write_buf->size - pt->write_buf->end > 1) + && scm_port_buffer_can_put (pt->write_buf) > 1) /* Buffered output possible. The "> 1" is because writing the last byte would flush the port. */ revents |= POLLOUT; diff --git a/libguile/ports-internal.h b/libguile/ports-internal.h index 1a94bd5b2..b3f15e187 100644 --- a/libguile/ports-internal.h +++ b/libguile/ports-internal.h @@ -25,6 +25,77 @@ #include "libguile/_scm.h" #include "libguile/ports.h" +static inline size_t +scm_port_buffer_size (scm_t_port_buffer *buf) +{ + return scm_c_bytevector_length (buf->bytevector); +} + +static inline void +scm_port_buffer_reset (scm_t_port_buffer *buf) +{ + buf->cur = buf->end = 0; +} + +static inline size_t +scm_port_buffer_can_take (scm_t_port_buffer *buf) +{ + return buf->end - buf->cur; +} + +static inline size_t +scm_port_buffer_can_put (scm_t_port_buffer *buf) +{ + return scm_port_buffer_size (buf) - buf->end; +} + +static inline void +scm_port_buffer_did_take (scm_t_port_buffer *buf, size_t count) +{ + buf->cur += count; +} + +static inline void +scm_port_buffer_did_put (scm_t_port_buffer *buf, size_t count) +{ + buf->end += count; +} + +static inline const scm_t_uint8 * +scm_port_buffer_take_pointer (scm_t_port_buffer *buf) +{ + signed char *ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector); + return ((scm_t_uint8 *) ret) + buf->cur; +} + +static inline scm_t_uint8 * +scm_port_buffer_put_pointer (scm_t_port_buffer *buf) +{ + signed char *ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector); + return ((scm_t_uint8 *) ret) + buf->end; +} + +static inline size_t +scm_port_buffer_take (scm_t_port_buffer *buf, scm_t_uint8 *dst, size_t count) +{ + count = min (count, scm_port_buffer_can_take (buf)); + if (dst) + memcpy (dst, scm_port_buffer_take_pointer (buf), count); + scm_port_buffer_did_take (buf, count); + return count; +} + +static inline size_t +scm_port_buffer_put (scm_t_port_buffer *buf, const scm_t_uint8 *src, + size_t count) +{ + count = min (count, scm_port_buffer_can_put (buf)); + if (src) + memcpy (scm_port_buffer_put_pointer (buf), src, count); + scm_port_buffer_did_put (buf, count); + return count; +} + enum scm_port_encoding_mode { SCM_PORT_ENCODING_MODE_UTF8, SCM_PORT_ENCODING_MODE_LATIN1, diff --git a/libguile/ports.c b/libguile/ports.c index 39551bc06..2351438df 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -517,7 +517,6 @@ scm_c_make_port_buffer (size_t size) { scm_t_port_buffer *ret = scm_gc_typed_calloc (scm_t_port_buffer); - ret->size = size; ret->bytevector = scm_c_make_bytevector (size); ret->buf = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (ret->bytevector); ret->has_eof_p = SCM_BOOL_F; @@ -1415,11 +1414,9 @@ scm_i_read_unlocked (SCM port, scm_t_port_buffer *buf) { size_t count; - assert (buf->end < buf->size); - count = scm_i_read_bytes_unlocked (port, buf->bytevector, buf->end, - buf->size - buf->end); - buf->end += count; + scm_port_buffer_can_put (buf)); + scm_port_buffer_did_put (buf, count); buf->has_eof_p = scm_from_bool (count == 0); } @@ -1435,7 +1432,7 @@ scm_c_read_bytes_unlocked (SCM port, SCM dst, size_t start, size_t count) size_t to_read = count; scm_t_port *pt; scm_t_port_buffer *read_buf; - signed char *dst_ptr = SCM_BYTEVECTOR_CONTENTS (dst) + start; + scm_t_uint8 *dst_ptr = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (dst) + start; SCM_VALIDATE_OPINPORT (1, port); @@ -1450,48 +1447,41 @@ scm_c_read_bytes_unlocked (SCM port, SCM dst, size_t start, size_t count) } /* Take bytes first from the port's read buffer. */ - if (read_buf->cur < read_buf->end) - { - size_t to_copy = count; - to_copy = min (to_copy, read_buf->end - read_buf->cur); - memcpy (dst_ptr, read_buf->buf + read_buf->cur, to_copy); - dst_ptr += to_copy; - to_read -= to_copy; - read_buf->cur += to_copy; - } + { + size_t did_read = scm_port_buffer_take (read_buf, dst_ptr, to_read); + dst_ptr += did_read; + to_read -= did_read; + } while (to_read) { + size_t did_read; + /* If the read is smaller than the buffering on the read side of this port, then go through the buffer. Otherwise fill our buffer directly. */ if (to_read < pt->read_buffering) { - size_t to_copy = to_read; read_buf = scm_fill_input_unlocked (port); - to_copy = min (to_copy, read_buf->end - read_buf->cur); - memcpy (dst_ptr, read_buf->buf + read_buf->cur, to_copy); - if (to_copy == 0) + did_read = scm_port_buffer_take (read_buf, dst_ptr, to_read); + dst_ptr += did_read; + to_read -= did_read; + if (did_read == 0) { /* Consider that we've read off this EOF. */ read_buf->has_eof_p = SCM_BOOL_F; break; } - dst_ptr += to_copy; - to_read -= to_copy; - read_buf->cur += to_copy; } else { - size_t filled; - - filled = scm_i_read_bytes_unlocked (port, dst, - start + count - to_read, - to_read); - if (filled == 0) + did_read = scm_i_read_bytes_unlocked (port, dst, + start + count - to_read, + to_read); + to_read -= did_read; + dst_ptr += did_read; + if (did_read == 0) break; - to_read -= filled; - dst_ptr += filled; } } @@ -1525,17 +1515,11 @@ scm_c_read_unlocked (SCM port, void *buffer, size_t size) while (copied < size) { + size_t count; read_buf = scm_fill_input_unlocked (port); - /* Take bytes first from the port's read buffer. */ - if (read_buf->cur < read_buf->end) - { - size_t to_copy = size - copied; - to_copy = min (to_copy, read_buf->end - read_buf->cur); - memcpy (dst + copied, read_buf->buf + read_buf->cur, to_copy); - copied += to_copy; - read_buf->cur += to_copy; - } - else + count = scm_port_buffer_take (read_buf, dst + copied, size - copied); + copied += count; + if (count == 0) { /* Consider that we've read off this EOF. */ read_buf->has_eof_p = SCM_BOOL_F; @@ -2005,31 +1989,31 @@ scm_i_unget_bytes_unlocked (const scm_t_uint8 *buf, size_t len, SCM port) if (read_buf->cur < len) { /* The bytes don't fit directly in the read_buf. */ - if (len <= read_buf->cur + (read_buf->size - read_buf->end)) + size_t buffered, size; + + buffered = scm_port_buffer_can_take (read_buf); + size = scm_port_buffer_size (read_buf); + + if (len <= size - buffered) { /* But they would fit if we shift the not-yet-read bytes from the read_buf right. Let's do that. */ - size_t to_move = read_buf->end - read_buf->cur; - - if (to_move > 0) - memmove (read_buf->buf + (read_buf->size - to_move), - read_buf->buf + read_buf->cur, - to_move); - read_buf->end = read_buf->size; - read_buf->cur = read_buf->end - to_move; + memmove (read_buf->buf + (size - buffered), + scm_port_buffer_take_pointer (read_buf), + buffered); + read_buf->end = size; + read_buf->cur = read_buf->end - buffered; } else { /* Bah, have to expand the read_buf for the putback. */ scm_t_port_buffer *new_buf; - size_t buffered = read_buf->end - read_buf->cur; - size_t size = read_buf->size; while (size < len + buffered) size *= 2; new_buf = scm_c_make_port_buffer (size); - new_buf->end = new_buf->size; + new_buf->end = size; new_buf->cur = new_buf->end - buffered; new_buf->has_eof_p = read_buf->has_eof_p; memcpy (new_buf->buf + new_buf->cur, read_buf->buf + read_buf->cur, @@ -2061,6 +2045,8 @@ void scm_unget_bytes (const unsigned char *buf, size_t len, SCM port) { scm_i_pthread_mutex_t *lock; + if (len == 0) + return; scm_c_lock_port (port, &lock); scm_i_unget_bytes_unlocked (buf, len, port); if (lock) @@ -2359,9 +2345,9 @@ SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0, pt->read_buf = scm_c_make_port_buffer (read_buf_size); pt->write_buf = scm_c_make_port_buffer (write_buf_size); - if (saved_read_buf && saved_read_buf->cur < saved_read_buf->end) - scm_unget_bytes (saved_read_buf->buf + saved_read_buf->cur, - saved_read_buf->end - saved_read_buf->cur, + if (saved_read_buf) + scm_unget_bytes (scm_port_buffer_take_pointer (saved_read_buf), + scm_port_buffer_can_take (saved_read_buf), port); if (saved_read_buf) @@ -2391,13 +2377,8 @@ scm_fill_input (SCM port) size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len) { - scm_t_port *pt = SCM_PTAB_ENTRY (port); - scm_t_port_buffer *read_buf = pt->read_buf; - size_t count = min (read_buf->end - read_buf->cur, read_len); - - memcpy (dest, read_buf->buf + read_buf->cur, count); - read_buf->cur += count; - return count; + scm_t_port_buffer *read_buf = SCM_PTAB_ENTRY (port)->read_buf; + return scm_port_buffer_take (read_buf, (scm_t_uint8 *) dest, read_len); } /* Clear a port's read buffers, returning the contents. */ @@ -2426,14 +2407,13 @@ SCM_DEFINE (scm_drain_input, "drain-input", 1, 0, 0, SCM_VALIDATE_OPINPORT (1, port); pt = SCM_PTAB_ENTRY (port); read_buf = pt->read_buf; - - count = read_buf->end - read_buf->cur; + count = scm_port_buffer_can_take (read_buf); if (count) { - scm_t_uint8 *ptr = read_buf->buf + read_buf->cur; - result = scm_from_port_stringn ((char *) ptr, count, port); - read_buf->cur = read_buf->end; + const scm_t_uint8 *ptr = scm_port_buffer_take_pointer (read_buf); + result = scm_from_port_stringn ((const char *) ptr, count, port); + scm_port_buffer_did_take (read_buf, count); } else result = scm_nullstr; @@ -2447,17 +2427,16 @@ scm_end_input_unlocked (SCM port) { scm_t_port *pt; scm_t_port_buffer *buf; - scm_t_off offset; + size_t discarded; pt = SCM_PTAB_ENTRY (port); buf = SCM_PTAB_ENTRY (port)->read_buf; - offset = buf->cur - buf->end; + discarded = scm_port_buffer_take (buf, NULL, (size_t) -1); assert (pt->rw_random); - buf->end = buf->cur = 0; - if (offset != 0) - SCM_PORT_DESCRIPTOR (port)->seek (port, offset, SEEK_CUR); + if (discarded != 0) + SCM_PORT_DESCRIPTOR (port)->seek (port, -discarded, SEEK_CUR); pt->rw_active = SCM_PORT_NEITHER; } @@ -2499,7 +2478,7 @@ void scm_flush_unlocked (SCM port) { scm_t_port_buffer *buf = SCM_PTAB_ENTRY (port)->write_buf; - if (buf->cur < buf->end) + if (scm_port_buffer_can_take (buf)) scm_i_write_unlocked (port, buf); SCM_PTAB_ENTRY (port)->rw_active = SCM_PORT_NEITHER; } @@ -2520,7 +2499,7 @@ scm_fill_input_unlocked (SCM port) scm_t_port *pt = SCM_PTAB_ENTRY (port); scm_t_port_buffer *read_buf = pt->read_buf; - if (read_buf->cur < read_buf->end || scm_is_true (read_buf->has_eof_p)) + if (scm_port_buffer_can_take (read_buf) || scm_is_true (read_buf->has_eof_p)) return read_buf; if (pt->rw_random) @@ -2532,10 +2511,10 @@ scm_fill_input_unlocked (SCM port) /* It could be that putback caused us to enlarge the buffer; now that we've read all the bytes we need to shrink it again. */ - if (read_buf->size != pt->read_buffering) + if (scm_port_buffer_size (read_buf) != pt->read_buffering) read_buf = pt->read_buf = scm_c_make_port_buffer (pt->read_buffering); else - read_buf->cur = read_buf->end = 0; + scm_port_buffer_reset (read_buf); scm_i_read_unlocked (port, read_buf); @@ -2589,7 +2568,7 @@ scm_i_write_unlocked (SCM port, scm_t_port_buffer *src) size_t start, count; assert (src->cur < src->end); - assert (src->end <= src->size); + assert (src->end <= scm_port_buffer_size (src)); /* Update cursors before attempting to write, assuming that I/O errors are sticky. That way if the write throws an error, causing the @@ -2599,7 +2578,7 @@ scm_i_write_unlocked (SCM port, scm_t_port_buffer *src) start = src->cur; count = src->end - src->cur; - src->cur = src->end = 0; + scm_port_buffer_reset (src); scm_i_write_bytes_unlocked (port, src->bytevector, start, count); } @@ -2627,34 +2606,34 @@ scm_c_write_bytes_unlocked (SCM port, SCM src, size_t start, size_t count) pt->rw_active = SCM_PORT_WRITE; } - if (count < write_buf->size) + if (count < scm_port_buffer_size (write_buf)) { /* Make it so that write_buf->end is only nonzero if there are buffered bytes already. */ - if (write_buf->cur == write_buf->end) - write_buf->cur = write_buf->end = 0; + if (scm_port_buffer_can_take (write_buf) == 0) + scm_port_buffer_reset (write_buf); /* We buffer writes that are smaller in size than the write buffer. If the buffer is too full to hold the new data, we flush it beforehand. Otherwise it could be that the buffer is full after filling it with the new data; if that's the case, we flush then instead. */ - if (write_buf->end + count > write_buf->size) + if (scm_port_buffer_can_put (write_buf) < count) scm_i_write_unlocked (port, write_buf); - memcpy (write_buf->buf + write_buf->end, - SCM_BYTEVECTOR_CONTENTS (src) + start, - count); - write_buf->end += count; + { + signed char *src_ptr = SCM_BYTEVECTOR_CONTENTS (src) + start; + scm_port_buffer_put (write_buf, (scm_t_uint8 *) src_ptr, count); + } - if (write_buf->end == write_buf->size) + if (scm_port_buffer_can_put (write_buf) == 0) scm_i_write_unlocked (port, write_buf); } else { /* Our write would overflow the buffer. Flush buffered bytes (if needed), then write our bytes with just one syscall. */ - if (write_buf->cur < write_buf->end) + if (scm_port_buffer_can_take (write_buf)) scm_i_write_unlocked (port, write_buf); scm_i_write_bytes_unlocked (port, src, start, count); @@ -2690,17 +2669,10 @@ scm_c_write_unlocked (SCM port, const void *ptr, size_t size) while (written < size) { - size_t to_write = write_buf->size - write_buf->end; - - if (to_write > size - written) - to_write = size - written; - - memcpy (write_buf->buf + write_buf->end, src, to_write); - write_buf->end += to_write; - written += to_write; - src += to_write; - - if (write_buf->end == write_buf->size) + size_t did_put = scm_port_buffer_put (write_buf, src, size - written); + written += did_put; + src += did_put; + if (scm_port_buffer_can_put (write_buf) == 0) scm_i_write_unlocked (port, write_buf); } } @@ -2801,7 +2773,7 @@ SCM_DEFINE (scm_char_ready_p, "char-ready?", 0, 1, 0, pt = SCM_PTAB_ENTRY (port); read_buf = pt->read_buf; - if (read_buf->cur < read_buf->end || scm_is_true (read_buf->has_eof_p)) + if (scm_port_buffer_can_take (read_buf) || scm_is_true (read_buf->has_eof_p)) /* FIXME: Verify that a whole character is available? */ return SCM_BOOL_T; else diff --git a/libguile/ports.h b/libguile/ports.h index 3c48bb754..9e28e4837 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -76,10 +76,9 @@ typedef struct /* Start of the buffer. Never changed. */ scm_t_uint8 *buf; - /* Offsets into the buffer. Invariant: cur <= end <= size. */ + /* Offsets into the buffer. Invariant: cur <= end <= size(buf). */ size_t cur; size_t end; - size_t size; /* For read buffers, flag indicating whether the last read() returned zero bytes. Note that in the case of pushback, there could still diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c index c1cf95af3..4c5c87ca5 100644 --- a/libguile/r6rs-ports.c +++ b/libguile/r6rs-ports.c @@ -475,13 +475,13 @@ SCM_DEFINE (scm_get_bytevector_some, "get-bytevector-some", 1, 0, 0, SCM_VALIDATE_BINARY_INPUT_PORT (1, port); buf = scm_fill_input_unlocked (port); - if (buf->cur == buf->end) + size = scm_port_buffer_can_take (buf); + if (size == 0) { buf->has_eof_p = SCM_BOOL_F; return SCM_EOF_VAL; } - size = buf->end - buf->cur; bv = scm_c_make_bytevector (size); scm_take_from_input_buffers (port, (char *) SCM_BYTEVECTOR_CONTENTS (bv), size); diff --git a/libguile/rw.c b/libguile/rw.c index 9bd23208a..76467a90e 100644 --- a/libguile/rw.c +++ b/libguile/rw.c @@ -36,6 +36,7 @@ #include "libguile/validate.h" #include "libguile/modules.h" #include "libguile/strports.h" +#include "libguile/ports-internal.h" #include <unistd.h> #ifdef HAVE_IO_H @@ -239,7 +240,7 @@ SCM_DEFINE (scm_write_string_partial, "write-string/partial", 1, 3, 0, /* Filling the last character in the buffer would require a flush. */ - if (write_len < write_buf->size - write_buf->end) + if (write_len < scm_port_buffer_size (write_buf) - write_buf->end) { scm_c_write_unlocked (port, src, write_len); return scm_from_long (write_len); |