diff options
author | 2004-04-28 06:53:12 +0000 | |
---|---|---|
committer | 2004-04-28 06:53:12 +0000 | |
commit | ff9272da353f4ed9d5641b639ae0f2c322e15c6e (patch) | |
tree | d1ed9a69ece119488a5f1b70f1664b54575557c1 /lib/libevent/buffer.c | |
parent | slightly more intricate selectors code. (diff) | |
download | wireguard-openbsd-ff9272da353f4ed9d5641b639ae0f2c322e15c6e.tar.xz wireguard-openbsd-ff9272da353f4ed9d5641b639ae0f2c322e15c6e.zip |
update to libevent 0.8; keep local changes
ok markus@
Diffstat (limited to 'lib/libevent/buffer.c')
-rw-r--r-- | lib/libevent/buffer.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/lib/libevent/buffer.c b/lib/libevent/buffer.c new file mode 100644 index 00000000000..f9a1f1b4d22 --- /dev/null +++ b/lib/libevent/buffer.c @@ -0,0 +1,222 @@ +/* $OpenBSD: buffer.c,v 1.1 2004/04/28 06:53:12 brad Exp $ */ + +/* + * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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 SUCH DAMAGE. + */ + +#include <sys/types.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_STDARG_H +#include <stdarg.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "event.h" + +struct evbuffer * +evbuffer_new(void) +{ + struct evbuffer *buffer; + + buffer = calloc(1, sizeof(struct evbuffer)); + + return (buffer); +} + +void +evbuffer_free(struct evbuffer *buffer) +{ + if (buffer->buffer != NULL) + free(buffer->buffer); + free(buffer); +} + +/* + * This is a destructive add. The data from one buffer moves into + * the other buffer. + */ + +int +evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) +{ + int res; + res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off); + if (res == 0) + evbuffer_drain(inbuf, inbuf->off); + + return (res); +} + +int +evbuffer_add_printf(struct evbuffer *buf, char *fmt, ...) +{ + int res = -1; + char *msg; + va_list ap; + + va_start(ap, fmt); + + if (vasprintf(&msg, fmt, ap) == -1) + goto end; + + res = strlen(msg); + if (evbuffer_add(buf, msg, res) == -1) + res = -1; + free(msg); + + end: + va_end(ap); + + return (res); +} + +int +evbuffer_add(struct evbuffer *buf, u_char *data, size_t datlen) +{ + size_t need = buf->off + datlen; + size_t oldoff = buf->off; + + if (buf->totallen < need) { + void *newbuf; + int length = buf->totallen; + + if (length < 256) + length = 256; + while (length < need) + length <<= 1; + + if ((newbuf = realloc(buf->buffer, length)) == NULL) + return (-1); + + buf->buffer = newbuf; + buf->totallen = length; + } + + memcpy(buf->buffer + buf->off, data, datlen); + buf->off += datlen; + + if (datlen && buf->cb != NULL) + (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); + + return (0); +} + +void +evbuffer_drain(struct evbuffer *buf, size_t len) +{ + size_t oldoff = buf->off; + + if (len >= buf->off) { + buf->off = 0; + goto done; + } + + memmove(buf->buffer, buf->buffer + len, buf->off - len); + buf->off -= len; + + done: + /* Tell someone about changes in this buffer */ + if (buf->off != oldoff && buf->cb != NULL) + (*buf->cb)(buf, oldoff, buf->off, buf->cbarg); + +} + +int +evbuffer_read(struct evbuffer *buffer, int fd, int howmuch) +{ + u_char inbuf[4096]; + int n; + + if (howmuch < 0 || howmuch > sizeof(inbuf)) + howmuch = sizeof(inbuf); + + n = read(fd, inbuf, howmuch); + if (n == -1) + return (-1); + if (n == 0) + return (0); + + evbuffer_add(buffer, inbuf, n); + + return (n); +} + +int +evbuffer_write(struct evbuffer *buffer, int fd) +{ + int n; + + n = write(fd, buffer->buffer, buffer->off); + if (n == -1) + return (-1); + if (n == 0) + return (0); + + evbuffer_drain(buffer, n); + + return (n); +} + +u_char * +evbuffer_find(struct evbuffer *buffer, u_char *what, size_t len) +{ + size_t remain = buffer->off; + u_char *search = buffer->buffer; + u_char *p; + + while ((p = memchr(search, *what, remain)) != NULL && remain >= len) { + if (memcmp(p, what, len) == 0) + return (p); + + search = p + 1; + remain = buffer->off - (size_t)(search - buffer->buffer); + } + + return (NULL); +} + +void evbuffer_setcb(struct evbuffer *buffer, + void (*cb)(struct evbuffer *, size_t, size_t, void *), + void *cbarg) +{ + buffer->cb = cb; + buffer->cbarg = cbarg; +} |