blob: d56faf87cc427648d5a04196ccf6a4a40603056e [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,
310 "ndarray assignment: lvalue and rvalue have different structures");
311 return 0;
312 }
313
314 return 1;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100315}
316
317/* Base case for recursive multi-dimensional copying. Contiguous arrays are
318 copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
319 sizeof(mem) == shape[0] * itemsize. */
320static void
321copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
322 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
323 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
324 char *mem)
325{
326 if (mem == NULL) { /* contiguous */
327 Py_ssize_t size = shape[0] * itemsize;
328 if (dptr + size < sptr || sptr + size < dptr)
329 memcpy(dptr, sptr, size); /* no overlapping */
330 else
331 memmove(dptr, sptr, size);
332 }
333 else {
334 char *p;
335 Py_ssize_t i;
336 for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
337 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
338 memcpy(p, xsptr, itemsize);
339 }
340 for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
341 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
342 memcpy(xdptr, p, itemsize);
343 }
344 }
345
346}
347
348/* Recursively copy a source buffer to a destination buffer. The two buffers
349 have the same ndim, shape and itemsize. */
350static void
351copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
352 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
353 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
354 char *mem)
355{
356 Py_ssize_t i;
357
358 assert(ndim >= 1);
359
360 if (ndim == 1) {
361 copy_base(shape, itemsize,
362 dptr, dstrides, dsuboffsets,
363 sptr, sstrides, ssuboffsets,
364 mem);
365 return;
366 }
367
368 for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
369 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
370 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
371
372 copy_rec(shape+1, ndim-1, itemsize,
373 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
374 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
375 mem);
376 }
377}
378
379/* Faster copying of one-dimensional arrays. */
380static int
381copy_single(Py_buffer *dest, Py_buffer *src)
382{
383 char *mem = NULL;
384
385 assert(dest->ndim == 1);
386
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000387 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100388 return -1;
389
390 if (!last_dim_is_contiguous(dest, src)) {
391 mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
392 if (mem == NULL) {
393 PyErr_NoMemory();
394 return -1;
395 }
396 }
397
398 copy_base(dest->shape, dest->itemsize,
399 dest->buf, dest->strides, dest->suboffsets,
400 src->buf, src->strides, src->suboffsets,
401 mem);
402
403 if (mem)
404 PyMem_Free(mem);
405
406 return 0;
407}
408
409/* Recursively copy src to dest. Both buffers must have the same basic
410 structure. Copying is atomic, the function never fails with a partial
411 copy. */
412static int
413copy_buffer(Py_buffer *dest, Py_buffer *src)
414{
415 char *mem = NULL;
416
417 assert(dest->ndim > 0);
418
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000419 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100420 return -1;
421
422 if (!last_dim_is_contiguous(dest, src)) {
423 mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
424 if (mem == NULL) {
425 PyErr_NoMemory();
426 return -1;
427 }
428 }
429
430 copy_rec(dest->shape, dest->ndim, dest->itemsize,
431 dest->buf, dest->strides, dest->suboffsets,
432 src->buf, src->strides, src->suboffsets,
433 mem);
434
435 if (mem)
436 PyMem_Free(mem);
437
438 return 0;
439}
440
441/* Initialize strides for a C-contiguous array. */
442Py_LOCAL_INLINE(void)
443init_strides_from_shape(Py_buffer *view)
444{
445 Py_ssize_t i;
446
447 assert(view->ndim > 0);
448
449 view->strides[view->ndim-1] = view->itemsize;
450 for (i = view->ndim-2; i >= 0; i--)
451 view->strides[i] = view->strides[i+1] * view->shape[i+1];
452}
453
454/* Initialize strides for a Fortran-contiguous array. */
455Py_LOCAL_INLINE(void)
456init_fortran_strides_from_shape(Py_buffer *view)
457{
458 Py_ssize_t i;
459
460 assert(view->ndim > 0);
461
462 view->strides[0] = view->itemsize;
463 for (i = 1; i < view->ndim; i++)
464 view->strides[i] = view->strides[i-1] * view->shape[i-1];
465}
466
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200467/* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran)
468 or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100469 len(mem) == src->len. */
470static int
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200471buffer_to_contiguous(char *mem, Py_buffer *src, char order)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100472{
473 Py_buffer dest;
474 Py_ssize_t *strides;
475 int ret;
476
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200477 assert(src->ndim >= 1);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100478 assert(src->shape != NULL);
479 assert(src->strides != NULL);
480
481 strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
482 if (strides == NULL) {
483 PyErr_NoMemory();
484 return -1;
485 }
486
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200487 /* initialize dest */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100488 dest = *src;
489 dest.buf = mem;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200490 /* shape is constant and shared: the logical representation of the
491 array is unaltered. */
492
493 /* The physical representation determined by strides (and possibly
494 suboffsets) may change. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100495 dest.strides = strides;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200496 if (order == 'C' || order == 'A') {
497 init_strides_from_shape(&dest);
498 }
499 else {
500 init_fortran_strides_from_shape(&dest);
501 }
502
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100503 dest.suboffsets = NULL;
504
505 ret = copy_buffer(&dest, src);
506
507 PyMem_Free(strides);
508 return ret;
509}
510
511
512/****************************************************************************/
513/* Constructors */
514/****************************************************************************/
515
516/* Initialize values that are shared with the managed buffer. */
517Py_LOCAL_INLINE(void)
518init_shared_values(Py_buffer *dest, const Py_buffer *src)
519{
520 dest->obj = src->obj;
521 dest->buf = src->buf;
522 dest->len = src->len;
523 dest->itemsize = src->itemsize;
524 dest->readonly = src->readonly;
525 dest->format = src->format ? src->format : "B";
526 dest->internal = src->internal;
527}
528
529/* Copy shape and strides. Reconstruct missing values. */
530static void
531init_shape_strides(Py_buffer *dest, const Py_buffer *src)
532{
533 Py_ssize_t i;
534
535 if (src->ndim == 0) {
536 dest->shape = NULL;
537 dest->strides = NULL;
538 return;
539 }
540 if (src->ndim == 1) {
541 dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
542 dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
543 return;
544 }
545
546 for (i = 0; i < src->ndim; i++)
547 dest->shape[i] = src->shape[i];
548 if (src->strides) {
549 for (i = 0; i < src->ndim; i++)
550 dest->strides[i] = src->strides[i];
551 }
552 else {
553 init_strides_from_shape(dest);
554 }
555}
556
557Py_LOCAL_INLINE(void)
558init_suboffsets(Py_buffer *dest, const Py_buffer *src)
559{
560 Py_ssize_t i;
561
562 if (src->suboffsets == NULL) {
563 dest->suboffsets = NULL;
564 return;
565 }
566 for (i = 0; i < src->ndim; i++)
567 dest->suboffsets[i] = src->suboffsets[i];
568}
569
570/* len = product(shape) * itemsize */
571Py_LOCAL_INLINE(void)
572init_len(Py_buffer *view)
573{
574 Py_ssize_t i, len;
575
576 len = 1;
577 for (i = 0; i < view->ndim; i++)
578 len *= view->shape[i];
579 len *= view->itemsize;
580
581 view->len = len;
582}
583
584/* Initialize memoryview buffer properties. */
585static void
586init_flags(PyMemoryViewObject *mv)
587{
588 const Py_buffer *view = &mv->view;
589 int flags = 0;
590
591 switch (view->ndim) {
592 case 0:
593 flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
594 _Py_MEMORYVIEW_FORTRAN);
595 break;
596 case 1:
597 if (MV_CONTIGUOUS_NDIM1(view))
598 flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
599 break;
600 default:
601 if (PyBuffer_IsContiguous(view, 'C'))
602 flags |= _Py_MEMORYVIEW_C;
603 if (PyBuffer_IsContiguous(view, 'F'))
604 flags |= _Py_MEMORYVIEW_FORTRAN;
605 break;
606 }
607
608 if (view->suboffsets) {
609 flags |= _Py_MEMORYVIEW_PIL;
610 flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
611 }
612
613 mv->flags = flags;
614}
615
616/* Allocate a new memoryview and perform basic initialization. New memoryviews
617 are exclusively created through the mbuf_add functions. */
618Py_LOCAL_INLINE(PyMemoryViewObject *)
619memory_alloc(int ndim)
620{
621 PyMemoryViewObject *mv;
622
623 mv = (PyMemoryViewObject *)
624 PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
625 if (mv == NULL)
626 return NULL;
627
628 mv->mbuf = NULL;
629 mv->hash = -1;
630 mv->flags = 0;
631 mv->exports = 0;
632 mv->view.ndim = ndim;
633 mv->view.shape = mv->ob_array;
634 mv->view.strides = mv->ob_array + ndim;
635 mv->view.suboffsets = mv->ob_array + 2 * ndim;
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +0100636 mv->weakreflist = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100637
638 _PyObject_GC_TRACK(mv);
639 return mv;
640}
641
642/*
643 Return a new memoryview that is registered with mbuf. If src is NULL,
644 use mbuf->master as the underlying buffer. Otherwise, use src.
645
646 The new memoryview has full buffer information: shape and strides
647 are always present, suboffsets as needed. Arrays are copied to
648 the memoryview's ob_array field.
649 */
650static PyObject *
651mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
652{
653 PyMemoryViewObject *mv;
654 Py_buffer *dest;
655
656 if (src == NULL)
657 src = &mbuf->master;
658
659 if (src->ndim > PyBUF_MAX_NDIM) {
660 PyErr_SetString(PyExc_ValueError,
661 "memoryview: number of dimensions must not exceed "
662 STRINGIZE(PyBUF_MAX_NDIM));
663 return NULL;
664 }
665
666 mv = memory_alloc(src->ndim);
667 if (mv == NULL)
668 return NULL;
669
670 dest = &mv->view;
671 init_shared_values(dest, src);
672 init_shape_strides(dest, src);
673 init_suboffsets(dest, src);
674 init_flags(mv);
675
676 mv->mbuf = mbuf;
677 Py_INCREF(mbuf);
678 mbuf->exports++;
679
680 return (PyObject *)mv;
681}
682
683/* Register an incomplete view: shape, strides, suboffsets and flags still
684 need to be initialized. Use 'ndim' instead of src->ndim to determine the
685 size of the memoryview's ob_array.
686
687 Assumption: ndim <= PyBUF_MAX_NDIM. */
688static PyObject *
689mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
690 int ndim)
691{
692 PyMemoryViewObject *mv;
693 Py_buffer *dest;
694
695 if (src == NULL)
696 src = &mbuf->master;
697
698 assert(ndim <= PyBUF_MAX_NDIM);
699
700 mv = memory_alloc(ndim);
701 if (mv == NULL)
702 return NULL;
703
704 dest = &mv->view;
705 init_shared_values(dest, src);
706
707 mv->mbuf = mbuf;
708 Py_INCREF(mbuf);
709 mbuf->exports++;
710
711 return (PyObject *)mv;
712}
713
714/* Expose a raw memory area as a view of contiguous bytes. flags can be
715 PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
716 The memoryview has complete buffer information. */
717PyObject *
718PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
719{
720 _PyManagedBufferObject *mbuf;
721 PyObject *mv;
722 int readonly;
723
724 assert(mem != NULL);
725 assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
726
727 mbuf = mbuf_alloc();
728 if (mbuf == NULL)
729 return NULL;
730
731 readonly = (flags == PyBUF_WRITE) ? 0 : 1;
732 (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
733 PyBUF_FULL_RO);
734
735 mv = mbuf_add_view(mbuf, NULL);
736 Py_DECREF(mbuf);
737
738 return mv;
739}
740
741/* Create a memoryview from a given Py_buffer. For simple byte views,
742 PyMemoryView_FromMemory() should be used instead.
743 This function is the only entry point that can create a master buffer
744 without full information. Because of this fact init_shape_strides()
745 must be able to reconstruct missing values. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000746PyObject *
Antoine Pitrouee58fa42008-08-19 18:22:14 +0000747PyMemoryView_FromBuffer(Py_buffer *info)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000748{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100749 _PyManagedBufferObject *mbuf;
750 PyObject *mv;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000751
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000752 if (info->buf == NULL) {
753 PyErr_SetString(PyExc_ValueError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100754 "PyMemoryView_FromBuffer(): info->buf must not be NULL");
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000755 return NULL;
756 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100757
758 mbuf = mbuf_alloc();
759 if (mbuf == NULL)
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000760 return NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100761
762 /* info->obj is either NULL or a borrowed reference. This reference
763 should not be decremented in PyBuffer_Release(). */
764 mbuf->master = *info;
765 mbuf->master.obj = NULL;
766
767 mv = mbuf_add_view(mbuf, NULL);
768 Py_DECREF(mbuf);
769
770 return mv;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000771}
772
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100773/* Create a memoryview from an object that implements the buffer protocol.
774 If the object is a memoryview, the new memoryview must be registered
775 with the same managed buffer. Otherwise, a new managed buffer is created. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000776PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100777PyMemoryView_FromObject(PyObject *v)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000778{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100779 _PyManagedBufferObject *mbuf;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000780
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100781 if (PyMemoryView_Check(v)) {
782 PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
783 CHECK_RELEASED(mv);
784 return mbuf_add_view(mv->mbuf, &mv->view);
785 }
786 else if (PyObject_CheckBuffer(v)) {
787 PyObject *ret;
788 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
789 if (mbuf == NULL)
790 return NULL;
791 ret = mbuf_add_view(mbuf, NULL);
792 Py_DECREF(mbuf);
793 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000794 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000795
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100796 PyErr_Format(PyExc_TypeError,
797 "memoryview: %.200s object does not have the buffer interface",
798 Py_TYPE(v)->tp_name);
799 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000800}
801
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100802/* Copy the format string from a base object that might vanish. */
803static int
804mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
805{
806 if (fmt != NULL) {
807 char *cp = PyMem_Malloc(strlen(fmt)+1);
808 if (cp == NULL) {
809 PyErr_NoMemory();
810 return -1;
811 }
812 mbuf->master.format = strcpy(cp, fmt);
813 mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
814 }
815
816 return 0;
817}
818
819/*
820 Return a memoryview that is based on a contiguous copy of src.
821 Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
822
823 Ownership rules:
824 1) As usual, the returned memoryview has a private copy
825 of src->shape, src->strides and src->suboffsets.
826 2) src->format is copied to the master buffer and released
827 in mbuf_dealloc(). The releasebufferproc of the bytes
828 object is NULL, so it does not matter that mbuf_release()
829 passes the altered format pointer to PyBuffer_Release().
830*/
831static PyObject *
832memory_from_contiguous_copy(Py_buffer *src, char order)
833{
834 _PyManagedBufferObject *mbuf;
835 PyMemoryViewObject *mv;
836 PyObject *bytes;
837 Py_buffer *dest;
838 int i;
839
840 assert(src->ndim > 0);
841 assert(src->shape != NULL);
842
843 bytes = PyBytes_FromStringAndSize(NULL, src->len);
844 if (bytes == NULL)
845 return NULL;
846
847 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
848 Py_DECREF(bytes);
849 if (mbuf == NULL)
850 return NULL;
851
852 if (mbuf_copy_format(mbuf, src->format) < 0) {
853 Py_DECREF(mbuf);
854 return NULL;
855 }
856
857 mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
858 Py_DECREF(mbuf);
859 if (mv == NULL)
860 return NULL;
861
862 dest = &mv->view;
863
864 /* shared values are initialized correctly except for itemsize */
865 dest->itemsize = src->itemsize;
866
867 /* shape and strides */
868 for (i = 0; i < src->ndim; i++) {
869 dest->shape[i] = src->shape[i];
870 }
871 if (order == 'C' || order == 'A') {
872 init_strides_from_shape(dest);
873 }
874 else {
875 init_fortran_strides_from_shape(dest);
876 }
877 /* suboffsets */
878 dest->suboffsets = NULL;
879
880 /* flags */
881 init_flags(mv);
882
883 if (copy_buffer(dest, src) < 0) {
884 Py_DECREF(mv);
885 return NULL;
886 }
887
888 return (PyObject *)mv;
889}
890
891/*
892 Return a new memoryview object based on a contiguous exporter with
893 buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
894 The logical structure of the input and output buffers is the same
895 (i.e. tolist(input) == tolist(output)), but the physical layout in
896 memory can be explicitly chosen.
897
898 As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
899 otherwise it may be writable or read-only.
900
901 If the exporter is already contiguous with the desired target order,
902 the memoryview will be directly based on the exporter.
903
904 Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
905 based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
906 'F'ortran order otherwise.
907*/
908PyObject *
909PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
910{
911 PyMemoryViewObject *mv;
912 PyObject *ret;
913 Py_buffer *view;
914
915 assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
916 assert(order == 'C' || order == 'F' || order == 'A');
917
918 mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
919 if (mv == NULL)
920 return NULL;
921
922 view = &mv->view;
923 if (buffertype == PyBUF_WRITE && view->readonly) {
924 PyErr_SetString(PyExc_BufferError,
925 "underlying buffer is not writable");
926 Py_DECREF(mv);
927 return NULL;
928 }
929
930 if (PyBuffer_IsContiguous(view, order))
931 return (PyObject *)mv;
932
933 if (buffertype == PyBUF_WRITE) {
934 PyErr_SetString(PyExc_BufferError,
935 "writable contiguous buffer requested "
936 "for a non-contiguous object.");
937 Py_DECREF(mv);
938 return NULL;
939 }
940
941 ret = memory_from_contiguous_copy(view, order);
942 Py_DECREF(mv);
943 return ret;
944}
945
946
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000947static PyObject *
948memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
949{
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000950 PyObject *obj;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100951 static char *kwlist[] = {"object", NULL};
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000952
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000953 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
954 &obj)) {
955 return NULL;
956 }
Christian Heimes7b6fc8e2007-11-08 02:28:11 +0000957
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000958 return PyMemoryView_FromObject(obj);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000959}
960
961
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100962/****************************************************************************/
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200963/* Previously in abstract.c */
964/****************************************************************************/
965
966typedef struct {
967 Py_buffer view;
968 Py_ssize_t array[1];
969} Py_buffer_full;
970
971int
972PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
973{
974 Py_buffer_full *fb = NULL;
975 int ret;
976
977 assert(order == 'C' || order == 'F' || order == 'A');
978
979 if (len != src->len) {
980 PyErr_SetString(PyExc_ValueError,
981 "PyBuffer_ToContiguous: len != view->len");
982 return -1;
983 }
984
985 if (PyBuffer_IsContiguous(src, order)) {
986 memcpy((char *)buf, src->buf, len);
987 return 0;
988 }
989
990 /* buffer_to_contiguous() assumes PyBUF_FULL */
991 fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array));
992 if (fb == NULL) {
993 PyErr_NoMemory();
994 return -1;
995 }
996 fb->view.ndim = src->ndim;
997 fb->view.shape = fb->array;
998 fb->view.strides = fb->array + src->ndim;
999 fb->view.suboffsets = fb->array + 2 * src->ndim;
1000
1001 init_shared_values(&fb->view, src);
1002 init_shape_strides(&fb->view, src);
1003 init_suboffsets(&fb->view, src);
1004
1005 src = &fb->view;
1006
1007 ret = buffer_to_contiguous(buf, src, order);
1008 PyMem_Free(fb);
1009 return ret;
1010}
1011
1012
1013/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001014/* Release/GC management */
1015/****************************************************************************/
1016
1017/* Inform the managed buffer that this particular memoryview will not access
1018 the underlying buffer again. If no other memoryviews are registered with
1019 the managed buffer, the underlying buffer is released instantly and
1020 marked as inaccessible for both the memoryview and the managed buffer.
1021
1022 This function fails if the memoryview itself has exported buffers. */
1023static int
1024_memory_release(PyMemoryViewObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001025{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001026 if (self->flags & _Py_MEMORYVIEW_RELEASED)
1027 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001028
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001029 if (self->exports == 0) {
1030 self->flags |= _Py_MEMORYVIEW_RELEASED;
1031 assert(self->mbuf->exports > 0);
1032 if (--self->mbuf->exports == 0)
1033 mbuf_release(self->mbuf);
1034 return 0;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001035 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001036 if (self->exports > 0) {
1037 PyErr_Format(PyExc_BufferError,
1038 "memoryview has %zd exported buffer%s", self->exports,
1039 self->exports==1 ? "" : "s");
1040 return -1;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001041 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001042
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001043 Py_FatalError("_memory_release(): negative export count");
1044 return -1;
1045}
1046
1047static PyObject *
Stefan Krahe4c07992012-07-28 14:10:02 +02001048memory_release(PyMemoryViewObject *self, PyObject *noargs)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001049{
1050 if (_memory_release(self) < 0)
1051 return NULL;
1052 Py_RETURN_NONE;
1053}
1054
1055static void
1056memory_dealloc(PyMemoryViewObject *self)
1057{
1058 assert(self->exports == 0);
1059 _PyObject_GC_UNTRACK(self);
1060 (void)_memory_release(self);
1061 Py_CLEAR(self->mbuf);
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01001062 if (self->weakreflist != NULL)
1063 PyObject_ClearWeakRefs((PyObject *) self);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001064 PyObject_GC_Del(self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001065}
1066
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001067static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001068memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001069{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001070 Py_VISIT(self->mbuf);
1071 return 0;
1072}
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001073
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001074static int
1075memory_clear(PyMemoryViewObject *self)
1076{
1077 (void)_memory_release(self);
1078 Py_CLEAR(self->mbuf);
1079 return 0;
1080}
1081
1082static PyObject *
1083memory_enter(PyObject *self, PyObject *args)
1084{
1085 CHECK_RELEASED(self);
1086 Py_INCREF(self);
1087 return self;
1088}
1089
1090static PyObject *
1091memory_exit(PyObject *self, PyObject *args)
1092{
Stefan Krahe4c07992012-07-28 14:10:02 +02001093 return memory_release((PyMemoryViewObject *)self, NULL);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001094}
1095
1096
1097/****************************************************************************/
1098/* Casting format and shape */
1099/****************************************************************************/
1100
1101#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
1102
1103Py_LOCAL_INLINE(Py_ssize_t)
1104get_native_fmtchar(char *result, const char *fmt)
1105{
1106 Py_ssize_t size = -1;
1107
1108 if (fmt[0] == '@') fmt++;
1109
1110 switch (fmt[0]) {
1111 case 'c': case 'b': case 'B': size = sizeof(char); break;
1112 case 'h': case 'H': size = sizeof(short); break;
1113 case 'i': case 'I': size = sizeof(int); break;
1114 case 'l': case 'L': size = sizeof(long); break;
1115 #ifdef HAVE_LONG_LONG
1116 case 'q': case 'Q': size = sizeof(PY_LONG_LONG); break;
1117 #endif
1118 case 'n': case 'N': size = sizeof(Py_ssize_t); break;
1119 case 'f': size = sizeof(float); break;
1120 case 'd': size = sizeof(double); break;
1121 #ifdef HAVE_C99_BOOL
1122 case '?': size = sizeof(_Bool); break;
1123 #else
1124 case '?': size = sizeof(char); break;
1125 #endif
1126 case 'P': size = sizeof(void *); break;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001127 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001128
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001129 if (size > 0 && fmt[1] == '\0') {
1130 *result = fmt[0];
1131 return size;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001132 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001133
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001134 return -1;
1135}
1136
1137/* Cast a memoryview's data type to 'format'. The input array must be
1138 C-contiguous. At least one of input-format, output-format must have
1139 byte size. The output array is 1-D, with the same byte length as the
1140 input array. Thus, view->len must be a multiple of the new itemsize. */
1141static int
1142cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1143{
1144 Py_buffer *view = &mv->view;
1145 PyObject *asciifmt;
1146 char srcchar, destchar;
1147 Py_ssize_t itemsize;
1148 int ret = -1;
1149
1150 assert(view->ndim >= 1);
1151 assert(Py_SIZE(mv) == 3*view->ndim);
1152 assert(view->shape == mv->ob_array);
1153 assert(view->strides == mv->ob_array + view->ndim);
1154 assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1155
1156 if (get_native_fmtchar(&srcchar, view->format) < 0) {
1157 PyErr_SetString(PyExc_ValueError,
1158 "memoryview: source format must be a native single character "
1159 "format prefixed with an optional '@'");
1160 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001161 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001162
1163 asciifmt = PyUnicode_AsASCIIString(format);
1164 if (asciifmt == NULL)
1165 return ret;
1166
1167 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1168 if (itemsize < 0) {
1169 PyErr_SetString(PyExc_ValueError,
1170 "memoryview: destination format must be a native single "
1171 "character format prefixed with an optional '@'");
1172 goto out;
1173 }
1174
1175 if (!IS_BYTE_FORMAT(srcchar) && !IS_BYTE_FORMAT(destchar)) {
1176 PyErr_SetString(PyExc_TypeError,
1177 "memoryview: cannot cast between two non-byte formats");
1178 goto out;
1179 }
1180 if (view->len % itemsize) {
1181 PyErr_SetString(PyExc_TypeError,
1182 "memoryview: length is not a multiple of itemsize");
1183 goto out;
1184 }
1185
1186 strncpy(mv->format, PyBytes_AS_STRING(asciifmt),
1187 _Py_MEMORYVIEW_MAX_FORMAT);
1188 mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0';
1189 view->format = mv->format;
1190 view->itemsize = itemsize;
1191
1192 view->ndim = 1;
1193 view->shape[0] = view->len / view->itemsize;
1194 view->strides[0] = view->itemsize;
1195 view->suboffsets = NULL;
1196
1197 init_flags(mv);
1198
1199 ret = 0;
1200
1201out:
1202 Py_DECREF(asciifmt);
1203 return ret;
1204}
1205
1206/* The memoryview must have space for 3*len(seq) elements. */
1207static Py_ssize_t
1208copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1209 Py_ssize_t itemsize)
1210{
1211 Py_ssize_t x, i;
1212 Py_ssize_t len = itemsize;
1213
1214 for (i = 0; i < ndim; i++) {
1215 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1216 if (!PyLong_Check(tmp)) {
1217 PyErr_SetString(PyExc_TypeError,
1218 "memoryview.cast(): elements of shape must be integers");
1219 return -1;
1220 }
1221 x = PyLong_AsSsize_t(tmp);
1222 if (x == -1 && PyErr_Occurred()) {
1223 return -1;
1224 }
1225 if (x <= 0) {
1226 /* In general elements of shape may be 0, but not for casting. */
1227 PyErr_Format(PyExc_ValueError,
1228 "memoryview.cast(): elements of shape must be integers > 0");
1229 return -1;
1230 }
1231 if (x > PY_SSIZE_T_MAX / len) {
1232 PyErr_Format(PyExc_ValueError,
1233 "memoryview.cast(): product(shape) > SSIZE_MAX");
1234 return -1;
1235 }
1236 len *= x;
1237 shape[i] = x;
1238 }
1239
1240 return len;
1241}
1242
1243/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1244 If the result array does not have exactly the same byte length as the
1245 input array, raise ValueError. */
1246static int
1247cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1248{
1249 Py_buffer *view = &mv->view;
1250 Py_ssize_t len;
1251
1252 assert(view->ndim == 1); /* ndim from cast_to_1D() */
1253 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1254 assert(view->shape == mv->ob_array);
1255 assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1256 assert(view->suboffsets == NULL);
1257
1258 view->ndim = ndim;
1259 if (view->ndim == 0) {
1260 view->shape = NULL;
1261 view->strides = NULL;
1262 len = view->itemsize;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001263 }
1264 else {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001265 len = copy_shape(view->shape, shape, ndim, view->itemsize);
1266 if (len < 0)
1267 return -1;
1268 init_strides_from_shape(view);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001269 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001270
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001271 if (view->len != len) {
1272 PyErr_SetString(PyExc_TypeError,
1273 "memoryview: product(shape) * itemsize != buffer size");
1274 return -1;
1275 }
1276
1277 init_flags(mv);
1278
1279 return 0;
1280}
1281
1282static int
1283zero_in_shape(PyMemoryViewObject *mv)
1284{
1285 Py_buffer *view = &mv->view;
1286 Py_ssize_t i;
1287
1288 for (i = 0; i < view->ndim; i++)
1289 if (view->shape[i] == 0)
1290 return 1;
1291
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001292 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001293}
1294
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001295/*
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001296 Cast a copy of 'self' to a different view. The input view must
1297 be C-contiguous. The function always casts the input view to a
1298 1-D output according to 'format'. At least one of input-format,
1299 output-format must have byte size.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001300
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001301 If 'shape' is given, the 1-D view from the previous step will
1302 be cast to a C-contiguous view with new shape and strides.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001303
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001304 All casts must result in views that will have the exact byte
1305 size of the original input. Otherwise, an error is raised.
1306*/
1307static PyObject *
1308memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001309{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001310 static char *kwlist[] = {"format", "shape", NULL};
1311 PyMemoryViewObject *mv = NULL;
1312 PyObject *shape = NULL;
1313 PyObject *format;
1314 Py_ssize_t ndim = 1;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001315
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001316 CHECK_RELEASED(self);
1317
1318 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
1319 &format, &shape)) {
1320 return NULL;
1321 }
1322 if (!PyUnicode_Check(format)) {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001323 PyErr_SetString(PyExc_TypeError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001324 "memoryview: format argument must be a string");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001325 return NULL;
1326 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001327 if (!MV_C_CONTIGUOUS(self->flags)) {
1328 PyErr_SetString(PyExc_TypeError,
1329 "memoryview: casts are restricted to C-contiguous views");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001330 return NULL;
1331 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001332 if (zero_in_shape(self)) {
1333 PyErr_SetString(PyExc_TypeError,
1334 "memoryview: cannot cast view with zeros in shape or strides");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001335 return NULL;
1336 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001337 if (shape) {
1338 CHECK_LIST_OR_TUPLE(shape)
1339 ndim = PySequence_Fast_GET_SIZE(shape);
1340 if (ndim > PyBUF_MAX_NDIM) {
1341 PyErr_SetString(PyExc_ValueError,
1342 "memoryview: number of dimensions must not exceed "
1343 STRINGIZE(PyBUF_MAX_NDIM));
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001344 return NULL;
1345 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001346 if (self->view.ndim != 1 && ndim != 1) {
1347 PyErr_SetString(PyExc_TypeError,
1348 "memoryview: cast must be 1D -> ND or ND -> 1D");
1349 return NULL;
1350 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001351 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001352
1353 mv = (PyMemoryViewObject *)
1354 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1355 if (mv == NULL)
1356 return NULL;
1357
1358 if (cast_to_1D(mv, format) < 0)
1359 goto error;
1360 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1361 goto error;
1362
1363 return (PyObject *)mv;
1364
1365error:
1366 Py_DECREF(mv);
1367 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001368}
1369
1370
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001371/**************************************************************************/
1372/* getbuffer */
1373/**************************************************************************/
1374
1375static int
1376memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1377{
1378 Py_buffer *base = &self->view;
1379 int baseflags = self->flags;
1380
1381 CHECK_RELEASED_INT(self);
1382
1383 /* start with complete information */
1384 *view = *base;
1385 view->obj = NULL;
1386
1387 if (REQ_WRITABLE(flags) && base->readonly) {
1388 PyErr_SetString(PyExc_BufferError,
1389 "memoryview: underlying buffer is not writable");
1390 return -1;
1391 }
1392 if (!REQ_FORMAT(flags)) {
1393 /* NULL indicates that the buffer's data type has been cast to 'B'.
1394 view->itemsize is the _previous_ itemsize. If shape is present,
1395 the equality product(shape) * itemsize = len still holds at this
1396 point. The equality calcsize(format) = itemsize does _not_ hold
1397 from here on! */
1398 view->format = NULL;
1399 }
1400
1401 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1402 PyErr_SetString(PyExc_BufferError,
1403 "memoryview: underlying buffer is not C-contiguous");
1404 return -1;
1405 }
1406 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1407 PyErr_SetString(PyExc_BufferError,
1408 "memoryview: underlying buffer is not Fortran contiguous");
1409 return -1;
1410 }
1411 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1412 PyErr_SetString(PyExc_BufferError,
1413 "memoryview: underlying buffer is not contiguous");
1414 return -1;
1415 }
1416 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1417 PyErr_SetString(PyExc_BufferError,
1418 "memoryview: underlying buffer requires suboffsets");
1419 return -1;
1420 }
1421 if (!REQ_STRIDES(flags)) {
1422 if (!MV_C_CONTIGUOUS(baseflags)) {
1423 PyErr_SetString(PyExc_BufferError,
1424 "memoryview: underlying buffer is not C-contiguous");
1425 return -1;
1426 }
1427 view->strides = NULL;
1428 }
1429 if (!REQ_SHAPE(flags)) {
1430 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1431 so base->buf = ndbuf->data. */
1432 if (view->format != NULL) {
1433 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1434 not make sense. */
1435 PyErr_Format(PyExc_BufferError,
1436 "ndarray: cannot cast to unsigned bytes if the format flag "
1437 "is present");
1438 return -1;
1439 }
1440 /* product(shape) * itemsize = len and calcsize(format) = itemsize
1441 do _not_ hold from here on! */
1442 view->ndim = 1;
1443 view->shape = NULL;
1444 }
1445
1446
1447 view->obj = (PyObject *)self;
1448 Py_INCREF(view->obj);
1449 self->exports++;
1450
1451 return 0;
1452}
1453
1454static void
1455memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1456{
1457 self->exports--;
1458 return;
1459 /* PyBuffer_Release() decrements view->obj after this function returns. */
1460}
1461
1462/* Buffer methods */
1463static PyBufferProcs memory_as_buffer = {
1464 (getbufferproc)memory_getbuf, /* bf_getbuffer */
1465 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1466};
1467
1468
1469/****************************************************************************/
1470/* Optimized pack/unpack for all native format specifiers */
1471/****************************************************************************/
1472
1473/*
1474 Fix exceptions:
1475 1) Include format string in the error message.
1476 2) OverflowError -> ValueError.
1477 3) The error message from PyNumber_Index() is not ideal.
1478*/
1479static int
1480type_error_int(const char *fmt)
1481{
1482 PyErr_Format(PyExc_TypeError,
1483 "memoryview: invalid type for format '%s'", fmt);
1484 return -1;
1485}
1486
1487static int
1488value_error_int(const char *fmt)
1489{
1490 PyErr_Format(PyExc_ValueError,
1491 "memoryview: invalid value for format '%s'", fmt);
1492 return -1;
1493}
1494
1495static int
1496fix_error_int(const char *fmt)
1497{
1498 assert(PyErr_Occurred());
1499 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1500 PyErr_Clear();
1501 return type_error_int(fmt);
1502 }
1503 else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1504 PyErr_ExceptionMatches(PyExc_ValueError)) {
1505 PyErr_Clear();
1506 return value_error_int(fmt);
1507 }
1508
1509 return -1;
1510}
1511
1512/* Accept integer objects or objects with an __index__() method. */
1513static long
1514pylong_as_ld(PyObject *item)
1515{
1516 PyObject *tmp;
1517 long ld;
1518
1519 tmp = PyNumber_Index(item);
1520 if (tmp == NULL)
1521 return -1;
1522
1523 ld = PyLong_AsLong(tmp);
1524 Py_DECREF(tmp);
1525 return ld;
1526}
1527
1528static unsigned long
1529pylong_as_lu(PyObject *item)
1530{
1531 PyObject *tmp;
1532 unsigned long lu;
1533
1534 tmp = PyNumber_Index(item);
1535 if (tmp == NULL)
1536 return (unsigned long)-1;
1537
1538 lu = PyLong_AsUnsignedLong(tmp);
1539 Py_DECREF(tmp);
1540 return lu;
1541}
1542
1543#ifdef HAVE_LONG_LONG
1544static PY_LONG_LONG
1545pylong_as_lld(PyObject *item)
1546{
1547 PyObject *tmp;
1548 PY_LONG_LONG lld;
1549
1550 tmp = PyNumber_Index(item);
1551 if (tmp == NULL)
1552 return -1;
1553
1554 lld = PyLong_AsLongLong(tmp);
1555 Py_DECREF(tmp);
1556 return lld;
1557}
1558
1559static unsigned PY_LONG_LONG
1560pylong_as_llu(PyObject *item)
1561{
1562 PyObject *tmp;
1563 unsigned PY_LONG_LONG llu;
1564
1565 tmp = PyNumber_Index(item);
1566 if (tmp == NULL)
1567 return (unsigned PY_LONG_LONG)-1;
1568
1569 llu = PyLong_AsUnsignedLongLong(tmp);
1570 Py_DECREF(tmp);
1571 return llu;
1572}
1573#endif
1574
1575static Py_ssize_t
1576pylong_as_zd(PyObject *item)
1577{
1578 PyObject *tmp;
1579 Py_ssize_t zd;
1580
1581 tmp = PyNumber_Index(item);
1582 if (tmp == NULL)
1583 return -1;
1584
1585 zd = PyLong_AsSsize_t(tmp);
1586 Py_DECREF(tmp);
1587 return zd;
1588}
1589
1590static size_t
1591pylong_as_zu(PyObject *item)
1592{
1593 PyObject *tmp;
1594 size_t zu;
1595
1596 tmp = PyNumber_Index(item);
1597 if (tmp == NULL)
1598 return (size_t)-1;
1599
1600 zu = PyLong_AsSize_t(tmp);
1601 Py_DECREF(tmp);
1602 return zu;
1603}
1604
1605/* Timings with the ndarray from _testbuffer.c indicate that using the
1606 struct module is around 15x slower than the two functions below. */
1607
1608#define UNPACK_SINGLE(dest, ptr, type) \
1609 do { \
1610 type x; \
1611 memcpy((char *)&x, ptr, sizeof x); \
1612 dest = x; \
1613 } while (0)
1614
1615/* Unpack a single item. 'fmt' can be any native format character in struct
1616 module syntax. This function is very sensitive to small changes. With this
1617 layout gcc automatically generates a fast jump table. */
1618Py_LOCAL_INLINE(PyObject *)
1619unpack_single(const char *ptr, const char *fmt)
1620{
1621 unsigned PY_LONG_LONG llu;
1622 unsigned long lu;
1623 size_t zu;
1624 PY_LONG_LONG lld;
1625 long ld;
1626 Py_ssize_t zd;
1627 double d;
1628 unsigned char uc;
1629 void *p;
1630
1631 switch (fmt[0]) {
1632
1633 /* signed integers and fast path for 'B' */
1634 case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
1635 case 'b': ld = *((signed char *)ptr); goto convert_ld;
1636 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1637 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1638 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1639
1640 /* boolean */
1641 #ifdef HAVE_C99_BOOL
1642 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
1643 #else
1644 case '?': UNPACK_SINGLE(ld, ptr, char); goto convert_bool;
1645 #endif
1646
1647 /* unsigned integers */
1648 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1649 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1650 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1651
1652 /* native 64-bit */
1653 #ifdef HAVE_LONG_LONG
1654 case 'q': UNPACK_SINGLE(lld, ptr, PY_LONG_LONG); goto convert_lld;
1655 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned PY_LONG_LONG); goto convert_llu;
1656 #endif
1657
1658 /* ssize_t and size_t */
1659 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1660 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1661
1662 /* floats */
1663 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1664 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1665
1666 /* bytes object */
1667 case 'c': goto convert_bytes;
1668
1669 /* pointer */
1670 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1671
1672 /* default */
1673 default: goto err_format;
1674 }
1675
1676convert_uc:
1677 /* PyLong_FromUnsignedLong() is slower */
1678 return PyLong_FromLong(uc);
1679convert_ld:
1680 return PyLong_FromLong(ld);
1681convert_lu:
1682 return PyLong_FromUnsignedLong(lu);
1683convert_lld:
1684 return PyLong_FromLongLong(lld);
1685convert_llu:
1686 return PyLong_FromUnsignedLongLong(llu);
1687convert_zd:
1688 return PyLong_FromSsize_t(zd);
1689convert_zu:
1690 return PyLong_FromSize_t(zu);
1691convert_double:
1692 return PyFloat_FromDouble(d);
1693convert_bool:
1694 return PyBool_FromLong(ld);
1695convert_bytes:
1696 return PyBytes_FromStringAndSize(ptr, 1);
1697convert_pointer:
1698 return PyLong_FromVoidPtr(p);
1699err_format:
1700 PyErr_Format(PyExc_NotImplementedError,
1701 "memoryview: format %s not supported", fmt);
1702 return NULL;
1703}
1704
1705#define PACK_SINGLE(ptr, src, type) \
1706 do { \
1707 type x; \
1708 x = (type)src; \
1709 memcpy(ptr, (char *)&x, sizeof x); \
1710 } while (0)
1711
1712/* Pack a single item. 'fmt' can be any native format character in
1713 struct module syntax. */
1714static int
1715pack_single(char *ptr, PyObject *item, const char *fmt)
1716{
1717 unsigned PY_LONG_LONG llu;
1718 unsigned long lu;
1719 size_t zu;
1720 PY_LONG_LONG lld;
1721 long ld;
1722 Py_ssize_t zd;
1723 double d;
1724 void *p;
1725
1726 switch (fmt[0]) {
1727 /* signed integers */
1728 case 'b': case 'h': case 'i': case 'l':
1729 ld = pylong_as_ld(item);
1730 if (ld == -1 && PyErr_Occurred())
1731 goto err_occurred;
1732 switch (fmt[0]) {
1733 case 'b':
1734 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1735 *((signed char *)ptr) = (signed char)ld; break;
1736 case 'h':
1737 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1738 PACK_SINGLE(ptr, ld, short); break;
1739 case 'i':
1740 if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1741 PACK_SINGLE(ptr, ld, int); break;
1742 default: /* 'l' */
1743 PACK_SINGLE(ptr, ld, long); break;
1744 }
1745 break;
1746
1747 /* unsigned integers */
1748 case 'B': case 'H': case 'I': case 'L':
1749 lu = pylong_as_lu(item);
1750 if (lu == (unsigned long)-1 && PyErr_Occurred())
1751 goto err_occurred;
1752 switch (fmt[0]) {
1753 case 'B':
1754 if (lu > UCHAR_MAX) goto err_range;
1755 *((unsigned char *)ptr) = (unsigned char)lu; break;
1756 case 'H':
1757 if (lu > USHRT_MAX) goto err_range;
1758 PACK_SINGLE(ptr, lu, unsigned short); break;
1759 case 'I':
1760 if (lu > UINT_MAX) goto err_range;
1761 PACK_SINGLE(ptr, lu, unsigned int); break;
1762 default: /* 'L' */
1763 PACK_SINGLE(ptr, lu, unsigned long); break;
1764 }
1765 break;
1766
1767 /* native 64-bit */
1768 #ifdef HAVE_LONG_LONG
1769 case 'q':
1770 lld = pylong_as_lld(item);
1771 if (lld == -1 && PyErr_Occurred())
1772 goto err_occurred;
1773 PACK_SINGLE(ptr, lld, PY_LONG_LONG);
1774 break;
1775 case 'Q':
1776 llu = pylong_as_llu(item);
1777 if (llu == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
1778 goto err_occurred;
1779 PACK_SINGLE(ptr, llu, unsigned PY_LONG_LONG);
1780 break;
1781 #endif
1782
1783 /* ssize_t and size_t */
1784 case 'n':
1785 zd = pylong_as_zd(item);
1786 if (zd == -1 && PyErr_Occurred())
1787 goto err_occurred;
1788 PACK_SINGLE(ptr, zd, Py_ssize_t);
1789 break;
1790 case 'N':
1791 zu = pylong_as_zu(item);
1792 if (zu == (size_t)-1 && PyErr_Occurred())
1793 goto err_occurred;
1794 PACK_SINGLE(ptr, zu, size_t);
1795 break;
1796
1797 /* floats */
1798 case 'f': case 'd':
1799 d = PyFloat_AsDouble(item);
1800 if (d == -1.0 && PyErr_Occurred())
1801 goto err_occurred;
1802 if (fmt[0] == 'f') {
1803 PACK_SINGLE(ptr, d, float);
1804 }
1805 else {
1806 PACK_SINGLE(ptr, d, double);
1807 }
1808 break;
1809
1810 /* bool */
1811 case '?':
1812 ld = PyObject_IsTrue(item);
1813 if (ld < 0)
1814 return -1; /* preserve original error */
1815 #ifdef HAVE_C99_BOOL
1816 PACK_SINGLE(ptr, ld, _Bool);
1817 #else
1818 PACK_SINGLE(ptr, ld, char);
1819 #endif
1820 break;
1821
1822 /* bytes object */
1823 case 'c':
1824 if (!PyBytes_Check(item))
1825 return type_error_int(fmt);
1826 if (PyBytes_GET_SIZE(item) != 1)
1827 return value_error_int(fmt);
1828 *ptr = PyBytes_AS_STRING(item)[0];
1829 break;
1830
1831 /* pointer */
1832 case 'P':
1833 p = PyLong_AsVoidPtr(item);
1834 if (p == NULL && PyErr_Occurred())
1835 goto err_occurred;
1836 PACK_SINGLE(ptr, p, void *);
1837 break;
1838
1839 /* default */
1840 default: goto err_format;
1841 }
1842
1843 return 0;
1844
1845err_occurred:
1846 return fix_error_int(fmt);
1847err_range:
1848 return value_error_int(fmt);
1849err_format:
1850 PyErr_Format(PyExc_NotImplementedError,
1851 "memoryview: format %s not supported", fmt);
1852 return -1;
1853}
1854
1855
1856/****************************************************************************/
Nick Coghlan06e1ab02012-08-25 17:59:50 +10001857/* unpack using the struct module */
1858/****************************************************************************/
1859
1860/* For reasonable performance it is necessary to cache all objects required
1861 for unpacking. An unpacker can handle the format passed to unpack_from().
1862 Invariant: All pointer fields of the struct should either be NULL or valid
1863 pointers. */
1864struct unpacker {
1865 PyObject *unpack_from; /* Struct.unpack_from(format) */
1866 PyObject *mview; /* cached memoryview */
1867 char *item; /* buffer for mview */
1868 Py_ssize_t itemsize; /* len(item) */
1869};
1870
1871static struct unpacker *
1872unpacker_new(void)
1873{
1874 struct unpacker *x = PyMem_Malloc(sizeof *x);
1875
1876 if (x == NULL) {
1877 PyErr_NoMemory();
1878 return NULL;
1879 }
1880
1881 x->unpack_from = NULL;
1882 x->mview = NULL;
1883 x->item = NULL;
1884 x->itemsize = 0;
1885
1886 return x;
1887}
1888
1889static void
1890unpacker_free(struct unpacker *x)
1891{
1892 if (x) {
1893 Py_XDECREF(x->unpack_from);
1894 Py_XDECREF(x->mview);
1895 PyMem_Free(x->item);
1896 PyMem_Free(x);
1897 }
1898}
1899
1900/* Return a new unpacker for the given format. */
1901static struct unpacker *
1902struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
1903{
1904 PyObject *structmodule; /* XXX cache these two */
1905 PyObject *Struct = NULL; /* XXX in globals? */
1906 PyObject *structobj = NULL;
1907 PyObject *format = NULL;
1908 struct unpacker *x = NULL;
1909
1910 structmodule = PyImport_ImportModule("struct");
1911 if (structmodule == NULL)
1912 return NULL;
1913
1914 Struct = PyObject_GetAttrString(structmodule, "Struct");
1915 Py_DECREF(structmodule);
1916 if (Struct == NULL)
1917 return NULL;
1918
1919 x = unpacker_new();
1920 if (x == NULL)
1921 goto error;
1922
1923 format = PyBytes_FromString(fmt);
1924 if (format == NULL)
1925 goto error;
1926
1927 structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
1928 if (structobj == NULL)
1929 goto error;
1930
1931 x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
1932 if (x->unpack_from == NULL)
1933 goto error;
1934
1935 x->item = PyMem_Malloc(itemsize);
1936 if (x->item == NULL) {
1937 PyErr_NoMemory();
1938 goto error;
1939 }
1940 x->itemsize = itemsize;
1941
1942 x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
1943 if (x->mview == NULL)
1944 goto error;
1945
1946
1947out:
1948 Py_XDECREF(Struct);
1949 Py_XDECREF(format);
1950 Py_XDECREF(structobj);
1951 return x;
1952
1953error:
1954 unpacker_free(x);
1955 x = NULL;
1956 goto out;
1957}
1958
1959/* unpack a single item */
1960static PyObject *
1961struct_unpack_single(const char *ptr, struct unpacker *x)
1962{
1963 PyObject *v;
1964
1965 memcpy(x->item, ptr, x->itemsize);
1966 v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL);
1967 if (v == NULL)
1968 return NULL;
1969
1970 if (PyTuple_GET_SIZE(v) == 1) {
1971 PyObject *tmp = PyTuple_GET_ITEM(v, 0);
1972 Py_INCREF(tmp);
1973 Py_DECREF(v);
1974 return tmp;
1975 }
1976
1977 return v;
1978}
1979
1980
1981/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001982/* Representations */
1983/****************************************************************************/
1984
1985/* allow explicit form of native format */
1986Py_LOCAL_INLINE(const char *)
1987adjust_fmt(const Py_buffer *view)
1988{
1989 const char *fmt;
1990
1991 fmt = (view->format[0] == '@') ? view->format+1 : view->format;
1992 if (fmt[0] && fmt[1] == '\0')
1993 return fmt;
1994
1995 PyErr_Format(PyExc_NotImplementedError,
1996 "memoryview: unsupported format %s", view->format);
1997 return NULL;
1998}
1999
2000/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
2001static PyObject *
2002tolist_base(const char *ptr, const Py_ssize_t *shape,
2003 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2004 const char *fmt)
2005{
2006 PyObject *lst, *item;
2007 Py_ssize_t i;
2008
2009 lst = PyList_New(shape[0]);
2010 if (lst == NULL)
2011 return NULL;
2012
2013 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2014 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2015 item = unpack_single(xptr, fmt);
2016 if (item == NULL) {
2017 Py_DECREF(lst);
2018 return NULL;
2019 }
2020 PyList_SET_ITEM(lst, i, item);
2021 }
2022
2023 return lst;
2024}
2025
2026/* Unpack a multi-dimensional array into a nested list.
2027 Assumption: ndim >= 1. */
2028static PyObject *
2029tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
2030 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2031 const char *fmt)
2032{
2033 PyObject *lst, *item;
2034 Py_ssize_t i;
2035
2036 assert(ndim >= 1);
2037 assert(shape != NULL);
2038 assert(strides != NULL);
2039
2040 if (ndim == 1)
2041 return tolist_base(ptr, shape, strides, suboffsets, fmt);
2042
2043 lst = PyList_New(shape[0]);
2044 if (lst == NULL)
2045 return NULL;
2046
2047 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2048 const char *xptr = ADJUST_PTR(ptr, suboffsets);
2049 item = tolist_rec(xptr, ndim-1, shape+1,
2050 strides+1, suboffsets ? suboffsets+1 : NULL,
2051 fmt);
2052 if (item == NULL) {
2053 Py_DECREF(lst);
2054 return NULL;
2055 }
2056 PyList_SET_ITEM(lst, i, item);
2057 }
2058
2059 return lst;
2060}
2061
2062/* Return a list representation of the memoryview. Currently only buffers
2063 with native format strings are supported. */
2064static PyObject *
2065memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
2066{
2067 const Py_buffer *view = &(mv->view);
2068 const char *fmt;
2069
2070 CHECK_RELEASED(mv);
2071
2072 fmt = adjust_fmt(view);
2073 if (fmt == NULL)
2074 return NULL;
2075 if (view->ndim == 0) {
2076 return unpack_single(view->buf, fmt);
2077 }
2078 else if (view->ndim == 1) {
2079 return tolist_base(view->buf, view->shape,
2080 view->strides, view->suboffsets,
2081 fmt);
2082 }
2083 else {
2084 return tolist_rec(view->buf, view->ndim, view->shape,
2085 view->strides, view->suboffsets,
2086 fmt);
2087 }
2088}
2089
2090static PyObject *
2091memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
2092{
2093 Py_buffer *src = VIEW_ADDR(self);
2094 PyObject *bytes = NULL;
2095
2096 CHECK_RELEASED(self);
2097
2098 if (MV_C_CONTIGUOUS(self->flags)) {
2099 return PyBytes_FromStringAndSize(src->buf, src->len);
2100 }
2101
2102 bytes = PyBytes_FromStringAndSize(NULL, src->len);
2103 if (bytes == NULL)
2104 return NULL;
2105
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002106 if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002107 Py_DECREF(bytes);
2108 return NULL;
2109 }
2110
2111 return bytes;
2112}
2113
2114static PyObject *
2115memory_repr(PyMemoryViewObject *self)
2116{
2117 if (self->flags & _Py_MEMORYVIEW_RELEASED)
2118 return PyUnicode_FromFormat("<released memory at %p>", self);
2119 else
2120 return PyUnicode_FromFormat("<memory at %p>", self);
2121}
2122
2123
2124/**************************************************************************/
2125/* Indexing and slicing */
2126/**************************************************************************/
2127
2128/* Get the pointer to the item at index. */
2129static char *
2130ptr_from_index(Py_buffer *view, Py_ssize_t index)
2131{
2132 char *ptr;
2133 Py_ssize_t nitems; /* items in the first dimension */
2134
2135 assert(view->shape);
2136 assert(view->strides);
2137
2138 nitems = view->shape[0];
2139 if (index < 0) {
2140 index += nitems;
2141 }
2142 if (index < 0 || index >= nitems) {
2143 PyErr_SetString(PyExc_IndexError, "index out of bounds");
2144 return NULL;
2145 }
2146
2147 ptr = (char *)view->buf;
2148 ptr += view->strides[0] * index;
2149
2150 ptr = ADJUST_PTR(ptr, view->suboffsets);
2151
2152 return ptr;
2153}
2154
2155/* Return the item at index. In a one-dimensional view, this is an object
2156 with the type specified by view->format. Otherwise, the item is a sub-view.
2157 The function is used in memory_subscript() and memory_as_sequence. */
2158static PyObject *
2159memory_item(PyMemoryViewObject *self, Py_ssize_t index)
2160{
2161 Py_buffer *view = &(self->view);
2162 const char *fmt;
2163
2164 CHECK_RELEASED(self);
2165
2166 fmt = adjust_fmt(view);
2167 if (fmt == NULL)
2168 return NULL;
2169
2170 if (view->ndim == 0) {
2171 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
2172 return NULL;
2173 }
2174 if (view->ndim == 1) {
2175 char *ptr = ptr_from_index(view, index);
2176 if (ptr == NULL)
2177 return NULL;
2178 return unpack_single(ptr, fmt);
2179 }
2180
2181 PyErr_SetString(PyExc_NotImplementedError,
2182 "multi-dimensional sub-views are not implemented");
2183 return NULL;
2184}
2185
2186Py_LOCAL_INLINE(int)
2187init_slice(Py_buffer *base, PyObject *key, int dim)
2188{
2189 Py_ssize_t start, stop, step, slicelength;
2190
2191 if (PySlice_GetIndicesEx(key, base->shape[dim],
2192 &start, &stop, &step, &slicelength) < 0) {
2193 return -1;
2194 }
2195
2196
2197 if (base->suboffsets == NULL || dim == 0) {
2198 adjust_buf:
2199 base->buf = (char *)base->buf + base->strides[dim] * start;
2200 }
2201 else {
2202 Py_ssize_t n = dim-1;
2203 while (n >= 0 && base->suboffsets[n] < 0)
2204 n--;
2205 if (n < 0)
2206 goto adjust_buf; /* all suboffsets are negative */
2207 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
2208 }
2209 base->shape[dim] = slicelength;
2210 base->strides[dim] = base->strides[dim] * step;
2211
2212 return 0;
2213}
2214
2215static int
2216is_multislice(PyObject *key)
2217{
2218 Py_ssize_t size, i;
2219
2220 if (!PyTuple_Check(key))
2221 return 0;
2222 size = PyTuple_GET_SIZE(key);
2223 if (size == 0)
2224 return 0;
2225
2226 for (i = 0; i < size; i++) {
2227 PyObject *x = PyTuple_GET_ITEM(key, i);
2228 if (!PySlice_Check(x))
2229 return 0;
2230 }
2231 return 1;
2232}
2233
2234/* mv[obj] returns an object holding the data for one element if obj
2235 fully indexes the memoryview or another memoryview object if it
2236 does not.
2237
2238 0-d memoryview objects can be referenced using mv[...] or mv[()]
2239 but not with anything else. */
2240static PyObject *
2241memory_subscript(PyMemoryViewObject *self, PyObject *key)
2242{
2243 Py_buffer *view;
2244 view = &(self->view);
2245
2246 CHECK_RELEASED(self);
2247
2248 if (view->ndim == 0) {
2249 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2250 const char *fmt = adjust_fmt(view);
2251 if (fmt == NULL)
2252 return NULL;
2253 return unpack_single(view->buf, fmt);
2254 }
2255 else if (key == Py_Ellipsis) {
2256 Py_INCREF(self);
2257 return (PyObject *)self;
2258 }
2259 else {
2260 PyErr_SetString(PyExc_TypeError,
2261 "invalid indexing of 0-dim memory");
2262 return NULL;
2263 }
2264 }
2265
2266 if (PyIndex_Check(key)) {
2267 Py_ssize_t index;
2268 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2269 if (index == -1 && PyErr_Occurred())
2270 return NULL;
2271 return memory_item(self, index);
2272 }
2273 else if (PySlice_Check(key)) {
2274 PyMemoryViewObject *sliced;
2275
2276 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2277 if (sliced == NULL)
2278 return NULL;
2279
2280 if (init_slice(&sliced->view, key, 0) < 0) {
2281 Py_DECREF(sliced);
2282 return NULL;
2283 }
2284 init_len(&sliced->view);
2285 init_flags(sliced);
2286
2287 return (PyObject *)sliced;
2288 }
2289 else if (is_multislice(key)) {
2290 PyErr_SetString(PyExc_NotImplementedError,
2291 "multi-dimensional slicing is not implemented");
2292 return NULL;
2293 }
2294
2295 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2296 return NULL;
2297}
2298
2299static int
2300memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2301{
2302 Py_buffer *view = &(self->view);
2303 Py_buffer src;
2304 const char *fmt;
2305 char *ptr;
2306
2307 CHECK_RELEASED_INT(self);
2308
2309 fmt = adjust_fmt(view);
2310 if (fmt == NULL)
2311 return -1;
2312
2313 if (view->readonly) {
2314 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2315 return -1;
2316 }
2317 if (value == NULL) {
2318 PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2319 return -1;
2320 }
2321 if (view->ndim == 0) {
2322 if (key == Py_Ellipsis ||
2323 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2324 ptr = (char *)view->buf;
2325 return pack_single(ptr, value, fmt);
2326 }
2327 else {
2328 PyErr_SetString(PyExc_TypeError,
2329 "invalid indexing of 0-dim memory");
2330 return -1;
2331 }
2332 }
2333 if (view->ndim != 1) {
2334 PyErr_SetString(PyExc_NotImplementedError,
2335 "memoryview assignments are currently restricted to ndim = 1");
2336 return -1;
2337 }
2338
2339 if (PyIndex_Check(key)) {
2340 Py_ssize_t index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2341 if (index == -1 && PyErr_Occurred())
2342 return -1;
2343 ptr = ptr_from_index(view, index);
2344 if (ptr == NULL)
2345 return -1;
2346 return pack_single(ptr, value, fmt);
2347 }
2348 /* one-dimensional: fast path */
2349 if (PySlice_Check(key) && view->ndim == 1) {
2350 Py_buffer dest; /* sliced view */
2351 Py_ssize_t arrays[3];
2352 int ret = -1;
2353
2354 /* rvalue must be an exporter */
2355 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2356 return ret;
2357
2358 dest = *view;
2359 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2360 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2361 if (view->suboffsets) {
2362 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2363 }
2364
2365 if (init_slice(&dest, key, 0) < 0)
2366 goto end_block;
2367 dest.len = dest.shape[0] * dest.itemsize;
2368
2369 ret = copy_single(&dest, &src);
2370
2371 end_block:
2372 PyBuffer_Release(&src);
2373 return ret;
2374 }
2375 else if (PySlice_Check(key) || is_multislice(key)) {
2376 /* Call memory_subscript() to produce a sliced lvalue, then copy
2377 rvalue into lvalue. This is already implemented in _testbuffer.c. */
2378 PyErr_SetString(PyExc_NotImplementedError,
2379 "memoryview slice assignments are currently restricted "
2380 "to ndim = 1");
2381 return -1;
2382 }
2383
2384 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2385 return -1;
2386}
2387
2388static Py_ssize_t
2389memory_length(PyMemoryViewObject *self)
2390{
2391 CHECK_RELEASED_INT(self);
2392 return self->view.ndim == 0 ? 1 : self->view.shape[0];
2393}
2394
2395/* As mapping */
2396static PyMappingMethods memory_as_mapping = {
2397 (lenfunc)memory_length, /* mp_length */
2398 (binaryfunc)memory_subscript, /* mp_subscript */
2399 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
2400};
2401
2402/* As sequence */
2403static PySequenceMethods memory_as_sequence = {
2404 0, /* sq_length */
2405 0, /* sq_concat */
2406 0, /* sq_repeat */
2407 (ssizeargfunc)memory_item, /* sq_item */
2408};
2409
2410
2411/**************************************************************************/
2412/* Comparisons */
2413/**************************************************************************/
2414
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002415#define MV_COMPARE_EX -1 /* exception */
2416#define MV_COMPARE_NOT_IMPL -2 /* not implemented */
2417
2418/* Translate a StructError to "not equal". Preserve other exceptions. */
2419static int
2420fix_struct_error_int(void)
2421{
2422 assert(PyErr_Occurred());
2423 /* XXX Cannot get at StructError directly? */
2424 if (PyErr_ExceptionMatches(PyExc_ImportError) ||
2425 PyErr_ExceptionMatches(PyExc_MemoryError)) {
2426 return MV_COMPARE_EX;
2427 }
2428 /* StructError: invalid or unknown format -> not equal */
2429 PyErr_Clear();
2430 return 0;
2431}
2432
2433/* Unpack and compare single items of p and q using the struct module. */
2434static int
2435struct_unpack_cmp(const char *p, const char *q,
2436 struct unpacker *unpack_p, struct unpacker *unpack_q)
2437{
2438 PyObject *v, *w;
2439 int ret;
2440
2441 /* At this point any exception from the struct module should not be
2442 StructError, since both formats have been accepted already. */
2443 v = struct_unpack_single(p, unpack_p);
2444 if (v == NULL)
2445 return MV_COMPARE_EX;
2446
2447 w = struct_unpack_single(q, unpack_q);
2448 if (w == NULL) {
2449 Py_DECREF(v);
2450 return MV_COMPARE_EX;
2451 }
2452
2453 /* MV_COMPARE_EX == -1: exceptions are preserved */
2454 ret = PyObject_RichCompareBool(v, w, Py_EQ);
2455 Py_DECREF(v);
2456 Py_DECREF(w);
2457
2458 return ret;
2459}
2460
2461/* Unpack and compare single items of p and q. If both p and q have the same
2462 single element native format, the comparison uses a fast path (gcc creates
2463 a jump table and converts memcpy into simple assignments on x86/x64).
2464
2465 Otherwise, the comparison is delegated to the struct module, which is
2466 30-60x slower. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002467#define CMP_SINGLE(p, q, type) \
2468 do { \
2469 type x; \
2470 type y; \
2471 memcpy((char *)&x, p, sizeof x); \
2472 memcpy((char *)&y, q, sizeof y); \
2473 equal = (x == y); \
2474 } while (0)
2475
2476Py_LOCAL_INLINE(int)
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002477unpack_cmp(const char *p, const char *q, char fmt,
2478 struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002479{
2480 int equal;
2481
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002482 switch (fmt) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002483
2484 /* signed integers and fast path for 'B' */
2485 case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
2486 case 'b': return *((signed char *)p) == *((signed char *)q);
2487 case 'h': CMP_SINGLE(p, q, short); return equal;
2488 case 'i': CMP_SINGLE(p, q, int); return equal;
2489 case 'l': CMP_SINGLE(p, q, long); return equal;
2490
2491 /* boolean */
2492 #ifdef HAVE_C99_BOOL
2493 case '?': CMP_SINGLE(p, q, _Bool); return equal;
2494 #else
2495 case '?': CMP_SINGLE(p, q, char); return equal;
2496 #endif
2497
2498 /* unsigned integers */
2499 case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2500 case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2501 case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2502
2503 /* native 64-bit */
2504 #ifdef HAVE_LONG_LONG
2505 case 'q': CMP_SINGLE(p, q, PY_LONG_LONG); return equal;
2506 case 'Q': CMP_SINGLE(p, q, unsigned PY_LONG_LONG); return equal;
2507 #endif
2508
2509 /* ssize_t and size_t */
2510 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2511 case 'N': CMP_SINGLE(p, q, size_t); return equal;
2512
2513 /* floats */
2514 /* XXX DBL_EPSILON? */
2515 case 'f': CMP_SINGLE(p, q, float); return equal;
2516 case 'd': CMP_SINGLE(p, q, double); return equal;
2517
2518 /* bytes object */
2519 case 'c': return *p == *q;
2520
2521 /* pointer */
2522 case 'P': CMP_SINGLE(p, q, void *); return equal;
2523
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002524 /* use the struct module */
2525 case '_':
2526 assert(unpack_p);
2527 assert(unpack_q);
2528 return struct_unpack_cmp(p, q, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002529 }
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002530
2531 /* NOT REACHED */
2532 PyErr_SetString(PyExc_RuntimeError,
2533 "memoryview: internal error in richcompare");
2534 return MV_COMPARE_EX;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002535}
2536
2537/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2538static int
2539cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2540 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2541 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002542 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002543{
2544 Py_ssize_t i;
2545 int equal;
2546
2547 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2548 const char *xp = ADJUST_PTR(p, psuboffsets);
2549 const char *xq = ADJUST_PTR(q, qsuboffsets);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002550 equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002551 if (equal <= 0)
2552 return equal;
2553 }
2554
2555 return 1;
2556}
2557
2558/* Recursively compare two multi-dimensional arrays that have the same
2559 logical structure. Assumption: ndim >= 1. */
2560static int
2561cmp_rec(const char *p, const char *q,
2562 Py_ssize_t ndim, const Py_ssize_t *shape,
2563 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2564 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002565 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002566{
2567 Py_ssize_t i;
2568 int equal;
2569
2570 assert(ndim >= 1);
2571 assert(shape != NULL);
2572 assert(pstrides != NULL);
2573 assert(qstrides != NULL);
2574
2575 if (ndim == 1) {
2576 return cmp_base(p, q, shape,
2577 pstrides, psuboffsets,
2578 qstrides, qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002579 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002580 }
2581
2582 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2583 const char *xp = ADJUST_PTR(p, psuboffsets);
2584 const char *xq = ADJUST_PTR(q, qsuboffsets);
2585 equal = cmp_rec(xp, xq, ndim-1, shape+1,
2586 pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2587 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002588 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002589 if (equal <= 0)
2590 return equal;
2591 }
2592
2593 return 1;
2594}
2595
2596static PyObject *
2597memory_richcompare(PyObject *v, PyObject *w, int op)
2598{
2599 PyObject *res;
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002600 Py_buffer wbuf, *vv;
2601 Py_buffer *ww = NULL;
2602 struct unpacker *unpack_v = NULL;
2603 struct unpacker *unpack_w = NULL;
2604 char vfmt, wfmt;
2605 int equal = MV_COMPARE_NOT_IMPL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002606
2607 if (op != Py_EQ && op != Py_NE)
2608 goto result; /* Py_NotImplemented */
2609
2610 assert(PyMemoryView_Check(v));
2611 if (BASE_INACCESSIBLE(v)) {
2612 equal = (v == w);
2613 goto result;
2614 }
2615 vv = VIEW_ADDR(v);
2616
2617 if (PyMemoryView_Check(w)) {
2618 if (BASE_INACCESSIBLE(w)) {
2619 equal = (v == w);
2620 goto result;
2621 }
2622 ww = VIEW_ADDR(w);
2623 }
2624 else {
2625 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2626 PyErr_Clear();
2627 goto result; /* Py_NotImplemented */
2628 }
2629 ww = &wbuf;
2630 }
2631
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002632 if (!equiv_shape(vv, ww)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002633 PyErr_Clear();
2634 equal = 0;
2635 goto result;
2636 }
2637
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002638 /* Use fast unpacking for identical primitive C type formats. */
2639 if (get_native_fmtchar(&vfmt, vv->format) < 0)
2640 vfmt = '_';
2641 if (get_native_fmtchar(&wfmt, ww->format) < 0)
2642 wfmt = '_';
2643 if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
2644 /* Use struct module unpacking. NOTE: Even for equal format strings,
2645 memcmp() cannot be used for item comparison since it would give
2646 incorrect results in the case of NaNs or uninitialized padding
2647 bytes. */
2648 vfmt = '_';
2649 unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
2650 if (unpack_v == NULL) {
2651 equal = fix_struct_error_int();
2652 goto result;
2653 }
2654 unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
2655 if (unpack_w == NULL) {
2656 equal = fix_struct_error_int();
2657 goto result;
2658 }
2659 }
2660
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002661 if (vv->ndim == 0) {
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002662 equal = unpack_cmp(vv->buf, ww->buf,
2663 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002664 }
2665 else if (vv->ndim == 1) {
2666 equal = cmp_base(vv->buf, ww->buf, vv->shape,
2667 vv->strides, vv->suboffsets,
2668 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002669 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002670 }
2671 else {
2672 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2673 vv->strides, vv->suboffsets,
2674 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002675 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002676 }
2677
2678result:
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002679 if (equal < 0) {
2680 if (equal == MV_COMPARE_NOT_IMPL)
2681 res = Py_NotImplemented;
2682 else /* exception */
2683 res = NULL;
2684 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002685 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2686 res = Py_True;
2687 else
2688 res = Py_False;
2689
2690 if (ww == &wbuf)
2691 PyBuffer_Release(ww);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002692
2693 unpacker_free(unpack_v);
2694 unpacker_free(unpack_w);
2695
2696 Py_XINCREF(res);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002697 return res;
2698}
2699
2700/**************************************************************************/
2701/* Hash */
2702/**************************************************************************/
2703
2704static Py_hash_t
2705memory_hash(PyMemoryViewObject *self)
2706{
2707 if (self->hash == -1) {
2708 Py_buffer *view = &self->view;
2709 char *mem = view->buf;
2710
2711 CHECK_RELEASED_INT(self);
2712
2713 if (!view->readonly) {
2714 PyErr_SetString(PyExc_ValueError,
2715 "cannot hash writable memoryview object");
2716 return -1;
2717 }
2718 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2719 /* Keep the original error message */
2720 return -1;
2721 }
2722
2723 if (!MV_C_CONTIGUOUS(self->flags)) {
2724 mem = PyMem_Malloc(view->len);
2725 if (mem == NULL) {
2726 PyErr_NoMemory();
2727 return -1;
2728 }
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002729 if (buffer_to_contiguous(mem, view, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002730 PyMem_Free(mem);
2731 return -1;
2732 }
2733 }
2734
2735 /* Can't fail */
2736 self->hash = _Py_HashBytes((unsigned char *)mem, view->len);
2737
2738 if (mem != view->buf)
2739 PyMem_Free(mem);
2740 }
2741
2742 return self->hash;
2743}
2744
2745
2746/**************************************************************************/
2747/* getters */
2748/**************************************************************************/
2749
2750static PyObject *
2751_IntTupleFromSsizet(int len, Py_ssize_t *vals)
2752{
2753 int i;
2754 PyObject *o;
2755 PyObject *intTuple;
2756
2757 if (vals == NULL)
2758 return PyTuple_New(0);
2759
2760 intTuple = PyTuple_New(len);
2761 if (!intTuple)
2762 return NULL;
2763 for (i=0; i<len; i++) {
2764 o = PyLong_FromSsize_t(vals[i]);
2765 if (!o) {
2766 Py_DECREF(intTuple);
2767 return NULL;
2768 }
2769 PyTuple_SET_ITEM(intTuple, i, o);
2770 }
2771 return intTuple;
2772}
2773
2774static PyObject *
2775memory_obj_get(PyMemoryViewObject *self)
2776{
2777 Py_buffer *view = &self->view;
2778
2779 CHECK_RELEASED(self);
2780 if (view->obj == NULL) {
2781 Py_RETURN_NONE;
2782 }
2783 Py_INCREF(view->obj);
2784 return view->obj;
2785}
2786
2787static PyObject *
2788memory_nbytes_get(PyMemoryViewObject *self)
2789{
2790 CHECK_RELEASED(self);
2791 return PyLong_FromSsize_t(self->view.len);
2792}
2793
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002794static PyObject *
2795memory_format_get(PyMemoryViewObject *self)
2796{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002797 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002798 return PyUnicode_FromString(self->view.format);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002799}
2800
2801static PyObject *
2802memory_itemsize_get(PyMemoryViewObject *self)
2803{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002804 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002805 return PyLong_FromSsize_t(self->view.itemsize);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002806}
2807
2808static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002809memory_shape_get(PyMemoryViewObject *self)
2810{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002811 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002812 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002813}
2814
2815static PyObject *
2816memory_strides_get(PyMemoryViewObject *self)
2817{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002818 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002819 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002820}
2821
2822static PyObject *
2823memory_suboffsets_get(PyMemoryViewObject *self)
2824{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002825 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002826 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002827}
2828
2829static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002830memory_readonly_get(PyMemoryViewObject *self)
2831{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002832 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002833 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002834}
2835
2836static PyObject *
2837memory_ndim_get(PyMemoryViewObject *self)
2838{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002839 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002840 return PyLong_FromLong(self->view.ndim);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002841}
2842
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002843static PyObject *
2844memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2845{
2846 CHECK_RELEASED(self);
2847 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
2848}
2849
2850static PyObject *
2851memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2852{
2853 CHECK_RELEASED(self);
2854 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
2855}
2856
2857static PyObject *
2858memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2859{
2860 CHECK_RELEASED(self);
2861 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
2862}
2863
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002864PyDoc_STRVAR(memory_obj_doc,
2865 "The underlying object of the memoryview.");
2866PyDoc_STRVAR(memory_nbytes_doc,
2867 "The amount of space in bytes that the array would use in\n"
2868 " a contiguous representation.");
2869PyDoc_STRVAR(memory_readonly_doc,
2870 "A bool indicating whether the memory is read only.");
2871PyDoc_STRVAR(memory_itemsize_doc,
2872 "The size in bytes of each element of the memoryview.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002873PyDoc_STRVAR(memory_format_doc,
2874 "A string containing the format (in struct module style)\n"
2875 " for each element in the view.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002876PyDoc_STRVAR(memory_ndim_doc,
2877 "An integer indicating how many dimensions of a multi-dimensional\n"
2878 " array the memory represents.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002879PyDoc_STRVAR(memory_shape_doc,
2880 "A tuple of ndim integers giving the shape of the memory\n"
2881 " as an N-dimensional array.");
2882PyDoc_STRVAR(memory_strides_doc,
2883 "A tuple of ndim integers giving the size in bytes to access\n"
2884 " each element for each dimension of the array.");
2885PyDoc_STRVAR(memory_suboffsets_doc,
2886 "A tuple of integers used internally for PIL-style arrays.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002887PyDoc_STRVAR(memory_c_contiguous_doc,
2888 "A bool indicating whether the memory is C contiguous.");
2889PyDoc_STRVAR(memory_f_contiguous_doc,
2890 "A bool indicating whether the memory is Fortran contiguous.");
2891PyDoc_STRVAR(memory_contiguous_doc,
2892 "A bool indicating whether the memory is contiguous.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002893
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002894static PyGetSetDef memory_getsetlist[] = {
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002895 {"obj", (getter)memory_obj_get, NULL, memory_obj_doc},
2896 {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc},
Alexander Belopolskye370c382012-09-03 16:43:55 -04002897 {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc},
2898 {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc},
2899 {"format", (getter)memory_format_get, NULL, memory_format_doc},
2900 {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc},
2901 {"shape", (getter)memory_shape_get, NULL, memory_shape_doc},
2902 {"strides", (getter)memory_strides_get, NULL, memory_strides_doc},
2903 {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002904 {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc},
2905 {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc},
2906 {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc},
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002907 {NULL, NULL, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002908};
2909
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04002910PyDoc_STRVAR(memory_release_doc,
2911"M.release() -> None\n\
2912\n\
2913Release the underlying buffer exposed by the memoryview object.");
2914PyDoc_STRVAR(memory_tobytes_doc,
2915"M.tobytes() -> bytes\n\
2916\n\
2917Return the data in the buffer as a byte string.");
2918PyDoc_STRVAR(memory_tolist_doc,
2919"M.tolist() -> list\n\
2920\n\
2921Return the data in the buffer as a list of elements.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002922PyDoc_STRVAR(memory_cast_doc,
2923"M.cast(format[, shape]) -> memoryview\n\
2924\n\
2925Cast a memoryview to a new format or shape.");
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002926
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002927static PyMethodDef memory_methods[] = {
Alexander Belopolskye370c382012-09-03 16:43:55 -04002928 {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
2929 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc},
2930 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04002931 {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
Stefan Krahe4c07992012-07-28 14:10:02 +02002932 {"__enter__", memory_enter, METH_NOARGS, NULL},
2933 {"__exit__", memory_exit, METH_VARARGS, NULL},
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002934 {NULL, NULL}
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002935};
2936
2937
2938PyTypeObject PyMemoryView_Type = {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002939 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002940 "memoryview", /* tp_name */
2941 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */
2942 sizeof(Py_ssize_t), /* tp_itemsize */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002943 (destructor)memory_dealloc, /* tp_dealloc */
2944 0, /* tp_print */
2945 0, /* tp_getattr */
2946 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002947 0, /* tp_reserved */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002948 (reprfunc)memory_repr, /* tp_repr */
2949 0, /* tp_as_number */
Raymond Hettinger159eac92009-06-23 20:38:54 +00002950 &memory_as_sequence, /* tp_as_sequence */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002951 &memory_as_mapping, /* tp_as_mapping */
Antoine Pitrouce4a9da2011-11-21 20:46:33 +01002952 (hashfunc)memory_hash, /* tp_hash */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002953 0, /* tp_call */
Benjamin Peterson87618552009-02-08 15:00:52 +00002954 0, /* tp_str */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002955 PyObject_GenericGetAttr, /* tp_getattro */
2956 0, /* tp_setattro */
2957 &memory_as_buffer, /* tp_as_buffer */
2958 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2959 memory_doc, /* tp_doc */
2960 (traverseproc)memory_traverse, /* tp_traverse */
2961 (inquiry)memory_clear, /* tp_clear */
2962 memory_richcompare, /* tp_richcompare */
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01002963 offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002964 0, /* tp_iter */
2965 0, /* tp_iternext */
2966 memory_methods, /* tp_methods */
2967 0, /* tp_members */
2968 memory_getsetlist, /* tp_getset */
2969 0, /* tp_base */
2970 0, /* tp_dict */
2971 0, /* tp_descr_get */
2972 0, /* tp_descr_set */
2973 0, /* tp_dictoffset */
2974 0, /* tp_init */
2975 0, /* tp_alloc */
2976 memory_new, /* tp_new */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002977};