blob: 0be84939ab62543d37488846c6dac6b95a70135a [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
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001138Py_LOCAL_INLINE(char *)
1139get_native_fmtstr(const char *fmt)
1140{
1141 int at = 0;
1142
1143 if (fmt[0] == '@') {
1144 at = 1;
1145 fmt++;
1146 }
1147 if (fmt[0] == '\0' || fmt[1] != '\0') {
1148 return NULL;
1149 }
1150
1151#define RETURN(s) do { return at ? "@" s : s; } while (0)
1152
1153 switch (fmt[0]) {
1154 case 'c': RETURN("c");
1155 case 'b': RETURN("b");
1156 case 'B': RETURN("B");
1157 case 'h': RETURN("h");
1158 case 'H': RETURN("H");
1159 case 'i': RETURN("i");
1160 case 'I': RETURN("I");
1161 case 'l': RETURN("l");
1162 case 'L': RETURN("L");
1163 #ifdef HAVE_LONG_LONG
1164 case 'q': RETURN("q");
1165 case 'Q': RETURN("Q");
1166 #endif
1167 case 'n': RETURN("n");
1168 case 'N': RETURN("N");
1169 case 'f': RETURN("f");
1170 case 'd': RETURN("d");
1171 #ifdef HAVE_C99_BOOL
1172 case '?': RETURN("?");
1173 #else
1174 case '?': RETURN("?");
1175 #endif
1176 case 'P': RETURN("P");
1177 }
1178
1179 return NULL;
1180}
1181
1182
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001183/* Cast a memoryview's data type to 'format'. The input array must be
1184 C-contiguous. At least one of input-format, output-format must have
1185 byte size. The output array is 1-D, with the same byte length as the
1186 input array. Thus, view->len must be a multiple of the new itemsize. */
1187static int
1188cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1189{
1190 Py_buffer *view = &mv->view;
1191 PyObject *asciifmt;
1192 char srcchar, destchar;
1193 Py_ssize_t itemsize;
1194 int ret = -1;
1195
1196 assert(view->ndim >= 1);
1197 assert(Py_SIZE(mv) == 3*view->ndim);
1198 assert(view->shape == mv->ob_array);
1199 assert(view->strides == mv->ob_array + view->ndim);
1200 assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1201
1202 if (get_native_fmtchar(&srcchar, view->format) < 0) {
1203 PyErr_SetString(PyExc_ValueError,
1204 "memoryview: source format must be a native single character "
1205 "format prefixed with an optional '@'");
1206 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001207 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001208
1209 asciifmt = PyUnicode_AsASCIIString(format);
1210 if (asciifmt == NULL)
1211 return ret;
1212
1213 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1214 if (itemsize < 0) {
1215 PyErr_SetString(PyExc_ValueError,
1216 "memoryview: destination format must be a native single "
1217 "character format prefixed with an optional '@'");
1218 goto out;
1219 }
1220
1221 if (!IS_BYTE_FORMAT(srcchar) && !IS_BYTE_FORMAT(destchar)) {
1222 PyErr_SetString(PyExc_TypeError,
1223 "memoryview: cannot cast between two non-byte formats");
1224 goto out;
1225 }
1226 if (view->len % itemsize) {
1227 PyErr_SetString(PyExc_TypeError,
1228 "memoryview: length is not a multiple of itemsize");
1229 goto out;
1230 }
1231
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001232 view->format = get_native_fmtstr(PyBytes_AS_STRING(asciifmt));
1233 if (view->format == NULL) {
1234 /* NOT_REACHED: get_native_fmtchar() already validates the format. */
1235 PyErr_SetString(PyExc_RuntimeError,
1236 "memoryview: internal error");
1237 goto out;
1238 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001239 view->itemsize = itemsize;
1240
1241 view->ndim = 1;
1242 view->shape[0] = view->len / view->itemsize;
1243 view->strides[0] = view->itemsize;
1244 view->suboffsets = NULL;
1245
1246 init_flags(mv);
1247
1248 ret = 0;
1249
1250out:
1251 Py_DECREF(asciifmt);
1252 return ret;
1253}
1254
1255/* The memoryview must have space for 3*len(seq) elements. */
1256static Py_ssize_t
1257copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1258 Py_ssize_t itemsize)
1259{
1260 Py_ssize_t x, i;
1261 Py_ssize_t len = itemsize;
1262
1263 for (i = 0; i < ndim; i++) {
1264 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1265 if (!PyLong_Check(tmp)) {
1266 PyErr_SetString(PyExc_TypeError,
1267 "memoryview.cast(): elements of shape must be integers");
1268 return -1;
1269 }
1270 x = PyLong_AsSsize_t(tmp);
1271 if (x == -1 && PyErr_Occurred()) {
1272 return -1;
1273 }
1274 if (x <= 0) {
1275 /* In general elements of shape may be 0, but not for casting. */
1276 PyErr_Format(PyExc_ValueError,
1277 "memoryview.cast(): elements of shape must be integers > 0");
1278 return -1;
1279 }
1280 if (x > PY_SSIZE_T_MAX / len) {
1281 PyErr_Format(PyExc_ValueError,
1282 "memoryview.cast(): product(shape) > SSIZE_MAX");
1283 return -1;
1284 }
1285 len *= x;
1286 shape[i] = x;
1287 }
1288
1289 return len;
1290}
1291
1292/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1293 If the result array does not have exactly the same byte length as the
1294 input array, raise ValueError. */
1295static int
1296cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1297{
1298 Py_buffer *view = &mv->view;
1299 Py_ssize_t len;
1300
1301 assert(view->ndim == 1); /* ndim from cast_to_1D() */
1302 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1303 assert(view->shape == mv->ob_array);
1304 assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1305 assert(view->suboffsets == NULL);
1306
1307 view->ndim = ndim;
1308 if (view->ndim == 0) {
1309 view->shape = NULL;
1310 view->strides = NULL;
1311 len = view->itemsize;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001312 }
1313 else {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001314 len = copy_shape(view->shape, shape, ndim, view->itemsize);
1315 if (len < 0)
1316 return -1;
1317 init_strides_from_shape(view);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001318 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001319
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001320 if (view->len != len) {
1321 PyErr_SetString(PyExc_TypeError,
1322 "memoryview: product(shape) * itemsize != buffer size");
1323 return -1;
1324 }
1325
1326 init_flags(mv);
1327
1328 return 0;
1329}
1330
1331static int
1332zero_in_shape(PyMemoryViewObject *mv)
1333{
1334 Py_buffer *view = &mv->view;
1335 Py_ssize_t i;
1336
1337 for (i = 0; i < view->ndim; i++)
1338 if (view->shape[i] == 0)
1339 return 1;
1340
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001341 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001342}
1343
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001344/*
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001345 Cast a copy of 'self' to a different view. The input view must
1346 be C-contiguous. The function always casts the input view to a
1347 1-D output according to 'format'. At least one of input-format,
1348 output-format must have byte size.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001349
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001350 If 'shape' is given, the 1-D view from the previous step will
1351 be cast to a C-contiguous view with new shape and strides.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001352
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001353 All casts must result in views that will have the exact byte
1354 size of the original input. Otherwise, an error is raised.
1355*/
1356static PyObject *
1357memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001358{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001359 static char *kwlist[] = {"format", "shape", NULL};
1360 PyMemoryViewObject *mv = NULL;
1361 PyObject *shape = NULL;
1362 PyObject *format;
1363 Py_ssize_t ndim = 1;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001364
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001365 CHECK_RELEASED(self);
1366
1367 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
1368 &format, &shape)) {
1369 return NULL;
1370 }
1371 if (!PyUnicode_Check(format)) {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001372 PyErr_SetString(PyExc_TypeError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001373 "memoryview: format argument must be a string");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001374 return NULL;
1375 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001376 if (!MV_C_CONTIGUOUS(self->flags)) {
1377 PyErr_SetString(PyExc_TypeError,
1378 "memoryview: casts are restricted to C-contiguous views");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001379 return NULL;
1380 }
Antoine Pitrou60b18342013-10-03 19:55:41 +02001381 if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001382 PyErr_SetString(PyExc_TypeError,
1383 "memoryview: cannot cast view with zeros in shape or strides");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001384 return NULL;
1385 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001386 if (shape) {
1387 CHECK_LIST_OR_TUPLE(shape)
1388 ndim = PySequence_Fast_GET_SIZE(shape);
1389 if (ndim > PyBUF_MAX_NDIM) {
1390 PyErr_SetString(PyExc_ValueError,
1391 "memoryview: number of dimensions must not exceed "
1392 STRINGIZE(PyBUF_MAX_NDIM));
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001393 return NULL;
1394 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001395 if (self->view.ndim != 1 && ndim != 1) {
1396 PyErr_SetString(PyExc_TypeError,
1397 "memoryview: cast must be 1D -> ND or ND -> 1D");
1398 return NULL;
1399 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001400 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001401
1402 mv = (PyMemoryViewObject *)
1403 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1404 if (mv == NULL)
1405 return NULL;
1406
1407 if (cast_to_1D(mv, format) < 0)
1408 goto error;
1409 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1410 goto error;
1411
1412 return (PyObject *)mv;
1413
1414error:
1415 Py_DECREF(mv);
1416 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001417}
1418
1419
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001420/**************************************************************************/
1421/* getbuffer */
1422/**************************************************************************/
1423
1424static int
1425memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1426{
1427 Py_buffer *base = &self->view;
1428 int baseflags = self->flags;
1429
1430 CHECK_RELEASED_INT(self);
1431
1432 /* start with complete information */
1433 *view = *base;
1434 view->obj = NULL;
1435
1436 if (REQ_WRITABLE(flags) && base->readonly) {
1437 PyErr_SetString(PyExc_BufferError,
1438 "memoryview: underlying buffer is not writable");
1439 return -1;
1440 }
1441 if (!REQ_FORMAT(flags)) {
1442 /* NULL indicates that the buffer's data type has been cast to 'B'.
1443 view->itemsize is the _previous_ itemsize. If shape is present,
1444 the equality product(shape) * itemsize = len still holds at this
1445 point. The equality calcsize(format) = itemsize does _not_ hold
1446 from here on! */
1447 view->format = NULL;
1448 }
1449
1450 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1451 PyErr_SetString(PyExc_BufferError,
1452 "memoryview: underlying buffer is not C-contiguous");
1453 return -1;
1454 }
1455 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1456 PyErr_SetString(PyExc_BufferError,
1457 "memoryview: underlying buffer is not Fortran contiguous");
1458 return -1;
1459 }
1460 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1461 PyErr_SetString(PyExc_BufferError,
1462 "memoryview: underlying buffer is not contiguous");
1463 return -1;
1464 }
1465 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1466 PyErr_SetString(PyExc_BufferError,
1467 "memoryview: underlying buffer requires suboffsets");
1468 return -1;
1469 }
1470 if (!REQ_STRIDES(flags)) {
1471 if (!MV_C_CONTIGUOUS(baseflags)) {
1472 PyErr_SetString(PyExc_BufferError,
1473 "memoryview: underlying buffer is not C-contiguous");
1474 return -1;
1475 }
1476 view->strides = NULL;
1477 }
1478 if (!REQ_SHAPE(flags)) {
1479 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1480 so base->buf = ndbuf->data. */
1481 if (view->format != NULL) {
1482 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1483 not make sense. */
1484 PyErr_Format(PyExc_BufferError,
Stefan Krah674a42b2013-02-19 13:44:49 +01001485 "memoryview: cannot cast to unsigned bytes if the format flag "
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001486 "is present");
1487 return -1;
1488 }
1489 /* product(shape) * itemsize = len and calcsize(format) = itemsize
1490 do _not_ hold from here on! */
1491 view->ndim = 1;
1492 view->shape = NULL;
1493 }
1494
1495
1496 view->obj = (PyObject *)self;
1497 Py_INCREF(view->obj);
1498 self->exports++;
1499
1500 return 0;
1501}
1502
1503static void
1504memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1505{
1506 self->exports--;
1507 return;
1508 /* PyBuffer_Release() decrements view->obj after this function returns. */
1509}
1510
1511/* Buffer methods */
1512static PyBufferProcs memory_as_buffer = {
1513 (getbufferproc)memory_getbuf, /* bf_getbuffer */
1514 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1515};
1516
1517
1518/****************************************************************************/
1519/* Optimized pack/unpack for all native format specifiers */
1520/****************************************************************************/
1521
1522/*
1523 Fix exceptions:
1524 1) Include format string in the error message.
1525 2) OverflowError -> ValueError.
1526 3) The error message from PyNumber_Index() is not ideal.
1527*/
1528static int
1529type_error_int(const char *fmt)
1530{
1531 PyErr_Format(PyExc_TypeError,
1532 "memoryview: invalid type for format '%s'", fmt);
1533 return -1;
1534}
1535
1536static int
1537value_error_int(const char *fmt)
1538{
1539 PyErr_Format(PyExc_ValueError,
1540 "memoryview: invalid value for format '%s'", fmt);
1541 return -1;
1542}
1543
1544static int
1545fix_error_int(const char *fmt)
1546{
1547 assert(PyErr_Occurred());
1548 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1549 PyErr_Clear();
1550 return type_error_int(fmt);
1551 }
1552 else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1553 PyErr_ExceptionMatches(PyExc_ValueError)) {
1554 PyErr_Clear();
1555 return value_error_int(fmt);
1556 }
1557
1558 return -1;
1559}
1560
1561/* Accept integer objects or objects with an __index__() method. */
1562static long
1563pylong_as_ld(PyObject *item)
1564{
1565 PyObject *tmp;
1566 long ld;
1567
1568 tmp = PyNumber_Index(item);
1569 if (tmp == NULL)
1570 return -1;
1571
1572 ld = PyLong_AsLong(tmp);
1573 Py_DECREF(tmp);
1574 return ld;
1575}
1576
1577static unsigned long
1578pylong_as_lu(PyObject *item)
1579{
1580 PyObject *tmp;
1581 unsigned long lu;
1582
1583 tmp = PyNumber_Index(item);
1584 if (tmp == NULL)
1585 return (unsigned long)-1;
1586
1587 lu = PyLong_AsUnsignedLong(tmp);
1588 Py_DECREF(tmp);
1589 return lu;
1590}
1591
1592#ifdef HAVE_LONG_LONG
1593static PY_LONG_LONG
1594pylong_as_lld(PyObject *item)
1595{
1596 PyObject *tmp;
1597 PY_LONG_LONG lld;
1598
1599 tmp = PyNumber_Index(item);
1600 if (tmp == NULL)
1601 return -1;
1602
1603 lld = PyLong_AsLongLong(tmp);
1604 Py_DECREF(tmp);
1605 return lld;
1606}
1607
1608static unsigned PY_LONG_LONG
1609pylong_as_llu(PyObject *item)
1610{
1611 PyObject *tmp;
1612 unsigned PY_LONG_LONG llu;
1613
1614 tmp = PyNumber_Index(item);
1615 if (tmp == NULL)
1616 return (unsigned PY_LONG_LONG)-1;
1617
1618 llu = PyLong_AsUnsignedLongLong(tmp);
1619 Py_DECREF(tmp);
1620 return llu;
1621}
1622#endif
1623
1624static Py_ssize_t
1625pylong_as_zd(PyObject *item)
1626{
1627 PyObject *tmp;
1628 Py_ssize_t zd;
1629
1630 tmp = PyNumber_Index(item);
1631 if (tmp == NULL)
1632 return -1;
1633
1634 zd = PyLong_AsSsize_t(tmp);
1635 Py_DECREF(tmp);
1636 return zd;
1637}
1638
1639static size_t
1640pylong_as_zu(PyObject *item)
1641{
1642 PyObject *tmp;
1643 size_t zu;
1644
1645 tmp = PyNumber_Index(item);
1646 if (tmp == NULL)
1647 return (size_t)-1;
1648
1649 zu = PyLong_AsSize_t(tmp);
1650 Py_DECREF(tmp);
1651 return zu;
1652}
1653
1654/* Timings with the ndarray from _testbuffer.c indicate that using the
1655 struct module is around 15x slower than the two functions below. */
1656
1657#define UNPACK_SINGLE(dest, ptr, type) \
1658 do { \
1659 type x; \
1660 memcpy((char *)&x, ptr, sizeof x); \
1661 dest = x; \
1662 } while (0)
1663
1664/* Unpack a single item. 'fmt' can be any native format character in struct
1665 module syntax. This function is very sensitive to small changes. With this
1666 layout gcc automatically generates a fast jump table. */
1667Py_LOCAL_INLINE(PyObject *)
1668unpack_single(const char *ptr, const char *fmt)
1669{
1670 unsigned PY_LONG_LONG llu;
1671 unsigned long lu;
1672 size_t zu;
1673 PY_LONG_LONG lld;
1674 long ld;
1675 Py_ssize_t zd;
1676 double d;
1677 unsigned char uc;
1678 void *p;
1679
1680 switch (fmt[0]) {
1681
1682 /* signed integers and fast path for 'B' */
1683 case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
1684 case 'b': ld = *((signed char *)ptr); goto convert_ld;
1685 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1686 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1687 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1688
1689 /* boolean */
1690 #ifdef HAVE_C99_BOOL
1691 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
1692 #else
1693 case '?': UNPACK_SINGLE(ld, ptr, char); goto convert_bool;
1694 #endif
1695
1696 /* unsigned integers */
1697 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1698 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1699 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1700
1701 /* native 64-bit */
1702 #ifdef HAVE_LONG_LONG
1703 case 'q': UNPACK_SINGLE(lld, ptr, PY_LONG_LONG); goto convert_lld;
1704 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned PY_LONG_LONG); goto convert_llu;
1705 #endif
1706
1707 /* ssize_t and size_t */
1708 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1709 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1710
1711 /* floats */
1712 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1713 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1714
1715 /* bytes object */
1716 case 'c': goto convert_bytes;
1717
1718 /* pointer */
1719 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1720
1721 /* default */
1722 default: goto err_format;
1723 }
1724
1725convert_uc:
1726 /* PyLong_FromUnsignedLong() is slower */
1727 return PyLong_FromLong(uc);
1728convert_ld:
1729 return PyLong_FromLong(ld);
1730convert_lu:
1731 return PyLong_FromUnsignedLong(lu);
1732convert_lld:
1733 return PyLong_FromLongLong(lld);
1734convert_llu:
1735 return PyLong_FromUnsignedLongLong(llu);
1736convert_zd:
1737 return PyLong_FromSsize_t(zd);
1738convert_zu:
1739 return PyLong_FromSize_t(zu);
1740convert_double:
1741 return PyFloat_FromDouble(d);
1742convert_bool:
1743 return PyBool_FromLong(ld);
1744convert_bytes:
1745 return PyBytes_FromStringAndSize(ptr, 1);
1746convert_pointer:
1747 return PyLong_FromVoidPtr(p);
1748err_format:
1749 PyErr_Format(PyExc_NotImplementedError,
1750 "memoryview: format %s not supported", fmt);
1751 return NULL;
1752}
1753
1754#define PACK_SINGLE(ptr, src, type) \
1755 do { \
1756 type x; \
1757 x = (type)src; \
1758 memcpy(ptr, (char *)&x, sizeof x); \
1759 } while (0)
1760
1761/* Pack a single item. 'fmt' can be any native format character in
1762 struct module syntax. */
1763static int
1764pack_single(char *ptr, PyObject *item, const char *fmt)
1765{
1766 unsigned PY_LONG_LONG llu;
1767 unsigned long lu;
1768 size_t zu;
1769 PY_LONG_LONG lld;
1770 long ld;
1771 Py_ssize_t zd;
1772 double d;
1773 void *p;
1774
1775 switch (fmt[0]) {
1776 /* signed integers */
1777 case 'b': case 'h': case 'i': case 'l':
1778 ld = pylong_as_ld(item);
1779 if (ld == -1 && PyErr_Occurred())
1780 goto err_occurred;
1781 switch (fmt[0]) {
1782 case 'b':
1783 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1784 *((signed char *)ptr) = (signed char)ld; break;
1785 case 'h':
1786 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1787 PACK_SINGLE(ptr, ld, short); break;
1788 case 'i':
1789 if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1790 PACK_SINGLE(ptr, ld, int); break;
1791 default: /* 'l' */
1792 PACK_SINGLE(ptr, ld, long); break;
1793 }
1794 break;
1795
1796 /* unsigned integers */
1797 case 'B': case 'H': case 'I': case 'L':
1798 lu = pylong_as_lu(item);
1799 if (lu == (unsigned long)-1 && PyErr_Occurred())
1800 goto err_occurred;
1801 switch (fmt[0]) {
1802 case 'B':
1803 if (lu > UCHAR_MAX) goto err_range;
1804 *((unsigned char *)ptr) = (unsigned char)lu; break;
1805 case 'H':
1806 if (lu > USHRT_MAX) goto err_range;
1807 PACK_SINGLE(ptr, lu, unsigned short); break;
1808 case 'I':
1809 if (lu > UINT_MAX) goto err_range;
1810 PACK_SINGLE(ptr, lu, unsigned int); break;
1811 default: /* 'L' */
1812 PACK_SINGLE(ptr, lu, unsigned long); break;
1813 }
1814 break;
1815
1816 /* native 64-bit */
1817 #ifdef HAVE_LONG_LONG
1818 case 'q':
1819 lld = pylong_as_lld(item);
1820 if (lld == -1 && PyErr_Occurred())
1821 goto err_occurred;
1822 PACK_SINGLE(ptr, lld, PY_LONG_LONG);
1823 break;
1824 case 'Q':
1825 llu = pylong_as_llu(item);
1826 if (llu == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
1827 goto err_occurred;
1828 PACK_SINGLE(ptr, llu, unsigned PY_LONG_LONG);
1829 break;
1830 #endif
1831
1832 /* ssize_t and size_t */
1833 case 'n':
1834 zd = pylong_as_zd(item);
1835 if (zd == -1 && PyErr_Occurred())
1836 goto err_occurred;
1837 PACK_SINGLE(ptr, zd, Py_ssize_t);
1838 break;
1839 case 'N':
1840 zu = pylong_as_zu(item);
1841 if (zu == (size_t)-1 && PyErr_Occurred())
1842 goto err_occurred;
1843 PACK_SINGLE(ptr, zu, size_t);
1844 break;
1845
1846 /* floats */
1847 case 'f': case 'd':
1848 d = PyFloat_AsDouble(item);
1849 if (d == -1.0 && PyErr_Occurred())
1850 goto err_occurred;
1851 if (fmt[0] == 'f') {
1852 PACK_SINGLE(ptr, d, float);
1853 }
1854 else {
1855 PACK_SINGLE(ptr, d, double);
1856 }
1857 break;
1858
1859 /* bool */
1860 case '?':
1861 ld = PyObject_IsTrue(item);
1862 if (ld < 0)
1863 return -1; /* preserve original error */
1864 #ifdef HAVE_C99_BOOL
1865 PACK_SINGLE(ptr, ld, _Bool);
1866 #else
1867 PACK_SINGLE(ptr, ld, char);
1868 #endif
1869 break;
1870
1871 /* bytes object */
1872 case 'c':
1873 if (!PyBytes_Check(item))
1874 return type_error_int(fmt);
1875 if (PyBytes_GET_SIZE(item) != 1)
1876 return value_error_int(fmt);
1877 *ptr = PyBytes_AS_STRING(item)[0];
1878 break;
1879
1880 /* pointer */
1881 case 'P':
1882 p = PyLong_AsVoidPtr(item);
1883 if (p == NULL && PyErr_Occurred())
1884 goto err_occurred;
1885 PACK_SINGLE(ptr, p, void *);
1886 break;
1887
1888 /* default */
1889 default: goto err_format;
1890 }
1891
1892 return 0;
1893
1894err_occurred:
1895 return fix_error_int(fmt);
1896err_range:
1897 return value_error_int(fmt);
1898err_format:
1899 PyErr_Format(PyExc_NotImplementedError,
1900 "memoryview: format %s not supported", fmt);
1901 return -1;
1902}
1903
1904
1905/****************************************************************************/
Nick Coghlan06e1ab02012-08-25 17:59:50 +10001906/* unpack using the struct module */
1907/****************************************************************************/
1908
1909/* For reasonable performance it is necessary to cache all objects required
1910 for unpacking. An unpacker can handle the format passed to unpack_from().
1911 Invariant: All pointer fields of the struct should either be NULL or valid
1912 pointers. */
1913struct unpacker {
1914 PyObject *unpack_from; /* Struct.unpack_from(format) */
1915 PyObject *mview; /* cached memoryview */
1916 char *item; /* buffer for mview */
1917 Py_ssize_t itemsize; /* len(item) */
1918};
1919
1920static struct unpacker *
1921unpacker_new(void)
1922{
1923 struct unpacker *x = PyMem_Malloc(sizeof *x);
1924
1925 if (x == NULL) {
1926 PyErr_NoMemory();
1927 return NULL;
1928 }
1929
1930 x->unpack_from = NULL;
1931 x->mview = NULL;
1932 x->item = NULL;
1933 x->itemsize = 0;
1934
1935 return x;
1936}
1937
1938static void
1939unpacker_free(struct unpacker *x)
1940{
1941 if (x) {
1942 Py_XDECREF(x->unpack_from);
1943 Py_XDECREF(x->mview);
1944 PyMem_Free(x->item);
1945 PyMem_Free(x);
1946 }
1947}
1948
1949/* Return a new unpacker for the given format. */
1950static struct unpacker *
1951struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
1952{
1953 PyObject *structmodule; /* XXX cache these two */
1954 PyObject *Struct = NULL; /* XXX in globals? */
1955 PyObject *structobj = NULL;
1956 PyObject *format = NULL;
1957 struct unpacker *x = NULL;
1958
1959 structmodule = PyImport_ImportModule("struct");
1960 if (structmodule == NULL)
1961 return NULL;
1962
1963 Struct = PyObject_GetAttrString(structmodule, "Struct");
1964 Py_DECREF(structmodule);
1965 if (Struct == NULL)
1966 return NULL;
1967
1968 x = unpacker_new();
1969 if (x == NULL)
1970 goto error;
1971
1972 format = PyBytes_FromString(fmt);
1973 if (format == NULL)
1974 goto error;
1975
1976 structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
1977 if (structobj == NULL)
1978 goto error;
1979
1980 x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
1981 if (x->unpack_from == NULL)
1982 goto error;
1983
1984 x->item = PyMem_Malloc(itemsize);
1985 if (x->item == NULL) {
1986 PyErr_NoMemory();
1987 goto error;
1988 }
1989 x->itemsize = itemsize;
1990
1991 x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
1992 if (x->mview == NULL)
1993 goto error;
1994
1995
1996out:
1997 Py_XDECREF(Struct);
1998 Py_XDECREF(format);
1999 Py_XDECREF(structobj);
2000 return x;
2001
2002error:
2003 unpacker_free(x);
2004 x = NULL;
2005 goto out;
2006}
2007
2008/* unpack a single item */
2009static PyObject *
2010struct_unpack_single(const char *ptr, struct unpacker *x)
2011{
2012 PyObject *v;
2013
2014 memcpy(x->item, ptr, x->itemsize);
2015 v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL);
2016 if (v == NULL)
2017 return NULL;
2018
2019 if (PyTuple_GET_SIZE(v) == 1) {
2020 PyObject *tmp = PyTuple_GET_ITEM(v, 0);
2021 Py_INCREF(tmp);
2022 Py_DECREF(v);
2023 return tmp;
2024 }
2025
2026 return v;
2027}
2028
2029
2030/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002031/* Representations */
2032/****************************************************************************/
2033
2034/* allow explicit form of native format */
2035Py_LOCAL_INLINE(const char *)
2036adjust_fmt(const Py_buffer *view)
2037{
2038 const char *fmt;
2039
2040 fmt = (view->format[0] == '@') ? view->format+1 : view->format;
2041 if (fmt[0] && fmt[1] == '\0')
2042 return fmt;
2043
2044 PyErr_Format(PyExc_NotImplementedError,
2045 "memoryview: unsupported format %s", view->format);
2046 return NULL;
2047}
2048
2049/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
2050static PyObject *
2051tolist_base(const char *ptr, const Py_ssize_t *shape,
2052 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2053 const char *fmt)
2054{
2055 PyObject *lst, *item;
2056 Py_ssize_t i;
2057
2058 lst = PyList_New(shape[0]);
2059 if (lst == NULL)
2060 return NULL;
2061
2062 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2063 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2064 item = unpack_single(xptr, fmt);
2065 if (item == NULL) {
2066 Py_DECREF(lst);
2067 return NULL;
2068 }
2069 PyList_SET_ITEM(lst, i, item);
2070 }
2071
2072 return lst;
2073}
2074
2075/* Unpack a multi-dimensional array into a nested list.
2076 Assumption: ndim >= 1. */
2077static PyObject *
2078tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
2079 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2080 const char *fmt)
2081{
2082 PyObject *lst, *item;
2083 Py_ssize_t i;
2084
2085 assert(ndim >= 1);
2086 assert(shape != NULL);
2087 assert(strides != NULL);
2088
2089 if (ndim == 1)
2090 return tolist_base(ptr, shape, strides, suboffsets, fmt);
2091
2092 lst = PyList_New(shape[0]);
2093 if (lst == NULL)
2094 return NULL;
2095
2096 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2097 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2098 item = tolist_rec(xptr, ndim-1, shape+1,
2099 strides+1, suboffsets ? suboffsets+1 : NULL,
2100 fmt);
2101 if (item == NULL) {
2102 Py_DECREF(lst);
2103 return NULL;
2104 }
2105 PyList_SET_ITEM(lst, i, item);
2106 }
2107
2108 return lst;
2109}
2110
2111/* Return a list representation of the memoryview. Currently only buffers
2112 with native format strings are supported. */
2113static PyObject *
2114memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
2115{
2116 const Py_buffer *view = &(mv->view);
2117 const char *fmt;
2118
2119 CHECK_RELEASED(mv);
2120
2121 fmt = adjust_fmt(view);
2122 if (fmt == NULL)
2123 return NULL;
2124 if (view->ndim == 0) {
2125 return unpack_single(view->buf, fmt);
2126 }
2127 else if (view->ndim == 1) {
2128 return tolist_base(view->buf, view->shape,
2129 view->strides, view->suboffsets,
2130 fmt);
2131 }
2132 else {
2133 return tolist_rec(view->buf, view->ndim, view->shape,
2134 view->strides, view->suboffsets,
2135 fmt);
2136 }
2137}
2138
2139static PyObject *
2140memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
2141{
2142 Py_buffer *src = VIEW_ADDR(self);
2143 PyObject *bytes = NULL;
2144
2145 CHECK_RELEASED(self);
2146
2147 if (MV_C_CONTIGUOUS(self->flags)) {
2148 return PyBytes_FromStringAndSize(src->buf, src->len);
2149 }
2150
2151 bytes = PyBytes_FromStringAndSize(NULL, src->len);
2152 if (bytes == NULL)
2153 return NULL;
2154
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002155 if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002156 Py_DECREF(bytes);
2157 return NULL;
2158 }
2159
2160 return bytes;
2161}
2162
2163static PyObject *
2164memory_repr(PyMemoryViewObject *self)
2165{
2166 if (self->flags & _Py_MEMORYVIEW_RELEASED)
2167 return PyUnicode_FromFormat("<released memory at %p>", self);
2168 else
2169 return PyUnicode_FromFormat("<memory at %p>", self);
2170}
2171
2172
2173/**************************************************************************/
2174/* Indexing and slicing */
2175/**************************************************************************/
2176
2177/* Get the pointer to the item at index. */
2178static char *
2179ptr_from_index(Py_buffer *view, Py_ssize_t index)
2180{
2181 char *ptr;
2182 Py_ssize_t nitems; /* items in the first dimension */
2183
2184 assert(view->shape);
2185 assert(view->strides);
2186
2187 nitems = view->shape[0];
2188 if (index < 0) {
2189 index += nitems;
2190 }
2191 if (index < 0 || index >= nitems) {
2192 PyErr_SetString(PyExc_IndexError, "index out of bounds");
2193 return NULL;
2194 }
2195
2196 ptr = (char *)view->buf;
2197 ptr += view->strides[0] * index;
2198
2199 ptr = ADJUST_PTR(ptr, view->suboffsets);
2200
2201 return ptr;
2202}
2203
2204/* Return the item at index. In a one-dimensional view, this is an object
2205 with the type specified by view->format. Otherwise, the item is a sub-view.
2206 The function is used in memory_subscript() and memory_as_sequence. */
2207static PyObject *
2208memory_item(PyMemoryViewObject *self, Py_ssize_t index)
2209{
2210 Py_buffer *view = &(self->view);
2211 const char *fmt;
2212
2213 CHECK_RELEASED(self);
2214
2215 fmt = adjust_fmt(view);
2216 if (fmt == NULL)
2217 return NULL;
2218
2219 if (view->ndim == 0) {
2220 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
2221 return NULL;
2222 }
2223 if (view->ndim == 1) {
2224 char *ptr = ptr_from_index(view, index);
2225 if (ptr == NULL)
2226 return NULL;
2227 return unpack_single(ptr, fmt);
2228 }
2229
2230 PyErr_SetString(PyExc_NotImplementedError,
2231 "multi-dimensional sub-views are not implemented");
2232 return NULL;
2233}
2234
2235Py_LOCAL_INLINE(int)
2236init_slice(Py_buffer *base, PyObject *key, int dim)
2237{
2238 Py_ssize_t start, stop, step, slicelength;
2239
2240 if (PySlice_GetIndicesEx(key, base->shape[dim],
2241 &start, &stop, &step, &slicelength) < 0) {
2242 return -1;
2243 }
2244
2245
2246 if (base->suboffsets == NULL || dim == 0) {
2247 adjust_buf:
2248 base->buf = (char *)base->buf + base->strides[dim] * start;
2249 }
2250 else {
2251 Py_ssize_t n = dim-1;
2252 while (n >= 0 && base->suboffsets[n] < 0)
2253 n--;
2254 if (n < 0)
2255 goto adjust_buf; /* all suboffsets are negative */
2256 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
2257 }
2258 base->shape[dim] = slicelength;
2259 base->strides[dim] = base->strides[dim] * step;
2260
2261 return 0;
2262}
2263
2264static int
2265is_multislice(PyObject *key)
2266{
2267 Py_ssize_t size, i;
2268
2269 if (!PyTuple_Check(key))
2270 return 0;
2271 size = PyTuple_GET_SIZE(key);
2272 if (size == 0)
2273 return 0;
2274
2275 for (i = 0; i < size; i++) {
2276 PyObject *x = PyTuple_GET_ITEM(key, i);
2277 if (!PySlice_Check(x))
2278 return 0;
2279 }
2280 return 1;
2281}
2282
2283/* mv[obj] returns an object holding the data for one element if obj
2284 fully indexes the memoryview or another memoryview object if it
2285 does not.
2286
2287 0-d memoryview objects can be referenced using mv[...] or mv[()]
2288 but not with anything else. */
2289static PyObject *
2290memory_subscript(PyMemoryViewObject *self, PyObject *key)
2291{
2292 Py_buffer *view;
2293 view = &(self->view);
2294
2295 CHECK_RELEASED(self);
2296
2297 if (view->ndim == 0) {
2298 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2299 const char *fmt = adjust_fmt(view);
2300 if (fmt == NULL)
2301 return NULL;
2302 return unpack_single(view->buf, fmt);
2303 }
2304 else if (key == Py_Ellipsis) {
2305 Py_INCREF(self);
2306 return (PyObject *)self;
2307 }
2308 else {
2309 PyErr_SetString(PyExc_TypeError,
2310 "invalid indexing of 0-dim memory");
2311 return NULL;
2312 }
2313 }
2314
2315 if (PyIndex_Check(key)) {
2316 Py_ssize_t index;
2317 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2318 if (index == -1 && PyErr_Occurred())
2319 return NULL;
2320 return memory_item(self, index);
2321 }
2322 else if (PySlice_Check(key)) {
2323 PyMemoryViewObject *sliced;
2324
2325 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2326 if (sliced == NULL)
2327 return NULL;
2328
2329 if (init_slice(&sliced->view, key, 0) < 0) {
2330 Py_DECREF(sliced);
2331 return NULL;
2332 }
2333 init_len(&sliced->view);
2334 init_flags(sliced);
2335
2336 return (PyObject *)sliced;
2337 }
2338 else if (is_multislice(key)) {
2339 PyErr_SetString(PyExc_NotImplementedError,
2340 "multi-dimensional slicing is not implemented");
2341 return NULL;
2342 }
2343
2344 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2345 return NULL;
2346}
2347
2348static int
2349memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2350{
2351 Py_buffer *view = &(self->view);
2352 Py_buffer src;
2353 const char *fmt;
2354 char *ptr;
2355
2356 CHECK_RELEASED_INT(self);
2357
2358 fmt = adjust_fmt(view);
2359 if (fmt == NULL)
2360 return -1;
2361
2362 if (view->readonly) {
2363 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2364 return -1;
2365 }
2366 if (value == NULL) {
2367 PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2368 return -1;
2369 }
2370 if (view->ndim == 0) {
2371 if (key == Py_Ellipsis ||
2372 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2373 ptr = (char *)view->buf;
2374 return pack_single(ptr, value, fmt);
2375 }
2376 else {
2377 PyErr_SetString(PyExc_TypeError,
2378 "invalid indexing of 0-dim memory");
2379 return -1;
2380 }
2381 }
2382 if (view->ndim != 1) {
2383 PyErr_SetString(PyExc_NotImplementedError,
2384 "memoryview assignments are currently restricted to ndim = 1");
2385 return -1;
2386 }
2387
2388 if (PyIndex_Check(key)) {
2389 Py_ssize_t index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2390 if (index == -1 && PyErr_Occurred())
2391 return -1;
2392 ptr = ptr_from_index(view, index);
2393 if (ptr == NULL)
2394 return -1;
2395 return pack_single(ptr, value, fmt);
2396 }
2397 /* one-dimensional: fast path */
2398 if (PySlice_Check(key) && view->ndim == 1) {
2399 Py_buffer dest; /* sliced view */
2400 Py_ssize_t arrays[3];
2401 int ret = -1;
2402
2403 /* rvalue must be an exporter */
2404 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2405 return ret;
2406
2407 dest = *view;
2408 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2409 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2410 if (view->suboffsets) {
2411 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2412 }
2413
2414 if (init_slice(&dest, key, 0) < 0)
2415 goto end_block;
2416 dest.len = dest.shape[0] * dest.itemsize;
2417
2418 ret = copy_single(&dest, &src);
2419
2420 end_block:
2421 PyBuffer_Release(&src);
2422 return ret;
2423 }
2424 else if (PySlice_Check(key) || is_multislice(key)) {
2425 /* Call memory_subscript() to produce a sliced lvalue, then copy
2426 rvalue into lvalue. This is already implemented in _testbuffer.c. */
2427 PyErr_SetString(PyExc_NotImplementedError,
2428 "memoryview slice assignments are currently restricted "
2429 "to ndim = 1");
2430 return -1;
2431 }
2432
2433 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2434 return -1;
2435}
2436
2437static Py_ssize_t
2438memory_length(PyMemoryViewObject *self)
2439{
2440 CHECK_RELEASED_INT(self);
2441 return self->view.ndim == 0 ? 1 : self->view.shape[0];
2442}
2443
2444/* As mapping */
2445static PyMappingMethods memory_as_mapping = {
2446 (lenfunc)memory_length, /* mp_length */
2447 (binaryfunc)memory_subscript, /* mp_subscript */
2448 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
2449};
2450
2451/* As sequence */
2452static PySequenceMethods memory_as_sequence = {
Nick Coghlana0f169c2013-10-02 22:06:54 +10002453 (lenfunc)memory_length, /* sq_length */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002454 0, /* sq_concat */
2455 0, /* sq_repeat */
2456 (ssizeargfunc)memory_item, /* sq_item */
2457};
2458
2459
2460/**************************************************************************/
2461/* Comparisons */
2462/**************************************************************************/
2463
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002464#define MV_COMPARE_EX -1 /* exception */
2465#define MV_COMPARE_NOT_IMPL -2 /* not implemented */
2466
2467/* Translate a StructError to "not equal". Preserve other exceptions. */
2468static int
2469fix_struct_error_int(void)
2470{
2471 assert(PyErr_Occurred());
2472 /* XXX Cannot get at StructError directly? */
2473 if (PyErr_ExceptionMatches(PyExc_ImportError) ||
2474 PyErr_ExceptionMatches(PyExc_MemoryError)) {
2475 return MV_COMPARE_EX;
2476 }
2477 /* StructError: invalid or unknown format -> not equal */
2478 PyErr_Clear();
2479 return 0;
2480}
2481
2482/* Unpack and compare single items of p and q using the struct module. */
2483static int
2484struct_unpack_cmp(const char *p, const char *q,
2485 struct unpacker *unpack_p, struct unpacker *unpack_q)
2486{
2487 PyObject *v, *w;
2488 int ret;
2489
2490 /* At this point any exception from the struct module should not be
2491 StructError, since both formats have been accepted already. */
2492 v = struct_unpack_single(p, unpack_p);
2493 if (v == NULL)
2494 return MV_COMPARE_EX;
2495
2496 w = struct_unpack_single(q, unpack_q);
2497 if (w == NULL) {
2498 Py_DECREF(v);
2499 return MV_COMPARE_EX;
2500 }
2501
2502 /* MV_COMPARE_EX == -1: exceptions are preserved */
2503 ret = PyObject_RichCompareBool(v, w, Py_EQ);
2504 Py_DECREF(v);
2505 Py_DECREF(w);
2506
2507 return ret;
2508}
2509
2510/* Unpack and compare single items of p and q. If both p and q have the same
2511 single element native format, the comparison uses a fast path (gcc creates
2512 a jump table and converts memcpy into simple assignments on x86/x64).
2513
2514 Otherwise, the comparison is delegated to the struct module, which is
2515 30-60x slower. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002516#define CMP_SINGLE(p, q, type) \
2517 do { \
2518 type x; \
2519 type y; \
2520 memcpy((char *)&x, p, sizeof x); \
2521 memcpy((char *)&y, q, sizeof y); \
2522 equal = (x == y); \
2523 } while (0)
2524
2525Py_LOCAL_INLINE(int)
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002526unpack_cmp(const char *p, const char *q, char fmt,
2527 struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002528{
2529 int equal;
2530
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002531 switch (fmt) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002532
2533 /* signed integers and fast path for 'B' */
2534 case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
2535 case 'b': return *((signed char *)p) == *((signed char *)q);
2536 case 'h': CMP_SINGLE(p, q, short); return equal;
2537 case 'i': CMP_SINGLE(p, q, int); return equal;
2538 case 'l': CMP_SINGLE(p, q, long); return equal;
2539
2540 /* boolean */
2541 #ifdef HAVE_C99_BOOL
2542 case '?': CMP_SINGLE(p, q, _Bool); return equal;
2543 #else
2544 case '?': CMP_SINGLE(p, q, char); return equal;
2545 #endif
2546
2547 /* unsigned integers */
2548 case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2549 case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2550 case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2551
2552 /* native 64-bit */
2553 #ifdef HAVE_LONG_LONG
2554 case 'q': CMP_SINGLE(p, q, PY_LONG_LONG); return equal;
2555 case 'Q': CMP_SINGLE(p, q, unsigned PY_LONG_LONG); return equal;
2556 #endif
2557
2558 /* ssize_t and size_t */
2559 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2560 case 'N': CMP_SINGLE(p, q, size_t); return equal;
2561
2562 /* floats */
2563 /* XXX DBL_EPSILON? */
2564 case 'f': CMP_SINGLE(p, q, float); return equal;
2565 case 'd': CMP_SINGLE(p, q, double); return equal;
2566
2567 /* bytes object */
2568 case 'c': return *p == *q;
2569
2570 /* pointer */
2571 case 'P': CMP_SINGLE(p, q, void *); return equal;
2572
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002573 /* use the struct module */
2574 case '_':
2575 assert(unpack_p);
2576 assert(unpack_q);
2577 return struct_unpack_cmp(p, q, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002578 }
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002579
2580 /* NOT REACHED */
2581 PyErr_SetString(PyExc_RuntimeError,
2582 "memoryview: internal error in richcompare");
2583 return MV_COMPARE_EX;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002584}
2585
2586/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2587static int
2588cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2589 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2590 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002591 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002592{
2593 Py_ssize_t i;
2594 int equal;
2595
2596 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2597 const char *xp = ADJUST_PTR(p, psuboffsets);
2598 const char *xq = ADJUST_PTR(q, qsuboffsets);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002599 equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002600 if (equal <= 0)
2601 return equal;
2602 }
2603
2604 return 1;
2605}
2606
2607/* Recursively compare two multi-dimensional arrays that have the same
2608 logical structure. Assumption: ndim >= 1. */
2609static int
2610cmp_rec(const char *p, const char *q,
2611 Py_ssize_t ndim, const Py_ssize_t *shape,
2612 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2613 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002614 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002615{
2616 Py_ssize_t i;
2617 int equal;
2618
2619 assert(ndim >= 1);
2620 assert(shape != NULL);
2621 assert(pstrides != NULL);
2622 assert(qstrides != NULL);
2623
2624 if (ndim == 1) {
2625 return cmp_base(p, q, shape,
2626 pstrides, psuboffsets,
2627 qstrides, qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002628 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002629 }
2630
2631 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2632 const char *xp = ADJUST_PTR(p, psuboffsets);
2633 const char *xq = ADJUST_PTR(q, qsuboffsets);
2634 equal = cmp_rec(xp, xq, ndim-1, shape+1,
2635 pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2636 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002637 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002638 if (equal <= 0)
2639 return equal;
2640 }
2641
2642 return 1;
2643}
2644
2645static PyObject *
2646memory_richcompare(PyObject *v, PyObject *w, int op)
2647{
2648 PyObject *res;
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002649 Py_buffer wbuf, *vv;
2650 Py_buffer *ww = NULL;
2651 struct unpacker *unpack_v = NULL;
2652 struct unpacker *unpack_w = NULL;
2653 char vfmt, wfmt;
2654 int equal = MV_COMPARE_NOT_IMPL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002655
2656 if (op != Py_EQ && op != Py_NE)
2657 goto result; /* Py_NotImplemented */
2658
2659 assert(PyMemoryView_Check(v));
2660 if (BASE_INACCESSIBLE(v)) {
2661 equal = (v == w);
2662 goto result;
2663 }
2664 vv = VIEW_ADDR(v);
2665
2666 if (PyMemoryView_Check(w)) {
2667 if (BASE_INACCESSIBLE(w)) {
2668 equal = (v == w);
2669 goto result;
2670 }
2671 ww = VIEW_ADDR(w);
2672 }
2673 else {
2674 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2675 PyErr_Clear();
2676 goto result; /* Py_NotImplemented */
2677 }
2678 ww = &wbuf;
2679 }
2680
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002681 if (!equiv_shape(vv, ww)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002682 PyErr_Clear();
2683 equal = 0;
2684 goto result;
2685 }
2686
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002687 /* Use fast unpacking for identical primitive C type formats. */
2688 if (get_native_fmtchar(&vfmt, vv->format) < 0)
2689 vfmt = '_';
2690 if (get_native_fmtchar(&wfmt, ww->format) < 0)
2691 wfmt = '_';
2692 if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
2693 /* Use struct module unpacking. NOTE: Even for equal format strings,
2694 memcmp() cannot be used for item comparison since it would give
2695 incorrect results in the case of NaNs or uninitialized padding
2696 bytes. */
2697 vfmt = '_';
2698 unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
2699 if (unpack_v == NULL) {
2700 equal = fix_struct_error_int();
2701 goto result;
2702 }
2703 unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
2704 if (unpack_w == NULL) {
2705 equal = fix_struct_error_int();
2706 goto result;
2707 }
2708 }
2709
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002710 if (vv->ndim == 0) {
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002711 equal = unpack_cmp(vv->buf, ww->buf,
2712 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002713 }
2714 else if (vv->ndim == 1) {
2715 equal = cmp_base(vv->buf, ww->buf, vv->shape,
2716 vv->strides, vv->suboffsets,
2717 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002718 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002719 }
2720 else {
2721 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2722 vv->strides, vv->suboffsets,
2723 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002724 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002725 }
2726
2727result:
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002728 if (equal < 0) {
2729 if (equal == MV_COMPARE_NOT_IMPL)
2730 res = Py_NotImplemented;
2731 else /* exception */
2732 res = NULL;
2733 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002734 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2735 res = Py_True;
2736 else
2737 res = Py_False;
2738
2739 if (ww == &wbuf)
2740 PyBuffer_Release(ww);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002741
2742 unpacker_free(unpack_v);
2743 unpacker_free(unpack_w);
2744
2745 Py_XINCREF(res);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002746 return res;
2747}
2748
2749/**************************************************************************/
2750/* Hash */
2751/**************************************************************************/
2752
2753static Py_hash_t
2754memory_hash(PyMemoryViewObject *self)
2755{
2756 if (self->hash == -1) {
2757 Py_buffer *view = &self->view;
2758 char *mem = view->buf;
Stefan Krah4af77a02012-11-02 17:49:22 +01002759 Py_ssize_t ret;
2760 char fmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002761
2762 CHECK_RELEASED_INT(self);
2763
2764 if (!view->readonly) {
2765 PyErr_SetString(PyExc_ValueError,
2766 "cannot hash writable memoryview object");
2767 return -1;
2768 }
Stefan Krah4af77a02012-11-02 17:49:22 +01002769 ret = get_native_fmtchar(&fmt, view->format);
2770 if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
2771 PyErr_SetString(PyExc_ValueError,
2772 "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
2773 return -1;
2774 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002775 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2776 /* Keep the original error message */
2777 return -1;
2778 }
2779
2780 if (!MV_C_CONTIGUOUS(self->flags)) {
2781 mem = PyMem_Malloc(view->len);
2782 if (mem == NULL) {
2783 PyErr_NoMemory();
2784 return -1;
2785 }
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002786 if (buffer_to_contiguous(mem, view, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002787 PyMem_Free(mem);
2788 return -1;
2789 }
2790 }
2791
2792 /* Can't fail */
Christian Heimes985ecdc2013-11-20 11:46:18 +01002793 self->hash = _Py_HashBytes(mem, view->len);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002794
2795 if (mem != view->buf)
2796 PyMem_Free(mem);
2797 }
2798
2799 return self->hash;
2800}
2801
2802
2803/**************************************************************************/
2804/* getters */
2805/**************************************************************************/
2806
2807static PyObject *
2808_IntTupleFromSsizet(int len, Py_ssize_t *vals)
2809{
2810 int i;
2811 PyObject *o;
2812 PyObject *intTuple;
2813
2814 if (vals == NULL)
2815 return PyTuple_New(0);
2816
2817 intTuple = PyTuple_New(len);
2818 if (!intTuple)
2819 return NULL;
2820 for (i=0; i<len; i++) {
2821 o = PyLong_FromSsize_t(vals[i]);
2822 if (!o) {
2823 Py_DECREF(intTuple);
2824 return NULL;
2825 }
2826 PyTuple_SET_ITEM(intTuple, i, o);
2827 }
2828 return intTuple;
2829}
2830
2831static PyObject *
2832memory_obj_get(PyMemoryViewObject *self)
2833{
2834 Py_buffer *view = &self->view;
2835
2836 CHECK_RELEASED(self);
2837 if (view->obj == NULL) {
2838 Py_RETURN_NONE;
2839 }
2840 Py_INCREF(view->obj);
2841 return view->obj;
2842}
2843
2844static PyObject *
2845memory_nbytes_get(PyMemoryViewObject *self)
2846{
2847 CHECK_RELEASED(self);
2848 return PyLong_FromSsize_t(self->view.len);
2849}
2850
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002851static PyObject *
2852memory_format_get(PyMemoryViewObject *self)
2853{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002854 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002855 return PyUnicode_FromString(self->view.format);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002856}
2857
2858static PyObject *
2859memory_itemsize_get(PyMemoryViewObject *self)
2860{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002861 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002862 return PyLong_FromSsize_t(self->view.itemsize);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002863}
2864
2865static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002866memory_shape_get(PyMemoryViewObject *self)
2867{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002868 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002869 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002870}
2871
2872static PyObject *
2873memory_strides_get(PyMemoryViewObject *self)
2874{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002875 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002876 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002877}
2878
2879static PyObject *
2880memory_suboffsets_get(PyMemoryViewObject *self)
2881{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002882 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002883 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002884}
2885
2886static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002887memory_readonly_get(PyMemoryViewObject *self)
2888{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002889 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002890 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002891}
2892
2893static PyObject *
2894memory_ndim_get(PyMemoryViewObject *self)
2895{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002896 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002897 return PyLong_FromLong(self->view.ndim);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002898}
2899
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002900static PyObject *
2901memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2902{
2903 CHECK_RELEASED(self);
2904 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
2905}
2906
2907static PyObject *
2908memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2909{
2910 CHECK_RELEASED(self);
2911 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
2912}
2913
2914static PyObject *
2915memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2916{
2917 CHECK_RELEASED(self);
2918 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
2919}
2920
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002921PyDoc_STRVAR(memory_obj_doc,
2922 "The underlying object of the memoryview.");
2923PyDoc_STRVAR(memory_nbytes_doc,
2924 "The amount of space in bytes that the array would use in\n"
2925 " a contiguous representation.");
2926PyDoc_STRVAR(memory_readonly_doc,
2927 "A bool indicating whether the memory is read only.");
2928PyDoc_STRVAR(memory_itemsize_doc,
2929 "The size in bytes of each element of the memoryview.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002930PyDoc_STRVAR(memory_format_doc,
2931 "A string containing the format (in struct module style)\n"
2932 " for each element in the view.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002933PyDoc_STRVAR(memory_ndim_doc,
2934 "An integer indicating how many dimensions of a multi-dimensional\n"
2935 " array the memory represents.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002936PyDoc_STRVAR(memory_shape_doc,
2937 "A tuple of ndim integers giving the shape of the memory\n"
2938 " as an N-dimensional array.");
2939PyDoc_STRVAR(memory_strides_doc,
2940 "A tuple of ndim integers giving the size in bytes to access\n"
2941 " each element for each dimension of the array.");
2942PyDoc_STRVAR(memory_suboffsets_doc,
2943 "A tuple of integers used internally for PIL-style arrays.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002944PyDoc_STRVAR(memory_c_contiguous_doc,
2945 "A bool indicating whether the memory is C contiguous.");
2946PyDoc_STRVAR(memory_f_contiguous_doc,
2947 "A bool indicating whether the memory is Fortran contiguous.");
2948PyDoc_STRVAR(memory_contiguous_doc,
2949 "A bool indicating whether the memory is contiguous.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002950
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002951static PyGetSetDef memory_getsetlist[] = {
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002952 {"obj", (getter)memory_obj_get, NULL, memory_obj_doc},
2953 {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc},
Alexander Belopolskye370c382012-09-03 16:43:55 -04002954 {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc},
2955 {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc},
2956 {"format", (getter)memory_format_get, NULL, memory_format_doc},
2957 {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc},
2958 {"shape", (getter)memory_shape_get, NULL, memory_shape_doc},
2959 {"strides", (getter)memory_strides_get, NULL, memory_strides_doc},
2960 {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002961 {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc},
2962 {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc},
2963 {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc},
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002964 {NULL, NULL, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002965};
2966
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002967PyDoc_STRVAR(memory_release_doc,
2968"M.release() -> None\n\
2969\n\
2970Release the underlying buffer exposed by the memoryview object.");
2971PyDoc_STRVAR(memory_tobytes_doc,
2972"M.tobytes() -> bytes\n\
2973\n\
2974Return the data in the buffer as a byte string.");
2975PyDoc_STRVAR(memory_tolist_doc,
2976"M.tolist() -> list\n\
2977\n\
2978Return the data in the buffer as a list of elements.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002979PyDoc_STRVAR(memory_cast_doc,
2980"M.cast(format[, shape]) -> memoryview\n\
2981\n\
2982Cast a memoryview to a new format or shape.");
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002983
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002984static PyMethodDef memory_methods[] = {
Alexander Belopolskye370c382012-09-03 16:43:55 -04002985 {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
2986 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc},
2987 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002988 {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
Stefan Krahe4c07992012-07-28 14:10:02 +02002989 {"__enter__", memory_enter, METH_NOARGS, NULL},
2990 {"__exit__", memory_exit, METH_VARARGS, NULL},
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002991 {NULL, NULL}
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002992};
2993
2994
2995PyTypeObject PyMemoryView_Type = {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002996 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002997 "memoryview", /* tp_name */
2998 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */
2999 sizeof(Py_ssize_t), /* tp_itemsize */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003000 (destructor)memory_dealloc, /* tp_dealloc */
3001 0, /* tp_print */
3002 0, /* tp_getattr */
3003 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003004 0, /* tp_reserved */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003005 (reprfunc)memory_repr, /* tp_repr */
3006 0, /* tp_as_number */
Raymond Hettinger159eac92009-06-23 20:38:54 +00003007 &memory_as_sequence, /* tp_as_sequence */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003008 &memory_as_mapping, /* tp_as_mapping */
Antoine Pitrouce4a9da2011-11-21 20:46:33 +01003009 (hashfunc)memory_hash, /* tp_hash */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003010 0, /* tp_call */
Benjamin Peterson87618552009-02-08 15:00:52 +00003011 0, /* tp_str */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003012 PyObject_GenericGetAttr, /* tp_getattro */
3013 0, /* tp_setattro */
3014 &memory_as_buffer, /* tp_as_buffer */
3015 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3016 memory_doc, /* tp_doc */
3017 (traverseproc)memory_traverse, /* tp_traverse */
3018 (inquiry)memory_clear, /* tp_clear */
3019 memory_richcompare, /* tp_richcompare */
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01003020 offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003021 0, /* tp_iter */
3022 0, /* tp_iternext */
3023 memory_methods, /* tp_methods */
3024 0, /* tp_members */
3025 memory_getsetlist, /* tp_getset */
3026 0, /* tp_base */
3027 0, /* tp_dict */
3028 0, /* tp_descr_get */
3029 0, /* tp_descr_set */
3030 0, /* tp_dictoffset */
3031 0, /* tp_init */
3032 0, /* tp_alloc */
3033 memory_new, /* tp_new */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003034};