
/* Memoryview object implementation */

#include "Python.h"

static Py_ssize_t
get_shape0(Py_buffer *buf)
{
    if (buf->shape != NULL)
        return buf->shape[0];
    if (buf->ndim == 0)
        return 1;
    PyErr_SetString(PyExc_TypeError,
        "exported buffer does not have any shape information associated "
        "to it");
    return -1;
}

static void
dup_buffer(Py_buffer *dest, Py_buffer *src)
{
    *dest = *src;
    if (src->ndim == 1 && src->shape != NULL) {
        dest->shape = &(dest->smalltable[0]);
        dest->shape[0] = get_shape0(src);
    }
    if (src->ndim == 1 && src->strides != NULL) {
        dest->strides = &(dest->smalltable[1]);
        dest->strides[0] = src->strides[0];
    }
}

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;
    Py_buffer view;

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

    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
        return NULL;

    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
    if (mview == NULL) {
        PyBuffer_Release(&view);
        return NULL;
    }

    mview->base = base;
    Py_INCREF(base);
    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 support 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);
}

/* Sequence methods */
static Py_ssize_t
memory_length(PyMemoryViewObject *self)
{
    return get_shape0(&self->view);
}

/* Alternate version of memory_subcript that only accepts indices.
   Used by PySeqIter_New().
*/
static PyObject *
memory_item(PyMemoryViewObject *self, Py_ssize_t result)
{
    Py_buffer *view = &(self->view);

    if (view->ndim == 0) {
        PyErr_SetString(PyExc_IndexError,
                        "invalid indexing of 0-dim memory");
        return NULL;
    }
    if (view->ndim == 1) {
        /* Return a bytes object */
        char *ptr;
        ptr = (char *)view->buf;
        if (result < 0) {
            result += get_shape0(view);
        }
        if ((result < 0) || (result >= get_shape0(view))) {
            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);
    }
}

/*
  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;
        return memory_item(self, result);
    }
    else if (PySlice_Check(key)) {
        Py_ssize_t start, stop, step, slicelength;

        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
                                 &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.itemsize;
            newview.format = view->format;
            newview.shape = &(newview.smalltable[0]);
            newview.shape[0] = slicelength;
            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;
    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 += get_shape0(view);
        }
        if ((start < 0) || (start >= get_shape0(view))) {
            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, get_shape0(view),
                         &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;
    }
    bytelen = len * view->itemsize;
    if (bytelen != srcview.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;
    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
        /* No overlapping */
        memcpy(destbuf, srcbuf, bytelen);
    else
        memmove(destbuf, srcbuf, bytelen);

    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);

_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 */
};

static PySequenceMethods memory_as_sequence = {
	0,                                  /* sq_length */
	0,                                  /* sq_concat */
	0,                                  /* sq_repeat */
	(ssizeargfunc)memory_item,          /* sq_item */
};

/* 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_reserved */
    (reprfunc)memory_repr,                    /* tp_repr */
    0,                                        /* tp_as_number */
    &memory_as_sequence,                      /* tp_as_sequence */
    &memory_as_mapping,                       /* tp_as_mapping */
    0,                                        /* tp_hash */
    0,                                        /* tp_call */
    0,                                        /* 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 */
};
