blob: a873ac1ec1ea5f325ba27654158aaf254b9099ff [file] [log] [blame]
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001/* Memoryview object implementation */
2
3#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01004#include "pycore_object.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01005#include "pycore_pymem.h"
6#include "pycore_pystate.h"
Gregory P. Smith8cb65692015-04-25 23:22:26 +00007#include "pystrhex.h"
Stefan Krah9a2d99e2012-02-25 12:24:21 +01008#include <stddef.h>
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00009
Gregory P. Smith0c2f9302019-05-29 11:46:58 -070010/*[clinic input]
11class memoryview "PyMemoryViewObject *" "&PyMemoryView_Type"
12[clinic start generated code]*/
13/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e2e49d2192835219]*/
14
15#include "clinic/memoryobject.c.h"
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000016
Stefan Krah9a2d99e2012-02-25 12:24:21 +010017/****************************************************************************/
18/* ManagedBuffer Object */
19/****************************************************************************/
20
21/*
22 ManagedBuffer Object:
23 ---------------------
24
25 The purpose of this object is to facilitate the handling of chained
26 memoryviews that have the same underlying exporting object. PEP-3118
27 allows the underlying object to change while a view is exported. This
28 could lead to unexpected results when constructing a new memoryview
29 from an existing memoryview.
30
31 Rather than repeatedly redirecting buffer requests to the original base
32 object, all chained memoryviews use a single buffer snapshot. This
33 snapshot is generated by the constructor _PyManagedBuffer_FromObject().
34
35 Ownership rules:
36 ----------------
37
38 The master buffer inside a managed buffer is filled in by the original
39 base object. shape, strides, suboffsets and format are read-only for
40 all consumers.
41
42 A memoryview's buffer is a private copy of the exporter's buffer. shape,
43 strides and suboffsets belong to the memoryview and are thus writable.
44
45 If a memoryview itself exports several buffers via memory_getbuf(), all
46 buffer copies share shape, strides and suboffsets. In this case, the
47 arrays are NOT writable.
48
49 Reference count assumptions:
50 ----------------------------
51
52 The 'obj' member of a Py_buffer must either be NULL or refer to the
53 exporting base object. In the Python codebase, all getbufferprocs
54 return a new reference to view.obj (example: bytes_buffer_getbuffer()).
55
56 PyBuffer_Release() decrements view.obj (if non-NULL), so the
57 releasebufferprocs must NOT decrement view.obj.
58*/
59
60
Stefan Krah9a2d99e2012-02-25 12:24:21 +010061#define CHECK_MBUF_RELEASED(mbuf) \
62 if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \
63 PyErr_SetString(PyExc_ValueError, \
64 "operation forbidden on released memoryview object"); \
65 return NULL; \
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000066 }
67
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000068
Benjamin Peterson82cce4c2016-09-08 11:56:06 -070069static inline _PyManagedBufferObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +010070mbuf_alloc(void)
Antoine Pitroubc420402008-12-07 20:14:49 +000071{
Stefan Krah9a2d99e2012-02-25 12:24:21 +010072 _PyManagedBufferObject *mbuf;
73
74 mbuf = (_PyManagedBufferObject *)
75 PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type);
76 if (mbuf == NULL)
77 return NULL;
78 mbuf->flags = 0;
79 mbuf->exports = 0;
80 mbuf->master.obj = NULL;
81 _PyObject_GC_TRACK(mbuf);
82
83 return mbuf;
84}
85
86static PyObject *
87_PyManagedBuffer_FromObject(PyObject *base)
88{
89 _PyManagedBufferObject *mbuf;
90
91 mbuf = mbuf_alloc();
92 if (mbuf == NULL)
93 return NULL;
94
95 if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) {
Stefan Krah1649c1b2012-03-05 17:45:17 +010096 mbuf->master.obj = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +010097 Py_DECREF(mbuf);
98 return NULL;
99 }
100
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100101 return (PyObject *)mbuf;
Antoine Pitrouc3b39242009-01-03 16:59:18 +0000102}
103
104static void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100105mbuf_release(_PyManagedBufferObject *self)
Antoine Pitrouc3b39242009-01-03 16:59:18 +0000106{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100107 if (self->flags&_Py_MANAGED_BUFFER_RELEASED)
108 return;
109
110 /* NOTE: at this point self->exports can still be > 0 if this function
111 is called from mbuf_clear() to break up a reference cycle. */
112 self->flags |= _Py_MANAGED_BUFFER_RELEASED;
113
114 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
115 _PyObject_GC_UNTRACK(self);
116 PyBuffer_Release(&self->master);
117}
118
119static void
120mbuf_dealloc(_PyManagedBufferObject *self)
121{
122 assert(self->exports == 0);
123 mbuf_release(self);
124 if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT)
125 PyMem_Free(self->master.format);
126 PyObject_GC_Del(self);
Antoine Pitroubc420402008-12-07 20:14:49 +0000127}
128
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000129static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100130mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000131{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100132 Py_VISIT(self->master.obj);
133 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000134}
135
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100136static int
137mbuf_clear(_PyManagedBufferObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000138{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100139 assert(self->exports >= 0);
140 mbuf_release(self);
141 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000142}
143
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100144PyTypeObject _PyManagedBuffer_Type = {
145 PyVarObject_HEAD_INIT(&PyType_Type, 0)
146 "managedbuffer",
147 sizeof(_PyManagedBufferObject),
148 0,
149 (destructor)mbuf_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200150 0, /* tp_vectorcall_offset */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100151 0, /* tp_getattr */
152 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200153 0, /* tp_as_async */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100154 0, /* tp_repr */
155 0, /* tp_as_number */
156 0, /* tp_as_sequence */
157 0, /* tp_as_mapping */
158 0, /* tp_hash */
159 0, /* tp_call */
160 0, /* tp_str */
161 PyObject_GenericGetAttr, /* tp_getattro */
162 0, /* tp_setattro */
163 0, /* tp_as_buffer */
164 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
165 0, /* tp_doc */
166 (traverseproc)mbuf_traverse, /* tp_traverse */
167 (inquiry)mbuf_clear /* tp_clear */
168};
169
170
171/****************************************************************************/
172/* MemoryView Object */
173/****************************************************************************/
174
175/* In the process of breaking reference cycles mbuf_release() can be
176 called before memory_release(). */
177#define BASE_INACCESSIBLE(mv) \
178 (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \
179 ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED)
180
181#define CHECK_RELEASED(mv) \
182 if (BASE_INACCESSIBLE(mv)) { \
183 PyErr_SetString(PyExc_ValueError, \
184 "operation forbidden on released memoryview object"); \
185 return NULL; \
186 }
187
188#define CHECK_RELEASED_INT(mv) \
189 if (BASE_INACCESSIBLE(mv)) { \
190 PyErr_SetString(PyExc_ValueError, \
191 "operation forbidden on released memoryview object"); \
192 return -1; \
193 }
194
195#define CHECK_LIST_OR_TUPLE(v) \
196 if (!PyList_Check(v) && !PyTuple_Check(v)) { \
197 PyErr_SetString(PyExc_TypeError, \
198 #v " must be a list or a tuple"); \
199 return NULL; \
200 }
201
202#define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view)
203
204/* Check for the presence of suboffsets in the first dimension. */
Antoine Pitrou31084ba2015-03-19 23:29:36 +0100205#define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100206/* Adjust ptr if suboffsets are present. */
Antoine Pitrou31084ba2015-03-19 23:29:36 +0100207#define ADJUST_PTR(ptr, suboffsets, dim) \
208 (HAVE_PTR(suboffsets, dim) ? *((char**)ptr) + suboffsets[dim] : ptr)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100209
210/* Memoryview buffer properties */
211#define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
212#define MV_F_CONTIGUOUS(flags) \
213 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
214#define MV_ANY_CONTIGUOUS(flags) \
215 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
216
217/* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */
218#define MV_CONTIGUOUS_NDIM1(view) \
219 ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize)
220
221/* getbuffer() requests */
222#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
223#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
224#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
225#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
226#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
227#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
228#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
229#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
230
231
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000232PyDoc_STRVAR(memory_doc,
Stefan Krah195319e2016-12-30 12:23:35 +0100233"memoryview(object)\n--\n\
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000234\n\
235Create a new memoryview object which references the given object.");
236
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100237
238/**************************************************************************/
239/* Copy memoryview buffers */
240/**************************************************************************/
241
242/* The functions in this section take a source and a destination buffer
243 with the same logical structure: format, itemsize, ndim and shape
244 are identical, with ndim > 0.
245
246 NOTE: All buffers are assumed to have PyBUF_FULL information, which
247 is the case for memoryviews! */
248
249
250/* Assumptions: ndim >= 1. The macro tests for a corner case that should
251 perhaps be explicitly forbidden in the PEP. */
252#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
253 (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
254
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700255static inline int
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000256last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100257{
258 assert(dest->ndim > 0 && src->ndim > 0);
259 return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) &&
260 !HAVE_SUBOFFSETS_IN_LAST_DIM(src) &&
261 dest->strides[dest->ndim-1] == dest->itemsize &&
262 src->strides[src->ndim-1] == src->itemsize);
263}
264
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000265/* This is not a general function for determining format equivalence.
266 It is used in copy_single() and copy_buffer() to weed out non-matching
267 formats. Skipping the '@' character is specifically used in slice
268 assignments, where the lvalue is already known to have a single character
269 format. This is a performance hack that could be rewritten (if properly
270 benchmarked). */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700271static inline int
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000272equiv_format(const Py_buffer *dest, const Py_buffer *src)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100273{
274 const char *dfmt, *sfmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100275
276 assert(dest->format && src->format);
277 dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format;
278 sfmt = src->format[0] == '@' ? src->format+1 : src->format;
279
280 if (strcmp(dfmt, sfmt) != 0 ||
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000281 dest->itemsize != src->itemsize) {
282 return 0;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100283 }
284
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000285 return 1;
286}
287
288/* Two shapes are equivalent if they are either equal or identical up
289 to a zero element at the same position. For example, in NumPy arrays
290 the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700291static inline int
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000292equiv_shape(const Py_buffer *dest, const Py_buffer *src)
293{
294 int i;
295
296 if (dest->ndim != src->ndim)
297 return 0;
298
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100299 for (i = 0; i < dest->ndim; i++) {
300 if (dest->shape[i] != src->shape[i])
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000301 return 0;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100302 if (dest->shape[i] == 0)
303 break;
304 }
305
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000306 return 1;
307}
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100308
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000309/* Check that the logical structure of the destination and source buffers
310 is identical. */
311static int
312equiv_structure(const Py_buffer *dest, const Py_buffer *src)
313{
314 if (!equiv_format(dest, src) ||
315 !equiv_shape(dest, src)) {
316 PyErr_SetString(PyExc_ValueError,
Stefan Krah674a42b2013-02-19 13:44:49 +0100317 "memoryview assignment: lvalue and rvalue have different "
318 "structures");
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000319 return 0;
320 }
321
322 return 1;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100323}
324
325/* Base case for recursive multi-dimensional copying. Contiguous arrays are
326 copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
327 sizeof(mem) == shape[0] * itemsize. */
328static void
329copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
330 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
331 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
332 char *mem)
333{
334 if (mem == NULL) { /* contiguous */
335 Py_ssize_t size = shape[0] * itemsize;
336 if (dptr + size < sptr || sptr + size < dptr)
337 memcpy(dptr, sptr, size); /* no overlapping */
338 else
339 memmove(dptr, sptr, size);
340 }
341 else {
342 char *p;
343 Py_ssize_t i;
344 for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +0100345 char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100346 memcpy(p, xsptr, itemsize);
347 }
348 for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +0100349 char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100350 memcpy(xdptr, p, itemsize);
351 }
352 }
353
354}
355
356/* Recursively copy a source buffer to a destination buffer. The two buffers
357 have the same ndim, shape and itemsize. */
358static void
359copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
360 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
361 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
362 char *mem)
363{
364 Py_ssize_t i;
365
366 assert(ndim >= 1);
367
368 if (ndim == 1) {
369 copy_base(shape, itemsize,
370 dptr, dstrides, dsuboffsets,
371 sptr, sstrides, ssuboffsets,
372 mem);
373 return;
374 }
375
376 for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +0100377 char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0);
378 char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100379
380 copy_rec(shape+1, ndim-1, itemsize,
381 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
382 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
383 mem);
384 }
385}
386
387/* Faster copying of one-dimensional arrays. */
388static int
389copy_single(Py_buffer *dest, Py_buffer *src)
390{
391 char *mem = NULL;
392
393 assert(dest->ndim == 1);
394
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000395 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100396 return -1;
397
398 if (!last_dim_is_contiguous(dest, src)) {
399 mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
400 if (mem == NULL) {
401 PyErr_NoMemory();
402 return -1;
403 }
404 }
405
406 copy_base(dest->shape, dest->itemsize,
407 dest->buf, dest->strides, dest->suboffsets,
408 src->buf, src->strides, src->suboffsets,
409 mem);
410
411 if (mem)
412 PyMem_Free(mem);
413
414 return 0;
415}
416
417/* Recursively copy src to dest. Both buffers must have the same basic
418 structure. Copying is atomic, the function never fails with a partial
419 copy. */
420static int
421copy_buffer(Py_buffer *dest, Py_buffer *src)
422{
423 char *mem = NULL;
424
425 assert(dest->ndim > 0);
426
Nick Coghlan06e1ab02012-08-25 17:59:50 +1000427 if (!equiv_structure(dest, src))
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100428 return -1;
429
430 if (!last_dim_is_contiguous(dest, src)) {
431 mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
432 if (mem == NULL) {
433 PyErr_NoMemory();
434 return -1;
435 }
436 }
437
438 copy_rec(dest->shape, dest->ndim, dest->itemsize,
439 dest->buf, dest->strides, dest->suboffsets,
440 src->buf, src->strides, src->suboffsets,
441 mem);
442
443 if (mem)
444 PyMem_Free(mem);
445
446 return 0;
447}
448
449/* Initialize strides for a C-contiguous array. */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700450static inline void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100451init_strides_from_shape(Py_buffer *view)
452{
453 Py_ssize_t i;
454
455 assert(view->ndim > 0);
456
457 view->strides[view->ndim-1] = view->itemsize;
458 for (i = view->ndim-2; i >= 0; i--)
459 view->strides[i] = view->strides[i+1] * view->shape[i+1];
460}
461
462/* Initialize strides for a Fortran-contiguous array. */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700463static inline void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100464init_fortran_strides_from_shape(Py_buffer *view)
465{
466 Py_ssize_t i;
467
468 assert(view->ndim > 0);
469
470 view->strides[0] = view->itemsize;
471 for (i = 1; i < view->ndim; i++)
472 view->strides[i] = view->strides[i-1] * view->shape[i-1];
473}
474
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200475/* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran)
476 or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100477 len(mem) == src->len. */
478static int
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200479buffer_to_contiguous(char *mem, Py_buffer *src, char order)
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100480{
481 Py_buffer dest;
482 Py_ssize_t *strides;
483 int ret;
484
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200485 assert(src->ndim >= 1);
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100486 assert(src->shape != NULL);
487 assert(src->strides != NULL);
488
489 strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
490 if (strides == NULL) {
491 PyErr_NoMemory();
492 return -1;
493 }
494
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200495 /* initialize dest */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100496 dest = *src;
497 dest.buf = mem;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200498 /* shape is constant and shared: the logical representation of the
499 array is unaltered. */
500
501 /* The physical representation determined by strides (and possibly
502 suboffsets) may change. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100503 dest.strides = strides;
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200504 if (order == 'C' || order == 'A') {
505 init_strides_from_shape(&dest);
506 }
507 else {
508 init_fortran_strides_from_shape(&dest);
509 }
510
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100511 dest.suboffsets = NULL;
512
513 ret = copy_buffer(&dest, src);
514
515 PyMem_Free(strides);
516 return ret;
517}
518
519
520/****************************************************************************/
521/* Constructors */
522/****************************************************************************/
523
524/* Initialize values that are shared with the managed buffer. */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700525static inline void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100526init_shared_values(Py_buffer *dest, const Py_buffer *src)
527{
528 dest->obj = src->obj;
529 dest->buf = src->buf;
530 dest->len = src->len;
531 dest->itemsize = src->itemsize;
532 dest->readonly = src->readonly;
533 dest->format = src->format ? src->format : "B";
534 dest->internal = src->internal;
535}
536
537/* Copy shape and strides. Reconstruct missing values. */
538static void
539init_shape_strides(Py_buffer *dest, const Py_buffer *src)
540{
541 Py_ssize_t i;
542
543 if (src->ndim == 0) {
544 dest->shape = NULL;
545 dest->strides = NULL;
546 return;
547 }
548 if (src->ndim == 1) {
549 dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
550 dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
551 return;
552 }
553
554 for (i = 0; i < src->ndim; i++)
555 dest->shape[i] = src->shape[i];
556 if (src->strides) {
557 for (i = 0; i < src->ndim; i++)
558 dest->strides[i] = src->strides[i];
559 }
560 else {
561 init_strides_from_shape(dest);
562 }
563}
564
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700565static inline void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100566init_suboffsets(Py_buffer *dest, const Py_buffer *src)
567{
568 Py_ssize_t i;
569
570 if (src->suboffsets == NULL) {
571 dest->suboffsets = NULL;
572 return;
573 }
574 for (i = 0; i < src->ndim; i++)
575 dest->suboffsets[i] = src->suboffsets[i];
576}
577
578/* len = product(shape) * itemsize */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700579static inline void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100580init_len(Py_buffer *view)
581{
582 Py_ssize_t i, len;
583
584 len = 1;
585 for (i = 0; i < view->ndim; i++)
586 len *= view->shape[i];
587 len *= view->itemsize;
588
589 view->len = len;
590}
591
592/* Initialize memoryview buffer properties. */
593static void
594init_flags(PyMemoryViewObject *mv)
595{
596 const Py_buffer *view = &mv->view;
597 int flags = 0;
598
599 switch (view->ndim) {
600 case 0:
601 flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
602 _Py_MEMORYVIEW_FORTRAN);
603 break;
604 case 1:
605 if (MV_CONTIGUOUS_NDIM1(view))
606 flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
607 break;
608 default:
609 if (PyBuffer_IsContiguous(view, 'C'))
610 flags |= _Py_MEMORYVIEW_C;
611 if (PyBuffer_IsContiguous(view, 'F'))
612 flags |= _Py_MEMORYVIEW_FORTRAN;
613 break;
614 }
615
616 if (view->suboffsets) {
617 flags |= _Py_MEMORYVIEW_PIL;
618 flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
619 }
620
621 mv->flags = flags;
622}
623
624/* Allocate a new memoryview and perform basic initialization. New memoryviews
625 are exclusively created through the mbuf_add functions. */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -0700626static inline PyMemoryViewObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100627memory_alloc(int ndim)
628{
629 PyMemoryViewObject *mv;
630
631 mv = (PyMemoryViewObject *)
632 PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
633 if (mv == NULL)
634 return NULL;
635
636 mv->mbuf = NULL;
637 mv->hash = -1;
638 mv->flags = 0;
639 mv->exports = 0;
640 mv->view.ndim = ndim;
641 mv->view.shape = mv->ob_array;
642 mv->view.strides = mv->ob_array + ndim;
643 mv->view.suboffsets = mv->ob_array + 2 * ndim;
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +0100644 mv->weakreflist = NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100645
646 _PyObject_GC_TRACK(mv);
647 return mv;
648}
649
650/*
651 Return a new memoryview that is registered with mbuf. If src is NULL,
652 use mbuf->master as the underlying buffer. Otherwise, use src.
653
654 The new memoryview has full buffer information: shape and strides
655 are always present, suboffsets as needed. Arrays are copied to
656 the memoryview's ob_array field.
657 */
658static PyObject *
659mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
660{
661 PyMemoryViewObject *mv;
662 Py_buffer *dest;
663
664 if (src == NULL)
665 src = &mbuf->master;
666
667 if (src->ndim > PyBUF_MAX_NDIM) {
668 PyErr_SetString(PyExc_ValueError,
669 "memoryview: number of dimensions must not exceed "
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200670 Py_STRINGIFY(PyBUF_MAX_NDIM));
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100671 return NULL;
672 }
673
674 mv = memory_alloc(src->ndim);
675 if (mv == NULL)
676 return NULL;
677
678 dest = &mv->view;
679 init_shared_values(dest, src);
680 init_shape_strides(dest, src);
681 init_suboffsets(dest, src);
682 init_flags(mv);
683
684 mv->mbuf = mbuf;
685 Py_INCREF(mbuf);
686 mbuf->exports++;
687
688 return (PyObject *)mv;
689}
690
691/* Register an incomplete view: shape, strides, suboffsets and flags still
692 need to be initialized. Use 'ndim' instead of src->ndim to determine the
693 size of the memoryview's ob_array.
694
695 Assumption: ndim <= PyBUF_MAX_NDIM. */
696static PyObject *
697mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
698 int ndim)
699{
700 PyMemoryViewObject *mv;
701 Py_buffer *dest;
702
703 if (src == NULL)
704 src = &mbuf->master;
705
706 assert(ndim <= PyBUF_MAX_NDIM);
707
708 mv = memory_alloc(ndim);
709 if (mv == NULL)
710 return NULL;
711
712 dest = &mv->view;
713 init_shared_values(dest, src);
714
715 mv->mbuf = mbuf;
716 Py_INCREF(mbuf);
717 mbuf->exports++;
718
719 return (PyObject *)mv;
720}
721
722/* Expose a raw memory area as a view of contiguous bytes. flags can be
723 PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
724 The memoryview has complete buffer information. */
725PyObject *
726PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
727{
728 _PyManagedBufferObject *mbuf;
729 PyObject *mv;
730 int readonly;
731
732 assert(mem != NULL);
733 assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
734
735 mbuf = mbuf_alloc();
736 if (mbuf == NULL)
737 return NULL;
738
739 readonly = (flags == PyBUF_WRITE) ? 0 : 1;
740 (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
741 PyBUF_FULL_RO);
742
743 mv = mbuf_add_view(mbuf, NULL);
744 Py_DECREF(mbuf);
745
746 return mv;
747}
748
749/* Create a memoryview from a given Py_buffer. For simple byte views,
750 PyMemoryView_FromMemory() should be used instead.
751 This function is the only entry point that can create a master buffer
752 without full information. Because of this fact init_shape_strides()
753 must be able to reconstruct missing values. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000754PyObject *
Antoine Pitrouee58fa42008-08-19 18:22:14 +0000755PyMemoryView_FromBuffer(Py_buffer *info)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000756{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100757 _PyManagedBufferObject *mbuf;
758 PyObject *mv;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000759
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000760 if (info->buf == NULL) {
761 PyErr_SetString(PyExc_ValueError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100762 "PyMemoryView_FromBuffer(): info->buf must not be NULL");
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000763 return NULL;
764 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100765
766 mbuf = mbuf_alloc();
767 if (mbuf == NULL)
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000768 return NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100769
770 /* info->obj is either NULL or a borrowed reference. This reference
771 should not be decremented in PyBuffer_Release(). */
772 mbuf->master = *info;
773 mbuf->master.obj = NULL;
774
775 mv = mbuf_add_view(mbuf, NULL);
776 Py_DECREF(mbuf);
777
778 return mv;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000779}
780
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100781/* Create a memoryview from an object that implements the buffer protocol.
782 If the object is a memoryview, the new memoryview must be registered
783 with the same managed buffer. Otherwise, a new managed buffer is created. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000784PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100785PyMemoryView_FromObject(PyObject *v)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000786{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100787 _PyManagedBufferObject *mbuf;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000788
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100789 if (PyMemoryView_Check(v)) {
790 PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
791 CHECK_RELEASED(mv);
792 return mbuf_add_view(mv->mbuf, &mv->view);
793 }
794 else if (PyObject_CheckBuffer(v)) {
795 PyObject *ret;
796 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
797 if (mbuf == NULL)
798 return NULL;
799 ret = mbuf_add_view(mbuf, NULL);
800 Py_DECREF(mbuf);
801 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000802 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000803
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100804 PyErr_Format(PyExc_TypeError,
R David Murray861470c2014-10-05 11:47:01 -0400805 "memoryview: a bytes-like object is required, not '%.200s'",
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100806 Py_TYPE(v)->tp_name);
807 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000808}
809
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100810/* Copy the format string from a base object that might vanish. */
811static int
812mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
813{
814 if (fmt != NULL) {
815 char *cp = PyMem_Malloc(strlen(fmt)+1);
816 if (cp == NULL) {
817 PyErr_NoMemory();
818 return -1;
819 }
820 mbuf->master.format = strcpy(cp, fmt);
821 mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
822 }
823
824 return 0;
825}
826
827/*
828 Return a memoryview that is based on a contiguous copy of src.
829 Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
830
831 Ownership rules:
832 1) As usual, the returned memoryview has a private copy
833 of src->shape, src->strides and src->suboffsets.
834 2) src->format is copied to the master buffer and released
835 in mbuf_dealloc(). The releasebufferproc of the bytes
836 object is NULL, so it does not matter that mbuf_release()
837 passes the altered format pointer to PyBuffer_Release().
838*/
839static PyObject *
840memory_from_contiguous_copy(Py_buffer *src, char order)
841{
842 _PyManagedBufferObject *mbuf;
843 PyMemoryViewObject *mv;
844 PyObject *bytes;
845 Py_buffer *dest;
846 int i;
847
848 assert(src->ndim > 0);
849 assert(src->shape != NULL);
850
851 bytes = PyBytes_FromStringAndSize(NULL, src->len);
852 if (bytes == NULL)
853 return NULL;
854
855 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
856 Py_DECREF(bytes);
857 if (mbuf == NULL)
858 return NULL;
859
860 if (mbuf_copy_format(mbuf, src->format) < 0) {
861 Py_DECREF(mbuf);
862 return NULL;
863 }
864
865 mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
866 Py_DECREF(mbuf);
867 if (mv == NULL)
868 return NULL;
869
870 dest = &mv->view;
871
872 /* shared values are initialized correctly except for itemsize */
873 dest->itemsize = src->itemsize;
874
875 /* shape and strides */
876 for (i = 0; i < src->ndim; i++) {
877 dest->shape[i] = src->shape[i];
878 }
879 if (order == 'C' || order == 'A') {
880 init_strides_from_shape(dest);
881 }
882 else {
883 init_fortran_strides_from_shape(dest);
884 }
885 /* suboffsets */
886 dest->suboffsets = NULL;
887
888 /* flags */
889 init_flags(mv);
890
891 if (copy_buffer(dest, src) < 0) {
892 Py_DECREF(mv);
893 return NULL;
894 }
895
896 return (PyObject *)mv;
897}
898
899/*
900 Return a new memoryview object based on a contiguous exporter with
901 buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
902 The logical structure of the input and output buffers is the same
903 (i.e. tolist(input) == tolist(output)), but the physical layout in
904 memory can be explicitly chosen.
Serhiy Storchaka009b8112015-03-18 21:53:15 +0200905
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100906 As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
907 otherwise it may be writable or read-only.
908
909 If the exporter is already contiguous with the desired target order,
910 the memoryview will be directly based on the exporter.
911
912 Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
913 based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
914 'F'ortran order otherwise.
915*/
916PyObject *
917PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
918{
919 PyMemoryViewObject *mv;
920 PyObject *ret;
921 Py_buffer *view;
922
923 assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
924 assert(order == 'C' || order == 'F' || order == 'A');
925
926 mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
927 if (mv == NULL)
928 return NULL;
929
930 view = &mv->view;
931 if (buffertype == PyBUF_WRITE && view->readonly) {
932 PyErr_SetString(PyExc_BufferError,
933 "underlying buffer is not writable");
934 Py_DECREF(mv);
935 return NULL;
936 }
937
938 if (PyBuffer_IsContiguous(view, order))
939 return (PyObject *)mv;
940
941 if (buffertype == PyBUF_WRITE) {
942 PyErr_SetString(PyExc_BufferError,
943 "writable contiguous buffer requested "
944 "for a non-contiguous object.");
945 Py_DECREF(mv);
946 return NULL;
947 }
948
949 ret = memory_from_contiguous_copy(view, order);
950 Py_DECREF(mv);
951 return ret;
952}
953
954
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000955static PyObject *
956memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
957{
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000958 PyObject *obj;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100959 static char *kwlist[] = {"object", NULL};
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000960
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000961 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
962 &obj)) {
963 return NULL;
964 }
Christian Heimes7b6fc8e2007-11-08 02:28:11 +0000965
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000966 return PyMemoryView_FromObject(obj);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000967}
968
969
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100970/****************************************************************************/
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200971/* Previously in abstract.c */
972/****************************************************************************/
973
974typedef struct {
975 Py_buffer view;
976 Py_ssize_t array[1];
977} Py_buffer_full;
978
979int
980PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
981{
982 Py_buffer_full *fb = NULL;
983 int ret;
984
985 assert(order == 'C' || order == 'F' || order == 'A');
986
987 if (len != src->len) {
988 PyErr_SetString(PyExc_ValueError,
989 "PyBuffer_ToContiguous: len != view->len");
990 return -1;
991 }
992
993 if (PyBuffer_IsContiguous(src, order)) {
994 memcpy((char *)buf, src->buf, len);
995 return 0;
996 }
997
998 /* buffer_to_contiguous() assumes PyBUF_FULL */
999 fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array));
1000 if (fb == NULL) {
1001 PyErr_NoMemory();
1002 return -1;
1003 }
1004 fb->view.ndim = src->ndim;
1005 fb->view.shape = fb->array;
1006 fb->view.strides = fb->array + src->ndim;
1007 fb->view.suboffsets = fb->array + 2 * src->ndim;
1008
1009 init_shared_values(&fb->view, src);
1010 init_shape_strides(&fb->view, src);
1011 init_suboffsets(&fb->view, src);
1012
1013 src = &fb->view;
1014
1015 ret = buffer_to_contiguous(buf, src, order);
1016 PyMem_Free(fb);
1017 return ret;
1018}
1019
1020
1021/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001022/* Release/GC management */
1023/****************************************************************************/
1024
1025/* Inform the managed buffer that this particular memoryview will not access
1026 the underlying buffer again. If no other memoryviews are registered with
1027 the managed buffer, the underlying buffer is released instantly and
1028 marked as inaccessible for both the memoryview and the managed buffer.
1029
1030 This function fails if the memoryview itself has exported buffers. */
1031static int
1032_memory_release(PyMemoryViewObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001033{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001034 if (self->flags & _Py_MEMORYVIEW_RELEASED)
1035 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001036
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001037 if (self->exports == 0) {
1038 self->flags |= _Py_MEMORYVIEW_RELEASED;
1039 assert(self->mbuf->exports > 0);
1040 if (--self->mbuf->exports == 0)
1041 mbuf_release(self->mbuf);
1042 return 0;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001043 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001044 if (self->exports > 0) {
1045 PyErr_Format(PyExc_BufferError,
1046 "memoryview has %zd exported buffer%s", self->exports,
1047 self->exports==1 ? "" : "s");
1048 return -1;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001049 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001050
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001051 Py_FatalError("_memory_release(): negative export count");
1052 return -1;
1053}
1054
1055static PyObject *
Stefan Krahe4c07992012-07-28 14:10:02 +02001056memory_release(PyMemoryViewObject *self, PyObject *noargs)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001057{
1058 if (_memory_release(self) < 0)
1059 return NULL;
1060 Py_RETURN_NONE;
1061}
1062
1063static void
1064memory_dealloc(PyMemoryViewObject *self)
1065{
1066 assert(self->exports == 0);
1067 _PyObject_GC_UNTRACK(self);
1068 (void)_memory_release(self);
1069 Py_CLEAR(self->mbuf);
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01001070 if (self->weakreflist != NULL)
1071 PyObject_ClearWeakRefs((PyObject *) self);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001072 PyObject_GC_Del(self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001073}
1074
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001075static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001076memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001077{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001078 Py_VISIT(self->mbuf);
1079 return 0;
1080}
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001081
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001082static int
1083memory_clear(PyMemoryViewObject *self)
1084{
1085 (void)_memory_release(self);
1086 Py_CLEAR(self->mbuf);
1087 return 0;
1088}
1089
1090static PyObject *
1091memory_enter(PyObject *self, PyObject *args)
1092{
1093 CHECK_RELEASED(self);
1094 Py_INCREF(self);
1095 return self;
1096}
1097
1098static PyObject *
1099memory_exit(PyObject *self, PyObject *args)
1100{
Stefan Krahe4c07992012-07-28 14:10:02 +02001101 return memory_release((PyMemoryViewObject *)self, NULL);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001102}
1103
1104
1105/****************************************************************************/
1106/* Casting format and shape */
1107/****************************************************************************/
1108
1109#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
1110
Benjamin Peterson82cce4c2016-09-08 11:56:06 -07001111static inline Py_ssize_t
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001112get_native_fmtchar(char *result, const char *fmt)
1113{
1114 Py_ssize_t size = -1;
1115
1116 if (fmt[0] == '@') fmt++;
1117
1118 switch (fmt[0]) {
1119 case 'c': case 'b': case 'B': size = sizeof(char); break;
1120 case 'h': case 'H': size = sizeof(short); break;
1121 case 'i': case 'I': size = sizeof(int); break;
1122 case 'l': case 'L': size = sizeof(long); break;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001123 case 'q': case 'Q': size = sizeof(long long); break;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001124 case 'n': case 'N': size = sizeof(Py_ssize_t); break;
1125 case 'f': size = sizeof(float); break;
1126 case 'd': size = sizeof(double); break;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001127 case '?': size = sizeof(_Bool); break;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001128 case 'P': size = sizeof(void *); break;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001129 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001130
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001131 if (size > 0 && fmt[1] == '\0') {
1132 *result = fmt[0];
1133 return size;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001134 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001135
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001136 return -1;
1137}
1138
Benjamin Peterson82cce4c2016-09-08 11:56:06 -07001139static inline const char *
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001140get_native_fmtstr(const char *fmt)
1141{
1142 int at = 0;
1143
1144 if (fmt[0] == '@') {
1145 at = 1;
1146 fmt++;
1147 }
1148 if (fmt[0] == '\0' || fmt[1] != '\0') {
1149 return NULL;
1150 }
1151
1152#define RETURN(s) do { return at ? "@" s : s; } while (0)
1153
1154 switch (fmt[0]) {
1155 case 'c': RETURN("c");
1156 case 'b': RETURN("b");
1157 case 'B': RETURN("B");
1158 case 'h': RETURN("h");
1159 case 'H': RETURN("H");
1160 case 'i': RETURN("i");
1161 case 'I': RETURN("I");
1162 case 'l': RETURN("l");
1163 case 'L': RETURN("L");
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001164 case 'q': RETURN("q");
1165 case 'Q': RETURN("Q");
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001166 case 'n': RETURN("n");
1167 case 'N': RETURN("N");
1168 case 'f': RETURN("f");
1169 case 'd': RETURN("d");
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001170 case '?': RETURN("?");
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001171 case 'P': RETURN("P");
1172 }
1173
1174 return NULL;
1175}
1176
1177
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001178/* Cast a memoryview's data type to 'format'. The input array must be
1179 C-contiguous. At least one of input-format, output-format must have
1180 byte size. The output array is 1-D, with the same byte length as the
1181 input array. Thus, view->len must be a multiple of the new itemsize. */
1182static int
1183cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1184{
1185 Py_buffer *view = &mv->view;
1186 PyObject *asciifmt;
1187 char srcchar, destchar;
1188 Py_ssize_t itemsize;
1189 int ret = -1;
1190
1191 assert(view->ndim >= 1);
1192 assert(Py_SIZE(mv) == 3*view->ndim);
1193 assert(view->shape == mv->ob_array);
1194 assert(view->strides == mv->ob_array + view->ndim);
1195 assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1196
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001197 asciifmt = PyUnicode_AsASCIIString(format);
1198 if (asciifmt == NULL)
1199 return ret;
1200
1201 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1202 if (itemsize < 0) {
1203 PyErr_SetString(PyExc_ValueError,
1204 "memoryview: destination format must be a native single "
1205 "character format prefixed with an optional '@'");
1206 goto out;
1207 }
1208
Stefan Krah0c515952015-08-08 13:38:10 +02001209 if ((get_native_fmtchar(&srcchar, view->format) < 0 ||
1210 !IS_BYTE_FORMAT(srcchar)) && !IS_BYTE_FORMAT(destchar)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001211 PyErr_SetString(PyExc_TypeError,
1212 "memoryview: cannot cast between two non-byte formats");
1213 goto out;
1214 }
1215 if (view->len % itemsize) {
1216 PyErr_SetString(PyExc_TypeError,
1217 "memoryview: length is not a multiple of itemsize");
1218 goto out;
1219 }
1220
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001221 view->format = (char *)get_native_fmtstr(PyBytes_AS_STRING(asciifmt));
Stefan Krahfa5d6a52015-01-29 14:27:23 +01001222 if (view->format == NULL) {
1223 /* NOT_REACHED: get_native_fmtchar() already validates the format. */
1224 PyErr_SetString(PyExc_RuntimeError,
1225 "memoryview: internal error");
1226 goto out;
1227 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001228 view->itemsize = itemsize;
1229
1230 view->ndim = 1;
1231 view->shape[0] = view->len / view->itemsize;
1232 view->strides[0] = view->itemsize;
1233 view->suboffsets = NULL;
1234
1235 init_flags(mv);
Serhiy Storchaka009b8112015-03-18 21:53:15 +02001236
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001237 ret = 0;
1238
1239out:
1240 Py_DECREF(asciifmt);
1241 return ret;
1242}
1243
1244/* The memoryview must have space for 3*len(seq) elements. */
1245static Py_ssize_t
1246copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1247 Py_ssize_t itemsize)
1248{
1249 Py_ssize_t x, i;
1250 Py_ssize_t len = itemsize;
1251
1252 for (i = 0; i < ndim; i++) {
1253 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1254 if (!PyLong_Check(tmp)) {
1255 PyErr_SetString(PyExc_TypeError,
1256 "memoryview.cast(): elements of shape must be integers");
1257 return -1;
1258 }
1259 x = PyLong_AsSsize_t(tmp);
1260 if (x == -1 && PyErr_Occurred()) {
1261 return -1;
1262 }
1263 if (x <= 0) {
1264 /* In general elements of shape may be 0, but not for casting. */
1265 PyErr_Format(PyExc_ValueError,
1266 "memoryview.cast(): elements of shape must be integers > 0");
1267 return -1;
1268 }
1269 if (x > PY_SSIZE_T_MAX / len) {
1270 PyErr_Format(PyExc_ValueError,
1271 "memoryview.cast(): product(shape) > SSIZE_MAX");
1272 return -1;
1273 }
1274 len *= x;
1275 shape[i] = x;
1276 }
1277
1278 return len;
1279}
1280
1281/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1282 If the result array does not have exactly the same byte length as the
1283 input array, raise ValueError. */
1284static int
1285cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1286{
1287 Py_buffer *view = &mv->view;
1288 Py_ssize_t len;
1289
1290 assert(view->ndim == 1); /* ndim from cast_to_1D() */
1291 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1292 assert(view->shape == mv->ob_array);
1293 assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1294 assert(view->suboffsets == NULL);
1295
1296 view->ndim = ndim;
1297 if (view->ndim == 0) {
1298 view->shape = NULL;
1299 view->strides = NULL;
1300 len = view->itemsize;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001301 }
1302 else {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001303 len = copy_shape(view->shape, shape, ndim, view->itemsize);
1304 if (len < 0)
1305 return -1;
1306 init_strides_from_shape(view);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001307 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001308
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001309 if (view->len != len) {
1310 PyErr_SetString(PyExc_TypeError,
1311 "memoryview: product(shape) * itemsize != buffer size");
1312 return -1;
1313 }
1314
1315 init_flags(mv);
1316
1317 return 0;
1318}
1319
1320static int
1321zero_in_shape(PyMemoryViewObject *mv)
1322{
1323 Py_buffer *view = &mv->view;
1324 Py_ssize_t i;
1325
1326 for (i = 0; i < view->ndim; i++)
1327 if (view->shape[i] == 0)
1328 return 1;
1329
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001330 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001331}
1332
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001333/*
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001334 Cast a copy of 'self' to a different view. The input view must
1335 be C-contiguous. The function always casts the input view to a
1336 1-D output according to 'format'. At least one of input-format,
1337 output-format must have byte size.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001338
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001339 If 'shape' is given, the 1-D view from the previous step will
1340 be cast to a C-contiguous view with new shape and strides.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001341
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001342 All casts must result in views that will have the exact byte
1343 size of the original input. Otherwise, an error is raised.
1344*/
1345static PyObject *
1346memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001347{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001348 static char *kwlist[] = {"format", "shape", NULL};
1349 PyMemoryViewObject *mv = NULL;
1350 PyObject *shape = NULL;
1351 PyObject *format;
1352 Py_ssize_t ndim = 1;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001353
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001354 CHECK_RELEASED(self);
1355
1356 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
1357 &format, &shape)) {
1358 return NULL;
1359 }
1360 if (!PyUnicode_Check(format)) {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001361 PyErr_SetString(PyExc_TypeError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001362 "memoryview: format argument must be a string");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001363 return NULL;
1364 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001365 if (!MV_C_CONTIGUOUS(self->flags)) {
1366 PyErr_SetString(PyExc_TypeError,
1367 "memoryview: casts are restricted to C-contiguous views");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001368 return NULL;
1369 }
Antoine Pitrou60b18342013-10-03 19:55:41 +02001370 if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001371 PyErr_SetString(PyExc_TypeError,
1372 "memoryview: cannot cast view with zeros in shape or strides");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001373 return NULL;
1374 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001375 if (shape) {
1376 CHECK_LIST_OR_TUPLE(shape)
1377 ndim = PySequence_Fast_GET_SIZE(shape);
1378 if (ndim > PyBUF_MAX_NDIM) {
1379 PyErr_SetString(PyExc_ValueError,
1380 "memoryview: number of dimensions must not exceed "
Victor Stinner45e8e2f2014-05-14 17:24:35 +02001381 Py_STRINGIFY(PyBUF_MAX_NDIM));
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001382 return NULL;
1383 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001384 if (self->view.ndim != 1 && ndim != 1) {
1385 PyErr_SetString(PyExc_TypeError,
1386 "memoryview: cast must be 1D -> ND or ND -> 1D");
1387 return NULL;
1388 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001389 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001390
1391 mv = (PyMemoryViewObject *)
1392 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1393 if (mv == NULL)
1394 return NULL;
1395
1396 if (cast_to_1D(mv, format) < 0)
1397 goto error;
1398 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1399 goto error;
1400
1401 return (PyObject *)mv;
1402
1403error:
1404 Py_DECREF(mv);
1405 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001406}
1407
Antoine Pitrou480ab052018-04-14 19:49:21 +02001408static PyObject *
1409memory_toreadonly(PyMemoryViewObject *self, PyObject *noargs)
1410{
1411 CHECK_RELEASED(self);
1412 /* Even if self is already readonly, we still need to create a new
1413 * object for .release() to work correctly.
1414 */
1415 self = (PyMemoryViewObject *) mbuf_add_view(self->mbuf, &self->view);
1416 if (self != NULL) {
1417 self->view.readonly = 1;
1418 };
1419 return (PyObject *) self;
1420}
1421
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001422
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001423/**************************************************************************/
1424/* getbuffer */
1425/**************************************************************************/
1426
1427static int
1428memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1429{
1430 Py_buffer *base = &self->view;
1431 int baseflags = self->flags;
1432
1433 CHECK_RELEASED_INT(self);
1434
1435 /* start with complete information */
1436 *view = *base;
1437 view->obj = NULL;
1438
1439 if (REQ_WRITABLE(flags) && base->readonly) {
1440 PyErr_SetString(PyExc_BufferError,
1441 "memoryview: underlying buffer is not writable");
1442 return -1;
1443 }
1444 if (!REQ_FORMAT(flags)) {
1445 /* NULL indicates that the buffer's data type has been cast to 'B'.
1446 view->itemsize is the _previous_ itemsize. If shape is present,
1447 the equality product(shape) * itemsize = len still holds at this
1448 point. The equality calcsize(format) = itemsize does _not_ hold
1449 from here on! */
1450 view->format = NULL;
1451 }
1452
1453 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1454 PyErr_SetString(PyExc_BufferError,
1455 "memoryview: underlying buffer is not C-contiguous");
1456 return -1;
1457 }
1458 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1459 PyErr_SetString(PyExc_BufferError,
1460 "memoryview: underlying buffer is not Fortran contiguous");
1461 return -1;
1462 }
1463 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1464 PyErr_SetString(PyExc_BufferError,
1465 "memoryview: underlying buffer is not contiguous");
1466 return -1;
1467 }
1468 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1469 PyErr_SetString(PyExc_BufferError,
1470 "memoryview: underlying buffer requires suboffsets");
1471 return -1;
1472 }
1473 if (!REQ_STRIDES(flags)) {
1474 if (!MV_C_CONTIGUOUS(baseflags)) {
1475 PyErr_SetString(PyExc_BufferError,
1476 "memoryview: underlying buffer is not C-contiguous");
1477 return -1;
1478 }
1479 view->strides = NULL;
1480 }
1481 if (!REQ_SHAPE(flags)) {
1482 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1483 so base->buf = ndbuf->data. */
1484 if (view->format != NULL) {
1485 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1486 not make sense. */
1487 PyErr_Format(PyExc_BufferError,
Stefan Krah674a42b2013-02-19 13:44:49 +01001488 "memoryview: cannot cast to unsigned bytes if the format flag "
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001489 "is present");
1490 return -1;
1491 }
1492 /* product(shape) * itemsize = len and calcsize(format) = itemsize
1493 do _not_ hold from here on! */
1494 view->ndim = 1;
1495 view->shape = NULL;
1496 }
1497
1498
1499 view->obj = (PyObject *)self;
1500 Py_INCREF(view->obj);
1501 self->exports++;
1502
1503 return 0;
1504}
1505
1506static void
1507memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1508{
1509 self->exports--;
1510 return;
1511 /* PyBuffer_Release() decrements view->obj after this function returns. */
1512}
1513
1514/* Buffer methods */
1515static PyBufferProcs memory_as_buffer = {
1516 (getbufferproc)memory_getbuf, /* bf_getbuffer */
1517 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1518};
1519
1520
1521/****************************************************************************/
1522/* Optimized pack/unpack for all native format specifiers */
1523/****************************************************************************/
1524
1525/*
1526 Fix exceptions:
1527 1) Include format string in the error message.
1528 2) OverflowError -> ValueError.
1529 3) The error message from PyNumber_Index() is not ideal.
1530*/
1531static int
1532type_error_int(const char *fmt)
1533{
1534 PyErr_Format(PyExc_TypeError,
1535 "memoryview: invalid type for format '%s'", fmt);
1536 return -1;
1537}
1538
1539static int
1540value_error_int(const char *fmt)
1541{
1542 PyErr_Format(PyExc_ValueError,
1543 "memoryview: invalid value for format '%s'", fmt);
1544 return -1;
1545}
1546
1547static int
1548fix_error_int(const char *fmt)
1549{
1550 assert(PyErr_Occurred());
1551 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1552 PyErr_Clear();
1553 return type_error_int(fmt);
1554 }
1555 else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1556 PyErr_ExceptionMatches(PyExc_ValueError)) {
1557 PyErr_Clear();
1558 return value_error_int(fmt);
1559 }
1560
1561 return -1;
1562}
1563
1564/* Accept integer objects or objects with an __index__() method. */
1565static long
1566pylong_as_ld(PyObject *item)
1567{
1568 PyObject *tmp;
1569 long ld;
1570
1571 tmp = PyNumber_Index(item);
1572 if (tmp == NULL)
1573 return -1;
1574
1575 ld = PyLong_AsLong(tmp);
1576 Py_DECREF(tmp);
1577 return ld;
1578}
1579
1580static unsigned long
1581pylong_as_lu(PyObject *item)
1582{
1583 PyObject *tmp;
1584 unsigned long lu;
1585
1586 tmp = PyNumber_Index(item);
1587 if (tmp == NULL)
1588 return (unsigned long)-1;
1589
1590 lu = PyLong_AsUnsignedLong(tmp);
1591 Py_DECREF(tmp);
1592 return lu;
1593}
1594
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001595static long long
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001596pylong_as_lld(PyObject *item)
1597{
1598 PyObject *tmp;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001599 long long lld;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001600
1601 tmp = PyNumber_Index(item);
1602 if (tmp == NULL)
1603 return -1;
1604
1605 lld = PyLong_AsLongLong(tmp);
1606 Py_DECREF(tmp);
1607 return lld;
1608}
1609
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001610static unsigned long long
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001611pylong_as_llu(PyObject *item)
1612{
1613 PyObject *tmp;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001614 unsigned long long llu;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001615
1616 tmp = PyNumber_Index(item);
1617 if (tmp == NULL)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001618 return (unsigned long long)-1;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001619
1620 llu = PyLong_AsUnsignedLongLong(tmp);
1621 Py_DECREF(tmp);
1622 return llu;
1623}
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001624
1625static Py_ssize_t
1626pylong_as_zd(PyObject *item)
1627{
1628 PyObject *tmp;
1629 Py_ssize_t zd;
1630
1631 tmp = PyNumber_Index(item);
1632 if (tmp == NULL)
1633 return -1;
1634
1635 zd = PyLong_AsSsize_t(tmp);
1636 Py_DECREF(tmp);
1637 return zd;
1638}
1639
1640static size_t
1641pylong_as_zu(PyObject *item)
1642{
1643 PyObject *tmp;
1644 size_t zu;
1645
1646 tmp = PyNumber_Index(item);
1647 if (tmp == NULL)
1648 return (size_t)-1;
1649
1650 zu = PyLong_AsSize_t(tmp);
1651 Py_DECREF(tmp);
1652 return zu;
1653}
1654
1655/* Timings with the ndarray from _testbuffer.c indicate that using the
1656 struct module is around 15x slower than the two functions below. */
1657
1658#define UNPACK_SINGLE(dest, ptr, type) \
1659 do { \
1660 type x; \
1661 memcpy((char *)&x, ptr, sizeof x); \
1662 dest = x; \
1663 } while (0)
1664
1665/* Unpack a single item. 'fmt' can be any native format character in struct
1666 module syntax. This function is very sensitive to small changes. With this
1667 layout gcc automatically generates a fast jump table. */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -07001668static inline PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001669unpack_single(const char *ptr, const char *fmt)
1670{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001671 unsigned long long llu;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001672 unsigned long lu;
1673 size_t zu;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001674 long long lld;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001675 long ld;
1676 Py_ssize_t zd;
1677 double d;
1678 unsigned char uc;
1679 void *p;
1680
1681 switch (fmt[0]) {
1682
1683 /* signed integers and fast path for 'B' */
1684 case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
1685 case 'b': ld = *((signed char *)ptr); goto convert_ld;
1686 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1687 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1688 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1689
1690 /* boolean */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001691 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001692
1693 /* unsigned integers */
1694 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1695 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1696 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1697
1698 /* native 64-bit */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001699 case 'q': UNPACK_SINGLE(lld, ptr, long long); goto convert_lld;
1700 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned long long); goto convert_llu;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001701
1702 /* ssize_t and size_t */
1703 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1704 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1705
1706 /* floats */
1707 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1708 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1709
1710 /* bytes object */
1711 case 'c': goto convert_bytes;
1712
1713 /* pointer */
1714 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1715
1716 /* default */
1717 default: goto err_format;
1718 }
1719
1720convert_uc:
1721 /* PyLong_FromUnsignedLong() is slower */
1722 return PyLong_FromLong(uc);
1723convert_ld:
1724 return PyLong_FromLong(ld);
1725convert_lu:
1726 return PyLong_FromUnsignedLong(lu);
1727convert_lld:
1728 return PyLong_FromLongLong(lld);
1729convert_llu:
1730 return PyLong_FromUnsignedLongLong(llu);
1731convert_zd:
1732 return PyLong_FromSsize_t(zd);
1733convert_zu:
1734 return PyLong_FromSize_t(zu);
1735convert_double:
1736 return PyFloat_FromDouble(d);
1737convert_bool:
1738 return PyBool_FromLong(ld);
1739convert_bytes:
1740 return PyBytes_FromStringAndSize(ptr, 1);
1741convert_pointer:
1742 return PyLong_FromVoidPtr(p);
1743err_format:
1744 PyErr_Format(PyExc_NotImplementedError,
1745 "memoryview: format %s not supported", fmt);
1746 return NULL;
1747}
1748
1749#define PACK_SINGLE(ptr, src, type) \
1750 do { \
1751 type x; \
1752 x = (type)src; \
1753 memcpy(ptr, (char *)&x, sizeof x); \
1754 } while (0)
1755
1756/* Pack a single item. 'fmt' can be any native format character in
1757 struct module syntax. */
1758static int
1759pack_single(char *ptr, PyObject *item, const char *fmt)
1760{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001761 unsigned long long llu;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001762 unsigned long lu;
1763 size_t zu;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001764 long long lld;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001765 long ld;
1766 Py_ssize_t zd;
1767 double d;
1768 void *p;
1769
1770 switch (fmt[0]) {
1771 /* signed integers */
1772 case 'b': case 'h': case 'i': case 'l':
1773 ld = pylong_as_ld(item);
1774 if (ld == -1 && PyErr_Occurred())
1775 goto err_occurred;
1776 switch (fmt[0]) {
1777 case 'b':
1778 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1779 *((signed char *)ptr) = (signed char)ld; break;
1780 case 'h':
1781 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1782 PACK_SINGLE(ptr, ld, short); break;
1783 case 'i':
1784 if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1785 PACK_SINGLE(ptr, ld, int); break;
1786 default: /* 'l' */
1787 PACK_SINGLE(ptr, ld, long); break;
1788 }
1789 break;
1790
1791 /* unsigned integers */
1792 case 'B': case 'H': case 'I': case 'L':
1793 lu = pylong_as_lu(item);
1794 if (lu == (unsigned long)-1 && PyErr_Occurred())
1795 goto err_occurred;
1796 switch (fmt[0]) {
1797 case 'B':
1798 if (lu > UCHAR_MAX) goto err_range;
1799 *((unsigned char *)ptr) = (unsigned char)lu; break;
1800 case 'H':
1801 if (lu > USHRT_MAX) goto err_range;
1802 PACK_SINGLE(ptr, lu, unsigned short); break;
1803 case 'I':
1804 if (lu > UINT_MAX) goto err_range;
1805 PACK_SINGLE(ptr, lu, unsigned int); break;
1806 default: /* 'L' */
1807 PACK_SINGLE(ptr, lu, unsigned long); break;
1808 }
1809 break;
1810
1811 /* native 64-bit */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001812 case 'q':
1813 lld = pylong_as_lld(item);
1814 if (lld == -1 && PyErr_Occurred())
1815 goto err_occurred;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001816 PACK_SINGLE(ptr, lld, long long);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001817 break;
1818 case 'Q':
1819 llu = pylong_as_llu(item);
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001820 if (llu == (unsigned long long)-1 && PyErr_Occurred())
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001821 goto err_occurred;
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001822 PACK_SINGLE(ptr, llu, unsigned long long);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001823 break;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001824
1825 /* ssize_t and size_t */
1826 case 'n':
1827 zd = pylong_as_zd(item);
1828 if (zd == -1 && PyErr_Occurred())
1829 goto err_occurred;
1830 PACK_SINGLE(ptr, zd, Py_ssize_t);
1831 break;
1832 case 'N':
1833 zu = pylong_as_zu(item);
1834 if (zu == (size_t)-1 && PyErr_Occurred())
1835 goto err_occurred;
1836 PACK_SINGLE(ptr, zu, size_t);
1837 break;
1838
1839 /* floats */
1840 case 'f': case 'd':
1841 d = PyFloat_AsDouble(item);
1842 if (d == -1.0 && PyErr_Occurred())
1843 goto err_occurred;
1844 if (fmt[0] == 'f') {
1845 PACK_SINGLE(ptr, d, float);
1846 }
1847 else {
1848 PACK_SINGLE(ptr, d, double);
1849 }
1850 break;
1851
1852 /* bool */
1853 case '?':
1854 ld = PyObject_IsTrue(item);
1855 if (ld < 0)
1856 return -1; /* preserve original error */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001857 PACK_SINGLE(ptr, ld, _Bool);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001858 break;
1859
1860 /* bytes object */
1861 case 'c':
1862 if (!PyBytes_Check(item))
1863 return type_error_int(fmt);
1864 if (PyBytes_GET_SIZE(item) != 1)
1865 return value_error_int(fmt);
1866 *ptr = PyBytes_AS_STRING(item)[0];
1867 break;
1868
1869 /* pointer */
1870 case 'P':
1871 p = PyLong_AsVoidPtr(item);
1872 if (p == NULL && PyErr_Occurred())
1873 goto err_occurred;
1874 PACK_SINGLE(ptr, p, void *);
1875 break;
1876
1877 /* default */
1878 default: goto err_format;
1879 }
1880
1881 return 0;
1882
1883err_occurred:
1884 return fix_error_int(fmt);
1885err_range:
1886 return value_error_int(fmt);
1887err_format:
1888 PyErr_Format(PyExc_NotImplementedError,
1889 "memoryview: format %s not supported", fmt);
1890 return -1;
1891}
1892
1893
1894/****************************************************************************/
Nick Coghlan06e1ab02012-08-25 17:59:50 +10001895/* unpack using the struct module */
1896/****************************************************************************/
1897
1898/* For reasonable performance it is necessary to cache all objects required
1899 for unpacking. An unpacker can handle the format passed to unpack_from().
1900 Invariant: All pointer fields of the struct should either be NULL or valid
1901 pointers. */
1902struct unpacker {
1903 PyObject *unpack_from; /* Struct.unpack_from(format) */
1904 PyObject *mview; /* cached memoryview */
1905 char *item; /* buffer for mview */
1906 Py_ssize_t itemsize; /* len(item) */
1907};
1908
1909static struct unpacker *
1910unpacker_new(void)
1911{
1912 struct unpacker *x = PyMem_Malloc(sizeof *x);
1913
1914 if (x == NULL) {
1915 PyErr_NoMemory();
1916 return NULL;
1917 }
1918
1919 x->unpack_from = NULL;
1920 x->mview = NULL;
1921 x->item = NULL;
1922 x->itemsize = 0;
1923
1924 return x;
1925}
1926
1927static void
1928unpacker_free(struct unpacker *x)
1929{
1930 if (x) {
1931 Py_XDECREF(x->unpack_from);
1932 Py_XDECREF(x->mview);
1933 PyMem_Free(x->item);
1934 PyMem_Free(x);
1935 }
1936}
1937
1938/* Return a new unpacker for the given format. */
1939static struct unpacker *
1940struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
1941{
1942 PyObject *structmodule; /* XXX cache these two */
1943 PyObject *Struct = NULL; /* XXX in globals? */
1944 PyObject *structobj = NULL;
1945 PyObject *format = NULL;
1946 struct unpacker *x = NULL;
1947
1948 structmodule = PyImport_ImportModule("struct");
1949 if (structmodule == NULL)
1950 return NULL;
1951
1952 Struct = PyObject_GetAttrString(structmodule, "Struct");
1953 Py_DECREF(structmodule);
1954 if (Struct == NULL)
1955 return NULL;
1956
1957 x = unpacker_new();
1958 if (x == NULL)
1959 goto error;
1960
1961 format = PyBytes_FromString(fmt);
1962 if (format == NULL)
1963 goto error;
1964
1965 structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
1966 if (structobj == NULL)
1967 goto error;
1968
1969 x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
1970 if (x->unpack_from == NULL)
1971 goto error;
1972
1973 x->item = PyMem_Malloc(itemsize);
1974 if (x->item == NULL) {
1975 PyErr_NoMemory();
1976 goto error;
1977 }
1978 x->itemsize = itemsize;
1979
1980 x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
1981 if (x->mview == NULL)
1982 goto error;
1983
1984
1985out:
1986 Py_XDECREF(Struct);
1987 Py_XDECREF(format);
1988 Py_XDECREF(structobj);
1989 return x;
1990
1991error:
1992 unpacker_free(x);
1993 x = NULL;
1994 goto out;
1995}
1996
1997/* unpack a single item */
1998static PyObject *
1999struct_unpack_single(const char *ptr, struct unpacker *x)
2000{
2001 PyObject *v;
2002
2003 memcpy(x->item, ptr, x->itemsize);
2004 v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL);
2005 if (v == NULL)
2006 return NULL;
2007
2008 if (PyTuple_GET_SIZE(v) == 1) {
2009 PyObject *tmp = PyTuple_GET_ITEM(v, 0);
2010 Py_INCREF(tmp);
2011 Py_DECREF(v);
2012 return tmp;
2013 }
2014
2015 return v;
2016}
2017
2018
2019/****************************************************************************/
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002020/* Representations */
2021/****************************************************************************/
2022
2023/* allow explicit form of native format */
Benjamin Peterson82cce4c2016-09-08 11:56:06 -07002024static inline const char *
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002025adjust_fmt(const Py_buffer *view)
2026{
2027 const char *fmt;
2028
2029 fmt = (view->format[0] == '@') ? view->format+1 : view->format;
2030 if (fmt[0] && fmt[1] == '\0')
2031 return fmt;
2032
2033 PyErr_Format(PyExc_NotImplementedError,
2034 "memoryview: unsupported format %s", view->format);
2035 return NULL;
2036}
2037
2038/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
2039static PyObject *
2040tolist_base(const char *ptr, const Py_ssize_t *shape,
2041 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2042 const char *fmt)
2043{
2044 PyObject *lst, *item;
2045 Py_ssize_t i;
2046
2047 lst = PyList_New(shape[0]);
2048 if (lst == NULL)
2049 return NULL;
2050
2051 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002052 const char *xptr = ADJUST_PTR(ptr, suboffsets, 0);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002053 item = unpack_single(xptr, fmt);
2054 if (item == NULL) {
2055 Py_DECREF(lst);
2056 return NULL;
2057 }
2058 PyList_SET_ITEM(lst, i, item);
2059 }
2060
2061 return lst;
2062}
2063
2064/* Unpack a multi-dimensional array into a nested list.
2065 Assumption: ndim >= 1. */
2066static PyObject *
2067tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
2068 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2069 const char *fmt)
2070{
2071 PyObject *lst, *item;
2072 Py_ssize_t i;
2073
2074 assert(ndim >= 1);
2075 assert(shape != NULL);
2076 assert(strides != NULL);
2077
2078 if (ndim == 1)
2079 return tolist_base(ptr, shape, strides, suboffsets, fmt);
2080
2081 lst = PyList_New(shape[0]);
2082 if (lst == NULL)
2083 return NULL;
2084
2085 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002086 const char *xptr = ADJUST_PTR(ptr, suboffsets, 0);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002087 item = tolist_rec(xptr, ndim-1, shape+1,
2088 strides+1, suboffsets ? suboffsets+1 : NULL,
2089 fmt);
2090 if (item == NULL) {
2091 Py_DECREF(lst);
2092 return NULL;
2093 }
2094 PyList_SET_ITEM(lst, i, item);
2095 }
2096
2097 return lst;
2098}
2099
2100/* Return a list representation of the memoryview. Currently only buffers
2101 with native format strings are supported. */
2102static PyObject *
2103memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
2104{
2105 const Py_buffer *view = &(mv->view);
2106 const char *fmt;
2107
2108 CHECK_RELEASED(mv);
2109
2110 fmt = adjust_fmt(view);
2111 if (fmt == NULL)
2112 return NULL;
2113 if (view->ndim == 0) {
2114 return unpack_single(view->buf, fmt);
2115 }
2116 else if (view->ndim == 1) {
2117 return tolist_base(view->buf, view->shape,
2118 view->strides, view->suboffsets,
2119 fmt);
2120 }
2121 else {
2122 return tolist_rec(view->buf, view->ndim, view->shape,
2123 view->strides, view->suboffsets,
2124 fmt);
2125 }
2126}
2127
2128static PyObject *
Stefan Krahd08ea702019-02-02 18:57:41 +01002129memory_tobytes(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002130{
Stefan Krahd08ea702019-02-02 18:57:41 +01002131 static char *kwlist[] = {"order", NULL};
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002132 Py_buffer *src = VIEW_ADDR(self);
Stefan Krahd08ea702019-02-02 18:57:41 +01002133 char *order = NULL;
2134 char ord = 'C';
2135 PyObject *bytes;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002136
2137 CHECK_RELEASED(self);
2138
Stefan Krahd08ea702019-02-02 18:57:41 +01002139 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|z", kwlist, &order)) {
2140 return NULL;
2141 }
2142
2143 if (order) {
2144 if (strcmp(order, "F") == 0) {
2145 ord = 'F';
2146 }
2147 else if (strcmp(order, "A") == 0) {
2148 ord = 'A';
2149 }
2150 else if (strcmp(order, "C") != 0) {
2151 PyErr_SetString(PyExc_ValueError,
2152 "order must be 'C', 'F' or 'A'");
2153 return NULL;
2154 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002155 }
2156
2157 bytes = PyBytes_FromStringAndSize(NULL, src->len);
2158 if (bytes == NULL)
2159 return NULL;
2160
Stefan Krahd08ea702019-02-02 18:57:41 +01002161 if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, ord) < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002162 Py_DECREF(bytes);
2163 return NULL;
2164 }
2165
2166 return bytes;
2167}
2168
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002169/*[clinic input]
2170memoryview.hex
2171
2172 sep: object = NULL
2173 An optional single character or byte to separate hex bytes.
2174 bytes_per_sep: int = 1
2175 How many bytes between separators. Positive values count from the
2176 right, negative values count from the left.
2177
2178Return the data in the buffer as a str of hexadecimal numbers.
2179
2180Example:
2181>>> value = memoryview(b'\xb9\x01\xef')
2182>>> value.hex()
2183'b901ef'
2184>>> value.hex(':')
2185'b9:01:ef'
2186>>> value.hex(':', 2)
2187'b9:01ef'
2188>>> value.hex(':', -2)
2189'b901:ef'
2190[clinic start generated code]*/
2191
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002192static PyObject *
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002193memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep,
2194 int bytes_per_sep)
2195/*[clinic end generated code: output=430ca760f94f3ca7 input=539f6a3a5fb56946]*/
Gregory P. Smith8cb65692015-04-25 23:22:26 +00002196{
2197 Py_buffer *src = VIEW_ADDR(self);
Stefan Krah0ce5b6e2015-11-10 18:17:22 +01002198 PyObject *bytes;
2199 PyObject *ret;
2200
Gregory P. Smith8cb65692015-04-25 23:22:26 +00002201 CHECK_RELEASED(self);
Stefan Krah0ce5b6e2015-11-10 18:17:22 +01002202
2203 if (MV_C_CONTIGUOUS(self->flags)) {
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002204 return _Py_strhex_with_sep(src->buf, src->len, sep, bytes_per_sep);
Stefan Krah0ce5b6e2015-11-10 18:17:22 +01002205 }
2206
Stefan Krahd08ea702019-02-02 18:57:41 +01002207 bytes = PyBytes_FromStringAndSize(NULL, src->len);
Stefan Krah0ce5b6e2015-11-10 18:17:22 +01002208 if (bytes == NULL)
2209 return NULL;
2210
Stefan Krahd08ea702019-02-02 18:57:41 +01002211 if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, 'C') < 0) {
2212 Py_DECREF(bytes);
2213 return NULL;
2214 }
2215
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002216 ret = _Py_strhex_with_sep(
2217 PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes),
2218 sep, bytes_per_sep);
Stefan Krah0ce5b6e2015-11-10 18:17:22 +01002219 Py_DECREF(bytes);
2220
2221 return ret;
Gregory P. Smith8cb65692015-04-25 23:22:26 +00002222}
2223
2224static PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002225memory_repr(PyMemoryViewObject *self)
2226{
2227 if (self->flags & _Py_MEMORYVIEW_RELEASED)
2228 return PyUnicode_FromFormat("<released memory at %p>", self);
2229 else
2230 return PyUnicode_FromFormat("<memory at %p>", self);
2231}
2232
2233
2234/**************************************************************************/
2235/* Indexing and slicing */
2236/**************************************************************************/
2237
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002238static char *
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002239lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002240{
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002241 Py_ssize_t nitems; /* items in the given dimension */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002242
2243 assert(view->shape);
2244 assert(view->strides);
2245
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002246 nitems = view->shape[dim];
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002247 if (index < 0) {
2248 index += nitems;
2249 }
2250 if (index < 0 || index >= nitems) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002251 PyErr_Format(PyExc_IndexError,
2252 "index out of bounds on dimension %d", dim + 1);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002253 return NULL;
2254 }
2255
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002256 ptr += view->strides[dim] * index;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002257
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002258 ptr = ADJUST_PTR(ptr, view->suboffsets, dim);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002259
2260 return ptr;
2261}
2262
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002263/* Get the pointer to the item at index. */
2264static char *
2265ptr_from_index(Py_buffer *view, Py_ssize_t index)
2266{
2267 char *ptr = (char *)view->buf;
2268 return lookup_dimension(view, ptr, 0, index);
2269}
2270
2271/* Get the pointer to the item at tuple. */
2272static char *
2273ptr_from_tuple(Py_buffer *view, PyObject *tup)
2274{
2275 char *ptr = (char *)view->buf;
2276 Py_ssize_t dim, nindices = PyTuple_GET_SIZE(tup);
2277
2278 if (nindices > view->ndim) {
2279 PyErr_Format(PyExc_TypeError,
2280 "cannot index %zd-dimension view with %zd-element tuple",
2281 view->ndim, nindices);
2282 return NULL;
2283 }
2284
2285 for (dim = 0; dim < nindices; dim++) {
2286 Py_ssize_t index;
2287 index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, dim),
2288 PyExc_IndexError);
2289 if (index == -1 && PyErr_Occurred())
2290 return NULL;
Stefan Krah7c3f3852015-11-10 18:35:19 +01002291 ptr = lookup_dimension(view, ptr, (int)dim, index);
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002292 if (ptr == NULL)
2293 return NULL;
2294 }
2295 return ptr;
2296}
2297
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002298/* Return the item at index. In a one-dimensional view, this is an object
2299 with the type specified by view->format. Otherwise, the item is a sub-view.
2300 The function is used in memory_subscript() and memory_as_sequence. */
2301static PyObject *
2302memory_item(PyMemoryViewObject *self, Py_ssize_t index)
2303{
2304 Py_buffer *view = &(self->view);
2305 const char *fmt;
2306
2307 CHECK_RELEASED(self);
2308
2309 fmt = adjust_fmt(view);
2310 if (fmt == NULL)
2311 return NULL;
2312
2313 if (view->ndim == 0) {
2314 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
2315 return NULL;
2316 }
2317 if (view->ndim == 1) {
2318 char *ptr = ptr_from_index(view, index);
2319 if (ptr == NULL)
2320 return NULL;
2321 return unpack_single(ptr, fmt);
2322 }
2323
2324 PyErr_SetString(PyExc_NotImplementedError,
2325 "multi-dimensional sub-views are not implemented");
2326 return NULL;
2327}
2328
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002329/* Return the item at position *key* (a tuple of indices). */
2330static PyObject *
2331memory_item_multi(PyMemoryViewObject *self, PyObject *tup)
2332{
2333 Py_buffer *view = &(self->view);
2334 const char *fmt;
2335 Py_ssize_t nindices = PyTuple_GET_SIZE(tup);
2336 char *ptr;
2337
2338 CHECK_RELEASED(self);
2339
2340 fmt = adjust_fmt(view);
2341 if (fmt == NULL)
2342 return NULL;
2343
2344 if (nindices < view->ndim) {
2345 PyErr_SetString(PyExc_NotImplementedError,
2346 "sub-views are not implemented");
2347 return NULL;
2348 }
2349 ptr = ptr_from_tuple(view, tup);
2350 if (ptr == NULL)
2351 return NULL;
2352 return unpack_single(ptr, fmt);
2353}
2354
Benjamin Peterson82cce4c2016-09-08 11:56:06 -07002355static inline int
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002356init_slice(Py_buffer *base, PyObject *key, int dim)
2357{
2358 Py_ssize_t start, stop, step, slicelength;
2359
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002360 if (PySlice_Unpack(key, &start, &stop, &step) < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002361 return -1;
2362 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +03002363 slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002364
2365
2366 if (base->suboffsets == NULL || dim == 0) {
2367 adjust_buf:
2368 base->buf = (char *)base->buf + base->strides[dim] * start;
2369 }
2370 else {
2371 Py_ssize_t n = dim-1;
2372 while (n >= 0 && base->suboffsets[n] < 0)
2373 n--;
2374 if (n < 0)
2375 goto adjust_buf; /* all suboffsets are negative */
2376 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
2377 }
2378 base->shape[dim] = slicelength;
2379 base->strides[dim] = base->strides[dim] * step;
2380
2381 return 0;
2382}
2383
2384static int
2385is_multislice(PyObject *key)
2386{
2387 Py_ssize_t size, i;
2388
2389 if (!PyTuple_Check(key))
2390 return 0;
2391 size = PyTuple_GET_SIZE(key);
2392 if (size == 0)
2393 return 0;
2394
2395 for (i = 0; i < size; i++) {
2396 PyObject *x = PyTuple_GET_ITEM(key, i);
2397 if (!PySlice_Check(x))
2398 return 0;
2399 }
2400 return 1;
2401}
2402
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002403static Py_ssize_t
2404is_multiindex(PyObject *key)
2405{
2406 Py_ssize_t size, i;
2407
2408 if (!PyTuple_Check(key))
2409 return 0;
2410 size = PyTuple_GET_SIZE(key);
2411 for (i = 0; i < size; i++) {
2412 PyObject *x = PyTuple_GET_ITEM(key, i);
2413 if (!PyIndex_Check(x))
2414 return 0;
2415 }
2416 return 1;
2417}
2418
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002419/* mv[obj] returns an object holding the data for one element if obj
2420 fully indexes the memoryview or another memoryview object if it
2421 does not.
2422
2423 0-d memoryview objects can be referenced using mv[...] or mv[()]
2424 but not with anything else. */
2425static PyObject *
2426memory_subscript(PyMemoryViewObject *self, PyObject *key)
2427{
2428 Py_buffer *view;
2429 view = &(self->view);
Serhiy Storchaka009b8112015-03-18 21:53:15 +02002430
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002431 CHECK_RELEASED(self);
2432
2433 if (view->ndim == 0) {
2434 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2435 const char *fmt = adjust_fmt(view);
2436 if (fmt == NULL)
2437 return NULL;
2438 return unpack_single(view->buf, fmt);
2439 }
2440 else if (key == Py_Ellipsis) {
2441 Py_INCREF(self);
2442 return (PyObject *)self;
2443 }
2444 else {
2445 PyErr_SetString(PyExc_TypeError,
2446 "invalid indexing of 0-dim memory");
2447 return NULL;
2448 }
2449 }
2450
2451 if (PyIndex_Check(key)) {
2452 Py_ssize_t index;
2453 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2454 if (index == -1 && PyErr_Occurred())
2455 return NULL;
2456 return memory_item(self, index);
2457 }
2458 else if (PySlice_Check(key)) {
2459 PyMemoryViewObject *sliced;
2460
2461 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2462 if (sliced == NULL)
2463 return NULL;
2464
2465 if (init_slice(&sliced->view, key, 0) < 0) {
2466 Py_DECREF(sliced);
2467 return NULL;
2468 }
2469 init_len(&sliced->view);
2470 init_flags(sliced);
2471
2472 return (PyObject *)sliced;
2473 }
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002474 else if (is_multiindex(key)) {
2475 return memory_item_multi(self, key);
2476 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002477 else if (is_multislice(key)) {
2478 PyErr_SetString(PyExc_NotImplementedError,
2479 "multi-dimensional slicing is not implemented");
2480 return NULL;
2481 }
2482
2483 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2484 return NULL;
2485}
2486
2487static int
2488memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2489{
2490 Py_buffer *view = &(self->view);
2491 Py_buffer src;
2492 const char *fmt;
2493 char *ptr;
2494
2495 CHECK_RELEASED_INT(self);
2496
2497 fmt = adjust_fmt(view);
2498 if (fmt == NULL)
2499 return -1;
2500
2501 if (view->readonly) {
2502 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2503 return -1;
2504 }
2505 if (value == NULL) {
2506 PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2507 return -1;
2508 }
2509 if (view->ndim == 0) {
2510 if (key == Py_Ellipsis ||
2511 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2512 ptr = (char *)view->buf;
2513 return pack_single(ptr, value, fmt);
2514 }
2515 else {
2516 PyErr_SetString(PyExc_TypeError,
2517 "invalid indexing of 0-dim memory");
2518 return -1;
2519 }
2520 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002521
2522 if (PyIndex_Check(key)) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002523 Py_ssize_t index;
2524 if (1 < view->ndim) {
2525 PyErr_SetString(PyExc_NotImplementedError,
2526 "sub-views are not implemented");
2527 return -1;
2528 }
2529 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002530 if (index == -1 && PyErr_Occurred())
2531 return -1;
2532 ptr = ptr_from_index(view, index);
2533 if (ptr == NULL)
2534 return -1;
2535 return pack_single(ptr, value, fmt);
2536 }
2537 /* one-dimensional: fast path */
2538 if (PySlice_Check(key) && view->ndim == 1) {
2539 Py_buffer dest; /* sliced view */
2540 Py_ssize_t arrays[3];
2541 int ret = -1;
2542
2543 /* rvalue must be an exporter */
2544 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2545 return ret;
2546
2547 dest = *view;
2548 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2549 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2550 if (view->suboffsets) {
2551 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2552 }
2553
2554 if (init_slice(&dest, key, 0) < 0)
2555 goto end_block;
2556 dest.len = dest.shape[0] * dest.itemsize;
2557
2558 ret = copy_single(&dest, &src);
2559
2560 end_block:
2561 PyBuffer_Release(&src);
2562 return ret;
2563 }
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002564 if (is_multiindex(key)) {
2565 char *ptr;
2566 if (PyTuple_GET_SIZE(key) < view->ndim) {
2567 PyErr_SetString(PyExc_NotImplementedError,
2568 "sub-views are not implemented");
2569 return -1;
2570 }
2571 ptr = ptr_from_tuple(view, key);
2572 if (ptr == NULL)
2573 return -1;
2574 return pack_single(ptr, value, fmt);
2575 }
2576 if (PySlice_Check(key) || is_multislice(key)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002577 /* Call memory_subscript() to produce a sliced lvalue, then copy
2578 rvalue into lvalue. This is already implemented in _testbuffer.c. */
2579 PyErr_SetString(PyExc_NotImplementedError,
2580 "memoryview slice assignments are currently restricted "
2581 "to ndim = 1");
2582 return -1;
2583 }
2584
2585 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2586 return -1;
2587}
2588
2589static Py_ssize_t
2590memory_length(PyMemoryViewObject *self)
2591{
2592 CHECK_RELEASED_INT(self);
2593 return self->view.ndim == 0 ? 1 : self->view.shape[0];
2594}
2595
2596/* As mapping */
2597static PyMappingMethods memory_as_mapping = {
2598 (lenfunc)memory_length, /* mp_length */
2599 (binaryfunc)memory_subscript, /* mp_subscript */
2600 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
2601};
2602
2603/* As sequence */
2604static PySequenceMethods memory_as_sequence = {
Nick Coghlana0f169c2013-10-02 22:06:54 +10002605 (lenfunc)memory_length, /* sq_length */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002606 0, /* sq_concat */
2607 0, /* sq_repeat */
2608 (ssizeargfunc)memory_item, /* sq_item */
2609};
2610
2611
2612/**************************************************************************/
2613/* Comparisons */
2614/**************************************************************************/
2615
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002616#define MV_COMPARE_EX -1 /* exception */
2617#define MV_COMPARE_NOT_IMPL -2 /* not implemented */
2618
2619/* Translate a StructError to "not equal". Preserve other exceptions. */
2620static int
2621fix_struct_error_int(void)
2622{
2623 assert(PyErr_Occurred());
2624 /* XXX Cannot get at StructError directly? */
2625 if (PyErr_ExceptionMatches(PyExc_ImportError) ||
2626 PyErr_ExceptionMatches(PyExc_MemoryError)) {
2627 return MV_COMPARE_EX;
2628 }
2629 /* StructError: invalid or unknown format -> not equal */
2630 PyErr_Clear();
2631 return 0;
2632}
2633
2634/* Unpack and compare single items of p and q using the struct module. */
2635static int
2636struct_unpack_cmp(const char *p, const char *q,
2637 struct unpacker *unpack_p, struct unpacker *unpack_q)
2638{
2639 PyObject *v, *w;
2640 int ret;
2641
2642 /* At this point any exception from the struct module should not be
2643 StructError, since both formats have been accepted already. */
2644 v = struct_unpack_single(p, unpack_p);
2645 if (v == NULL)
2646 return MV_COMPARE_EX;
2647
2648 w = struct_unpack_single(q, unpack_q);
2649 if (w == NULL) {
2650 Py_DECREF(v);
2651 return MV_COMPARE_EX;
2652 }
2653
2654 /* MV_COMPARE_EX == -1: exceptions are preserved */
2655 ret = PyObject_RichCompareBool(v, w, Py_EQ);
2656 Py_DECREF(v);
2657 Py_DECREF(w);
2658
2659 return ret;
2660}
2661
2662/* Unpack and compare single items of p and q. If both p and q have the same
2663 single element native format, the comparison uses a fast path (gcc creates
2664 a jump table and converts memcpy into simple assignments on x86/x64).
2665
2666 Otherwise, the comparison is delegated to the struct module, which is
2667 30-60x slower. */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002668#define CMP_SINGLE(p, q, type) \
2669 do { \
2670 type x; \
2671 type y; \
2672 memcpy((char *)&x, p, sizeof x); \
2673 memcpy((char *)&y, q, sizeof y); \
2674 equal = (x == y); \
2675 } while (0)
2676
Benjamin Peterson82cce4c2016-09-08 11:56:06 -07002677static inline int
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002678unpack_cmp(const char *p, const char *q, char fmt,
2679 struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002680{
2681 int equal;
2682
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002683 switch (fmt) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002684
2685 /* signed integers and fast path for 'B' */
2686 case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
2687 case 'b': return *((signed char *)p) == *((signed char *)q);
2688 case 'h': CMP_SINGLE(p, q, short); return equal;
2689 case 'i': CMP_SINGLE(p, q, int); return equal;
2690 case 'l': CMP_SINGLE(p, q, long); return equal;
2691
2692 /* boolean */
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002693 case '?': CMP_SINGLE(p, q, _Bool); return equal;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002694
2695 /* unsigned integers */
2696 case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2697 case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2698 case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2699
2700 /* native 64-bit */
Benjamin Petersonaf580df2016-09-06 10:46:49 -07002701 case 'q': CMP_SINGLE(p, q, long long); return equal;
2702 case 'Q': CMP_SINGLE(p, q, unsigned long long); return equal;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002703
2704 /* ssize_t and size_t */
2705 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2706 case 'N': CMP_SINGLE(p, q, size_t); return equal;
2707
2708 /* floats */
2709 /* XXX DBL_EPSILON? */
2710 case 'f': CMP_SINGLE(p, q, float); return equal;
2711 case 'd': CMP_SINGLE(p, q, double); return equal;
2712
2713 /* bytes object */
2714 case 'c': return *p == *q;
2715
2716 /* pointer */
2717 case 'P': CMP_SINGLE(p, q, void *); return equal;
2718
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002719 /* use the struct module */
2720 case '_':
2721 assert(unpack_p);
2722 assert(unpack_q);
2723 return struct_unpack_cmp(p, q, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002724 }
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002725
2726 /* NOT REACHED */
2727 PyErr_SetString(PyExc_RuntimeError,
2728 "memoryview: internal error in richcompare");
2729 return MV_COMPARE_EX;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002730}
2731
2732/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2733static int
2734cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2735 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2736 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002737 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002738{
2739 Py_ssize_t i;
2740 int equal;
2741
2742 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002743 const char *xp = ADJUST_PTR(p, psuboffsets, 0);
2744 const char *xq = ADJUST_PTR(q, qsuboffsets, 0);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002745 equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002746 if (equal <= 0)
2747 return equal;
2748 }
2749
2750 return 1;
2751}
2752
2753/* Recursively compare two multi-dimensional arrays that have the same
2754 logical structure. Assumption: ndim >= 1. */
2755static int
2756cmp_rec(const char *p, const char *q,
2757 Py_ssize_t ndim, const Py_ssize_t *shape,
2758 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2759 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002760 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002761{
2762 Py_ssize_t i;
2763 int equal;
2764
2765 assert(ndim >= 1);
2766 assert(shape != NULL);
2767 assert(pstrides != NULL);
2768 assert(qstrides != NULL);
2769
2770 if (ndim == 1) {
2771 return cmp_base(p, q, shape,
2772 pstrides, psuboffsets,
2773 qstrides, qsuboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002774 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002775 }
2776
2777 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
Antoine Pitrou31084ba2015-03-19 23:29:36 +01002778 const char *xp = ADJUST_PTR(p, psuboffsets, 0);
2779 const char *xq = ADJUST_PTR(q, qsuboffsets, 0);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002780 equal = cmp_rec(xp, xq, ndim-1, shape+1,
2781 pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2782 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002783 fmt, unpack_p, unpack_q);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002784 if (equal <= 0)
2785 return equal;
2786 }
2787
2788 return 1;
2789}
2790
2791static PyObject *
2792memory_richcompare(PyObject *v, PyObject *w, int op)
2793{
2794 PyObject *res;
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002795 Py_buffer wbuf, *vv;
2796 Py_buffer *ww = NULL;
2797 struct unpacker *unpack_v = NULL;
2798 struct unpacker *unpack_w = NULL;
2799 char vfmt, wfmt;
2800 int equal = MV_COMPARE_NOT_IMPL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002801
2802 if (op != Py_EQ && op != Py_NE)
2803 goto result; /* Py_NotImplemented */
2804
2805 assert(PyMemoryView_Check(v));
2806 if (BASE_INACCESSIBLE(v)) {
2807 equal = (v == w);
2808 goto result;
2809 }
2810 vv = VIEW_ADDR(v);
2811
2812 if (PyMemoryView_Check(w)) {
2813 if (BASE_INACCESSIBLE(w)) {
2814 equal = (v == w);
2815 goto result;
2816 }
2817 ww = VIEW_ADDR(w);
2818 }
2819 else {
2820 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2821 PyErr_Clear();
2822 goto result; /* Py_NotImplemented */
2823 }
2824 ww = &wbuf;
2825 }
2826
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002827 if (!equiv_shape(vv, ww)) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002828 PyErr_Clear();
2829 equal = 0;
2830 goto result;
2831 }
2832
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002833 /* Use fast unpacking for identical primitive C type formats. */
2834 if (get_native_fmtchar(&vfmt, vv->format) < 0)
2835 vfmt = '_';
2836 if (get_native_fmtchar(&wfmt, ww->format) < 0)
2837 wfmt = '_';
2838 if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
2839 /* Use struct module unpacking. NOTE: Even for equal format strings,
2840 memcmp() cannot be used for item comparison since it would give
2841 incorrect results in the case of NaNs or uninitialized padding
2842 bytes. */
2843 vfmt = '_';
2844 unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
2845 if (unpack_v == NULL) {
2846 equal = fix_struct_error_int();
2847 goto result;
2848 }
2849 unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
2850 if (unpack_w == NULL) {
2851 equal = fix_struct_error_int();
2852 goto result;
2853 }
2854 }
2855
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002856 if (vv->ndim == 0) {
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002857 equal = unpack_cmp(vv->buf, ww->buf,
2858 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002859 }
2860 else if (vv->ndim == 1) {
2861 equal = cmp_base(vv->buf, ww->buf, vv->shape,
2862 vv->strides, vv->suboffsets,
2863 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002864 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002865 }
2866 else {
2867 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2868 vv->strides, vv->suboffsets,
2869 ww->strides, ww->suboffsets,
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002870 vfmt, unpack_v, unpack_w);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002871 }
2872
2873result:
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002874 if (equal < 0) {
2875 if (equal == MV_COMPARE_NOT_IMPL)
2876 res = Py_NotImplemented;
2877 else /* exception */
2878 res = NULL;
2879 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002880 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2881 res = Py_True;
2882 else
2883 res = Py_False;
2884
2885 if (ww == &wbuf)
2886 PyBuffer_Release(ww);
Nick Coghlan06e1ab02012-08-25 17:59:50 +10002887
2888 unpacker_free(unpack_v);
2889 unpacker_free(unpack_w);
2890
2891 Py_XINCREF(res);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002892 return res;
2893}
2894
2895/**************************************************************************/
2896/* Hash */
2897/**************************************************************************/
2898
2899static Py_hash_t
2900memory_hash(PyMemoryViewObject *self)
2901{
2902 if (self->hash == -1) {
2903 Py_buffer *view = &self->view;
2904 char *mem = view->buf;
Stefan Krah4af77a02012-11-02 17:49:22 +01002905 Py_ssize_t ret;
2906 char fmt;
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002907
2908 CHECK_RELEASED_INT(self);
2909
2910 if (!view->readonly) {
2911 PyErr_SetString(PyExc_ValueError,
2912 "cannot hash writable memoryview object");
2913 return -1;
2914 }
Stefan Krah4af77a02012-11-02 17:49:22 +01002915 ret = get_native_fmtchar(&fmt, view->format);
2916 if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
2917 PyErr_SetString(PyExc_ValueError,
2918 "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
2919 return -1;
2920 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002921 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2922 /* Keep the original error message */
2923 return -1;
2924 }
2925
2926 if (!MV_C_CONTIGUOUS(self->flags)) {
2927 mem = PyMem_Malloc(view->len);
2928 if (mem == NULL) {
2929 PyErr_NoMemory();
2930 return -1;
2931 }
Stefan Krah7d12d9d2012-07-28 12:25:55 +02002932 if (buffer_to_contiguous(mem, view, 'C') < 0) {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002933 PyMem_Free(mem);
2934 return -1;
2935 }
2936 }
2937
2938 /* Can't fail */
Christian Heimes985ecdc2013-11-20 11:46:18 +01002939 self->hash = _Py_HashBytes(mem, view->len);
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002940
2941 if (mem != view->buf)
2942 PyMem_Free(mem);
2943 }
2944
2945 return self->hash;
2946}
2947
2948
2949/**************************************************************************/
2950/* getters */
2951/**************************************************************************/
2952
2953static PyObject *
2954_IntTupleFromSsizet(int len, Py_ssize_t *vals)
2955{
2956 int i;
2957 PyObject *o;
2958 PyObject *intTuple;
2959
2960 if (vals == NULL)
2961 return PyTuple_New(0);
2962
2963 intTuple = PyTuple_New(len);
2964 if (!intTuple)
2965 return NULL;
2966 for (i=0; i<len; i++) {
2967 o = PyLong_FromSsize_t(vals[i]);
2968 if (!o) {
2969 Py_DECREF(intTuple);
2970 return NULL;
2971 }
2972 PyTuple_SET_ITEM(intTuple, i, o);
2973 }
2974 return intTuple;
2975}
2976
2977static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002978memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002979{
2980 Py_buffer *view = &self->view;
2981
2982 CHECK_RELEASED(self);
2983 if (view->obj == NULL) {
2984 Py_RETURN_NONE;
2985 }
2986 Py_INCREF(view->obj);
2987 return view->obj;
2988}
2989
2990static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002991memory_nbytes_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002992{
2993 CHECK_RELEASED(self);
2994 return PyLong_FromSsize_t(self->view.len);
2995}
2996
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002997static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02002998memory_format_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002999{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003000 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003001 return PyUnicode_FromString(self->view.format);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003002}
3003
3004static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02003005memory_itemsize_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003006{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003007 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003008 return PyLong_FromSsize_t(self->view.itemsize);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003009}
3010
3011static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02003012memory_shape_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003013{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003014 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003015 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003016}
3017
3018static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02003019memory_strides_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003020{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003021 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003022 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003023}
3024
3025static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02003026memory_suboffsets_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003027{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003028 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003029 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003030}
3031
3032static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02003033memory_readonly_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003034{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003035 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003036 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003037}
3038
3039static PyObject *
Serhiy Storchakad4f9cf52018-11-27 19:34:35 +02003040memory_ndim_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003041{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003042 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003043 return PyLong_FromLong(self->view.ndim);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003044}
3045
Stefan Krah9a2d99e2012-02-25 12:24:21 +01003046static PyObject *
3047memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
3048{
3049 CHECK_RELEASED(self);
3050 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
3051}
3052
3053static PyObject *
3054memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
3055{
3056 CHECK_RELEASED(self);
3057 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
3058}
3059
3060static PyObject *
3061memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
3062{
3063 CHECK_RELEASED(self);
3064 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
3065}
3066
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003067PyDoc_STRVAR(memory_obj_doc,
3068 "The underlying object of the memoryview.");
3069PyDoc_STRVAR(memory_nbytes_doc,
3070 "The amount of space in bytes that the array would use in\n"
3071 " a contiguous representation.");
3072PyDoc_STRVAR(memory_readonly_doc,
3073 "A bool indicating whether the memory is read only.");
3074PyDoc_STRVAR(memory_itemsize_doc,
3075 "The size in bytes of each element of the memoryview.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003076PyDoc_STRVAR(memory_format_doc,
3077 "A string containing the format (in struct module style)\n"
3078 " for each element in the view.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003079PyDoc_STRVAR(memory_ndim_doc,
3080 "An integer indicating how many dimensions of a multi-dimensional\n"
3081 " array the memory represents.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003082PyDoc_STRVAR(memory_shape_doc,
3083 "A tuple of ndim integers giving the shape of the memory\n"
3084 " as an N-dimensional array.");
3085PyDoc_STRVAR(memory_strides_doc,
3086 "A tuple of ndim integers giving the size in bytes to access\n"
3087 " each element for each dimension of the array.");
3088PyDoc_STRVAR(memory_suboffsets_doc,
3089 "A tuple of integers used internally for PIL-style arrays.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003090PyDoc_STRVAR(memory_c_contiguous_doc,
3091 "A bool indicating whether the memory is C contiguous.");
3092PyDoc_STRVAR(memory_f_contiguous_doc,
3093 "A bool indicating whether the memory is Fortran contiguous.");
3094PyDoc_STRVAR(memory_contiguous_doc,
3095 "A bool indicating whether the memory is contiguous.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003096
Stefan Krahbcaf5992014-05-18 00:35:09 +02003097
Stefan Krah9a2d99e2012-02-25 12:24:21 +01003098static PyGetSetDef memory_getsetlist[] = {
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003099 {"obj", (getter)memory_obj_get, NULL, memory_obj_doc},
3100 {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc},
Alexander Belopolskye370c382012-09-03 16:43:55 -04003101 {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc},
3102 {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc},
3103 {"format", (getter)memory_format_get, NULL, memory_format_doc},
3104 {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc},
3105 {"shape", (getter)memory_shape_get, NULL, memory_shape_doc},
3106 {"strides", (getter)memory_strides_get, NULL, memory_strides_doc},
3107 {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003108 {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc},
3109 {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc},
3110 {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc},
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003111 {NULL, NULL, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003112};
3113
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003114PyDoc_STRVAR(memory_release_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02003115"release($self, /)\n--\n\
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003116\n\
3117Release the underlying buffer exposed by the memoryview object.");
3118PyDoc_STRVAR(memory_tobytes_doc,
Stefan Krahd08ea702019-02-02 18:57:41 +01003119"tobytes($self, /, order=None)\n--\n\
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003120\n\
Stefan Krahd08ea702019-02-02 18:57:41 +01003121Return the data in the buffer as a byte string. Order can be {'C', 'F', 'A'}.\n\
3122When order is 'C' or 'F', the data of the original array is converted to C or\n\
3123Fortran order. For contiguous views, 'A' returns an exact copy of the physical\n\
3124memory. In particular, in-memory Fortran order is preserved. For non-contiguous\n\
3125views, the data is converted to C first. order=None is the same as order='C'.");
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003126PyDoc_STRVAR(memory_tolist_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02003127"tolist($self, /)\n--\n\
Alexander Belopolsky397e5c92012-09-03 16:29:11 -04003128\n\
3129Return the data in the buffer as a list of elements.");
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003130PyDoc_STRVAR(memory_cast_doc,
Stefan Krahbcaf5992014-05-18 00:35:09 +02003131"cast($self, /, format, *, shape)\n--\n\
Alexander Belopolskyf73c69e2012-09-03 16:51:01 -04003132\n\
3133Cast a memoryview to a new format or shape.");
Antoine Pitrou480ab052018-04-14 19:49:21 +02003134PyDoc_STRVAR(memory_toreadonly_doc,
3135"toreadonly($self, /)\n--\n\
3136\n\
3137Return a readonly version of the memoryview.");
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003138
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00003139static PyMethodDef memory_methods[] = {
Alexander Belopolskye370c382012-09-03 16:43:55 -04003140 {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
Stéphane Wirtel359a2f32019-03-05 16:10:53 +01003141 {"tobytes", (PyCFunction)(void(*)(void))memory_tobytes, METH_VARARGS|METH_KEYWORDS, memory_tobytes_doc},
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07003142 MEMORYVIEW_HEX_METHODDEF
Alexander Belopolskye370c382012-09-03 16:43:55 -04003143 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
Serhiy Storchaka62be7422018-11-27 13:27:31 +02003144 {"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
Antoine Pitrou480ab052018-04-14 19:49:21 +02003145 {"toreadonly", (PyCFunction)memory_toreadonly, METH_NOARGS, memory_toreadonly_doc},
Stefan Krahe4c07992012-07-28 14:10:02 +02003146 {"__enter__", memory_enter, METH_NOARGS, NULL},
3147 {"__exit__", memory_exit, METH_VARARGS, NULL},
Stefan Krah9a2d99e2012-02-25 12:24:21 +01003148 {NULL, NULL}
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003149};
3150
3151
3152PyTypeObject PyMemoryView_Type = {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003153 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01003154 "memoryview", /* tp_name */
3155 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */
3156 sizeof(Py_ssize_t), /* tp_itemsize */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003157 (destructor)memory_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003158 0, /* tp_vectorcall_offset */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003159 0, /* tp_getattr */
3160 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02003161 0, /* tp_as_async */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003162 (reprfunc)memory_repr, /* tp_repr */
3163 0, /* tp_as_number */
Raymond Hettinger159eac92009-06-23 20:38:54 +00003164 &memory_as_sequence, /* tp_as_sequence */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003165 &memory_as_mapping, /* tp_as_mapping */
Antoine Pitrouce4a9da2011-11-21 20:46:33 +01003166 (hashfunc)memory_hash, /* tp_hash */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003167 0, /* tp_call */
Benjamin Peterson87618552009-02-08 15:00:52 +00003168 0, /* tp_str */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003169 PyObject_GenericGetAttr, /* tp_getattro */
3170 0, /* tp_setattro */
3171 &memory_as_buffer, /* tp_as_buffer */
3172 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3173 memory_doc, /* tp_doc */
3174 (traverseproc)memory_traverse, /* tp_traverse */
3175 (inquiry)memory_clear, /* tp_clear */
3176 memory_richcompare, /* tp_richcompare */
Richard Oudkerk3e0a1eb2012-05-28 21:35:09 +01003177 offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00003178 0, /* tp_iter */
3179 0, /* tp_iternext */
3180 memory_methods, /* tp_methods */
3181 0, /* tp_members */
3182 memory_getsetlist, /* tp_getset */
3183 0, /* tp_base */
3184 0, /* tp_dict */
3185 0, /* tp_descr_get */
3186 0, /* tp_descr_set */
3187 0, /* tp_dictoffset */
3188 0, /* tp_init */
3189 0, /* tp_alloc */
3190 memory_new, /* tp_new */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00003191};