
/* Memoryview object implementation */

#include "Python.h"

static void
dup_buffer(Py_buffer *dest, Py_buffer *src)
{
	*dest = *src;
        if (src->shape == &(src->len))
            dest->shape = &(dest->len);
        if (src->strides == &(src->itemsize))
            dest->strides = &(dest->itemsize);
}

static int
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
	int res = 0;
	/* XXX for whatever reason fixing the flags seems necessary */
	if (self->view.readonly)
		flags &= ~PyBUF_WRITABLE;
	if (self->view.obj != NULL)
		res = PyObject_GetBuffer(self->view.obj, view, flags);
	if (view)
		dup_buffer(view, &self->view);
	return res;
}

static void
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
{
	PyBuffer_Release(view);
}

PyDoc_STRVAR(memory_doc,
"memoryview(object)\n\
\n\
Create a new memoryview object which references the given object.");

PyObject *
PyMemoryView_FromBuffer(Py_buffer *info)
{
	PyMemoryViewObject *mview;

	mview = (PyMemoryViewObject *)
		PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
	if (mview == NULL)
		return NULL;
	mview->base = NULL;
	dup_buffer(&mview->view, info);
        /* NOTE: mview->view.obj should already have been incref'ed as
           part of PyBuffer_FillInfo(). */
	_PyObject_GC_TRACK(mview);
	return (PyObject *)mview;
}

PyObject *
PyMemoryView_FromObject(PyObject *base)
{
        PyMemoryViewObject *mview;

        if (!PyObject_CheckBuffer(base)) {
                PyErr_SetString(PyExc_TypeError,
                                "cannot make memory view because object does "
                                "not have the buffer interface");
                return NULL;
        }

	mview = (PyMemoryViewObject *)
		PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
        if (mview == NULL)
		return NULL;

        mview->base = NULL;
        if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL_RO) < 0) {
                Py_DECREF(mview);
                return NULL;
        }

        mview->base = base;
        Py_INCREF(base);
	_PyObject_GC_TRACK(mview);
        return (PyObject *)mview;
}

static PyObject *
memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
	PyObject *obj;
	static char *kwlist[] = {"object", 0};

	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
					 &obj)) {
		return NULL;
	}

	return PyMemoryView_FromObject(obj);
}


static void
_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
                 Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
{
        int k;
        Py_ssize_t outstride;

        if (nd==0) {
                memcpy(dest, src, itemsize);
        }
        else if (nd == 1) {
                for (k = 0; k<shape[0]; k++) {
                        memcpy(dest, src, itemsize);
                        dest += itemsize;
                        src += strides[0];
                }
        }
        else {
                if (fort == 'F') {
                        /* Copy first dimension first,
                           second dimension second, etc...
                           Set up the recursive loop backwards so that final
                           dimension is actually copied last.
                        */
                        outstride = itemsize;
                        for (k=1; k<nd-1;k++) {
                                outstride *= shape[k];
                        }
                        for (k=0; k<shape[nd-1]; k++) {
                                _strided_copy_nd(dest, src, nd-1, shape,
                                                 strides, itemsize, fort);
                                dest += outstride;
                                src += strides[nd-1];
                        }
                }

                else {
                        /* Copy last dimension first,
                           second-to-last dimension second, etc.
                           Set up the recursion so that the
                           first dimension is copied last
                        */
                        outstride = itemsize;
                        for (k=1; k < nd; k++) {
                                outstride *= shape[k];
                        }
                        for (k=0; k<shape[0]; k++) {
                                _strided_copy_nd(dest, src, nd-1, shape+1,
                                                 strides+1, itemsize,
                                                 fort);
                                dest += outstride;
                                src += strides[0];
                        }
                }
        }
        return;
}

void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);

static int
_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
{
        Py_ssize_t *indices;
        int k;
        Py_ssize_t elements;
        char *ptr;
        void (*func)(int, Py_ssize_t *, Py_ssize_t *);

        if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
                PyErr_NoMemory();
                return -1;
        }

        indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
        if (indices == NULL) {
                PyErr_NoMemory();
                return -1;
        }
        for (k=0; k<view->ndim;k++) {
                indices[k] = 0;
        }

        elements = 1;
        for (k=0; k<view->ndim; k++) {
                elements *= view->shape[k];
        }
        if (fort == 'F') {
                func = _add_one_to_index_F;
        }
        else {
                func = _add_one_to_index_C;
        }
        while (elements--) {
                func(view->ndim, indices, view->shape);
                ptr = PyBuffer_GetPointer(view, indices);
                memcpy(dest, ptr, view->itemsize);
                dest += view->itemsize;
        }

        PyMem_Free(indices);
        return 0;
}

/*
   Get a the data from an object as a contiguous chunk of memory (in
   either 'C' or 'F'ortran order) even if it means copying it into a
   separate memory area.

   Returns a new reference to a Memory view object.  If no copy is needed,
   the memory view object points to the original memory and holds a
   lock on the original.  If a copy is needed, then the memory view object
   points to a brand-new Bytes object (and holds a memory lock on it).

   buffertype

   PyBUF_READ  buffer only needs to be read-only
   PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
   PyBUF_SHADOW buffer needs to be writable so shadow it with
                a contiguous buffer if it is not. The view will point to
                the shadow buffer which can be written to and then
                will be copied back into the other buffer when the memory
                view is de-allocated.  While the shadow buffer is
		being used, it will have an exclusive write lock on
		the original buffer.
 */

PyObject *
PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
{
        PyMemoryViewObject *mem;
        PyObject *bytes;
        Py_buffer *view;
        int flags;
        char *dest;

        if (!PyObject_CheckBuffer(obj)) {
                PyErr_SetString(PyExc_TypeError,
                                "object does not have the buffer interface");
                return NULL;
        }

        mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
        if (mem == NULL)
		return NULL;

        view = &mem->view;
        flags = PyBUF_FULL_RO;
        switch(buffertype) {
        case PyBUF_WRITE:
                flags = PyBUF_FULL;
                break;
        }

        if (PyObject_GetBuffer(obj, view, flags) != 0) {
                Py_DECREF(mem);
                return NULL;
        }

        if (PyBuffer_IsContiguous(view, fort)) {
                /* no copy needed */
                Py_INCREF(obj);
                mem->base = obj;
		_PyObject_GC_TRACK(mem);
                return (PyObject *)mem;
        }
        /* otherwise a copy is needed */
        if (buffertype == PyBUF_WRITE) {
                Py_DECREF(mem);
                PyErr_SetString(PyExc_BufferError,
                                "writable contiguous buffer requested "
                                "for a non-contiguousobject.");
                return NULL;
        }
        bytes = PyBytes_FromStringAndSize(NULL, view->len);
        if (bytes == NULL) {
                Py_DECREF(mem);
                return NULL;
        }
        dest = PyBytes_AS_STRING(bytes);
        /* different copying strategy depending on whether
           or not any pointer de-referencing is needed
        */
        /* strided or in-direct copy */
        if (view->suboffsets==NULL) {
                _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
                                 view->strides, view->itemsize, fort);
        }
        else {
                if (_indirect_copy_nd(dest, view, fort) < 0) {
                        Py_DECREF(bytes);
			Py_DECREF(mem);
                        return NULL;
                }
        }
        if (buffertype == PyBUF_SHADOW) {
                /* return a shadowed memory-view object */
                view->buf = dest;
                mem->base = PyTuple_Pack(2, obj, bytes);
                Py_DECREF(bytes);
		if (mem->base == NULL) {
			Py_DECREF(mem);
			return NULL;
		}
        }
        else {
                PyBuffer_Release(view);  /* XXX ? */
                /* steal the reference */
                mem->base = bytes;
        }
	_PyObject_GC_TRACK(mem);
        return (PyObject *)mem;
}


static PyObject *
memory_format_get(PyMemoryViewObject *self)
{
        return PyUnicode_FromString(self->view.format);
}

static PyObject *
memory_itemsize_get(PyMemoryViewObject *self)
{
        return PyLong_FromSsize_t(self->view.itemsize);
}

static PyObject *
_IntTupleFromSsizet(int len, Py_ssize_t *vals)
{
        int i;
        PyObject *o;
        PyObject *intTuple;

        if (vals == NULL) {
                Py_INCREF(Py_None);
                return Py_None;
        }
        intTuple = PyTuple_New(len);
        if (!intTuple) return NULL;
        for(i=0; i<len; i++) {
                o = PyLong_FromSsize_t(vals[i]);
                if (!o) {
                        Py_DECREF(intTuple);
                        return NULL;
                }
                PyTuple_SET_ITEM(intTuple, i, o);
        }
        return intTuple;
}

static PyObject *
memory_shape_get(PyMemoryViewObject *self)
{
        return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
}

static PyObject *
memory_strides_get(PyMemoryViewObject *self)
{
        return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
}

static PyObject *
memory_suboffsets_get(PyMemoryViewObject *self)
{
        return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
}

static PyObject *
memory_readonly_get(PyMemoryViewObject *self)
{
        return PyBool_FromLong(self->view.readonly);
}

static PyObject *
memory_ndim_get(PyMemoryViewObject *self)
{
        return PyLong_FromLong(self->view.ndim);
}

static PyGetSetDef memory_getsetlist[] ={
        {"format",	(getter)memory_format_get,	NULL, NULL},
        {"itemsize",	(getter)memory_itemsize_get,	NULL, NULL},
        {"shape",	(getter)memory_shape_get,	NULL, NULL},
        {"strides",	(getter)memory_strides_get,	NULL, NULL},
        {"suboffsets",	(getter)memory_suboffsets_get,	NULL, NULL},
        {"readonly",	(getter)memory_readonly_get,	NULL, NULL},
        {"ndim",	(getter)memory_ndim_get,	NULL, NULL},
        {NULL, NULL, NULL, NULL},
};


static PyObject *
memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
{
	return PyObject_CallFunctionObjArgs(
		(PyObject *) &PyBytes_Type, mem, NULL);
}

/* TODO: rewrite this function using the struct module to unpack
   each buffer item */

static PyObject *
memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
{
	Py_buffer *view = &(mem->view);
	Py_ssize_t i;
	PyObject *res, *item;
	char *buf;

	if (strcmp(view->format, "B") || view->itemsize != 1) {
		PyErr_SetString(PyExc_NotImplementedError, 
			"tolist() only supports byte views");
		return NULL;
	}
	if (view->ndim != 1) {
		PyErr_SetString(PyExc_NotImplementedError, 
			"tolist() only supports one-dimensional objects");
		return NULL;
	}
	res = PyList_New(view->len);
	if (res == NULL)
		return NULL;
	buf = view->buf;
	for (i = 0; i < view->len; i++) {
		item = PyLong_FromUnsignedLong((unsigned char) *buf);
		if (item == NULL) {
			Py_DECREF(res);
			return NULL;
		}
		PyList_SET_ITEM(res, i, item);
		buf++;
	}
	return res;
}



