Commit 4e00e65c authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Merge closer to FreeBSD's present sbuf version

parent 3e98f982
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $FreeBSD: head/sys/sys/sbuf.h 212425 2010-09-10 16:42:16Z mdf $ * $FreeBSD: head/sys/sys/vsb.h 221993 2011-05-16 16:18:40Z phk $
*/ */
#ifndef VSB_H_INCLUDED #ifndef VSB_H_INCLUDED
...@@ -76,7 +76,7 @@ int vsb_printf(struct vsb *, const char *, ...) ...@@ -76,7 +76,7 @@ int vsb_printf(struct vsb *, const char *, ...)
int vsb_vprintf(struct vsb *, const char *, va_list) int vsb_vprintf(struct vsb *, const char *, va_list)
__printflike(2, 0); __printflike(2, 0);
#endif #endif
int vsb_putc(struct vsb *, char); int vsb_putc(struct vsb *, int);
int vsb_trim(struct vsb *); int vsb_trim(struct vsb *);
int vsb_error(const struct vsb *); int vsb_error(const struct vsb *);
int vsb_finish(struct vsb *); int vsb_finish(struct vsb *);
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
__FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 212750 2010-09-16 16:13:12Z mdf $ __FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 222004 2011-05-17 06:36:32Z phk $")
*/ */
#include "config.h" #include "config.h"
...@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 212750 2010-09-16 16:13:12Z mdf $ ...@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 212750 2010-09-16 16:13:12Z mdf $
#define VSB_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0) #define VSB_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0)
#define VSB_MINEXTENDSIZE 16 /* Should be power of 2. */ #define VSB_MINEXTENDSIZE 16 /* Should be power of 2. */
#ifdef PAGE_SIZE #ifdef PAGE_SIZE
#define VSB_MAXEXTENDSIZE PAGE_SIZE #define VSB_MAXEXTENDSIZE PAGE_SIZE
#define VSB_MAXEXTENDINCR PAGE_SIZE #define VSB_MAXEXTENDINCR PAGE_SIZE
...@@ -108,6 +109,12 @@ _assert_vsb_state(const char *fun, struct vsb *s, int state) ...@@ -108,6 +109,12 @@ _assert_vsb_state(const char *fun, struct vsb *s, int state)
#define assert_vsb_state(s, i) do { } while (0) #define assert_vsb_state(s, i) do { } while (0)
#endif #endif
#ifdef CTASSERT
CTASSERT(powerof2(VSB_MAXEXTENDSIZE));
CTASSERT(powerof2(VSB_MAXEXTENDINCR));
#endif
static int static int
vsb_extendsize(int size) vsb_extendsize(int size)
{ {
...@@ -124,7 +131,6 @@ vsb_extendsize(int size) ...@@ -124,7 +131,6 @@ vsb_extendsize(int size)
return (newsize); return (newsize);
} }
/* /*
* Extend an vsb. * Extend an vsb.
*/ */
...@@ -164,8 +170,6 @@ vsb_newbuf(struct vsb *s, char *buf, int length, int flags) ...@@ -164,8 +170,6 @@ vsb_newbuf(struct vsb *s, char *buf, int length, int flags)
s->s_magic = VSB_MAGIC; s->s_magic = VSB_MAGIC;
if (buf != NULL) { if (buf != NULL) {
KASSERT(length > 0,
("zero or negative length (%d)", length));
s->s_size = length; s->s_size = length;
s->s_buf = buf; s->s_buf = buf;
return (s); return (s);
...@@ -182,6 +186,8 @@ vsb_newbuf(struct vsb *s, char *buf, int length, int flags) ...@@ -182,6 +186,8 @@ vsb_newbuf(struct vsb *s, char *buf, int length, int flags)
/* /*
* Initialize an vsb. * Initialize an vsb.
* If buf is non-NULL, it points to a static or already-allocated string
* big enough to hold at least length characters.
*/ */
struct vsb * struct vsb *
vsb_new(struct vsb *s, char *buf, int length, int flags) vsb_new(struct vsb *s, char *buf, int length, int flags)
...@@ -234,9 +240,10 @@ vsb_setpos(struct vsb *s, ssize_t pos) ...@@ -234,9 +240,10 @@ vsb_setpos(struct vsb *s, ssize_t pos)
assert_vsb_state(s, 0); assert_vsb_state(s, 0);
KASSERT(pos >= 0, KASSERT(pos >= 0,
("attempt to seek to a negative position (%d)", pos)); ("attempt to seek to a negative position (%jd)", (intmax_t)pos));
KASSERT(pos < s->s_size, KASSERT(pos < s->s_size,
("attempt to seek past end of vsb (%d >= %d)", pos, s->s_size)); ("attempt to seek past end of vsb (%jd >= %jd)",
(intmax_t)pos, (intmax_t)->s_size));
if (pos < 0 || pos > s->s_len) if (pos < 0 || pos > s->s_len)
return (-1); return (-1);
...@@ -250,7 +257,7 @@ vsb_setpos(struct vsb *s, ssize_t pos) ...@@ -250,7 +257,7 @@ vsb_setpos(struct vsb *s, ssize_t pos)
* buffer and marking overflow. * buffer and marking overflow.
*/ */
static void static void
vsb_put_byte(struct vsb *s, char c) vsb_put_byte(struct vsb *s, int c)
{ {
assert_vsb_integrity(s); assert_vsb_integrity(s);
...@@ -264,10 +271,9 @@ vsb_put_byte(struct vsb *s, char c) ...@@ -264,10 +271,9 @@ vsb_put_byte(struct vsb *s, char c)
if (s->s_error != 0) if (s->s_error != 0)
return; return;
} }
s->s_buf[s->s_len++] = c; s->s_buf[s->s_len++] = (char)c;
} }
/* /*
* Append a byte string to an vsb. * Append a byte string to an vsb.
*/ */
...@@ -357,6 +363,17 @@ vsb_vprintf(struct vsb *s, const char *fmt, va_list ap) ...@@ -357,6 +363,17 @@ vsb_vprintf(struct vsb *s, const char *fmt, va_list ap)
if (s->s_error != 0) if (s->s_error != 0)
return (-1); return (-1);
/*
* For the moment, there is no way to get vsnprintf(3) to hand
* back a character at a time, to push everything into
* vsb_putc_func() as was done for the kernel.
*
* In userspace, while drains are useful, there's generally
* not a problem attempting to malloc(3) on out of space. So
* expand a userland vsb if there is not enough room for the
* data produced by vsb_[v]printf(3).
*/
do { do {
va_copy(ap_copy, ap); va_copy(ap_copy, ap);
len = vsnprintf(&s->s_buf[s->s_len], VSB_FREESPACE(s) + 1, len = vsnprintf(&s->s_buf[s->s_len], VSB_FREESPACE(s) + 1,
...@@ -407,7 +424,7 @@ vsb_printf(struct vsb *s, const char *fmt, ...) ...@@ -407,7 +424,7 @@ vsb_printf(struct vsb *s, const char *fmt, ...)
* Append a character to an vsb. * Append a character to an vsb.
*/ */
int int
vsb_putc(struct vsb *s, char c) vsb_putc(struct vsb *s, int c)
{ {
vsb_put_byte(s, c); vsb_put_byte(s, c);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment