blob: d06d7e505f5ce404dd6e1f100ae6c18a76728173 [file] [log] [blame]
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001
2/* Memoryview object implementation */
3
4#include "Python.h"
5
6static int
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +00007memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00008{
Guido van Rossum5dde61d2007-09-25 22:10:05 +00009 if (view != NULL)
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +000010 *view = self->view;
Guido van Rossum5dde61d2007-09-25 22:10:05 +000011 return self->base->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
12 PyBUF_FULL);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000013}
14
15static void
Guido van Rossum5dde61d2007-09-25 22:10:05 +000016memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000017{
18 PyObject_ReleaseBuffer(self->base, NULL);
19}
20
21PyDoc_STRVAR(memory_doc,
22"memoryview(object)\n\
23\n\
24Create a new memoryview object which references the given object.");
25
26PyObject *
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +000027PyMemoryView_FromMemory(Py_buffer *info)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000028{
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +000029 PyMemoryViewObject *mview;
30
31 mview = (PyMemoryViewObject *)PyObject_New(PyMemoryViewObject,
32 &PyMemoryView_Type);
33 if (mview == NULL) return NULL;
34 mview->base = NULL;
35 mview->view = *info;
36 return (PyObject *)mview;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000037}
38
39PyObject *
40PyMemoryView_FromObject(PyObject *base)
41{
42 PyMemoryViewObject *mview;
43
44 if (!PyObject_CheckBuffer(base)) {
Guido van Rossum5dde61d2007-09-25 22:10:05 +000045 PyErr_SetString(PyExc_TypeError,
46 "cannot make memory view because object does "
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000047 "not have the buffer interface");
Guido van Rossum5dde61d2007-09-25 22:10:05 +000048 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000049 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +000050
51 mview = (PyMemoryViewObject *)PyObject_New(PyMemoryViewObject,
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000052 &PyMemoryView_Type);
53 if (mview == NULL) return NULL;
Guido van Rossum5dde61d2007-09-25 22:10:05 +000054
Neal Norwitz666bb412007-08-19 18:38:46 +000055 mview->base = NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000056 if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL) < 0) {
Neal Norwitz666bb412007-08-19 18:38:46 +000057 Py_DECREF(mview);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000058 return NULL;
59 }
60
61 mview->base = base;
62 Py_INCREF(base);
63 return (PyObject *)mview;
64}
65
66static PyObject *
67memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
68{
69 PyObject *obj;
Neal Norwitzfaa54a32007-08-19 04:23:20 +000070 if (!PyArg_UnpackTuple(args, "memoryview", 1, 1, &obj)) return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000071
Guido van Rossum5dde61d2007-09-25 22:10:05 +000072 return PyMemoryView_FromObject(obj);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000073}
74
75
76static void
Guido van Rossum5dde61d2007-09-25 22:10:05 +000077_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape,
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000078 Py_ssize_t *strides, int itemsize, char fort)
79{
80 int k;
81 Py_ssize_t outstride;
82
83 if (nd==0) {
84 memcpy(dest, src, itemsize);
85 }
86 else if (nd == 1) {
87 for (k = 0; k<shape[0]; k++) {
88 memcpy(dest, src, itemsize);
89 dest += itemsize;
90 src += strides[0];
91 }
92 }
93 else {
94 if (fort == 'F') {
Guido van Rossum5dde61d2007-09-25 22:10:05 +000095 /* Copy first dimension first,
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000096 second dimension second, etc...
97 Set up the recursive loop backwards so that final
Guido van Rossum5dde61d2007-09-25 22:10:05 +000098 dimension is actually copied last.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +000099 */
100 outstride = itemsize;
101 for (k=1; k<nd-1;k++) {
102 outstride *= shape[k];
103 }
104 for (k=0; k<shape[nd-1]; k++) {
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000105 _strided_copy_nd(dest, src, nd-1, shape,
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000106 strides, itemsize, fort);
107 dest += outstride;
108 src += strides[nd-1];
109 }
110 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000111
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000112 else {
113 /* Copy last dimension first,
114 second-to-last dimension second, etc.
115 Set up the recursion so that the
116 first dimension is copied last
117 */
118 outstride = itemsize;
119 for (k=1; k < nd; k++) {
120 outstride *= shape[k];
121 }
122 for (k=0; k<shape[0]; k++) {
123 _strided_copy_nd(dest, src, nd-1, shape+1,
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000124 strides+1, itemsize,
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000125 fort);
126 dest += outstride;
127 src += strides[0];
128 }
129 }
130 }
131 return;
132}
133
134void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
135void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);
136
137static int
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000138_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000139{
140 Py_ssize_t *indices;
141 int k;
142 Py_ssize_t elements;
143 char *ptr;
144 void (*func)(int, Py_ssize_t *, Py_ssize_t *);
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000145
146
Neal Norwitzfaa54a32007-08-19 04:23:20 +0000147 /* XXX(nnorwitz): need to check for overflow! */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000148 indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
149 if (indices == NULL) {
150 PyErr_NoMemory();
151 return -1;
152 }
153 for (k=0; k<view->ndim;k++) {
154 indices[k] = 0;
155 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000156
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000157 elements = 1;
158 for (k=0; k<view->ndim; k++) {
159 elements *= view->shape[k];
160 }
161 if (fort == 'F') {
162 func = _add_one_to_index_F;
163 }
164 else {
165 func = _add_one_to_index_C;
166 }
167 while (elements--) {
168 func(view->ndim, indices, view->shape);
169 ptr = PyBuffer_GetPointer(view, indices);
170 memcpy(dest, ptr, view->itemsize);
171 dest += view->itemsize;
172 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000173
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000174 PyMem_Free(indices);
175 return 0;
176}
177
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000178/*
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000179 Get a the data from an object as a contiguous chunk of memory (in
180 either 'C' or 'F'ortran order) even if it means copying it into a
181 separate memory area.
182
183 Returns a new reference to a Memory view object. If no copy is needed,
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000184 the memory view object points to the original memory and holds a
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000185 lock on the original. If a copy is needed, then the memory view object
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000186 points to a brand-new Bytes object (and holds a memory lock on it).
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000187
188 buffertype
189
190 PyBUF_READ buffer only needs to be read-only
Sean Reifscheider54cf12b2007-09-17 17:55:36 +0000191 PyBUF_WRITE buffer needs to be writable (give error if not contiguous)
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000192 PyBUF_SHADOW buffer needs to be writable so shadow it with
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000193 a contiguous buffer if it is not. The view will point to
194 the shadow buffer which can be written to and then
195 will be copied back into the other buffer when the memory
196 view is de-allocated.
197 */
198
199PyObject *
200PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
201{
202 PyMemoryViewObject *mem;
203 PyObject *bytes;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000204 Py_buffer *view;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000205 int flags;
206 char *dest;
207
208 if (!PyObject_CheckBuffer(obj)) {
209 PyErr_SetString(PyExc_TypeError,
210 "object does not have the buffer interface");
211 return NULL;
212 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000213
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000214 mem = PyObject_New(PyMemoryViewObject, &PyMemoryView_Type);
215 if (mem == NULL) return NULL;
216
217 view = &PyMemoryView(mem);
218 flags = PyBUF_FULL_RO;
219 switch(buffertype) {
220 case PyBUF_WRITE:
221 flags = PyBUF_FULL;
222 break;
223 case PyBUF_SHADOW:
224 flags = PyBUF_FULL_LCK;
225 break;
226 }
227
228 if (PyObject_GetBuffer(obj, view, flags) != 0) {
229 PyObject_DEL(mem);
230 return NULL;
231 }
232
233 if (PyBuffer_IsContiguous(view, fort)) {
234 /* no copy needed */
235 Py_INCREF(obj);
236 mem->base = obj;
237 return (PyObject *)mem;
238 }
239 /* otherwise a copy is needed */
240 if (buffertype == PyBUF_WRITE) {
241 PyObject_DEL(mem);
242 PyErr_SetString(PyExc_BufferError,
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000243 "writable contiguous buffer requested "
244 "for a non-contiguousobject.");
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000245 return NULL;
246 }
247 bytes = PyBytes_FromStringAndSize(NULL, view->len);
248 if (bytes == NULL) {
249 PyObject_ReleaseBuffer(obj, view);
250 return NULL;
251 }
252 dest = PyBytes_AS_STRING(bytes);
253 /* different copying strategy depending on whether
254 or not any pointer de-referencing is needed
255 */
256 /* strided or in-direct copy */
257 if (view->suboffsets==NULL) {
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000258 _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
259 view->strides, view->itemsize, fort);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000260 }
261 else {
262 if (_indirect_copy_nd(dest, view, fort) < 0) {
263 Py_DECREF(bytes);
264 PyObject_ReleaseBuffer(obj, view);
265 return NULL;
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000266 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000267 }
268 if (buffertype == PyBUF_SHADOW) {
269 /* return a shadowed memory-view object */
270 view->buf = dest;
271 mem->base = PyTuple_Pack(2, obj, bytes);
272 Py_DECREF(bytes);
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000273 if (mem->base == NULL) {
274 PyObject_ReleaseBuffer(obj, view);
275 return NULL;
276 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000277 }
278 else {
279 PyObject_ReleaseBuffer(obj, view);
280 /* steal the reference */
281 mem->base = bytes;
282 }
283 return (PyObject *)mem;
284}
285
286
287static PyObject *
288memory_format_get(PyMemoryViewObject *self)
289{
290 return PyUnicode_FromString(self->view.format);
291}
292
293static PyObject *
294memory_itemsize_get(PyMemoryViewObject *self)
295{
296 return PyInt_FromLong(self->view.itemsize);
297}
298
299static PyObject *
300_IntTupleFromSsizet(int len, Py_ssize_t *vals)
301{
302 int i;
303 PyObject *o;
304 PyObject *intTuple;
305
306 if (vals == NULL) {
307 Py_INCREF(Py_None);
308 return Py_None;
309 }
310 intTuple = PyTuple_New(len);
311 if (!intTuple) return NULL;
312 for(i=0; i<len; i++) {
313 o = PyInt_FromSsize_t(vals[i]);
314 if (!o) {
315 Py_DECREF(intTuple);
316 return NULL;
317 }
318 PyTuple_SET_ITEM(intTuple, i, o);
319 }
320 return intTuple;
321}
322
323static PyObject *
324memory_shape_get(PyMemoryViewObject *self)
325{
326 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
327}
328
329static PyObject *
330memory_strides_get(PyMemoryViewObject *self)
331{
332 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
333}
334
335static PyObject *
336memory_suboffsets_get(PyMemoryViewObject *self)
337{
338 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
339}
340
341static PyObject *
342memory_size_get(PyMemoryViewObject *self)
343{
344 return PyInt_FromSsize_t(self->view.len);
345}
346
347static PyObject *
348memory_readonly_get(PyMemoryViewObject *self)
349{
Neal Norwitz666bb412007-08-19 18:38:46 +0000350 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000351}
352
353static PyObject *
354memory_ndim_get(PyMemoryViewObject *self)
355{
356 return PyInt_FromLong(self->view.ndim);
357}
358
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000359static PyGetSetDef memory_getsetlist[] ={
Neal Norwitz666bb412007-08-19 18:38:46 +0000360 {"format", (getter)memory_format_get, NULL, NULL},
361 {"itemsize", (getter)memory_itemsize_get, NULL, NULL},
362 {"shape", (getter)memory_shape_get, NULL, NULL},
363 {"strides", (getter)memory_strides_get, NULL, NULL},
364 {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL},
365 {"size", (getter)memory_size_get, NULL, NULL},
366 {"readonly", (getter)memory_readonly_get, NULL, NULL},
367 {"ndim", (getter)memory_ndim_get, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000368 {NULL, NULL, NULL, NULL},
369};
370
371
372static PyObject *
Neal Norwitzfaa54a32007-08-19 04:23:20 +0000373memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000374{
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000375 return PyBytes_FromObject((PyObject *)mem);
376}
377
378static PyObject *
Neal Norwitzfaa54a32007-08-19 04:23:20 +0000379memory_tolist(PyMemoryViewObject *mem, PyObject *noargs)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000380{
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000381 /* This should construct a (nested) list of unpacked objects
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000382 possibly using the struct module.
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000383 */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000384 Py_INCREF(Py_NotImplemented);
385 return Py_NotImplemented;
386}
387
388
389
390static PyMethodDef memory_methods[] = {
Neal Norwitzfaa54a32007-08-19 04:23:20 +0000391 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
392 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000393 {NULL, NULL} /* sentinel */
394};
395
396
397static void
398memory_dealloc(PyMemoryViewObject *self)
399{
Neal Norwitz666bb412007-08-19 18:38:46 +0000400 if (self->base != NULL) {
401 if (PyTuple_Check(self->base)) {
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000402 /* Special case when first element is generic object
403 with buffer interface and the second element is a
404 contiguous "shadow" that must be copied back into
405 the data areay of the first tuple element before
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000406 releasing the buffer on the first element.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000407 */
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000408
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000409 PyObject_CopyData(PyTuple_GET_ITEM(self->base,0),
410 PyTuple_GET_ITEM(self->base,1));
411
412 /* The view member should have readonly == -1 in
413 this instance indicating that the memory can
414 be "locked" and was locked and will be unlocked
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000415 again after this call.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000416 */
417 PyObject_ReleaseBuffer(PyTuple_GET_ITEM(self->base,0),
418 &(self->view));
Neal Norwitz666bb412007-08-19 18:38:46 +0000419 }
420 else {
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000421 PyObject_ReleaseBuffer(self->base, &(self->view));
Neal Norwitz666bb412007-08-19 18:38:46 +0000422 }
423 Py_CLEAR(self->base);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000424 }
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000425 PyObject_DEL(self);
426}
427
428static PyObject *
429memory_repr(PyMemoryViewObject *self)
430{
Neal Norwitzfaa54a32007-08-19 04:23:20 +0000431 /* XXX(nnorwitz): the code should be different or remove condition. */
432 if (self->base == NULL)
433 return PyUnicode_FromFormat("<memory at %p>", self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000434 else
Neal Norwitzfaa54a32007-08-19 04:23:20 +0000435 return PyUnicode_FromFormat("<memory at %p>", self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000436}
437
438
439static PyObject *
440memory_str(PyMemoryViewObject *self)
441{
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000442 Py_buffer view;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000443 PyObject *res;
444
445 if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
446 return NULL;
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000447
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000448 res = PyBytes_FromStringAndSize(NULL, view.len);
449 PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C');
450 PyObject_ReleaseBuffer((PyObject *)self, &view);
451 return res;
452}
453
454/* Sequence methods */
455
456static Py_ssize_t
457memory_length(PyMemoryViewObject *self)
458{
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000459 Py_buffer view;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000460
461 if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
462 return -1;
463 PyObject_ReleaseBuffer((PyObject *)self, &view);
464 return view.len;
465}
466
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000467/*
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000468 mem[obj] returns a bytes object holding the data for one element if
469 obj fully indexes the memory view or another memory-view object
470 if it does not.
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000471
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000472 0-d memory-view objects can be referenced using ... or () but
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000473 not with anything else.
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000474 */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000475static PyObject *
476memory_subscript(PyMemoryViewObject *self, PyObject *key)
477{
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000478 Py_buffer *view;
479 view = &(self->view);
480
481 if (view->ndim == 0) {
482 if (key == Py_Ellipsis ||
483 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
484 Py_INCREF(self);
485 return (PyObject *)self;
486 }
487 else {
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000488 PyErr_SetString(PyExc_IndexError,
489 "invalid indexing of 0-dim memory");
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000490 return NULL;
491 }
492 }
493 if (PyIndex_Check(key)) {
494 Py_ssize_t result;
495 result = PyNumber_AsSsize_t(key, NULL);
496 if (result == -1 && PyErr_Occurred())
497 return NULL;
498 if (view->ndim == 1) {
499 /* Return a bytes object */
500 char *ptr;
501 ptr = (char *)view->buf;
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000502 if (view->strides == NULL)
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000503 ptr += view->itemsize * result;
504 else
505 ptr += view->strides[0] * result;
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000506 if (view->suboffsets != NULL &&
507 view->suboffsets[0] >= 0)
508 {
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000509 ptr = *((char **)ptr) + view->suboffsets[0];
510 }
511 return PyBytes_FromStringAndSize(ptr, view->itemsize);
512 }
513 else {
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000514 /* Return a new memory-view object */
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000515 Py_buffer newview;
516 PyMemoryView_FromMemory(&newview);
517 }
518 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000519
520
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000521
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000522 Py_INCREF(Py_NotImplemented);
523 return Py_NotImplemented;
524}
525
526static int
527memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
528{
529 return 0;
530}
531
532/* As mapping */
533static PyMappingMethods memory_as_mapping = {
534 (lenfunc)memory_length, /*mp_length*/
535 (binaryfunc)memory_subscript, /*mp_subscript*/
536 (objobjargproc)memory_ass_sub, /*mp_ass_subscript*/
537};
538
539
540/* Buffer methods */
541
542static PyBufferProcs memory_as_buffer = {
543 (getbufferproc)memory_getbuf, /* bf_getbuffer */
544 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
545};
546
547
548PyTypeObject PyMemoryView_Type = {
549 PyVarObject_HEAD_INIT(&PyType_Type, 0)
550 "memoryview",
551 sizeof(PyMemoryViewObject),
552 0,
553 (destructor)memory_dealloc, /* tp_dealloc */
554 0, /* tp_print */
555 0, /* tp_getattr */
556 0, /* tp_setattr */
557 0, /* tp_compare */
558 (reprfunc)memory_repr, /* tp_repr */
559 0, /* tp_as_number */
560 0, /* tp_as_sequence */
561 &memory_as_mapping, /* tp_as_mapping */
562 0, /* tp_hash */
563 0, /* tp_call */
564 (reprfunc)memory_str, /* tp_str */
565 PyObject_GenericGetAttr, /* tp_getattro */
566 0, /* tp_setattro */
567 &memory_as_buffer, /* tp_as_buffer */
568 Py_TPFLAGS_DEFAULT, /* tp_flags */
569 memory_doc, /* tp_doc */
570 0, /* tp_traverse */
571 0, /* tp_clear */
572 0, /* tp_richcompare */
573 0, /* tp_weaklistoffset */
574 0, /* tp_iter */
575 0, /* tp_iternext */
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000576 memory_methods, /* tp_methods */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000577 0, /* tp_members */
578 memory_getsetlist, /* tp_getset */
579 0, /* tp_base */
580 0, /* tp_dict */
581 0, /* tp_descr_get */
582 0, /* tp_descr_set */
583 0, /* tp_dictoffset */
584 0, /* tp_init */
585 0, /* tp_alloc */
586 memory_new, /* tp_new */
587};