/* $Id: buffer.c 5463 2002-05-06 05:40:46Z rra $
**
** Counted, reusable memory buffer.
**
** A buffer is an allocated bit of memory with a known size and a separate
** data length. It's intended to store strings and can be reused repeatedly
** to minimize the number of memory allocations. Buffers increase in
** increments of 1K.
**
** A buffer contains a notion of the data that's been used and the data
** that's been left, used when the buffer is an I/O buffer where lots of data
** is buffered and then slowly processed out of the buffer. The total length
** of the data is used + left. If a buffer is just used to store some data,
** used can be set to 0 and left stores the length of the data.
*/
#include "config.h"
#include "clibrary.h"
#include "inn/buffer.h"
#include "libinn.h"
/*
** Allocate a new struct buffer and initialize it.
*/
struct buffer *
buffer_new(void)
{
struct buffer *buffer;
buffer = xmalloc(sizeof(struct buffer));
buffer->size = 0;
buffer->used = 0;
buffer->left = 0;
buffer->data = NULL;
return buffer;
}
/*
** Resize a buffer to be at least as large as the provided second argument.
** Resize buffers to multiples of 1KB to keep the number of reallocations to
** a minimum. Refuse to resize a buffer to make it smaller.
*/
void
buffer_resize(struct buffer *buffer, size_t size)
{
if (size < buffer->size)
return;
buffer->size = (size + 1023) & ~1023UL;
buffer->data = xrealloc(buffer->data, buffer->size);
}
/*
** Replace whatever data is currently in the buffer with the provided data.
*/
void
buffer_set(struct buffer *buffer, const char *data, size_t length)
{
if (length > 0) {
buffer_resize(buffer, length);
memmove(buffer->data, data, length);
}
buffer->left = length;
buffer->used = 0;
}
/*
** Append data to a buffer. The new data shows up as additional unused data
** at the end of the buffer. Resize the buffer to multiples of 1KB.
*/
void
buffer_append(struct buffer *buffer, const char *data, size_t length)
{
size_t total;
if (length == 0)
return;
total = buffer->used + buffer->left;
buffer_resize(buffer, total + length);
buffer->left += length;
memcpy(buffer->data + total, data, length);
}
/*
** Swap the contents of two buffers.
*/
void
buffer_swap(struct buffer *one, struct buffer *two)
{
struct buffer tmp;
tmp = *one;
*one = *two;
*two = tmp;
}
syntax highlighted by Code2HTML, v. 0.9.1