From 800d4c590fc75ba21ae7b742fe11472cdc71d4a1 Mon Sep 17 00:00:00 2001 Message-Id: <800d4c590fc75ba21ae7b742fe11472cdc71d4a1.1714935107.git.mdw@distorted.org.uk> From: Mark Wooding Date: Fri, 23 Sep 2005 10:36:36 +0000 Subject: [PATCH 1/1] Refugees from Catacomb: low-level buffer primitives. Organization: Straylight/Edgeware From: mdw --- buf.c | 533 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ buf.h | 383 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 916 insertions(+) create mode 100644 buf.c create mode 100644 buf.h diff --git a/buf.c b/buf.c new file mode 100644 index 0000000..e34d876 --- /dev/null +++ b/buf.c @@ -0,0 +1,533 @@ +/* -*-c-*- + * + * $Id$ + * + * Buffer handling + * + * (c) 2001 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include "mp.h" +#include "ec.h" +#include "buf.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @buf_init@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @void *p@ = pointer to a buffer + * @size_t sz@ = size of the buffer + * + * Returns: --- + * + * Use: Initializes the buffer block appropriately. + */ + +void buf_init(buf *b, void *p, size_t sz) +{ + b->base = b->p = p; + b->limit = b->p + sz; + b->f = 0; +} + +/* --- @buf_break@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * + * Returns: Some negative value. + * + * Use: Marks a buffer as broken. + */ + +int buf_break(buf *b) { b->f |= BF_BROKEN; return (-1); } + +/* --- @buf_flip@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * + * Returns: --- + * + * Use: Flips a buffer so that if you've just been writing to it, + * you can now read from the bit you've written. + */ + +void buf_flip(buf *b) +{ + b->limit = b->p; + b->p = b->base; +} + +/* --- @buf_ensure@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t sz@ = size of data wanted + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Ensures that there are @sz@ bytes still in the buffer. + */ + +int buf_ensure(buf *b, size_t sz) { return (BENSURE(b, sz)); } + +/* --- @buf_get@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t sz@ = size of the buffer + * + * Returns: Pointer to the place in the buffer. + * + * Use: Reserves a space in the buffer of the requested size, and + * returns its start address. + */ + +void *buf_get(buf *b, size_t sz) +{ + void *p; + if (BENSURE(b, sz)) + return (0); + p = BCUR(b); + BSTEP(b, sz); + return (p); +} + +/* --- @buf_put@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @const void *p@ = pointer to a buffer + * @size_t sz@ = size of the buffer + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Fetches data from some place and puts it in the buffer + */ + +int buf_put(buf *b, const void *p, size_t sz) +{ + if (BENSURE(b, sz)) + return (-1); + memcpy(BCUR(b), p, sz); + BSTEP(b, sz); + return (0); +} + +/* --- @buf_getbyte@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * + * Returns: A byte, or less than zero if there wasn't a byte there. + * + * Use: Gets a single byte from a buffer. + */ + +int buf_getbyte(buf *b) +{ + if (BENSURE(b, 1)) + return (-1); + return (*b->p++); +} + +/* --- @buf_putbyte@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @int ch@ = byte to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Puts a single byte in a buffer. + */ + +int buf_putbyte(buf *b, int ch) +{ + if (BENSURE(b, 1)) + return (-1); + *b->p++ = ch; + return (0); +} + +/* --- @buf_getu16@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint16 *w@ = where to put the word + * + * Returns: Zero if OK, or nonzero if there wasn't a word there. + * + * Use: Gets a 16-bit word from a buffer. + */ + +int buf_getu16(buf *b, uint16 *w) +{ + if (BENSURE(b, 2)) + return (-1); + *w = LOAD16(b->p); + BSTEP(b, 2); + return (0); +} + +/* --- @buf_putu16@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint16 w@ = word to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Puts a 16-but word in a buffer. + */ + +int buf_putu16(buf *b, uint16 w) +{ + if (BENSURE(b, 2)) + return (-1); + STORE16(b->p, w); + BSTEP(b, 2); + return (0); +} + +/* --- @buf_getu32@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint32 *w@ = where to put the word + * + * Returns: Zero if OK, or nonzero if there wasn't a word there. + * + * Use: Gets a 32-bit word from a buffer. + */ + +int buf_getu32(buf *b, uint32 *w) +{ + if (BENSURE(b, 4)) + return (-1); + *w = LOAD32(b->p); + BSTEP(b, 4); + return (0); +} + +/* --- @buf_putu32@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint32 w@ = word to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Puts a 32-but word in a buffer. + */ + +int buf_putu32(buf *b, uint32 w) +{ + if (BENSURE(b, 4)) + return (-1); + STORE32(b->p, w); + BSTEP(b, 4); + 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 + * + * Returns: A multiprecision integer, or null if there wasn't one there. + * + * Use: Gets a multiprecision integer from a buffer. + */ + +mp *buf_getmp(buf *b) +{ + uint16 sz; + size_t n; + mp *m; + if (buf_getu16(b, &sz) || buf_ensure(b, sz)) + return (0); + m = mp_loadb(MP_NEW, BCUR(b), sz); + n = mp_octets(m); + if (n != sz && n != 0 && sz != 1) { + mp_drop(m); + return (0); + } + BSTEP(b, sz); + return (m); +} + +/* --- @buf_putmp@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @mp *m@ = a multiprecision integer + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts a multiprecision integer to a buffer. + */ + +int buf_putmp(buf *b, mp *m) +{ + size_t sz = mp_octets(m); + assert(sz < MASK16); + if (!sz) sz = 1; + if (buf_putu16(b, sz) || buf_ensure(b, sz)) + return (-1); + mp_storeb(m, BCUR(b), sz); + BSTEP(b, sz); + return (0); +} + +/* --- @buf_getec@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @ec *p@ = where to put the point + * + * Returns: Zero if it worked, nonzero if it failed. + * + * Use: Gets a multiprecision integer from a buffer. The point must + * be initialized. + */ + +int buf_getec(buf *b, ec *p) +{ + mp *x = 0, *y = 0; + uint16 n; + if (buf_ensure(b, 2)) return (-1); + n = LOAD16(BCUR(b)); if (!n) { BSTEP(b, 2); EC_SETINF(p); return (0); } + if ((x = buf_getmp(b)) == 0 || (y = buf_getmp(b)) == 0) { + mp_drop(x); mp_drop(y); return (-1); + } + EC_DESTROY(p); p->x = x; p->y = y; p->z = 0; + return (0); +} + +/* --- @buf_putec@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @ec *p@ = an elliptic curve point + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts an elliptic curve point to a buffer. + */ + +int buf_putec(buf *b, ec *p) +{ + if (EC_ATINF(p)) return (buf_putu16(b, 0)); + if (buf_putmp(b, p->x) || buf_putmp(b, p->y)) return (-1); + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/buf.h b/buf.h new file mode 100644 index 0000000..84c4121 --- /dev/null +++ b/buf.h @@ -0,0 +1,383 @@ +/* -*-c-*- + * + * $Id$ + * + * Reading and writing packet buffers + * + * (c) 2001 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef CATACOMB_BUF_H +#define CATACOMB_BUF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#include + +#include + +#ifndef CATACOMB_MP_H +# include "mp.h" +#endif + +#ifndef CATACOMB_EC_H +# include "ec.h" +#endif + +/*----- Data structures ---------------------------------------------------*/ + +/* --- Buffers --- * + * + * Buffers provide a simple stream-like interface for building and parsing + * packets. + */ + +typedef struct buf { + octet *base, *p, *limit; /* Pointers to the buffer */ + unsigned f; /* Various flags */ +} buf; + +#define BF_BROKEN 1u /* Buffer is broken */ + +/*----- Useful macros -----------------------------------------------------*/ + +#define BBASE(b) ((b)->base) +#define BLIM(b) ((b)->limit) +#define BCUR(b) ((b)->p) +#define BSZ(b) ((b)->limit - (b)->base) +#define BLEN(b) ((b)->p - (b)->base) +#define BLEFT(b) ((b)->limit - (b)->p) +#define BSTEP(b, sz) ((b)->p += (sz)) +#define BBAD(b) ((b)->f & BF_BROKEN) +#define BOK(b) (!BBAD(b)) + +#define BENSURE(b, sz) \ + (BBAD(b) ? -1 : (sz) > BLEFT(b) ? (b)->f |= BF_BROKEN, -1 : 0) + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @buf_init@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @void *p@ = pointer to a buffer + * @size_t sz@ = size of the buffer + * + * Returns: --- + * + * Use: Initializes the buffer block appropriately. + */ + +extern void buf_init(buf */*b*/, void */*p*/, size_t /*sz*/); + +/* --- @buf_break@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * + * Returns: Some negative value. + * + * Use: Marks a buffer as broken. + */ + +extern int buf_break(buf */*b*/); + +/* --- @buf_flip@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * + * Returns: --- + * + * Use: Flips a buffer so that if you've just been writing to it, + * you can now read from the bit you've written. + */ + +extern void buf_flip(buf */*b*/); + +/* --- @buf_ensure@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t sz@ = size of data wanted + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Ensures that there are @sz@ bytes still in the buffer. + */ + +extern int buf_ensure(buf */*b*/, size_t /*sz*/); + +/* --- @buf_get@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @size_t sz@ = size of the buffer + * + * Returns: Pointer to the place in the buffer. + * + * Use: Reserves a space in the buffer of the requested size, and + * returns its start address. + */ + +extern void *buf_get(buf */*b*/, size_t /*sz*/); + +/* --- @buf_put@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @const void *p@ = pointer to a buffer + * @size_t sz@ = size of the buffer + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Fetches data from some place and puts it in the buffer + */ + +extern int buf_put(buf */*b*/, const void */*p*/, size_t /*sz*/); + +/* --- @buf_getbyte@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * + * Returns: A byte, or less than zero if there wasn't a byte there. + * + * Use: Gets a single byte from a buffer. + */ + +extern int buf_getbyte(buf */*b*/); + +/* --- @buf_putbyte@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @int ch@ = byte to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Puts a single byte in a buffer. + */ + +extern int buf_putbyte(buf */*b*/, int /*ch*/); + +/* --- @buf_getu16@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint16 *w@ = where to put the word + * + * Returns: Zero if OK, or nonzero if there wasn't a word there. + * + * Use: Gets a 16-bit word from a buffer. + */ + +extern int buf_getu16(buf */*b*/, uint16 */*w*/); + +/* --- @buf_putu16@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint16 w@ = word to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Puts a 16-but word in a buffer. + */ + +extern int buf_putu16(buf */*b*/, uint16 /*w*/); + +/* --- @buf_getu32@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint32 *w@ = where to put the word + * + * Returns: Zero if OK, or nonzero if there wasn't a word there. + * + * Use: Gets a 32-bit word from a buffer. + */ + +extern int buf_getu32(buf */*b*/, uint32 */*w*/); + +/* --- @buf_putu32@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @uint32 w@ = word to write + * + * Returns: Zero if OK, nonzero if there wasn't enough space. + * + * Use: Puts a 32-but word in a buffer. + */ + +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 + * + * Returns: A multiprecision integer, or null if there wasn't one there. + * + * Use: Gets a multiprecision integer from a buffer. + */ + +extern mp *buf_getmp(buf */*b*/); + +/* --- @buf_putmp@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @mp *m@ = a multiprecision integer + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts a multiprecision integer to a buffer. + */ + +extern int buf_putmp(buf */*b*/, mp */*m*/); + +/* --- @buf_getec@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @ec *p@ = where to put the point + * + * Returns: Zero if it worked, nonzero if it failed. + * + * Use: Gets a multiprecision integer from a buffer. The point must + * be initialized. + */ + +extern int buf_getec(buf */*b*/, ec */*p*/); + +/* --- @buf_putec@ --- * + * + * Arguments: @buf *b@ = pointer to a buffer block + * @ec *p@ = an elliptic curve point + * + * Returns: Zero if it worked, nonzero if there wasn't enough space. + * + * Use: Puts an elliptic curve point to a buffer. + */ + +extern int buf_putec(buf */*b*/, ec */*p*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif -- [mdw]