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