/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* Buffer object implementation */

#include "Python.h"


typedef struct {
	PyObject_HEAD
	PyObject *b_base;
	void *b_ptr;
	int b_size;
	int b_readonly;
#ifdef CACHE_HASH
	long b_hash;
#endif
} PyBufferObject;


static PyObject *
_PyBuffer_FromMemory(base, ptr, size, readonly)
	PyObject *base;
	void *ptr;
	int size;
	int readonly;
{
	PyBufferObject * b;

	if ( size < 0 ) {
		PyErr_SetString(PyExc_ValueError,
				"size must be zero or positive");
		return NULL;
	}

	b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
	if ( b == NULL )
		return NULL;

	Py_XINCREF(base);
	b->b_base = base;
	b->b_ptr = ptr;
	b->b_size = size;
	b->b_readonly = readonly;
#ifdef CACHE_HASH
	b->b_hash = -1;
#endif

	return (PyObject *) b;
}

static PyObject *
_PyBuffer_FromObject(base, offset, size, proc, readonly)
	PyObject *base;
	int offset;
	int size;
	getreadbufferproc proc;
	int readonly;
{
	PyBufferProcs *pb = base->ob_type->tp_as_buffer;
	void *p;
	int count;

	if ( offset < 0 ) {
		PyErr_SetString(PyExc_ValueError,
				"offset must be zero or positive");
		return NULL;
	}

	if ( (*pb->bf_getsegcount)(base, NULL) != 1 )
	{
		PyErr_SetString(PyExc_TypeError,
				"single-segment buffer object expected");
		return NULL;
	}
	if ( (count = (*proc)(base, 0, &p)) < 0 )
		return NULL;

	/* apply constraints to the start/end */
	if ( size == Py_END_OF_BUFFER || size < 0 )
		size = count;
	if ( offset > count )
		offset = count;
	if ( offset + size > count )
		size = count - offset;

	/* if the base object is another buffer, then "deref" it */
	if ( PyBuffer_Check(base) )
		base = ((PyBufferObject *)base)->b_base;

	return _PyBuffer_FromMemory(base, (char *)p + offset, size, readonly);
}


PyObject *
PyBuffer_FromObject(base, offset, size)
	PyObject *base;
	int offset;
	int size;
{
	PyBufferProcs *pb = base->ob_type->tp_as_buffer;

	if ( pb == NULL ||
	     pb->bf_getreadbuffer == NULL ||
	     pb->bf_getsegcount == NULL )
	{
		PyErr_SetString(PyExc_TypeError, "buffer object expected");
		return NULL;
	}

	return _PyBuffer_FromObject(base, offset, size,
				    pb->bf_getreadbuffer, 1);
}

PyObject *
PyBuffer_FromReadWriteObject(base, offset, size)
	PyObject *base;
	int offset;
	int size;
{
	PyBufferProcs *pb = base->ob_type->tp_as_buffer;

	if ( pb == NULL ||
	     pb->bf_getwritebuffer == NULL ||
	     pb->bf_getsegcount == NULL )
	{
		PyErr_SetString(PyExc_TypeError, "buffer object expected");
		return NULL;
	}

	return _PyBuffer_FromObject(base, offset, size,
				    (getreadbufferproc)pb->bf_getwritebuffer,
				    0);
}

PyObject *
PyBuffer_FromMemory(ptr, size)
	void *ptr;
	int size;
{
	return _PyBuffer_FromMemory(NULL, ptr, size, 1);
}

PyObject *
PyBuffer_FromReadWriteMemory(ptr, size)
	void *ptr;
	int size;
{
	return _PyBuffer_FromMemory(NULL, ptr, size, 0);
}

PyObject *
PyBuffer_New(size)
	int size;
{
	PyBufferObject * b;

	if (size < 0) {
		PyErr_SetString(PyExc_ValueError,
				"size must be zero or positive");
		return NULL;
	}
	b = (PyBufferObject *)malloc(sizeof(*b) + size);
	if ( b == NULL )
		return PyErr_NoMemory();
	b->ob_type = &PyBuffer_Type;
	_Py_NewReference((PyObject *)b);

	b->b_base = NULL;
	b->b_ptr = (void *)(b + 1);
	b->b_size = size;
	b->b_readonly = 0;
#ifdef CACHE_HASH
	b->b_hash = -1;
#endif

	return (PyObject *) b;
}

/* Methods */

static void
buffer_dealloc(self)
	PyBufferObject *self;
{
	Py_XDECREF(self->b_base);
	free((void *)self);
}

static int
buffer_compare(self, other)
	PyBufferObject *self;
	PyBufferObject *other;
{
	int len_self = self->b_size;
	int len_other = other->b_size;
	int min_len = (len_self < len_other) ? len_self : len_other;
	int cmp;
	if (min_len > 0) {
		cmp = memcmp(self->b_ptr, other->b_ptr, min_len);
		if (cmp != 0)
			return cmp;
	}
	return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
}

static PyObject *
buffer_repr(self)
	PyBufferObject *self;
{
	char buf[300];
	char *status = self->b_readonly ? "read-only" : "read-write";

	if ( self->b_base == NULL )
	{
		sprintf(buf, "<%s buffer ptr %lx, size %d at %lx>",
			status,
			(long)self->b_ptr,
			self->b_size,
			(long)self);
	}
	else
	{
		sprintf(buf, "<%s buffer for %lx, ptr %lx, size %d at %lx>",
			status,
			(long)self->b_base,
			(long)self->b_ptr,
			self->b_size,
			(long)self);
	}

	return PyString_FromString(buf);
}

static long
buffer_hash(self)
	PyBufferObject *self;
{
	register int len;
	register unsigned char *p;
	register long x;

#ifdef CACHE_HASH
	if ( self->b_hash != -1 )
		return self->b_hash;
#endif

	if ( !self->b_readonly )
	{
		/* ### use different wording, since this is conditional? */
		PyErr_SetString(PyExc_TypeError, "unhashable type");
		return -1;
	}

	len = self->b_size;
	p = (unsigned char *) self->b_ptr;
	x = *p << 7;
	while (--len >= 0)
		x = (1000003*x) ^ *p++;
	x ^= self->b_size;
	if (x == -1)
		x = -2;
#ifdef CACHE_HASH
	self->b_hash = x;
#endif
	return x;
}

static PyObject *
buffer_str(self)
	PyBufferObject *self;
{
	return PyString_FromStringAndSize(self->b_ptr, self->b_size);
}

/* Sequence methods */

static int
buffer_length(self)
	PyBufferObject *self;
{
	return self->b_size;
}

static PyObject *
buffer_concat(self, other)
	PyBufferObject *self;
	PyObject *other;
{
	PyBufferProcs *pb = other->ob_type->tp_as_buffer;
	char *p1;
	void *p2;
	PyObject *ob;
	int count;

	if ( pb == NULL ||
	     pb->bf_getreadbuffer == NULL ||
	     pb->bf_getsegcount == NULL )
	{
		PyErr_BadArgument();
		return NULL;
	}
	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
	{
		/* ### use a different exception type/message? */
		PyErr_SetString(PyExc_TypeError,
				"single-segment buffer object expected");
		return NULL;
	}

	/* optimize special case */
	if ( self->b_size == 0 )
	{
	    Py_INCREF(other);
	    return other;
	}

	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &p2)) < 0 )
		return NULL;

	/* optimize special case */
	if ( count == 0 )
	{
	    Py_INCREF(self);
	    return (PyObject *)self;
	}

	ob = PyString_FromStringAndSize(NULL, self->b_size + count);
	p1 = PyString_AS_STRING(ob);
	memcpy(p1, self->b_ptr, self->b_size);
	memcpy(p1 + self->b_size, p2, count);

	/* there is an extra byte in the string object, so this is safe */
	p1[self->b_size + count] = '\0';

	return ob;
}

static PyObject *
buffer_repeat(self, count)
	PyBufferObject *self;
	int count;
{
	PyObject *ob;
	register char *p;
	void *ptr = self->b_ptr;
	int size = self->b_size;

	if ( count < 0 )
		count = 0;
	ob = PyString_FromStringAndSize(NULL, size * count);
	if ( ob == NULL )
		return NULL;

	p = PyString_AS_STRING(ob);
	while ( count-- )
	{
	    memcpy(p, ptr, size);
	    p += size;
	}

	/* there is an extra byte in the string object, so this is safe */
	*p = '\0';

	return ob;
}

static PyObject *
buffer_item(self, idx)
	PyBufferObject *self;
	int idx;
{
	if ( idx < 0 || idx >= self->b_size )
	{
		PyErr_SetString(PyExc_IndexError, "buffer index out of range");
		return NULL;
	}
	return PyString_FromStringAndSize((char *)self->b_ptr + idx, 1);
}

static PyObject *
buffer_slice(self, left, right)
	PyBufferObject *self;
	int left;
	int right;
{
	if ( left < 0 )
		left = 0;
	if ( right < 0 )
		right = 0;
	if ( right > self->b_size )
		right = self->b_size;
	if ( left == 0 && right == self->b_size )
	{
		/* same as self */
		Py_INCREF(self);
		return (PyObject *)self;
	}
	if ( right < left )
		right = left;
	return PyString_FromStringAndSize((char *)self->b_ptr + left,
					  right - left);
}

