1789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
2789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/* Memoryview object implementation */
3789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
4789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou#include "Python.h"
5789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
6789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic Py_ssize_t
7789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrouget_shape0(Py_buffer *buf)
8789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
9789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (buf->shape != NULL)
10789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return buf->shape[0];
11789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (buf->ndim == 0)
12789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return 1;
13789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyErr_SetString(PyExc_TypeError,
14789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        "exported buffer does not have any shape information associated "
15789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        "to it");
16789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return -1;
17789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
18789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
19789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic void
20789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroudup_buffer(Py_buffer *dest, Py_buffer *src)
21789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
22789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    *dest = *src;
23789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (src->ndim == 1 && src->shape != NULL) {
24789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        dest->shape = &(dest->smalltable[0]);
25789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        dest->shape[0] = get_shape0(src);
26789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
27789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (src->ndim == 1 && src->strides != NULL) {
28789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        dest->strides = &(dest->smalltable[1]);
29789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        dest->strides[0] = src->strides[0];
30789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
31789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
32789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
33789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic int
34789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
35789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
36789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    int res = 0;
37789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (self->view.obj != NULL)
38789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        res = PyObject_GetBuffer(self->view.obj, view, flags);
39789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view)
40789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        dup_buffer(view, &self->view);
41789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return res;
42789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
43789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
44789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic void
45789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
46789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
47789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(view);
48789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
49789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
50789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyDoc_STRVAR(memory_doc,
51789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou"memoryview(object)\n\
52789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou\n\
53789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouCreate a new memoryview object which references the given object.");
54789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
55789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyObject *
56789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyMemoryView_FromBuffer(Py_buffer *info)
57789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
58789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyMemoryViewObject *mview;
59789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
60789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    mview = (PyMemoryViewObject *)
61789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
62789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (mview == NULL)
63789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
64789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    mview->base = NULL;
65789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    dup_buffer(&mview->view, info);
66789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    /* NOTE: mview->view.obj should already have been incref'ed as
67789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou       part of PyBuffer_FillInfo(). */
68789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    _PyObject_GC_TRACK(mview);
69789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return (PyObject *)mview;
70789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
71789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
72789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyObject *
73789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyMemoryView_FromObject(PyObject *base)
74789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
75789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyMemoryViewObject *mview;
76526e421b12654368443926b83fb0ca1e7ff027b4Antoine Pitrou    Py_buffer view;
77789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
78789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (!PyObject_CheckBuffer(base)) {
79789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
80789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            "cannot make memory view because object does "
81789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            "not have the buffer interface");
82789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
83789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
84789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
85526e421b12654368443926b83fb0ca1e7ff027b4Antoine Pitrou    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
86789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
87789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
88526e421b12654368443926b83fb0ca1e7ff027b4Antoine Pitrou    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
89526e421b12654368443926b83fb0ca1e7ff027b4Antoine Pitrou    if (mview == NULL) {
90526e421b12654368443926b83fb0ca1e7ff027b4Antoine Pitrou        PyBuffer_Release(&view);
91789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
92789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
93789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
94789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    mview->base = base;
95789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_INCREF(base);
96789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return (PyObject *)mview;
97789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
98789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
99789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
100789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
101789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
102789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *obj;
103789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    static char *kwlist[] = {"object", 0};
104789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
105789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
106789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                     &obj)) {
107789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
108789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
109789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
110789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return PyMemoryView_FromObject(obj);
111789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
112789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
113789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
114789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic void
115789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
116789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                 Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
117789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
118789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    int k;
119789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_ssize_t outstride;
120789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
121789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (nd==0) {
122789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        memcpy(dest, src, itemsize);
123789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
124789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else if (nd == 1) {
125789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        for (k = 0; k<shape[0]; k++) {
126789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            memcpy(dest, src, itemsize);
127789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            dest += itemsize;
128789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            src += strides[0];
129789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
130789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
131789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else {
132789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (fort == 'F') {
133789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            /* Copy first dimension first,
134789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               second dimension second, etc...
135789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               Set up the recursive loop backwards so that final
136789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               dimension is actually copied last.
137789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            */
138789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            outstride = itemsize;
139789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            for (k=1; k<nd-1;k++) {
140789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                outstride *= shape[k];
141789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            }
142789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            for (k=0; k<shape[nd-1]; k++) {
143789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                _strided_copy_nd(dest, src, nd-1, shape,
144789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                 strides, itemsize, fort);
145789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                dest += outstride;
146789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                src += strides[nd-1];
147789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            }
148789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
149789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
150789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        else {
151789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            /* Copy last dimension first,
152789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               second-to-last dimension second, etc.
153789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               Set up the recursion so that the
154789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               first dimension is copied last
155789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            */
156789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            outstride = itemsize;
157789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            for (k=1; k < nd; k++) {
158789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                outstride *= shape[k];
159789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            }
160789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            for (k=0; k<shape[0]; k++) {
161789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                _strided_copy_nd(dest, src, nd-1, shape+1,
162789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                 strides+1, itemsize,
163789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                 fort);
164789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                dest += outstride;
165789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                src += strides[0];
166789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            }
167789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
168789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
169789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return;
170789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
171789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
172789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic int
173789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
174789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
175789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_ssize_t *indices;
176789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    int k;
177789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_ssize_t elements;
178789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    char *ptr;
1799cf85f144e73a1b1566e536436c066cfab32dac8Antoine Pitrou    void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
180789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
181789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
182789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_NoMemory();
183789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return -1;
184789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
185789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
186789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
187789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (indices == NULL) {
188789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_NoMemory();
189789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return -1;
190789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
191789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    for (k=0; k<view->ndim;k++) {
192789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        indices[k] = 0;
193789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
194789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
195789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    elements = 1;
196789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    for (k=0; k<view->ndim; k++) {
197789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        elements *= view->shape[k];
198789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
199789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (fort == 'F') {
2001fcdba84be218fa2952315bd95e21339422df922Antoine Pitrou        func = _Py_add_one_to_index_F;
201789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
202789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else {
2031fcdba84be218fa2952315bd95e21339422df922Antoine Pitrou        func = _Py_add_one_to_index_C;
204789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
205789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    while (elements--) {
206789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        func(view->ndim, indices, view->shape);
207789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        ptr = PyBuffer_GetPointer(view, indices);
208789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        memcpy(dest, ptr, view->itemsize);
209789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        dest += view->itemsize;
210789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
211789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
212789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyMem_Free(indices);
213789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return 0;
214789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
215789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
216789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/*
217789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   Get a the data from an object as a contiguous chunk of memory (in
218789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   either 'C' or 'F'ortran order) even if it means copying it into a
219789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   separate memory area.
220789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
221789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   Returns a new reference to a Memory view object.  If no copy is needed,
222789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   the memory view object points to the original memory and holds a
223789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   lock on the original.  If a copy is needed, then the memory view object
224789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   points to a brand-new Bytes object (and holds a memory lock on it).
225789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
226789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   buffertype
227789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
228789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   PyBUF_READ  buffer only needs to be read-only
229789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
230789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   PyBUF_SHADOW buffer needs to be writable so shadow it with
231789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                a contiguous buffer if it is not. The view will point to
232789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                the shadow buffer which can be written to and then
233789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                will be copied back into the other buffer when the memory
234789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                view is de-allocated.  While the shadow buffer is
235789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                being used, it will have an exclusive write lock on
236789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                the original buffer.
237789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou */
238789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
239789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyObject *
240789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
241789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
242789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyMemoryViewObject *mem;
243789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *bytes;
244789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer *view;
245789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    int flags;
246789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    char *dest;
247789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
248789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (!PyObject_CheckBuffer(obj)) {
249789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
250789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                        "object does not have the buffer interface");
251789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
252789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
253789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
254789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
255789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (mem == NULL)
256789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
257789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
258789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    view = &mem->view;
259789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    flags = PyBUF_FULL_RO;
260789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    switch(buffertype) {
261789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    case PyBUF_WRITE:
262789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        flags = PyBUF_FULL;
263789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        break;
264789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
265789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
266789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyObject_GetBuffer(obj, view, flags) != 0) {
267789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_DECREF(mem);
268789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
269789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
270789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
271789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyBuffer_IsContiguous(view, fort)) {
272789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        /* no copy needed */
273789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_INCREF(obj);
274789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        mem->base = obj;
275789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        _PyObject_GC_TRACK(mem);
276789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return (PyObject *)mem;
277789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
278789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    /* otherwise a copy is needed */
279789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (buffertype == PyBUF_WRITE) {
280789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_DECREF(mem);
281789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_BufferError,
282789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                        "writable contiguous buffer requested "
283789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                        "for a non-contiguousobject.");
284789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
285789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
286789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    bytes = PyBytes_FromStringAndSize(NULL, view->len);
287789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (bytes == NULL) {
288789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_DECREF(mem);
289789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
290789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
291789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    dest = PyBytes_AS_STRING(bytes);
292789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    /* different copying strategy depending on whether
293789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou       or not any pointer de-referencing is needed
294789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    */
295789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    /* strided or in-direct copy */
296789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view->suboffsets==NULL) {
297789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
298789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                         view->strides, view->itemsize, fort);
299789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
300789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else {
301789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (_indirect_copy_nd(dest, view, fort) < 0) {
302789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_DECREF(bytes);
303789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_DECREF(mem);
304789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return NULL;
305789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
306789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
307789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (buffertype == PyBUF_SHADOW) {
308789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        /* return a shadowed memory-view object */
309789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        view->buf = dest;
310789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        mem->base = PyTuple_Pack(2, obj, bytes);
311789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_DECREF(bytes);
312789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (mem->base == NULL) {
313789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_DECREF(mem);
314789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return NULL;
315789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
316789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
317789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else {
318789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyBuffer_Release(view);  /* XXX ? */
319789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        /* steal the reference */
320789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        mem->base = bytes;
321789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
322789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    _PyObject_GC_TRACK(mem);
323789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return (PyObject *)mem;
324789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
325789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
326789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
327789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
328789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_format_get(PyMemoryViewObject *self)
329789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
33008133af12e4dee7f688528075d96bb4df94dc0b0Mark Dickinson    return PyString_FromString(self->view.format);
331789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
332789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
333789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
334789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_itemsize_get(PyMemoryViewObject *self)
335789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
336789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return PyLong_FromSsize_t(self->view.itemsize);
337789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
338789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
339789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
340789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou_IntTupleFromSsizet(int len, Py_ssize_t *vals)
341789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
342789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    int i;
343789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *o;
344789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *intTuple;
345789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
346789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (vals == NULL) {
347789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_INCREF(Py_None);
348789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return Py_None;
349789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
350789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    intTuple = PyTuple_New(len);
351789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (!intTuple) return NULL;
352789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    for(i=0; i<len; i++) {
353789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        o = PyLong_FromSsize_t(vals[i]);
354789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (!o) {
355789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_DECREF(intTuple);
356789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return NULL;
357789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
358789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyTuple_SET_ITEM(intTuple, i, o);
359789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
360789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return intTuple;
361789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
362789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
363789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
364789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_shape_get(PyMemoryViewObject *self)
365789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
366789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
367789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
368789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
369789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
370789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_strides_get(PyMemoryViewObject *self)
371789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
372789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
373789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
374789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
375789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
376789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_suboffsets_get(PyMemoryViewObject *self)
377789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
378789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
379789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
380789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
381789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
382789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_readonly_get(PyMemoryViewObject *self)
383789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
384789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return PyBool_FromLong(self->view.readonly);
385789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
386789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
387789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
388789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_ndim_get(PyMemoryViewObject *self)
389789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
390789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return PyLong_FromLong(self->view.ndim);
391789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
392789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
393789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyGetSetDef memory_getsetlist[] ={
394789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"format",          (getter)memory_format_get,      NULL, NULL},
395789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"itemsize",        (getter)memory_itemsize_get,    NULL, NULL},
396789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"shape",           (getter)memory_shape_get,       NULL, NULL},
397789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"strides",         (getter)memory_strides_get,     NULL, NULL},
398789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"suboffsets",      (getter)memory_suboffsets_get,  NULL, NULL},
399789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"readonly",        (getter)memory_readonly_get,    NULL, NULL},
400789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"ndim",            (getter)memory_ndim_get,        NULL, NULL},
401789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {NULL, NULL, NULL, NULL},
402789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou};
403789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
404789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
405789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
406789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_tobytes(PyMemoryViewObject *self, PyObject *noargs)
407789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
408789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer view;
409789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *res;
410789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
4113013b16b62be7768700d685f6a68e606b5f20e5aAntoine Pitrou    if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_SIMPLE) < 0)
412789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
413789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
414789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    res = PyBytes_FromStringAndSize(NULL, view.len);
415789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
416789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&view);
417789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return res;
418789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
419789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
420789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/* TODO: rewrite this function using the struct module to unpack
421789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou   each buffer item */
422789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
423789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
424789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
425789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
426789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer *view = &(mem->view);
427789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_ssize_t i;
428789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *res, *item;
429789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    char *buf;
430789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
431789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (strcmp(view->format, "B") || view->itemsize != 1) {
432789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_NotImplementedError,
433789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                "tolist() only supports byte views");
434789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
435789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
436789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view->ndim != 1) {
437789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_NotImplementedError,
438789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                "tolist() only supports one-dimensional objects");
439789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
440789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
441789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    res = PyList_New(view->len);
442789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (res == NULL)
443789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
444789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    buf = view->buf;
445789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    for (i = 0; i < view->len; i++) {
446789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        item = PyInt_FromLong((unsigned char) *buf);
447789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (item == NULL) {
448789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_DECREF(res);
449789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return NULL;
450789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
451789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyList_SET_ITEM(res, i, item);
452789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        buf++;
453789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
454789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return res;
455789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
456789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
457789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyMethodDef memory_methods[] = {
458789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
459789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
460789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    {NULL,          NULL}           /* sentinel */
461789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou};
462789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
463789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
464789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic void
465789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_dealloc(PyMemoryViewObject *self)
466789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
467789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    _PyObject_GC_UNTRACK(self);
468789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (self->view.obj != NULL) {
469789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (self->base && PyTuple_Check(self->base)) {
470789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            /* Special case when first element is generic object
471789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               with buffer interface and the second element is a
472789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               contiguous "shadow" that must be copied back into
473789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               the data areay of the first tuple element before
474789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               releasing the buffer on the first element.
475789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            */
476789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
477789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
478789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                              PyTuple_GET_ITEM(self->base,1));
479789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
480789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            /* The view member should have readonly == -1 in
481789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               this instance indicating that the memory can
482789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               be "locked" and was locked and will be unlocked
483789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou               again after this call.
484789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            */
485789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            PyBuffer_Release(&(self->view));
486789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
487789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        else {
488789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            PyBuffer_Release(&(self->view));
489789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
490789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_CLEAR(self->base);
491789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
492789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject_GC_Del(self);
493789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
494789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
495789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
496789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_repr(PyMemoryViewObject *self)
497789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
49808133af12e4dee7f688528075d96bb4df94dc0b0Mark Dickinson    return PyString_FromFormat("<memory at %p>", self);
499789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
500789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
501789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/* Sequence methods */
502789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic Py_ssize_t
503789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_length(PyMemoryViewObject *self)
504789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
505789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return get_shape0(&self->view);
506789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
507789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
50862641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger/* Alternate version of memory_subcript that only accepts indices.
50962641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger   Used by PySeqIter_New().
51062641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger*/
51162641e9534d7b085e21285921c70f3e8ee786929Raymond Hettingerstatic PyObject *
51262641e9534d7b085e21285921c70f3e8ee786929Raymond Hettingermemory_item(PyMemoryViewObject *self, Py_ssize_t result)
51362641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger{
51462641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    Py_buffer *view = &(self->view);
51562641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger
51662641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    if (view->ndim == 0) {
51762641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        PyErr_SetString(PyExc_IndexError,
51862641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger                        "invalid indexing of 0-dim memory");
51962641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        return NULL;
52062641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    }
52162641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    if (view->ndim == 1) {
52262641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        /* Return a bytes object */
52362641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        char *ptr;
52462641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        ptr = (char *)view->buf;
52562641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        if (result < 0) {
52662641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            result += get_shape0(view);
52762641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        }
52862641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        if ((result < 0) || (result >= get_shape0(view))) {
52962641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            PyErr_SetString(PyExc_IndexError,
53062641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger                                "index out of bounds");
53162641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            return NULL;
53262641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        }
53362641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        if (view->strides == NULL)
53462641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            ptr += view->itemsize * result;
53562641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        else
53662641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            ptr += view->strides[0] * result;
53762641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        if (view->suboffsets != NULL &&
53862641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            view->suboffsets[0] >= 0) {
53962641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger            ptr = *((char **)ptr) + view->suboffsets[0];
54062641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        }
54162641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        return PyBytes_FromStringAndSize(ptr, view->itemsize);
54262641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    } else {
54362641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        /* Return a new memory-view object */
54462641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        Py_buffer newview;
54562641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        memset(&newview, 0, sizeof(newview));
54662641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        /* XXX:  This needs to be fixed so it actually returns a sub-view */
54762641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        return PyMemoryView_FromBuffer(&newview);
54862641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    }
54962641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger}
55062641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger
551789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/*
552789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou  mem[obj] returns a bytes object holding the data for one element if
553789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou           obj fully indexes the memory view or another memory-view object
554789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou           if it does not.
555789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
556789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou           0-d memory-view objects can be referenced using ... or () but
557789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou           not with anything else.
558789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou */
559789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
560789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_subscript(PyMemoryViewObject *self, PyObject *key)
561789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
562789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer *view;
563789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    view = &(self->view);
564789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
565789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view->ndim == 0) {
566789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (key == Py_Ellipsis ||
567789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
568789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_INCREF(self);
569789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return (PyObject *)self;
570789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
571789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        else {
572789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            PyErr_SetString(PyExc_IndexError,
573789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                "invalid indexing of 0-dim memory");
574789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return NULL;
575789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
576789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
577789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyIndex_Check(key)) {
578789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_ssize_t result;
579789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        result = PyNumber_AsSsize_t(key, NULL);
580789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (result == -1 && PyErr_Occurred())
581789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                return NULL;
58262641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger        return memory_item(self, result);
583789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
584789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else if (PySlice_Check(key)) {
585789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_ssize_t start, stop, step, slicelength;
586789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
587789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
588789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                 &start, &stop, &step, &slicelength) < 0) {
589789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return NULL;
590789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
591789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
592789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (step == 1 && view->ndim == 1) {
593789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            Py_buffer newview;
594789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            void *newbuf = (char *) view->buf
595789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                                    + start * view->itemsize;
596789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            int newflags = view->readonly
597789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                    ? PyBUF_CONTIG_RO : PyBUF_CONTIG;
598789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
599789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            /* XXX There should be an API to create a subbuffer */
600789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            if (view->obj != NULL) {
601789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)
602789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                    return NULL;
603789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            }
604789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            else {
605789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                newview = *view;
606789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            }
607789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            newview.buf = newbuf;
608789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            newview.len = slicelength * newview.itemsize;
609789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            newview.format = view->format;
610789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            newview.shape = &(newview.smalltable[0]);
611789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            newview.shape[0] = slicelength;
612789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            newview.strides = &(newview.itemsize);
613789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return PyMemoryView_FromBuffer(&newview);
614789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
615789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetNone(PyExc_NotImplementedError);
616789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return NULL;
617789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
618789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyErr_Format(PyExc_TypeError,
619789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        "cannot index memory using \"%.200s\"",
620789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        key->ob_type->tp_name);
621789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return NULL;
622789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
623789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
624789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
625789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/* Need to support assigning memory if we can */
626789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic int
627789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
628789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
6293266978300ace81216e7cf7d072d43319efa2f65Antoine Pitrou    Py_ssize_t start, len, bytelen;
630789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer srcview;
631789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer *view = &(self->view);
632789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    char *srcbuf, *destbuf;
633789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
634789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view->readonly) {
635789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
636789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            "cannot modify read-only memory");
637789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return -1;
638789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
6399cf85f144e73a1b1566e536436c066cfab32dac8Antoine Pitrou    if (value == NULL) {
6409cf85f144e73a1b1566e536436c066cfab32dac8Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
6419cf85f144e73a1b1566e536436c066cfab32dac8Antoine Pitrou                        "cannot delete memory");
6429cf85f144e73a1b1566e536436c066cfab32dac8Antoine Pitrou        return -1;
6439cf85f144e73a1b1566e536436c066cfab32dac8Antoine Pitrou    }
644789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (view->ndim != 1) {
645789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetNone(PyExc_NotImplementedError);
646789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return -1;
647789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
648789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyIndex_Check(key)) {
649789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        start = PyNumber_AsSsize_t(key, NULL);
650789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (start == -1 && PyErr_Occurred())
651789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return -1;
652789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (start < 0) {
653789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            start += get_shape0(view);
654789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
655789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if ((start < 0) || (start >= get_shape0(view))) {
656789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            PyErr_SetString(PyExc_IndexError,
657789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                            "index out of bounds");
658789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return -1;
659789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
660789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        len = 1;
661789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
662789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else if (PySlice_Check(key)) {
663789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_ssize_t stop, step;
664789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
665789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
666789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou                         &start, &stop, &step, &len) < 0) {
667789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return -1;
668789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
669789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        if (step != 1) {
670789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            PyErr_SetNone(PyExc_NotImplementedError);
671789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            return -1;
672789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        }
673789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
674789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else {
675789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_Format(PyExc_TypeError,
676789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            "cannot index memory using \"%.200s\"",
677789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            key->ob_type->tp_name);
678789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return -1;
679789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
680789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
681789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        return -1;
682789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
683789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    /* XXX should we allow assignment of different item sizes
684789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou       as long as the byte length is the same?
685789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou       (e.g. assign 2 shorts to a 4-byte slice) */
686789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (srcview.itemsize != view->itemsize) {
687789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_Format(PyExc_TypeError,
688789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            "mismatching item sizes for \"%.200s\" and \"%.200s\"",
689789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
690789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        goto _error;
691789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
692789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    bytelen = len * view->itemsize;
693789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (bytelen != srcview.len) {
694789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
695789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou            "cannot modify size of memoryview object");
696789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        goto _error;
697789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
698789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    /* Do the actual copy */
699789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    destbuf = (char *) view->buf + start * view->itemsize;
700789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    srcbuf = (char *) srcview.buf;
701789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
702789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        /* No overlapping */
703789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        memcpy(destbuf, srcbuf, bytelen);
7043266978300ace81216e7cf7d072d43319efa2f65Antoine Pitrou    else
7053266978300ace81216e7cf7d072d43319efa2f65Antoine Pitrou        memmove(destbuf, srcbuf, bytelen);
706789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
707789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&srcview);
708789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return 0;
709789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
710789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou_error:
711789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&srcview);
712789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return -1;
713789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
714789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
715789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyObject *
716789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_richcompare(PyObject *v, PyObject *w, int op)
717789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
718789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_buffer vv, ww;
719789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    int equal = 0;
720789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject *res;
721789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
722789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    vv.obj = NULL;
723789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    ww.obj = NULL;
724789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (op != Py_EQ && op != Py_NE)
725789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        goto _notimpl;
726789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
727789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_Clear();
728789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        goto _notimpl;
729789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
730789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
731789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        PyErr_Clear();
732789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        goto _notimpl;
733789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    }
734789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
735789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (vv.itemsize != ww.itemsize || vv.len != ww.len)
736789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        goto _end;
737789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
738789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    equal = !memcmp(vv.buf, ww.buf, vv.len);
739789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
740789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou_end:
741789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&vv);
742789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&ww);
743789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
744789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        res = Py_True;
745789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    else
746789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        res = Py_False;
747789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_INCREF(res);
748789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return res;
749789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
750789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou_notimpl:
751789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&vv);
752789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&ww);
753789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_INCREF(Py_NotImplemented);
754789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return Py_NotImplemented;
755789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
756789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
757789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
758789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic int
759789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
760789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
761789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (self->base != NULL)
762789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_VISIT(self->base);
763789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    if (self->view.obj != NULL)
764789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_VISIT(self->view.obj);
765789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return 0;
766789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
767789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
768789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic int
769789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroumemory_clear(PyMemoryViewObject *self)
770789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou{
771789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_CLEAR(self->base);
772789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyBuffer_Release(&self->view);
773789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    return 0;
774789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou}
775789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
776789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
777789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/* As mapping */
778789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyMappingMethods memory_as_mapping = {
779789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (lenfunc)memory_length,               /* mp_length */
780789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (binaryfunc)memory_subscript,         /* mp_subscript */
781789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (objobjargproc)memory_ass_sub,        /* mp_ass_subscript */
782789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou};
783789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
78462641e9534d7b085e21285921c70f3e8ee786929Raymond Hettingerstatic PySequenceMethods memory_as_sequence = {
78562641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger	0,                                  /* sq_length */
78662641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger	0,                                  /* sq_concat */
78762641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger	0,                                  /* sq_repeat */
78862641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger	(ssizeargfunc)memory_item,          /* sq_item */
78962641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger};
790789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
791789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou/* Buffer methods */
792789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitroustatic PyBufferProcs memory_as_buffer = {
793789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                    /* bf_getreadbuffer */
794789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                    /* bf_getwritebuffer */
795789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                    /* bf_getsegcount */
796789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                    /* bf_getcharbuffer */
797789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (getbufferproc)memory_getbuf,         /* bf_getbuffer */
798789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
799789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou};
800789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
801789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou
802789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine PitrouPyTypeObject PyMemoryView_Type = {
803789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyVarObject_HEAD_INIT(&PyType_Type, 0)
804789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    "memoryview",
805789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    sizeof(PyMemoryViewObject),
806789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,
807789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (destructor)memory_dealloc,               /* tp_dealloc */
808789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_print */
809789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_getattr */
810789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_setattr */
811789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_compare */
812789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (reprfunc)memory_repr,                    /* tp_repr */
813789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_as_number */
81462641e9534d7b085e21285921c70f3e8ee786929Raymond Hettinger    &memory_as_sequence,                      /* tp_as_sequence */
815789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    &memory_as_mapping,                       /* tp_as_mapping */
816789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_hash */
817789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_call */
818789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_str */
819789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    PyObject_GenericGetAttr,                  /* tp_getattro */
820789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_setattro */
821789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    &memory_as_buffer,                        /* tp_as_buffer */
822789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
823789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou        Py_TPFLAGS_HAVE_NEWBUFFER,            /* tp_flags */
824789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    memory_doc,                               /* tp_doc */
825789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (traverseproc)memory_traverse,            /* tp_traverse */
826789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    (inquiry)memory_clear,                    /* tp_clear */
827789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    memory_richcompare,                       /* tp_richcompare */
828789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_weaklistoffset */
829789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_iter */
830789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_iternext */
831789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    memory_methods,                           /* tp_methods */
832789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_members */
833789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    memory_getsetlist,                        /* tp_getset */
834789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_base */
835789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_dict */
836789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_descr_get */
837789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_descr_set */
838789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_dictoffset */
839789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_init */
840789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    0,                                        /* tp_alloc */
841789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou    memory_new,                               /* tp_new */
842789be0c0a0656d17f831aa781cf7c5d55e5b4835Antoine Pitrou};
843