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

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 *, const 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 = _Py_add_one_to_index_F;
    }
    else {
        func = _Py_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 (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "cannot delete 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 */
};
