/
MudOS_0.9.19/bin/
MudOS_0.9.19/doc/concepts/
MudOS_0.9.19/doc/driver/
MudOS_0.9.19/doc/efuns/bitstrings/
MudOS_0.9.19/doc/efuns/buffers/
MudOS_0.9.19/doc/efuns/communication/
MudOS_0.9.19/doc/efuns/core/
MudOS_0.9.19/doc/efuns/mappings/
MudOS_0.9.19/doc/efuns/math/
MudOS_0.9.19/doc/efuns/security/
MudOS_0.9.19/doc/lpc/constructs/
MudOS_0.9.19/doc/lpc/types/
MudOS_0.9.19/doc/platforms/
MudOS_0.9.19/etc/
MudOS_0.9.19/mudlib/
MudOS_0.9.19/mudlib/lil/
MudOS_0.9.19/mudlib/lil/clone/
MudOS_0.9.19/mudlib/lil/command/
MudOS_0.9.19/mudlib/lil/data/
MudOS_0.9.19/mudlib/lil/etc/
MudOS_0.9.19/mudlib/lil/include/
MudOS_0.9.19/mudlib/lil/inherit/
MudOS_0.9.19/mudlib/lil/inherit/master/
MudOS_0.9.19/mudlib/lil/log/
MudOS_0.9.19/mudlib/lil/single/
MudOS_0.9.19/mudlib/lil/u/
MudOS_0.9.19/src/testsuite/
MudOS_0.9.19/src/testsuite/clone/
MudOS_0.9.19/src/testsuite/command/
MudOS_0.9.19/src/testsuite/data/
MudOS_0.9.19/src/testsuite/etc/
MudOS_0.9.19/src/testsuite/include/
MudOS_0.9.19/src/testsuite/inherit/
MudOS_0.9.19/src/testsuite/inherit/master/
MudOS_0.9.19/src/testsuite/log/
MudOS_0.9.19/src/testsuite/single/
MudOS_0.9.19/src/testsuite/single/efuns/
MudOS_0.9.19/src/testsuite/u/
/* buffer.c for MudOS 0.9.x by John Garnett, 1993/11/07 */

#include <stdio.h>
#include "config.h"
#include "buffer.h"
#include "crctab.h"
#include "lint.h"

extern int max_buffer_size;

struct buffer null_buf = {
	0,  /* size */
	1   /* Ref count, which will ensure that it will never be deallocated */
};

INLINE struct buffer *
null_buffer()
{
	null_buf.ref++;
	return &null_buf;
}

INLINE void
free_buffer(b)
struct buffer *b;
{
	b->ref--;
	/* don't try to free the null_buffer (ref count might overflow) */
	if ((b->ref > 0) || (b == &null_buf)) {
		return;
	}
	FREE((char *)b);
}

struct buffer *
allocate_buffer(size)
int size;
{
	struct buffer *buf;

#ifndef DISALLOW_BUFFER_TYPE
	if ((size < 0) || (size > max_buffer_size)) {
		error("Illegal buffer size.\n");
	}
	if (size == 0) {
		return null_buffer();
	}
	/* using calloc() so that memory will be zero'd out when allocated */
	buf = (struct buffer *)CALLOC(sizeof(struct buffer) + size - 1, 1);
	buf->size = size;
	buf->ref = 1;
	return buf;
#else
	return NULL;
#endif
}

int
write_buffer(buf, start, str, theLength)
struct buffer *buf;
char *str;
int start, theLength;
{
	int size;

	size = buf->size;
	if (start < 0) {
		start = size + start;
		if (start < 0) {
			return 0;
		}
	}
	/* can't write past the end of the buffer since we can't reallocate the
	   buffer here (no easy way to propagate back the changes to the caller
	*/
	if ((start + theLength) > size) {
		return 0;
	}
	memcpy(buf->item + start, str, theLength);
	return 1;
}

char *
read_buffer(b,start,len,rlen)
struct buffer *b;
int start,len;
int *rlen;
{
	char *str;
	int size;

	if (len < 0)
		return 0;

	size = b->size;
	if (start < 0) {
		start = size + start;
		if (start < 0) {
			return 0;
		}
	}

    if (len == 0) len = size;

	if (start >= size) {
		return 0;
    }
	if ((start + len) > size) {
		len = (size - start);
	}

    str = (char *)DXALLOC(len + 1, 42, "read_buffer: str");

	memcpy(str, b->item + start, len);

    /*
     * The string has to end to '\0'!!!
     */
    str[len] = '\0';
	if ((*rlen = strlen(str)) != len) {
		char *p;

		p = str;
		str = string_copy(p);
		*rlen = strlen(str);
		FREE(p);
	}

    return str;
}