From 10dc6d043e0b76f36461f0a04160a4d2f411413e Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 18 Apr 2016 00:19:24 +0200 Subject: [PATCH] Remove "buf" field from port buffers * libguile/ports-internal.h (scm_port_buffer_reset_end): New helper. (scm_port_buffer_putback): New helper. * libguile/ports.h (scm_t_port_buffer): Remove "buf" field. (scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt. * libguile/ports.c (scm_c_make_port_buffer): No more "buf" field. (scm_i_unget_bytes_unlocked): Use helper. * libguile/read.c (scm_i_scan_for_encoding): No more "buf" field. --- libguile/ports-internal.h | 20 ++++++++++++++++++++ libguile/ports.c | 21 ++++++++------------- libguile/ports.h | 22 ++++++++++++---------- libguile/read.c | 2 +- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/libguile/ports-internal.h b/libguile/ports-internal.h index b3f15e187..14d00c2a6 100644 --- a/libguile/ports-internal.h +++ b/libguile/ports-internal.h @@ -22,6 +22,8 @@ #ifndef SCM_PORTS_INTERNAL #define SCM_PORTS_INTERNAL +#include + #include "libguile/_scm.h" #include "libguile/ports.h" @@ -37,6 +39,12 @@ scm_port_buffer_reset (scm_t_port_buffer *buf) buf->cur = buf->end = 0; } +static inline void +scm_port_buffer_reset_end (scm_t_port_buffer *buf) +{ + buf->cur = buf->end = scm_port_buffer_size (buf); +} + static inline size_t scm_port_buffer_can_take (scm_t_port_buffer *buf) { @@ -96,6 +104,18 @@ scm_port_buffer_put (scm_t_port_buffer *buf, const scm_t_uint8 *src, return count; } +static inline void +scm_port_buffer_putback (scm_t_port_buffer *buf, const scm_t_uint8 *src, + size_t count) +{ + assert (count <= buf->cur); + + /* Sometimes used to move around data within a buffer, so we must use + memmove. */ + buf->cur -= count; + memmove (SCM_BYTEVECTOR_CONTENTS (buf->bytevector) + buf->cur, src, 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 2351438df..a433e28fb 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -518,7 +518,6 @@ scm_c_make_port_buffer (size_t size) scm_t_port_buffer *ret = scm_gc_typed_calloc (scm_t_port_buffer); ret->bytevector = scm_c_make_bytevector (size); - ret->buf = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (ret->bytevector); ret->has_eof_p = SCM_BOOL_F; return ret; @@ -1998,11 +1997,9 @@ scm_i_unget_bytes_unlocked (const scm_t_uint8 *buf, size_t len, SCM port) { /* But they would fit if we shift the not-yet-read bytes from the read_buf right. Let's do that. */ - 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; + const scm_t_uint8 *to_shift = scm_port_buffer_take_pointer (read_buf); + scm_port_buffer_reset_end (read_buf); + scm_port_buffer_putback (read_buf, to_shift, buffered); } else { @@ -2013,18 +2010,16 @@ scm_i_unget_bytes_unlocked (const scm_t_uint8 *buf, size_t len, SCM port) size *= 2; new_buf = scm_c_make_port_buffer (size); - new_buf->end = size; - new_buf->cur = new_buf->end - buffered; + scm_port_buffer_reset_end (new_buf); new_buf->has_eof_p = read_buf->has_eof_p; - memcpy (new_buf->buf + new_buf->cur, read_buf->buf + read_buf->cur, - buffered); - + scm_port_buffer_putback (new_buf, + scm_port_buffer_take_pointer (read_buf), + buffered); pt->read_buf = read_buf = new_buf; } } - read_buf->cur -= len; - memcpy (read_buf->buf + read_buf->cur, buf, len); + scm_port_buffer_putback (read_buf, buf, len); } #undef FUNC_NAME diff --git a/libguile/ports.h b/libguile/ports.h index 9e28e4837..12a67ec99 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -29,6 +29,7 @@ #include #include #include +#include "libguile/bytevectors.h" #include "libguile/gc.h" #include "libguile/tags.h" #include "libguile/error.h" @@ -73,8 +74,8 @@ struct scm_port_internal; typedef struct { - /* Start of the buffer. Never changed. */ - scm_t_uint8 *buf; + /* The port buffer. */ + SCM bytevector; /* Offsets into the buffer. Invariant: cur <= end <= size(buf). */ size_t cur; @@ -86,8 +87,6 @@ typedef struct peek-u8 should still return EOF. */ SCM has_eof_p; - /* Bytevector whose contents are [BUF, BUF + SIZE). */ - SCM bytevector; } scm_t_port_buffer; @@ -430,13 +429,16 @@ SCM_INLINE_IMPLEMENTATION int scm_get_byte_or_eof_unlocked (SCM port) { scm_t_port_buffer *buf = SCM_PTAB_ENTRY (port)->read_buf; + scm_t_uint8 *ptr; + ptr = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (buf->bytevector); if (SCM_LIKELY (buf->cur < buf->end)) - return buf->buf[buf->cur++]; + return ptr[buf->cur++]; buf = scm_fill_input_unlocked (port); + ptr = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (buf->bytevector); if (buf->cur < buf->end) - return buf->buf[buf->cur++]; + return ptr[buf->cur++]; /* The next peek or get should cause the read() function to be called to see if we still have EOF. */ @@ -448,15 +450,15 @@ scm_get_byte_or_eof_unlocked (SCM port) SCM_INLINE_IMPLEMENTATION int scm_peek_byte_or_eof_unlocked (SCM port) { - scm_t_port *pt = SCM_PTAB_ENTRY (port); - scm_t_port_buffer *buf = pt->read_buf; + scm_t_port_buffer *buf = SCM_PTAB_ENTRY (port)->read_buf; + scm_t_uint8 *ptr = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (buf->bytevector); if (SCM_LIKELY (buf->cur < buf->end)) - return buf->buf[buf->cur]; + return ptr[buf->cur]; buf = scm_fill_input_unlocked (port); if (buf->cur < buf->end) - return buf->buf[buf->cur]; + return ptr[buf->cur]; return EOF; } diff --git a/libguile/read.c b/libguile/read.c index 27cb094b9..a4357d179 100644 --- a/libguile/read.c +++ b/libguile/read.c @@ -2086,7 +2086,7 @@ scm_i_scan_for_encoding (SCM port) /* An unbuffered port -- don't scan. */ return NULL; - memcpy (header, buf->buf + buf->cur, bytes_read); + memcpy (header, scm_port_buffer_take_pointer (buf), bytes_read); header[bytes_read] = '\0'; } else