X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/34e4f738bcba58e6d8c4cabbb0b3232a65b42a9d..025c5f4aa5ffbf8948482a4233318db81c2df5d2:/buf.c diff --git a/buf.c b/buf.c index b4cbb71..e34d876 100644 --- a/buf.c +++ b/buf.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: buf.c,v 1.3 2004/04/01 12:50:09 mdw Exp $ + * $Id$ * * Buffer handling * @@ -27,37 +27,6 @@ * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: buf.c,v $ - * Revision 1.3 2004/04/01 12:50:09 mdw - * Add cyclic group abstraction, with test code. Separate off exponentation - * functions for better static linking. Fix a buttload of bugs on the way. - * Generally ensure that negative exponents do inversion correctly. Add - * table of standard prime-field subgroups. (Binary field subgroups are - * currently unimplemented but easy to add if anyone ever finds a good one.) - * - * Revision 1.2 2003/11/10 22:18:30 mdw - * Build fixes. - * - * Revision 1.1 2003/10/11 21:02:33 mdw - * Import buf stuff from tripe. - * - * Revision 1.4 2001/06/19 22:09:54 mdw - * Expose interface, for use in the proxy. - * - * Revision 1.3 2001/03/03 12:06:48 mdw - * Use 16-bit lengths on MPs, since there's a packet limit of 64K anyway. - * - * Revision 1.2 2001/02/16 21:23:20 mdw - * Various minor changes. Check that MPs are in canonical form when - * loading. - * - * Revision 1.1 2001/02/03 20:26:37 mdw - * Initial checkin. - * - */ - /*----- Header files ------------------------------------------------------*/ #include @@ -276,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