mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
scm_fill_input can guarantee a minimum fill amount
* libguile/ports.h (scm_fill_input): Add "minimum_size" argument. Adapt all callers to pass 0 as this argument. * libguile/ports.c (scm_i_read): Inline into scm_fill_input. (scm_fill_input): "minimum_size" argument ensures that there are a certain number of bytes available, or EOF. Instead of shrinking the read buffer, only fill by the read_buffering amount, or the minimum_size, whichever is larger. * libguile/r6rs-ports.c: * libguile/read.c: Adapt scm_fill_input callers.
This commit is contained in:
parent
6a752bcf2a
commit
56c48d14ac
4 changed files with 52 additions and 31 deletions
|
@ -1414,7 +1414,7 @@ get_byte_or_eof (SCM port)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = scm_fill_input (port);
|
buf = scm_fill_input (port, 0);
|
||||||
buf_bv = scm_port_buffer_bytevector (buf);
|
buf_bv = scm_port_buffer_bytevector (buf);
|
||||||
buf_cur = scm_port_buffer_cur (buf);
|
buf_cur = scm_port_buffer_cur (buf);
|
||||||
buf_end = scm_port_buffer_end (buf);
|
buf_end = scm_port_buffer_end (buf);
|
||||||
|
@ -1453,7 +1453,7 @@ peek_byte_or_eof (SCM port)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = scm_fill_input (port);
|
buf = scm_fill_input (port, 0);
|
||||||
buf_bv = scm_port_buffer_bytevector (buf);
|
buf_bv = scm_port_buffer_bytevector (buf);
|
||||||
buf_cur = scm_port_buffer_cur (buf);
|
buf_cur = scm_port_buffer_cur (buf);
|
||||||
buf_end = scm_port_buffer_end (buf);
|
buf_end = scm_port_buffer_end (buf);
|
||||||
|
@ -1495,21 +1495,6 @@ scm_i_read_bytes (SCM port, SCM dst, size_t start, size_t count)
|
||||||
return filled;
|
return filled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* scm_i_read is used internally to add bytes to the given port
|
|
||||||
buffer. If the number of available bytes in the buffer does not
|
|
||||||
increase after a call to scm_i_read, that indicates EOF. */
|
|
||||||
static void
|
|
||||||
scm_i_read (SCM port, SCM buf)
|
|
||||||
{
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
count = scm_i_read_bytes (port, scm_port_buffer_bytevector (buf),
|
|
||||||
scm_to_size_t (scm_port_buffer_end (buf)),
|
|
||||||
scm_port_buffer_can_put (buf));
|
|
||||||
scm_port_buffer_did_put (buf, count);
|
|
||||||
scm_port_buffer_set_has_eof_p (buf, scm_from_bool (count == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used by an application to read arbitrary number of bytes from an SCM
|
/* Used by an application to read arbitrary number of bytes from an SCM
|
||||||
port. Same semantics as libc read, except that scm_c_read_bytes only
|
port. Same semantics as libc read, except that scm_c_read_bytes only
|
||||||
returns less than SIZE bytes if at end-of-file.
|
returns less than SIZE bytes if at end-of-file.
|
||||||
|
@ -1548,7 +1533,7 @@ scm_c_read_bytes (SCM port, SCM dst, size_t start, size_t count)
|
||||||
buffer directly. */
|
buffer directly. */
|
||||||
if (to_read < pt->read_buffering)
|
if (to_read < pt->read_buffering)
|
||||||
{
|
{
|
||||||
read_buf = scm_fill_input (port);
|
read_buf = scm_fill_input (port, 0);
|
||||||
did_read = scm_port_buffer_take (read_buf, dst_ptr, to_read);
|
did_read = scm_port_buffer_take (read_buf, dst_ptr, to_read);
|
||||||
dst_ptr += did_read;
|
dst_ptr += did_read;
|
||||||
to_read -= did_read;
|
to_read -= did_read;
|
||||||
|
@ -1598,7 +1583,7 @@ scm_c_read (SCM port, void *buffer, size_t size)
|
||||||
while (copied < size)
|
while (copied < size)
|
||||||
{
|
{
|
||||||
size_t count;
|
size_t count;
|
||||||
read_buf = scm_fill_input (port);
|
read_buf = scm_fill_input (port, 0);
|
||||||
count = scm_port_buffer_take (read_buf, dst + copied, size - copied);
|
count = scm_port_buffer_take (read_buf, dst + copied, size - copied);
|
||||||
copied += count;
|
copied += count;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
|
@ -2451,26 +2436,62 @@ scm_flush (SCM port)
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_fill_input (SCM port)
|
scm_fill_input (SCM port, size_t minimum_size)
|
||||||
{
|
{
|
||||||
scm_t_port *pt = SCM_PTAB_ENTRY (port);
|
scm_t_port *pt = SCM_PTAB_ENTRY (port);
|
||||||
SCM read_buf = pt->read_buf;
|
SCM read_buf = pt->read_buf;
|
||||||
|
size_t buffered = scm_port_buffer_can_take (read_buf);
|
||||||
|
|
||||||
if (scm_port_buffer_can_take (read_buf) ||
|
if (minimum_size == 0)
|
||||||
scm_is_true (scm_port_buffer_has_eof_p (read_buf)))
|
minimum_size = 1;
|
||||||
|
|
||||||
|
if (buffered >= minimum_size
|
||||||
|
|| scm_is_true (scm_port_buffer_has_eof_p (read_buf)))
|
||||||
return read_buf;
|
return read_buf;
|
||||||
|
|
||||||
if (pt->rw_random)
|
if (pt->rw_random)
|
||||||
scm_flush (pt->port);
|
scm_flush (pt->port);
|
||||||
|
|
||||||
/* It could be that putback caused us to enlarge the buffer; now that
|
/* Prepare to read. Make sure there is enough space in the buffer for
|
||||||
we've read all the bytes we need to shrink it again. */
|
minimum_size, and ensure that cur is zero so that we fill towards
|
||||||
if (scm_port_buffer_size (read_buf) != pt->read_buffering)
|
the end of the buffer. */
|
||||||
read_buf = pt->read_buf = scm_c_make_port_buffer (pt->read_buffering);
|
if (minimum_size > scm_port_buffer_size (read_buf))
|
||||||
else
|
{
|
||||||
|
/* Grow the read buffer. */
|
||||||
|
SCM new_buf = scm_c_make_port_buffer (minimum_size);
|
||||||
|
scm_port_buffer_reset (new_buf);
|
||||||
|
scm_port_buffer_put (new_buf,
|
||||||
|
scm_port_buffer_take_pointer (read_buf),
|
||||||
|
buffered);
|
||||||
|
pt->read_buf = read_buf = new_buf;
|
||||||
|
}
|
||||||
|
else if (buffered == 0)
|
||||||
scm_port_buffer_reset (read_buf);
|
scm_port_buffer_reset (read_buf);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const scm_t_uint8 *to_shift = scm_port_buffer_take_pointer (read_buf);
|
||||||
|
scm_port_buffer_reset (read_buf);
|
||||||
|
memmove (scm_port_buffer_put_pointer (read_buf), to_shift, buffered);
|
||||||
|
scm_port_buffer_did_put (read_buf, buffered);
|
||||||
|
}
|
||||||
|
|
||||||
scm_i_read (port, read_buf);
|
while (buffered < minimum_size
|
||||||
|
&& !scm_is_true (scm_port_buffer_has_eof_p (read_buf)))
|
||||||
|
{
|
||||||
|
size_t count;
|
||||||
|
size_t buffering = pt->read_buffering;
|
||||||
|
size_t to_read;
|
||||||
|
|
||||||
|
if (pt->read_buffering < minimum_size)
|
||||||
|
buffering = minimum_size;
|
||||||
|
to_read = buffering - buffered;
|
||||||
|
|
||||||
|
count = scm_i_read_bytes (port, scm_port_buffer_bytevector (read_buf),
|
||||||
|
buffered, to_read);
|
||||||
|
buffered += count;
|
||||||
|
scm_port_buffer_did_put (read_buf, count);
|
||||||
|
scm_port_buffer_set_has_eof_p (read_buf, scm_from_bool (count == 0));
|
||||||
|
}
|
||||||
|
|
||||||
return read_buf;
|
return read_buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,7 @@ SCM_API SCM scm_unread_string (SCM str, SCM port);
|
||||||
|
|
||||||
/* Manipulating the buffers. */
|
/* Manipulating the buffers. */
|
||||||
SCM_API SCM scm_setvbuf (SCM port, SCM mode, SCM size);
|
SCM_API SCM scm_setvbuf (SCM port, SCM mode, SCM size);
|
||||||
SCM_API SCM scm_fill_input (SCM port);
|
SCM_API SCM scm_fill_input (SCM port, size_t minimum_size);
|
||||||
SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
|
SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
|
||||||
SCM_API SCM scm_drain_input (SCM port);
|
SCM_API SCM scm_drain_input (SCM port);
|
||||||
SCM_API void scm_end_input (SCM port);
|
SCM_API void scm_end_input (SCM port);
|
||||||
|
|
|
@ -474,7 +474,7 @@ SCM_DEFINE (scm_get_bytevector_some, "get-bytevector-some", 1, 0, 0,
|
||||||
|
|
||||||
SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
|
SCM_VALIDATE_BINARY_INPUT_PORT (1, port);
|
||||||
|
|
||||||
buf = scm_fill_input (port);
|
buf = scm_fill_input (port, 0);
|
||||||
size = scm_port_buffer_can_take (buf);
|
size = scm_port_buffer_can_take (buf);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2073,7 +2073,7 @@ scm_i_scan_for_encoding (SCM port)
|
||||||
if (scm_port_buffer_can_take (buf) == 0)
|
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 (port);
|
buf = scm_fill_input (port, 0);
|
||||||
bytes_read = scm_port_buffer_can_take (buf);
|
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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue