From fe9de6c9fbf52fa3a0eb0929fd18d615741f1d49 Mon Sep 17 00:00:00 2001 From: mdw Date: Fri, 18 Mar 2005 00:26:11 +0000 Subject: [PATCH] Support strings in buffer formats. --- buf.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- buf.h | 103 +++++++++++++++++++++++++++++++++- 2 files changed, 299 insertions(+), 2 deletions(-) diff --git a/buf.c b/buf.c index 3a09365..e34d876 100644 --- a/buf.c +++ b/buf.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: buf.c,v 1.4 2004/04/08 01:36:15 mdw Exp $ + * $Id$ * * Buffer handling * @@ -245,6 +245,202 @@ int buf_putu32(buf *b, uint32 w) return (0); } +/* --- @findz@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t *nn@ = where to put the length + * + * Returns: Zero if OK, nonzero if there wasn't a null byte to be found. + * + * Use: Finds a terminating null byte. + */ + +static int findz(buf *b, size_t *nn) +{ + octet *p; + + if ((p = memchr(BCUR(b), 0, BLEN(b))) == 0) { + buf_break(b); + return (-1); + } + *nn = p - BCUR(b); + return (0); +} + +#define DOSUFFIXES(DO) DO(8) DO(16) DO(32) DO(z) + +/* --- @buf_getmem{8,16,32,z} --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t *nn@ = where to put the length + * + * Returns: Pointer to the buffer data, or null. + * + * Use: Gets a chunk of memory from a buffer. The number, @16@ or + * @32@, is the width of the length; @z@ means null-terminated. + */ + +void *buf_getmem8(buf *b, size_t *nn) +{ + int n; + + if ((n = buf_getbyte(b)) < 0) return (0); + *nn = n; + return (buf_get(b, n)); +} + +void *buf_getmem16(buf *b, size_t *nn) +{ + uint16 n; + + if (buf_getu16(b, &n)) return (0); + *nn = n; + return (buf_get(b, n)); +} + +void *buf_getmem32(buf *b, size_t *nn) +{ + uint32 n; + + if (buf_getu32(b, &n)) return (0); + *nn = n; + return (buf_get(b, n)); +} + +void *buf_getmemz(buf *b, size_t *nn) +{ + if (findz(b, nn)) return (0); + return (buf_get(b, *nn)); +} + +/* --- @buf_putmem{8,16,32,z} --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @const void *p@ = pointer to data to write + * @size_t n@ = length to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Writes a chunk of data to a buffer. The number, @16@ or + * @32@, is the width of the length; @z@ means null-terminated. + */ + +int buf_putmem8(buf *b, const void *p, size_t n) +{ + assert(n <= 0xfful); + if (buf_putbyte(b, n) || buf_put(b, p, n)) + return (-1); + return (0); +} + +int buf_putmem16(buf *b, const void *p, size_t n) +{ + assert(n <= 0xfffful); + if (buf_putu16(b, n) || buf_put(b, p, n)) + return (-1); + return (0); +} + +int buf_putmem32(buf *b, const void *p, size_t n) +{ + assert(n <= 0xfffffffful); + if (buf_putu32(b, n) || buf_put(b, p, n)) + return (-1); + return (0); +} + +int buf_putmemz(buf *b, const void *p, size_t n) +{ + octet *q; + + assert(!memchr(p, 0, n)); + if ((q = buf_get(b, n + 1)) == 0) + return (-1); + memcpy(q, p, n); + q[n] = 0; + return (0); +} + +/* --- @buf_getbuf{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @buf *bb@ = where to put the result + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Gets a block of data from a buffer, and writes its bounds to + * another buffer. The number, @16@ or @32@, is the width of + * the length; @z@ means null-terminated. + */ + +#define GETBUF(suff) int buf_getbuf##suff(buf *b, buf *bb) \ +{ \ + void *p; \ + size_t n; \ + \ + if ((p = buf_getmem##suff(b, &n)) == 0) \ + return (-1); \ + buf_init(bb, p, n); \ + return (0); \ +} +DOSUFFIXES(GETBUF) + +/* --- @buf_putbuf{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @buf *bb@ = buffer to write + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts the contents of a buffer to a buffer. The number, @16@ + * or @32@, is the width of the length; @z@ means null- + * terminated. + */ + +#define PUTBUF(suff) int buf_putbuf##suff(buf *b, buf *bb) \ + { return (buf_putmem##suff(b, BBASE(bb), BLEN(bb))); } +DOSUFFIXES(PUTBUF) + +/* --- @buf_getstr{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @dstr *d@ = where to put the result + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Gets a block of data from a buffer, and writes its contents + * to a string. The number, @16@ or @32@, is the width of the + * length; @z@ means null-terminated. + */ + +#define GETSTR(suff) int buf_getstr##suff(buf *b, dstr *d) \ +{ \ + void *p; \ + size_t n; \ + \ + if ((p = buf_getmem##suff(b, &n)) == 0) \ + return (-1); \ + DPUTM(d, p, n); \ + return (0); \ +} +DOSUFFIXES(GETSTR) + +/* --- @buf_putstr{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @dstr *d@ = string to write + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts a string to a buffer, and writes its bounds to + * another buffer. The number, @16@ or @32@, is the width of + * the length; @z@ means null-terminated. + */ + +#define PUTSTR(suff) int buf_putstr##suff(buf *b, dstr *d) \ + { return (buf_putmem##suff(b, d->buf, d->len)); } +DOSUFFIXES(PUTSTR) + /* --- @buf_getmp@ --- * * * Arguments: @buf *b@ = pointer to a buffer block diff --git a/buf.h b/buf.h index a83985c..84c4121 100644 --- a/buf.h +++ b/buf.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: buf.h,v 1.4 2004/04/08 01:36:15 mdw Exp $ + * $Id$ * * Reading and writing packet buffers * @@ -225,6 +225,107 @@ extern int buf_getu32(buf */*b*/, uint32 */*w*/); extern int buf_putu32(buf */*b*/, uint32 /*w*/); +/* --- @buf_getmem{8,16,32,z} --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t *nn@ = where to put the length + * + * Returns: Pointer to the buffer data, or null. + * + * Use: Gets a chunk of memory from a buffer. The number, @16@ or + * @32@, is the width of the length; @z@ means null-terminated. + */ + +extern void *buf_getmem8(buf */*b*/, size_t */*nn*/); +extern void *buf_getmem16(buf */*b*/, size_t */*nn*/); +extern void *buf_getmem32(buf */*b*/, size_t */*nn*/); +extern void *buf_getmemz(buf */*b*/, size_t */*nn*/); + +/* --- @buf_putmem{8,16,32,z} --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @const void *p@ = pointer to data to write + * @size_t n@ = length to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Writes a chunk of data to a buffer. The number, @16@ or + * @32@, is the width of the length; @z@ means null-terminated. + */ + +extern int buf_putmem8(buf */*b*/, const void */*p*/, size_t /*n*/); +extern int buf_putmem16(buf */*b*/, const void */*p*/, size_t /*n*/); +extern int buf_putmem32(buf */*b*/, const void */*p*/, size_t /*n*/); +extern int buf_putmemz(buf */*b*/, const void */*p*/, size_t /*n*/); + +/* --- @buf_getbuf{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @buf *bb@ = where to put the result + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Gets a block of data from a buffer, and writes its bounds to + * another buffer. The number, @16@ or @32@, is the width of + * the length; @z@ means null-terminated. + */ + +extern int buf_getbuf8(buf */*b*/, buf */*bb*/); +extern int buf_getbuf16(buf */*b*/, buf */*bb*/); +extern int buf_getbuf32(buf */*b*/, buf */*bb*/); +extern int buf_getbufz(buf */*b*/, buf */*bb*/); + +/* --- @buf_putbuf{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @buf *bb@ = buffer to write + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts the contents of a buffer to a buffer. The number, @16@ + * or @32@, is the width of the length; @z@ means null- + * terminated. + */ + +extern int buf_putbuf8(buf */*b*/, buf */*bb*/); +extern int buf_putbuf16(buf */*b*/, buf */*bb*/); +extern int buf_putbuf32(buf */*b*/, buf */*bb*/); +extern int buf_putbufz(buf */*b*/, buf */*bb*/); + +/* --- @buf_getstr{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @dstr *d@ = where to put the result + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Gets a block of data from a buffer, and writes its contents + * to a string. The number, @16@ or @32@, is the width of the + * length; @z@ means null-terminated. + */ + +extern int buf_getstr8(buf */*b*/, dstr */*d*/); +extern int buf_getstr16(buf */*b*/, dstr */*d*/); +extern int buf_getstr32(buf */*b*/, dstr */*d*/); +extern int buf_getstrz(buf */*b*/, dstr */*d*/); + +/* --- @buf_putstr{8,16,32,z}@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @dstr *d@ = string to write + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts a string to a buffer, and writes its bounds to + * another buffer. The number, @16@ or @32@, is the width of + * the length; @z@ means null-terminated. + */ + +extern int buf_putstr8(buf */*b*/, dstr */*d*/); +extern int buf_putstr16(buf */*b*/, dstr */*d*/); +extern int buf_putstr32(buf */*b*/, dstr */*d*/); +extern int buf_putstrz(buf */*b*/, dstr */*d*/); + /* --- @buf_getmp@ --- * * * Arguments: @buf *b@ = pointer to a buffer block -- 2.11.0