Add sbuf_clear() and sbuf_overflowed().

Move the helper macros from sbuf.h to sbuf.c
Use ints instead of size_ts.
Relax the requirements for sbuf_finish(): it is now possible to finish an
overflowed buffer.
Make sbuf_len() return -1 instead of 0 if the sbuf overflowed.

Requested by:	gibbs
This commit is contained in:
des 2001-01-28 00:13:01 +00:00
parent 5790cce92d
commit ba6b6e22f5
2 changed files with 57 additions and 32 deletions

View File

@ -38,6 +38,23 @@
MALLOC_DEFINE(M_SBUF, "sbuf", "string buffers");
/*
* Predicates
*/
#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED)
#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
/*
* Set / clear flags
*/
#define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0)
#define SBUF_CLEARFLAG(s, f) do { (s)->s_flags &= ~(f); } while (0)
/*
* Debugging support
*/
#ifdef INVARIANTS
static void
assert_sbuf_integrity(struct sbuf *s)
@ -68,8 +85,10 @@ assert_sbuf_state(struct sbuf *s, int state)
* big enough to hold at least length characters.
*/
int
sbuf_new(struct sbuf *s, char *buf, size_t length, int flags)
sbuf_new(struct sbuf *s, char *buf, int length, int flags)
{
KASSERT(length >= 0,
("attempt to create an sbuf of negative length (%d)", length));
KASSERT(flags == 0,
(__FUNCTION__ " called with non-zero flags"));
KASSERT(s != NULL,
@ -88,11 +107,24 @@ sbuf_new(struct sbuf *s, char *buf, size_t length, int flags)
return (0);
}
/*
* Clear an sbuf and reset its position
*/
void
sbuf_clear(struct sbuf *s)
{
assert_sbuf_integrity(s);
SBUF_CLEARFLAG(s, SBUF_FINISHED);
SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
s->s_len = 0;
}
/*
* Set the sbuf's position to an arbitrary value
*/
int
sbuf_setpos(struct sbuf *s, size_t pos)
sbuf_setpos(struct sbuf *s, int pos)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
@ -138,7 +170,7 @@ sbuf_cpy(struct sbuf *s, char *str)
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
s->s_len = 0;
sbuf_clear(s);
return (sbuf_cat(s, str));
}
@ -168,7 +200,7 @@ int
sbuf_printf(struct sbuf *s, char *fmt, ...)
{
va_list ap;
size_t len;
int len;
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
@ -212,20 +244,26 @@ sbuf_putc(struct sbuf *s, int c)
}
/*
* Finish off an sbuf.
* Check if an sbuf overflowed
*/
int
sbuf_overflowed(struct sbuf *s)
{
return SBUF_HASOVERFLOWED(s);
}
/*
* Finish off an sbuf.
*/
void
sbuf_finish(struct sbuf *s)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, 0);
if (SBUF_HASOVERFLOWED(s))
return (-1);
s->s_buf[s->s_len++] = '\0';
SBUF_CLEARFLAG(s, SBUF_OVERFLOWED);
SBUF_SETFLAG(s, SBUF_FINISHED);
return (0);
}
/*
@ -237,22 +275,20 @@ sbuf_data(struct sbuf *s)
assert_sbuf_integrity(s);
assert_sbuf_state(s, SBUF_FINISHED);
if (SBUF_HASOVERFLOWED(s))
return (NULL);
return s->s_buf;
}
/*
* Return the length of the sbuf data.
*/
size_t
int
sbuf_len(struct sbuf *s)
{
assert_sbuf_integrity(s);
assert_sbuf_state(s, SBUF_FINISHED);
if (SBUF_HASOVERFLOWED(s))
return (0);
return (-1);
return s->s_len;
}

View File

@ -37,8 +37,8 @@
struct sbuf {
char *s_buf; /* storage buffer */
struct sbuf *s_next; /* next in chain */
size_t s_size; /* size of storage buffer */
size_t s_len; /* current length of string */
int s_size; /* size of storage buffer */
int s_len; /* current length of string */
#define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */
#define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */
#define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */
@ -46,31 +46,20 @@ struct sbuf {
int s_flags; /* flags */
};
/*
* Predicates
*/
#define SBUF_ISDYNAMIC(s) ((s)->s_flags & SBUF_DYNAMIC)
#define SBUF_ISFINISHED(s) ((s)->s_flags & SBUF_FINISHED)
#define SBUF_HASOVERFLOWED(s) ((s)->s_flags & SBUF_OVERFLOWED)
#define SBUF_HASROOM(s) ((s)->s_len < (s)->s_size - 1)
/*
* Other macros
*/
#define SBUF_SETFLAG(s, f) do { (s)->s_flags |= (f); } while (0)
/*
* API functions
*/
int sbuf_new(struct sbuf *s, char *buf, size_t length, int flags);
int sbuf_setpos(struct sbuf *s, size_t pos);
int sbuf_new(struct sbuf *s, char *buf, int length, int flags);
void sbuf_clear(struct sbuf *s);
int sbuf_setpos(struct sbuf *s, int pos);
int sbuf_cat(struct sbuf *s, char *str);
int sbuf_cpy(struct sbuf *s, char *str);
int sbuf_printf(struct sbuf *s, char *fmt, ...);
int sbuf_putc(struct sbuf *s, int c);
int sbuf_finish(struct sbuf *s);
int sbuf_overflowed(struct sbuf *s);
void sbuf_finish(struct sbuf *s);
char *sbuf_data(struct sbuf *s);
size_t sbuf_len(struct sbuf *s);
int sbuf_len(struct sbuf *s);
void sbuf_delete(struct sbuf *s);
#endif