1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 19:50:24 +02:00

Port buffer cur/next pointers are Scheme values

* libguile/ports.h (scm_t_port_buffer): Change "cur" and "end" members
  to be SCM values, in preparation for changing port buffers to be
  Scheme vectors.
  (scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt.
* libguile/ports.c (scm_c_make_port_buffer): Initialize cur and end
  members.
  (looking_at_bytes): Use helper instead of incrementing cur.
  (scm_i_read_unlocked): Adapt to end type change.
  (CONSUME_PEEKED_BYTE): Use helper instead of incrementing cur.
  (scm_i_unget_bytes_unlocked): Use helper instead of comparing cur.
  (scm_i_write_unlocked): Fix for changing end/cur types.
* libguile/read.c (scm_i_scan_for_encoding): Use helpers instead of
  addressing cursors directly.
* libguile/rw.c (scm_write_string_partial): Likewise.
* libguile/ports-internal.h (scm_port_buffer_reset):
  (scm_port_buffer_reset_end, scm_port_buffer_can_take):
  (scm_port_buffer_can_put, scm_port_buffer_can_putback):
  (scm_port_buffer_did_take, scm_port_buffer_did_put):
  (scm_port_buffer_take_pointer, scm_port_buffer_put_pointer):
  (scm_port_buffer_putback): Adapt to data types.
This commit is contained in:
Andy Wingo 2016-04-19 19:50:21 +02:00
parent 10dc6d043e
commit ffb4347d53
5 changed files with 61 additions and 36 deletions

View file

@ -36,51 +36,57 @@ scm_port_buffer_size (scm_t_port_buffer *buf)
static inline void static inline void
scm_port_buffer_reset (scm_t_port_buffer *buf) scm_port_buffer_reset (scm_t_port_buffer *buf)
{ {
buf->cur = buf->end = 0; buf->cur = buf->end = SCM_INUM0;
} }
static inline void static inline void
scm_port_buffer_reset_end (scm_t_port_buffer *buf) scm_port_buffer_reset_end (scm_t_port_buffer *buf)
{ {
buf->cur = buf->end = scm_port_buffer_size (buf); buf->cur = buf->end = scm_from_size_t (scm_port_buffer_size (buf));
} }
static inline size_t static inline size_t
scm_port_buffer_can_take (scm_t_port_buffer *buf) scm_port_buffer_can_take (scm_t_port_buffer *buf)
{ {
return buf->end - buf->cur; return scm_to_size_t (buf->end) - scm_to_size_t (buf->cur);
} }
static inline size_t static inline size_t
scm_port_buffer_can_put (scm_t_port_buffer *buf) scm_port_buffer_can_put (scm_t_port_buffer *buf)
{ {
return scm_port_buffer_size (buf) - buf->end; return scm_port_buffer_size (buf) - scm_to_size_t (buf->end);
}
static inline size_t
scm_port_buffer_can_putback (scm_t_port_buffer *buf)
{
return scm_to_size_t (buf->cur);
} }
static inline void static inline void
scm_port_buffer_did_take (scm_t_port_buffer *buf, size_t count) scm_port_buffer_did_take (scm_t_port_buffer *buf, size_t count)
{ {
buf->cur += count; buf->cur = scm_from_size_t (scm_to_size_t (buf->cur) + count);
} }
static inline void static inline void
scm_port_buffer_did_put (scm_t_port_buffer *buf, size_t count) scm_port_buffer_did_put (scm_t_port_buffer *buf, size_t count)
{ {
buf->end += count; buf->end = scm_from_size_t (scm_to_size_t (buf->end) + count);
} }
static inline const scm_t_uint8 * static inline const scm_t_uint8 *
scm_port_buffer_take_pointer (scm_t_port_buffer *buf) scm_port_buffer_take_pointer (scm_t_port_buffer *buf)
{ {
signed char *ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector); signed char *ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector);
return ((scm_t_uint8 *) ret) + buf->cur; return ((scm_t_uint8 *) ret) + scm_to_size_t (buf->cur);
} }
static inline scm_t_uint8 * static inline scm_t_uint8 *
scm_port_buffer_put_pointer (scm_t_port_buffer *buf) scm_port_buffer_put_pointer (scm_t_port_buffer *buf)
{ {
signed char *ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector); signed char *ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector);
return ((scm_t_uint8 *) ret) + buf->end; return ((scm_t_uint8 *) ret) + scm_to_size_t (buf->end);
} }
static inline size_t static inline size_t
@ -108,12 +114,13 @@ static inline void
scm_port_buffer_putback (scm_t_port_buffer *buf, const scm_t_uint8 *src, scm_port_buffer_putback (scm_t_port_buffer *buf, const scm_t_uint8 *src,
size_t count) size_t count)
{ {
assert (count <= buf->cur); assert (count <= scm_to_size_t (buf->cur));
/* Sometimes used to move around data within a buffer, so we must use /* Sometimes used to move around data within a buffer, so we must use
memmove. */ memmove. */
buf->cur -= count; buf->cur = scm_from_size_t (scm_to_size_t (buf->cur) - count);
memmove (SCM_BYTEVECTOR_CONTENTS (buf->bytevector) + buf->cur, src, count); memmove (SCM_BYTEVECTOR_CONTENTS (buf->bytevector) + scm_to_size_t (buf->cur),
src, count);
} }
enum scm_port_encoding_mode { enum scm_port_encoding_mode {

View file

@ -518,6 +518,7 @@ scm_c_make_port_buffer (size_t size)
scm_t_port_buffer *ret = scm_gc_typed_calloc (scm_t_port_buffer); scm_t_port_buffer *ret = scm_gc_typed_calloc (scm_t_port_buffer);
ret->bytevector = scm_c_make_bytevector (size); ret->bytevector = scm_c_make_bytevector (size);
ret->cur = ret->end = SCM_INUM0;
ret->has_eof_p = SCM_BOOL_F; ret->has_eof_p = SCM_BOOL_F;
return ret; return ret;
@ -1000,7 +1001,7 @@ looking_at_bytes (SCM port, const unsigned char *bytes, int len)
while (i < len && scm_peek_byte_or_eof_unlocked (port) == bytes[i]) while (i < len && scm_peek_byte_or_eof_unlocked (port) == bytes[i])
{ {
pt->read_buf->cur++; scm_port_buffer_did_take (pt->read_buf, 1);
i++; i++;
} }
scm_i_unget_bytes_unlocked (bytes, i, port); scm_i_unget_bytes_unlocked (bytes, i, port);
@ -1413,7 +1414,8 @@ scm_i_read_unlocked (SCM port, scm_t_port_buffer *buf)
{ {
size_t count; size_t count;
count = scm_i_read_bytes_unlocked (port, buf->bytevector, buf->end, count = scm_i_read_bytes_unlocked (port, buf->bytevector,
scm_to_size_t (buf->end),
scm_port_buffer_can_put (buf)); scm_port_buffer_can_put (buf));
scm_port_buffer_did_put (buf, count); scm_port_buffer_did_put (buf, count);
buf->has_eof_p = scm_from_bool (count == 0); buf->has_eof_p = scm_from_bool (count == 0);
@ -1636,7 +1638,7 @@ get_utf8_codepoint (SCM port, scm_t_wchar *codepoint,
if (SCM_UNLIKELY ((b) == EOF)) \ if (SCM_UNLIKELY ((b) == EOF)) \
goto invalid_seq goto invalid_seq
#define CONSUME_PEEKED_BYTE() \ #define CONSUME_PEEKED_BYTE() \
pt->read_buf->cur++ scm_port_buffer_did_take (pt->read_buf, 1)
int byte; int byte;
scm_t_port *pt; scm_t_port *pt;
@ -1985,7 +1987,7 @@ scm_i_unget_bytes_unlocked (const scm_t_uint8 *buf, size_t len, SCM port)
pt->rw_active = SCM_PORT_READ; pt->rw_active = SCM_PORT_READ;
} }
if (read_buf->cur < len) if (scm_port_buffer_can_putback (read_buf) < len)
{ {
/* The bytes don't fit directly in the read_buf. */ /* The bytes don't fit directly in the read_buf. */
size_t buffered, size; size_t buffered, size;
@ -2562,8 +2564,8 @@ scm_i_write_unlocked (SCM port, scm_t_port_buffer *src)
{ {
size_t start, count; size_t start, count;
assert (src->cur < src->end); assert (scm_to_size_t (src->cur) < scm_to_size_t (src->end));
assert (src->end <= scm_port_buffer_size (src)); assert (scm_to_size_t (src->end) <= scm_port_buffer_size (src));
/* Update cursors before attempting to write, assuming that I/O errors /* Update cursors before attempting to write, assuming that I/O errors
are sticky. That way if the write throws an error, causing the are sticky. That way if the write throws an error, causing the
@ -2571,8 +2573,8 @@ scm_i_write_unlocked (SCM port, scm_t_port_buffer *src)
by GC when it's open, any subsequent close-port / force-output by GC when it's open, any subsequent close-port / force-output
won't signal *another* error. */ won't signal *another* error. */
start = src->cur; start = scm_to_size_t (src->cur);
count = src->end - src->cur; count = scm_port_buffer_can_take (src);
scm_port_buffer_reset (src); scm_port_buffer_reset (src);
scm_i_write_bytes_unlocked (port, src->bytevector, start, count); scm_i_write_bytes_unlocked (port, src->bytevector, start, count);
} }

View file

@ -78,8 +78,8 @@ typedef struct
SCM bytevector; SCM bytevector;
/* Offsets into the buffer. Invariant: cur <= end <= size(buf). */ /* Offsets into the buffer. Invariant: cur <= end <= size(buf). */
size_t cur; SCM cur;
size_t end; SCM end;
/* For read buffers, flag indicating whether the last read() returned /* For read buffers, flag indicating whether the last read() returned
zero bytes. Note that in the case of pushback, there could still zero bytes. Note that in the case of pushback, there could still
@ -429,16 +429,24 @@ SCM_INLINE_IMPLEMENTATION int
scm_get_byte_or_eof_unlocked (SCM port) scm_get_byte_or_eof_unlocked (SCM port)
{ {
scm_t_port_buffer *buf = SCM_PTAB_ENTRY (port)->read_buf; scm_t_port_buffer *buf = SCM_PTAB_ENTRY (port)->read_buf;
scm_t_uint8 *ptr; size_t cur;
ptr = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (buf->bytevector); cur = scm_to_size_t (buf->cur);
if (SCM_LIKELY (buf->cur < buf->end)) if (SCM_LIKELY (cur < scm_to_size_t (buf->end)))
return ptr[buf->cur++]; {
scm_t_uint8 ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector)[cur];
buf->cur = scm_from_size_t (cur + 1);
return ret;
}
buf = scm_fill_input_unlocked (port); buf = scm_fill_input_unlocked (port);
ptr = (scm_t_uint8 *) SCM_BYTEVECTOR_CONTENTS (buf->bytevector); cur = scm_to_size_t (buf->cur);
if (buf->cur < buf->end) if (cur < scm_to_size_t (buf->end))
return ptr[buf->cur++]; {
scm_t_uint8 ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector)[cur];
buf->cur = scm_from_size_t (cur + 1);
return ret;
}
/* The next peek or get should cause the read() function to be called /* The next peek or get should cause the read() function to be called
to see if we still have EOF. */ to see if we still have EOF. */
@ -451,14 +459,22 @@ SCM_INLINE_IMPLEMENTATION int
scm_peek_byte_or_eof_unlocked (SCM port) scm_peek_byte_or_eof_unlocked (SCM port)
{ {
scm_t_port_buffer *buf = SCM_PTAB_ENTRY (port)->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); size_t cur;
if (SCM_LIKELY (buf->cur < buf->end)) cur = scm_to_size_t (buf->cur);
return ptr[buf->cur]; if (SCM_LIKELY (cur < scm_to_size_t (buf->end)))
{
scm_t_uint8 ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector)[cur];
return ret;
}
buf = scm_fill_input_unlocked (port); buf = scm_fill_input_unlocked (port);
if (buf->cur < buf->end) cur = scm_to_size_t (buf->cur);
return ptr[buf->cur]; if (cur < scm_to_size_t (buf->end))
{
scm_t_uint8 ret = SCM_BYTEVECTOR_CONTENTS (buf->bytevector)[cur];
return ret;
}
return EOF; return EOF;
} }

View file

@ -2074,11 +2074,11 @@ scm_i_scan_for_encoding (SCM port)
pt->rw_active = SCM_PORT_READ; pt->rw_active = SCM_PORT_READ;
} }
if (buf->cur == buf->end) if (scm_port_buffer_can_take (buf) == 0)
{ {
/* We can use the read buffer, and thus avoid a seek. */ /* We can use the read buffer, and thus avoid a seek. */
buf = scm_fill_input_unlocked (port); buf = scm_fill_input_unlocked (port);
bytes_read = buf->end - buf->cur; bytes_read = scm_port_buffer_can_take (buf);
if (bytes_read > SCM_ENCODING_SEARCH_SIZE) if (bytes_read > SCM_ENCODING_SEARCH_SIZE)
bytes_read = SCM_ENCODING_SEARCH_SIZE; bytes_read = SCM_ENCODING_SEARCH_SIZE;

View file

@ -240,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 /* Filling the last character in the buffer would require a
flush. */ flush. */
if (write_len < scm_port_buffer_size (write_buf) - write_buf->end) if (write_len < scm_port_buffer_can_put (write_buf))
{ {
scm_c_write_unlocked (port, src, write_len); scm_c_write_unlocked (port, src, write_len);
return scm_from_long (write_len); return scm_from_long (write_len);