blob: e87abf5497c32a3cad3187a823ab4f6314f3d8ec [file] [log] [blame]
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001/* Memoryview object implementation */
2
3#include "Python.h"
Stefan Krah9a2d99e2012-02-25 12:24:21 +01004#include <stddef.h>
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00005
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00006
Stefan Krah9a2d99e2012-02-25 12:24:21 +01007/****************************************************************************/
8/* ManagedBuffer Object */
9/****************************************************************************/
10
11/*
12 ManagedBuffer Object:
13 ---------------------
14
15 The purpose of this object is to facilitate the handling of chained
16 memoryviews that have the same underlying exporting object. PEP-3118
17 allows the underlying object to change while a view is exported. This
18 could lead to unexpected results when constructing a new memoryview
19 from an existing memoryview.
20
21 Rather than repeatedly redirecting buffer requests to the original base
22 object, all chained memoryviews use a single buffer snapshot. This
23 snapshot is generated by the constructor _PyManagedBuffer_FromObject().
24
25 Ownership rules:
26 ----------------
27
28 The master buffer inside a managed buffer is filled in by the original
29 base object. shape, strides, suboffsets and format are read-only for
30 all consumers.
31
32 A memoryview's buffer is a private copy of the exporter's buffer. shape,
33 strides and suboffsets belong to the memoryview and are thus writable.
34
35 If a memoryview itself exports several buffers via memory_getbuf(), all
36 buffer copies share shape, strides and suboffsets. In this case, the
37 arrays are NOT writable.
38
39 Reference count assumptions:
40 ----------------------------
41
42 The 'obj' member of a Py_buffer must either be NULL or refer to the
43 exporting base object. In the Python codebase, all getbufferprocs
44 return a new reference to view.obj (example: bytes_buffer_getbuffer()).
45
46 PyBuffer_Release() decrements view.obj (if non-NULL), so the
47 releasebufferprocs must NOT decrement view.obj.
48*/
49
50
51#define XSTRINGIZE(v) #v
52#define STRINGIZE(v) XSTRINGIZE(v)
53
54#define CHECK_MBUF_RELEASED(mbuf) \
55 if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \
56 PyErr_SetString(PyExc_ValueError, \
57 "operation forbidden on released memoryview object"); \
58 return NULL; \
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000059 }
60
Antoine Pitrou6e6cc832010-09-09 12:59:39 +000061
Stefan Krah9a2d99e2012-02-25 12:24:21 +010062Py_LOCAL_INLINE(_PyManagedBufferObject *)
63mbuf_alloc(void)
Antoine Pitroubc420402008-12-07 20:14:49 +000064{
Stefan Krah9a2d99e2012-02-25 12:24:21 +010065 _PyManagedBufferObject *mbuf;
66
67 mbuf = (_PyManagedBufferObject *)
68 PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type);
69 if (mbuf == NULL)
70 return NULL;
71 mbuf->flags = 0;
72 mbuf->exports = 0;
73 mbuf->master.obj = NULL;
74 _PyObject_GC_TRACK(mbuf);
75
76 return mbuf;
77}
78
79static PyObject *
80_PyManagedBuffer_FromObject(PyObject *base)
81{
82 _PyManagedBufferObject *mbuf;
83
84 mbuf = mbuf_alloc();
85 if (mbuf == NULL)
86 return NULL;
87
88 if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) {
89 /* mbuf->master.obj must be NULL. */
90 Py_DECREF(mbuf);
91 return NULL;
92 }
93
94 /* Assume that master.obj is a new reference to base. */
95 assert(mbuf->master.obj == base);
96
97 return (PyObject *)mbuf;
Antoine Pitrouc3b39242009-01-03 16:59:18 +000098}
99
100static void
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100101mbuf_release(_PyManagedBufferObject *self)
Antoine Pitrouc3b39242009-01-03 16:59:18 +0000102{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100103 if (self->flags&_Py_MANAGED_BUFFER_RELEASED)
104 return;
105
106 /* NOTE: at this point self->exports can still be > 0 if this function
107 is called from mbuf_clear() to break up a reference cycle. */
108 self->flags |= _Py_MANAGED_BUFFER_RELEASED;
109
110 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
111 _PyObject_GC_UNTRACK(self);
112 PyBuffer_Release(&self->master);
113}
114
115static void
116mbuf_dealloc(_PyManagedBufferObject *self)
117{
118 assert(self->exports == 0);
119 mbuf_release(self);
120 if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT)
121 PyMem_Free(self->master.format);
122 PyObject_GC_Del(self);
Antoine Pitroubc420402008-12-07 20:14:49 +0000123}
124
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000125static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100126mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000127{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100128 Py_VISIT(self->master.obj);
129 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000130}
131
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100132static int
133mbuf_clear(_PyManagedBufferObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000134{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100135 assert(self->exports >= 0);
136 mbuf_release(self);
137 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000138}
139
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100140PyTypeObject _PyManagedBuffer_Type = {
141 PyVarObject_HEAD_INIT(&PyType_Type, 0)
142 "managedbuffer",
143 sizeof(_PyManagedBufferObject),
144 0,
145 (destructor)mbuf_dealloc, /* tp_dealloc */
146 0, /* tp_print */
147 0, /* tp_getattr */
148 0, /* tp_setattr */
149 0, /* tp_reserved */
150 0, /* tp_repr */
151 0, /* tp_as_number */
152 0, /* tp_as_sequence */
153 0, /* tp_as_mapping */
154 0, /* tp_hash */
155 0, /* tp_call */
156 0, /* tp_str */
157 PyObject_GenericGetAttr, /* tp_getattro */
158 0, /* tp_setattro */
159 0, /* tp_as_buffer */
160 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
161 0, /* tp_doc */
162 (traverseproc)mbuf_traverse, /* tp_traverse */
163 (inquiry)mbuf_clear /* tp_clear */
164};
165
166
167/****************************************************************************/
168/* MemoryView Object */
169/****************************************************************************/
170
171/* In the process of breaking reference cycles mbuf_release() can be
172 called before memory_release(). */
173#define BASE_INACCESSIBLE(mv) \
174 (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \
175 ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED)
176
177#define CHECK_RELEASED(mv) \
178 if (BASE_INACCESSIBLE(mv)) { \
179 PyErr_SetString(PyExc_ValueError, \
180 "operation forbidden on released memoryview object"); \
181 return NULL; \
182 }
183
184#define CHECK_RELEASED_INT(mv) \
185 if (BASE_INACCESSIBLE(mv)) { \
186 PyErr_SetString(PyExc_ValueError, \
187 "operation forbidden on released memoryview object"); \
188 return -1; \
189 }
190
191#define CHECK_LIST_OR_TUPLE(v) \
192 if (!PyList_Check(v) && !PyTuple_Check(v)) { \
193 PyErr_SetString(PyExc_TypeError, \
194 #v " must be a list or a tuple"); \
195 return NULL; \
196 }
197
198#define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view)
199
200/* Check for the presence of suboffsets in the first dimension. */
201#define HAVE_PTR(suboffsets) (suboffsets && suboffsets[0] >= 0)
202/* Adjust ptr if suboffsets are present. */
203#define ADJUST_PTR(ptr, suboffsets) \
204 (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr)
205
206/* Memoryview buffer properties */
207#define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
208#define MV_F_CONTIGUOUS(flags) \
209 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
210#define MV_ANY_CONTIGUOUS(flags) \
211 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
212
213/* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */
214#define MV_CONTIGUOUS_NDIM1(view) \
215 ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize)
216
217/* getbuffer() requests */
218#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
219#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
220#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
221#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
222#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
223#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
224#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
225#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
226
227
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000228PyDoc_STRVAR(memory_doc,
229"memoryview(object)\n\
230\n\
231Create a new memoryview object which references the given object.");
232
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100233
234/**************************************************************************/
235/* Copy memoryview buffers */
236/**************************************************************************/
237
238/* The functions in this section take a source and a destination buffer
239 with the same logical structure: format, itemsize, ndim and shape
240 are identical, with ndim > 0.
241
242 NOTE: All buffers are assumed to have PyBUF_FULL information, which
243 is the case for memoryviews! */
244
245
246/* Assumptions: ndim >= 1. The macro tests for a corner case that should
247 perhaps be explicitly forbidden in the PEP. */
248#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
249 (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
250
251Py_LOCAL_INLINE(int)
252last_dim_is_contiguous(Py_buffer *dest, Py_buffer *src)
253{
254 assert(dest->ndim > 0 && src->ndim > 0);
255 return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) &&
256 !HAVE_SUBOFFSETS_IN_LAST_DIM(src) &&
257 dest->strides[dest->ndim-1] == dest->itemsize &&
258 src->strides[src->ndim-1] == src->itemsize);
259}
260
261/* Check that the logical structure of the destination and source buffers
262 is identical. */
263static int
264cmp_structure(Py_buffer *dest, Py_buffer *src)
265{
266 const char *dfmt, *sfmt;
267 int i;
268
269 assert(dest->format && src->format);
270 dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format;
271 sfmt = src->format[0] == '@' ? src->format+1 : src->format;
272
273 if (strcmp(dfmt, sfmt) != 0 ||
274 dest->itemsize != src->itemsize ||
275 dest->ndim != src->ndim) {
276 goto value_error;
277 }
278
279 for (i = 0; i < dest->ndim; i++) {
280 if (dest->shape[i] != src->shape[i])
281 goto value_error;
282 if (dest->shape[i] == 0)
283 break;
284 }
285
286 return 0;
287
288value_error:
289 PyErr_SetString(PyExc_ValueError,
290 "ndarray assignment: lvalue and rvalue have different structures");
291 return -1;
292}
293
294/* Base case for recursive multi-dimensional copying. Contiguous arrays are
295 copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
296 sizeof(mem) == shape[0] * itemsize. */
297static void
298copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
299 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
300 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
301 char *mem)
302{
303 if (mem == NULL) { /* contiguous */
304 Py_ssize_t size = shape[0] * itemsize;
305 if (dptr + size < sptr || sptr + size < dptr)
306 memcpy(dptr, sptr, size); /* no overlapping */
307 else
308 memmove(dptr, sptr, size);
309 }
310 else {
311 char *p;
312 Py_ssize_t i;
313 for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
314 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
315 memcpy(p, xsptr, itemsize);
316 }
317 for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
318 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
319 memcpy(xdptr, p, itemsize);
320 }
321 }
322
323}
324
325/* Recursively copy a source buffer to a destination buffer. The two buffers
326 have the same ndim, shape and itemsize. */
327static void
328copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
329 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
330 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
331 char *mem)
332{
333 Py_ssize_t i;
334
335 assert(ndim >= 1);
336
337 if (ndim == 1) {
338 copy_base(shape, itemsize,
339 dptr, dstrides, dsuboffsets,
340 sptr, sstrides, ssuboffsets,
341 mem);
342 return;
343 }
344
345 for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
346 char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
347 char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
348
349 copy_rec(shape+1, ndim-1, itemsize,
350 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
351 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
352 mem);
353 }
354}
355
356/* Faster copying of one-dimensional arrays. */
357static int
358copy_single(Py_buffer *dest, Py_buffer *src)
359{
360 char *mem = NULL;
361
362 assert(dest->ndim == 1);
363
364 if (cmp_structure(dest, src) < 0)
365 return -1;
366
367 if (!last_dim_is_contiguous(dest, src)) {
368 mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
369 if (mem == NULL) {
370 PyErr_NoMemory();
371 return -1;
372 }
373 }
374
375 copy_base(dest->shape, dest->itemsize,
376 dest->buf, dest->strides, dest->suboffsets,
377 src->buf, src->strides, src->suboffsets,
378 mem);
379
380 if (mem)
381 PyMem_Free(mem);
382
383 return 0;
384}
385
386/* Recursively copy src to dest. Both buffers must have the same basic
387 structure. Copying is atomic, the function never fails with a partial
388 copy. */
389static int
390copy_buffer(Py_buffer *dest, Py_buffer *src)
391{
392 char *mem = NULL;
393
394 assert(dest->ndim > 0);
395
396 if (cmp_structure(dest, src) < 0)
397 return -1;
398
399 if (!last_dim_is_contiguous(dest, src)) {
400 mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
401 if (mem == NULL) {
402 PyErr_NoMemory();
403 return -1;
404 }
405 }
406
407 copy_rec(dest->shape, dest->ndim, dest->itemsize,
408 dest->buf, dest->strides, dest->suboffsets,
409 src->buf, src->strides, src->suboffsets,
410 mem);
411
412 if (mem)
413 PyMem_Free(mem);
414
415 return 0;
416}
417
418/* Initialize strides for a C-contiguous array. */
419Py_LOCAL_INLINE(void)
420init_strides_from_shape(Py_buffer *view)
421{
422 Py_ssize_t i;
423
424 assert(view->ndim > 0);
425
426 view->strides[view->ndim-1] = view->itemsize;
427 for (i = view->ndim-2; i >= 0; i--)
428 view->strides[i] = view->strides[i+1] * view->shape[i+1];
429}
430
431/* Initialize strides for a Fortran-contiguous array. */
432Py_LOCAL_INLINE(void)
433init_fortran_strides_from_shape(Py_buffer *view)
434{
435 Py_ssize_t i;
436
437 assert(view->ndim > 0);
438
439 view->strides[0] = view->itemsize;
440 for (i = 1; i < view->ndim; i++)
441 view->strides[i] = view->strides[i-1] * view->shape[i-1];
442}
443
444/* Copy src to a C-contiguous representation. Assumptions:
445 len(mem) == src->len. */
446static int
447buffer_to_c_contiguous(char *mem, Py_buffer *src)
448{
449 Py_buffer dest;
450 Py_ssize_t *strides;
451 int ret;
452
453 assert(src->shape != NULL);
454 assert(src->strides != NULL);
455
456 strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
457 if (strides == NULL) {
458 PyErr_NoMemory();
459 return -1;
460 }
461
462 /* initialize dest as a C-contiguous buffer */
463 dest = *src;
464 dest.buf = mem;
465 /* shape is constant and shared */
466 dest.strides = strides;
467 init_strides_from_shape(&dest);
468 dest.suboffsets = NULL;
469
470 ret = copy_buffer(&dest, src);
471
472 PyMem_Free(strides);
473 return ret;
474}
475
476
477/****************************************************************************/
478/* Constructors */
479/****************************************************************************/
480
481/* Initialize values that are shared with the managed buffer. */
482Py_LOCAL_INLINE(void)
483init_shared_values(Py_buffer *dest, const Py_buffer *src)
484{
485 dest->obj = src->obj;
486 dest->buf = src->buf;
487 dest->len = src->len;
488 dest->itemsize = src->itemsize;
489 dest->readonly = src->readonly;
490 dest->format = src->format ? src->format : "B";
491 dest->internal = src->internal;
492}
493
494/* Copy shape and strides. Reconstruct missing values. */
495static void
496init_shape_strides(Py_buffer *dest, const Py_buffer *src)
497{
498 Py_ssize_t i;
499
500 if (src->ndim == 0) {
501 dest->shape = NULL;
502 dest->strides = NULL;
503 return;
504 }
505 if (src->ndim == 1) {
506 dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
507 dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
508 return;
509 }
510
511 for (i = 0; i < src->ndim; i++)
512 dest->shape[i] = src->shape[i];
513 if (src->strides) {
514 for (i = 0; i < src->ndim; i++)
515 dest->strides[i] = src->strides[i];
516 }
517 else {
518 init_strides_from_shape(dest);
519 }
520}
521
522Py_LOCAL_INLINE(void)
523init_suboffsets(Py_buffer *dest, const Py_buffer *src)
524{
525 Py_ssize_t i;
526
527 if (src->suboffsets == NULL) {
528 dest->suboffsets = NULL;
529 return;
530 }
531 for (i = 0; i < src->ndim; i++)
532 dest->suboffsets[i] = src->suboffsets[i];
533}
534
535/* len = product(shape) * itemsize */
536Py_LOCAL_INLINE(void)
537init_len(Py_buffer *view)
538{
539 Py_ssize_t i, len;
540
541 len = 1;
542 for (i = 0; i < view->ndim; i++)
543 len *= view->shape[i];
544 len *= view->itemsize;
545
546 view->len = len;
547}
548
549/* Initialize memoryview buffer properties. */
550static void
551init_flags(PyMemoryViewObject *mv)
552{
553 const Py_buffer *view = &mv->view;
554 int flags = 0;
555
556 switch (view->ndim) {
557 case 0:
558 flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
559 _Py_MEMORYVIEW_FORTRAN);
560 break;
561 case 1:
562 if (MV_CONTIGUOUS_NDIM1(view))
563 flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
564 break;
565 default:
566 if (PyBuffer_IsContiguous(view, 'C'))
567 flags |= _Py_MEMORYVIEW_C;
568 if (PyBuffer_IsContiguous(view, 'F'))
569 flags |= _Py_MEMORYVIEW_FORTRAN;
570 break;
571 }
572
573 if (view->suboffsets) {
574 flags |= _Py_MEMORYVIEW_PIL;
575 flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
576 }
577
578 mv->flags = flags;
579}
580
581/* Allocate a new memoryview and perform basic initialization. New memoryviews
582 are exclusively created through the mbuf_add functions. */
583Py_LOCAL_INLINE(PyMemoryViewObject *)
584memory_alloc(int ndim)
585{
586 PyMemoryViewObject *mv;
587
588 mv = (PyMemoryViewObject *)
589 PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
590 if (mv == NULL)
591 return NULL;
592
593 mv->mbuf = NULL;
594 mv->hash = -1;
595 mv->flags = 0;
596 mv->exports = 0;
597 mv->view.ndim = ndim;
598 mv->view.shape = mv->ob_array;
599 mv->view.strides = mv->ob_array + ndim;
600 mv->view.suboffsets = mv->ob_array + 2 * ndim;
601
602 _PyObject_GC_TRACK(mv);
603 return mv;
604}
605
606/*
607 Return a new memoryview that is registered with mbuf. If src is NULL,
608 use mbuf->master as the underlying buffer. Otherwise, use src.
609
610 The new memoryview has full buffer information: shape and strides
611 are always present, suboffsets as needed. Arrays are copied to
612 the memoryview's ob_array field.
613 */
614static PyObject *
615mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
616{
617 PyMemoryViewObject *mv;
618 Py_buffer *dest;
619
620 if (src == NULL)
621 src = &mbuf->master;
622
623 if (src->ndim > PyBUF_MAX_NDIM) {
624 PyErr_SetString(PyExc_ValueError,
625 "memoryview: number of dimensions must not exceed "
626 STRINGIZE(PyBUF_MAX_NDIM));
627 return NULL;
628 }
629
630 mv = memory_alloc(src->ndim);
631 if (mv == NULL)
632 return NULL;
633
634 dest = &mv->view;
635 init_shared_values(dest, src);
636 init_shape_strides(dest, src);
637 init_suboffsets(dest, src);
638 init_flags(mv);
639
640 mv->mbuf = mbuf;
641 Py_INCREF(mbuf);
642 mbuf->exports++;
643
644 return (PyObject *)mv;
645}
646
647/* Register an incomplete view: shape, strides, suboffsets and flags still
648 need to be initialized. Use 'ndim' instead of src->ndim to determine the
649 size of the memoryview's ob_array.
650
651 Assumption: ndim <= PyBUF_MAX_NDIM. */
652static PyObject *
653mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
654 int ndim)
655{
656 PyMemoryViewObject *mv;
657 Py_buffer *dest;
658
659 if (src == NULL)
660 src = &mbuf->master;
661
662 assert(ndim <= PyBUF_MAX_NDIM);
663
664 mv = memory_alloc(ndim);
665 if (mv == NULL)
666 return NULL;
667
668 dest = &mv->view;
669 init_shared_values(dest, src);
670
671 mv->mbuf = mbuf;
672 Py_INCREF(mbuf);
673 mbuf->exports++;
674
675 return (PyObject *)mv;
676}
677
678/* Expose a raw memory area as a view of contiguous bytes. flags can be
679 PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
680 The memoryview has complete buffer information. */
681PyObject *
682PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
683{
684 _PyManagedBufferObject *mbuf;
685 PyObject *mv;
686 int readonly;
687
688 assert(mem != NULL);
689 assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
690
691 mbuf = mbuf_alloc();
692 if (mbuf == NULL)
693 return NULL;
694
695 readonly = (flags == PyBUF_WRITE) ? 0 : 1;
696 (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
697 PyBUF_FULL_RO);
698
699 mv = mbuf_add_view(mbuf, NULL);
700 Py_DECREF(mbuf);
701
702 return mv;
703}
704
705/* Create a memoryview from a given Py_buffer. For simple byte views,
706 PyMemoryView_FromMemory() should be used instead.
707 This function is the only entry point that can create a master buffer
708 without full information. Because of this fact init_shape_strides()
709 must be able to reconstruct missing values. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000710PyObject *
Antoine Pitrouee58fa42008-08-19 18:22:14 +0000711PyMemoryView_FromBuffer(Py_buffer *info)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000712{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100713 _PyManagedBufferObject *mbuf;
714 PyObject *mv;
Travis E. Oliphant8ae62b62007-09-23 02:00:13 +0000715
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000716 if (info->buf == NULL) {
717 PyErr_SetString(PyExc_ValueError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100718 "PyMemoryView_FromBuffer(): info->buf must not be NULL");
Antoine Pitrou5bffa792011-02-24 20:50:49 +0000719 return NULL;
720 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100721
722 mbuf = mbuf_alloc();
723 if (mbuf == NULL)
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000724 return NULL;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100725
726 /* info->obj is either NULL or a borrowed reference. This reference
727 should not be decremented in PyBuffer_Release(). */
728 mbuf->master = *info;
729 mbuf->master.obj = NULL;
730
731 mv = mbuf_add_view(mbuf, NULL);
732 Py_DECREF(mbuf);
733
734 return mv;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000735}
736
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100737/* Create a memoryview from an object that implements the buffer protocol.
738 If the object is a memoryview, the new memoryview must be registered
739 with the same managed buffer. Otherwise, a new managed buffer is created. */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000740PyObject *
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100741PyMemoryView_FromObject(PyObject *v)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000742{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100743 _PyManagedBufferObject *mbuf;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000744
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100745 if (PyMemoryView_Check(v)) {
746 PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
747 CHECK_RELEASED(mv);
748 return mbuf_add_view(mv->mbuf, &mv->view);
749 }
750 else if (PyObject_CheckBuffer(v)) {
751 PyObject *ret;
752 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
753 if (mbuf == NULL)
754 return NULL;
755 ret = mbuf_add_view(mbuf, NULL);
756 Py_DECREF(mbuf);
757 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000758 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000759
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100760 PyErr_Format(PyExc_TypeError,
761 "memoryview: %.200s object does not have the buffer interface",
762 Py_TYPE(v)->tp_name);
763 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000764}
765
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100766/* Copy the format string from a base object that might vanish. */
767static int
768mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
769{
770 if (fmt != NULL) {
771 char *cp = PyMem_Malloc(strlen(fmt)+1);
772 if (cp == NULL) {
773 PyErr_NoMemory();
774 return -1;
775 }
776 mbuf->master.format = strcpy(cp, fmt);
777 mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
778 }
779
780 return 0;
781}
782
783/*
784 Return a memoryview that is based on a contiguous copy of src.
785 Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
786
787 Ownership rules:
788 1) As usual, the returned memoryview has a private copy
789 of src->shape, src->strides and src->suboffsets.
790 2) src->format is copied to the master buffer and released
791 in mbuf_dealloc(). The releasebufferproc of the bytes
792 object is NULL, so it does not matter that mbuf_release()
793 passes the altered format pointer to PyBuffer_Release().
794*/
795static PyObject *
796memory_from_contiguous_copy(Py_buffer *src, char order)
797{
798 _PyManagedBufferObject *mbuf;
799 PyMemoryViewObject *mv;
800 PyObject *bytes;
801 Py_buffer *dest;
802 int i;
803
804 assert(src->ndim > 0);
805 assert(src->shape != NULL);
806
807 bytes = PyBytes_FromStringAndSize(NULL, src->len);
808 if (bytes == NULL)
809 return NULL;
810
811 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
812 Py_DECREF(bytes);
813 if (mbuf == NULL)
814 return NULL;
815
816 if (mbuf_copy_format(mbuf, src->format) < 0) {
817 Py_DECREF(mbuf);
818 return NULL;
819 }
820
821 mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
822 Py_DECREF(mbuf);
823 if (mv == NULL)
824 return NULL;
825
826 dest = &mv->view;
827
828 /* shared values are initialized correctly except for itemsize */
829 dest->itemsize = src->itemsize;
830
831 /* shape and strides */
832 for (i = 0; i < src->ndim; i++) {
833 dest->shape[i] = src->shape[i];
834 }
835 if (order == 'C' || order == 'A') {
836 init_strides_from_shape(dest);
837 }
838 else {
839 init_fortran_strides_from_shape(dest);
840 }
841 /* suboffsets */
842 dest->suboffsets = NULL;
843
844 /* flags */
845 init_flags(mv);
846
847 if (copy_buffer(dest, src) < 0) {
848 Py_DECREF(mv);
849 return NULL;
850 }
851
852 return (PyObject *)mv;
853}
854
855/*
856 Return a new memoryview object based on a contiguous exporter with
857 buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
858 The logical structure of the input and output buffers is the same
859 (i.e. tolist(input) == tolist(output)), but the physical layout in
860 memory can be explicitly chosen.
861
862 As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
863 otherwise it may be writable or read-only.
864
865 If the exporter is already contiguous with the desired target order,
866 the memoryview will be directly based on the exporter.
867
868 Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
869 based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
870 'F'ortran order otherwise.
871*/
872PyObject *
873PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
874{
875 PyMemoryViewObject *mv;
876 PyObject *ret;
877 Py_buffer *view;
878
879 assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
880 assert(order == 'C' || order == 'F' || order == 'A');
881
882 mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
883 if (mv == NULL)
884 return NULL;
885
886 view = &mv->view;
887 if (buffertype == PyBUF_WRITE && view->readonly) {
888 PyErr_SetString(PyExc_BufferError,
889 "underlying buffer is not writable");
890 Py_DECREF(mv);
891 return NULL;
892 }
893
894 if (PyBuffer_IsContiguous(view, order))
895 return (PyObject *)mv;
896
897 if (buffertype == PyBUF_WRITE) {
898 PyErr_SetString(PyExc_BufferError,
899 "writable contiguous buffer requested "
900 "for a non-contiguous object.");
901 Py_DECREF(mv);
902 return NULL;
903 }
904
905 ret = memory_from_contiguous_copy(view, order);
906 Py_DECREF(mv);
907 return ret;
908}
909
910
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000911static PyObject *
912memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
913{
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000914 PyObject *obj;
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100915 static char *kwlist[] = {"object", NULL};
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000916
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000917 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
918 &obj)) {
919 return NULL;
920 }
Christian Heimes7b6fc8e2007-11-08 02:28:11 +0000921
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000922 return PyMemoryView_FromObject(obj);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000923}
924
925
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100926/****************************************************************************/
927/* Release/GC management */
928/****************************************************************************/
929
930/* Inform the managed buffer that this particular memoryview will not access
931 the underlying buffer again. If no other memoryviews are registered with
932 the managed buffer, the underlying buffer is released instantly and
933 marked as inaccessible for both the memoryview and the managed buffer.
934
935 This function fails if the memoryview itself has exported buffers. */
936static int
937_memory_release(PyMemoryViewObject *self)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000938{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100939 if (self->flags & _Py_MEMORYVIEW_RELEASED)
940 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000941
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100942 if (self->exports == 0) {
943 self->flags |= _Py_MEMORYVIEW_RELEASED;
944 assert(self->mbuf->exports > 0);
945 if (--self->mbuf->exports == 0)
946 mbuf_release(self->mbuf);
947 return 0;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000948 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100949 if (self->exports > 0) {
950 PyErr_Format(PyExc_BufferError,
951 "memoryview has %zd exported buffer%s", self->exports,
952 self->exports==1 ? "" : "s");
953 return -1;
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000954 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +0000955
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100956 Py_FatalError("_memory_release(): negative export count");
957 return -1;
958}
959
960static PyObject *
961memory_release(PyMemoryViewObject *self)
962{
963 if (_memory_release(self) < 0)
964 return NULL;
965 Py_RETURN_NONE;
966}
967
968static void
969memory_dealloc(PyMemoryViewObject *self)
970{
971 assert(self->exports == 0);
972 _PyObject_GC_UNTRACK(self);
973 (void)_memory_release(self);
974 Py_CLEAR(self->mbuf);
975 PyObject_GC_Del(self);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000976}
977
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000978static int
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100979memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +0000980{
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100981 Py_VISIT(self->mbuf);
982 return 0;
983}
Guido van Rossum5dde61d2007-09-25 22:10:05 +0000984
Stefan Krah9a2d99e2012-02-25 12:24:21 +0100985static int
986memory_clear(PyMemoryViewObject *self)
987{
988 (void)_memory_release(self);
989 Py_CLEAR(self->mbuf);
990 return 0;
991}
992
993static PyObject *
994memory_enter(PyObject *self, PyObject *args)
995{
996 CHECK_RELEASED(self);
997 Py_INCREF(self);
998 return self;
999}
1000
1001static PyObject *
1002memory_exit(PyObject *self, PyObject *args)
1003{
1004 return memory_release((PyMemoryViewObject *)self);
1005}
1006
1007
1008/****************************************************************************/
1009/* Casting format and shape */
1010/****************************************************************************/
1011
1012#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
1013
1014Py_LOCAL_INLINE(Py_ssize_t)
1015get_native_fmtchar(char *result, const char *fmt)
1016{
1017 Py_ssize_t size = -1;
1018
1019 if (fmt[0] == '@') fmt++;
1020
1021 switch (fmt[0]) {
1022 case 'c': case 'b': case 'B': size = sizeof(char); break;
1023 case 'h': case 'H': size = sizeof(short); break;
1024 case 'i': case 'I': size = sizeof(int); break;
1025 case 'l': case 'L': size = sizeof(long); break;
1026 #ifdef HAVE_LONG_LONG
1027 case 'q': case 'Q': size = sizeof(PY_LONG_LONG); break;
1028 #endif
1029 case 'n': case 'N': size = sizeof(Py_ssize_t); break;
1030 case 'f': size = sizeof(float); break;
1031 case 'd': size = sizeof(double); break;
1032 #ifdef HAVE_C99_BOOL
1033 case '?': size = sizeof(_Bool); break;
1034 #else
1035 case '?': size = sizeof(char); break;
1036 #endif
1037 case 'P': size = sizeof(void *); break;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001038 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001039
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001040 if (size > 0 && fmt[1] == '\0') {
1041 *result = fmt[0];
1042 return size;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001043 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001044
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001045 return -1;
1046}
1047
1048/* Cast a memoryview's data type to 'format'. The input array must be
1049 C-contiguous. At least one of input-format, output-format must have
1050 byte size. The output array is 1-D, with the same byte length as the
1051 input array. Thus, view->len must be a multiple of the new itemsize. */
1052static int
1053cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1054{
1055 Py_buffer *view = &mv->view;
1056 PyObject *asciifmt;
1057 char srcchar, destchar;
1058 Py_ssize_t itemsize;
1059 int ret = -1;
1060
1061 assert(view->ndim >= 1);
1062 assert(Py_SIZE(mv) == 3*view->ndim);
1063 assert(view->shape == mv->ob_array);
1064 assert(view->strides == mv->ob_array + view->ndim);
1065 assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1066
1067 if (get_native_fmtchar(&srcchar, view->format) < 0) {
1068 PyErr_SetString(PyExc_ValueError,
1069 "memoryview: source format must be a native single character "
1070 "format prefixed with an optional '@'");
1071 return ret;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001072 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001073
1074 asciifmt = PyUnicode_AsASCIIString(format);
1075 if (asciifmt == NULL)
1076 return ret;
1077
1078 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1079 if (itemsize < 0) {
1080 PyErr_SetString(PyExc_ValueError,
1081 "memoryview: destination format must be a native single "
1082 "character format prefixed with an optional '@'");
1083 goto out;
1084 }
1085
1086 if (!IS_BYTE_FORMAT(srcchar) && !IS_BYTE_FORMAT(destchar)) {
1087 PyErr_SetString(PyExc_TypeError,
1088 "memoryview: cannot cast between two non-byte formats");
1089 goto out;
1090 }
1091 if (view->len % itemsize) {
1092 PyErr_SetString(PyExc_TypeError,
1093 "memoryview: length is not a multiple of itemsize");
1094 goto out;
1095 }
1096
1097 strncpy(mv->format, PyBytes_AS_STRING(asciifmt),
1098 _Py_MEMORYVIEW_MAX_FORMAT);
1099 mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0';
1100 view->format = mv->format;
1101 view->itemsize = itemsize;
1102
1103 view->ndim = 1;
1104 view->shape[0] = view->len / view->itemsize;
1105 view->strides[0] = view->itemsize;
1106 view->suboffsets = NULL;
1107
1108 init_flags(mv);
1109
1110 ret = 0;
1111
1112out:
1113 Py_DECREF(asciifmt);
1114 return ret;
1115}
1116
1117/* The memoryview must have space for 3*len(seq) elements. */
1118static Py_ssize_t
1119copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1120 Py_ssize_t itemsize)
1121{
1122 Py_ssize_t x, i;
1123 Py_ssize_t len = itemsize;
1124
1125 for (i = 0; i < ndim; i++) {
1126 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1127 if (!PyLong_Check(tmp)) {
1128 PyErr_SetString(PyExc_TypeError,
1129 "memoryview.cast(): elements of shape must be integers");
1130 return -1;
1131 }
1132 x = PyLong_AsSsize_t(tmp);
1133 if (x == -1 && PyErr_Occurred()) {
1134 return -1;
1135 }
1136 if (x <= 0) {
1137 /* In general elements of shape may be 0, but not for casting. */
1138 PyErr_Format(PyExc_ValueError,
1139 "memoryview.cast(): elements of shape must be integers > 0");
1140 return -1;
1141 }
1142 if (x > PY_SSIZE_T_MAX / len) {
1143 PyErr_Format(PyExc_ValueError,
1144 "memoryview.cast(): product(shape) > SSIZE_MAX");
1145 return -1;
1146 }
1147 len *= x;
1148 shape[i] = x;
1149 }
1150
1151 return len;
1152}
1153
1154/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1155 If the result array does not have exactly the same byte length as the
1156 input array, raise ValueError. */
1157static int
1158cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1159{
1160 Py_buffer *view = &mv->view;
1161 Py_ssize_t len;
1162
1163 assert(view->ndim == 1); /* ndim from cast_to_1D() */
1164 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1165 assert(view->shape == mv->ob_array);
1166 assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1167 assert(view->suboffsets == NULL);
1168
1169 view->ndim = ndim;
1170 if (view->ndim == 0) {
1171 view->shape = NULL;
1172 view->strides = NULL;
1173 len = view->itemsize;
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001174 }
1175 else {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001176 len = copy_shape(view->shape, shape, ndim, view->itemsize);
1177 if (len < 0)
1178 return -1;
1179 init_strides_from_shape(view);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001180 }
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001181
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001182 if (view->len != len) {
1183 PyErr_SetString(PyExc_TypeError,
1184 "memoryview: product(shape) * itemsize != buffer size");
1185 return -1;
1186 }
1187
1188 init_flags(mv);
1189
1190 return 0;
1191}
1192
1193static int
1194zero_in_shape(PyMemoryViewObject *mv)
1195{
1196 Py_buffer *view = &mv->view;
1197 Py_ssize_t i;
1198
1199 for (i = 0; i < view->ndim; i++)
1200 if (view->shape[i] == 0)
1201 return 1;
1202
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001203 return 0;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001204}
1205
Guido van Rossum5dde61d2007-09-25 22:10:05 +00001206/*
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001207 Cast a copy of 'self' to a different view. The input view must
1208 be C-contiguous. The function always casts the input view to a
1209 1-D output according to 'format'. At least one of input-format,
1210 output-format must have byte size.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001211
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001212 If 'shape' is given, the 1-D view from the previous step will
1213 be cast to a C-contiguous view with new shape and strides.
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001214
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001215 All casts must result in views that will have the exact byte
1216 size of the original input. Otherwise, an error is raised.
1217*/
1218static PyObject *
1219memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001220{
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001221 static char *kwlist[] = {"format", "shape", NULL};
1222 PyMemoryViewObject *mv = NULL;
1223 PyObject *shape = NULL;
1224 PyObject *format;
1225 Py_ssize_t ndim = 1;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001226
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001227 CHECK_RELEASED(self);
1228
1229 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
1230 &format, &shape)) {
1231 return NULL;
1232 }
1233 if (!PyUnicode_Check(format)) {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001234 PyErr_SetString(PyExc_TypeError,
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001235 "memoryview: format argument must be a string");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001236 return NULL;
1237 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001238 if (!MV_C_CONTIGUOUS(self->flags)) {
1239 PyErr_SetString(PyExc_TypeError,
1240 "memoryview: casts are restricted to C-contiguous views");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001241 return NULL;
1242 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001243 if (zero_in_shape(self)) {
1244 PyErr_SetString(PyExc_TypeError,
1245 "memoryview: cannot cast view with zeros in shape or strides");
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001246 return NULL;
1247 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001248 if (shape) {
1249 CHECK_LIST_OR_TUPLE(shape)
1250 ndim = PySequence_Fast_GET_SIZE(shape);
1251 if (ndim > PyBUF_MAX_NDIM) {
1252 PyErr_SetString(PyExc_ValueError,
1253 "memoryview: number of dimensions must not exceed "
1254 STRINGIZE(PyBUF_MAX_NDIM));
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001255 return NULL;
1256 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001257 if (self->view.ndim != 1 && ndim != 1) {
1258 PyErr_SetString(PyExc_TypeError,
1259 "memoryview: cast must be 1D -> ND or ND -> 1D");
1260 return NULL;
1261 }
Antoine Pitrou35b7e832009-01-03 19:20:36 +00001262 }
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001263
1264 mv = (PyMemoryViewObject *)
1265 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1266 if (mv == NULL)
1267 return NULL;
1268
1269 if (cast_to_1D(mv, format) < 0)
1270 goto error;
1271 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1272 goto error;
1273
1274 return (PyObject *)mv;
1275
1276error:
1277 Py_DECREF(mv);
1278 return NULL;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001279}
1280
1281
Stefan Krah9a2d99e2012-02-25 12:24:21 +01001282/**************************************************************************/
1283/* getbuffer */
1284/**************************************************************************/
1285
1286static int
1287memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1288{
1289 Py_buffer *base = &self->view;
1290 int baseflags = self->flags;
1291
1292 CHECK_RELEASED_INT(self);
1293
1294 /* start with complete information */
1295 *view = *base;
1296 view->obj = NULL;
1297
1298 if (REQ_WRITABLE(flags) && base->readonly) {
1299 PyErr_SetString(PyExc_BufferError,
1300 "memoryview: underlying buffer is not writable");
1301 return -1;
1302 }
1303 if (!REQ_FORMAT(flags)) {
1304 /* NULL indicates that the buffer's data type has been cast to 'B'.
1305 view->itemsize is the _previous_ itemsize. If shape is present,
1306 the equality product(shape) * itemsize = len still holds at this
1307 point. The equality calcsize(format) = itemsize does _not_ hold
1308 from here on! */
1309 view->format = NULL;
1310 }
1311
1312 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1313 PyErr_SetString(PyExc_BufferError,
1314 "memoryview: underlying buffer is not C-contiguous");
1315 return -1;
1316 }
1317 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1318 PyErr_SetString(PyExc_BufferError,
1319 "memoryview: underlying buffer is not Fortran contiguous");
1320 return -1;
1321 }
1322 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1323 PyErr_SetString(PyExc_BufferError,
1324 "memoryview: underlying buffer is not contiguous");
1325 return -1;
1326 }
1327 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1328 PyErr_SetString(PyExc_BufferError,
1329 "memoryview: underlying buffer requires suboffsets");
1330 return -1;
1331 }
1332 if (!REQ_STRIDES(flags)) {
1333 if (!MV_C_CONTIGUOUS(baseflags)) {
1334 PyErr_SetString(PyExc_BufferError,
1335 "memoryview: underlying buffer is not C-contiguous");
1336 return -1;
1337 }
1338 view->strides = NULL;
1339 }
1340 if (!REQ_SHAPE(flags)) {
1341 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1342 so base->buf = ndbuf->data. */
1343 if (view->format != NULL) {
1344 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1345 not make sense. */
1346 PyErr_Format(PyExc_BufferError,
1347 "ndarray: cannot cast to unsigned bytes if the format flag "
1348 "is present");
1349 return -1;
1350 }
1351 /* product(shape) * itemsize = len and calcsize(format) = itemsize
1352 do _not_ hold from here on! */
1353 view->ndim = 1;
1354 view->shape = NULL;
1355 }
1356
1357
1358 view->obj = (PyObject *)self;
1359 Py_INCREF(view->obj);
1360 self->exports++;
1361
1362 return 0;
1363}
1364
1365static void
1366memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1367{
1368 self->exports--;
1369 return;
1370 /* PyBuffer_Release() decrements view->obj after this function returns. */
1371}
1372
1373/* Buffer methods */
1374static PyBufferProcs memory_as_buffer = {
1375 (getbufferproc)memory_getbuf, /* bf_getbuffer */
1376 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1377};
1378
1379
1380/****************************************************************************/
1381/* Optimized pack/unpack for all native format specifiers */
1382/****************************************************************************/
1383
1384/*
1385 Fix exceptions:
1386 1) Include format string in the error message.
1387 2) OverflowError -> ValueError.
1388 3) The error message from PyNumber_Index() is not ideal.
1389*/
1390static int
1391type_error_int(const char *fmt)
1392{
1393 PyErr_Format(PyExc_TypeError,
1394 "memoryview: invalid type for format '%s'", fmt);
1395 return -1;
1396}
1397
1398static int
1399value_error_int(const char *fmt)
1400{
1401 PyErr_Format(PyExc_ValueError,
1402 "memoryview: invalid value for format '%s'", fmt);
1403 return -1;
1404}
1405
1406static int
1407fix_error_int(const char *fmt)
1408{
1409 assert(PyErr_Occurred());
1410 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1411 PyErr_Clear();
1412 return type_error_int(fmt);
1413 }
1414 else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1415 PyErr_ExceptionMatches(PyExc_ValueError)) {
1416 PyErr_Clear();
1417 return value_error_int(fmt);
1418 }
1419
1420 return -1;
1421}
1422
1423/* Accept integer objects or objects with an __index__() method. */
1424static long
1425pylong_as_ld(PyObject *item)
1426{
1427 PyObject *tmp;
1428 long ld;
1429
1430 tmp = PyNumber_Index(item);
1431 if (tmp == NULL)
1432 return -1;
1433
1434 ld = PyLong_AsLong(tmp);
1435 Py_DECREF(tmp);
1436 return ld;
1437}
1438
1439static unsigned long
1440pylong_as_lu(PyObject *item)
1441{
1442 PyObject *tmp;
1443 unsigned long lu;
1444
1445 tmp = PyNumber_Index(item);
1446 if (tmp == NULL)
1447 return (unsigned long)-1;
1448
1449 lu = PyLong_AsUnsignedLong(tmp);
1450 Py_DECREF(tmp);
1451 return lu;
1452}
1453
1454#ifdef HAVE_LONG_LONG
1455static PY_LONG_LONG
1456pylong_as_lld(PyObject *item)
1457{
1458 PyObject *tmp;
1459 PY_LONG_LONG lld;
1460
1461 tmp = PyNumber_Index(item);
1462 if (tmp == NULL)
1463 return -1;
1464
1465 lld = PyLong_AsLongLong(tmp);
1466 Py_DECREF(tmp);
1467 return lld;
1468}
1469
1470static unsigned PY_LONG_LONG
1471pylong_as_llu(PyObject *item)
1472{
1473 PyObject *tmp;
1474 unsigned PY_LONG_LONG llu;
1475
1476 tmp = PyNumber_Index(item);
1477 if (tmp == NULL)
1478 return (unsigned PY_LONG_LONG)-1;
1479
1480 llu = PyLong_AsUnsignedLongLong(tmp);
1481 Py_DECREF(tmp);
1482 return llu;
1483}
1484#endif
1485
1486static Py_ssize_t
1487pylong_as_zd(PyObject *item)
1488{
1489 PyObject *tmp;
1490 Py_ssize_t zd;
1491
1492 tmp = PyNumber_Index(item);
1493 if (tmp == NULL)
1494 return -1;
1495
1496 zd = PyLong_AsSsize_t(tmp);
1497 Py_DECREF(tmp);
1498 return zd;
1499}
1500
1501static size_t
1502pylong_as_zu(PyObject *item)
1503{
1504 PyObject *tmp;
1505 size_t zu;
1506
1507 tmp = PyNumber_Index(item);
1508 if (tmp == NULL)
1509 return (size_t)-1;
1510
1511 zu = PyLong_AsSize_t(tmp);
1512 Py_DECREF(tmp);
1513 return zu;
1514}
1515
1516/* Timings with the ndarray from _testbuffer.c indicate that using the
1517 struct module is around 15x slower than the two functions below. */
1518
1519#define UNPACK_SINGLE(dest, ptr, type) \
1520 do { \
1521 type x; \
1522 memcpy((char *)&x, ptr, sizeof x); \
1523 dest = x; \
1524 } while (0)
1525
1526/* Unpack a single item. 'fmt' can be any native format character in struct
1527 module syntax. This function is very sensitive to small changes. With this
1528 layout gcc automatically generates a fast jump table. */
1529Py_LOCAL_INLINE(PyObject *)
1530unpack_single(const char *ptr, const char *fmt)
1531{
1532 unsigned PY_LONG_LONG llu;
1533 unsigned long lu;
1534 size_t zu;
1535 PY_LONG_LONG lld;
1536 long ld;
1537 Py_ssize_t zd;
1538 double d;
1539 unsigned char uc;
1540 void *p;
1541
1542 switch (fmt[0]) {
1543
1544 /* signed integers and fast path for 'B' */
1545 case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
1546 case 'b': ld = *((signed char *)ptr); goto convert_ld;
1547 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1548 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1549 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1550
1551 /* boolean */
1552 #ifdef HAVE_C99_BOOL
1553 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
1554 #else
1555 case '?': UNPACK_SINGLE(ld, ptr, char); goto convert_bool;
1556 #endif
1557
1558 /* unsigned integers */
1559 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1560 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1561 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1562
1563 /* native 64-bit */
1564 #ifdef HAVE_LONG_LONG
1565 case 'q': UNPACK_SINGLE(lld, ptr, PY_LONG_LONG); goto convert_lld;
1566 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned PY_LONG_LONG); goto convert_llu;
1567 #endif
1568
1569 /* ssize_t and size_t */
1570 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1571 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1572
1573 /* floats */
1574 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1575 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1576
1577 /* bytes object */
1578 case 'c': goto convert_bytes;
1579
1580 /* pointer */
1581 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1582
1583 /* default */
1584 default: goto err_format;
1585 }
1586
1587convert_uc:
1588 /* PyLong_FromUnsignedLong() is slower */
1589 return PyLong_FromLong(uc);
1590convert_ld:
1591 return PyLong_FromLong(ld);
1592convert_lu:
1593 return PyLong_FromUnsignedLong(lu);
1594convert_lld:
1595 return PyLong_FromLongLong(lld);
1596convert_llu:
1597 return PyLong_FromUnsignedLongLong(llu);
1598convert_zd:
1599 return PyLong_FromSsize_t(zd);
1600convert_zu:
1601 return PyLong_FromSize_t(zu);
1602convert_double:
1603 return PyFloat_FromDouble(d);
1604convert_bool:
1605 return PyBool_FromLong(ld);
1606convert_bytes:
1607 return PyBytes_FromStringAndSize(ptr, 1);
1608convert_pointer:
1609 return PyLong_FromVoidPtr(p);
1610err_format:
1611 PyErr_Format(PyExc_NotImplementedError,
1612 "memoryview: format %s not supported", fmt);
1613 return NULL;
1614}
1615
1616#define PACK_SINGLE(ptr, src, type) \
1617 do { \
1618 type x; \
1619 x = (type)src; \
1620 memcpy(ptr, (char *)&x, sizeof x); \
1621 } while (0)
1622
1623/* Pack a single item. 'fmt' can be any native format character in
1624 struct module syntax. */
1625static int
1626pack_single(char *ptr, PyObject *item, const char *fmt)
1627{
1628 unsigned PY_LONG_LONG llu;
1629 unsigned long lu;
1630 size_t zu;
1631 PY_LONG_LONG lld;
1632 long ld;
1633 Py_ssize_t zd;
1634 double d;
1635 void *p;
1636
1637 switch (fmt[0]) {
1638 /* signed integers */
1639 case 'b': case 'h': case 'i': case 'l':
1640 ld = pylong_as_ld(item);
1641 if (ld == -1 && PyErr_Occurred())
1642 goto err_occurred;
1643 switch (fmt[0]) {
1644 case 'b':
1645 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1646 *((signed char *)ptr) = (signed char)ld; break;
1647 case 'h':
1648 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1649 PACK_SINGLE(ptr, ld, short); break;
1650 case 'i':
1651 if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1652 PACK_SINGLE(ptr, ld, int); break;
1653 default: /* 'l' */
1654 PACK_SINGLE(ptr, ld, long); break;
1655 }
1656 break;
1657
1658 /* unsigned integers */
1659 case 'B': case 'H': case 'I': case 'L':
1660 lu = pylong_as_lu(item);
1661 if (lu == (unsigned long)-1 && PyErr_Occurred())
1662 goto err_occurred;
1663 switch (fmt[0]) {
1664 case 'B':
1665 if (lu > UCHAR_MAX) goto err_range;
1666 *((unsigned char *)ptr) = (unsigned char)lu; break;
1667 case 'H':
1668 if (lu > USHRT_MAX) goto err_range;
1669 PACK_SINGLE(ptr, lu, unsigned short); break;
1670 case 'I':
1671 if (lu > UINT_MAX) goto err_range;
1672 PACK_SINGLE(ptr, lu, unsigned int); break;
1673 default: /* 'L' */
1674 PACK_SINGLE(ptr, lu, unsigned long); break;
1675 }
1676 break;
1677
1678 /* native 64-bit */
1679 #ifdef HAVE_LONG_LONG
1680 case 'q':
1681 lld = pylong_as_lld(item);
1682 if (lld == -1 && PyErr_Occurred())
1683 goto err_occurred;
1684 PACK_SINGLE(ptr, lld, PY_LONG_LONG);
1685 break;
1686 case 'Q':
1687 llu = pylong_as_llu(item);
1688 if (llu == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
1689 goto err_occurred;
1690 PACK_SINGLE(ptr, llu, unsigned PY_LONG_LONG);
1691 break;
1692 #endif
1693
1694 /* ssize_t and size_t */
1695 case 'n':
1696 zd = pylong_as_zd(item);
1697 if (zd == -1 && PyErr_Occurred())
1698 goto err_occurred;
1699 PACK_SINGLE(ptr, zd, Py_ssize_t);
1700 break;
1701 case 'N':
1702 zu = pylong_as_zu(item);
1703 if (zu == (size_t)-1 && PyErr_Occurred())
1704 goto err_occurred;
1705 PACK_SINGLE(ptr, zu, size_t);
1706 break;
1707
1708 /* floats */
1709 case 'f': case 'd':
1710 d = PyFloat_AsDouble(item);
1711 if (d == -1.0 && PyErr_Occurred())
1712 goto err_occurred;
1713 if (fmt[0] == 'f') {
1714 PACK_SINGLE(ptr, d, float);
1715 }
1716 else {
1717 PACK_SINGLE(ptr, d, double);
1718 }
1719 break;
1720
1721 /* bool */
1722 case '?':
1723 ld = PyObject_IsTrue(item);
1724 if (ld < 0)
1725 return -1; /* preserve original error */
1726 #ifdef HAVE_C99_BOOL
1727 PACK_SINGLE(ptr, ld, _Bool);
1728 #else
1729 PACK_SINGLE(ptr, ld, char);
1730 #endif
1731 break;
1732
1733 /* bytes object */
1734 case 'c':
1735 if (!PyBytes_Check(item))
1736 return type_error_int(fmt);
1737 if (PyBytes_GET_SIZE(item) != 1)
1738 return value_error_int(fmt);
1739 *ptr = PyBytes_AS_STRING(item)[0];
1740 break;
1741
1742 /* pointer */
1743 case 'P':
1744 p = PyLong_AsVoidPtr(item);
1745 if (p == NULL && PyErr_Occurred())
1746 goto err_occurred;
1747 PACK_SINGLE(ptr, p, void *);
1748 break;
1749
1750 /* default */
1751 default: goto err_format;
1752 }
1753
1754 return 0;
1755
1756err_occurred:
1757 return fix_error_int(fmt);
1758err_range:
1759 return value_error_int(fmt);
1760err_format:
1761 PyErr_Format(PyExc_NotImplementedError,
1762 "memoryview: format %s not supported", fmt);
1763 return -1;
1764}
1765
1766
1767/****************************************************************************/
1768/* Representations */
1769/****************************************************************************/
1770
1771/* allow explicit form of native format */
1772Py_LOCAL_INLINE(const char *)
1773adjust_fmt(const Py_buffer *view)
1774{
1775 const char *fmt;
1776
1777 fmt = (view->format[0] == '@') ? view->format+1 : view->format;
1778 if (fmt[0] && fmt[1] == '\0')
1779 return fmt;
1780
1781 PyErr_Format(PyExc_NotImplementedError,
1782 "memoryview: unsupported format %s", view->format);
1783 return NULL;
1784}
1785
1786/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
1787static PyObject *
1788tolist_base(const char *ptr, const Py_ssize_t *shape,
1789 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
1790 const char *fmt)
1791{
1792 PyObject *lst, *item;
1793 Py_ssize_t i;
1794
1795 lst = PyList_New(shape[0]);
1796 if (lst == NULL)
1797 return NULL;
1798
1799 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
1800 const char *xptr = ADJUST_PTR(ptr, suboffsets);
1801 item = unpack_single(xptr, fmt);
1802 if (item == NULL) {
1803 Py_DECREF(lst);
1804 return NULL;
1805 }
1806 PyList_SET_ITEM(lst, i, item);
1807 }
1808
1809 return lst;
1810}
1811
1812/* Unpack a multi-dimensional array into a nested list.
1813 Assumption: ndim >= 1. */
1814static PyObject *
1815tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
1816 const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
1817 const char *fmt)
1818{
1819 PyObject *lst, *item;
1820 Py_ssize_t i;
1821
1822 assert(ndim >= 1);
1823 assert(shape != NULL);
1824 assert(strides != NULL);
1825
1826 if (ndim == 1)
1827 return tolist_base(ptr, shape, strides, suboffsets, fmt);
1828
1829 lst = PyList_New(shape[0]);
1830 if (lst == NULL)
1831 return NULL;
1832
1833 for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
1834 const char *xptr = ADJUST_PTR(ptr, suboffsets);
1835 item = tolist_rec(xptr, ndim-1, shape+1,
1836 strides+1, suboffsets ? suboffsets+1 : NULL,
1837 fmt);
1838 if (item == NULL) {
1839 Py_DECREF(lst);
1840 return NULL;
1841 }
1842 PyList_SET_ITEM(lst, i, item);
1843 }
1844
1845 return lst;
1846}
1847
1848/* Return a list representation of the memoryview. Currently only buffers
1849 with native format strings are supported. */
1850static PyObject *
1851memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
1852{
1853 const Py_buffer *view = &(mv->view);
1854 const char *fmt;
1855
1856 CHECK_RELEASED(mv);
1857
1858 fmt = adjust_fmt(view);
1859 if (fmt == NULL)
1860 return NULL;
1861 if (view->ndim == 0) {
1862 return unpack_single(view->buf, fmt);
1863 }
1864 else if (view->ndim == 1) {
1865 return tolist_base(view->buf, view->shape,
1866 view->strides, view->suboffsets,
1867 fmt);
1868 }
1869 else {
1870 return tolist_rec(view->buf, view->ndim, view->shape,
1871 view->strides, view->suboffsets,
1872 fmt);
1873 }
1874}
1875
1876static PyObject *
1877memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
1878{
1879 Py_buffer *src = VIEW_ADDR(self);
1880 PyObject *bytes = NULL;
1881
1882 CHECK_RELEASED(self);
1883
1884 if (MV_C_CONTIGUOUS(self->flags)) {
1885 return PyBytes_FromStringAndSize(src->buf, src->len);
1886 }
1887
1888 bytes = PyBytes_FromStringAndSize(NULL, src->len);
1889 if (bytes == NULL)
1890 return NULL;
1891
1892 if (buffer_to_c_contiguous(PyBytes_AS_STRING(bytes), src) < 0) {
1893 Py_DECREF(bytes);
1894 return NULL;
1895 }
1896
1897 return bytes;
1898}
1899
1900static PyObject *
1901memory_repr(PyMemoryViewObject *self)
1902{
1903 if (self->flags & _Py_MEMORYVIEW_RELEASED)
1904 return PyUnicode_FromFormat("<released memory at %p>", self);
1905 else
1906 return PyUnicode_FromFormat("<memory at %p>", self);
1907}
1908
1909
1910/**************************************************************************/
1911/* Indexing and slicing */
1912/**************************************************************************/
1913
1914/* Get the pointer to the item at index. */
1915static char *
1916ptr_from_index(Py_buffer *view, Py_ssize_t index)
1917{
1918 char *ptr;
1919 Py_ssize_t nitems; /* items in the first dimension */
1920
1921 assert(view->shape);
1922 assert(view->strides);
1923
1924 nitems = view->shape[0];
1925 if (index < 0) {
1926 index += nitems;
1927 }
1928 if (index < 0 || index >= nitems) {
1929 PyErr_SetString(PyExc_IndexError, "index out of bounds");
1930 return NULL;
1931 }
1932
1933 ptr = (char *)view->buf;
1934 ptr += view->strides[0] * index;
1935
1936 ptr = ADJUST_PTR(ptr, view->suboffsets);
1937
1938 return ptr;
1939}
1940
1941/* Return the item at index. In a one-dimensional view, this is an object
1942 with the type specified by view->format. Otherwise, the item is a sub-view.
1943 The function is used in memory_subscript() and memory_as_sequence. */
1944static PyObject *
1945memory_item(PyMemoryViewObject *self, Py_ssize_t index)
1946{
1947 Py_buffer *view = &(self->view);
1948 const char *fmt;
1949
1950 CHECK_RELEASED(self);
1951
1952 fmt = adjust_fmt(view);
1953 if (fmt == NULL)
1954 return NULL;
1955
1956 if (view->ndim == 0) {
1957 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
1958 return NULL;
1959 }
1960 if (view->ndim == 1) {
1961 char *ptr = ptr_from_index(view, index);
1962 if (ptr == NULL)
1963 return NULL;
1964 return unpack_single(ptr, fmt);
1965 }
1966
1967 PyErr_SetString(PyExc_NotImplementedError,
1968 "multi-dimensional sub-views are not implemented");
1969 return NULL;
1970}
1971
1972Py_LOCAL_INLINE(int)
1973init_slice(Py_buffer *base, PyObject *key, int dim)
1974{
1975 Py_ssize_t start, stop, step, slicelength;
1976
1977 if (PySlice_GetIndicesEx(key, base->shape[dim],
1978 &start, &stop, &step, &slicelength) < 0) {
1979 return -1;
1980 }
1981
1982
1983 if (base->suboffsets == NULL || dim == 0) {
1984 adjust_buf:
1985 base->buf = (char *)base->buf + base->strides[dim] * start;
1986 }
1987 else {
1988 Py_ssize_t n = dim-1;
1989 while (n >= 0 && base->suboffsets[n] < 0)
1990 n--;
1991 if (n < 0)
1992 goto adjust_buf; /* all suboffsets are negative */
1993 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
1994 }
1995 base->shape[dim] = slicelength;
1996 base->strides[dim] = base->strides[dim] * step;
1997
1998 return 0;
1999}
2000
2001static int
2002is_multislice(PyObject *key)
2003{
2004 Py_ssize_t size, i;
2005
2006 if (!PyTuple_Check(key))
2007 return 0;
2008 size = PyTuple_GET_SIZE(key);
2009 if (size == 0)
2010 return 0;
2011
2012 for (i = 0; i < size; i++) {
2013 PyObject *x = PyTuple_GET_ITEM(key, i);
2014 if (!PySlice_Check(x))
2015 return 0;
2016 }
2017 return 1;
2018}
2019
2020/* mv[obj] returns an object holding the data for one element if obj
2021 fully indexes the memoryview or another memoryview object if it
2022 does not.
2023
2024 0-d memoryview objects can be referenced using mv[...] or mv[()]
2025 but not with anything else. */
2026static PyObject *
2027memory_subscript(PyMemoryViewObject *self, PyObject *key)
2028{
2029 Py_buffer *view;
2030 view = &(self->view);
2031
2032 CHECK_RELEASED(self);
2033
2034 if (view->ndim == 0) {
2035 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2036 const char *fmt = adjust_fmt(view);
2037 if (fmt == NULL)
2038 return NULL;
2039 return unpack_single(view->buf, fmt);
2040 }
2041 else if (key == Py_Ellipsis) {
2042 Py_INCREF(self);
2043 return (PyObject *)self;
2044 }
2045 else {
2046 PyErr_SetString(PyExc_TypeError,
2047 "invalid indexing of 0-dim memory");
2048 return NULL;
2049 }
2050 }
2051
2052 if (PyIndex_Check(key)) {
2053 Py_ssize_t index;
2054 index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2055 if (index == -1 && PyErr_Occurred())
2056 return NULL;
2057 return memory_item(self, index);
2058 }
2059 else if (PySlice_Check(key)) {
2060 PyMemoryViewObject *sliced;
2061
2062 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2063 if (sliced == NULL)
2064 return NULL;
2065
2066 if (init_slice(&sliced->view, key, 0) < 0) {
2067 Py_DECREF(sliced);
2068 return NULL;
2069 }
2070 init_len(&sliced->view);
2071 init_flags(sliced);
2072
2073 return (PyObject *)sliced;
2074 }
2075 else if (is_multislice(key)) {
2076 PyErr_SetString(PyExc_NotImplementedError,
2077 "multi-dimensional slicing is not implemented");
2078 return NULL;
2079 }
2080
2081 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2082 return NULL;
2083}
2084
2085static int
2086memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2087{
2088 Py_buffer *view = &(self->view);
2089 Py_buffer src;
2090 const char *fmt;
2091 char *ptr;
2092
2093 CHECK_RELEASED_INT(self);
2094
2095 fmt = adjust_fmt(view);
2096 if (fmt == NULL)
2097 return -1;
2098
2099 if (view->readonly) {
2100 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2101 return -1;
2102 }
2103 if (value == NULL) {
2104 PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2105 return -1;
2106 }
2107 if (view->ndim == 0) {
2108 if (key == Py_Ellipsis ||
2109 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2110 ptr = (char *)view->buf;
2111 return pack_single(ptr, value, fmt);
2112 }
2113 else {
2114 PyErr_SetString(PyExc_TypeError,
2115 "invalid indexing of 0-dim memory");
2116 return -1;
2117 }
2118 }
2119 if (view->ndim != 1) {
2120 PyErr_SetString(PyExc_NotImplementedError,
2121 "memoryview assignments are currently restricted to ndim = 1");
2122 return -1;
2123 }
2124
2125 if (PyIndex_Check(key)) {
2126 Py_ssize_t index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2127 if (index == -1 && PyErr_Occurred())
2128 return -1;
2129 ptr = ptr_from_index(view, index);
2130 if (ptr == NULL)
2131 return -1;
2132 return pack_single(ptr, value, fmt);
2133 }
2134 /* one-dimensional: fast path */
2135 if (PySlice_Check(key) && view->ndim == 1) {
2136 Py_buffer dest; /* sliced view */
2137 Py_ssize_t arrays[3];
2138 int ret = -1;
2139
2140 /* rvalue must be an exporter */
2141 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2142 return ret;
2143
2144 dest = *view;
2145 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2146 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2147 if (view->suboffsets) {
2148 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2149 }
2150
2151 if (init_slice(&dest, key, 0) < 0)
2152 goto end_block;
2153 dest.len = dest.shape[0] * dest.itemsize;
2154
2155 ret = copy_single(&dest, &src);
2156
2157 end_block:
2158 PyBuffer_Release(&src);
2159 return ret;
2160 }
2161 else if (PySlice_Check(key) || is_multislice(key)) {
2162 /* Call memory_subscript() to produce a sliced lvalue, then copy
2163 rvalue into lvalue. This is already implemented in _testbuffer.c. */
2164 PyErr_SetString(PyExc_NotImplementedError,
2165 "memoryview slice assignments are currently restricted "
2166 "to ndim = 1");
2167 return -1;
2168 }
2169
2170 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2171 return -1;
2172}
2173
2174static Py_ssize_t
2175memory_length(PyMemoryViewObject *self)
2176{
2177 CHECK_RELEASED_INT(self);
2178 return self->view.ndim == 0 ? 1 : self->view.shape[0];
2179}
2180
2181/* As mapping */
2182static PyMappingMethods memory_as_mapping = {
2183 (lenfunc)memory_length, /* mp_length */
2184 (binaryfunc)memory_subscript, /* mp_subscript */
2185 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */
2186};
2187
2188/* As sequence */
2189static PySequenceMethods memory_as_sequence = {
2190 0, /* sq_length */
2191 0, /* sq_concat */
2192 0, /* sq_repeat */
2193 (ssizeargfunc)memory_item, /* sq_item */
2194};
2195
2196
2197/**************************************************************************/
2198/* Comparisons */
2199/**************************************************************************/
2200
2201#define CMP_SINGLE(p, q, type) \
2202 do { \
2203 type x; \
2204 type y; \
2205 memcpy((char *)&x, p, sizeof x); \
2206 memcpy((char *)&y, q, sizeof y); \
2207 equal = (x == y); \
2208 } while (0)
2209
2210Py_LOCAL_INLINE(int)
2211unpack_cmp(const char *p, const char *q, const char *fmt)
2212{
2213 int equal;
2214
2215 switch (fmt[0]) {
2216
2217 /* signed integers and fast path for 'B' */
2218 case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
2219 case 'b': return *((signed char *)p) == *((signed char *)q);
2220 case 'h': CMP_SINGLE(p, q, short); return equal;
2221 case 'i': CMP_SINGLE(p, q, int); return equal;
2222 case 'l': CMP_SINGLE(p, q, long); return equal;
2223
2224 /* boolean */
2225 #ifdef HAVE_C99_BOOL
2226 case '?': CMP_SINGLE(p, q, _Bool); return equal;
2227 #else
2228 case '?': CMP_SINGLE(p, q, char); return equal;
2229 #endif
2230
2231 /* unsigned integers */
2232 case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2233 case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2234 case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2235
2236 /* native 64-bit */
2237 #ifdef HAVE_LONG_LONG
2238 case 'q': CMP_SINGLE(p, q, PY_LONG_LONG); return equal;
2239 case 'Q': CMP_SINGLE(p, q, unsigned PY_LONG_LONG); return equal;
2240 #endif
2241
2242 /* ssize_t and size_t */
2243 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2244 case 'N': CMP_SINGLE(p, q, size_t); return equal;
2245
2246 /* floats */
2247 /* XXX DBL_EPSILON? */
2248 case 'f': CMP_SINGLE(p, q, float); return equal;
2249 case 'd': CMP_SINGLE(p, q, double); return equal;
2250
2251 /* bytes object */
2252 case 'c': return *p == *q;
2253
2254 /* pointer */
2255 case 'P': CMP_SINGLE(p, q, void *); return equal;
2256
2257 /* Py_NotImplemented */
2258 default: return -1;
2259 }
2260}
2261
2262/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2263static int
2264cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2265 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2266 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
2267 const char *fmt)
2268{
2269 Py_ssize_t i;
2270 int equal;
2271
2272 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2273 const char *xp = ADJUST_PTR(p, psuboffsets);
2274 const char *xq = ADJUST_PTR(q, qsuboffsets);
2275 equal = unpack_cmp(xp, xq, fmt);
2276 if (equal <= 0)
2277 return equal;
2278 }
2279
2280 return 1;
2281}
2282
2283/* Recursively compare two multi-dimensional arrays that have the same
2284 logical structure. Assumption: ndim >= 1. */
2285static int
2286cmp_rec(const char *p, const char *q,
2287 Py_ssize_t ndim, const Py_ssize_t *shape,
2288 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2289 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
2290 const char *fmt)
2291{
2292 Py_ssize_t i;
2293 int equal;
2294
2295 assert(ndim >= 1);
2296 assert(shape != NULL);
2297 assert(pstrides != NULL);
2298 assert(qstrides != NULL);
2299
2300 if (ndim == 1) {
2301 return cmp_base(p, q, shape,
2302 pstrides, psuboffsets,
2303 qstrides, qsuboffsets,
2304 fmt);
2305 }
2306
2307 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2308 const char *xp = ADJUST_PTR(p, psuboffsets);
2309 const char *xq = ADJUST_PTR(q, qsuboffsets);
2310 equal = cmp_rec(xp, xq, ndim-1, shape+1,
2311 pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2312 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
2313 fmt);
2314 if (equal <= 0)
2315 return equal;
2316 }
2317
2318 return 1;
2319}
2320
2321static PyObject *
2322memory_richcompare(PyObject *v, PyObject *w, int op)
2323{
2324 PyObject *res;
2325 Py_buffer wbuf, *vv, *ww = NULL;
2326 const char *vfmt, *wfmt;
2327 int equal = -1; /* Py_NotImplemented */
2328
2329 if (op != Py_EQ && op != Py_NE)
2330 goto result; /* Py_NotImplemented */
2331
2332 assert(PyMemoryView_Check(v));
2333 if (BASE_INACCESSIBLE(v)) {
2334 equal = (v == w);
2335 goto result;
2336 }
2337 vv = VIEW_ADDR(v);
2338
2339 if (PyMemoryView_Check(w)) {
2340 if (BASE_INACCESSIBLE(w)) {
2341 equal = (v == w);
2342 goto result;
2343 }
2344 ww = VIEW_ADDR(w);
2345 }
2346 else {
2347 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2348 PyErr_Clear();
2349 goto result; /* Py_NotImplemented */
2350 }
2351 ww = &wbuf;
2352 }
2353
2354 vfmt = adjust_fmt(vv);
2355 wfmt = adjust_fmt(ww);
2356 if (vfmt == NULL || wfmt == NULL) {
2357 PyErr_Clear();
2358 goto result; /* Py_NotImplemented */
2359 }
2360
2361 if (cmp_structure(vv, ww) < 0) {
2362 PyErr_Clear();
2363 equal = 0;
2364 goto result;
2365 }
2366
2367 if (vv->ndim == 0) {
2368 equal = unpack_cmp(vv->buf, ww->buf, vfmt);
2369 }
2370 else if (vv->ndim == 1) {
2371 equal = cmp_base(vv->buf, ww->buf, vv->shape,
2372 vv->strides, vv->suboffsets,
2373 ww->strides, ww->suboffsets,
2374 vfmt);
2375 }
2376 else {
2377 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2378 vv->strides, vv->suboffsets,
2379 ww->strides, ww->suboffsets,
2380 vfmt);
2381 }
2382
2383result:
2384 if (equal < 0)
2385 res = Py_NotImplemented;
2386 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2387 res = Py_True;
2388 else
2389 res = Py_False;
2390
2391 if (ww == &wbuf)
2392 PyBuffer_Release(ww);
2393 Py_INCREF(res);
2394 return res;
2395}
2396
2397/**************************************************************************/
2398/* Hash */
2399/**************************************************************************/
2400
2401static Py_hash_t
2402memory_hash(PyMemoryViewObject *self)
2403{
2404 if (self->hash == -1) {
2405 Py_buffer *view = &self->view;
2406 char *mem = view->buf;
2407
2408 CHECK_RELEASED_INT(self);
2409
2410 if (!view->readonly) {
2411 PyErr_SetString(PyExc_ValueError,
2412 "cannot hash writable memoryview object");
2413 return -1;
2414 }
2415 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2416 /* Keep the original error message */
2417 return -1;
2418 }
2419
2420 if (!MV_C_CONTIGUOUS(self->flags)) {
2421 mem = PyMem_Malloc(view->len);
2422 if (mem == NULL) {
2423 PyErr_NoMemory();
2424 return -1;
2425 }
2426 if (buffer_to_c_contiguous(mem, view) < 0) {
2427 PyMem_Free(mem);
2428 return -1;
2429 }
2430 }
2431
2432 /* Can't fail */
2433 self->hash = _Py_HashBytes((unsigned char *)mem, view->len);
2434
2435 if (mem != view->buf)
2436 PyMem_Free(mem);
2437 }
2438
2439 return self->hash;
2440}
2441
2442
2443/**************************************************************************/
2444/* getters */
2445/**************************************************************************/
2446
2447static PyObject *
2448_IntTupleFromSsizet(int len, Py_ssize_t *vals)
2449{
2450 int i;
2451 PyObject *o;
2452 PyObject *intTuple;
2453
2454 if (vals == NULL)
2455 return PyTuple_New(0);
2456
2457 intTuple = PyTuple_New(len);
2458 if (!intTuple)
2459 return NULL;
2460 for (i=0; i<len; i++) {
2461 o = PyLong_FromSsize_t(vals[i]);
2462 if (!o) {
2463 Py_DECREF(intTuple);
2464 return NULL;
2465 }
2466 PyTuple_SET_ITEM(intTuple, i, o);
2467 }
2468 return intTuple;
2469}
2470
2471static PyObject *
2472memory_obj_get(PyMemoryViewObject *self)
2473{
2474 Py_buffer *view = &self->view;
2475
2476 CHECK_RELEASED(self);
2477 if (view->obj == NULL) {
2478 Py_RETURN_NONE;
2479 }
2480 Py_INCREF(view->obj);
2481 return view->obj;
2482}
2483
2484static PyObject *
2485memory_nbytes_get(PyMemoryViewObject *self)
2486{
2487 CHECK_RELEASED(self);
2488 return PyLong_FromSsize_t(self->view.len);
2489}
2490
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002491static PyObject *
2492memory_format_get(PyMemoryViewObject *self)
2493{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002494 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002495 return PyUnicode_FromString(self->view.format);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002496}
2497
2498static PyObject *
2499memory_itemsize_get(PyMemoryViewObject *self)
2500{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002501 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002502 return PyLong_FromSsize_t(self->view.itemsize);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002503}
2504
2505static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002506memory_shape_get(PyMemoryViewObject *self)
2507{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002508 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002509 return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002510}
2511
2512static PyObject *
2513memory_strides_get(PyMemoryViewObject *self)
2514{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002515 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002516 return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002517}
2518
2519static PyObject *
2520memory_suboffsets_get(PyMemoryViewObject *self)
2521{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002522 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002523 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002524}
2525
2526static PyObject *
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002527memory_readonly_get(PyMemoryViewObject *self)
2528{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002529 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002530 return PyBool_FromLong(self->view.readonly);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002531}
2532
2533static PyObject *
2534memory_ndim_get(PyMemoryViewObject *self)
2535{
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002536 CHECK_RELEASED(self);
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002537 return PyLong_FromLong(self->view.ndim);
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002538}
2539
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002540static PyObject *
2541memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2542{
2543 CHECK_RELEASED(self);
2544 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
2545}
2546
2547static PyObject *
2548memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2549{
2550 CHECK_RELEASED(self);
2551 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
2552}
2553
2554static PyObject *
2555memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
2556{
2557 CHECK_RELEASED(self);
2558 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
2559}
2560
2561static PyGetSetDef memory_getsetlist[] = {
2562 {"obj", (getter)memory_obj_get, NULL, NULL},
2563 {"nbytes", (getter)memory_nbytes_get, NULL, NULL},
2564 {"readonly", (getter)memory_readonly_get, NULL, NULL},
2565 {"itemsize", (getter)memory_itemsize_get, NULL, NULL},
2566 {"format", (getter)memory_format_get, NULL, NULL},
2567 {"ndim", (getter)memory_ndim_get, NULL, NULL},
2568 {"shape", (getter)memory_shape_get, NULL, NULL},
2569 {"strides", (getter)memory_strides_get, NULL, NULL},
2570 {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL},
2571 {"c_contiguous", (getter)memory_c_contiguous, NULL, NULL},
2572 {"f_contiguous", (getter)memory_f_contiguous, NULL, NULL},
2573 {"contiguous", (getter)memory_contiguous, NULL, NULL},
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002574 {NULL, NULL, NULL, NULL},
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002575};
2576
2577
Antoine Pitrou6e6cc832010-09-09 12:59:39 +00002578static PyMethodDef memory_methods[] = {
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002579 {"release", (PyCFunction)memory_release, METH_NOARGS},
2580 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
2581 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
2582 {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, NULL},
2583 {"__enter__", memory_enter, METH_NOARGS},
2584 {"__exit__", memory_exit, METH_VARARGS},
2585 {NULL, NULL}
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002586};
2587
2588
2589PyTypeObject PyMemoryView_Type = {
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002590 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Stefan Krah9a2d99e2012-02-25 12:24:21 +01002591 "memoryview", /* tp_name */
2592 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */
2593 sizeof(Py_ssize_t), /* tp_itemsize */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002594 (destructor)memory_dealloc, /* tp_dealloc */
2595 0, /* tp_print */
2596 0, /* tp_getattr */
2597 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00002598 0, /* tp_reserved */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002599 (reprfunc)memory_repr, /* tp_repr */
2600 0, /* tp_as_number */
Raymond Hettinger159eac92009-06-23 20:38:54 +00002601 &memory_as_sequence, /* tp_as_sequence */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002602 &memory_as_mapping, /* tp_as_mapping */
Antoine Pitrouce4a9da2011-11-21 20:46:33 +01002603 (hashfunc)memory_hash, /* tp_hash */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002604 0, /* tp_call */
Benjamin Peterson87618552009-02-08 15:00:52 +00002605 0, /* tp_str */
Antoine Pitrou35b7e832009-01-03 19:20:36 +00002606 PyObject_GenericGetAttr, /* tp_getattro */
2607 0, /* tp_setattro */
2608 &memory_as_buffer, /* tp_as_buffer */
2609 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2610 memory_doc, /* tp_doc */
2611 (traverseproc)memory_traverse, /* tp_traverse */
2612 (inquiry)memory_clear, /* tp_clear */
2613 memory_richcompare, /* tp_richcompare */
2614 0, /* tp_weaklistoffset */
2615 0, /* tp_iter */
2616 0, /* tp_iternext */
2617 memory_methods, /* tp_methods */
2618 0, /* tp_members */
2619 memory_getsetlist, /* tp_getset */
2620 0, /* tp_base */
2621 0, /* tp_dict */
2622 0, /* tp_descr_get */
2623 0, /* tp_descr_set */
2624 0, /* tp_dictoffset */
2625 0, /* tp_init */
2626 0, /* tp_alloc */
2627 memory_new, /* tp_new */
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00002628};