blob: 5148ce6bef6e56ce3c4dbfa2db05588fd46429de [file] [log] [blame]
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001/* Memoryview object implementation */
2
3#include "Python.h"
Stefan Krah9a2d99e2012-02-25 12:24:21 +01004#include <stddef.h>
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00005
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00006
Stefan Krah9a2d99e2012-02-25 12:24:21 +01007/****************************************************************************/
8/* ManagedBuffer Object */
9/****************************************************************************/
10
11/*
12 ManagedBuffer Object:
13 ---------------------
14
15 The purpose of this object is to facilitate the handling of chained
16 memoryviews that have the same underlying exporting object. PEP-3118
17 allows the underlying object to change while a view is exported. This
18 could lead to unexpected results when constructing a new memoryview
19 from an existing memoryview.
20
21 Rather than repeatedly redirecting buffer requests to the original base
22 object, all chained memoryviews use a single buffer snapshot. This
23 snapshot is generated by the constructor _PyManagedBuffer_FromObject().
24
25 Ownership rules:
26 ----------------
27
28 The master buffer inside a managed buffer is filled in by the original
29 base object. shape, strides, suboffsets and format are read-only for
30 all consumers.
31
32 A memoryview's buffer is a private copy of the exporter's buffer. shape,
33 strides and suboffsets belong to the memoryview and are thus writable.
34
35 If a memoryview itself exports several buffers via memory_getbuf(), all
36 buffer copies share shape, strides and suboffsets. In this case, the
37 arrays are NOT writable.
38
39 Reference count assumptions:
40 ----------------------------
41
42 The 'obj' member of a Py_buffer must either be NULL or refer to the
43 exporting base object. In the Python codebase, all getbufferprocs
44 return a new reference to view.obj (example: bytes_buffer_getbuffer()).
45
46 PyBuffer_Release() decrements view.obj (if non-NULL), so the
47 releasebufferprocs must NOT decrement view.obj.
48*/
49
50
Stefan Krah9a2d99e2012-02-25 12:24:21 +010051#define CHECK_MBUF_RELEASED(mbuf) \
52 if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \
53 PyErr_SetString(PyExc_ValueError, \
54 "operation forbidden on released memoryview object"); \
55 return NULL; \
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000056 }
57
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000058
Stefan Krah9a2d99e2012-02-25 12:24:21 +010059Py_LOCAL_INLINE(_PyManagedBufferObject *)
60mbuf_alloc(void)
Antoine Pitroubc420402008-12-07 20:14:49 +000061{
Stefan Krah9a2d99e2012-02-25 12:24:21 +010062 _PyManagedBufferObject *mbuf;
63
64 mbuf = (_PyManagedBufferObject *)
65 PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type);
66 if (mbuf == NULL)
67 return NULL;
68 mbuf->flags = 0;
69 mbuf->exports = 0;
70 mbuf->master.obj = NULL;
71 _PyObject_GC_TRACK(mbuf);
72
73 return mbuf;
74}
75
76static PyObject *
77_PyManagedBuffer_FromObject(PyObject *base)
78{
79 _PyManagedBufferObject *mbuf;
80
81 mbuf = mbuf_alloc();
82 if (mbuf == NULL)
83 return NULL;
84
85 if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) {
Stefan Krah1649c1b2012-03-05 17:45:17 +010086 mbuf->master.obj = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +010087 Py_DECREF(mbuf);
88 return NULL;
89 }
90
Stefan Krah9a2d99e2012-02-25 12:24:21 +010091 return (PyObject *)mbuf;
Antoine Pitrouc3b39242009-01-03 16:59:18 +000092}
93
94static void
Stefan Krah9a2d99e2012-02-25 12:24:21 +010095mbuf_release(_PyManagedBufferObject *self)
Antoine Pitrouc3b39242009-01-03 16:59:18 +000096{
Stefan Krah9a2d99e2012-02-25 12:24:21 +010097 if (self->flags&_Py_MANAGED_BUFFER_RELEASED)
98 return;
99
100 /* NOTE: at this point self->exports can still be > 0 if this function
101 is called from mbuf_clear() to break up a reference cycle. */
102 self->flags |= _Py_MANAGED_BUFFER_RELEASED;
103
104 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
105 _PyObject_GC_UNTRACK(self);
106 PyBuffer_Release(&self->master);
107}
108
109static void
110mbuf_dealloc(_PyManagedBufferObject *self)
111{
112 assert(self->exports == 0);
113 mbuf_release(self);
114 if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT)
115 PyMem_Free(self->master.format);
116 PyObject_GC_Del(self);
Antoine Pitroubc420402008-12-07 20:14:49 +0000117}
118
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000119static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100120mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000121{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100122 Py_VISIT(self->master.obj);
123 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000124}
125
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100126static int
127mbuf_clear(_PyManagedBufferObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000128{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100129 assert(self->exports >= 0);
130 mbuf_release(self);
131 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000132}
133
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100134PyTypeObject _PyManagedBuffer_Type = {
135 PyVarObject_HEAD_INIT(&PyType_Type, 0)
136 "managedbuffer",
137 sizeof(_PyManagedBufferObject),
138 0,
139 (destructor)mbuf_dealloc, /* tp_dealloc */
140 0, /* tp_print */
141 0, /* tp_getattr */
142 0, /* tp_setattr */
143 0, /* tp_reserved */
144 0, /* tp_repr */
145 0, /* tp_as_number */
146 0, /* tp_as_sequence */
147 0, /* tp_as_mapping */
148 0, /* tp_hash */
149 0, /* tp_call */
150 0, /* tp_str */
151 PyObject_GenericGetAttr, /* tp_getattro */
152 0, /* tp_setattro */
153 0, /* tp_as_buffer */
154 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
155 0, /* tp_doc */
156 (traverseproc)mbuf_traverse, /* tp_traverse */
157 (inquiry)mbuf_clear /* tp_clear */
158};
159
160
161/****************************************************************************/
162/* MemoryView Object */
163/****************************************************************************/
164
165/* In the process of breaking reference cycles mbuf_release() can be
166 called before memory_release(). */
167#define BASE_INACCESSIBLE(mv) \
168 (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \
169 ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED)
170
171#define CHECK_RELEASED(mv) \
172 if (BASE_INACCESSIBLE(mv)) { \
173 PyErr_SetString(PyExc_ValueError, \
174 "operation forbidden on released memoryview object"); \
175 return NULL; \
176 }
177
178#define CHECK_RELEASED_INT(mv) \
179 if (BASE_INACCESSIBLE(mv)) { \
180 PyErr_SetString(PyExc_ValueError, \
181 "operation forbidden on released memoryview object"); \
182 return -1; \
183 }
184
185#define CHECK_LIST_OR_TUPLE(v) \
186 if (!PyList_Check(v) && !PyTuple_Check(v)) { \
187 PyErr_SetString(PyExc_TypeError, \
188 #v " must be a list or a tuple"); \
189 return NULL; \
190 }
191
192#define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view)
193
194/* Check for the presence of suboffsets in the first dimension. */
195#define HAVE_PTR(suboffsets) (suboffsets && suboffsets[0] >= 0)
196/* Adjust ptr if suboffsets are present. */
197#define ADJUST_PTR(ptr, suboffsets) \
198 (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr)
199
200/* Memoryview buffer properties */
201#define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
202#define MV_F_CONTIGUOUS(flags) \
203 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
204#define MV_ANY_CONTIGUOUS(flags) \
205 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
206
207/* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */
208#define MV_CONTIGUOUS_NDIM1(view) \
209 ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize)
210
211/* getbuffer() requests */
212#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
213#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
214#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
215#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
216#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
217#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
218#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
219#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
220
221
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000222PyDoc_STRVAR(memory_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +0200223"memoryview($module, object)\n--\n\
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000224\n\
225Create a new memoryview object which references the given object.");
226
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100227
228/**************************************************************************/
229/* Copy memoryview buffers */
230/**************************************************************************/
231
232/* The functions in this section take a source and a destination buffer
233 with the same logical structure: format, itemsize, ndim and shape
234 are identical, with ndim > 0.
235
236 NOTE: All buffers are assumed to have PyBUF_FULL information, which
237 is the case for memoryviews! */
238
239
240/* Assumptions: ndim >= 1. The macro tests for a corner case that should
241 perhaps be explicitly forbidden in the PEP. */
242#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
243 (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
244
245Py_LOCAL_INLINE(int)
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000246last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100247{
248 assert(dest->ndim > 0 && src->ndim > 0);
249 return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) &&
250 !HAVE_SUBOFFSETS_IN_LAST_DIM(src) &&
251 dest->strides[dest->ndim-1] == dest->itemsize &&
252 src->strides[src->ndim-1] == src->itemsize);
253}
254
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000255/* This is not a general function for determining format equivalence.
256 It is used in copy_single() and copy_buffer() to weed out non-matching
257 formats. Skipping the '@' character is specifically used in slice
258 assignments, where the lvalue is already known to have a single character
259 format. This is a performance hack that could be rewritten (if properly
260 benchmarked). */
261Py_LOCAL_INLINE(int)
262equiv_format(const Py_buffer *dest, const Py_buffer *src)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100263{
264 const char *dfmt, *sfmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100265
266 assert(dest->format && src->format);
267 dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format;
268 sfmt = src->format[0] == '@' ? src->format+1 : src->format;
269
270 if (strcmp(dfmt, sfmt) != 0 ||
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000271 dest->itemsize != src->itemsize) {
272 return 0;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100273 }
274
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000275 return 1;
276}
277
278/* Two shapes are equivalent if they are either equal or identical up
279 to a zero element at the same position. For example, in NumPy arrays
280 the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */
281Py_LOCAL_INLINE(int)
282equiv_shape(const Py_buffer *dest, const Py_buffer *src)
283{
284 int i;
285
286 if (dest->ndim != src->ndim)
287 return 0;
288
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100289 for (i = 0; i < dest->ndim; i++) {
290 if (dest->shape[i] != src->shape[i])
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000291 return 0;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100292 if (dest->shape[i] == 0)
293 break;
294 }
295
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000296 return 1;
297}
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100298
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000299/* Check that the logical structure of the destination and source buffers
300 is identical. */
301static int
302equiv_structure(const Py_buffer *dest, const Py_buffer *src)
303{
304 if (!equiv_format(dest, src) ||
305 !equiv_shape(dest, src)) {
306 PyErr_SetString(PyExc_ValueError,
Stefan Krah674a42b2013-02-19 13:44:49 +0100307 "memoryview assignment: lvalue and rvalue have different "
308 "structures");
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000309 return 0;
310 }
311
312 return 1;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100313}
314
315/* Base case for recursive multi-dimensional copying. Contiguous arrays are
316 copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
317 sizeof(mem) == shape[0] * itemsize. */
318static void
319copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
320 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
321 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
322 char *mem)
323{
324 if (mem == NULL) { /* contiguous */
325 Py_ssize_t size = shape[0] * itemsize;
326 if (dptr + size < sptr || sptr + size < dptr)
327 memcpy(dptr, sptr, size); /* no overlapping */
328 else
329 memmove(dptr, sptr, size);
330 }
331 else {
332 char *p;
333 Py_ssize_t i;
334 for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
335 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
336 memcpy(p, xsptr, itemsize);
337 }
338 for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
339 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
340 memcpy(xdptr, p, itemsize);
341 }
342 }
343
344}
345
346/* Recursively copy a source buffer to a destination buffer. The two buffers
347 have the same ndim, shape and itemsize. */
348static void
349copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
350 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
351 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
352 char *mem)
353{
354 Py_ssize_t i;
355
356 assert(ndim >= 1);
357
358 if (ndim == 1) {
359 copy_base(shape, itemsize,
360 dptr, dstrides, dsuboffsets,
361 sptr, sstrides, ssuboffsets,
362 mem);
363 return;
364 }
365
366 for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
367 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
368 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
369
370 copy_rec(shape+1, ndim-1, itemsize,
371 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
372 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
373 mem);
374 }
375}
376
377/* Faster copying of one-dimensional arrays. */
378static int
379copy_single(Py_buffer *dest, Py_buffer *src)
380{
381 char *mem = NULL;
382
383 assert(dest->ndim == 1);
384
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000385 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100386 return -1;
387
388 if (!last_dim_is_contiguous(dest, src)) {
389 mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
390 if (mem == NULL) {
391 PyErr_NoMemory();
392 return -1;
393 }
394 }
395
396 copy_base(dest->shape, dest->itemsize,
397 dest->buf, dest->strides, dest->suboffsets,
398 src->buf, src->strides, src->suboffsets,
399 mem);
400
401 if (mem)
402 PyMem_Free(mem);
403
404 return 0;
405}
406
407/* Recursively copy src to dest. Both buffers must have the same basic
408 structure. Copying is atomic, the function never fails with a partial
409 copy. */
410static int
411copy_buffer(Py_buffer *dest, Py_buffer *src)
412{
413 char *mem = NULL;
414
415 assert(dest->ndim > 0);
416
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000417 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100418 return -1;
419
420 if (!last_dim_is_contiguous(dest, src)) {
421 mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
422 if (mem == NULL) {
423 PyErr_NoMemory();
424 return -1;
425 }
426 }
427
428 copy_rec(dest->shape, dest->ndim, dest->itemsize,
429 dest->buf, dest->strides, dest->suboffsets,
430 src->buf, src->strides, src->suboffsets,
431 mem);
432
433 if (mem)
434 PyMem_Free(mem);
435
436 return 0;
437}
438
439/* Initialize strides for a C-contiguous array. */
440Py_LOCAL_INLINE(void)
441init_strides_from_shape(Py_buffer *view)
442{
443 Py_ssize_t i;
444
445 assert(view->ndim > 0);
446
447 view->strides[view->ndim-1] = view->itemsize;
448 for (i = view->ndim-2; i >= 0; i--)
449 view->strides[i] = view->strides[i+1] * view->shape[i+1];
450}
451
452/* Initialize strides for a Fortran-contiguous array. */
453Py_LOCAL_INLINE(void)
454init_fortran_strides_from_shape(Py_buffer *view)
455{
456 Py_ssize_t i;
457
458 assert(view->ndim > 0);
459
460 view->strides[0] = view->itemsize;
461 for (i = 1; i < view->ndim; i++)
462 view->strides[i] = view->strides[i-1] * view->shape[i-1];
463}
464
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200465/* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran)
466 or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100467 len(mem) == src->len. */
468static int
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200469buffer_to_contiguous(char *mem, Py_buffer *src, char order)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100470{
471 Py_buffer dest;
472 Py_ssize_t *strides;
473 int ret;
474
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200475 assert(src->ndim >= 1);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100476 assert(src->shape != NULL);
477 assert(src->strides != NULL);
478
479 strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
480 if (strides == NULL) {
481 PyErr_NoMemory();
482 return -1;
483 }
484
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200485 /* initialize dest */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100486 dest = *src;
487 dest.buf = mem;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200488 /* shape is constant and shared: the logical representation of the
489 array is unaltered. */
490
491 /* The physical representation determined by strides (and possibly
492 suboffsets) may change. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100493 dest.strides = strides;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200494 if (order == 'C' || order == 'A') {
495 init_strides_from_shape(&dest);
496 }
497 else {
498 init_fortran_strides_from_shape(&dest);
499 }
500
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100501 dest.suboffsets = NULL;
502
503 ret = copy_buffer(&dest, src);
504
505 PyMem_Free(strides);
506 return ret;
507}
508
509
510/****************************************************************************/
511/* Constructors */
512/****************************************************************************/
513
514/* Initialize values that are shared with the managed buffer. */
515Py_LOCAL_INLINE(void)
516init_shared_values(Py_buffer *dest, const Py_buffer *src)
517{
518 dest->obj = src->obj;
519 dest->buf = src->buf;
520 dest->len = src->len;
521 dest->itemsize = src->itemsize;
522 dest->readonly = src->readonly;
523 dest->format = src->format ? src->format : "B";
524 dest->internal = src->internal;
525}
526
527/* Copy shape and strides. Reconstruct missing values. */
528static void
529init_shape_strides(Py_buffer *dest, const Py_buffer *src)
530{
531 Py_ssize_t i;
532
533 if (src->ndim == 0) {
534 dest->shape = NULL;
535 dest->strides = NULL;
536 return;
537 }
538 if (src->ndim == 1) {
539 dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
540 dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
541 return;
542 }
543
544 for (i = 0; i < src->ndim; i++)
545 dest->shape[i] = src->shape[i];
546 if (src->strides) {
547 for (i = 0; i < src->ndim; i++)
548 dest->strides[i] = src->strides[i];
549 }
550 else {
551 init_strides_from_shape(dest);
552 }
553}
554
555Py_LOCAL_INLINE(void)
556init_suboffsets(Py_buffer *dest, const Py_buffer *src)
557{
558 Py_ssize_t i;
559
560 if (src->suboffsets == NULL) {
561 dest->suboffsets = NULL;
562 return;
563 }
564 for (i = 0; i < src->ndim; i++)
565 dest->suboffsets[i] = src->suboffsets[i];
566}
567
568/* len = product(shape) * itemsize */
569Py_LOCAL_INLINE(void)
570init_len(Py_buffer *view)
571{
572 Py_ssize_t i, len;
573
574 len = 1;
575 for (i = 0; i < view->ndim; i++)
576 len *= view->shape[i];
577 len *= view->itemsize;
578
579 view->len = len;
580}
581
582/* Initialize memoryview buffer properties. */
583static void
584init_flags(PyMemoryViewObject *mv)
585{
586 const Py_buffer *view = &mv->view;
587 int flags = 0;
588
589 switch (view->ndim) {
590 case 0:
591 flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
592 _Py_MEMORYVIEW_FORTRAN);
593 break;
594 case 1:
595 if (MV_CONTIGUOUS_NDIM1(view))
596 flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
597 break;
598 default:
599 if (PyBuffer_IsContiguous(view, 'C'))
600 flags |= _Py_MEMORYVIEW_C;
601 if (PyBuffer_IsContiguous(view, 'F'))
602 flags |= _Py_MEMORYVIEW_FORTRAN;
603 break;
604 }
605
606 if (view->suboffsets) {
607 flags |= _Py_MEMORYVIEW_PIL;
608 flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
609 }
610
611 mv->flags = flags;
612}
613
614/* Allocate a new memoryview and perform basic initialization. New memoryviews
615 are exclusively created through the mbuf_add functions. */
616Py_LOCAL_INLINE(PyMemoryViewObject *)
617memory_alloc(int ndim)
618{
619 PyMemoryViewObject *mv;
620
621 mv = (PyMemoryViewObject *)
622 PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
623 if (mv == NULL)
624 return NULL;
625
626 mv->mbuf = NULL;
627 mv->hash = -1;
628 mv->flags = 0;
629 mv->exports = 0;
630 mv->view.ndim = ndim;
631 mv->view.shape = mv->ob_array;
632 mv->view.strides = mv->ob_array + ndim;
633 mv->view.suboffsets = mv->ob_array + 2 * ndim;
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +0100634 mv->weakreflist = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100635
636 _PyObject_GC_TRACK(mv);
637 return mv;
638}
639
640/*
641 Return a new memoryview that is registered with mbuf. If src is NULL,
642 use mbuf->master as the underlying buffer. Otherwise, use src.
643
644 The new memoryview has full buffer information: shape and strides
645 are always present, suboffsets as needed. Arrays are copied to
646 the memoryview's ob_array field.
647 */
648static PyObject *
649mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
650{
651 PyMemoryViewObject *mv;
652 Py_buffer *dest;
653
654 if (src == NULL)
655 src = &mbuf->master;
656
657 if (src->ndim > PyBUF_MAX_NDIM) {
658 PyErr_SetString(PyExc_ValueError,
659 "memoryview: number of dimensions must not exceed "
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200660 Py_STRINGIFY(PyBUF_MAX_NDIM));
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100661 return NULL;
662 }
663
664 mv = memory_alloc(src->ndim);
665 if (mv == NULL)
666 return NULL;
667
668 dest = &mv->view;
669 init_shared_values(dest, src);
670 init_shape_strides(dest, src);
671 init_suboffsets(dest, src);
672 init_flags(mv);
673
674 mv->mbuf = mbuf;
675 Py_INCREF(mbuf);
676 mbuf->exports++;
677
678 return (PyObject *)mv;
679}
680
681/* Register an incomplete view: shape, strides, suboffsets and flags still
682 need to be initialized. Use 'ndim' instead of src->ndim to determine the
683 size of the memoryview's ob_array.
684
685 Assumption: ndim <= PyBUF_MAX_NDIM. */
686static PyObject *
687mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
688 int ndim)
689{
690 PyMemoryViewObject *mv;
691 Py_buffer *dest;
692
693 if (src == NULL)
694 src = &mbuf->master;
695
696 assert(ndim <= PyBUF_MAX_NDIM);
697
698 mv = memory_alloc(ndim);
699 if (mv == NULL)
700 return NULL;
701
702 dest = &mv->view;
703 init_shared_values(dest, src);
704
705 mv->mbuf = mbuf;
706 Py_INCREF(mbuf);
707 mbuf->exports++;
708
709 return (PyObject *)mv;
710}
711
712/* Expose a raw memory area as a view of contiguous bytes. flags can be
713 PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
714 The memoryview has complete buffer information. */
715PyObject *
716PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
717{
718 _PyManagedBufferObject *mbuf;
719 PyObject *mv;
720 int readonly;
721
722 assert(mem != NULL);
723 assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
724
725 mbuf = mbuf_alloc();
726 if (mbuf == NULL)
727 return NULL;
728
729 readonly = (flags == PyBUF_WRITE) ? 0 : 1;
730 (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
731 PyBUF_FULL_RO);
732
733 mv = mbuf_add_view(mbuf, NULL);
734 Py_DECREF(mbuf);
735
736 return mv;
737}
738
739/* Create a memoryview from a given Py_buffer. For simple byte views,
740 PyMemoryView_FromMemory() should be used instead.
741 This function is the only entry point that can create a master buffer
742 without full information. Because of this fact init_shape_strides()
743 must be able to reconstruct missing values. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000744PyObject *
Antoine Pitrouee58fa42008-08-19 18:22:14 +0000745PyMemoryView_FromBuffer(Py_buffer *info)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000746{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100747 _PyManagedBufferObject *mbuf;
748 PyObject *mv;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000749
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000750 if (info->buf == NULL) {
751 PyErr_SetString(PyExc_ValueError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100752 "PyMemoryView_FromBuffer(): info->buf must not be NULL");
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000753 return NULL;
754 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100755
756 mbuf = mbuf_alloc();
757 if (mbuf == NULL)
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000758 return NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100759
760 /* info->obj is either NULL or a borrowed reference. This reference
761 should not be decremented in PyBuffer_Release(). */
762 mbuf->master = *info;
763 mbuf->master.obj = NULL;
764
765 mv = mbuf_add_view(mbuf, NULL);
766 Py_DECREF(mbuf);
767
768 return mv;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000769}
770
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100771/* Create a memoryview from an object that implements the buffer protocol.
772 If the object is a memoryview, the new memoryview must be registered
773 with the same managed buffer. Otherwise, a new managed buffer is created. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000774PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100775PyMemoryView_FromObject(PyObject *v)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000776{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100777 _PyManagedBufferObject *mbuf;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000778
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100779 if (PyMemoryView_Check(v)) {
780 PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
781 CHECK_RELEASED(mv);
782 return mbuf_add_view(mv->mbuf, &mv->view);
783 }
784 else if (PyObject_CheckBuffer(v)) {
785 PyObject *ret;
786 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
787 if (mbuf == NULL)
788 return NULL;
789 ret = mbuf_add_view(mbuf, NULL);
790 Py_DECREF(mbuf);
791 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000792 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000793
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100794 PyErr_Format(PyExc_TypeError,
795 "memoryview: %.200s object does not have the buffer interface",
796 Py_TYPE(v)->tp_name);
797 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000798}
799
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100800/* Copy the format string from a base object that might vanish. */
801static int
802mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
803{
804 if (fmt != NULL) {
805 char *cp = PyMem_Malloc(strlen(fmt)+1);
806 if (cp == NULL) {
807 PyErr_NoMemory();
808 return -1;
809 }
810 mbuf->master.format = strcpy(cp, fmt);
811 mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
812 }
813
814 return 0;
815}
816
817/*
818 Return a memoryview that is based on a contiguous copy of src.
819 Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
820
821 Ownership rules:
822 1) As usual, the returned memoryview has a private copy
823 of src->shape, src->strides and src->suboffsets.
824 2) src->format is copied to the master buffer and released
825 in mbuf_dealloc(). The releasebufferproc of the bytes
826 object is NULL, so it does not matter that mbuf_release()
827 passes the altered format pointer to PyBuffer_Release().
828*/
829static PyObject *
830memory_from_contiguous_copy(Py_buffer *src, char order)
831{
832 _PyManagedBufferObject *mbuf;
833 PyMemoryViewObject *mv;
834 PyObject *bytes;
835 Py_buffer *dest;
836 int i;
837
838 assert(src->ndim > 0);
839 assert(src->shape != NULL);
840
841 bytes = PyBytes_FromStringAndSize(NULL, src->len);
842 if (bytes == NULL)
843 return NULL;
844
845 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
846 Py_DECREF(bytes);
847 if (mbuf == NULL)
848 return NULL;
849
850 if (mbuf_copy_format(mbuf, src->format) < 0) {
851 Py_DECREF(mbuf);
852 return NULL;
853 }
854
855 mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
856 Py_DECREF(mbuf);
857 if (mv == NULL)
858 return NULL;
859
860 dest = &mv->view;
861
862 /* shared values are initialized correctly except for itemsize */
863 dest->itemsize = src->itemsize;
864
865 /* shape and strides */
866 for (i = 0; i < src->ndim; i++) {
867 dest->shape[i] = src->shape[i];
868 }
869 if (order == 'C' || order == 'A') {
870 init_strides_from_shape(dest);
871 }
872 else {
873 init_fortran_strides_from_shape(dest);
874 }
875 /* suboffsets */
876 dest->suboffsets = NULL;
877
878 /* flags */
879 init_flags(mv);
880
881 if (copy_buffer(dest, src) < 0) {
882 Py_DECREF(mv);
883 return NULL;
884 }
885
886 return (PyObject *)mv;
887}
888
889/*
890 Return a new memoryview object based on a contiguous exporter with
891 buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
892 The logical structure of the input and output buffers is the same
893 (i.e. tolist(input) == tolist(output)), but the physical layout in
894 memory can be explicitly chosen.
895
896 As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
897 otherwise it may be writable or read-only.
898
899 If the exporter is already contiguous with the desired target order,
900 the memoryview will be directly based on the exporter.
901
902 Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
903 based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
904 'F'ortran order otherwise.
905*/
906PyObject *
907PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
908{
909 PyMemoryViewObject *mv;
910 PyObject *ret;
911 Py_buffer *view;
912
913 assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
914 assert(order == 'C' || order == 'F' || order == 'A');
915
916 mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
917 if (mv == NULL)
918 return NULL;
919
920 view = &mv->view;
921 if (buffertype == PyBUF_WRITE && view->readonly) {
922 PyErr_SetString(PyExc_BufferError,
923 "underlying buffer is not writable");
924 Py_DECREF(mv);
925 return NULL;
926 }
927
928 if (PyBuffer_IsContiguous(view, order))
929 return (PyObject *)mv;
930
931 if (buffertype == PyBUF_WRITE) {
932 PyErr_SetString(PyExc_BufferError,
933 "writable contiguous buffer requested "
934 "for a non-contiguous object.");
935 Py_DECREF(mv);
936 return NULL;
937 }
938
939 ret = memory_from_contiguous_copy(view, order);
940 Py_DECREF(mv);
941 return ret;
942}
943
944
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000945static PyObject *
946memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
947{
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000948 PyObject *obj;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100949 static char *kwlist[] = {"object", NULL};
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000950
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000951 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
952 &obj)) {
953 return NULL;
954 }
Christian Heimes7b6fc8e2007-11-08 02:28:11 +0000955
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000956 return PyMemoryView_FromObject(obj);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000957}
958
959
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100960/****************************************************************************/
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200961/* Previously in abstract.c */
962/****************************************************************************/
963
964typedef struct {
965 Py_buffer view;
966 Py_ssize_t array[1];
967} Py_buffer_full;
968
969int
970PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
971{
972 Py_buffer_full *fb = NULL;
973 int ret;
974
975 assert(order == 'C' || order == 'F' || order == 'A');
976
977 if (len != src->len) {
978 PyErr_SetString(PyExc_ValueError,
979 "PyBuffer_ToContiguous: len != view->len");
980 return -1;
981 }
982
983 if (PyBuffer_IsContiguous(src, order)) {
984 memcpy((char *)buf, src->buf, len);
985 return 0;
986 }
987
988 /* buffer_to_contiguous() assumes PyBUF_FULL */
989 fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array));
990 if (fb == NULL) {
991 PyErr_NoMemory();
992 return -1;
993 }
994 fb->view.ndim = src->ndim;
995 fb->view.shape = fb->array;
996 fb->view.strides = fb->array + src->ndim;
997 fb->view.suboffsets = fb->array + 2 * src->ndim;
998
999 init_shared_values(&fb->view, src);
1000 init_shape_strides(&fb->view, src);
1001 init_suboffsets(&fb->view, src);
1002
1003 src = &fb->view;
1004
1005 ret = buffer_to_contiguous(buf, src, order);
1006 PyMem_Free(fb);
1007 return ret;
1008}
1009
1010
1011/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001012/* Release/GC management */
1013/****************************************************************************/
1014
1015/* Inform the managed buffer that this particular memoryview will not access
1016 the underlying buffer again. If no other memoryviews are registered with
1017 the managed buffer, the underlying buffer is released instantly and
1018 marked as inaccessible for both the memoryview and the managed buffer.
1019
1020 This function fails if the memoryview itself has exported buffers. */
1021static int
1022_memory_release(PyMemoryViewObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001023{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001024 if (self->flags & _Py_MEMORYVIEW_RELEASED)
1025 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001026
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001027 if (self->exports == 0) {
1028 self->flags |= _Py_MEMORYVIEW_RELEASED;
1029 assert(self->mbuf->exports > 0);
1030 if (--self->mbuf->exports == 0)
1031 mbuf_release(self->mbuf);
1032 return 0;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001033 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001034 if (self->exports > 0) {
1035 PyErr_Format(PyExc_BufferError,
1036 "memoryview has %zd exported buffer%s", self->exports,
1037 self->exports==1 ? "" : "s");
1038 return -1;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001039 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001040
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001041 Py_FatalError("_memory_release(): negative export count");
1042 return -1;
1043}
1044
1045static PyObject *
Stefan Krahe4c07992012-07-28 14:10:02 +02001046memory_release(PyMemoryViewObject *self, PyObject *noargs)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001047{
1048 if (_memory_release(self) < 0)
1049 return NULL;
1050 Py_RETURN_NONE;
1051}
1052
1053static void
1054memory_dealloc(PyMemoryViewObject *self)
1055{
1056 assert(self->exports == 0);
1057 _PyObject_GC_UNTRACK(self);
1058 (void)_memory_release(self);
1059 Py_CLEAR(self->mbuf);
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01001060 if (self->weakreflist != NULL)
1061 PyObject_ClearWeakRefs((PyObject *) self);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001062 PyObject_GC_Del(self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001063}
1064
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001065static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001066memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001067{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001068 Py_VISIT(self->mbuf);
1069 return 0;
1070}
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001071
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001072static int
1073memory_clear(PyMemoryViewObject *self)
1074{
1075 (void)_memory_release(self);
1076 Py_CLEAR(self->mbuf);
1077 return 0;
1078}
1079
1080static PyObject *
1081memory_enter(PyObject *self, PyObject *args)
1082{
1083 CHECK_RELEASED(self);
1084 Py_INCREF(self);
1085 return self;
1086}
1087
1088static PyObject *
1089memory_exit(PyObject *self, PyObject *args)
1090{
Stefan Krahe4c07992012-07-28 14:10:02 +02001091 return memory_release((PyMemoryViewObject *)self, NULL);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001092}
1093
1094
1095/****************************************************************************/
1096/* Casting format and shape */
1097/****************************************************************************/
1098
1099#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
1100
1101Py_LOCAL_INLINE(Py_ssize_t)
1102get_native_fmtchar(char *result, const char *fmt)
1103{
1104 Py_ssize_t size = -1;
1105
1106 if (fmt[0] == '@') fmt++;
1107
1108 switch (fmt[0]) {
1109 case 'c': case 'b': case 'B': size = sizeof(char); break;
1110 case 'h': case 'H': size = sizeof(short); break;
1111 case 'i': case 'I': size = sizeof(int); break;
1112 case 'l': case 'L': size = sizeof(long); break;
1113 #ifdef HAVE_LONG_LONG
1114 case 'q': case 'Q': size = sizeof(PY_LONG_LONG); break;
1115 #endif
1116 case 'n': case 'N': size = sizeof(Py_ssize_t); break;
1117 case 'f': size = sizeof(float); break;
1118 case 'd': size = sizeof(double); break;
1119 #ifdef HAVE_C99_BOOL
1120 case '?': size = sizeof(_Bool); break;
1121 #else
1122 case '?': size = sizeof(char); break;
1123 #endif
1124 case 'P': size = sizeof(void *); break;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001125 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001126
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001127 if (size > 0 && fmt[1] == '\0') {
1128 *result = fmt[0];
1129 return size;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001130 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001131
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001132 return -1;
1133}
1134
1135/* Cast a memoryview's data type to 'format'. The input array must be
1136 C-contiguous. At least one of input-format, output-format must have
1137 byte size. The output array is 1-D, with the same byte length as the
1138 input array. Thus, view->len must be a multiple of the new itemsize. */
1139static int
1140cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1141{
1142 Py_buffer *view = &mv->view;
1143 PyObject *asciifmt;
1144 char srcchar, destchar;
1145 Py_ssize_t itemsize;
1146 int ret = -1;
1147
1148 assert(view->ndim >= 1);
1149 assert(Py_SIZE(mv) == 3*view->ndim);
1150 assert(view->shape == mv->ob_array);
1151 assert(view->strides == mv->ob_array + view->ndim);
1152 assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1153
1154 if (get_native_fmtchar(&srcchar, view->format) < 0) {
1155 PyErr_SetString(PyExc_ValueError,
1156 "memoryview: source format must be a native single character "
1157 "format prefixed with an optional '@'");
1158 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001159 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001160
1161 asciifmt = PyUnicode_AsASCIIString(format);
1162 if (asciifmt == NULL)
1163 return ret;
1164
1165 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1166 if (itemsize < 0) {
1167 PyErr_SetString(PyExc_ValueError,
1168 "memoryview: destination format must be a native single "
1169 "character format prefixed with an optional '@'");
1170 goto out;
1171 }
1172
1173 if (!IS_BYTE_FORMAT(srcchar) && !IS_BYTE_FORMAT(destchar)) {
1174 PyErr_SetString(PyExc_TypeError,
1175 "memoryview: cannot cast between two non-byte formats");
1176 goto out;
1177 }
1178 if (view->len % itemsize) {
1179 PyErr_SetString(PyExc_TypeError,
1180 "memoryview: length is not a multiple of itemsize");
1181 goto out;
1182 }
1183
1184 strncpy(mv->format, PyBytes_AS_STRING(asciifmt),
1185 _Py_MEMORYVIEW_MAX_FORMAT);
1186 mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0';
1187 view->format = mv->format;
1188 view->itemsize = itemsize;
1189
1190 view->ndim = 1;
1191 view->shape[0] = view->len / view->itemsize;
1192 view->strides[0] = view->itemsize;
1193 view->suboffsets = NULL;
1194
1195 init_flags(mv);
1196
1197 ret = 0;
1198
1199out:
1200 Py_DECREF(asciifmt);
1201 return ret;
1202}
1203
1204/* The memoryview must have space for 3*len(seq) elements. */
1205static Py_ssize_t
1206copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1207 Py_ssize_t itemsize)
1208{
1209 Py_ssize_t x, i;
1210 Py_ssize_t len = itemsize;
1211
1212 for (i = 0; i < ndim; i++) {
1213 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1214 if (!PyLong_Check(tmp)) {
1215 PyErr_SetString(PyExc_TypeError,
1216 "memoryview.cast(): elements of shape must be integers");
1217 return -1;
1218 }
1219 x = PyLong_AsSsize_t(tmp);
1220 if (x == -1 && PyErr_Occurred()) {
1221 return -1;
1222 }
1223 if (x <= 0) {
1224 /* In general elements of shape may be 0, but not for casting. */
1225 PyErr_Format(PyExc_ValueError,
1226 "memoryview.cast(): elements of shape must be integers > 0");
1227 return -1;
1228 }
1229 if (x > PY_SSIZE_T_MAX / len) {
1230 PyErr_Format(PyExc_ValueError,
1231 "memoryview.cast(): product(shape) > SSIZE_MAX");
1232 return -1;
1233 }
1234 len *= x;
1235 shape[i] = x;
1236 }
1237
1238 return len;
1239}
1240
1241/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1242 If the result array does not have exactly the same byte length as the
1243 input array, raise ValueError. */
1244static int
1245cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1246{
1247 Py_buffer *view = &mv->view;
1248 Py_ssize_t len;
1249
1250 assert(view->ndim == 1); /* ndim from cast_to_1D() */
1251 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1252 assert(view->shape == mv->ob_array);
1253 assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1254 assert(view->suboffsets == NULL);
1255
1256 view->ndim = ndim;
1257 if (view->ndim == 0) {
1258 view->shape = NULL;
1259 view->strides = NULL;
1260 len = view->itemsize;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001261 }
1262 else {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001263 len = copy_shape(view->shape, shape, ndim, view->itemsize);
1264 if (len < 0)
1265 return -1;
1266 init_strides_from_shape(view);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001267 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001268
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001269 if (view->len != len) {
1270 PyErr_SetString(PyExc_TypeError,
1271 "memoryview: product(shape) * itemsize != buffer size");
1272 return -1;
1273 }
1274
1275 init_flags(mv);
1276
1277 return 0;
1278}
1279
1280static int
1281zero_in_shape(PyMemoryViewObject *mv)
1282{
1283 Py_buffer *view = &mv->view;
1284 Py_ssize_t i;
1285
1286 for (i = 0; i < view->ndim; i++)
1287 if (view->shape[i] == 0)
1288 return 1;
1289
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001290 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001291}
1292
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001293/*
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001294 Cast a copy of 'self' to a different view. The input view must
1295 be C-contiguous. The function always casts the input view to a
1296 1-D output according to 'format'. At least one of input-format,
1297 output-format must have byte size.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001298
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001299 If 'shape' is given, the 1-D view from the previous step will
1300 be cast to a C-contiguous view with new shape and strides.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001301
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001302 All casts must result in views that will have the exact byte
1303 size of the original input. Otherwise, an error is raised.
1304*/
1305static PyObject *
1306memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001307{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001308 static char *kwlist[] = {"format", "shape", NULL};
1309 PyMemoryViewObject *mv = NULL;
1310 PyObject *shape = NULL;
1311 PyObject *format;
1312 Py_ssize_t ndim = 1;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001313
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001314 CHECK_RELEASED(self);
1315
1316 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
1317 &format, &shape)) {
1318 return NULL;
1319 }
1320 if (!PyUnicode_Check(format)) {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001321 PyErr_SetString(PyExc_TypeError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001322 "memoryview: format argument must be a string");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001323 return NULL;
1324 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001325 if (!MV_C_CONTIGUOUS(self->flags)) {
1326 PyErr_SetString(PyExc_TypeError,
1327 "memoryview: casts are restricted to C-contiguous views");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001328 return NULL;
1329 }
Antoine Pitrou60b18342013-10-03 19:55:41 +02001330 if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001331 PyErr_SetString(PyExc_TypeError,
1332 "memoryview: cannot cast view with zeros in shape or strides");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001333 return NULL;
1334 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001335 if (shape) {
1336 CHECK_LIST_OR_TUPLE(shape)
1337 ndim = PySequence_Fast_GET_SIZE(shape);
1338 if (ndim > PyBUF_MAX_NDIM) {
1339 PyErr_SetString(PyExc_ValueError,
1340 "memoryview: number of dimensions must not exceed "
Victor Stinner45e8e2f2014-05-14 17:24:35 +02001341 Py_STRINGIFY(PyBUF_MAX_NDIM));
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001342 return NULL;
1343 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001344 if (self->view.ndim != 1 && ndim != 1) {
1345 PyErr_SetString(PyExc_TypeError,
1346 "memoryview: cast must be 1D -> ND or ND -> 1D");
1347 return NULL;
1348 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001349 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001350
1351 mv = (PyMemoryViewObject *)
1352 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1353 if (mv == NULL)
1354 return NULL;
1355
1356 if (cast_to_1D(mv, format) < 0)
1357 goto error;
1358 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1359 goto error;
1360
1361 return (PyObject *)mv;
1362
1363error:
1364 Py_DECREF(mv);
1365 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001366}
1367
1368
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001369/**************************************************************************/
1370/* getbuffer */
1371/**************************************************************************/
1372
1373static int
1374memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1375{
1376 Py_buffer *base = &self->view;
1377 int baseflags = self->flags;
1378
1379 CHECK_RELEASED_INT(self);
1380
1381 /* start with complete information */
1382 *view = *base;
1383 view->obj = NULL;
1384
1385 if (REQ_WRITABLE(flags) && base->readonly) {
1386 PyErr_SetString(PyExc_BufferError,
1387 "memoryview: underlying buffer is not writable");
1388 return -1;
1389 }
1390 if (!REQ_FORMAT(flags)) {
1391 /* NULL indicates that the buffer's data type has been cast to 'B'.
1392 view->itemsize is the _previous_ itemsize. If shape is present,
1393 the equality product(shape) * itemsize = len still holds at this
1394 point. The equality calcsize(format) = itemsize does _not_ hold
1395 from here on! */
1396 view->format = NULL;
1397 }
1398
1399 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1400 PyErr_SetString(PyExc_BufferError,
1401 "memoryview: underlying buffer is not C-contiguous");
1402 return -1;
1403 }
1404 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1405 PyErr_SetString(PyExc_BufferError,
1406 "memoryview: underlying buffer is not Fortran contiguous");
1407 return -1;
1408 }
1409 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1410 PyErr_SetString(PyExc_BufferError,
1411 "memoryview: underlying buffer is not contiguous");
1412 return -1;
1413 }
1414 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1415 PyErr_SetString(PyExc_BufferError,
1416 "memoryview: underlying buffer requires suboffsets");
1417 return -1;
1418 }
1419 if (!REQ_STRIDES(flags)) {
1420 if (!MV_C_CONTIGUOUS(baseflags)) {
1421 PyErr_SetString(PyExc_BufferError,
1422 "memoryview: underlying buffer is not C-contiguous");
1423 return -1;
1424 }
1425 view->strides = NULL;
1426 }
1427 if (!REQ_SHAPE(flags)) {
1428 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1429 so base->buf = ndbuf->data. */
1430 if (view->format != NULL) {
1431 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1432 not make sense. */
1433 PyErr_Format(PyExc_BufferError,
Stefan Krah674a42b2013-02-19 13:44:49 +01001434 "memoryview: cannot cast to unsigned bytes if the format flag "
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001435 "is present");
1436 return -1;
1437 }
1438 /* product(shape) * itemsize = len and calcsize(format) = itemsize
1439 do _not_ hold from here on! */
1440 view->ndim = 1;
1441 view->shape = NULL;
1442 }
1443
1444
1445 view->obj = (PyObject *)self;
1446 Py_INCREF(view->obj);
1447 self->exports++;
1448
1449 return 0;
1450}
1451
1452static void
1453memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1454{
1455 self->exports--;
1456 return;
1457 /* PyBuffer_Release() decrements view->obj after this function returns. */
1458}
1459
1460/* Buffer methods */
1461static PyBufferProcs memory_as_buffer = {
1462 (getbufferproc)memory_getbuf, /* bf_getbuffer */
1463 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1464};
1465
1466
1467/****************************************************************************/
1468/* Optimized pack/unpack for all native format specifiers */
1469/****************************************************************************/
1470
1471/*
1472 Fix exceptions:
1473 1) Include format string in the error message.
1474 2) OverflowError -> ValueError.
1475 3) The error message from PyNumber_Index() is not ideal.
1476*/
1477static int
1478type_error_int(const char *fmt)
1479{
1480 PyErr_Format(PyExc_TypeError,
1481 "memoryview: invalid type for format '%s'", fmt);
1482 return -1;
1483}
1484
1485static int
1486value_error_int(const char *fmt)
1487{
1488 PyErr_Format(PyExc_ValueError,
1489 "memoryview: invalid value for format '%s'", fmt);
1490 return -1;
1491}
1492
1493static int
1494fix_error_int(const char *fmt)
1495{
1496 assert(PyErr_Occurred());
1497 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1498 PyErr_Clear();
1499 return type_error_int(fmt);
1500 }
1501 else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1502 PyErr_ExceptionMatches(PyExc_ValueError)) {
1503 PyErr_Clear();
1504 return value_error_int(fmt);
1505 }
1506
1507 return -1;
1508}
1509
1510/* Accept integer objects or objects with an __index__() method. */
1511static long
1512pylong_as_ld(PyObject *item)
1513{
1514 PyObject *tmp;
1515 long ld;
1516
1517 tmp = PyNumber_Index(item);
1518 if (tmp == NULL)
1519 return -1;
1520
1521 ld = PyLong_AsLong(tmp);
1522 Py_DECREF(tmp);
1523 return ld;
1524}
1525
1526static unsigned long
1527pylong_as_lu(PyObject *item)
1528{
1529 PyObject *tmp;
1530 unsigned long lu;
1531
1532 tmp = PyNumber_Index(item);
1533 if (tmp == NULL)
1534 return (unsigned long)-1;
1535
1536 lu = PyLong_AsUnsignedLong(tmp);
1537 Py_DECREF(tmp);
1538 return lu;
1539}
1540
1541#ifdef HAVE_LONG_LONG
1542static PY_LONG_LONG
1543pylong_as_lld(PyObject *item)
1544{
1545 PyObject *tmp;
1546 PY_LONG_LONG lld;
1547
1548 tmp = PyNumber_Index(item);
1549 if (tmp == NULL)
1550 return -1;
1551
1552 lld = PyLong_AsLongLong(tmp);
1553 Py_DECREF(tmp);
1554 return lld;
1555}
1556
1557static unsigned PY_LONG_LONG
1558pylong_as_llu(PyObject *item)
1559{
1560 PyObject *tmp;
1561 unsigned PY_LONG_LONG llu;
1562
1563 tmp = PyNumber_Index(item);
1564 if (tmp == NULL)
1565 return (unsigned PY_LONG_LONG)-1;
1566
1567 llu = PyLong_AsUnsignedLongLong(tmp);
1568 Py_DECREF(tmp);
1569 return llu;
1570}
1571#endif
1572
1573static Py_ssize_t
1574pylong_as_zd(PyObject *item)
1575{
1576 PyObject *tmp;
1577 Py_ssize_t zd;
1578
1579 tmp = PyNumber_Index(item);
1580 if (tmp == NULL)
1581 return -1;
1582
1583 zd = PyLong_AsSsize_t(tmp);
1584 Py_DECREF(tmp);
1585 return zd;
1586}
1587
1588static size_t
1589pylong_as_zu(PyObject *item)
1590{
1591 PyObject *tmp;
1592 size_t zu;
1593
1594 tmp = PyNumber_Index(item);
1595 if (tmp == NULL)
1596 return (size_t)-1;
1597
1598 zu = PyLong_AsSize_t(tmp);
1599 Py_DECREF(tmp);
1600 return zu;
1601}
1602
1603/* Timings with the ndarray from _testbuffer.c indicate that using the
1604 struct module is around 15x slower than the two functions below. */
1605
1606#define UNPACK_SINGLE(dest, ptr, type) \
1607 do { \
1608 type x; \
1609 memcpy((char *)&x, ptr, sizeof x); \
1610 dest = x; \
1611 } while (0)
1612
1613/* Unpack a single item. 'fmt' can be any native format character in struct
1614 module syntax. This function is very sensitive to small changes. With this
1615 layout gcc automatically generates a fast jump table. */
1616Py_LOCAL_INLINE(PyObject *)
1617unpack_single(const char *ptr, const char *fmt)
1618{
1619 unsigned PY_LONG_LONG llu;
1620 unsigned long lu;
1621 size_t zu;
1622 PY_LONG_LONG lld;
1623 long ld;
1624 Py_ssize_t zd;
1625 double d;
1626 unsigned char uc;
1627 void *p;
1628
1629 switch (fmt[0]) {
1630
1631 /* signed integers and fast path for 'B' */
1632 case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
1633 case 'b': ld = *((signed char *)ptr); goto convert_ld;
1634 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1635 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1636 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1637
1638 /* boolean */
1639 #ifdef HAVE_C99_BOOL
1640 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
1641 #else
1642 case '?': UNPACK_SINGLE(ld, ptr, char); goto convert_bool;
1643 #endif
1644
1645 /* unsigned integers */
1646 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1647 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1648 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1649
1650 /* native 64-bit */
1651 #ifdef HAVE_LONG_LONG
1652 case 'q': UNPACK_SINGLE(lld, ptr, PY_LONG_LONG); goto convert_lld;
1653 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned PY_LONG_LONG); goto convert_llu;
1654 #endif
1655
1656 /* ssize_t and size_t */
1657 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1658 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1659
1660 /* floats */
1661 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1662 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1663
1664 /* bytes object */
1665 case 'c': goto convert_bytes;
1666
1667 /* pointer */
1668 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1669
1670 /* default */
1671 default: goto err_format;
1672 }
1673
1674convert_uc:
1675 /* PyLong_FromUnsignedLong() is slower */
1676 return PyLong_FromLong(uc);
1677convert_ld:
1678 return PyLong_FromLong(ld);
1679convert_lu:
1680 return PyLong_FromUnsignedLong(lu);
1681convert_lld:
1682 return PyLong_FromLongLong(lld);
1683convert_llu:
1684 return PyLong_FromUnsignedLongLong(llu);
1685convert_zd:
1686 return PyLong_FromSsize_t(zd);
1687convert_zu:
1688 return PyLong_FromSize_t(zu);
1689convert_double:
1690 return PyFloat_FromDouble(d);
1691convert_bool:
1692 return PyBool_FromLong(ld);
1693convert_bytes:
1694 return PyBytes_FromStringAndSize(ptr, 1);
1695convert_pointer:
1696 return PyLong_FromVoidPtr(p);
1697err_format:
1698 PyErr_Format(PyExc_NotImplementedError,
1699 "memoryview: format %s not supported", fmt);
1700 return NULL;
1701}
1702
1703#define PACK_SINGLE(ptr, src, type) \
1704 do { \
1705 type x; \
1706 x = (type)src; \
1707 memcpy(ptr, (char *)&x, sizeof x); \
1708 } while (0)
1709
1710/* Pack a single item. 'fmt' can be any native format character in
1711 struct module syntax. */
1712static int
1713pack_single(char *ptr, PyObject *item, const char *fmt)
1714{
1715 unsigned PY_LONG_LONG llu;
1716 unsigned long lu;
1717 size_t zu;
1718 PY_LONG_LONG lld;
1719 long ld;
1720 Py_ssize_t zd;
1721 double d;
1722 void *p;
1723
1724 switch (fmt[0]) {
1725 /* signed integers */
1726 case 'b': case 'h': case 'i': case 'l':
1727 ld = pylong_as_ld(item);
1728 if (ld == -1 && PyErr_Occurred())
1729 goto err_occurred;
1730 switch (fmt[0]) {
1731 case 'b':
1732 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1733 *((signed char *)ptr) = (signed char)ld; break;
1734 case 'h':
1735 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1736 PACK_SINGLE(ptr, ld, short); break;
1737 case 'i':
1738 if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1739 PACK_SINGLE(ptr, ld, int); break;
1740 default: /* 'l' */
1741 PACK_SINGLE(ptr, ld, long); break;
1742 }
1743 break;
1744
1745 /* unsigned integers */
1746 case 'B': case 'H': case 'I': case 'L':
1747 lu = pylong_as_lu(item);
1748 if (lu == (unsigned long)-1 && PyErr_Occurred())
1749 goto err_occurred;
1750 switch (fmt[0]) {
1751 case 'B':
1752 if (lu > UCHAR_MAX) goto err_range;
1753 *((unsigned char *)ptr) = (unsigned char)lu; break;
1754 case 'H':
1755 if (lu > USHRT_MAX) goto err_range;
1756 PACK_SINGLE(ptr, lu, unsigned short); break;
1757 case 'I':
1758 if (lu > UINT_MAX) goto err_range;
1759 PACK_SINGLE(ptr, lu, unsigned int); break;
1760 default: /* 'L' */
1761 PACK_SINGLE(ptr, lu, unsigned long); break;
1762 }
1763 break;
1764
1765 /* native 64-bit */
1766 #ifdef HAVE_LONG_LONG
1767 case 'q':
1768 lld = pylong_as_lld(item);
1769 if (lld == -1 && PyErr_Occurred())
1770 goto err_occurred;
1771 PACK_SINGLE(ptr, lld, PY_LONG_LONG);
1772 break;
1773 case 'Q':
1774 llu = pylong_as_llu(item);
1775 if (llu == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
1776 goto err_occurred;
1777 PACK_SINGLE(ptr, llu, unsigned PY_LONG_LONG);
1778 break;
1779 #endif
1780
1781 /* ssize_t and size_t */
1782 case 'n':
1783 zd = pylong_as_zd(item);
1784 if (zd == -1 && PyErr_Occurred())
1785 goto err_occurred;
1786 PACK_SINGLE(ptr, zd, Py_ssize_t);
1787 break;
1788 case 'N':
1789 zu = pylong_as_zu(item);
1790 if (zu == (size_t)-1 && PyErr_Occurred())
1791 goto err_occurred;
1792 PACK_SINGLE(ptr, zu, size_t);
1793 break;
1794
1795 /* floats */
1796 case 'f': case 'd':
1797 d = PyFloat_AsDouble(item);
1798 if (d == -1.0 && PyErr_Occurred())
1799 goto err_occurred;
1800 if (fmt[0] == 'f') {
1801 PACK_SINGLE(ptr, d, float);
1802 }
1803 else {
1804 PACK_SINGLE(ptr, d, double);
1805 }
1806 break;
1807
1808 /* bool */
1809 case '?':
1810 ld = PyObject_IsTrue(item);
1811 if (ld < 0)
1812 return -1; /* preserve original error */
1813 #ifdef HAVE_C99_BOOL
1814 PACK_SINGLE(ptr, ld, _Bool);
1815 #else
1816 PACK_SINGLE(ptr, ld, char);
1817 #endif
1818 break;
1819
1820 /* bytes object */
1821 case 'c':
1822 if (!PyBytes_Check(item))
1823 return type_error_int(fmt);
1824 if (PyBytes_GET_SIZE(item) != 1)
1825 return value_error_int(fmt);
1826 *ptr = PyBytes_AS_STRING(item)[0];
1827 break;
1828
1829 /* pointer */
1830 case 'P':
1831 p = PyLong_AsVoidPtr(item);
1832 if (p == NULL && PyErr_Occurred())
1833 goto err_occurred;
1834 PACK_SINGLE(ptr, p, void *);
1835 break;
1836
1837 /* default */
1838 default: goto err_format;
1839 }
1840
1841 return 0;
1842
1843err_occurred:
1844 return fix_error_int(fmt);
1845err_range:
1846 return value_error_int(fmt);
1847err_format:
1848 PyErr_Format(PyExc_NotImplementedError,
1849 "memoryview: format %s not supported", fmt);
1850 return -1;
1851}
1852
1853
1854/****************************************************************************/
Nick Coghlan06e1ab02012-08-25 17:59:50 +10001855/* unpack using the struct module */
1856/****************************************************************************/
1857
1858/* For reasonable performance it is necessary to cache all objects required
1859 for unpacking. An unpacker can handle the format passed to unpack_from().
1860 Invariant: All pointer fields of the struct should either be NULL or valid
1861 pointers. */
1862struct unpacker {
1863 PyObject *unpack_from; /* Struct.unpack_from(format) */
1864 PyObject *mview; /* cached memoryview */
1865 char *item; /* buffer for mview */
1866 Py_ssize_t itemsize; /* len(item) */
1867};
1868
1869static struct unpacker *
1870unpacker_new(void)
1871{
1872 struct unpacker *x = PyMem_Malloc(sizeof *x);
1873
1874 if (x == NULL) {
1875 PyErr_NoMemory();
1876 return NULL;
1877 }
1878
1879 x->unpack_from = NULL;
1880 x->mview = NULL;
1881 x->item = NULL;
1882 x->itemsize = 0;
1883
1884 return x;
1885}
1886
1887static void
1888unpacker_free(struct unpacker *x)
1889{
1890 if (x) {
1891 Py_XDECREF(x->unpack_from);
1892 Py_XDECREF(x->mview);
1893 PyMem_Free(x->item);
1894 PyMem_Free(x);
1895 }
1896}
1897
1898/* Return a new unpacker for the given format. */
1899static struct unpacker *
1900struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
1901{
1902 PyObject *structmodule; /* XXX cache these two */
1903 PyObject *Struct = NULL; /* XXX in globals? */
1904 PyObject *structobj = NULL;
1905 PyObject *format = NULL;
1906 struct unpacker *x = NULL;
1907
1908 structmodule = PyImport_ImportModule("struct");
1909 if (structmodule == NULL)
1910 return NULL;
1911
1912 Struct = PyObject_GetAttrString(structmodule, "Struct");
1913 Py_DECREF(structmodule);
1914 if (Struct == NULL)
1915 return NULL;
1916
1917 x = unpacker_new();
1918 if (x == NULL)
1919 goto error;
1920
1921 format = PyBytes_FromString(fmt);
1922 if (format == NULL)
1923 goto error;
1924
1925 structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
1926 if (structobj == NULL)
1927 goto error;
1928
1929 x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
1930 if (x->unpack_from == NULL)
1931 goto error;
1932
1933 x->item = PyMem_Malloc(itemsize);
1934 if (x->item == NULL) {
1935 PyErr_NoMemory();
1936 goto error;
1937 }
1938 x->itemsize = itemsize;
1939
1940 x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
1941 if (x->mview == NULL)
1942 goto error;
1943
1944
1945out:
1946 Py_XDECREF(Struct);
1947 Py_XDECREF(format);
1948 Py_XDECREF(structobj);
1949 return x;
1950
1951error:
1952 unpacker_free(x);
1953 x = NULL;
1954 goto out;
1955}
1956
1957/* unpack a single item */
1958static PyObject *
1959struct_unpack_single(const char *ptr, struct unpacker *x)
1960{
1961 PyObject *v;
1962
1963 memcpy(x->item, ptr, x->itemsize);
1964 v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL);
1965 if (v == NULL)
1966 return NULL;
1967
1968 if (PyTuple_GET_SIZE(v) == 1) {
1969 PyObject *tmp = PyTuple_GET_ITEM(v, 0);
1970 Py_INCREF(tmp);
1971 Py_DECREF(v);
1972 return tmp;
1973 }
1974
1975 return v;
1976}
1977
1978
1979/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001980/* Representations */
1981/****************************************************************************/
1982
1983/* allow explicit form of native format */
1984Py_LOCAL_INLINE(const char *)
1985adjust_fmt(const Py_buffer *view)
1986{
1987 const char *fmt;
1988
1989 fmt = (view->format[0] == '@') ? view->format+1 : view->format;
1990 if (fmt[0] && fmt[1] == '\0')
1991 return fmt;
1992
1993 PyErr_Format(PyExc_NotImplementedError,
1994 "memoryview: unsupported format %s", view->format);
1995 return NULL;
1996}
1997
1998/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
1999static PyObject *
2000tolist_base(const char *ptr, const Py_ssize_t *shape,
2001 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2002 const char *fmt)
2003{
2004 PyObject *lst, *item;
2005 Py_ssize_t i;
2006
2007 lst = PyList_New(shape[0]);
2008 if (lst == NULL)
2009 return NULL;
2010
2011 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2012 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2013 item = unpack_single(xptr, fmt);
2014 if (item == NULL) {
2015 Py_DECREF(lst);
2016 return NULL;
2017 }
2018 PyList_SET_ITEM(lst, i, item);
2019 }
2020
2021 return lst;
2022}
2023
2024/* Unpack a multi-dimensional array into a nested list.
2025 Assumption: ndim >= 1. */
2026static PyObject *
2027tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
2028 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2029 const char *fmt)
2030{
2031 PyObject *lst, *item;
2032 Py_ssize_t i;
2033
2034 assert(ndim >= 1);
2035 assert(shape != NULL);
2036 assert(strides != NULL);
2037
2038 if (ndim == 1)
2039 return tolist_base(ptr, shape, strides, suboffsets, fmt);
2040
2041 lst = PyList_New(shape[0]);
2042 if (lst == NULL)
2043 return NULL;
2044
2045 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2046 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2047 item = tolist_rec(xptr, ndim-1, shape+1,
2048 strides+1, suboffsets ? suboffsets+1 : NULL,
2049 fmt);
2050 if (item == NULL) {
2051 Py_DECREF(lst);
2052 return NULL;
2053 }
2054 PyList_SET_ITEM(lst, i, item);
2055 }
2056
2057 return lst;
2058}
2059
2060/* Return a list representation of the memoryview. Currently only buffers
2061 with native format strings are supported. */
2062static PyObject *
2063memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
2064{
2065 const Py_buffer *view = &(mv->view);
2066 const char *fmt;
2067
2068 CHECK_RELEASED(mv);
2069
2070 fmt = adjust_fmt(view);
2071 if (fmt == NULL)
2072 return NULL;
2073 if (view->ndim == 0) {
2074 return unpack_single(view->buf, fmt);
2075 }
2076 else if (view->ndim == 1) {
2077 return tolist_base(view->buf, view->shape,
2078 view->strides, view->suboffsets,
2079 fmt);
2080 }
2081 else {
2082 return tolist_rec(view->buf, view->ndim, view->shape,
2083 view->strides, view->suboffsets,
2084 fmt);
2085 }
2086}
2087
2088static PyObject *
2089memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
2090{
2091 Py_buffer *src = VIEW_ADDR(self);
2092 PyObject *bytes = NULL;
2093
2094 CHECK_RELEASED(self);
2095
2096 if (MV_C_CONTIGUOUS(self->flags)) {
2097 return PyBytes_FromStringAndSize(src->buf, src->len);
2098 }
2099
2100 bytes = PyBytes_FromStringAndSize(NULL, src->len);
2101 if (bytes == NULL)
2102 return NULL;
2103
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002104 if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002105 Py_DECREF(bytes);
2106 return NULL;
2107 }
2108
2109 return bytes;
2110}
2111
2112static PyObject *
2113memory_repr(PyMemoryViewObject *self)
2114{
2115 if (self->flags & _Py_MEMORYVIEW_RELEASED)
2116 return PyUnicode_FromFormat("<released memory at %p>", self);
2117 else
2118 return PyUnicode_FromFormat("<memory at %p>", self);
2119}
2120
2121
2122/**************************************************************************/
2123/* Indexing and slicing */
2124/**************************************************************************/
2125
2126/* Get the pointer to the item at index. */
2127static char *
2128ptr_from_index(Py_buffer *view, Py_ssize_t index)
2129{
2130 char *ptr;
2131 Py_ssize_t nitems; /* items in the first dimension */
2132
2133 assert(view->shape);
2134 assert(view->strides);
2135
2136 nitems = view->shape[0];
2137 if (index < 0) {
2138 index += nitems;
2139 }
2140 if (index < 0 || index >= nitems) {
2141 PyErr_SetString(PyExc_IndexError, "index out of bounds");
2142 return NULL;
2143 }
2144
2145 ptr = (char *)view->buf;
2146 ptr += view->strides[0] * index;
2147
2148 ptr = ADJUST_PTR(ptr, view->suboffsets);
2149
2150 return ptr;
2151}
2152
2153/* Return the item at index. In a one-dimensional view, this is an object
2154 with the type specified by view->format. Otherwise, the item is a sub-view.
2155 The function is used in memory_subscript() and memory_as_sequence. */
2156static PyObject *
2157memory_item(PyMemoryViewObject *self, Py_ssize_t index)
2158{
2159 Py_buffer *view = &(self->view);
2160 const char *fmt;
2161
2162 CHECK_RELEASED(self);
2163
2164 fmt = adjust_fmt(view);
2165 if (fmt == NULL)
2166 return NULL;
2167
2168 if (view->ndim == 0) {
2169 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
2170 return NULL;
2171 }
2172 if (view->ndim == 1) {
2173 char *ptr = ptr_from_index(view, index);
2174 if (ptr == NULL)
2175 return NULL;
2176 return unpack_single(ptr, fmt);
2177 }
2178
2179 PyErr_SetString(PyExc_NotImplementedError,
2180 "multi-dimensional sub-views are not implemented");
2181 return NULL;
2182}
2183
2184Py_LOCAL_INLINE(int)
2185init_slice(Py_buffer *base, PyObject *key, int dim)
2186{
2187 Py_ssize_t start, stop, step, slicelength;
2188
2189 if (PySlice_GetIndicesEx(key, base->shape[dim],
2190 &start, &stop, &step, &slicelength) < 0) {
2191 return -1;
2192 }
2193
2194
2195 if (base->suboffsets == NULL || dim == 0) {
2196 adjust_buf:
2197 base->buf = (char *)base->buf + base->strides[dim] * start;
2198 }
2199 else {
2200 Py_ssize_t n = dim-1;
2201 while (n >= 0 && base->suboffsets[n] < 0)
2202 n--;
2203 if (n < 0)
2204 goto adjust_buf; /* all suboffsets are negative */
2205 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
2206 }
2207 base->shape[dim] = slicelength;
2208 base->strides[dim] = base->strides[dim] * step;
2209
2210 return 0;
2211}
2212
2213static int
2214is_multislice(PyObject *key)
2215{
2216 Py_ssize_t size, i;
2217
2218 if (!PyTuple_Check(key))
2219 return 0;
2220 size = PyTuple_GET_SIZE(key);
2221 if (size == 0)
2222 return 0;
2223
2224 for (i = 0; i < size; i++) {
2225 PyObject *x = PyTuple_GET_ITEM(key, i);
2226 if (!PySlice_Check(x))
2227 return 0;
2228 }
2229 return 1;
2230}
2231
2232/* mv[obj] returns an object holding the data for one element if obj
2233 fully indexes the memoryview or another memoryview object if it
2234 does not.
2235
2236 0-d memoryview objects can be referenced using mv[...] or mv[()]
2237 but not with anything else. */
2238static PyObject *
2239memory_subscript(PyMemoryViewObject *self, PyObject *key)
2240{
2241 Py_buffer *view;
2242 view = &(self->view);
2243
2244 CHECK_RELEASED(self);
2245
2246 if (view->ndim == 0) {
2247 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2248 const char *fmt = adjust_fmt(view);
2249 if (fmt == NULL)
2250 return NULL;
2251 return unpack_single(view->buf, fmt);
2252 }
2253 else if (key == Py_Ellipsis) {
2254 Py_INCREF(self);
2255 return (PyObject *)self;
2256 }
2257 else {
2258 PyErr_SetString(PyExc_TypeError,
2259 "invalid indexing of 0-dim memory");
2260 return NULL;
2261 }
2262 }
2263
2264 if (PyIndex_Check(key)) {
2265 Py_ssize_t index;
2266 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2267 if (index == -1 && PyErr_Occurred())
2268 return NULL;
2269 return memory_item(self, index);
2270 }
2271 else if (PySlice_Check(key)) {
2272 PyMemoryViewObject *sliced;
2273
2274 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2275 if (sliced == NULL)
2276 return NULL;
2277
2278 if (init_slice(&sliced->view, key, 0) < 0) {
2279 Py_DECREF(sliced);
2280 return NULL;
2281 }
2282 init_len(&sliced->view);
2283 init_flags(sliced);
2284
2285 return (PyObject *)sliced;
2286 }
2287 else if (is_multislice(key)) {
2288 PyErr_SetString(PyExc_NotImplementedError,
2289 "multi-dimensional slicing is not implemented");
2290 return NULL;
2291 }
2292
2293 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2294 return NULL;
2295}
2296
2297static int
2298memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2299{
2300 Py_buffer *view = &(self->view);
2301 Py_buffer src;
2302 const char *fmt;
2303 char *ptr;
2304
2305 CHECK_RELEASED_INT(self);
2306
2307 fmt = adjust_fmt(view);
2308 if (fmt == NULL)
2309 return -1;
2310
2311 if (view->readonly) {
2312 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2313 return -1;
2314 }
2315 if (value == NULL) {
2316 PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2317 return -1;
2318 }
2319 if (view->ndim == 0) {
2320 if (key == Py_Ellipsis ||
2321 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2322 ptr = (char *)view->buf;
2323 return pack_single(ptr, value, fmt);
2324 }
2325 else {
2326 PyErr_SetString(PyExc_TypeError,
2327 "invalid indexing of 0-dim memory");
2328 return -1;
2329 }
2330 }
2331 if (view->ndim != 1) {
2332 PyErr_SetString(PyExc_NotImplementedError,
2333 "memoryview assignments are currently restricted to ndim = 1");
2334 return -1;
2335 }
2336
2337 if (PyIndex_Check(key)) {
2338 Py_ssize_t index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2339 if (index == -1 && PyErr_Occurred())
2340 return -1;
2341 ptr = ptr_from_index(view, index);
2342 if (ptr == NULL)
2343 return -1;
2344 return pack_single(ptr, value, fmt);
2345 }
2346 /* one-dimensional: fast path */
2347 if (PySlice_Check(key) && view->ndim == 1) {
2348 Py_buffer dest; /* sliced view */
2349 Py_ssize_t arrays[3];
2350 int ret = -1;
2351
2352 /* rvalue must be an exporter */
2353 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2354 return ret;
2355
2356 dest = *view;
2357 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2358 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2359 if (view->suboffsets) {
2360 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2361 }
2362
2363 if (init_slice(&dest, key, 0) < 0)
2364 goto end_block;
2365 dest.len = dest.shape[0] * dest.itemsize;
2366
2367 ret = copy_single(&dest, &src);
2368
2369 end_block:
2370 PyBuffer_Release(&src);
2371 return ret;
2372 }
2373 else if (PySlice_Check(key) || is_multislice(key)) {
2374 /* Call memory_subscript() to produce a sliced lvalue, then copy
2375 rvalue into lvalue. This is already implemented in _testbuffer.c. */
2376 PyErr_SetString(PyExc_NotImplementedError,
2377 "memoryview slice assignments are currently restricted "
2378 "to ndim = 1");
2379 return -1;
2380 }
2381
2382 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2383 return -1;
2384}
2385
2386static Py_ssize_t
2387memory_length(PyMemoryViewObject *self)
2388{
2389 CHECK_RELEASED_INT(self);
2390 return self->view.ndim == 0 ? 1 : self->view.shape[0];
2391}
2392
2393/* As mapping */
2394static PyMappingMethods memory_as_mapping = {
2395 (lenfunc)memory_length, /* mp_length */
2396 (binaryfunc)memory_subscript, /* mp_subscript */
2397 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
2398};
2399
2400/* As sequence */
2401static PySequenceMethods memory_as_sequence = {
Nick Coghlana0f169c2013-10-02 22:06:54 +10002402 (lenfunc)memory_length, /* sq_length */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002403 0, /* sq_concat */
2404 0, /* sq_repeat */
2405 (ssizeargfunc)memory_item, /* sq_item */
2406};
2407
2408
2409/**************************************************************************/
2410/* Comparisons */
2411/**************************************************************************/
2412
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002413#define MV_COMPARE_EX -1 /* exception */
2414#define MV_COMPARE_NOT_IMPL -2 /* not implemented */
2415
2416/* Translate a StructError to "not equal". Preserve other exceptions. */
2417static int
2418fix_struct_error_int(void)
2419{
2420 assert(PyErr_Occurred());
2421 /* XXX Cannot get at StructError directly? */
2422 if (PyErr_ExceptionMatches(PyExc_ImportError) ||
2423 PyErr_ExceptionMatches(PyExc_MemoryError)) {
2424 return MV_COMPARE_EX;
2425 }
2426 /* StructError: invalid or unknown format -> not equal */
2427 PyErr_Clear();
2428 return 0;
2429}
2430
2431/* Unpack and compare single items of p and q using the struct module. */
2432static int
2433struct_unpack_cmp(const char *p, const char *q,
2434 struct unpacker *unpack_p, struct unpacker *unpack_q)
2435{
2436 PyObject *v, *w;
2437 int ret;
2438
2439 /* At this point any exception from the struct module should not be
2440 StructError, since both formats have been accepted already. */
2441 v = struct_unpack_single(p, unpack_p);
2442 if (v == NULL)
2443 return MV_COMPARE_EX;
2444
2445 w = struct_unpack_single(q, unpack_q);
2446 if (w == NULL) {
2447 Py_DECREF(v);
2448 return MV_COMPARE_EX;
2449 }
2450
2451 /* MV_COMPARE_EX == -1: exceptions are preserved */
2452 ret = PyObject_RichCompareBool(v, w, Py_EQ);
2453 Py_DECREF(v);
2454 Py_DECREF(w);
2455
2456 return ret;
2457}
2458
2459/* Unpack and compare single items of p and q. If both p and q have the same
2460 single element native format, the comparison uses a fast path (gcc creates
2461 a jump table and converts memcpy into simple assignments on x86/x64).
2462
2463 Otherwise, the comparison is delegated to the struct module, which is
2464 30-60x slower. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002465#define CMP_SINGLE(p, q, type) \
2466 do { \
2467 type x; \
2468 type y; \
2469 memcpy((char *)&x, p, sizeof x); \
2470 memcpy((char *)&y, q, sizeof y); \
2471 equal = (x == y); \
2472 } while (0)
2473
2474Py_LOCAL_INLINE(int)
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002475unpack_cmp(const char *p, const char *q, char fmt,
2476 struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002477{
2478 int equal;
2479
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002480 switch (fmt) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002481
2482 /* signed integers and fast path for 'B' */
2483 case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
2484 case 'b': return *((signed char *)p) == *((signed char *)q);
2485 case 'h': CMP_SINGLE(p, q, short); return equal;
2486 case 'i': CMP_SINGLE(p, q, int); return equal;
2487 case 'l': CMP_SINGLE(p, q, long); return equal;
2488
2489 /* boolean */
2490 #ifdef HAVE_C99_BOOL
2491 case '?': CMP_SINGLE(p, q, _Bool); return equal;
2492 #else
2493 case '?': CMP_SINGLE(p, q, char); return equal;
2494 #endif
2495
2496 /* unsigned integers */
2497 case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2498 case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2499 case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2500
2501 /* native 64-bit */
2502 #ifdef HAVE_LONG_LONG
2503 case 'q': CMP_SINGLE(p, q, PY_LONG_LONG); return equal;
2504 case 'Q': CMP_SINGLE(p, q, unsigned PY_LONG_LONG); return equal;
2505 #endif
2506
2507 /* ssize_t and size_t */
2508 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2509 case 'N': CMP_SINGLE(p, q, size_t); return equal;
2510
2511 /* floats */
2512 /* XXX DBL_EPSILON? */
2513 case 'f': CMP_SINGLE(p, q, float); return equal;
2514 case 'd': CMP_SINGLE(p, q, double); return equal;
2515
2516 /* bytes object */
2517 case 'c': return *p == *q;
2518
2519 /* pointer */
2520 case 'P': CMP_SINGLE(p, q, void *); return equal;
2521
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002522 /* use the struct module */
2523 case '_':
2524 assert(unpack_p);
2525 assert(unpack_q);
2526 return struct_unpack_cmp(p, q, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002527 }
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002528
2529 /* NOT REACHED */
2530 PyErr_SetString(PyExc_RuntimeError,
2531 "memoryview: internal error in richcompare");
2532 return MV_COMPARE_EX;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002533}
2534
2535/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2536static int
2537cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2538 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2539 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002540 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002541{
2542 Py_ssize_t i;
2543 int equal;
2544
2545 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2546 const char *xp = ADJUST_PTR(p, psuboffsets);
2547 const char *xq = ADJUST_PTR(q, qsuboffsets);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002548 equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002549 if (equal <= 0)
2550 return equal;
2551 }
2552
2553 return 1;
2554}
2555
2556/* Recursively compare two multi-dimensional arrays that have the same
2557 logical structure. Assumption: ndim >= 1. */
2558static int
2559cmp_rec(const char *p, const char *q,
2560 Py_ssize_t ndim, const Py_ssize_t *shape,
2561 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2562 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002563 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002564{
2565 Py_ssize_t i;
2566 int equal;
2567
2568 assert(ndim >= 1);
2569 assert(shape != NULL);
2570 assert(pstrides != NULL);
2571 assert(qstrides != NULL);
2572
2573 if (ndim == 1) {
2574 return cmp_base(p, q, shape,
2575 pstrides, psuboffsets,
2576 qstrides, qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002577 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002578 }
2579
2580 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2581 const char *xp = ADJUST_PTR(p, psuboffsets);
2582 const char *xq = ADJUST_PTR(q, qsuboffsets);
2583 equal = cmp_rec(xp, xq, ndim-1, shape+1,
2584 pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2585 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002586 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002587 if (equal <= 0)
2588 return equal;
2589 }
2590
2591 return 1;
2592}
2593
2594static PyObject *
2595memory_richcompare(PyObject *v, PyObject *w, int op)
2596{
2597 PyObject *res;
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002598 Py_buffer wbuf, *vv;
2599 Py_buffer *ww = NULL;
2600 struct unpacker *unpack_v = NULL;
2601 struct unpacker *unpack_w = NULL;
2602 char vfmt, wfmt;
2603 int equal = MV_COMPARE_NOT_IMPL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002604
2605 if (op != Py_EQ && op != Py_NE)
2606 goto result; /* Py_NotImplemented */
2607
2608 assert(PyMemoryView_Check(v));
2609 if (BASE_INACCESSIBLE(v)) {
2610 equal = (v == w);
2611 goto result;
2612 }
2613 vv = VIEW_ADDR(v);
2614
2615 if (PyMemoryView_Check(w)) {
2616 if (BASE_INACCESSIBLE(w)) {
2617 equal = (v == w);
2618 goto result;
2619 }
2620 ww = VIEW_ADDR(w);
2621 }
2622 else {
2623 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2624 PyErr_Clear();
2625 goto result; /* Py_NotImplemented */
2626 }
2627 ww = &wbuf;
2628 }
2629
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002630 if (!equiv_shape(vv, ww)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002631 PyErr_Clear();
2632 equal = 0;
2633 goto result;
2634 }
2635
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002636 /* Use fast unpacking for identical primitive C type formats. */
2637 if (get_native_fmtchar(&vfmt, vv->format) < 0)
2638 vfmt = '_';
2639 if (get_native_fmtchar(&wfmt, ww->format) < 0)
2640 wfmt = '_';
2641 if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
2642 /* Use struct module unpacking. NOTE: Even for equal format strings,
2643 memcmp() cannot be used for item comparison since it would give
2644 incorrect results in the case of NaNs or uninitialized padding
2645 bytes. */
2646 vfmt = '_';
2647 unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
2648 if (unpack_v == NULL) {
2649 equal = fix_struct_error_int();
2650 goto result;
2651 }
2652 unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
2653 if (unpack_w == NULL) {
2654 equal = fix_struct_error_int();
2655 goto result;
2656 }
2657 }
2658
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002659 if (vv->ndim == 0) {
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002660 equal = unpack_cmp(vv->buf, ww->buf,
2661 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002662 }
2663 else if (vv->ndim == 1) {
2664 equal = cmp_base(vv->buf, ww->buf, vv->shape,
2665 vv->strides, vv->suboffsets,
2666 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002667 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002668 }
2669 else {
2670 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2671 vv->strides, vv->suboffsets,
2672 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002673 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002674 }
2675
2676result:
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002677 if (equal < 0) {
2678 if (equal == MV_COMPARE_NOT_IMPL)
2679 res = Py_NotImplemented;
2680 else /* exception */
2681 res = NULL;
2682 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002683 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2684 res = Py_True;
2685 else
2686 res = Py_False;
2687
2688 if (ww == &wbuf)
2689 PyBuffer_Release(ww);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002690
2691 unpacker_free(unpack_v);
2692 unpacker_free(unpack_w);
2693
2694 Py_XINCREF(res);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002695 return res;
2696}
2697
2698/**************************************************************************/
2699/* Hash */
2700/**************************************************************************/
2701
2702static Py_hash_t
2703memory_hash(PyMemoryViewObject *self)
2704{
2705 if (self->hash == -1) {
2706 Py_buffer *view = &self->view;
2707 char *mem = view->buf;
Stefan Krah4af77a02012-11-02 17:49:22 +01002708 Py_ssize_t ret;
2709 char fmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002710
2711 CHECK_RELEASED_INT(self);
2712
2713 if (!view->readonly) {
2714 PyErr_SetString(PyExc_ValueError,
2715 "cannot hash writable memoryview object");
2716 return -1;
2717 }
Stefan Krah4af77a02012-11-02 17:49:22 +01002718 ret = get_native_fmtchar(&fmt, view->format);
2719 if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
2720 PyErr_SetString(PyExc_ValueError,
2721 "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
2722 return -1;
2723 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002724 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2725 /* Keep the original error message */
2726 return -1;
2727 }
2728
2729 if (!MV_C_CONTIGUOUS(self->flags)) {
2730 mem = PyMem_Malloc(view->len);
2731 if (mem == NULL) {
2732 PyErr_NoMemory();
2733 return -1;
2734 }
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002735 if (buffer_to_contiguous(mem, view, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002736 PyMem_Free(mem);
2737 return -1;
2738 }
2739 }
2740
2741 /* Can't fail */
Christian Heimes985ecdc2013-11-20 11:46:18 +01002742 self->hash = _Py_HashBytes(mem, view->len);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002743
2744 if (mem != view->buf)
2745 PyMem_Free(mem);
2746 }
2747
2748 return self->hash;
2749}
2750
2751
2752/**************************************************************************/
2753/* getters */
2754/**************************************************************************/
2755
2756static PyObject *
2757_IntTupleFromSsizet(int len, Py_ssize_t *vals)
2758{
2759 int i;
2760 PyObject *o;
2761 PyObject *intTuple;
2762
2763 if (vals == NULL)
2764 return PyTuple_New(0);
2765
2766 intTuple = PyTuple_New(len);
2767 if (!intTuple)
2768 return NULL;
2769 for (i=0; i<len; i++) {
2770 o = PyLong_FromSsize_t(vals[i]);
2771 if (!o) {
2772 Py_DECREF(intTuple);
2773 return NULL;
2774 }
2775 PyTuple_SET_ITEM(intTuple, i, o);
2776 }
2777 return intTuple;
2778}
2779
2780static PyObject *
2781memory_obj_get(PyMemoryViewObject *self)
2782{
2783 Py_buffer *view = &self->view;
2784
2785 CHECK_RELEASED(self);
2786 if (view->obj == NULL) {
2787 Py_RETURN_NONE;
2788 }
2789 Py_INCREF(view->obj);
2790 return view->obj;
2791}
2792
2793static PyObject *
2794memory_nbytes_get(PyMemoryViewObject *self)
2795{
2796 CHECK_RELEASED(self);
2797 return PyLong_FromSsize_t(self->view.len);
2798}
2799
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002800static PyObject *
2801memory_format_get(PyMemoryViewObject *self)
2802{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002803 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002804 return PyUnicode_FromString(self->view.format);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002805}
2806
2807static PyObject *
2808memory_itemsize_get(PyMemoryViewObject *self)
2809{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002810 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002811 return PyLong_FromSsize_t(self->view.itemsize);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002812}
2813
2814static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002815memory_shape_get(PyMemoryViewObject *self)
2816{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002817 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002818 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002819}
2820
2821static PyObject *
2822memory_strides_get(PyMemoryViewObject *self)
2823{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002824 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002825 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002826}
2827
2828static PyObject *
2829memory_suboffsets_get(PyMemoryViewObject *self)
2830{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002831 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002832 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002833}
2834
2835static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002836memory_readonly_get(PyMemoryViewObject *self)
2837{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002838 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002839 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002840}
2841
2842static PyObject *
2843memory_ndim_get(PyMemoryViewObject *self)
2844{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002845 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002846 return PyLong_FromLong(self->view.ndim);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002847}
2848
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002849static PyObject *
2850memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2851{
2852 CHECK_RELEASED(self);
2853 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
2854}
2855
2856static PyObject *
2857memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2858{
2859 CHECK_RELEASED(self);
2860 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
2861}
2862
2863static PyObject *
2864memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2865{
2866 CHECK_RELEASED(self);
2867 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
2868}
2869
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002870PyDoc_STRVAR(memory_obj_doc,
2871 "The underlying object of the memoryview.");
2872PyDoc_STRVAR(memory_nbytes_doc,
2873 "The amount of space in bytes that the array would use in\n"
2874 " a contiguous representation.");
2875PyDoc_STRVAR(memory_readonly_doc,
2876 "A bool indicating whether the memory is read only.");
2877PyDoc_STRVAR(memory_itemsize_doc,
2878 "The size in bytes of each element of the memoryview.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002879PyDoc_STRVAR(memory_format_doc,
2880 "A string containing the format (in struct module style)\n"
2881 " for each element in the view.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002882PyDoc_STRVAR(memory_ndim_doc,
2883 "An integer indicating how many dimensions of a multi-dimensional\n"
2884 " array the memory represents.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002885PyDoc_STRVAR(memory_shape_doc,
2886 "A tuple of ndim integers giving the shape of the memory\n"
2887 " as an N-dimensional array.");
2888PyDoc_STRVAR(memory_strides_doc,
2889 "A tuple of ndim integers giving the size in bytes to access\n"
2890 " each element for each dimension of the array.");
2891PyDoc_STRVAR(memory_suboffsets_doc,
2892 "A tuple of integers used internally for PIL-style arrays.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002893PyDoc_STRVAR(memory_c_contiguous_doc,
2894 "A bool indicating whether the memory is C contiguous.");
2895PyDoc_STRVAR(memory_f_contiguous_doc,
2896 "A bool indicating whether the memory is Fortran contiguous.");
2897PyDoc_STRVAR(memory_contiguous_doc,
2898 "A bool indicating whether the memory is contiguous.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002899
Stefan Krahbcaf5992014-05-18 00:35:09 +02002900
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002901static PyGetSetDef memory_getsetlist[] = {
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002902 {"obj", (getter)memory_obj_get, NULL, memory_obj_doc},
2903 {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc},
Alexander Belopolskye370c382012-09-03 16:43:55 -04002904 {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc},
2905 {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc},
2906 {"format", (getter)memory_format_get, NULL, memory_format_doc},
2907 {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc},
2908 {"shape", (getter)memory_shape_get, NULL, memory_shape_doc},
2909 {"strides", (getter)memory_strides_get, NULL, memory_strides_doc},
2910 {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002911 {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc},
2912 {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc},
2913 {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc},
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002914 {NULL, NULL, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002915};
2916
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002917PyDoc_STRVAR(memory_release_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02002918"release($self, /)\n--\n\
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002919\n\
2920Release the underlying buffer exposed by the memoryview object.");
2921PyDoc_STRVAR(memory_tobytes_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02002922"tobytes($self, /)\n--\n\
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002923\n\
2924Return the data in the buffer as a byte string.");
2925PyDoc_STRVAR(memory_tolist_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02002926"tolist($self, /)\n--\n\
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002927\n\
2928Return the data in the buffer as a list of elements.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002929PyDoc_STRVAR(memory_cast_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02002930"cast($self, /, format, *, shape)\n--\n\
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002931\n\
2932Cast a memoryview to a new format or shape.");
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002933
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002934static PyMethodDef memory_methods[] = {
Alexander Belopolskye370c382012-09-03 16:43:55 -04002935 {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
2936 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc},
2937 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002938 {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
Stefan Krahe4c07992012-07-28 14:10:02 +02002939 {"__enter__", memory_enter, METH_NOARGS, NULL},
2940 {"__exit__", memory_exit, METH_VARARGS, NULL},
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002941 {NULL, NULL}
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002942};
2943
2944
2945PyTypeObject PyMemoryView_Type = {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002946 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002947 "memoryview", /* tp_name */
2948 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */
2949 sizeof(Py_ssize_t), /* tp_itemsize */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002950 (destructor)memory_dealloc, /* tp_dealloc */
2951 0, /* tp_print */
2952 0, /* tp_getattr */
2953 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002954 0, /* tp_reserved */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002955 (reprfunc)memory_repr, /* tp_repr */
2956 0, /* tp_as_number */
Raymond Hettinger159eac92009-06-23 20:38:54 +00002957 &memory_as_sequence, /* tp_as_sequence */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002958 &memory_as_mapping, /* tp_as_mapping */
Antoine Pitrouce4a9da2011-11-21 20:46:33 +01002959 (hashfunc)memory_hash, /* tp_hash */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002960 0, /* tp_call */
Benjamin Peterson87618552009-02-08 15:00:52 +00002961 0, /* tp_str */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002962 PyObject_GenericGetAttr, /* tp_getattro */
2963 0, /* tp_setattro */
2964 &memory_as_buffer, /* tp_as_buffer */
2965 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2966 memory_doc, /* tp_doc */
2967 (traverseproc)memory_traverse, /* tp_traverse */
2968 (inquiry)memory_clear, /* tp_clear */
2969 memory_richcompare, /* tp_richcompare */
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01002970 offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002971 0, /* tp_iter */
2972 0, /* tp_iternext */
2973 memory_methods, /* tp_methods */
2974 0, /* tp_members */
2975 memory_getsetlist, /* tp_getset */
2976 0, /* tp_base */
2977 0, /* tp_dict */
2978 0, /* tp_descr_get */
2979 0, /* tp_descr_set */
2980 0, /* tp_dictoffset */
2981 0, /* tp_init */
2982 0, /* tp_alloc */
2983 memory_new, /* tp_new */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002984};