static int
buffer_ass_item(self, idx, other)
	PyBufferObject *self;
	int idx;
	PyObject *other;
{
	PyBufferProcs *pb;
	void *p;
	int count;

	if ( self->b_readonly ) {
		PyErr_SetString(PyExc_TypeError,
				"buffer is read-only");
		return -1;
	}

	if (idx < 0 || idx >= self->b_size) {
		PyErr_SetString(PyExc_IndexError,
				"buffer assignment index out of range");
		return -1;
	}

	pb = other ? other->ob_type->tp_as_buffer : NULL;
	if ( pb == NULL ||
	     pb->bf_getreadbuffer == NULL ||
	     pb->bf_getsegcount == NULL )
	{
		PyErr_BadArgument();
		return -1;
	}
	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
	{
		/* ### use a different exception type/message? */
		PyErr_SetString(PyExc_TypeError,
				"single-segment buffer object expected");
		return -1;
	}

	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &p)) < 0 )
		return -1;
	if ( count != 1 ) {
		PyErr_SetString(PyExc_TypeError,
				"right operand must be a single byte");
		return -1;
	}

	((char *)self->b_ptr)[idx] = *(char *)p;
	return 0;
}

static int
buffer_ass_slice(self, left, right, other)
	PyBufferObject *self;
	int left;
	int right;
	PyObject *other;
{
	PyBufferProcs *pb;
	void *p;
	int slice_len;
	int count;

	if ( self->b_readonly ) {
		PyErr_SetString(PyExc_TypeError,
				"buffer is read-only");
		return -1;
	}

	pb = other ? other->ob_type->tp_as_buffer : NULL;
	if ( pb == NULL ||
	     pb->bf_getreadbuffer == NULL ||
	     pb->bf_getsegcount == NULL )
	{
		PyErr_BadArgument();
		return -1;
	}
	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
	{
		/* ### use a different exception type/message? */
		PyErr_SetString(PyExc_TypeError,
				"single-segment buffer object expected");
		return -1;
	}
	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &p)) < 0 )
		return -1;

	if ( left < 0 )
		left = 0;
	else if ( left > self->b_size )
		left = self->b_size;
	if ( right < left )
		right = left;
	else if ( right > self->b_size )
		right = self->b_size;
	slice_len = right - left;

	if ( count != slice_len ) {
		PyErr_SetString(
			PyExc_TypeError,
			"right operand length must match slice length");
		return -1;
	}

	if ( slice_len )
	    memcpy((char *)self->b_ptr + left, p, slice_len);

	return 0;
}

/* Buffer methods */

static int
buffer_getreadbuf(self, idx, pp)
	PyBufferObject *self;
	int idx;
	void ** pp;
{
	if ( idx != 0 ) {
		PyErr_SetString(PyExc_SystemError,
				"accessing non-existent buffer segment");
		return -1;
	}
	*pp = self->b_ptr;
	return self->b_size;
}

static int
buffer_getwritebuf(self, idx, pp)
	PyBufferObject *self;
	int idx;
	void ** pp;
{
	if ( self->b_readonly )
	{
		PyErr_SetString(PyExc_TypeError, "buffer is read-only");
		return -1;
	}
	return buffer_getreadbuf(self, idx, pp);
}

static int
buffer_getsegcount(self, lenp)
	PyBufferObject *self;
	int *lenp;
{
	if ( lenp )
		*lenp = self->b_size;
	return 1;
}

static int
buffer_getcharbuf(self, idx, pp)
	PyBufferObject *self;
	int idx;
	const char ** pp;
{
	if ( idx != 0 ) {
		PyErr_SetString(PyExc_SystemError,
				"accessing non-existent buffer segment");
		return -1;
	}
	*pp = (const char *)self->b_ptr;
	return self->b_size;
}


static PySequenceMethods buffer_as_sequence = {
	(inquiry)buffer_length, /*sq_length*/
	(binaryfunc)buffer_concat, /*sq_concat*/
	(intargfunc)buffer_repeat, /*sq_repeat*/
	(intargfunc)buffer_item, /*sq_item*/
	(intintargfunc)buffer_slice, /*sq_slice*/
	(intobjargproc)buffer_ass_item, /*sq_ass_item*/
	(intintobjargproc)buffer_ass_slice, /*sq_ass_slice*/
};

static PyBufferProcs buffer_as_buffer = {
	(getreadbufferproc)buffer_getreadbuf,
	(getwritebufferproc)buffer_getwritebuf,
	(getsegcountproc)buffer_getsegcount,
	(getcharbufferproc)buffer_getcharbuf,
};

PyTypeObject PyBuffer_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,
	"buffer",
	sizeof(PyBufferObject),
	0,
	(destructor)buffer_dealloc, /*tp_dealloc*/
	0,		/*tp_print*/
	0,		/*tp_getattr*/
	0,		/*tp_setattr*/
	(cmpfunc)buffer_compare, /*tp_compare*/
	(reprfunc)buffer_repr, /*tp_repr*/
	0,		/*tp_as_number*/
	&buffer_as_sequence,	/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
	(hashfunc)buffer_hash,	/*tp_hash*/
	0,		/*tp_call*/
	(reprfunc)buffer_str,		/*tp_str*/
	0,		/*tp_getattro*/
	0,		/*tp_setattro*/
	&buffer_as_buffer,	/*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT,	/*tp_flags*/
	0,		/*tp_doc*/
};

