]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Objects / memoryobject.c
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c b/AppPkg/Applications/Python/Python-2.7.10/Objects/memoryobject.c
deleted file mode 100644 (file)
index 00da8b9..0000000
+++ /dev/null
@@ -1,842 +0,0 @@
-\r
-/* Memoryview object implementation */\r
-\r
-#include "Python.h"\r
-\r
-static Py_ssize_t\r
-get_shape0(Py_buffer *buf)\r
-{\r
-    if (buf->shape != NULL)\r
-        return buf->shape[0];\r
-    if (buf->ndim == 0)\r
-        return 1;\r
-    PyErr_SetString(PyExc_TypeError,\r
-        "exported buffer does not have any shape information associated "\r
-        "to it");\r
-    return -1;\r
-}\r
-\r
-static void\r
-dup_buffer(Py_buffer *dest, Py_buffer *src)\r
-{\r
-    *dest = *src;\r
-    if (src->ndim == 1 && src->shape != NULL) {\r
-        dest->shape = &(dest->smalltable[0]);\r
-        dest->shape[0] = get_shape0(src);\r
-    }\r
-    if (src->ndim == 1 && src->strides != NULL) {\r
-        dest->strides = &(dest->smalltable[1]);\r
-        dest->strides[0] = src->strides[0];\r
-    }\r
-}\r
-\r
-static int\r
-memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)\r
-{\r
-    int res = 0;\r
-    if (self->view.obj != NULL)\r
-        res = PyObject_GetBuffer(self->view.obj, view, flags);\r
-    if (view)\r
-        dup_buffer(view, &self->view);\r
-    return res;\r
-}\r
-\r
-static void\r
-memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)\r
-{\r
-    PyBuffer_Release(view);\r
-}\r
-\r
-PyDoc_STRVAR(memory_doc,\r
-"memoryview(object)\n\\r
-\n\\r
-Create a new memoryview object which references the given object.");\r
-\r
-PyObject *\r
-PyMemoryView_FromBuffer(Py_buffer *info)\r
-{\r
-    PyMemoryViewObject *mview;\r
-\r
-    mview = (PyMemoryViewObject *)\r
-        PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);\r
-    if (mview == NULL)\r
-        return NULL;\r
-    mview->base = NULL;\r
-    dup_buffer(&mview->view, info);\r
-    /* NOTE: mview->view.obj should already have been incref'ed as\r
-       part of PyBuffer_FillInfo(). */\r
-    _PyObject_GC_TRACK(mview);\r
-    return (PyObject *)mview;\r
-}\r
-\r
-PyObject *\r
-PyMemoryView_FromObject(PyObject *base)\r
-{\r
-    PyMemoryViewObject *mview;\r
-    Py_buffer view;\r
-\r
-    if (!PyObject_CheckBuffer(base)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-            "cannot make memory view because object does "\r
-            "not have the buffer interface");\r
-        return NULL;\r
-    }\r
-\r
-    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)\r
-        return NULL;\r
-\r
-    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);\r
-    if (mview == NULL) {\r
-        PyBuffer_Release(&view);\r
-        return NULL;\r
-    }\r
-\r
-    mview->base = base;\r
-    Py_INCREF(base);\r
-    return (PyObject *)mview;\r
-}\r
-\r
-static PyObject *\r
-memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)\r
-{\r
-    PyObject *obj;\r
-    static char *kwlist[] = {"object", 0};\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,\r
-                                     &obj)) {\r
-        return NULL;\r
-    }\r
-\r
-    return PyMemoryView_FromObject(obj);\r
-}\r
-\r
-\r
-static void\r
-_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,\r
-                 Py_ssize_t *strides, Py_ssize_t itemsize, char fort)\r
-{\r
-    int k;\r
-    Py_ssize_t outstride;\r
-\r
-    if (nd==0) {\r
-        memcpy(dest, src, itemsize);\r
-    }\r
-    else if (nd == 1) {\r
-        for (k = 0; k<shape[0]; k++) {\r
-            memcpy(dest, src, itemsize);\r
-            dest += itemsize;\r
-            src += strides[0];\r
-        }\r
-    }\r
-    else {\r
-        if (fort == 'F') {\r
-            /* Copy first dimension first,\r
-               second dimension second, etc...\r
-               Set up the recursive loop backwards so that final\r
-               dimension is actually copied last.\r
-            */\r
-            outstride = itemsize;\r
-            for (k=1; k<nd-1;k++) {\r
-                outstride *= shape[k];\r
-            }\r
-            for (k=0; k<shape[nd-1]; k++) {\r
-                _strided_copy_nd(dest, src, nd-1, shape,\r
-                                 strides, itemsize, fort);\r
-                dest += outstride;\r
-                src += strides[nd-1];\r
-            }\r
-        }\r
-\r
-        else {\r
-            /* Copy last dimension first,\r
-               second-to-last dimension second, etc.\r
-               Set up the recursion so that the\r
-               first dimension is copied last\r
-            */\r
-            outstride = itemsize;\r
-            for (k=1; k < nd; k++) {\r
-                outstride *= shape[k];\r
-            }\r
-            for (k=0; k<shape[0]; k++) {\r
-                _strided_copy_nd(dest, src, nd-1, shape+1,\r
-                                 strides+1, itemsize,\r
-                                 fort);\r
-                dest += outstride;\r
-                src += strides[0];\r
-            }\r
-        }\r
-    }\r
-    return;\r
-}\r
-\r
-static int\r
-_indirect_copy_nd(char *dest, Py_buffer *view, char fort)\r
-{\r
-    Py_ssize_t *indices;\r
-    int k;\r
-    Py_ssize_t elements;\r
-    char *ptr;\r
-    void (*func)(int, Py_ssize_t *, const Py_ssize_t *);\r
-\r
-    if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {\r
-        PyErr_NoMemory();\r
-        return -1;\r
-    }\r
-\r
-    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);\r
-    if (indices == NULL) {\r
-        PyErr_NoMemory();\r
-        return -1;\r
-    }\r
-    for (k=0; k<view->ndim;k++) {\r
-        indices[k] = 0;\r
-    }\r
-\r
-    elements = 1;\r
-    for (k=0; k<view->ndim; k++) {\r
-        elements *= view->shape[k];\r
-    }\r
-    if (fort == 'F') {\r
-        func = _Py_add_one_to_index_F;\r
-    }\r
-    else {\r
-        func = _Py_add_one_to_index_C;\r
-    }\r
-    while (elements--) {\r
-        func(view->ndim, indices, view->shape);\r
-        ptr = PyBuffer_GetPointer(view, indices);\r
-        memcpy(dest, ptr, view->itemsize);\r
-        dest += view->itemsize;\r
-    }\r
-\r
-    PyMem_Free(indices);\r
-    return 0;\r
-}\r
-\r
-/*\r
-   Get a the data from an object as a contiguous chunk of memory (in\r
-   either 'C' or 'F'ortran order) even if it means copying it into a\r
-   separate memory area.\r
-\r
-   Returns a new reference to a Memory view object.  If no copy is needed,\r
-   the memory view object points to the original memory and holds a\r
-   lock on the original.  If a copy is needed, then the memory view object\r
-   points to a brand-new Bytes object (and holds a memory lock on it).\r
-\r
-   buffertype\r
-\r
-   PyBUF_READ  buffer only needs to be read-only\r
-   PyBUF_WRITE buffer needs to be writable (give error if not contiguous)\r
-   PyBUF_SHADOW buffer needs to be writable so shadow it with\r
-                a contiguous buffer if it is not. The view will point to\r
-                the shadow buffer which can be written to and then\r
-                will be copied back into the other buffer when the memory\r
-                view is de-allocated.  While the shadow buffer is\r
-                being used, it will have an exclusive write lock on\r
-                the original buffer.\r
- */\r
-\r
-PyObject *\r
-PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)\r
-{\r
-    PyMemoryViewObject *mem;\r
-    PyObject *bytes;\r
-    Py_buffer *view;\r
-    int flags;\r
-    char *dest;\r
-\r
-    if (!PyObject_CheckBuffer(obj)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "object does not have the buffer interface");\r
-        return NULL;\r
-    }\r
-\r
-    mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);\r
-    if (mem == NULL)\r
-        return NULL;\r
-\r
-    view = &mem->view;\r
-    flags = PyBUF_FULL_RO;\r
-    switch(buffertype) {\r
-    case PyBUF_WRITE:\r
-        flags = PyBUF_FULL;\r
-        break;\r
-    }\r
-\r
-    if (PyObject_GetBuffer(obj, view, flags) != 0) {\r
-        Py_DECREF(mem);\r
-        return NULL;\r
-    }\r
-\r
-    if (PyBuffer_IsContiguous(view, fort)) {\r
-        /* no copy needed */\r
-        Py_INCREF(obj);\r
-        mem->base = obj;\r
-        _PyObject_GC_TRACK(mem);\r
-        return (PyObject *)mem;\r
-    }\r
-    /* otherwise a copy is needed */\r
-    if (buffertype == PyBUF_WRITE) {\r
-        Py_DECREF(mem);\r
-        PyErr_SetString(PyExc_BufferError,\r
-                        "writable contiguous buffer requested "\r
-                        "for a non-contiguousobject.");\r
-        return NULL;\r
-    }\r
-    bytes = PyBytes_FromStringAndSize(NULL, view->len);\r
-    if (bytes == NULL) {\r
-        Py_DECREF(mem);\r
-        return NULL;\r
-    }\r
-    dest = PyBytes_AS_STRING(bytes);\r
-    /* different copying strategy depending on whether\r
-       or not any pointer de-referencing is needed\r
-    */\r
-    /* strided or in-direct copy */\r
-    if (view->suboffsets==NULL) {\r
-        _strided_copy_nd(dest, view->buf, view->ndim, view->shape,\r
-                         view->strides, view->itemsize, fort);\r
-    }\r
-    else {\r
-        if (_indirect_copy_nd(dest, view, fort) < 0) {\r
-            Py_DECREF(bytes);\r
-            Py_DECREF(mem);\r
-            return NULL;\r
-        }\r
-    }\r
-    if (buffertype == PyBUF_SHADOW) {\r
-        /* return a shadowed memory-view object */\r
-        view->buf = dest;\r
-        mem->base = PyTuple_Pack(2, obj, bytes);\r
-        Py_DECREF(bytes);\r
-        if (mem->base == NULL) {\r
-            Py_DECREF(mem);\r
-            return NULL;\r
-        }\r
-    }\r
-    else {\r
-        PyBuffer_Release(view);  /* XXX ? */\r
-        /* steal the reference */\r
-        mem->base = bytes;\r
-    }\r
-    _PyObject_GC_TRACK(mem);\r
-    return (PyObject *)mem;\r
-}\r
-\r
-\r
-static PyObject *\r
-memory_format_get(PyMemoryViewObject *self)\r
-{\r
-    return PyString_FromString(self->view.format);\r
-}\r
-\r
-static PyObject *\r
-memory_itemsize_get(PyMemoryViewObject *self)\r
-{\r
-    return PyLong_FromSsize_t(self->view.itemsize);\r
-}\r
-\r
-static PyObject *\r
-_IntTupleFromSsizet(int len, Py_ssize_t *vals)\r
-{\r
-    int i;\r
-    PyObject *o;\r
-    PyObject *intTuple;\r
-\r
-    if (vals == NULL) {\r
-        Py_INCREF(Py_None);\r
-        return Py_None;\r
-    }\r
-    intTuple = PyTuple_New(len);\r
-    if (!intTuple) return NULL;\r
-    for(i=0; i<len; i++) {\r
-        o = PyLong_FromSsize_t(vals[i]);\r
-        if (!o) {\r
-            Py_DECREF(intTuple);\r
-            return NULL;\r
-        }\r
-        PyTuple_SET_ITEM(intTuple, i, o);\r
-    }\r
-    return intTuple;\r
-}\r
-\r
-static PyObject *\r
-memory_shape_get(PyMemoryViewObject *self)\r
-{\r
-    return _IntTupleFromSsizet(self->view.ndim, self->view.shape);\r
-}\r
-\r
-static PyObject *\r
-memory_strides_get(PyMemoryViewObject *self)\r
-{\r
-    return _IntTupleFromSsizet(self->view.ndim, self->view.strides);\r
-}\r
-\r
-static PyObject *\r
-memory_suboffsets_get(PyMemoryViewObject *self)\r
-{\r
-    return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);\r
-}\r
-\r
-static PyObject *\r
-memory_readonly_get(PyMemoryViewObject *self)\r
-{\r
-    return PyBool_FromLong(self->view.readonly);\r
-}\r
-\r
-static PyObject *\r
-memory_ndim_get(PyMemoryViewObject *self)\r
-{\r
-    return PyLong_FromLong(self->view.ndim);\r
-}\r
-\r
-static PyGetSetDef memory_getsetlist[] ={\r
-    {"format",          (getter)memory_format_get,      NULL, NULL},\r
-    {"itemsize",        (getter)memory_itemsize_get,    NULL, NULL},\r
-    {"shape",           (getter)memory_shape_get,       NULL, NULL},\r
-    {"strides",         (getter)memory_strides_get,     NULL, NULL},\r
-    {"suboffsets",      (getter)memory_suboffsets_get,  NULL, NULL},\r
-    {"readonly",        (getter)memory_readonly_get,    NULL, NULL},\r
-    {"ndim",            (getter)memory_ndim_get,        NULL, NULL},\r
-    {NULL, NULL, NULL, NULL},\r
-};\r
-\r
-\r
-static PyObject *\r
-memory_tobytes(PyMemoryViewObject *self, PyObject *noargs)\r
-{\r
-    Py_buffer view;\r
-    PyObject *res;\r
-\r
-    if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_SIMPLE) < 0)\r
-        return NULL;\r
-\r
-    res = PyBytes_FromStringAndSize(NULL, view.len);\r
-    PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');\r
-    PyBuffer_Release(&view);\r
-    return res;\r
-}\r
-\r
-/* TODO: rewrite this function using the struct module to unpack\r
-   each buffer item */\r
-\r
-static PyObject *\r
-memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)\r
-{\r
-    Py_buffer *view = &(mem->view);\r
-    Py_ssize_t i;\r
-    PyObject *res, *item;\r
-    char *buf;\r
-\r
-    if (strcmp(view->format, "B") || view->itemsize != 1) {\r
-        PyErr_SetString(PyExc_NotImplementedError, \r
-                "tolist() only supports byte views");\r
-        return NULL;\r
-    }\r
-    if (view->ndim != 1) {\r
-        PyErr_SetString(PyExc_NotImplementedError, \r
-                "tolist() only supports one-dimensional objects");\r
-        return NULL;\r
-    }\r
-    res = PyList_New(view->len);\r
-    if (res == NULL)\r
-        return NULL;\r
-    buf = view->buf;\r
-    for (i = 0; i < view->len; i++) {\r
-        item = PyInt_FromLong((unsigned char) *buf);\r
-        if (item == NULL) {\r
-            Py_DECREF(res);\r
-            return NULL;\r
-        }\r
-        PyList_SET_ITEM(res, i, item);\r
-        buf++;\r
-    }\r
-    return res;\r
-}\r
-\r
-static PyMethodDef memory_methods[] = {\r
-    {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},\r
-    {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},\r
-    {NULL,          NULL}           /* sentinel */\r
-};\r
-\r
-\r
-static void\r
-memory_dealloc(PyMemoryViewObject *self)\r
-{\r
-    _PyObject_GC_UNTRACK(self);\r
-    if (self->view.obj != NULL) {\r
-        if (self->base && PyTuple_Check(self->base)) {\r
-            /* Special case when first element is generic object\r
-               with buffer interface and the second element is a\r
-               contiguous "shadow" that must be copied back into\r
-               the data areay of the first tuple element before\r
-               releasing the buffer on the first element.\r
-            */\r
-\r
-            PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),\r
-                              PyTuple_GET_ITEM(self->base,1));\r
-\r
-            /* The view member should have readonly == -1 in\r
-               this instance indicating that the memory can\r
-               be "locked" and was locked and will be unlocked\r
-               again after this call.\r
-            */\r
-            PyBuffer_Release(&(self->view));\r
-        }\r
-        else {\r
-            PyBuffer_Release(&(self->view));\r
-        }\r
-        Py_CLEAR(self->base);\r
-    }\r
-    PyObject_GC_Del(self);\r
-}\r
-\r
-static PyObject *\r
-memory_repr(PyMemoryViewObject *self)\r
-{\r
-    return PyString_FromFormat("<memory at %p>", self);\r
-}\r
-\r
-/* Sequence methods */\r
-static Py_ssize_t\r
-memory_length(PyMemoryViewObject *self)\r
-{\r
-    return get_shape0(&self->view);\r
-}\r
-\r
-/* Alternate version of memory_subcript that only accepts indices.\r
-   Used by PySeqIter_New().\r
-*/\r
-static PyObject *\r
-memory_item(PyMemoryViewObject *self, Py_ssize_t result)\r
-{\r
-    Py_buffer *view = &(self->view);\r
-\r
-    if (view->ndim == 0) {\r
-        PyErr_SetString(PyExc_IndexError,\r
-                        "invalid indexing of 0-dim memory");\r
-        return NULL;\r
-    }\r
-    if (view->ndim == 1) {\r
-        /* Return a bytes object */\r
-        char *ptr;\r
-        ptr = (char *)view->buf;\r
-        if (result < 0) {\r
-            result += get_shape0(view);\r
-        }\r
-        if ((result < 0) || (result >= get_shape0(view))) {\r
-            PyErr_SetString(PyExc_IndexError,\r
-                                "index out of bounds");\r
-            return NULL;\r
-        }\r
-        if (view->strides == NULL)\r
-            ptr += view->itemsize * result;\r
-        else\r
-            ptr += view->strides[0] * result;\r
-        if (view->suboffsets != NULL &&\r
-            view->suboffsets[0] >= 0) {\r
-            ptr = *((char **)ptr) + view->suboffsets[0];\r
-        }\r
-        return PyBytes_FromStringAndSize(ptr, view->itemsize);\r
-    } else {\r
-        /* Return a new memory-view object */\r
-        Py_buffer newview;\r
-        memset(&newview, 0, sizeof(newview));\r
-        /* XXX:  This needs to be fixed so it actually returns a sub-view */\r
-        return PyMemoryView_FromBuffer(&newview);\r
-    }\r
-}\r
-\r
-/*\r
-  mem[obj] returns a bytes object holding the data for one element if\r
-           obj fully indexes the memory view or another memory-view object\r
-           if it does not.\r
-\r
-           0-d memory-view objects can be referenced using ... or () but\r
-           not with anything else.\r
- */\r
-static PyObject *\r
-memory_subscript(PyMemoryViewObject *self, PyObject *key)\r
-{\r
-    Py_buffer *view;\r
-    view = &(self->view);\r
-    \r
-    if (view->ndim == 0) {\r
-        if (key == Py_Ellipsis ||\r
-            (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {\r
-            Py_INCREF(self);\r
-            return (PyObject *)self;\r
-        }\r
-        else {\r
-            PyErr_SetString(PyExc_IndexError,\r
-                                "invalid indexing of 0-dim memory");\r
-            return NULL;\r
-        }\r
-    }\r
-    if (PyIndex_Check(key)) {\r
-        Py_ssize_t result;\r
-        result = PyNumber_AsSsize_t(key, NULL);\r
-        if (result == -1 && PyErr_Occurred())\r
-                return NULL;\r
-        return memory_item(self, result);\r
-    }\r
-    else if (PySlice_Check(key)) {\r
-        Py_ssize_t start, stop, step, slicelength;\r
-\r
-        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),\r
-                                 &start, &stop, &step, &slicelength) < 0) {\r
-            return NULL;\r
-        }\r
-    \r
-        if (step == 1 && view->ndim == 1) {\r
-            Py_buffer newview;\r
-            void *newbuf = (char *) view->buf\r
-                                    + start * view->itemsize;\r
-            int newflags = view->readonly\r
-                    ? PyBUF_CONTIG_RO : PyBUF_CONTIG;\r
-    \r
-            /* XXX There should be an API to create a subbuffer */\r
-            if (view->obj != NULL) {\r
-                if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)\r
-                    return NULL;\r
-            }\r
-            else {\r
-                newview = *view;\r
-            }\r
-            newview.buf = newbuf;\r
-            newview.len = slicelength * newview.itemsize;\r
-            newview.format = view->format;\r
-            newview.shape = &(newview.smalltable[0]);\r
-            newview.shape[0] = slicelength;\r
-            newview.strides = &(newview.itemsize);\r
-            return PyMemoryView_FromBuffer(&newview);\r
-        }\r
-        PyErr_SetNone(PyExc_NotImplementedError);\r
-        return NULL;\r
-    }\r
-    PyErr_Format(PyExc_TypeError,\r
-        "cannot index memory using \"%.200s\"", \r
-        key->ob_type->tp_name);\r
-    return NULL;\r
-}\r
-\r
-\r
-/* Need to support assigning memory if we can */\r
-static int\r
-memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)\r
-{\r
-    Py_ssize_t start, len, bytelen;\r
-    Py_buffer srcview;\r
-    Py_buffer *view = &(self->view);\r
-    char *srcbuf, *destbuf;\r
-\r
-    if (view->readonly) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-            "cannot modify read-only memory");\r
-        return -1;\r
-    }\r
-    if (value == NULL) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "cannot delete memory");\r
-        return -1;\r
-    }\r
-    if (view->ndim != 1) {\r
-        PyErr_SetNone(PyExc_NotImplementedError);\r
-        return -1;\r
-    }\r
-    if (PyIndex_Check(key)) {\r
-        start = PyNumber_AsSsize_t(key, NULL);\r
-        if (start == -1 && PyErr_Occurred())\r
-            return -1;\r
-        if (start < 0) {\r
-            start += get_shape0(view);\r
-        }\r
-        if ((start < 0) || (start >= get_shape0(view))) {\r
-            PyErr_SetString(PyExc_IndexError,\r
-                            "index out of bounds");\r
-            return -1;\r
-        }\r
-        len = 1;\r
-    }\r
-    else if (PySlice_Check(key)) {\r
-        Py_ssize_t stop, step;\r
-\r
-        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),\r
-                         &start, &stop, &step, &len) < 0) {\r
-            return -1;\r
-        }\r
-        if (step != 1) {\r
-            PyErr_SetNone(PyExc_NotImplementedError);\r
-            return -1;\r
-        }\r
-    }\r
-    else {\r
-        PyErr_Format(PyExc_TypeError,\r
-            "cannot index memory using \"%.200s\"", \r
-            key->ob_type->tp_name);\r
-        return -1;\r
-    }\r
-    if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {\r
-        return -1;\r
-    }\r
-    /* XXX should we allow assignment of different item sizes\r
-       as long as the byte length is the same?\r
-       (e.g. assign 2 shorts to a 4-byte slice) */\r
-    if (srcview.itemsize != view->itemsize) {\r
-        PyErr_Format(PyExc_TypeError,\r
-            "mismatching item sizes for \"%.200s\" and \"%.200s\"", \r
-            view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);\r
-        goto _error;\r
-    }\r
-    bytelen = len * view->itemsize;\r
-    if (bytelen != srcview.len) {\r
-        PyErr_SetString(PyExc_ValueError,\r
-            "cannot modify size of memoryview object");\r
-        goto _error;\r
-    }\r
-    /* Do the actual copy */\r
-    destbuf = (char *) view->buf + start * view->itemsize;\r
-    srcbuf = (char *) srcview.buf;\r
-    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)\r
-        /* No overlapping */\r
-        memcpy(destbuf, srcbuf, bytelen);\r
-    else\r
-        memmove(destbuf, srcbuf, bytelen);\r
-\r
-    PyBuffer_Release(&srcview);\r
-    return 0;\r
-\r
-_error:\r
-    PyBuffer_Release(&srcview);\r
-    return -1;\r
-}\r
-\r
-static PyObject *\r
-memory_richcompare(PyObject *v, PyObject *w, int op)\r
-{\r
-    Py_buffer vv, ww;\r
-    int equal = 0;\r
-    PyObject *res;\r
-\r
-    vv.obj = NULL;\r
-    ww.obj = NULL;\r
-    if (op != Py_EQ && op != Py_NE)\r
-        goto _notimpl;\r
-    if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {\r
-        PyErr_Clear();\r
-        goto _notimpl;\r
-    }\r
-    if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {\r
-        PyErr_Clear();\r
-        goto _notimpl;\r
-    }\r
-\r
-    if (vv.itemsize != ww.itemsize || vv.len != ww.len)\r
-        goto _end;\r
-\r
-    equal = !memcmp(vv.buf, ww.buf, vv.len);\r
-\r
-_end:\r
-    PyBuffer_Release(&vv);\r
-    PyBuffer_Release(&ww);\r
-    if ((equal && op == Py_EQ) || (!equal && op == Py_NE))\r
-        res = Py_True;\r
-    else\r
-        res = Py_False;\r
-    Py_INCREF(res);\r
-    return res;\r
-\r
-_notimpl:\r
-    PyBuffer_Release(&vv);\r
-    PyBuffer_Release(&ww);\r
-    Py_INCREF(Py_NotImplemented);\r
-    return Py_NotImplemented;\r
-}\r
-\r
-\r
-static int\r
-memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)\r
-{\r
-    if (self->base != NULL)\r
-        Py_VISIT(self->base);\r
-    if (self->view.obj != NULL)\r
-        Py_VISIT(self->view.obj);\r
-    return 0;\r
-}\r
-\r
-static int\r
-memory_clear(PyMemoryViewObject *self)\r
-{\r
-    Py_CLEAR(self->base);\r
-    PyBuffer_Release(&self->view);\r
-    return 0;\r
-}\r
-\r
-\r
-/* As mapping */\r
-static PyMappingMethods memory_as_mapping = {\r
-    (lenfunc)memory_length,               /* mp_length */\r
-    (binaryfunc)memory_subscript,         /* mp_subscript */\r
-    (objobjargproc)memory_ass_sub,        /* mp_ass_subscript */\r
-};\r
-\r
-static PySequenceMethods memory_as_sequence = {\r
-       0,                                  /* sq_length */\r
-       0,                                  /* sq_concat */\r
-       0,                                  /* sq_repeat */\r
-       (ssizeargfunc)memory_item,          /* sq_item */\r
-};\r
-\r
-/* Buffer methods */\r
-static PyBufferProcs memory_as_buffer = {\r
-    0,                                    /* bf_getreadbuffer */\r
-    0,                                    /* bf_getwritebuffer */\r
-    0,                                    /* bf_getsegcount */\r
-    0,                                    /* bf_getcharbuffer */\r
-    (getbufferproc)memory_getbuf,         /* bf_getbuffer */\r
-    (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */\r
-};\r
-\r
-\r
-PyTypeObject PyMemoryView_Type = {\r
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
-    "memoryview",\r
-    sizeof(PyMemoryViewObject),\r
-    0,\r
-    (destructor)memory_dealloc,               /* tp_dealloc */\r
-    0,                                        /* tp_print */\r
-    0,                                        /* tp_getattr */\r
-    0,                                        /* tp_setattr */\r
-    0,                                        /* tp_compare */\r
-    (reprfunc)memory_repr,                    /* tp_repr */\r
-    0,                                        /* tp_as_number */\r
-    &memory_as_sequence,                      /* tp_as_sequence */\r
-    &memory_as_mapping,                       /* tp_as_mapping */\r
-    0,                                        /* tp_hash */\r
-    0,                                        /* tp_call */\r
-    0,                                        /* tp_str */\r
-    PyObject_GenericGetAttr,                  /* tp_getattro */\r
-    0,                                        /* tp_setattro */\r
-    &memory_as_buffer,                        /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |\r
-        Py_TPFLAGS_HAVE_NEWBUFFER,            /* tp_flags */\r
-    memory_doc,                               /* tp_doc */\r
-    (traverseproc)memory_traverse,            /* tp_traverse */\r
-    (inquiry)memory_clear,                    /* tp_clear */\r
-    memory_richcompare,                       /* tp_richcompare */\r
-    0,                                        /* tp_weaklistoffset */\r
-    0,                                        /* tp_iter */\r
-    0,                                        /* tp_iternext */\r
-    memory_methods,                           /* tp_methods */\r
-    0,                                        /* tp_members */\r
-    memory_getsetlist,                        /* tp_getset */\r
-    0,                                        /* tp_base */\r
-    0,                                        /* tp_dict */\r
-    0,                                        /* tp_descr_get */\r
-    0,                                        /* tp_descr_set */\r
-    0,                                        /* tp_dictoffset */\r
-    0,                                        /* tp_init */\r
-    0,                                        /* tp_alloc */\r
-    memory_new,                               /* tp_new */\r
-};\r