/
vortex/area/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>  
#include "merc.h"

#define EMEM_SIZE -1 /* find_mem_size returns this when block is too large */
#define NUL '\0'
#define MSL MAX_STRING_LENGTH
extern const int rgSizeList [MAX_MEM_LIST];

/* Find in rgSizeList a memory size at least this long */
int find_mem_size (int min_size)
{
	int i;
	
	for (i = 0; i < MAX_MEM_LIST; i++)
		if (rgSizeList[i] >= min_size)
			return rgSizeList[i];
	
	/* min_size is bigger than biggest allowable size! */
	
	return EMEM_SIZE;
}

/* Create a new buffer, of at least size bytes */

BUFFER * __buffer_new (int min_size)
{
	int size;
	BUFFER *buffer;
	char buf[200]; /* for the bug line */
	
	size = find_mem_size (min_size);
	
	if (size == EMEM_SIZE)
	{
		sprintf (buf, "Buffer size too big: %d bytes.", min_size);
		bug (buf,0);
		abort();
	}
	
	buffer = alloc_mem (sizeof(BUFFER));
	
	buffer->size = size;
	buffer->data = alloc_mem (size);
	buffer->overflowed = FALSE;
	
	buffer->len = 0;
	
	return buffer;
} /* __buf_new */

/* Add a string to a buffer. Expand if necessary */

void __buffer_strcat (BUFFER *buffer, const char *text)
{
	int new_size;
	int text_len;
	char *new_data;
	char buf[200];
	
	if (buffer->overflowed) /* Do not attempt to add anymore if buffer is already overflowed */
		return;

	if (!text) /* Adding NULL string ? */
		return;
	
	text_len = strlen(text);
	
	if (text_len == 0) /* Adding empty string ? */
		return;
		
	/* Will the combined len of the added text and the current text exceed our buffer? */

	if ((text_len+buffer->len+1) > buffer->size) /* expand? */
	{
		new_size = find_mem_size (buffer->size + text_len + 1);
		if (new_size == EMEM_SIZE) /* New size too big ? */
		{
			sprintf (buf, "Buffer overflow, wanted %d bytes.",text_len+buffer->len);			
			bug (buf, 0);
			buffer->overflowed = TRUE;
			return;
		}

		/* Allocate the new buffer */
		
		new_data = alloc_mem (new_size);		
		
		/* Copy the current buffer to the new buffer */
		
		memcpy (new_data, buffer->data, buffer->len);
		free_mem (buffer->data, buffer->size);
		buffer->data = new_data;
		buffer->size = new_size;

	} /* if */

	memcpy (buffer->data + buffer->len, text, text_len);	/* Start copying */
	buffer->len += text_len;	/* Adjust length */
	buffer->data[buffer->len] = NUL; /* Null-terminate at new end */
	
} /* __buf_strcat */

/* Free a buffer */
void buffer_free (BUFFER *buffer)
{
	/* Free data */
	free_mem (buffer->data, buffer->size);
	
	/* Free buffer */
	
	free_mem (buffer, sizeof(BUFFER));
}

/* Clear a buffer's contents, but do not deallocate anything */

void buffer_clear (BUFFER *buffer)
{
	buffer->overflowed = FALSE;
	buffer->len = 0;
        buffer->data[0] = '\0';
}

/* print stuff, append to buffer. safe. */
int bprintf (BUFFER *buffer, char *fmt, ...)
{
	char buf[MSL];
	va_list va;
	int res;
	
	va_start (va, fmt);
	res = vsnprintf (buf, MSL, fmt, va);
	va_end (va);

	if (res >= MSL-1)	
	{
		buf[0] = NUL;
		sprintf(buf,"Overflow when printing string %s",fmt);
                bug(buf,0);
                buf[0] = NUL;
	}
	else
		buffer_strcat (buffer, buf);

	return res;	
}