From d4a8b7e34dd619a4debf9a206c81db26d1402ea6 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 27 Oct 1999 13:42:43 +1000 Subject: Initial revision --- buffer.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 buffer.c (limited to 'buffer.c') diff --git a/buffer.c b/buffer.c new file mode 100644 index 00000000..e183d101 --- /dev/null +++ b/buffer.c @@ -0,0 +1,150 @@ +/* + +buffer.c + +Author: Tatu Ylonen + +Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + All rights reserved + +Created: Sat Mar 18 04:15:33 1995 ylo + +Functions for manipulating fifo buffers (that can grow if needed). + +*/ + +#include "includes.h" +RCSID("$Id: buffer.c,v 1.1 1999/10/27 03:42:43 damien Exp $"); + +#include "xmalloc.h" +#include "buffer.h" +#include "ssh.h" + +/* Initializes the buffer structure. */ + +void buffer_init(Buffer *buffer) +{ + buffer->alloc = 4096; + buffer->buf = xmalloc(buffer->alloc); + buffer->offset = 0; + buffer->end = 0; +} + +/* Frees any memory used for the buffer. */ + +void buffer_free(Buffer *buffer) +{ + memset(buffer->buf, 0, buffer->alloc); + xfree(buffer->buf); +} + +/* Clears any data from the buffer, making it empty. This does not actually + zero the memory. */ + +void buffer_clear(Buffer *buffer) +{ + buffer->offset = 0; + buffer->end = 0; +} + +/* Appends data to the buffer, expanding it if necessary. */ + +void buffer_append(Buffer *buffer, const char *data, unsigned int len) +{ + char *cp; + buffer_append_space(buffer, &cp, len); + memcpy(cp, data, len); +} + +/* Appends space to the buffer, expanding the buffer if necessary. + This does not actually copy the data into the buffer, but instead + returns a pointer to the allocated region. */ + +void buffer_append_space(Buffer *buffer, char **datap, unsigned int len) +{ + /* If the buffer is empty, start using it from the beginning. */ + if (buffer->offset == buffer->end) + { + buffer->offset = 0; + buffer->end = 0; + } + + restart: + /* If there is enough space to store all data, store it now. */ + if (buffer->end + len < buffer->alloc) + { + *datap = buffer->buf + buffer->end; + buffer->end += len; + return; + } + + /* If the buffer is quite empty, but all data is at the end, move the + data to the beginning and retry. */ + if (buffer->offset > buffer->alloc / 2) + { + memmove(buffer->buf, buffer->buf + buffer->offset, + buffer->end - buffer->offset); + buffer->end -= buffer->offset; + buffer->offset = 0; + goto restart; + } + + /* Increase the size of the buffer and retry. */ + buffer->alloc += len + 32768; + buffer->buf = xrealloc(buffer->buf, buffer->alloc); + goto restart; +} + +/* Returns the number of bytes of data in the buffer. */ + +unsigned int buffer_len(Buffer *buffer) +{ + return buffer->end - buffer->offset; +} + +/* Gets data from the beginning of the buffer. */ + +void buffer_get(Buffer *buffer, char *buf, unsigned int len) +{ + if (len > buffer->end - buffer->offset) + fatal("buffer_get trying to get more bytes than in buffer"); + memcpy(buf, buffer->buf + buffer->offset, len); + buffer->offset += len; +} + +/* Consumes the given number of bytes from the beginning of the buffer. */ + +void buffer_consume(Buffer *buffer, unsigned int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_get trying to get more bytes than in buffer"); + buffer->offset += bytes; +} + +/* Consumes the given number of bytes from the end of the buffer. */ + +void buffer_consume_end(Buffer *buffer, unsigned int bytes) +{ + if (bytes > buffer->end - buffer->offset) + fatal("buffer_get trying to get more bytes than in buffer"); + buffer->end -= bytes; +} + +/* Returns a pointer to the first used byte in the buffer. */ + +char *buffer_ptr(Buffer *buffer) +{ + return buffer->buf + buffer->offset; +} + +/* Dumps the contents of the buffer to stderr. */ + +void buffer_dump(Buffer *buffer) +{ + int i; + unsigned char *ucp = (unsigned char *)buffer->buf; + + for (i = buffer->offset; i < buffer->end; i++) + fprintf(stderr, " %02x", ucp[i]); + fprintf(stderr, "\n"); +} -- cgit v1.2.3