static PyMethodDef memory_methods[] = {
        {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
        {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
        {NULL,          NULL}           /* sentinel */
};


static void
memory_dealloc(PyMemoryViewObject *self)
{
	_PyObject_GC_UNTRACK(self);
        if (self->view.obj != NULL) {
            if (self->base && PyTuple_Check(self->base)) {
                /* Special case when first element is generic object
                   with buffer interface and the second element is a
                   contiguous "shadow" that must be copied back into
                   the data areay of the first tuple element before
                   releasing the buffer on the first element.
                */

                PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
                                  PyTuple_GET_ITEM(self->base,1));

                /* The view member should have readonly == -1 in
                   this instance indicating that the memory can
                   be "locked" and was locked and will be unlocked
                   again after this call.
                */
                PyBuffer_Release(&(self->view));
            }
            else {
                PyBuffer_Release(&(self->view));
            }
            Py_CLEAR(self->base);
        }
	PyObject_GC_Del(self);
}

static PyObject *
memory_repr(PyMemoryViewObject *self)
{
	return PyUnicode_FromFormat("<memory at %p>", self);
}


static PyObject *
memory_str(PyMemoryViewObject *self)
{
        Py_buffer view;
        PyObject *res;

        if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
                return NULL;

	res = PyBytes_FromStringAndSize(NULL, view.len);
        PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
        PyBuffer_Release(&view);
        return res;
}

/* Sequence methods */

static Py_ssize_t
memory_length(PyMemoryViewObject *self)
{
        Py_buffer view;

        if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
                return -1;
        PyBuffer_Release(&view);
	return view.len;
}

/*
  mem[obj] returns a bytes object holding the data for one element if
           obj fully indexes the memory view or another memory-view object
	   if it does not.

	   0-d memory-view objects can be referenced using ... or () but
	   not with anything else.
 */
static PyObject *
memory_subscript(PyMemoryViewObject *self, PyObject *key)
{
	Py_buffer *view;
	view = &(self->view);

	if (view->ndim == 0) {
		if (key == Py_Ellipsis ||
		    (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
			Py_INCREF(self);
			return (PyObject *)self;
		}
		else {
			PyErr_SetString(PyExc_IndexError,
                                        "invalid indexing of 0-dim memory");
			return NULL;
		}
	}
	if (PyIndex_Check(key)) {
		Py_ssize_t result;
		result = PyNumber_AsSsize_t(key, NULL);
		if (result == -1 && PyErr_Occurred())
			return NULL;
		if (view->ndim == 1) {
			/* Return a bytes object */
			char *ptr;
			ptr = (char *)view->buf;
			if (result < 0) {
				result += view->shape[0];
			}
			if ((result < 0) || (result >= view->shape[0])) {
				PyErr_SetString(PyExc_IndexError,
						"index out of bounds");
				return NULL;
			}
			if (view->strides == NULL)
				ptr += view->itemsize * result;
			else
				ptr += view->strides[0] * result;
			if (view->suboffsets != NULL &&
                            view->suboffsets[0] >= 0)
                        {
				ptr = *((char **)ptr) + view->suboffsets[0];
			}
			return PyBytes_FromStringAndSize(ptr, view->itemsize);
		}
		else {
			/* Return a new memory-view object */
			Py_buffer newview;
			memset(&newview, 0, sizeof(newview));
			/* XXX:  This needs to be fixed so it
			         actually returns a sub-view
			*/
			return PyMemoryView_FromBuffer(&newview);
		}
	}
	else if (PySlice_Check(key)) {
		Py_ssize_t start, stop, step, slicelength;

		if (PySlice_GetIndicesEx((PySliceObject*)key, view->len,
				 &start, &stop, &step, &slicelength) < 0) {
			return NULL;
		}

		if (step == 1 && view->ndim == 1) {
			Py_buffer newview;
			void *newbuf = (char *) view->buf
						+ start * view->itemsize;
			int newflags = view->readonly
				? PyBUF_CONTIG_RO : PyBUF_CONTIG;

			/* XXX There should be an API to create a subbuffer */
			if (view->obj != NULL) {
				if (PyObject_GetBuffer(view->obj,
						&newview, newflags) == -1)
					return NULL;
			}
			else {
				newview = *view;
			}
			newview.buf = newbuf;
			newview.len = slicelength;
			newview.format = view->format;
			if (view->shape == &(view->len))
				newview.shape = &(newview.len);
			if (view->strides == &(view->itemsize))
				newview.strides = &(newview.itemsize);
			return PyMemoryView_FromBuffer(&newview);
		}
		PyErr_SetNone(PyExc_NotImplementedError);
		return NULL;
	}
	PyErr_Format(PyExc_TypeError,
		"cannot index memory using \"%.200s\"", 
		key->ob_type->tp_name);
	return NULL;
}


/* Need to support assigning memory if we can */
static int
memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
{
    Py_ssize_t start, len, bytelen, i;
    Py_buffer srcview;
    Py_buffer *view = &(self->view);
    char *srcbuf, *destbuf;

    if (view->readonly) {
        PyErr_SetString(PyExc_TypeError,
            "cannot modify read-only memory");
        return -1;
    }
    if (view->ndim != 1) {
        PyErr_SetNone(PyExc_NotImplementedError);
        return -1;
    }
    if (PyIndex_Check(key)) {
        start = PyNumber_AsSsize_t(key, NULL);
        if (start == -1 && PyErr_Occurred())
            return -1;
        if (start < 0) {
            start += view->shape[0];
        }
        if ((start < 0) || (start >= view->shape[0])) {
            PyErr_SetString(PyExc_IndexError,
                            "index out of bounds");
            return -1;
        }
        len = 1;
    }
    else if (PySlice_Check(key)) {
        Py_ssize_t stop, step;

        if (PySlice_GetIndicesEx((PySliceObject*)key, view->len,
                         &start, &stop, &step, &len) < 0) {
            return -1;
        }
        if (step != 1) {
            PyErr_SetNone(PyExc_NotImplementedError);
            return -1;
        }
    }
    else {
        PyErr_Format(PyExc_TypeError,
            "cannot index memory using \"%.200s\"", 
            key->ob_type->tp_name);
        return -1;
    }
    if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
        return -1;
    }
    /* XXX should we allow assignment of different item sizes
       as long as the byte length is the same?
       (e.g. assign 2 shorts to a 4-byte slice) */
    if (srcview.itemsize != view->itemsize) {
        PyErr_Format(PyExc_TypeError,
            "mismatching item sizes for \"%.200s\" and \"%.200s\"", 
            view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
        goto _error;
    }
    if (srcview.len != len) {
        PyErr_SetString(PyExc_ValueError,
            "cannot modify size of memoryview object");
        goto _error;
    }
    /* Do the actual copy */
    destbuf = (char *) view->buf + start * view->itemsize;
    srcbuf = (char *) srcview.buf;
    bytelen = len * view->itemsize;
    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
        /* No overlapping */
        memcpy(destbuf, srcbuf, bytelen);
    else if (destbuf < srcbuf) {
        /* Copy in ascending order */
        for (i = 0; i < bytelen; i++)
            destbuf[i] = srcbuf[i];
    }
    else {
        /* Copy in descencing order */
        for (i = bytelen - 1; i >= 0; i--)
            destbuf[i] = srcbuf[i];
    }

    PyBuffer_Release(&srcview);
    return 0;

_error:
    PyBuffer_Release(&srcview);
    return -1;
}

static PyObject *
memory_richcompare(PyObject *v, PyObject *w, int op)
{
	Py_buffer vv, ww;
	int equal = 0;
	PyObject *res;

	vv.obj = NULL;
	ww.obj = NULL;
	if (op != Py_EQ && op != Py_NE)
		goto _notimpl;
	if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
		PyErr_Clear();
		goto _notimpl;
	}
	if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
		PyErr_Clear();
		goto _notimpl;
	}

	if (vv.itemsize != ww.itemsize || vv.len != ww.len)
		goto _end;

	equal = !memcmp(vv.buf, ww.buf, vv.len * vv.itemsize);

_end:
	PyBuffer_Release(&vv);
	PyBuffer_Release(&ww);
	if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
		res = Py_True;
	else
		res = Py_False;
	Py_INCREF(res);
	return res;

_notimpl:
	PyBuffer_Release(&vv);
	PyBuffer_Release(&ww);
	Py_INCREF(Py_NotImplemented);
	return Py_NotImplemented;
}


