summaryrefslogtreecommitdiff
path: root/Objects/memoryobject.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2009-06-23 20:59:43 +0000
committerRaymond Hettinger <python@rcn.com>2009-06-23 20:59:43 +0000
commit44a0a7ac9f1bbc975f0905e842115283f0c9c79a (patch)
tree69d2d5771b2bb38a6848a3d28974207a899c10e9 /Objects/memoryobject.c
parent475585475e3af61a3074bacf867b05f48323b7d3 (diff)
downloadcpython-44a0a7ac9f1bbc975f0905e842115283f0c9c79a.tar.gz
Issue 6329: Fix iteration for memoryviews.
Diffstat (limited to 'Objects/memoryobject.c')
-rw-r--r--Objects/memoryobject.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
index 1828cef330..9427522c36 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -513,6 +513,49 @@ memory_length(PyMemoryViewObject *self)
return get_shape0(&self->view);
}
+/* Alternate version of memory_subcript that only accepts indices.
+ Used by PySeqIter_New().
+*/
+static PyObject *
+memory_item(PyMemoryViewObject *self, Py_ssize_t result)
+{
+ Py_buffer *view = &(self->view);
+
+ if (view->ndim == 0) {
+ PyErr_SetString(PyExc_IndexError,
+ "invalid indexing of 0-dim memory");
+ return NULL;
+ }
+ if (view->ndim == 1) {
+ /* Return a bytes object */
+ char *ptr;
+ ptr = (char *)view->buf;
+ if (result < 0) {
+ result += get_shape0(view);
+ }
+ if ((result < 0) || (result >= get_shape0(view))) {
+ PyErr_SetString(PyExc_IndexError,
+ "index out of bounds");
+ return NULL;
+ }
+ if (view->strides == NULL)
+ ptr += view->itemsize * result;
+ else
+ ptr += view->strides[0] * result;
+ if (view->suboffsets != NULL &&
+ view->suboffsets[0] >= 0) {
+ ptr = *((char **)ptr) + view->suboffsets[0];
+ }
+ return PyBytes_FromStringAndSize(ptr, view->itemsize);
+ } else {
+ /* Return a new memory-view object */
+ Py_buffer newview;
+ memset(&newview, 0, sizeof(newview));
+ /* XXX: This needs to be fixed so it actually returns a sub-view */
+ return PyMemoryView_FromBuffer(&newview);
+ }
+}
+
/*
mem[obj] returns a bytes object holding the data for one element if
obj fully indexes the memory view or another memory-view object
@@ -544,37 +587,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key)
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);
- }
+ return memory_item(self, result);
}
else if (PySlice_Check(key)) {
Py_ssize_t start, stop, step, slicelength;
@@ -779,6 +792,12 @@ static PyMappingMethods memory_as_mapping = {
(objobjargproc)memory_ass_sub, /* mp_ass_subscript */
};
+static PySequenceMethods memory_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ (ssizeargfunc)memory_item, /* sq_item */
+};
/* Buffer methods */
static PyBufferProcs memory_as_buffer = {
@@ -803,7 +822,7 @@ PyTypeObject PyMemoryView_Type = {
0, /* tp_compare */
(reprfunc)memory_repr, /* tp_repr */
0, /* tp_as_number */
- 0, /* tp_as_sequence */
+ &memory_as_sequence, /* tp_as_sequence */
&memory_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */