summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Include/memoryobject.h70
-rw-r--r--Objects/memoryobject.c863
2 files changed, 466 insertions, 467 deletions
diff --git a/Include/memoryobject.h b/Include/memoryobject.h
index 3888259124..bf0b621ab9 100644
--- a/Include/memoryobject.h
+++ b/Include/memoryobject.h
@@ -20,53 +20,53 @@ PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base,
int buffertype,
char fort);
- /* Return a contiguous chunk of memory representing the buffer
- from an object in a memory view object. If a copy is made then the
- base object for the memory view will be a *new* bytes object.
-
- Otherwise, the base-object will be the object itself and no
- data-copying will be done.
+ /* Return a contiguous chunk of memory representing the buffer
+ from an object in a memory view object. If a copy is made then the
+ base object for the memory view will be a *new* bytes object.
+
+ Otherwise, the base-object will be the object itself and no
+ data-copying will be done.
- The buffertype argument can be PyBUF_READ, PyBUF_WRITE,
- PyBUF_SHADOW to determine whether the returned buffer
- should be READONLY, WRITABLE, or set to update the
- original buffer if a copy must be made. If buffertype is
- PyBUF_WRITE and the buffer is not contiguous an error will
- be raised. In this circumstance, the user can use
- PyBUF_SHADOW to ensure that a a writable temporary
- contiguous buffer is returned. The contents of this
- contiguous buffer will be copied back into the original
- object after the memoryview object is deleted as long as
- the original object is writable and allows setting an
- exclusive write lock. If this is not allowed by the
- original object, then a BufferError is raised.
-
- If the object is multi-dimensional and if fortran is 'F',
- the first dimension of the underlying array will vary the
- fastest in the buffer. If fortran is 'C', then the last
- dimension will vary the fastest (C-style contiguous). If
- fortran is 'A', then it does not matter and you will get
- whatever the object decides is more efficient.
+ The buffertype argument can be PyBUF_READ, PyBUF_WRITE,
+ PyBUF_SHADOW to determine whether the returned buffer
+ should be READONLY, WRITABLE, or set to update the
+ original buffer if a copy must be made. If buffertype is
+ PyBUF_WRITE and the buffer is not contiguous an error will
+ be raised. In this circumstance, the user can use
+ PyBUF_SHADOW to ensure that a a writable temporary
+ contiguous buffer is returned. The contents of this
+ contiguous buffer will be copied back into the original
+ object after the memoryview object is deleted as long as
+ the original object is writable and allows setting an
+ exclusive write lock. If this is not allowed by the
+ original object, then a BufferError is raised.
+
+ If the object is multi-dimensional and if fortran is 'F',
+ the first dimension of the underlying array will vary the
+ fastest in the buffer. If fortran is 'C', then the last
+ dimension will vary the fastest (C-style contiguous). If
+ fortran is 'A', then it does not matter and you will get
+ whatever the object decides is more efficient.
- A new reference is returned that must be DECREF'd when finished.
- */
+ A new reference is returned that must be DECREF'd when finished.
+ */
PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base);
PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info);
- /* create new if bufptr is NULL
- will be a new bytesobject in base */
+ /* create new if bufptr is NULL
+ will be a new bytesobject in base */
+
-
/* The struct is declared here so that macros can work, but it shouldn't
be considered public. Don't access those fields directly, use the macros
and functions instead! */
typedef struct {
- PyObject_HEAD
- PyObject *base;
- Py_buffer view;
+ PyObject_HEAD
+ PyObject *base;
+ Py_buffer view;
} PyMemoryViewObject;
-
+
#ifdef __cplusplus
}
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index df89313285..0b65d44370 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -33,21 +33,21 @@ dup_buffer(Py_buffer *dest, Py_buffer *src)
static int
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
- int res = 0;
- /* XXX for whatever reason fixing the flags seems necessary */
- if (self->view.readonly)
- flags &= ~PyBUF_WRITABLE;
- if (self->view.obj != NULL)
- res = PyObject_GetBuffer(self->view.obj, view, flags);
- if (view)
- dup_buffer(view, &self->view);
- return res;
+ int res = 0;
+ /* XXX for whatever reason fixing the flags seems necessary */
+ if (self->view.readonly)
+ flags &= ~PyBUF_WRITABLE;
+ if (self->view.obj != NULL)
+ res = PyObject_GetBuffer(self->view.obj, view, flags);
+ if (view)
+ dup_buffer(view, &self->view);
+ return res;
}
static void
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
{
- PyBuffer_Release(view);
+ PyBuffer_Release(view);
}
PyDoc_STRVAR(memory_doc,
@@ -58,61 +58,61 @@ Create a new memoryview object which references the given object.");
PyObject *
PyMemoryView_FromBuffer(Py_buffer *info)
{
- PyMemoryViewObject *mview;
-
- mview = (PyMemoryViewObject *)
- PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
- if (mview == NULL)
- return NULL;
- mview->base = NULL;
- dup_buffer(&mview->view, info);
- /* NOTE: mview->view.obj should already have been incref'ed as
- part of PyBuffer_FillInfo(). */
- _PyObject_GC_TRACK(mview);
- return (PyObject *)mview;
+ PyMemoryViewObject *mview;
+
+ mview = (PyMemoryViewObject *)
+ PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mview == NULL)
+ return NULL;
+ mview->base = NULL;
+ dup_buffer(&mview->view, info);
+ /* NOTE: mview->view.obj should already have been incref'ed as
+ part of PyBuffer_FillInfo(). */
+ _PyObject_GC_TRACK(mview);
+ return (PyObject *)mview;
}
PyObject *
PyMemoryView_FromObject(PyObject *base)
{
- PyMemoryViewObject *mview;
+ PyMemoryViewObject *mview;
- if (!PyObject_CheckBuffer(base)) {
- PyErr_SetString(PyExc_TypeError,
- "cannot make memory view because object does "
- "not have the buffer interface");
- return NULL;
- }
+ if (!PyObject_CheckBuffer(base)) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot make memory view because object does "
+ "not have the buffer interface");
+ return NULL;
+ }
- mview = (PyMemoryViewObject *)
- PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
- if (mview == NULL)
- return NULL;
+ mview = (PyMemoryViewObject *)
+ PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mview == NULL)
+ return NULL;
- mview->base = NULL;
- if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL_RO) < 0) {
- Py_DECREF(mview);
- return NULL;
- }
+ mview->base = NULL;
+ if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL_RO) < 0) {
+ Py_DECREF(mview);
+ return NULL;
+ }
- mview->base = base;
- Py_INCREF(base);
- _PyObject_GC_TRACK(mview);
- return (PyObject *)mview;
+ mview->base = base;
+ Py_INCREF(base);
+ _PyObject_GC_TRACK(mview);
+ return (PyObject *)mview;
}
static PyObject *
memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
- PyObject *obj;
- static char *kwlist[] = {"object", 0};
+ PyObject *obj;
+ static char *kwlist[] = {"object", 0};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
- &obj)) {
- return NULL;
- }
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
+ &obj)) {
+ return NULL;
+ }
- return PyMemoryView_FromObject(obj);
+ return PyMemoryView_FromObject(obj);
}
@@ -120,58 +120,58 @@ static void
_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
{
- int k;
- Py_ssize_t outstride;
+ int k;
+ Py_ssize_t outstride;
- if (nd==0) {
- memcpy(dest, src, itemsize);
+ if (nd==0) {
+ memcpy(dest, src, itemsize);
+ }
+ else if (nd == 1) {
+ for (k = 0; k<shape[0]; k++) {
+ memcpy(dest, src, itemsize);
+ dest += itemsize;
+ src += strides[0];
}
- else if (nd == 1) {
- for (k = 0; k<shape[0]; k++) {
- memcpy(dest, src, itemsize);
- dest += itemsize;
- src += strides[0];
- }
+ }
+ else {
+ if (fort == 'F') {
+ /* Copy first dimension first,
+ second dimension second, etc...
+ Set up the recursive loop backwards so that final
+ dimension is actually copied last.
+ */
+ outstride = itemsize;
+ for (k=1; k<nd-1;k++) {
+ outstride *= shape[k];
+ }
+ for (k=0; k<shape[nd-1]; k++) {
+ _strided_copy_nd(dest, src, nd-1, shape,
+ strides, itemsize, fort);
+ dest += outstride;
+ src += strides[nd-1];
+ }
}
+
else {
- if (fort == 'F') {
- /* Copy first dimension first,
- second dimension second, etc...
- Set up the recursive loop backwards so that final
- dimension is actually copied last.
- */
- outstride = itemsize;
- for (k=1; k<nd-1;k++) {
- outstride *= shape[k];
- }
- for (k=0; k<shape[nd-1]; k++) {
- _strided_copy_nd(dest, src, nd-1, shape,
- strides, itemsize, fort);
- dest += outstride;
- src += strides[nd-1];
- }
- }
-
- else {
- /* Copy last dimension first,
- second-to-last dimension second, etc.
- Set up the recursion so that the
- first dimension is copied last
- */
- outstride = itemsize;
- for (k=1; k < nd; k++) {
- outstride *= shape[k];
- }
- for (k=0; k<shape[0]; k++) {
- _strided_copy_nd(dest, src, nd-1, shape+1,
- strides+1, itemsize,
- fort);
- dest += outstride;
- src += strides[0];
- }
- }
+ /* Copy last dimension first,
+ second-to-last dimension second, etc.
+ Set up the recursion so that the
+ first dimension is copied last
+ */
+ outstride = itemsize;
+ for (k=1; k < nd; k++) {
+ outstride *= shape[k];
+ }
+ for (k=0; k<shape[0]; k++) {
+ _strided_copy_nd(dest, src, nd-1, shape+1,
+ strides+1, itemsize,
+ fort);
+ dest += outstride;
+ src += strides[0];
+ }
}
- return;
+ }
+ return;
}
void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
@@ -180,45 +180,45 @@ void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);
static int
_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
{
- Py_ssize_t *indices;
- int k;
- Py_ssize_t elements;
- char *ptr;
- void (*func)(int, Py_ssize_t *, Py_ssize_t *);
-
- if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
- PyErr_NoMemory();
- return -1;
- }
+ Py_ssize_t *indices;
+ int k;
+ Py_ssize_t elements;
+ char *ptr;
+ void (*func)(int, Py_ssize_t *, Py_ssize_t *);
+
+ if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
+ PyErr_NoMemory();
+ return -1;
+ }
- indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
- if (indices == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- for (k=0; k<view->ndim;k++) {
- indices[k] = 0;
- }
+ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
+ if (indices == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ for (k=0; k<view->ndim;k++) {
+ indices[k] = 0;
+ }
- elements = 1;
- for (k=0; k<view->ndim; k++) {
- elements *= view->shape[k];
- }
- if (fort == 'F') {
- func = _add_one_to_index_F;
- }
- else {
- func = _add_one_to_index_C;
- }
- while (elements--) {
- func(view->ndim, indices, view->shape);
- ptr = PyBuffer_GetPointer(view, indices);
- memcpy(dest, ptr, view->itemsize);
- dest += view->itemsize;
- }
+ elements = 1;
+ for (k=0; k<view->ndim; k++) {
+ elements *= view->shape[k];
+ }
+ if (fort == 'F') {
+ func = _add_one_to_index_F;
+ }
+ else {
+ func = _add_one_to_index_C;
+ }
+ while (elements--) {
+ func(view->ndim, indices, view->shape);
+ ptr = PyBuffer_GetPointer(view, indices);
+ memcpy(dest, ptr, view->itemsize);
+ dest += view->itemsize;
+ }
- PyMem_Free(indices);
- return 0;
+ PyMem_Free(indices);
+ return 0;
}
/*
@@ -240,181 +240,181 @@ _indirect_copy_nd(char *dest, Py_buffer *view, char fort)
the shadow buffer which can be written to and then
will be copied back into the other buffer when the memory
view is de-allocated. While the shadow buffer is
- being used, it will have an exclusive write lock on
- the original buffer.
+ being used, it will have an exclusive write lock on
+ the original buffer.
*/
PyObject *
PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
{
- PyMemoryViewObject *mem;
- PyObject *bytes;
- Py_buffer *view;
- int flags;
- char *dest;
-
- if (!PyObject_CheckBuffer(obj)) {
- PyErr_SetString(PyExc_TypeError,
- "object does not have the buffer interface");
- return NULL;
- }
+ PyMemoryViewObject *mem;
+ PyObject *bytes;
+ Py_buffer *view;
+ int flags;
+ char *dest;
- mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
- if (mem == NULL)
- return NULL;
+ if (!PyObject_CheckBuffer(obj)) {
+ PyErr_SetString(PyExc_TypeError,
+ "object does not have the buffer interface");
+ return NULL;
+ }
- view = &mem->view;
- flags = PyBUF_FULL_RO;
- switch(buffertype) {
- case PyBUF_WRITE:
- flags = PyBUF_FULL;
- break;
- }
+ mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
+ if (mem == NULL)
+ return NULL;
- if (PyObject_GetBuffer(obj, view, flags) != 0) {
- Py_DECREF(mem);
- return NULL;
- }
+ view = &mem->view;
+ flags = PyBUF_FULL_RO;
+ switch(buffertype) {
+ case PyBUF_WRITE:
+ flags = PyBUF_FULL;
+ break;
+ }
- if (PyBuffer_IsContiguous(view, fort)) {
- /* no copy needed */
- Py_INCREF(obj);
- mem->base = obj;
- _PyObject_GC_TRACK(mem);
- return (PyObject *)mem;
- }
- /* otherwise a copy is needed */
- if (buffertype == PyBUF_WRITE) {
- Py_DECREF(mem);
- PyErr_SetString(PyExc_BufferError,
- "writable contiguous buffer requested "
- "for a non-contiguousobject.");
- return NULL;
- }
- bytes = PyBytes_FromStringAndSize(NULL, view->len);
- if (bytes == NULL) {
- Py_DECREF(mem);
- return NULL;
- }
- dest = PyBytes_AS_STRING(bytes);
- /* different copying strategy depending on whether
- or not any pointer de-referencing is needed
- */
- /* strided or in-direct copy */
- if (view->suboffsets==NULL) {
- _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
- view->strides, view->itemsize, fort);
- }
- else {
- if (_indirect_copy_nd(dest, view, fort) < 0) {
- Py_DECREF(bytes);
- Py_DECREF(mem);
- return NULL;
- }
- }
- if (buffertype == PyBUF_SHADOW) {
- /* return a shadowed memory-view object */
- view->buf = dest;
- mem->base = PyTuple_Pack(2, obj, bytes);
- Py_DECREF(bytes);
- if (mem->base == NULL) {
- Py_DECREF(mem);
- return NULL;
- }
+ if (PyObject_GetBuffer(obj, view, flags) != 0) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+
+ if (PyBuffer_IsContiguous(view, fort)) {
+ /* no copy needed */
+ Py_INCREF(obj);
+ mem->base = obj;
+ _PyObject_GC_TRACK(mem);
+ return (PyObject *)mem;
+ }
+ /* otherwise a copy is needed */
+ if (buffertype == PyBUF_WRITE) {
+ Py_DECREF(mem);
+ PyErr_SetString(PyExc_BufferError,
+ "writable contiguous buffer requested "
+ "for a non-contiguousobject.");
+ return NULL;
+ }
+ bytes = PyBytes_FromStringAndSize(NULL, view->len);
+ if (bytes == NULL) {
+ Py_DECREF(mem);
+ return NULL;
+ }
+ dest = PyBytes_AS_STRING(bytes);
+ /* different copying strategy depending on whether
+ or not any pointer de-referencing is needed
+ */
+ /* strided or in-direct copy */
+ if (view->suboffsets==NULL) {
+ _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
+ view->strides, view->itemsize, fort);
+ }
+ else {
+ if (_indirect_copy_nd(dest, view, fort) < 0) {
+ Py_DECREF(bytes);
+ Py_DECREF(mem);
+ return NULL;
}
- else {
- PyBuffer_Release(view); /* XXX ? */
- /* steal the reference */
- mem->base = bytes;
+ }
+ if (buffertype == PyBUF_SHADOW) {
+ /* return a shadowed memory-view object */
+ view->buf = dest;
+ mem->base = PyTuple_Pack(2, obj, bytes);
+ Py_DECREF(bytes);
+ if (mem->base == NULL) {
+ Py_DECREF(mem);
+ return NULL;
}
- _PyObject_GC_TRACK(mem);
- return (PyObject *)mem;
+ }
+ else {
+ PyBuffer_Release(view); /* XXX ? */
+ /* steal the reference */
+ mem->base = bytes;
+ }
+ _PyObject_GC_TRACK(mem);
+ return (PyObject *)mem;
}
static PyObject *
memory_format_get(PyMemoryViewObject *self)
{
- return PyUnicode_FromString(self->view.format);
+ return PyUnicode_FromString(self->view.format);
}
static PyObject *
memory_itemsize_get(PyMemoryViewObject *self)
{
- return PyLong_FromSsize_t(self->view.itemsize);
+ return PyLong_FromSsize_t(self->view.itemsize);
}
static PyObject *
_IntTupleFromSsizet(int len, Py_ssize_t *vals)
{
- int i;
- PyObject *o;
- PyObject *intTuple;
+ int i;
+ PyObject *o;
+ PyObject *intTuple;
- if (vals == NULL) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- intTuple = PyTuple_New(len);
- if (!intTuple) return NULL;
- for(i=0; i<len; i++) {
- o = PyLong_FromSsize_t(vals[i]);
- if (!o) {
- Py_DECREF(intTuple);
- return NULL;
- }
- PyTuple_SET_ITEM(intTuple, i, o);
- }
- return intTuple;
+ if (vals == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ intTuple = PyTuple_New(len);
+ if (!intTuple) return NULL;
+ for(i=0; i<len; i++) {
+ o = PyLong_FromSsize_t(vals[i]);
+ if (!o) {
+ Py_DECREF(intTuple);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(intTuple, i, o);
+ }
+ return intTuple;
}
static PyObject *
memory_shape_get(PyMemoryViewObject *self)
{
- return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
+ return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
}
static PyObject *
memory_strides_get(PyMemoryViewObject *self)
{
- return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
+ return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
}
static PyObject *
memory_suboffsets_get(PyMemoryViewObject *self)
{
- return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
+ return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
}
static PyObject *
memory_readonly_get(PyMemoryViewObject *self)
{
- return PyBool_FromLong(self->view.readonly);
+ return PyBool_FromLong(self->view.readonly);
}
static PyObject *
memory_ndim_get(PyMemoryViewObject *self)
{
- return PyLong_FromLong(self->view.ndim);
+ return PyLong_FromLong(self->view.ndim);
}
static PyGetSetDef memory_getsetlist[] ={
- {"format", (getter)memory_format_get, NULL, NULL},
- {"itemsize", (getter)memory_itemsize_get, NULL, NULL},
- {"shape", (getter)memory_shape_get, NULL, NULL},
- {"strides", (getter)memory_strides_get, NULL, NULL},
- {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL},
- {"readonly", (getter)memory_readonly_get, NULL, NULL},
- {"ndim", (getter)memory_ndim_get, NULL, NULL},
- {NULL, NULL, NULL, NULL},
+ {"format", (getter)memory_format_get, NULL, NULL},
+ {"itemsize", (getter)memory_itemsize_get, NULL, NULL},
+ {"shape", (getter)memory_shape_get, NULL, NULL},
+ {"strides", (getter)memory_strides_get, NULL, NULL},
+ {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL},
+ {"readonly", (getter)memory_readonly_get, NULL, NULL},
+ {"ndim", (getter)memory_ndim_get, NULL, NULL},
+ {NULL, NULL, NULL, NULL},
};
static PyObject *
memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
{
- return PyObject_CallFunctionObjArgs(
- (PyObject *) &PyBytes_Type, mem, NULL);
+ return PyObject_CallFunctionObjArgs(
+ (PyObject *) &PyBytes_Type, mem, NULL);
}
/* TODO: rewrite this function using the struct module to unpack
@@ -423,59 +423,59 @@ memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
static PyObject *
memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
{
- Py_buffer *view = &(mem->view);
- Py_ssize_t i;
- PyObject *res, *item;
- char *buf;
-
- if (strcmp(view->format, "B") || view->itemsize != 1) {
- PyErr_SetString(PyExc_NotImplementedError,
- "tolist() only supports byte views");
- return NULL;
- }
- if (view->ndim != 1) {
- PyErr_SetString(PyExc_NotImplementedError,
- "tolist() only supports one-dimensional objects");
- return NULL;
- }
- res = PyList_New(view->len);
- if (res == NULL)
- return NULL;
- buf = view->buf;
- for (i = 0; i < view->len; i++) {
- item = PyLong_FromUnsignedLong((unsigned char) *buf);
- if (item == NULL) {
- Py_DECREF(res);
- return NULL;
- }
- PyList_SET_ITEM(res, i, item);
- buf++;
- }
- return res;
+ Py_buffer *view = &(mem->view);
+ Py_ssize_t i;
+ PyObject *res, *item;
+ char *buf;
+
+ if (strcmp(view->format, "B") || view->itemsize != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "tolist() only supports byte views");
+ return NULL;
+ }
+ if (view->ndim != 1) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "tolist() only supports one-dimensional objects");
+ return NULL;
+ }
+ res = PyList_New(view->len);
+ if (res == NULL)
+ return NULL;
+ buf = view->buf;
+ for (i = 0; i < view->len; i++) {
+ item = PyLong_FromUnsignedLong((unsigned char) *buf);
+ if (item == NULL) {
+ Py_DECREF(res);
+ return NULL;
+ }
+ PyList_SET_ITEM(res, i, item);
+ buf++;
+ }
+ return res;
}
static PyMethodDef memory_methods[] = {
- {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
- {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
- {NULL, NULL} /* sentinel */
+ {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
+ {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
+ {NULL, NULL} /* sentinel */
};
static void
memory_dealloc(PyMemoryViewObject *self)
{
- _PyObject_GC_UNTRACK(self);
- if (self->view.obj != NULL) {
- if (self->base && PyTuple_Check(self->base)) {
- /* Special case when first element is generic object
- with buffer interface and the second element is a
- contiguous "shadow" that must be copied back into
- the data areay of the first tuple element before
- releasing the buffer on the first element.
- */
-
- PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
- PyTuple_GET_ITEM(self->base,1));
+ _PyObject_GC_UNTRACK(self);
+ if (self->view.obj != NULL) {
+ if (self->base && PyTuple_Check(self->base)) {
+ /* Special case when first element is generic object
+ with buffer interface and the second element is a
+ contiguous "shadow" that must be copied back into
+ the data areay of the first tuple element before
+ releasing the buffer on the first element.
+ */
+
+ PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
+ PyTuple_GET_ITEM(self->base,1));
/* The view member should have readonly == -1 in
this instance indicating that the memory can
@@ -495,23 +495,23 @@ memory_dealloc(PyMemoryViewObject *self)
static PyObject *
memory_repr(PyMemoryViewObject *self)
{
- return PyUnicode_FromFormat("<memory at %p>", self);
+ return PyUnicode_FromFormat("<memory at %p>", self);
}
static PyObject *
memory_str(PyMemoryViewObject *self)
{
- Py_buffer view;
- PyObject *res;
+ Py_buffer view;
+ PyObject *res;
- if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
- return NULL;
+ if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
+ return NULL;
- res = PyBytes_FromStringAndSize(NULL, view.len);
- PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
- PyBuffer_Release(&view);
- return res;
+ res = PyBytes_FromStringAndSize(NULL, view.len);
+ PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
+ PyBuffer_Release(&view);
+ return res;
}
/* Sequence methods */
@@ -524,10 +524,10 @@ memory_length(PyMemoryViewObject *self)
/*
mem[obj] returns a bytes object holding the data for one element if
obj fully indexes the memory view or another memory-view object
- if it does not.
+ if it does not.
- 0-d memory-view objects can be referenced using ... or () but
- not with anything else.
+ 0-d memory-view objects can be referenced using ... or () but
+ not with anything else.
*/
static PyObject *
memory_subscript(PyMemoryViewObject *self, PyObject *key)
@@ -536,61 +536,60 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
view = &(self->view);
if (view->ndim == 0) {
- if (key == Py_Ellipsis ||
- (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
- Py_INCREF(self);
- return (PyObject *)self;
- }
- else {
- PyErr_SetString(PyExc_IndexError,
- "invalid indexing of 0-dim memory");
- return NULL;
- }
+ if (key == Py_Ellipsis ||
+ (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid indexing of 0-dim memory");
+ return NULL;
+ }
}
if (PyIndex_Check(key)) {
- Py_ssize_t result;
- result = PyNumber_AsSsize_t(key, NULL);
- if (result == -1 && PyErr_Occurred())
- return NULL;
- if (view->ndim == 1) {
- /* Return a bytes object */
- char *ptr;
- ptr = (char *)view->buf;
- if (result < 0) {
+ Py_ssize_t result;
+ result = PyNumber_AsSsize_t(key, NULL);
+ if (result == -1 && PyErr_Occurred())
+ return NULL;
+ if (view->ndim == 1) {
+ /* Return a bytes object */
+ char *ptr;
+ ptr = (char *)view->buf;
+ if (result < 0) {
result += get_shape0(view);
- }
+ }
if ((result < 0) || (result >= get_shape0(view))) {
- PyErr_SetString(PyExc_IndexError,
- "index out of bounds");
- return NULL;
- }
- if (view->strides == NULL)
- ptr += view->itemsize * result;
- else
- ptr += view->strides[0] * result;
- if (view->suboffsets != NULL &&
- view->suboffsets[0] >= 0)
- {
- ptr = *((char **)ptr) + view->suboffsets[0];
- }
- return PyBytes_FromStringAndSize(ptr, view->itemsize);
- }
- else {
- /* Return a new memory-view object */
- Py_buffer newview;
- memset(&newview, 0, sizeof(newview));
- /* XXX: This needs to be fixed so it
- actually returns a sub-view
- */
- return PyMemoryView_FromBuffer(&newview);
- }
+ PyErr_SetString(PyExc_IndexError,
+ "index out of bounds");
+ return NULL;
+ }
+ if (view->strides == NULL)
+ ptr += view->itemsize * result;
+ else
+ ptr += view->strides[0] * result;
+ if (view->suboffsets != NULL &&
+ view->suboffsets[0] >= 0) {
+ ptr = *((char **)ptr) + view->suboffsets[0];
+ }
+ return PyBytes_FromStringAndSize(ptr, view->itemsize);
+ }
+ else {
+ /* Return a new memory-view object */
+ Py_buffer newview;
+ memset(&newview, 0, sizeof(newview));
+ /* XXX: This needs to be fixed so it
+ actually returns a sub-view
+ */
+ return PyMemoryView_FromBuffer(&newview);
+ }
}
else if (PySlice_Check(key)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view),
&start, &stop, &step, &slicelength) < 0) {
- return NULL;
+ return NULL;
}
if (step == 1 && view->ndim == 1) {
@@ -620,8 +619,8 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
return NULL;
}
PyErr_Format(PyExc_TypeError,
- "cannot index memory using \"%.200s\"",
- key->ob_type->tp_name);
+ "cannot index memory using \"%.200s\"",
+ key->ob_type->tp_name);
return NULL;
}
@@ -722,118 +721,118 @@ _error:
static PyObject *
memory_richcompare(PyObject *v, PyObject *w, int op)
{
- Py_buffer vv, ww;
- int equal = 0;
- PyObject *res;
-
- vv.obj = NULL;
- ww.obj = NULL;
- if (op != Py_EQ && op != Py_NE)
- goto _notimpl;
- if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
- PyErr_Clear();
- goto _notimpl;
- }
- if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
- PyErr_Clear();
- goto _notimpl;
- }
-
- if (vv.itemsize != ww.itemsize || vv.len != ww.len)
- goto _end;
-
- equal = !memcmp(vv.buf, ww.buf, vv.len);
+ Py_buffer vv, ww;
+ int equal = 0;
+ PyObject *res;
+
+ vv.obj = NULL;
+ ww.obj = NULL;
+ if (op != Py_EQ && op != Py_NE)
+ goto _notimpl;
+ if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
+ PyErr_Clear();
+ goto _notimpl;
+ }
+ if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
+ PyErr_Clear();
+ goto _notimpl;
+ }
+
+ if (vv.itemsize != ww.itemsize || vv.len != ww.len)
+ goto _end;
+
+ equal = !memcmp(vv.buf, ww.buf, vv.len);
_end:
- PyBuffer_Release(&vv);
- PyBuffer_Release(&ww);
- if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
- res = Py_True;
- else
- res = Py_False;
- Py_INCREF(res);
- return res;
+ PyBuffer_Release(&vv);
+ PyBuffer_Release(&ww);
+ if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
_notimpl:
- PyBuffer_Release(&vv);
- PyBuffer_Release(&ww);
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ PyBuffer_Release(&vv);
+ PyBuffer_Release(&ww);
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
}
static int
memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
{
- if (self->base != NULL)
- Py_VISIT(self->base);
- if (self->view.obj != NULL)
- Py_VISIT(self->view.obj);
- return 0;
+ if (self->base != NULL)
+ Py_VISIT(self->base);
+ if (self->view.obj != NULL)
+ Py_VISIT(self->view.obj);
+ return 0;
}
static int
memory_clear(PyMemoryViewObject *self)
{
- Py_CLEAR(self->base);
- PyBuffer_Release(&self->view);
- return 0;
+ Py_CLEAR(self->base);
+ PyBuffer_Release(&self->view);
+ return 0;
}
/* As mapping */
static PyMappingMethods memory_as_mapping = {
- (lenfunc)memory_length, /*mp_length*/
- (binaryfunc)memory_subscript, /*mp_subscript*/
- (objobjargproc)memory_ass_sub, /*mp_ass_subscript*/
+ (lenfunc)memory_length, /* mp_length */
+ (binaryfunc)memory_subscript, /* mp_subscript */
+ (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
};
/* Buffer methods */
static PyBufferProcs memory_as_buffer = {
- (getbufferproc)memory_getbuf, /* bf_getbuffer */
- (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
+ (getbufferproc)memory_getbuf, /* bf_getbuffer */
+ (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
};
PyTypeObject PyMemoryView_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "memoryview",
- sizeof(PyMemoryViewObject),
- 0,
- (destructor)memory_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc)memory_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- &memory_as_mapping, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)memory_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- &memory_as_buffer, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
- memory_doc, /* tp_doc */
- (traverseproc)memory_traverse, /* tp_traverse */
- (inquiry)memory_clear, /* tp_clear */
- memory_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- memory_methods, /* tp_methods */
- 0, /* tp_members */
- memory_getsetlist, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- memory_new, /* tp_new */
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "memoryview",
+ sizeof(PyMemoryViewObject),
+ 0,
+ (destructor)memory_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)memory_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ &memory_as_mapping, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)memory_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &memory_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ memory_doc, /* tp_doc */
+ (traverseproc)memory_traverse, /* tp_traverse */
+ (inquiry)memory_clear, /* tp_clear */
+ memory_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ memory_methods, /* tp_methods */
+ 0, /* tp_members */
+ memory_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ memory_new, /* tp_new */
};