sbuf: Process more than one char at a time
Revamp sbuf_put_byte() to sbuf_put_bytes() in the obvious fashion and fixup callers. Add a thin shim around sbuf_put_bytes() with the old ABI to avoid ugly changes to some callers. Reviewed by: jhb, markj Obtained from: Dan Sledz Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D3717
This commit is contained in:
parent
048c6e7723
commit
d13a26b53a
@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/ctype.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/uio.h>
|
||||
@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$");
|
||||
#else /* _KERNEL */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -383,34 +385,51 @@ sbuf_drain(struct sbuf *s)
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a byte to an sbuf. This is the core function for appending
|
||||
* Append bytes to an sbuf. This is the core function for appending
|
||||
* to an sbuf and is the main place that deals with extending the
|
||||
* buffer and marking overflow.
|
||||
*/
|
||||
static void
|
||||
sbuf_put_byte(struct sbuf *s, int c)
|
||||
sbuf_put_bytes(struct sbuf *s, const char *buf, size_t len)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
assert_sbuf_integrity(s);
|
||||
assert_sbuf_state(s, 0);
|
||||
|
||||
if (s->s_error != 0)
|
||||
return;
|
||||
if (SBUF_FREESPACE(s) <= 0) {
|
||||
/*
|
||||
* If there is a drain, use it, otherwise extend the
|
||||
* buffer.
|
||||
*/
|
||||
if (s->s_drain_func != NULL)
|
||||
(void)sbuf_drain(s);
|
||||
else if (sbuf_extend(s, 1) < 0)
|
||||
s->s_error = ENOMEM;
|
||||
if (s->s_error != 0)
|
||||
return;
|
||||
while (len > 0) {
|
||||
if (SBUF_FREESPACE(s) <= 0) {
|
||||
/*
|
||||
* If there is a drain, use it, otherwise extend the
|
||||
* buffer.
|
||||
*/
|
||||
if (s->s_drain_func != NULL)
|
||||
(void)sbuf_drain(s);
|
||||
else if (sbuf_extend(s, len > INT_MAX ? INT_MAX : len)
|
||||
< 0)
|
||||
s->s_error = ENOMEM;
|
||||
if (s->s_error != 0)
|
||||
return;
|
||||
}
|
||||
n = SBUF_FREESPACE(s);
|
||||
if (len < n)
|
||||
n = len;
|
||||
memcpy(&s->s_buf[s->s_len], buf, n);
|
||||
s->s_len += n;
|
||||
if (SBUF_ISSECTION(s))
|
||||
s->s_sect_len += n;
|
||||
len -= n;
|
||||
buf += n;
|
||||
}
|
||||
s->s_buf[s->s_len++] = c;
|
||||
if (SBUF_ISSECTION(s))
|
||||
s->s_sect_len++;
|
||||
}
|
||||
|
||||
static void
|
||||
sbuf_put_byte(struct sbuf *s, char c)
|
||||
{
|
||||
|
||||
sbuf_put_bytes(s, &c, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -419,19 +438,10 @@ sbuf_put_byte(struct sbuf *s, int c)
|
||||
int
|
||||
sbuf_bcat(struct sbuf *s, const void *buf, size_t len)
|
||||
{
|
||||
const char *str = buf;
|
||||
const char *end = str + len;
|
||||
|
||||
assert_sbuf_integrity(s);
|
||||
assert_sbuf_state(s, 0);
|
||||
|
||||
sbuf_put_bytes(s, buf, len);
|
||||
if (s->s_error != 0)
|
||||
return (-1);
|
||||
for (; str < end; str++) {
|
||||
sbuf_put_byte(s, *str);
|
||||
if (s->s_error != 0)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -485,18 +495,12 @@ sbuf_bcpy(struct sbuf *s, const void *buf, size_t len)
|
||||
int
|
||||
sbuf_cat(struct sbuf *s, const char *str)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
assert_sbuf_integrity(s);
|
||||
assert_sbuf_state(s, 0);
|
||||
|
||||
n = strlen(str);
|
||||
sbuf_put_bytes(s, str, n);
|
||||
if (s->s_error != 0)
|
||||
return (-1);
|
||||
|
||||
while (*str != '\0') {
|
||||
sbuf_put_byte(s, *str++);
|
||||
if (s->s_error != 0)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user