diff options
Diffstat (limited to 'common/iobuf.c')
-rw-r--r-- | common/iobuf.c | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/common/iobuf.c b/common/iobuf.c index 02c9b491c..05944255f 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -68,8 +68,8 @@ /*-- End configurable part. --*/ -/* The size of the iobuffers. This can be chnages using the - * iobuf_set_buffer_size fucntion. */ +/* The size of the iobuffers. This can be changed using the + * iobuf_set_buffer_size function. */ static unsigned int iobuf_buffer_size = DEFAULT_IOBUF_BUFFER_SIZE; @@ -878,9 +878,9 @@ block_filter (void *opaque, int control, iobuf_t chain, byte * buffer, } else if (c == 255) { - a->size = (size_t)iobuf_get (chain) << 24; - a->size |= iobuf_get (chain) << 16; - a->size |= iobuf_get (chain) << 8; + a->size = iobuf_get_noeof (chain) << 24; + a->size |= iobuf_get_noeof (chain) << 16; + a->size |= iobuf_get_noeof (chain) << 8; if ((c = iobuf_get (chain)) == -1) { log_error ("block_filter: invalid 4 byte length\n"); @@ -2262,6 +2262,7 @@ iobuf_copy (iobuf_t dest, iobuf_t source) size_t nread; size_t nwrote = 0; + size_t max_read = 0; int err; assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP); @@ -2278,6 +2279,9 @@ iobuf_copy (iobuf_t dest, iobuf_t source) /* EOF. */ break; + if (nread > max_read) + max_read = nread; + err = iobuf_write (dest, temp, nread); if (err) break; @@ -2285,7 +2289,8 @@ iobuf_copy (iobuf_t dest, iobuf_t source) } /* Burn the buffer. */ - wipememory (temp, sizeof (temp)); + if (max_read) + wipememory (temp, max_read); xfree (temp); return nwrote; @@ -2610,12 +2615,50 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, } p = buffer; - while ((c = iobuf_get (a)) != -1) + while (1) { - *p++ = c; - nbytes++; - if (c == '\n') - break; + if (!a->nofast && a->d.start < a->d.len && nbytes < length - 1) + /* Fast path for finding '\n' by using standard C library's optimized + memchr. */ + { + unsigned size = a->d.len - a->d.start; + byte *newline_pos; + + if (size > length - 1 - nbytes) + size = length - 1 - nbytes; + + newline_pos = memchr (a->d.buf + a->d.start, '\n', size); + if (newline_pos) + { + /* Found newline, copy buffer and return. */ + size = (newline_pos - (a->d.buf + a->d.start)) + 1; + memcpy (p, a->d.buf + a->d.start, size); + p += size; + nbytes += size; + a->d.start += size; + a->nbytes += size; + break; + } + else + { + /* No newline, copy buffer and continue. */ + memcpy (p, a->d.buf + a->d.start, size); + p += size; + nbytes += size; + a->d.start += size; + a->nbytes += size; + } + } + else + { + c = iobuf_readbyte (a); + if (c == -1) + break; + *p++ = c; + nbytes++; + if (c == '\n') + break; + } if (nbytes == length - 1) /* We don't have enough space to add a \n and a \0. Increase |