static int
memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
{
	if (self->base != NULL)
		Py_VISIT(self->base);
	if (self->view.obj != NULL)
		Py_VISIT(self->view.obj);
	return 0;
}

static int
memory_clear(PyMemoryViewObject *self)
{
	Py_CLEAR(self->base);
	PyBuffer_Release(&self->view);
	return 0;
}


/* As mapping */
static PyMappingMethods memory_as_mapping = {
	(lenfunc)memory_length, /*mp_length*/
	(binaryfunc)memory_subscript, /*mp_subscript*/
	(objobjargproc)memory_ass_sub, /*mp_ass_subscript*/
};


/* Buffer methods */

static PyBufferProcs memory_as_buffer = {
	(getbufferproc)memory_getbuf,         /* bf_getbuffer */
        (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
};


PyTypeObject PyMemoryView_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"memoryview",
	sizeof(PyMemoryViewObject),
	0,
	(destructor)memory_dealloc, 		/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	(reprfunc)memory_repr,			/* tp_repr */
	0,					/* tp_as_number */
	0,			                /* tp_as_sequence */
	&memory_as_mapping,	    	        /* tp_as_mapping */
	0,		                        /* tp_hash */
	0,					/* tp_call */
	(reprfunc)memory_str,			/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	&memory_as_buffer,			/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
	memory_doc,				/* tp_doc */
	(traverseproc)memory_traverse,		/* tp_traverse */
	(inquiry)memory_clear,			/* tp_clear */
	memory_richcompare,                     /* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	memory_methods,	   		        /* tp_methods */
	0,	      		                /* tp_members */
	memory_getsetlist,  		        /* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	0,					/* tp_alloc */
	memory_new,				/* tp_new */
};
