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