mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-22 19:58:29 +01:00
common/iobuf.c: Improve iobuf_peek.
* common/iobuf.c (underflow): Take additional parameter clear_pending_eof. If not set, don't clear a pending eof when returning EOF. Update callers. (iobuf_peek): Fill the internal buffer, if needed, to be able to better satisfy any request. -- Signed-off-by: Neal H. Walfield <neal@g10code.com>.
This commit is contained in:
parent
c7ad36eb0d
commit
a250f73783
@ -161,7 +161,7 @@ block_filter_ctx_t;
|
|||||||
static int special_names_enabled;
|
static int special_names_enabled;
|
||||||
|
|
||||||
/* Local prototypes. */
|
/* Local prototypes. */
|
||||||
static int underflow (iobuf_t a);
|
static int underflow (iobuf_t a, int clear_pending_eof);
|
||||||
static int translate_file_handle (int fd, int for_write);
|
static int translate_file_handle (int fd, int for_write);
|
||||||
|
|
||||||
|
|
||||||
@ -1762,7 +1762,7 @@ pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
|
|||||||
* the first byte or -1 on EOF.
|
* the first byte or -1 on EOF.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
underflow (iobuf_t a)
|
underflow (iobuf_t a, int clear_pending_eof)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
int rc;
|
int rc;
|
||||||
@ -1792,6 +1792,9 @@ underflow (iobuf_t a)
|
|||||||
if (DBG_IOBUF)
|
if (DBG_IOBUF)
|
||||||
log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
|
log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
|
||||||
a->no, a->subno);
|
a->no, a->subno);
|
||||||
|
if (! clear_pending_eof)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (a->chain)
|
if (a->chain)
|
||||||
/* A filter follows this one. Free this filter. */
|
/* A filter follows this one. Free this filter. */
|
||||||
{
|
{
|
||||||
@ -1865,7 +1868,7 @@ underflow (iobuf_t a)
|
|||||||
a->filter = NULL;
|
a->filter = NULL;
|
||||||
a->filter_eof = 1;
|
a->filter_eof = 1;
|
||||||
|
|
||||||
if (a->d.len == 0 && a->chain)
|
if (clear_pending_eof && a->d.len == 0 && a->chain)
|
||||||
/* We don't need to keep this filter around at all:
|
/* We don't need to keep this filter around at all:
|
||||||
|
|
||||||
- we got an EOF
|
- we got an EOF
|
||||||
@ -1967,7 +1970,7 @@ iobuf_readbyte (iobuf_t a)
|
|||||||
{
|
{
|
||||||
c = a->d.buf[a->d.start++];
|
c = a->d.buf[a->d.start++];
|
||||||
}
|
}
|
||||||
else if ((c = underflow (a)) == -1)
|
else if ((c = underflow (a, 1)) == -1)
|
||||||
return -1; /* EOF */
|
return -1; /* EOF */
|
||||||
|
|
||||||
a->nbytes++;
|
a->nbytes++;
|
||||||
@ -2017,7 +2020,7 @@ iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
|
|||||||
}
|
}
|
||||||
if (n < buflen)
|
if (n < buflen)
|
||||||
{
|
{
|
||||||
if ((c = underflow (a)) == -1)
|
if ((c = underflow (a, 1)) == -1)
|
||||||
{
|
{
|
||||||
a->nbytes += n;
|
a->nbytes += n;
|
||||||
return n ? n : -1 /*EOF*/;
|
return n ? n : -1 /*EOF*/;
|
||||||
@ -2034,29 +2037,42 @@ iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* Have a look at the iobuf.
|
|
||||||
* NOTE: This only works in special cases.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
|
iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
if (a->filter_eof)
|
assert (buflen > 0);
|
||||||
return -1;
|
assert (a->use == IOBUF_INPUT);
|
||||||
|
|
||||||
if (!(a->d.start < a->d.len))
|
if (buflen > a->d.size)
|
||||||
|
/* We can't peek more than we can buffer. */
|
||||||
|
buflen = a->d.size;
|
||||||
|
|
||||||
|
/* Try to fill the internal buffer with enough data to satisfy the
|
||||||
|
request. */
|
||||||
|
while (buflen > a->d.len - a->d.start)
|
||||||
{
|
{
|
||||||
if (underflow (a) == -1)
|
if (underflow (a, 0) == -1)
|
||||||
return -1;
|
/* EOF. We can't read any more. */
|
||||||
/* And unget this character. */
|
break;
|
||||||
|
|
||||||
|
/* Underflow consumes the first character (it's the return
|
||||||
|
value). unget() it by resetting the "file position". */
|
||||||
assert (a->d.start == 1);
|
assert (a->d.start == 1);
|
||||||
a->d.start = 0;
|
a->d.start = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++)
|
n = a->d.len - a->d.start;
|
||||||
*buf = a->d.buf[n];
|
if (n > buflen)
|
||||||
|
n = buflen;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
/* EOF. */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy (buf, &a->d.buf[a->d.start], n);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user