blob: cb644b822b7ab1d09be9b5936399ffc9d9ffd2c5 [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
51#define XSTRINGIZE(v) #v
52#define STRINGIZE(v) XSTRINGIZE(v)
53
54#define CHECK_MBUF_RELEASED(mbuf) \
55 if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \
56 PyErr_SetString(PyExc_ValueError, \
57 "operation forbidden on released memoryview object"); \
58 return NULL; \
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000059 }
60
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000061
Stefan Krah9a2d99e2012-02-25 12:24:21 +010062Py_LOCAL_INLINE(_PyManagedBufferObject *)
63mbuf_alloc(void)
Antoine Pitroubc420402008-12-07 20:14:49 +000064{
Stefan Krah9a2d99e2012-02-25 12:24:21 +010065 _PyManagedBufferObject *mbuf;
66
67 mbuf = (_PyManagedBufferObject *)
68 PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type);
69 if (mbuf == NULL)
70 return NULL;
71 mbuf->flags = 0;
72 mbuf->exports = 0;
73 mbuf->master.obj = NULL;
74 _PyObject_GC_TRACK(mbuf);
75
76 return mbuf;
77}
78
79static PyObject *
80_PyManagedBuffer_FromObject(PyObject *base)
81{
82 _PyManagedBufferObject *mbuf;
83
84 mbuf = mbuf_alloc();
85 if (mbuf == NULL)
86 return NULL;
87
88 if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) {
Stefan Krah1649c1b2012-03-05 17:45:17 +010089 mbuf->master.obj = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +010090 Py_DECREF(mbuf);
91 return NULL;
92 }
93
Stefan Krah9a2d99e2012-02-25 12:24:21 +010094 return (PyObject *)mbuf;
Antoine Pitrouc3b39242009-01-03 16:59:18 +000095}
96
97static void
Stefan Krah9a2d99e2012-02-25 12:24:21 +010098mbuf_release(_PyManagedBufferObject *self)
Antoine Pitrouc3b39242009-01-03 16:59:18 +000099{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100100 if (self->flags&_Py_MANAGED_BUFFER_RELEASED)
101 return;
102
103 /* NOTE: at this point self->exports can still be > 0 if this function
104 is called from mbuf_clear() to break up a reference cycle. */
105 self->flags |= _Py_MANAGED_BUFFER_RELEASED;
106
107 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
108 _PyObject_GC_UNTRACK(self);
109 PyBuffer_Release(&self->master);
110}
111
112static void
113mbuf_dealloc(_PyManagedBufferObject *self)
114{
115 assert(self->exports == 0);
116 mbuf_release(self);
117 if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT)
118 PyMem_Free(self->master.format);
119 PyObject_GC_Del(self);
Antoine Pitroubc420402008-12-07 20:14:49 +0000120}
121
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000122static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100123mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000124{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100125 Py_VISIT(self->master.obj);
126 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000127}
128
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100129static int
130mbuf_clear(_PyManagedBufferObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000131{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100132 assert(self->exports >= 0);
133 mbuf_release(self);
134 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000135}
136
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100137PyTypeObject _PyManagedBuffer_Type = {
138 PyVarObject_HEAD_INIT(&PyType_Type, 0)
139 "managedbuffer",
140 sizeof(_PyManagedBufferObject),
141 0,
142 (destructor)mbuf_dealloc, /* tp_dealloc */
143 0, /* tp_print */
144 0, /* tp_getattr */
145 0, /* tp_setattr */
146 0, /* tp_reserved */
147 0, /* tp_repr */
148 0, /* tp_as_number */
149 0, /* tp_as_sequence */
150 0, /* tp_as_mapping */
151 0, /* tp_hash */
152 0, /* tp_call */
153 0, /* tp_str */
154 PyObject_GenericGetAttr, /* tp_getattro */
155 0, /* tp_setattro */
156 0, /* tp_as_buffer */
157 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
158 0, /* tp_doc */
159 (traverseproc)mbuf_traverse, /* tp_traverse */
160 (inquiry)mbuf_clear /* tp_clear */
161};
162
163
164/****************************************************************************/
165/* MemoryView Object */
166/****************************************************************************/
167
168/* In the process of breaking reference cycles mbuf_release() can be
169 called before memory_release(). */
170#define BASE_INACCESSIBLE(mv) \
171 (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \
172 ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED)
173
174#define CHECK_RELEASED(mv) \
175 if (BASE_INACCESSIBLE(mv)) { \
176 PyErr_SetString(PyExc_ValueError, \
177 "operation forbidden on released memoryview object"); \
178 return NULL; \
179 }
180
181#define CHECK_RELEASED_INT(mv) \
182 if (BASE_INACCESSIBLE(mv)) { \
183 PyErr_SetString(PyExc_ValueError, \
184 "operation forbidden on released memoryview object"); \
185 return -1; \
186 }
187
188#define CHECK_LIST_OR_TUPLE(v) \
189 if (!PyList_Check(v) && !PyTuple_Check(v)) { \
190 PyErr_SetString(PyExc_TypeError, \
191 #v " must be a list or a tuple"); \
192 return NULL; \
193 }
194
195#define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view)
196
197/* Check for the presence of suboffsets in the first dimension. */
198#define HAVE_PTR(suboffsets) (suboffsets && suboffsets[0] >= 0)
199/* Adjust ptr if suboffsets are present. */
200#define ADJUST_PTR(ptr, suboffsets) \
201 (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr)
202
203/* Memoryview buffer properties */
204#define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
205#define MV_F_CONTIGUOUS(flags) \
206 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
207#define MV_ANY_CONTIGUOUS(flags) \
208 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
209
210/* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */
211#define MV_CONTIGUOUS_NDIM1(view) \
212 ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize)
213
214/* getbuffer() requests */
215#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
216#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
217#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
218#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
219#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
220#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
221#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
222#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
223
224
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000225PyDoc_STRVAR(memory_doc,
226"memoryview(object)\n\
227\n\
228Create a new memoryview object which references the given object.");
229
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100230
231/**************************************************************************/
232/* Copy memoryview buffers */
233/**************************************************************************/
234
235/* The functions in this section take a source and a destination buffer
236 with the same logical structure: format, itemsize, ndim and shape
237 are identical, with ndim > 0.
238
239 NOTE: All buffers are assumed to have PyBUF_FULL information, which
240 is the case for memoryviews! */
241
242
243/* Assumptions: ndim >= 1. The macro tests for a corner case that should
244 perhaps be explicitly forbidden in the PEP. */
245#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
246 (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
247
248Py_LOCAL_INLINE(int)
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000249last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100250{
251 assert(dest->ndim > 0 && src->ndim > 0);
252 return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) &&
253 !HAVE_SUBOFFSETS_IN_LAST_DIM(src) &&
254 dest->strides[dest->ndim-1] == dest->itemsize &&
255 src->strides[src->ndim-1] == src->itemsize);
256}
257
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000258/* This is not a general function for determining format equivalence.
259 It is used in copy_single() and copy_buffer() to weed out non-matching
260 formats. Skipping the '@' character is specifically used in slice
261 assignments, where the lvalue is already known to have a single character
262 format. This is a performance hack that could be rewritten (if properly
263 benchmarked). */
264Py_LOCAL_INLINE(int)
265equiv_format(const Py_buffer *dest, const Py_buffer *src)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100266{
267 const char *dfmt, *sfmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100268
269 assert(dest->format && src->format);
270 dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format;
271 sfmt = src->format[0] == '@' ? src->format+1 : src->format;
272
273 if (strcmp(dfmt, sfmt) != 0 ||
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000274 dest->itemsize != src->itemsize) {
275 return 0;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100276 }
277
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000278 return 1;
279}
280
281/* Two shapes are equivalent if they are either equal or identical up
282 to a zero element at the same position. For example, in NumPy arrays
283 the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */
284Py_LOCAL_INLINE(int)
285equiv_shape(const Py_buffer *dest, const Py_buffer *src)
286{
287 int i;
288
289 if (dest->ndim != src->ndim)
290 return 0;
291
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100292 for (i = 0; i < dest->ndim; i++) {
293 if (dest->shape[i] != src->shape[i])
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000294 return 0;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100295 if (dest->shape[i] == 0)
296 break;
297 }
298
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000299 return 1;
300}
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100301
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000302/* Check that the logical structure of the destination and source buffers
303 is identical. */
304static int
305equiv_structure(const Py_buffer *dest, const Py_buffer *src)
306{
307 if (!equiv_format(dest, src) ||
308 !equiv_shape(dest, src)) {
309 PyErr_SetString(PyExc_ValueError,
Stefan Krah674a42b2013-02-19 13:44:49 +0100310 "memoryview assignment: lvalue and rvalue have different "
311 "structures");
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000312 return 0;
313 }
314
315 return 1;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100316}
317
318/* Base case for recursive multi-dimensional copying. Contiguous arrays are
319 copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
320 sizeof(mem) == shape[0] * itemsize. */
321static void
322copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
323 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
324 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
325 char *mem)
326{
327 if (mem == NULL) { /* contiguous */
328 Py_ssize_t size = shape[0] * itemsize;
329 if (dptr + size < sptr || sptr + size < dptr)
330 memcpy(dptr, sptr, size); /* no overlapping */
331 else
332 memmove(dptr, sptr, size);
333 }
334 else {
335 char *p;
336 Py_ssize_t i;
337 for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
338 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
339 memcpy(p, xsptr, itemsize);
340 }
341 for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
342 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
343 memcpy(xdptr, p, itemsize);
344 }
345 }
346
347}
348
349/* Recursively copy a source buffer to a destination buffer. The two buffers
350 have the same ndim, shape and itemsize. */
351static void
352copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
353 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
354 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
355 char *mem)
356{
357 Py_ssize_t i;
358
359 assert(ndim >= 1);
360
361 if (ndim == 1) {
362 copy_base(shape, itemsize,
363 dptr, dstrides, dsuboffsets,
364 sptr, sstrides, ssuboffsets,
365 mem);
366 return;
367 }
368
369 for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
370 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
371 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
372
373 copy_rec(shape+1, ndim-1, itemsize,
374 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
375 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
376 mem);
377 }
378}
379
380/* Faster copying of one-dimensional arrays. */
381static int
382copy_single(Py_buffer *dest, Py_buffer *src)
383{
384 char *mem = NULL;
385
386 assert(dest->ndim == 1);
387
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000388 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100389 return -1;
390
391 if (!last_dim_is_contiguous(dest, src)) {
392 mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
393 if (mem == NULL) {
394 PyErr_NoMemory();
395 return -1;
396 }
397 }
398
399 copy_base(dest->shape, dest->itemsize,
400 dest->buf, dest->strides, dest->suboffsets,
401 src->buf, src->strides, src->suboffsets,
402 mem);
403
404 if (mem)
405 PyMem_Free(mem);
406
407 return 0;
408}
409
410/* Recursively copy src to dest. Both buffers must have the same basic
411 structure. Copying is atomic, the function never fails with a partial
412 copy. */
413static int
414copy_buffer(Py_buffer *dest, Py_buffer *src)
415{
416 char *mem = NULL;
417
418 assert(dest->ndim > 0);
419
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000420 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100421 return -1;
422
423 if (!last_dim_is_contiguous(dest, src)) {
424 mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
425 if (mem == NULL) {
426 PyErr_NoMemory();
427 return -1;
428 }
429 }
430
431 copy_rec(dest->shape, dest->ndim, dest->itemsize,
432 dest->buf, dest->strides, dest->suboffsets,
433 src->buf, src->strides, src->suboffsets,
434 mem);
435
436 if (mem)
437 PyMem_Free(mem);
438
439 return 0;
440}
441
442/* Initialize strides for a C-contiguous array. */
443Py_LOCAL_INLINE(void)
444init_strides_from_shape(Py_buffer *view)
445{
446 Py_ssize_t i;
447
448 assert(view->ndim > 0);
449
450 view->strides[view->ndim-1] = view->itemsize;
451 for (i = view->ndim-2; i >= 0; i--)
452 view->strides[i] = view->strides[i+1] * view->shape[i+1];
453}
454
455/* Initialize strides for a Fortran-contiguous array. */
456Py_LOCAL_INLINE(void)
457init_fortran_strides_from_shape(Py_buffer *view)
458{
459 Py_ssize_t i;
460
461 assert(view->ndim > 0);
462
463 view->strides[0] = view->itemsize;
464 for (i = 1; i < view->ndim; i++)
465 view->strides[i] = view->strides[i-1] * view->shape[i-1];
466}
467
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200468/* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran)
469 or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100470 len(mem) == src->len. */
471static int
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200472buffer_to_contiguous(char *mem, Py_buffer *src, char order)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100473{
474 Py_buffer dest;
475 Py_ssize_t *strides;
476 int ret;
477
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200478 assert(src->ndim >= 1);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100479 assert(src->shape != NULL);
480 assert(src->strides != NULL);
481
482 strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
483 if (strides == NULL) {
484 PyErr_NoMemory();
485 return -1;
486 }
487
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200488 /* initialize dest */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100489 dest = *src;
490 dest.buf = mem;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200491 /* shape is constant and shared: the logical representation of the
492 array is unaltered. */
493
494 /* The physical representation determined by strides (and possibly
495 suboffsets) may change. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100496 dest.strides = strides;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200497 if (order == 'C' || order == 'A') {
498 init_strides_from_shape(&dest);
499 }
500 else {
501 init_fortran_strides_from_shape(&dest);
502 }
503
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100504 dest.suboffsets = NULL;
505
506 ret = copy_buffer(&dest, src);
507
508 PyMem_Free(strides);
509 return ret;
510}
511
512
513/****************************************************************************/
514/* Constructors */
515/****************************************************************************/
516
517/* Initialize values that are shared with the managed buffer. */
518Py_LOCAL_INLINE(void)
519init_shared_values(Py_buffer *dest, const Py_buffer *src)
520{
521 dest->obj = src->obj;
522 dest->buf = src->buf;
523 dest->len = src->len;
524 dest->itemsize = src->itemsize;
525 dest->readonly = src->readonly;
526 dest->format = src->format ? src->format : "B";
527 dest->internal = src->internal;
528}
529
530/* Copy shape and strides. Reconstruct missing values. */
531static void
532init_shape_strides(Py_buffer *dest, const Py_buffer *src)
533{
534 Py_ssize_t i;
535
536 if (src->ndim == 0) {
537 dest->shape = NULL;
538 dest->strides = NULL;
539 return;
540 }
541 if (src->ndim == 1) {
542 dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
543 dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
544 return;
545 }
546
547 for (i = 0; i < src->ndim; i++)
548 dest->shape[i] = src->shape[i];
549 if (src->strides) {
550 for (i = 0; i < src->ndim; i++)
551 dest->strides[i] = src->strides[i];
552 }
553 else {
554 init_strides_from_shape(dest);
555 }
556}
557
558Py_LOCAL_INLINE(void)
559init_suboffsets(Py_buffer *dest, const Py_buffer *src)
560{
561 Py_ssize_t i;
562
563 if (src->suboffsets == NULL) {
564 dest->suboffsets = NULL;
565 return;
566 }
567 for (i = 0; i < src->ndim; i++)
568 dest->suboffsets[i] = src->suboffsets[i];
569}
570
571/* len = product(shape) * itemsize */
572Py_LOCAL_INLINE(void)
573init_len(Py_buffer *view)
574{
575 Py_ssize_t i, len;
576
577 len = 1;
578 for (i = 0; i < view->ndim; i++)
579 len *= view->shape[i];
580 len *= view->itemsize;
581
582 view->len = len;
583}
584
585/* Initialize memoryview buffer properties. */
586static void
587init_flags(PyMemoryViewObject *mv)
588{
589 const Py_buffer *view = &mv->view;
590 int flags = 0;
591
592 switch (view->ndim) {
593 case 0:
594 flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
595 _Py_MEMORYVIEW_FORTRAN);
596 break;
597 case 1:
598 if (MV_CONTIGUOUS_NDIM1(view))
599 flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
600 break;
601 default:
602 if (PyBuffer_IsContiguous(view, 'C'))
603 flags |= _Py_MEMORYVIEW_C;
604 if (PyBuffer_IsContiguous(view, 'F'))
605 flags |= _Py_MEMORYVIEW_FORTRAN;
606 break;
607 }
608
609 if (view->suboffsets) {
610 flags |= _Py_MEMORYVIEW_PIL;
611 flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
612 }
613
614 mv->flags = flags;
615}
616
617/* Allocate a new memoryview and perform basic initialization. New memoryviews
618 are exclusively created through the mbuf_add functions. */
619Py_LOCAL_INLINE(PyMemoryViewObject *)
620memory_alloc(int ndim)
621{
622 PyMemoryViewObject *mv;
623
624 mv = (PyMemoryViewObject *)
625 PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
626 if (mv == NULL)
627 return NULL;
628
629 mv->mbuf = NULL;
630 mv->hash = -1;
631 mv->flags = 0;
632 mv->exports = 0;
633 mv->view.ndim = ndim;
634 mv->view.shape = mv->ob_array;
635 mv->view.strides = mv->ob_array + ndim;
636 mv->view.suboffsets = mv->ob_array + 2 * ndim;
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +0100637 mv->weakreflist = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100638
639 _PyObject_GC_TRACK(mv);
640 return mv;
641}
642
643/*
644 Return a new memoryview that is registered with mbuf. If src is NULL,
645 use mbuf->master as the underlying buffer. Otherwise, use src.
646
647 The new memoryview has full buffer information: shape and strides
648 are always present, suboffsets as needed. Arrays are copied to
649 the memoryview's ob_array field.
650 */
651static PyObject *
652mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
653{
654 PyMemoryViewObject *mv;
655 Py_buffer *dest;
656
657 if (src == NULL)
658 src = &mbuf->master;
659
660 if (src->ndim > PyBUF_MAX_NDIM) {
661 PyErr_SetString(PyExc_ValueError,
662 "memoryview: number of dimensions must not exceed "
663 STRINGIZE(PyBUF_MAX_NDIM));
664 return NULL;
665 }
666
667 mv = memory_alloc(src->ndim);
668 if (mv == NULL)
669 return NULL;
670
671 dest = &mv->view;
672 init_shared_values(dest, src);
673 init_shape_strides(dest, src);
674 init_suboffsets(dest, src);
675 init_flags(mv);
676
677 mv->mbuf = mbuf;
678 Py_INCREF(mbuf);
679 mbuf->exports++;
680
681 return (PyObject *)mv;
682}
683
684/* Register an incomplete view: shape, strides, suboffsets and flags still
685 need to be initialized. Use 'ndim' instead of src->ndim to determine the
686 size of the memoryview's ob_array.
687
688 Assumption: ndim <= PyBUF_MAX_NDIM. */
689static PyObject *
690mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
691 int ndim)
692{
693 PyMemoryViewObject *mv;
694 Py_buffer *dest;
695
696 if (src == NULL)
697 src = &mbuf->master;
698
699 assert(ndim <= PyBUF_MAX_NDIM);
700
701 mv = memory_alloc(ndim);
702 if (mv == NULL)
703 return NULL;
704
705 dest = &mv->view;
706 init_shared_values(dest, src);
707
708 mv->mbuf = mbuf;
709 Py_INCREF(mbuf);
710 mbuf->exports++;
711
712 return (PyObject *)mv;
713}
714
715/* Expose a raw memory area as a view of contiguous bytes. flags can be
716 PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
717 The memoryview has complete buffer information. */
718PyObject *
719PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
720{
721 _PyManagedBufferObject *mbuf;
722 PyObject *mv;
723 int readonly;
724
725 assert(mem != NULL);
726 assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
727
728 mbuf = mbuf_alloc();
729 if (mbuf == NULL)
730 return NULL;
731
732 readonly = (flags == PyBUF_WRITE) ? 0 : 1;
733 (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
734 PyBUF_FULL_RO);
735
736 mv = mbuf_add_view(mbuf, NULL);
737 Py_DECREF(mbuf);
738
739 return mv;
740}
741
742/* Create a memoryview from a given Py_buffer. For simple byte views,
743 PyMemoryView_FromMemory() should be used instead.
744 This function is the only entry point that can create a master buffer
745 without full information. Because of this fact init_shape_strides()
746 must be able to reconstruct missing values. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000747PyObject *
Antoine Pitrouee58fa42008-08-19 18:22:14 +0000748PyMemoryView_FromBuffer(Py_buffer *info)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000749{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100750 _PyManagedBufferObject *mbuf;
751 PyObject *mv;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000752
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000753 if (info->buf == NULL) {
754 PyErr_SetString(PyExc_ValueError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100755 "PyMemoryView_FromBuffer(): info->buf must not be NULL");
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000756 return NULL;
757 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100758
759 mbuf = mbuf_alloc();
760 if (mbuf == NULL)
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000761 return NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100762
763 /* info->obj is either NULL or a borrowed reference. This reference
764 should not be decremented in PyBuffer_Release(). */
765 mbuf->master = *info;
766 mbuf->master.obj = NULL;
767
768 mv = mbuf_add_view(mbuf, NULL);
769 Py_DECREF(mbuf);
770
771 return mv;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000772}
773
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100774/* Create a memoryview from an object that implements the buffer protocol.
775 If the object is a memoryview, the new memoryview must be registered
776 with the same managed buffer. Otherwise, a new managed buffer is created. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000777PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100778PyMemoryView_FromObject(PyObject *v)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000779{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100780 _PyManagedBufferObject *mbuf;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000781
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100782 if (PyMemoryView_Check(v)) {
783 PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
784 CHECK_RELEASED(mv);
785 return mbuf_add_view(mv->mbuf, &mv->view);
786 }
787 else if (PyObject_CheckBuffer(v)) {
788 PyObject *ret;
789 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
790 if (mbuf == NULL)
791 return NULL;
792 ret = mbuf_add_view(mbuf, NULL);
793 Py_DECREF(mbuf);
794 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000795 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000796
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100797 PyErr_Format(PyExc_TypeError,
798 "memoryview: %.200s object does not have the buffer interface",
799 Py_TYPE(v)->tp_name);
800 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000801}
802
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100803/* Copy the format string from a base object that might vanish. */
804static int
805mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
806{
807 if (fmt != NULL) {
808 char *cp = PyMem_Malloc(strlen(fmt)+1);
809 if (cp == NULL) {
810 PyErr_NoMemory();
811 return -1;
812 }
813 mbuf->master.format = strcpy(cp, fmt);
814 mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
815 }
816
817 return 0;
818}
819
820/*
821 Return a memoryview that is based on a contiguous copy of src.
822 Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
823
824 Ownership rules:
825 1) As usual, the returned memoryview has a private copy
826 of src->shape, src->strides and src->suboffsets.
827 2) src->format is copied to the master buffer and released
828 in mbuf_dealloc(). The releasebufferproc of the bytes
829 object is NULL, so it does not matter that mbuf_release()
830 passes the altered format pointer to PyBuffer_Release().
831*/
832static PyObject *
833memory_from_contiguous_copy(Py_buffer *src, char order)
834{
835 _PyManagedBufferObject *mbuf;
836 PyMemoryViewObject *mv;
837 PyObject *bytes;
838 Py_buffer *dest;
839 int i;
840
841 assert(src->ndim > 0);
842 assert(src->shape != NULL);
843
844 bytes = PyBytes_FromStringAndSize(NULL, src->len);
845 if (bytes == NULL)
846 return NULL;
847
848 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
849 Py_DECREF(bytes);
850 if (mbuf == NULL)
851 return NULL;
852
853 if (mbuf_copy_format(mbuf, src->format) < 0) {
854 Py_DECREF(mbuf);
855 return NULL;
856 }
857
858 mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
859 Py_DECREF(mbuf);
860 if (mv == NULL)
861 return NULL;
862
863 dest = &mv->view;
864
865 /* shared values are initialized correctly except for itemsize */
866 dest->itemsize = src->itemsize;
867
868 /* shape and strides */
869 for (i = 0; i < src->ndim; i++) {
870 dest->shape[i] = src->shape[i];
871 }
872 if (order == 'C' || order == 'A') {
873 init_strides_from_shape(dest);
874 }
875 else {
876 init_fortran_strides_from_shape(dest);
877 }
878 /* suboffsets */
879 dest->suboffsets = NULL;
880
881 /* flags */
882 init_flags(mv);
883
884 if (copy_buffer(dest, src) < 0) {
885 Py_DECREF(mv);
886 return NULL;
887 }
888
889 return (PyObject *)mv;
890}
891
892/*
893 Return a new memoryview object based on a contiguous exporter with
894 buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
895 The logical structure of the input and output buffers is the same
896 (i.e. tolist(input) == tolist(output)), but the physical layout in
897 memory can be explicitly chosen.
898
899 As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
900 otherwise it may be writable or read-only.
901
902 If the exporter is already contiguous with the desired target order,
903 the memoryview will be directly based on the exporter.
904
905 Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
906 based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
907 'F'ortran order otherwise.
908*/
909PyObject *
910PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
911{
912 PyMemoryViewObject *mv;
913 PyObject *ret;
914 Py_buffer *view;
915
916 assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
917 assert(order == 'C' || order == 'F' || order == 'A');
918
919 mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
920 if (mv == NULL)
921 return NULL;
922
923 view = &mv->view;
924 if (buffertype == PyBUF_WRITE && view->readonly) {
925 PyErr_SetString(PyExc_BufferError,
926 "underlying buffer is not writable");
927 Py_DECREF(mv);
928 return NULL;
929 }
930
931 if (PyBuffer_IsContiguous(view, order))
932 return (PyObject *)mv;
933
934 if (buffertype == PyBUF_WRITE) {
935 PyErr_SetString(PyExc_BufferError,
936 "writable contiguous buffer requested "
937 "for a non-contiguous object.");
938 Py_DECREF(mv);
939 return NULL;
940 }
941
942 ret = memory_from_contiguous_copy(view, order);
943 Py_DECREF(mv);
944 return ret;
945}
946
947
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000948static PyObject *
949memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
950{
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000951 PyObject *obj;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100952 static char *kwlist[] = {"object", NULL};
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000953
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000954 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
955 &obj)) {
956 return NULL;
957 }
Christian Heimes7b6fc8e2007-11-08 02:28:11 +0000958
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000959 return PyMemoryView_FromObject(obj);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000960}
961
962
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100963/****************************************************************************/
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200964/* Previously in abstract.c */
965/****************************************************************************/
966
967typedef struct {
968 Py_buffer view;
969 Py_ssize_t array[1];
970} Py_buffer_full;
971
972int
973PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
974{
975 Py_buffer_full *fb = NULL;
976 int ret;
977
978 assert(order == 'C' || order == 'F' || order == 'A');
979
980 if (len != src->len) {
981 PyErr_SetString(PyExc_ValueError,
982 "PyBuffer_ToContiguous: len != view->len");
983 return -1;
984 }
985
986 if (PyBuffer_IsContiguous(src, order)) {
987 memcpy((char *)buf, src->buf, len);
988 return 0;
989 }
990
991 /* buffer_to_contiguous() assumes PyBUF_FULL */
992 fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array));
993 if (fb == NULL) {
994 PyErr_NoMemory();
995 return -1;
996 }
997 fb->view.ndim = src->ndim;
998 fb->view.shape = fb->array;
999 fb->view.strides = fb->array + src->ndim;
1000 fb->view.suboffsets = fb->array + 2 * src->ndim;
1001
1002 init_shared_values(&fb->view, src);
1003 init_shape_strides(&fb->view, src);
1004 init_suboffsets(&fb->view, src);
1005
1006 src = &fb->view;
1007
1008 ret = buffer_to_contiguous(buf, src, order);
1009 PyMem_Free(fb);
1010 return ret;
1011}
1012
1013
1014/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001015/* Release/GC management */
1016/****************************************************************************/
1017
1018/* Inform the managed buffer that this particular memoryview will not access
1019 the underlying buffer again. If no other memoryviews are registered with
1020 the managed buffer, the underlying buffer is released instantly and
1021 marked as inaccessible for both the memoryview and the managed buffer.
1022
1023 This function fails if the memoryview itself has exported buffers. */
1024static int
1025_memory_release(PyMemoryViewObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001026{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001027 if (self->flags & _Py_MEMORYVIEW_RELEASED)
1028 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001029
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001030 if (self->exports == 0) {
1031 self->flags |= _Py_MEMORYVIEW_RELEASED;
1032 assert(self->mbuf->exports > 0);
1033 if (--self->mbuf->exports == 0)
1034 mbuf_release(self->mbuf);
1035 return 0;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001036 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001037 if (self->exports > 0) {
1038 PyErr_Format(PyExc_BufferError,
1039 "memoryview has %zd exported buffer%s", self->exports,
1040 self->exports==1 ? "" : "s");
1041 return -1;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001042 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001043
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001044 Py_FatalError("_memory_release(): negative export count");
1045 return -1;
1046}
1047
1048static PyObject *
Stefan Krahe4c07992012-07-28 14:10:02 +02001049memory_release(PyMemoryViewObject *self, PyObject *noargs)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001050{
1051 if (_memory_release(self) < 0)
1052 return NULL;
1053 Py_RETURN_NONE;
1054}
1055
1056static void
1057memory_dealloc(PyMemoryViewObject *self)
1058{
1059 assert(self->exports == 0);
1060 _PyObject_GC_UNTRACK(self);
1061 (void)_memory_release(self);
1062 Py_CLEAR(self->mbuf);
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01001063 if (self->weakreflist != NULL)
1064 PyObject_ClearWeakRefs((PyObject *) self);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001065 PyObject_GC_Del(self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001066}
1067
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001068static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001069memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001070{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001071 Py_VISIT(self->mbuf);
1072 return 0;
1073}
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001074
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001075static int
1076memory_clear(PyMemoryViewObject *self)
1077{
1078 (void)_memory_release(self);
1079 Py_CLEAR(self->mbuf);
1080 return 0;
1081}
1082
1083static PyObject *
1084memory_enter(PyObject *self, PyObject *args)
1085{
1086 CHECK_RELEASED(self);
1087 Py_INCREF(self);
1088 return self;
1089}
1090
1091static PyObject *
1092memory_exit(PyObject *self, PyObject *args)
1093{
Stefan Krahe4c07992012-07-28 14:10:02 +02001094 return memory_release((PyMemoryViewObject *)self, NULL);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001095}
1096
1097
1098/****************************************************************************/
1099/* Casting format and shape */
1100/****************************************************************************/
1101
1102#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
1103
1104Py_LOCAL_INLINE(Py_ssize_t)
1105get_native_fmtchar(char *result, const char *fmt)
1106{
1107 Py_ssize_t size = -1;
1108
1109 if (fmt[0] == '@') fmt++;
1110
1111 switch (fmt[0]) {
1112 case 'c': case 'b': case 'B': size = sizeof(char); break;
1113 case 'h': case 'H': size = sizeof(short); break;
1114 case 'i': case 'I': size = sizeof(int); break;
1115 case 'l': case 'L': size = sizeof(long); break;
1116 #ifdef HAVE_LONG_LONG
1117 case 'q': case 'Q': size = sizeof(PY_LONG_LONG); break;
1118 #endif
1119 case 'n': case 'N': size = sizeof(Py_ssize_t); break;
1120 case 'f': size = sizeof(float); break;
1121 case 'd': size = sizeof(double); break;
1122 #ifdef HAVE_C99_BOOL
1123 case '?': size = sizeof(_Bool); break;
1124 #else
1125 case '?': size = sizeof(char); break;
1126 #endif
1127 case 'P': size = sizeof(void *); break;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001128 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001129
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001130 if (size > 0 && fmt[1] == '\0') {
1131 *result = fmt[0];
1132 return size;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001133 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001134
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001135 return -1;
1136}
1137
1138/* Cast a memoryview's data type to 'format'. The input array must be
1139 C-contiguous. At least one of input-format, output-format must have
1140 byte size. The output array is 1-D, with the same byte length as the
1141 input array. Thus, view->len must be a multiple of the new itemsize. */
1142static int
1143cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1144{
1145 Py_buffer *view = &mv->view;
1146 PyObject *asciifmt;
1147 char srcchar, destchar;
1148 Py_ssize_t itemsize;
1149 int ret = -1;
1150
1151 assert(view->ndim >= 1);
1152 assert(Py_SIZE(mv) == 3*view->ndim);
1153 assert(view->shape == mv->ob_array);
1154 assert(view->strides == mv->ob_array + view->ndim);
1155 assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1156
1157 if (get_native_fmtchar(&srcchar, view->format) < 0) {
1158 PyErr_SetString(PyExc_ValueError,
1159 "memoryview: source format must be a native single character "
1160 "format prefixed with an optional '@'");
1161 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001162 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001163
1164 asciifmt = PyUnicode_AsASCIIString(format);
1165 if (asciifmt == NULL)
1166 return ret;
1167
1168 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1169 if (itemsize < 0) {
1170 PyErr_SetString(PyExc_ValueError,
1171 "memoryview: destination format must be a native single "
1172 "character format prefixed with an optional '@'");
1173 goto out;
1174 }
1175
1176 if (!IS_BYTE_FORMAT(srcchar) && !IS_BYTE_FORMAT(destchar)) {
1177 PyErr_SetString(PyExc_TypeError,
1178 "memoryview: cannot cast between two non-byte formats");
1179 goto out;
1180 }
1181 if (view->len % itemsize) {
1182 PyErr_SetString(PyExc_TypeError,
1183 "memoryview: length is not a multiple of itemsize");
1184 goto out;
1185 }
1186
1187 strncpy(mv->format, PyBytes_AS_STRING(asciifmt),
1188 _Py_MEMORYVIEW_MAX_FORMAT);
1189 mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0';
1190 view->format = mv->format;
1191 view->itemsize = itemsize;
1192
1193 view->ndim = 1;
1194 view->shape[0] = view->len / view->itemsize;
1195 view->strides[0] = view->itemsize;
1196 view->suboffsets = NULL;
1197
1198 init_flags(mv);
1199
1200 ret = 0;
1201
1202out:
1203 Py_DECREF(asciifmt);
1204 return ret;
1205}
1206
1207/* The memoryview must have space for 3*len(seq) elements. */
1208static Py_ssize_t
1209copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1210 Py_ssize_t itemsize)
1211{
1212 Py_ssize_t x, i;
1213 Py_ssize_t len = itemsize;
1214
1215 for (i = 0; i < ndim; i++) {
1216 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1217 if (!PyLong_Check(tmp)) {
1218 PyErr_SetString(PyExc_TypeError,
1219 "memoryview.cast(): elements of shape must be integers");
1220 return -1;
1221 }
1222 x = PyLong_AsSsize_t(tmp);
1223 if (x == -1 && PyErr_Occurred()) {
1224 return -1;
1225 }
1226 if (x <= 0) {
1227 /* In general elements of shape may be 0, but not for casting. */
1228 PyErr_Format(PyExc_ValueError,
1229 "memoryview.cast(): elements of shape must be integers > 0");
1230 return -1;
1231 }
1232 if (x > PY_SSIZE_T_MAX / len) {
1233 PyErr_Format(PyExc_ValueError,
1234 "memoryview.cast(): product(shape) > SSIZE_MAX");
1235 return -1;
1236 }
1237 len *= x;
1238 shape[i] = x;
1239 }
1240
1241 return len;
1242}
1243
1244/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1245 If the result array does not have exactly the same byte length as the
1246 input array, raise ValueError. */
1247static int
1248cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1249{
1250 Py_buffer *view = &mv->view;
1251 Py_ssize_t len;
1252
1253 assert(view->ndim == 1); /* ndim from cast_to_1D() */
1254 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1255 assert(view->shape == mv->ob_array);
1256 assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1257 assert(view->suboffsets == NULL);
1258
1259 view->ndim = ndim;
1260 if (view->ndim == 0) {
1261 view->shape = NULL;
1262 view->strides = NULL;
1263 len = view->itemsize;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001264 }
1265 else {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001266 len = copy_shape(view->shape, shape, ndim, view->itemsize);
1267 if (len < 0)
1268 return -1;
1269 init_strides_from_shape(view);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001270 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001271
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001272 if (view->len != len) {
1273 PyErr_SetString(PyExc_TypeError,
1274 "memoryview: product(shape) * itemsize != buffer size");
1275 return -1;
1276 }
1277
1278 init_flags(mv);
1279
1280 return 0;
1281}
1282
1283static int
1284zero_in_shape(PyMemoryViewObject *mv)
1285{
1286 Py_buffer *view = &mv->view;
1287 Py_ssize_t i;
1288
1289 for (i = 0; i < view->ndim; i++)
1290 if (view->shape[i] == 0)
1291 return 1;
1292
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001293 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001294}
1295
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001296/*
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001297 Cast a copy of 'self' to a different view. The input view must
1298 be C-contiguous. The function always casts the input view to a
1299 1-D output according to 'format'. At least one of input-format,
1300 output-format must have byte size.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001301
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001302 If 'shape' is given, the 1-D view from the previous step will
1303 be cast to a C-contiguous view with new shape and strides.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001304
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001305 All casts must result in views that will have the exact byte
1306 size of the original input. Otherwise, an error is raised.
1307*/
1308static PyObject *
1309memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001310{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001311 static char *kwlist[] = {"format", "shape", NULL};
1312 PyMemoryViewObject *mv = NULL;
1313 PyObject *shape = NULL;
1314 PyObject *format;
1315 Py_ssize_t ndim = 1;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001316
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001317 CHECK_RELEASED(self);
1318
1319 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
1320 &format, &shape)) {
1321 return NULL;
1322 }
1323 if (!PyUnicode_Check(format)) {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001324 PyErr_SetString(PyExc_TypeError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001325 "memoryview: format argument must be a string");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001326 return NULL;
1327 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001328 if (!MV_C_CONTIGUOUS(self->flags)) {
1329 PyErr_SetString(PyExc_TypeError,
1330 "memoryview: casts are restricted to C-contiguous views");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001331 return NULL;
1332 }
Antoine Pitrou60b18342013-10-03 19:55:41 +02001333 if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001334 PyErr_SetString(PyExc_TypeError,
1335 "memoryview: cannot cast view with zeros in shape or strides");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001336 return NULL;
1337 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001338 if (shape) {
1339 CHECK_LIST_OR_TUPLE(shape)
1340 ndim = PySequence_Fast_GET_SIZE(shape);
1341 if (ndim > PyBUF_MAX_NDIM) {
1342 PyErr_SetString(PyExc_ValueError,
1343 "memoryview: number of dimensions must not exceed "
1344 STRINGIZE(PyBUF_MAX_NDIM));
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001345 return NULL;
1346 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001347 if (self->view.ndim != 1 && ndim != 1) {
1348 PyErr_SetString(PyExc_TypeError,
1349 "memoryview: cast must be 1D -> ND or ND -> 1D");
1350 return NULL;
1351 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001352 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001353
1354 mv = (PyMemoryViewObject *)
1355 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1356 if (mv == NULL)
1357 return NULL;
1358
1359 if (cast_to_1D(mv, format) < 0)
1360 goto error;
1361 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1362 goto error;
1363
1364 return (PyObject *)mv;
1365
1366error:
1367 Py_DECREF(mv);
1368 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001369}
1370
1371
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001372/**************************************************************************/
1373/* getbuffer */
1374/**************************************************************************/
1375
1376static int
1377memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1378{
1379 Py_buffer *base = &self->view;
1380 int baseflags = self->flags;
1381
1382 CHECK_RELEASED_INT(self);
1383
1384 /* start with complete information */
1385 *view = *base;
1386 view->obj = NULL;
1387
1388 if (REQ_WRITABLE(flags) && base->readonly) {
1389 PyErr_SetString(PyExc_BufferError,
1390 "memoryview: underlying buffer is not writable");
1391 return -1;
1392 }
1393 if (!REQ_FORMAT(flags)) {
1394 /* NULL indicates that the buffer's data type has been cast to 'B'.
1395 view->itemsize is the _previous_ itemsize. If shape is present,
1396 the equality product(shape) * itemsize = len still holds at this
1397 point. The equality calcsize(format) = itemsize does _not_ hold
1398 from here on! */
1399 view->format = NULL;
1400 }
1401
1402 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1403 PyErr_SetString(PyExc_BufferError,
1404 "memoryview: underlying buffer is not C-contiguous");
1405 return -1;
1406 }
1407 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1408 PyErr_SetString(PyExc_BufferError,
1409 "memoryview: underlying buffer is not Fortran contiguous");
1410 return -1;
1411 }
1412 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1413 PyErr_SetString(PyExc_BufferError,
1414 "memoryview: underlying buffer is not contiguous");
1415 return -1;
1416 }
1417 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1418 PyErr_SetString(PyExc_BufferError,
1419 "memoryview: underlying buffer requires suboffsets");
1420 return -1;
1421 }
1422 if (!REQ_STRIDES(flags)) {
1423 if (!MV_C_CONTIGUOUS(baseflags)) {
1424 PyErr_SetString(PyExc_BufferError,
1425 "memoryview: underlying buffer is not C-contiguous");
1426 return -1;
1427 }
1428 view->strides = NULL;
1429 }
1430 if (!REQ_SHAPE(flags)) {
1431 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1432 so base->buf = ndbuf->data. */
1433 if (view->format != NULL) {
1434 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1435 not make sense. */
1436 PyErr_Format(PyExc_BufferError,
Stefan Krah674a42b2013-02-19 13:44:49 +01001437 "memoryview: cannot cast to unsigned bytes if the format flag "
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001438 "is present");
1439 return -1;
1440 }
1441 /* product(shape) * itemsize = len and calcsize(format) = itemsize
1442 do _not_ hold from here on! */
1443 view->ndim = 1;
1444 view->shape = NULL;
1445 }
1446
1447
1448 view->obj = (PyObject *)self;
1449 Py_INCREF(view->obj);
1450 self->exports++;
1451
1452 return 0;
1453}
1454
1455static void
1456memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1457{
1458 self->exports--;
1459 return;
1460 /* PyBuffer_Release() decrements view->obj after this function returns. */
1461}
1462
1463/* Buffer methods */
1464static PyBufferProcs memory_as_buffer = {
1465 (getbufferproc)memory_getbuf, /* bf_getbuffer */
1466 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1467};
1468
1469
1470/****************************************************************************/
1471/* Optimized pack/unpack for all native format specifiers */
1472/****************************************************************************/
1473
1474/*
1475 Fix exceptions:
1476 1) Include format string in the error message.
1477 2) OverflowError -> ValueError.
1478 3) The error message from PyNumber_Index() is not ideal.
1479*/
1480static int
1481type_error_int(const char *fmt)
1482{
1483 PyErr_Format(PyExc_TypeError,
1484 "memoryview: invalid type for format '%s'", fmt);
1485 return -1;
1486}
1487
1488static int
1489value_error_int(const char *fmt)
1490{
1491 PyErr_Format(PyExc_ValueError,
1492 "memoryview: invalid value for format '%s'", fmt);
1493 return -1;
1494}
1495
1496static int
1497fix_error_int(const char *fmt)
1498{
1499 assert(PyErr_Occurred());
1500 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1501 PyErr_Clear();
1502 return type_error_int(fmt);
1503 }
1504 else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1505 PyErr_ExceptionMatches(PyExc_ValueError)) {
1506 PyErr_Clear();
1507 return value_error_int(fmt);
1508 }
1509
1510 return -1;
1511}
1512
1513/* Accept integer objects or objects with an __index__() method. */
1514static long
1515pylong_as_ld(PyObject *item)
1516{
1517 PyObject *tmp;
1518 long ld;
1519
1520 tmp = PyNumber_Index(item);
1521 if (tmp == NULL)
1522 return -1;
1523
1524 ld = PyLong_AsLong(tmp);
1525 Py_DECREF(tmp);
1526 return ld;
1527}
1528
1529static unsigned long
1530pylong_as_lu(PyObject *item)
1531{
1532 PyObject *tmp;
1533 unsigned long lu;
1534
1535 tmp = PyNumber_Index(item);
1536 if (tmp == NULL)
1537 return (unsigned long)-1;
1538
1539 lu = PyLong_AsUnsignedLong(tmp);
1540 Py_DECREF(tmp);
1541 return lu;
1542}
1543
1544#ifdef HAVE_LONG_LONG
1545static PY_LONG_LONG
1546pylong_as_lld(PyObject *item)
1547{
1548 PyObject *tmp;
1549 PY_LONG_LONG lld;
1550
1551 tmp = PyNumber_Index(item);
1552 if (tmp == NULL)
1553 return -1;
1554
1555 lld = PyLong_AsLongLong(tmp);
1556 Py_DECREF(tmp);
1557 return lld;
1558}
1559
1560static unsigned PY_LONG_LONG
1561pylong_as_llu(PyObject *item)
1562{
1563 PyObject *tmp;
1564 unsigned PY_LONG_LONG llu;
1565
1566 tmp = PyNumber_Index(item);
1567 if (tmp == NULL)
1568 return (unsigned PY_LONG_LONG)-1;
1569
1570 llu = PyLong_AsUnsignedLongLong(tmp);
1571 Py_DECREF(tmp);
1572 return llu;
1573}
1574#endif
1575
1576static Py_ssize_t
1577pylong_as_zd(PyObject *item)
1578{
1579 PyObject *tmp;
1580 Py_ssize_t zd;
1581
1582 tmp = PyNumber_Index(item);
1583 if (tmp == NULL)
1584 return -1;
1585
1586 zd = PyLong_AsSsize_t(tmp);
1587 Py_DECREF(tmp);
1588 return zd;
1589}
1590
1591static size_t
1592pylong_as_zu(PyObject *item)
1593{
1594 PyObject *tmp;
1595 size_t zu;
1596
1597 tmp = PyNumber_Index(item);
1598 if (tmp == NULL)
1599 return (size_t)-1;
1600
1601 zu = PyLong_AsSize_t(tmp);
1602 Py_DECREF(tmp);
1603 return zu;
1604}
1605
1606/* Timings with the ndarray from _testbuffer.c indicate that using the
1607 struct module is around 15x slower than the two functions below. */
1608
1609#define UNPACK_SINGLE(dest, ptr, type) \
1610 do { \
1611 type x; \
1612 memcpy((char *)&x, ptr, sizeof x); \
1613 dest = x; \
1614 } while (0)
1615
1616/* Unpack a single item. 'fmt' can be any native format character in struct
1617 module syntax. This function is very sensitive to small changes. With this
1618 layout gcc automatically generates a fast jump table. */
1619Py_LOCAL_INLINE(PyObject *)
1620unpack_single(const char *ptr, const char *fmt)
1621{
1622 unsigned PY_LONG_LONG llu;
1623 unsigned long lu;
1624 size_t zu;
1625 PY_LONG_LONG lld;
1626 long ld;
1627 Py_ssize_t zd;
1628 double d;
1629 unsigned char uc;
1630 void *p;
1631
1632 switch (fmt[0]) {
1633
1634 /* signed integers and fast path for 'B' */
1635 case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
1636 case 'b': ld = *((signed char *)ptr); goto convert_ld;
1637 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1638 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1639 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1640
1641 /* boolean */
1642 #ifdef HAVE_C99_BOOL
1643 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
1644 #else
1645 case '?': UNPACK_SINGLE(ld, ptr, char); goto convert_bool;
1646 #endif
1647
1648 /* unsigned integers */
1649 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1650 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1651 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1652
1653 /* native 64-bit */
1654 #ifdef HAVE_LONG_LONG
1655 case 'q': UNPACK_SINGLE(lld, ptr, PY_LONG_LONG); goto convert_lld;
1656 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned PY_LONG_LONG); goto convert_llu;
1657 #endif
1658
1659 /* ssize_t and size_t */
1660 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1661 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1662
1663 /* floats */
1664 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1665 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1666
1667 /* bytes object */
1668 case 'c': goto convert_bytes;
1669
1670 /* pointer */
1671 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1672
1673 /* default */
1674 default: goto err_format;
1675 }
1676
1677convert_uc:
1678 /* PyLong_FromUnsignedLong() is slower */
1679 return PyLong_FromLong(uc);
1680convert_ld:
1681 return PyLong_FromLong(ld);
1682convert_lu:
1683 return PyLong_FromUnsignedLong(lu);
1684convert_lld:
1685 return PyLong_FromLongLong(lld);
1686convert_llu:
1687 return PyLong_FromUnsignedLongLong(llu);
1688convert_zd:
1689 return PyLong_FromSsize_t(zd);
1690convert_zu:
1691 return PyLong_FromSize_t(zu);
1692convert_double:
1693 return PyFloat_FromDouble(d);
1694convert_bool:
1695 return PyBool_FromLong(ld);
1696convert_bytes:
1697 return PyBytes_FromStringAndSize(ptr, 1);
1698convert_pointer:
1699 return PyLong_FromVoidPtr(p);
1700err_format:
1701 PyErr_Format(PyExc_NotImplementedError,
1702 "memoryview: format %s not supported", fmt);
1703 return NULL;
1704}
1705
1706#define PACK_SINGLE(ptr, src, type) \
1707 do { \
1708 type x; \
1709 x = (type)src; \
1710 memcpy(ptr, (char *)&x, sizeof x); \
1711 } while (0)
1712
1713/* Pack a single item. 'fmt' can be any native format character in
1714 struct module syntax. */
1715static int
1716pack_single(char *ptr, PyObject *item, const char *fmt)
1717{
1718 unsigned PY_LONG_LONG llu;
1719 unsigned long lu;
1720 size_t zu;
1721 PY_LONG_LONG lld;
1722 long ld;
1723 Py_ssize_t zd;
1724 double d;
1725 void *p;
1726
1727 switch (fmt[0]) {
1728 /* signed integers */
1729 case 'b': case 'h': case 'i': case 'l':
1730 ld = pylong_as_ld(item);
1731 if (ld == -1 && PyErr_Occurred())
1732 goto err_occurred;
1733 switch (fmt[0]) {
1734 case 'b':
1735 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1736 *((signed char *)ptr) = (signed char)ld; break;
1737 case 'h':
1738 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1739 PACK_SINGLE(ptr, ld, short); break;
1740 case 'i':
1741 if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1742 PACK_SINGLE(ptr, ld, int); break;
1743 default: /* 'l' */
1744 PACK_SINGLE(ptr, ld, long); break;
1745 }
1746 break;
1747
1748 /* unsigned integers */
1749 case 'B': case 'H': case 'I': case 'L':
1750 lu = pylong_as_lu(item);
1751 if (lu == (unsigned long)-1 && PyErr_Occurred())
1752 goto err_occurred;
1753 switch (fmt[0]) {
1754 case 'B':
1755 if (lu > UCHAR_MAX) goto err_range;
1756 *((unsigned char *)ptr) = (unsigned char)lu; break;
1757 case 'H':
1758 if (lu > USHRT_MAX) goto err_range;
1759 PACK_SINGLE(ptr, lu, unsigned short); break;
1760 case 'I':
1761 if (lu > UINT_MAX) goto err_range;
1762 PACK_SINGLE(ptr, lu, unsigned int); break;
1763 default: /* 'L' */
1764 PACK_SINGLE(ptr, lu, unsigned long); break;
1765 }
1766 break;
1767
1768 /* native 64-bit */
1769 #ifdef HAVE_LONG_LONG
1770 case 'q':
1771 lld = pylong_as_lld(item);
1772 if (lld == -1 && PyErr_Occurred())
1773 goto err_occurred;
1774 PACK_SINGLE(ptr, lld, PY_LONG_LONG);
1775 break;
1776 case 'Q':
1777 llu = pylong_as_llu(item);
1778 if (llu == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
1779 goto err_occurred;
1780 PACK_SINGLE(ptr, llu, unsigned PY_LONG_LONG);
1781 break;
1782 #endif
1783
1784 /* ssize_t and size_t */
1785 case 'n':
1786 zd = pylong_as_zd(item);
1787 if (zd == -1 && PyErr_Occurred())
1788 goto err_occurred;
1789 PACK_SINGLE(ptr, zd, Py_ssize_t);
1790 break;
1791 case 'N':
1792 zu = pylong_as_zu(item);
1793 if (zu == (size_t)-1 && PyErr_Occurred())
1794 goto err_occurred;
1795 PACK_SINGLE(ptr, zu, size_t);
1796 break;
1797
1798 /* floats */
1799 case 'f': case 'd':
1800 d = PyFloat_AsDouble(item);
1801 if (d == -1.0 && PyErr_Occurred())
1802 goto err_occurred;
1803 if (fmt[0] == 'f') {
1804 PACK_SINGLE(ptr, d, float);
1805 }
1806 else {
1807 PACK_SINGLE(ptr, d, double);
1808 }
1809 break;
1810
1811 /* bool */
1812 case '?':
1813 ld = PyObject_IsTrue(item);
1814 if (ld < 0)
1815 return -1; /* preserve original error */
1816 #ifdef HAVE_C99_BOOL
1817 PACK_SINGLE(ptr, ld, _Bool);
1818 #else
1819 PACK_SINGLE(ptr, ld, char);
1820 #endif
1821 break;
1822
1823 /* bytes object */
1824 case 'c':
1825 if (!PyBytes_Check(item))
1826 return type_error_int(fmt);
1827 if (PyBytes_GET_SIZE(item) != 1)
1828 return value_error_int(fmt);
1829 *ptr = PyBytes_AS_STRING(item)[0];
1830 break;
1831
1832 /* pointer */
1833 case 'P':
1834 p = PyLong_AsVoidPtr(item);
1835 if (p == NULL && PyErr_Occurred())
1836 goto err_occurred;
1837 PACK_SINGLE(ptr, p, void *);
1838 break;
1839
1840 /* default */
1841 default: goto err_format;
1842 }
1843
1844 return 0;
1845
1846err_occurred:
1847 return fix_error_int(fmt);
1848err_range:
1849 return value_error_int(fmt);
1850err_format:
1851 PyErr_Format(PyExc_NotImplementedError,
1852 "memoryview: format %s not supported", fmt);
1853 return -1;
1854}
1855
1856
1857/****************************************************************************/
Nick Coghlan06e1ab02012-08-25 17:59:50 +10001858/* unpack using the struct module */
1859/****************************************************************************/
1860
1861/* For reasonable performance it is necessary to cache all objects required
1862 for unpacking. An unpacker can handle the format passed to unpack_from().
1863 Invariant: All pointer fields of the struct should either be NULL or valid
1864 pointers. */
1865struct unpacker {
1866 PyObject *unpack_from; /* Struct.unpack_from(format) */
1867 PyObject *mview; /* cached memoryview */
1868 char *item; /* buffer for mview */
1869 Py_ssize_t itemsize; /* len(item) */
1870};
1871
1872static struct unpacker *
1873unpacker_new(void)
1874{
1875 struct unpacker *x = PyMem_Malloc(sizeof *x);
1876
1877 if (x == NULL) {
1878 PyErr_NoMemory();
1879 return NULL;
1880 }
1881
1882 x->unpack_from = NULL;
1883 x->mview = NULL;
1884 x->item = NULL;
1885 x->itemsize = 0;
1886
1887 return x;
1888}
1889
1890static void
1891unpacker_free(struct unpacker *x)
1892{
1893 if (x) {
1894 Py_XDECREF(x->unpack_from);
1895 Py_XDECREF(x->mview);
1896 PyMem_Free(x->item);
1897 PyMem_Free(x);
1898 }
1899}
1900
1901/* Return a new unpacker for the given format. */
1902static struct unpacker *
1903struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
1904{
1905 PyObject *structmodule; /* XXX cache these two */
1906 PyObject *Struct = NULL; /* XXX in globals? */
1907 PyObject *structobj = NULL;
1908 PyObject *format = NULL;
1909 struct unpacker *x = NULL;
1910
1911 structmodule = PyImport_ImportModule("struct");
1912 if (structmodule == NULL)
1913 return NULL;
1914
1915 Struct = PyObject_GetAttrString(structmodule, "Struct");
1916 Py_DECREF(structmodule);
1917 if (Struct == NULL)
1918 return NULL;
1919
1920 x = unpacker_new();
1921 if (x == NULL)
1922 goto error;
1923
1924 format = PyBytes_FromString(fmt);
1925 if (format == NULL)
1926 goto error;
1927
1928 structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
1929 if (structobj == NULL)
1930 goto error;
1931
1932 x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
1933 if (x->unpack_from == NULL)
1934 goto error;
1935
1936 x->item = PyMem_Malloc(itemsize);
1937 if (x->item == NULL) {
1938 PyErr_NoMemory();
1939 goto error;
1940 }
1941 x->itemsize = itemsize;
1942
1943 x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
1944 if (x->mview == NULL)
1945 goto error;
1946
1947
1948out:
1949 Py_XDECREF(Struct);
1950 Py_XDECREF(format);
1951 Py_XDECREF(structobj);
1952 return x;
1953
1954error:
1955 unpacker_free(x);
1956 x = NULL;
1957 goto out;
1958}
1959
1960/* unpack a single item */
1961static PyObject *
1962struct_unpack_single(const char *ptr, struct unpacker *x)
1963{
1964 PyObject *v;
1965
1966 memcpy(x->item, ptr, x->itemsize);
1967 v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL);
1968 if (v == NULL)
1969 return NULL;
1970
1971 if (PyTuple_GET_SIZE(v) == 1) {
1972 PyObject *tmp = PyTuple_GET_ITEM(v, 0);
1973 Py_INCREF(tmp);
1974 Py_DECREF(v);
1975 return tmp;
1976 }
1977
1978 return v;
1979}
1980
1981
1982/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001983/* Representations */
1984/****************************************************************************/
1985
1986/* allow explicit form of native format */
1987Py_LOCAL_INLINE(const char *)
1988adjust_fmt(const Py_buffer *view)
1989{
1990 const char *fmt;
1991
1992 fmt = (view->format[0] == '@') ? view->format+1 : view->format;
1993 if (fmt[0] && fmt[1] == '\0')
1994 return fmt;
1995
1996 PyErr_Format(PyExc_NotImplementedError,
1997 "memoryview: unsupported format %s", view->format);
1998 return NULL;
1999}
2000
2001/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
2002static PyObject *
2003tolist_base(const char *ptr, const Py_ssize_t *shape,
2004 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2005 const char *fmt)
2006{
2007 PyObject *lst, *item;
2008 Py_ssize_t i;
2009
2010 lst = PyList_New(shape[0]);
2011 if (lst == NULL)
2012 return NULL;
2013
2014 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2015 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2016 item = unpack_single(xptr, fmt);
2017 if (item == NULL) {
2018 Py_DECREF(lst);
2019 return NULL;
2020 }
2021 PyList_SET_ITEM(lst, i, item);
2022 }
2023
2024 return lst;
2025}
2026
2027/* Unpack a multi-dimensional array into a nested list.
2028 Assumption: ndim >= 1. */
2029static PyObject *
2030tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
2031 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2032 const char *fmt)
2033{
2034 PyObject *lst, *item;
2035 Py_ssize_t i;
2036
2037 assert(ndim >= 1);
2038 assert(shape != NULL);
2039 assert(strides != NULL);
2040
2041 if (ndim == 1)
2042 return tolist_base(ptr, shape, strides, suboffsets, fmt);
2043
2044 lst = PyList_New(shape[0]);
2045 if (lst == NULL)
2046 return NULL;
2047
2048 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2049 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2050 item = tolist_rec(xptr, ndim-1, shape+1,
2051 strides+1, suboffsets ? suboffsets+1 : NULL,
2052 fmt);
2053 if (item == NULL) {
2054 Py_DECREF(lst);
2055 return NULL;
2056 }
2057 PyList_SET_ITEM(lst, i, item);
2058 }
2059
2060 return lst;
2061}
2062
2063/* Return a list representation of the memoryview. Currently only buffers
2064 with native format strings are supported. */
2065static PyObject *
2066memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
2067{
2068 const Py_buffer *view = &(mv->view);
2069 const char *fmt;
2070
2071 CHECK_RELEASED(mv);
2072
2073 fmt = adjust_fmt(view);
2074 if (fmt == NULL)
2075 return NULL;
2076 if (view->ndim == 0) {
2077 return unpack_single(view->buf, fmt);
2078 }
2079 else if (view->ndim == 1) {
2080 return tolist_base(view->buf, view->shape,
2081 view->strides, view->suboffsets,
2082 fmt);
2083 }
2084 else {
2085 return tolist_rec(view->buf, view->ndim, view->shape,
2086 view->strides, view->suboffsets,
2087 fmt);
2088 }
2089}
2090
2091static PyObject *
2092memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
2093{
2094 Py_buffer *src = VIEW_ADDR(self);
2095 PyObject *bytes = NULL;
2096
2097 CHECK_RELEASED(self);
2098
2099 if (MV_C_CONTIGUOUS(self->flags)) {
2100 return PyBytes_FromStringAndSize(src->buf, src->len);
2101 }
2102
2103 bytes = PyBytes_FromStringAndSize(NULL, src->len);
2104 if (bytes == NULL)
2105 return NULL;
2106
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002107 if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002108 Py_DECREF(bytes);
2109 return NULL;
2110 }
2111
2112 return bytes;
2113}
2114
2115static PyObject *
2116memory_repr(PyMemoryViewObject *self)
2117{
2118 if (self->flags & _Py_MEMORYVIEW_RELEASED)
2119 return PyUnicode_FromFormat("<released memory at %p>", self);
2120 else
2121 return PyUnicode_FromFormat("<memory at %p>", self);
2122}
2123
2124
2125/**************************************************************************/
2126/* Indexing and slicing */
2127/**************************************************************************/
2128
2129/* Get the pointer to the item at index. */
2130static char *
2131ptr_from_index(Py_buffer *view, Py_ssize_t index)
2132{
2133 char *ptr;
2134 Py_ssize_t nitems; /* items in the first dimension */
2135
2136 assert(view->shape);
2137 assert(view->strides);
2138
2139 nitems = view->shape[0];
2140 if (index < 0) {
2141 index += nitems;
2142 }
2143 if (index < 0 || index >= nitems) {
2144 PyErr_SetString(PyExc_IndexError, "index out of bounds");
2145 return NULL;
2146 }
2147
2148 ptr = (char *)view->buf;
2149 ptr += view->strides[0] * index;
2150
2151 ptr = ADJUST_PTR(ptr, view->suboffsets);
2152
2153 return ptr;
2154}
2155
2156/* Return the item at index. In a one-dimensional view, this is an object
2157 with the type specified by view->format. Otherwise, the item is a sub-view.
2158 The function is used in memory_subscript() and memory_as_sequence. */
2159static PyObject *
2160memory_item(PyMemoryViewObject *self, Py_ssize_t index)
2161{
2162 Py_buffer *view = &(self->view);
2163 const char *fmt;
2164
2165 CHECK_RELEASED(self);
2166
2167 fmt = adjust_fmt(view);
2168 if (fmt == NULL)
2169 return NULL;
2170
2171 if (view->ndim == 0) {
2172 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
2173 return NULL;
2174 }
2175 if (view->ndim == 1) {
2176 char *ptr = ptr_from_index(view, index);
2177 if (ptr == NULL)
2178 return NULL;
2179 return unpack_single(ptr, fmt);
2180 }
2181
2182 PyErr_SetString(PyExc_NotImplementedError,
2183 "multi-dimensional sub-views are not implemented");
2184 return NULL;
2185}
2186
2187Py_LOCAL_INLINE(int)
2188init_slice(Py_buffer *base, PyObject *key, int dim)
2189{
2190 Py_ssize_t start, stop, step, slicelength;
2191
2192 if (PySlice_GetIndicesEx(key, base->shape[dim],
2193 &start, &stop, &step, &slicelength) < 0) {
2194 return -1;
2195 }
2196
2197
2198 if (base->suboffsets == NULL || dim == 0) {
2199 adjust_buf:
2200 base->buf = (char *)base->buf + base->strides[dim] * start;
2201 }
2202 else {
2203 Py_ssize_t n = dim-1;
2204 while (n >= 0 && base->suboffsets[n] < 0)
2205 n--;
2206 if (n < 0)
2207 goto adjust_buf; /* all suboffsets are negative */
2208 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
2209 }
2210 base->shape[dim] = slicelength;
2211 base->strides[dim] = base->strides[dim] * step;
2212
2213 return 0;
2214}
2215
2216static int
2217is_multislice(PyObject *key)
2218{
2219 Py_ssize_t size, i;
2220
2221 if (!PyTuple_Check(key))
2222 return 0;
2223 size = PyTuple_GET_SIZE(key);
2224 if (size == 0)
2225 return 0;
2226
2227 for (i = 0; i < size; i++) {
2228 PyObject *x = PyTuple_GET_ITEM(key, i);
2229 if (!PySlice_Check(x))
2230 return 0;
2231 }
2232 return 1;
2233}
2234
2235/* mv[obj] returns an object holding the data for one element if obj
2236 fully indexes the memoryview or another memoryview object if it
2237 does not.
2238
2239 0-d memoryview objects can be referenced using mv[...] or mv[()]
2240 but not with anything else. */
2241static PyObject *
2242memory_subscript(PyMemoryViewObject *self, PyObject *key)
2243{
2244 Py_buffer *view;
2245 view = &(self->view);
2246
2247 CHECK_RELEASED(self);
2248
2249 if (view->ndim == 0) {
2250 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2251 const char *fmt = adjust_fmt(view);
2252 if (fmt == NULL)
2253 return NULL;
2254 return unpack_single(view->buf, fmt);
2255 }
2256 else if (key == Py_Ellipsis) {
2257 Py_INCREF(self);
2258 return (PyObject *)self;
2259 }
2260 else {
2261 PyErr_SetString(PyExc_TypeError,
2262 "invalid indexing of 0-dim memory");
2263 return NULL;
2264 }
2265 }
2266
2267 if (PyIndex_Check(key)) {
2268 Py_ssize_t index;
2269 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2270 if (index == -1 && PyErr_Occurred())
2271 return NULL;
2272 return memory_item(self, index);
2273 }
2274 else if (PySlice_Check(key)) {
2275 PyMemoryViewObject *sliced;
2276
2277 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2278 if (sliced == NULL)
2279 return NULL;
2280
2281 if (init_slice(&sliced->view, key, 0) < 0) {
2282 Py_DECREF(sliced);
2283 return NULL;
2284 }
2285 init_len(&sliced->view);
2286 init_flags(sliced);
2287
2288 return (PyObject *)sliced;
2289 }
2290 else if (is_multislice(key)) {
2291 PyErr_SetString(PyExc_NotImplementedError,
2292 "multi-dimensional slicing is not implemented");
2293 return NULL;
2294 }
2295
2296 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2297 return NULL;
2298}
2299
2300static int
2301memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2302{
2303 Py_buffer *view = &(self->view);
2304 Py_buffer src;
2305 const char *fmt;
2306 char *ptr;
2307
2308 CHECK_RELEASED_INT(self);
2309
2310 fmt = adjust_fmt(view);
2311 if (fmt == NULL)
2312 return -1;
2313
2314 if (view->readonly) {
2315 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2316 return -1;
2317 }
2318 if (value == NULL) {
2319 PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2320 return -1;
2321 }
2322 if (view->ndim == 0) {
2323 if (key == Py_Ellipsis ||
2324 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2325 ptr = (char *)view->buf;
2326 return pack_single(ptr, value, fmt);
2327 }
2328 else {
2329 PyErr_SetString(PyExc_TypeError,
2330 "invalid indexing of 0-dim memory");
2331 return -1;
2332 }
2333 }
2334 if (view->ndim != 1) {
2335 PyErr_SetString(PyExc_NotImplementedError,
2336 "memoryview assignments are currently restricted to ndim = 1");
2337 return -1;
2338 }
2339
2340 if (PyIndex_Check(key)) {
2341 Py_ssize_t index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2342 if (index == -1 && PyErr_Occurred())
2343 return -1;
2344 ptr = ptr_from_index(view, index);
2345 if (ptr == NULL)
2346 return -1;
2347 return pack_single(ptr, value, fmt);
2348 }
2349 /* one-dimensional: fast path */
2350 if (PySlice_Check(key) && view->ndim == 1) {
2351 Py_buffer dest; /* sliced view */
2352 Py_ssize_t arrays[3];
2353 int ret = -1;
2354
2355 /* rvalue must be an exporter */
2356 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2357 return ret;
2358
2359 dest = *view;
2360 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2361 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2362 if (view->suboffsets) {
2363 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2364 }
2365
2366 if (init_slice(&dest, key, 0) < 0)
2367 goto end_block;
2368 dest.len = dest.shape[0] * dest.itemsize;
2369
2370 ret = copy_single(&dest, &src);
2371
2372 end_block:
2373 PyBuffer_Release(&src);
2374 return ret;
2375 }
2376 else if (PySlice_Check(key) || is_multislice(key)) {
2377 /* Call memory_subscript() to produce a sliced lvalue, then copy
2378 rvalue into lvalue. This is already implemented in _testbuffer.c. */
2379 PyErr_SetString(PyExc_NotImplementedError,
2380 "memoryview slice assignments are currently restricted "
2381 "to ndim = 1");
2382 return -1;
2383 }
2384
2385 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2386 return -1;
2387}
2388
2389static Py_ssize_t
2390memory_length(PyMemoryViewObject *self)
2391{
2392 CHECK_RELEASED_INT(self);
2393 return self->view.ndim == 0 ? 1 : self->view.shape[0];
2394}
2395
2396/* As mapping */
2397static PyMappingMethods memory_as_mapping = {
2398 (lenfunc)memory_length, /* mp_length */
2399 (binaryfunc)memory_subscript, /* mp_subscript */
2400 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
2401};
2402
2403/* As sequence */
2404static PySequenceMethods memory_as_sequence = {
Nick Coghlana0f169c2013-10-02 22:06:54 +10002405 (lenfunc)memory_length, /* sq_length */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002406 0, /* sq_concat */
2407 0, /* sq_repeat */
2408 (ssizeargfunc)memory_item, /* sq_item */
2409};
2410
2411
2412/**************************************************************************/
2413/* Comparisons */
2414/**************************************************************************/
2415
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002416#define MV_COMPARE_EX -1 /* exception */
2417#define MV_COMPARE_NOT_IMPL -2 /* not implemented */
2418
2419/* Translate a StructError to "not equal". Preserve other exceptions. */
2420static int
2421fix_struct_error_int(void)
2422{
2423 assert(PyErr_Occurred());
2424 /* XXX Cannot get at StructError directly? */
2425 if (PyErr_ExceptionMatches(PyExc_ImportError) ||
2426 PyErr_ExceptionMatches(PyExc_MemoryError)) {
2427 return MV_COMPARE_EX;
2428 }
2429 /* StructError: invalid or unknown format -> not equal */
2430 PyErr_Clear();
2431 return 0;
2432}
2433
2434/* Unpack and compare single items of p and q using the struct module. */
2435static int
2436struct_unpack_cmp(const char *p, const char *q,
2437 struct unpacker *unpack_p, struct unpacker *unpack_q)
2438{
2439 PyObject *v, *w;
2440 int ret;
2441
2442 /* At this point any exception from the struct module should not be
2443 StructError, since both formats have been accepted already. */
2444 v = struct_unpack_single(p, unpack_p);
2445 if (v == NULL)
2446 return MV_COMPARE_EX;
2447
2448 w = struct_unpack_single(q, unpack_q);
2449 if (w == NULL) {
2450 Py_DECREF(v);
2451 return MV_COMPARE_EX;
2452 }
2453
2454 /* MV_COMPARE_EX == -1: exceptions are preserved */
2455 ret = PyObject_RichCompareBool(v, w, Py_EQ);
2456 Py_DECREF(v);
2457 Py_DECREF(w);
2458
2459 return ret;
2460}
2461
2462/* Unpack and compare single items of p and q. If both p and q have the same
2463 single element native format, the comparison uses a fast path (gcc creates
2464 a jump table and converts memcpy into simple assignments on x86/x64).
2465
2466 Otherwise, the comparison is delegated to the struct module, which is
2467 30-60x slower. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002468#define CMP_SINGLE(p, q, type) \
2469 do { \
2470 type x; \
2471 type y; \
2472 memcpy((char *)&x, p, sizeof x); \
2473 memcpy((char *)&y, q, sizeof y); \
2474 equal = (x == y); \
2475 } while (0)
2476
2477Py_LOCAL_INLINE(int)
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002478unpack_cmp(const char *p, const char *q, char fmt,
2479 struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002480{
2481 int equal;
2482
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002483 switch (fmt) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002484
2485 /* signed integers and fast path for 'B' */
2486 case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
2487 case 'b': return *((signed char *)p) == *((signed char *)q);
2488 case 'h': CMP_SINGLE(p, q, short); return equal;
2489 case 'i': CMP_SINGLE(p, q, int); return equal;
2490 case 'l': CMP_SINGLE(p, q, long); return equal;
2491
2492 /* boolean */
2493 #ifdef HAVE_C99_BOOL
2494 case '?': CMP_SINGLE(p, q, _Bool); return equal;
2495 #else
2496 case '?': CMP_SINGLE(p, q, char); return equal;
2497 #endif
2498
2499 /* unsigned integers */
2500 case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2501 case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2502 case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2503
2504 /* native 64-bit */
2505 #ifdef HAVE_LONG_LONG
2506 case 'q': CMP_SINGLE(p, q, PY_LONG_LONG); return equal;
2507 case 'Q': CMP_SINGLE(p, q, unsigned PY_LONG_LONG); return equal;
2508 #endif
2509
2510 /* ssize_t and size_t */
2511 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2512 case 'N': CMP_SINGLE(p, q, size_t); return equal;
2513
2514 /* floats */
2515 /* XXX DBL_EPSILON? */
2516 case 'f': CMP_SINGLE(p, q, float); return equal;
2517 case 'd': CMP_SINGLE(p, q, double); return equal;
2518
2519 /* bytes object */
2520 case 'c': return *p == *q;
2521
2522 /* pointer */
2523 case 'P': CMP_SINGLE(p, q, void *); return equal;
2524
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002525 /* use the struct module */
2526 case '_':
2527 assert(unpack_p);
2528 assert(unpack_q);
2529 return struct_unpack_cmp(p, q, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002530 }
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002531
2532 /* NOT REACHED */
2533 PyErr_SetString(PyExc_RuntimeError,
2534 "memoryview: internal error in richcompare");
2535 return MV_COMPARE_EX;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002536}
2537
2538/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2539static int
2540cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2541 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2542 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002543 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002544{
2545 Py_ssize_t i;
2546 int equal;
2547
2548 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2549 const char *xp = ADJUST_PTR(p, psuboffsets);
2550 const char *xq = ADJUST_PTR(q, qsuboffsets);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002551 equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002552 if (equal <= 0)
2553 return equal;
2554 }
2555
2556 return 1;
2557}
2558
2559/* Recursively compare two multi-dimensional arrays that have the same
2560 logical structure. Assumption: ndim >= 1. */
2561static int
2562cmp_rec(const char *p, const char *q,
2563 Py_ssize_t ndim, const Py_ssize_t *shape,
2564 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2565 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002566 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002567{
2568 Py_ssize_t i;
2569 int equal;
2570
2571 assert(ndim >= 1);
2572 assert(shape != NULL);
2573 assert(pstrides != NULL);
2574 assert(qstrides != NULL);
2575
2576 if (ndim == 1) {
2577 return cmp_base(p, q, shape,
2578 pstrides, psuboffsets,
2579 qstrides, qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002580 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002581 }
2582
2583 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2584 const char *xp = ADJUST_PTR(p, psuboffsets);
2585 const char *xq = ADJUST_PTR(q, qsuboffsets);
2586 equal = cmp_rec(xp, xq, ndim-1, shape+1,
2587 pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2588 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002589 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002590 if (equal <= 0)
2591 return equal;
2592 }
2593
2594 return 1;
2595}
2596
2597static PyObject *
2598memory_richcompare(PyObject *v, PyObject *w, int op)
2599{
2600 PyObject *res;
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002601 Py_buffer wbuf, *vv;
2602 Py_buffer *ww = NULL;
2603 struct unpacker *unpack_v = NULL;
2604 struct unpacker *unpack_w = NULL;
2605 char vfmt, wfmt;
2606 int equal = MV_COMPARE_NOT_IMPL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002607
2608 if (op != Py_EQ && op != Py_NE)
2609 goto result; /* Py_NotImplemented */
2610
2611 assert(PyMemoryView_Check(v));
2612 if (BASE_INACCESSIBLE(v)) {
2613 equal = (v == w);
2614 goto result;
2615 }
2616 vv = VIEW_ADDR(v);
2617
2618 if (PyMemoryView_Check(w)) {
2619 if (BASE_INACCESSIBLE(w)) {
2620 equal = (v == w);
2621 goto result;
2622 }
2623 ww = VIEW_ADDR(w);
2624 }
2625 else {
2626 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2627 PyErr_Clear();
2628 goto result; /* Py_NotImplemented */
2629 }
2630 ww = &wbuf;
2631 }
2632
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002633 if (!equiv_shape(vv, ww)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002634 PyErr_Clear();
2635 equal = 0;
2636 goto result;
2637 }
2638
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002639 /* Use fast unpacking for identical primitive C type formats. */
2640 if (get_native_fmtchar(&vfmt, vv->format) < 0)
2641 vfmt = '_';
2642 if (get_native_fmtchar(&wfmt, ww->format) < 0)
2643 wfmt = '_';
2644 if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
2645 /* Use struct module unpacking. NOTE: Even for equal format strings,
2646 memcmp() cannot be used for item comparison since it would give
2647 incorrect results in the case of NaNs or uninitialized padding
2648 bytes. */
2649 vfmt = '_';
2650 unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
2651 if (unpack_v == NULL) {
2652 equal = fix_struct_error_int();
2653 goto result;
2654 }
2655 unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
2656 if (unpack_w == NULL) {
2657 equal = fix_struct_error_int();
2658 goto result;
2659 }
2660 }
2661
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002662 if (vv->ndim == 0) {
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002663 equal = unpack_cmp(vv->buf, ww->buf,
2664 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002665 }
2666 else if (vv->ndim == 1) {
2667 equal = cmp_base(vv->buf, ww->buf, vv->shape,
2668 vv->strides, vv->suboffsets,
2669 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002670 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002671 }
2672 else {
2673 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2674 vv->strides, vv->suboffsets,
2675 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002676 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002677 }
2678
2679result:
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002680 if (equal < 0) {
2681 if (equal == MV_COMPARE_NOT_IMPL)
2682 res = Py_NotImplemented;
2683 else /* exception */
2684 res = NULL;
2685 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002686 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2687 res = Py_True;
2688 else
2689 res = Py_False;
2690
2691 if (ww == &wbuf)
2692 PyBuffer_Release(ww);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002693
2694 unpacker_free(unpack_v);
2695 unpacker_free(unpack_w);
2696
2697 Py_XINCREF(res);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002698 return res;
2699}
2700
2701/**************************************************************************/
2702/* Hash */
2703/**************************************************************************/
2704
2705static Py_hash_t
2706memory_hash(PyMemoryViewObject *self)
2707{
2708 if (self->hash == -1) {
2709 Py_buffer *view = &self->view;
2710 char *mem = view->buf;
Stefan Krah4af77a02012-11-02 17:49:22 +01002711 Py_ssize_t ret;
2712 char fmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002713
2714 CHECK_RELEASED_INT(self);
2715
2716 if (!view->readonly) {
2717 PyErr_SetString(PyExc_ValueError,
2718 "cannot hash writable memoryview object");
2719 return -1;
2720 }
Stefan Krah4af77a02012-11-02 17:49:22 +01002721 ret = get_native_fmtchar(&fmt, view->format);
2722 if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
2723 PyErr_SetString(PyExc_ValueError,
2724 "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
2725 return -1;
2726 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002727 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2728 /* Keep the original error message */
2729 return -1;
2730 }
2731
2732 if (!MV_C_CONTIGUOUS(self->flags)) {
2733 mem = PyMem_Malloc(view->len);
2734 if (mem == NULL) {
2735 PyErr_NoMemory();
2736 return -1;
2737 }
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002738 if (buffer_to_contiguous(mem, view, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002739 PyMem_Free(mem);
2740 return -1;
2741 }
2742 }
2743
2744 /* Can't fail */
Christian Heimes985ecdc2013-11-20 11:46:18 +01002745 self->hash = _Py_HashBytes(mem, view->len);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002746
2747 if (mem != view->buf)
2748 PyMem_Free(mem);
2749 }
2750
2751 return self->hash;
2752}
2753
2754
2755/**************************************************************************/
2756/* getters */
2757/**************************************************************************/
2758
2759static PyObject *
2760_IntTupleFromSsizet(int len, Py_ssize_t *vals)
2761{
2762 int i;
2763 PyObject *o;
2764 PyObject *intTuple;
2765
2766 if (vals == NULL)
2767 return PyTuple_New(0);
2768
2769 intTuple = PyTuple_New(len);
2770 if (!intTuple)
2771 return NULL;
2772 for (i=0; i<len; i++) {
2773 o = PyLong_FromSsize_t(vals[i]);
2774 if (!o) {
2775 Py_DECREF(intTuple);
2776 return NULL;
2777 }
2778 PyTuple_SET_ITEM(intTuple, i, o);
2779 }
2780 return intTuple;
2781}
2782
2783static PyObject *
2784memory_obj_get(PyMemoryViewObject *self)
2785{
2786 Py_buffer *view = &self->view;
2787
2788 CHECK_RELEASED(self);
2789 if (view->obj == NULL) {
2790 Py_RETURN_NONE;
2791 }
2792 Py_INCREF(view->obj);
2793 return view->obj;
2794}
2795
2796static PyObject *
2797memory_nbytes_get(PyMemoryViewObject *self)
2798{
2799 CHECK_RELEASED(self);
2800 return PyLong_FromSsize_t(self->view.len);
2801}
2802
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002803static PyObject *
2804memory_format_get(PyMemoryViewObject *self)
2805{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002806 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002807 return PyUnicode_FromString(self->view.format);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002808}
2809
2810static PyObject *
2811memory_itemsize_get(PyMemoryViewObject *self)
2812{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002813 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002814 return PyLong_FromSsize_t(self->view.itemsize);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002815}
2816
2817static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002818memory_shape_get(PyMemoryViewObject *self)
2819{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002820 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002821 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002822}
2823
2824static PyObject *
2825memory_strides_get(PyMemoryViewObject *self)
2826{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002827 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002828 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002829}
2830
2831static PyObject *
2832memory_suboffsets_get(PyMemoryViewObject *self)
2833{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002834 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002835 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002836}
2837
2838static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002839memory_readonly_get(PyMemoryViewObject *self)
2840{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002841 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002842 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002843}
2844
2845static PyObject *
2846memory_ndim_get(PyMemoryViewObject *self)
2847{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002848 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002849 return PyLong_FromLong(self->view.ndim);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002850}
2851
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002852static PyObject *
2853memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2854{
2855 CHECK_RELEASED(self);
2856 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
2857}
2858
2859static PyObject *
2860memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2861{
2862 CHECK_RELEASED(self);
2863 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
2864}
2865
2866static PyObject *
2867memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2868{
2869 CHECK_RELEASED(self);
2870 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
2871}
2872
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002873PyDoc_STRVAR(memory_obj_doc,
2874 "The underlying object of the memoryview.");
2875PyDoc_STRVAR(memory_nbytes_doc,
2876 "The amount of space in bytes that the array would use in\n"
2877 " a contiguous representation.");
2878PyDoc_STRVAR(memory_readonly_doc,
2879 "A bool indicating whether the memory is read only.");
2880PyDoc_STRVAR(memory_itemsize_doc,
2881 "The size in bytes of each element of the memoryview.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002882PyDoc_STRVAR(memory_format_doc,
2883 "A string containing the format (in struct module style)\n"
2884 " for each element in the view.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002885PyDoc_STRVAR(memory_ndim_doc,
2886 "An integer indicating how many dimensions of a multi-dimensional\n"
2887 " array the memory represents.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002888PyDoc_STRVAR(memory_shape_doc,
2889 "A tuple of ndim integers giving the shape of the memory\n"
2890 " as an N-dimensional array.");
2891PyDoc_STRVAR(memory_strides_doc,
2892 "A tuple of ndim integers giving the size in bytes to access\n"
2893 " each element for each dimension of the array.");
2894PyDoc_STRVAR(memory_suboffsets_doc,
2895 "A tuple of integers used internally for PIL-style arrays.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002896PyDoc_STRVAR(memory_c_contiguous_doc,
2897 "A bool indicating whether the memory is C contiguous.");
2898PyDoc_STRVAR(memory_f_contiguous_doc,
2899 "A bool indicating whether the memory is Fortran contiguous.");
2900PyDoc_STRVAR(memory_contiguous_doc,
2901 "A bool indicating whether the memory is contiguous.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002902
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002903static PyGetSetDef memory_getsetlist[] = {
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002904 {"obj", (getter)memory_obj_get, NULL, memory_obj_doc},
2905 {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc},
Alexander Belopolskye370c382012-09-03 16:43:55 -04002906 {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc},
2907 {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc},
2908 {"format", (getter)memory_format_get, NULL, memory_format_doc},
2909 {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc},
2910 {"shape", (getter)memory_shape_get, NULL, memory_shape_doc},
2911 {"strides", (getter)memory_strides_get, NULL, memory_strides_doc},
2912 {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002913 {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc},
2914 {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc},
2915 {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc},
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002916 {NULL, NULL, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002917};
2918
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002919PyDoc_STRVAR(memory_release_doc,
2920"M.release() -> None\n\
2921\n\
2922Release the underlying buffer exposed by the memoryview object.");
2923PyDoc_STRVAR(memory_tobytes_doc,
2924"M.tobytes() -> bytes\n\
2925\n\
2926Return the data in the buffer as a byte string.");
2927PyDoc_STRVAR(memory_tolist_doc,
2928"M.tolist() -> list\n\
2929\n\
2930Return the data in the buffer as a list of elements.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002931PyDoc_STRVAR(memory_cast_doc,
2932"M.cast(format[, shape]) -> memoryview\n\
2933\n\
2934Cast a memoryview to a new format or shape.");
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002935
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002936static PyMethodDef memory_methods[] = {
Alexander Belopolskye370c382012-09-03 16:43:55 -04002937 {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
2938 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc},
2939 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002940 {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
Stefan Krahe4c07992012-07-28 14:10:02 +02002941 {"__enter__", memory_enter, METH_NOARGS, NULL},
2942 {"__exit__", memory_exit, METH_VARARGS, NULL},
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002943 {NULL, NULL}
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002944};
2945
2946
2947PyTypeObject PyMemoryView_Type = {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002948 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002949 "memoryview", /* tp_name */
2950 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */
2951 sizeof(Py_ssize_t), /* tp_itemsize */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002952 (destructor)memory_dealloc, /* tp_dealloc */
2953 0, /* tp_print */
2954 0, /* tp_getattr */
2955 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002956 0, /* tp_reserved */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002957 (reprfunc)memory_repr, /* tp_repr */
2958 0, /* tp_as_number */
Raymond Hettinger159eac92009-06-23 20:38:54 +00002959 &memory_as_sequence, /* tp_as_sequence */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002960 &memory_as_mapping, /* tp_as_mapping */
Antoine Pitrouce4a9da2011-11-21 20:46:33 +01002961 (hashfunc)memory_hash, /* tp_hash */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002962 0, /* tp_call */
Benjamin Peterson87618552009-02-08 15:00:52 +00002963 0, /* tp_str */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002964 PyObject_GenericGetAttr, /* tp_getattro */
2965 0, /* tp_setattro */
2966 &memory_as_buffer, /* tp_as_buffer */
2967 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2968 memory_doc, /* tp_doc */
2969 (traverseproc)memory_traverse, /* tp_traverse */
2970 (inquiry)memory_clear, /* tp_clear */
2971 memory_richcompare, /* tp_richcompare */
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01002972 offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002973 0, /* tp_iter */
2974 0, /* tp_iternext */
2975 memory_methods, /* tp_methods */
2976 0, /* tp_members */
2977 memory_getsetlist, /* tp_getset */
2978 0, /* tp_base */
2979 0, /* tp_dict */
2980 0, /* tp_descr_get */
2981 0, /* tp_descr_set */
2982 0, /* tp_dictoffset */
2983 0, /* tp_init */
2984 0, /* tp_alloc */
2985 memory_new, /* tp_new */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002986};