Home | History | Annotate | Download | only in Objects
      1 /* Memoryview object implementation */
      2 
      3 #include "Python.h"
      4 #include "pystrhex.h"
      5 #include <stddef.h>
      6 
      7 
      8 /****************************************************************************/
      9 /*                           ManagedBuffer Object                           */
     10 /****************************************************************************/
     11 
     12 /*
     13    ManagedBuffer Object:
     14    ---------------------
     15 
     16      The purpose of this object is to facilitate the handling of chained
     17      memoryviews that have the same underlying exporting object. PEP-3118
     18      allows the underlying object to change while a view is exported. This
     19      could lead to unexpected results when constructing a new memoryview
     20      from an existing memoryview.
     21 
     22      Rather than repeatedly redirecting buffer requests to the original base
     23      object, all chained memoryviews use a single buffer snapshot. This
     24      snapshot is generated by the constructor _PyManagedBuffer_FromObject().
     25 
     26    Ownership rules:
     27    ----------------
     28 
     29      The master buffer inside a managed buffer is filled in by the original
     30      base object. shape, strides, suboffsets and format are read-only for
     31      all consumers.
     32 
     33      A memoryview's buffer is a private copy of the exporter's buffer. shape,
     34      strides and suboffsets belong to the memoryview and are thus writable.
     35 
     36      If a memoryview itself exports several buffers via memory_getbuf(), all
     37      buffer copies share shape, strides and suboffsets. In this case, the
     38      arrays are NOT writable.
     39 
     40    Reference count assumptions:
     41    ----------------------------
     42 
     43      The 'obj' member of a Py_buffer must either be NULL or refer to the
     44      exporting base object. In the Python codebase, all getbufferprocs
     45      return a new reference to view.obj (example: bytes_buffer_getbuffer()).
     46 
     47      PyBuffer_Release() decrements view.obj (if non-NULL), so the
     48      releasebufferprocs must NOT decrement view.obj.
     49 */
     50 
     51 
     52 #define CHECK_MBUF_RELEASED(mbuf) \
     53     if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \
     54         PyErr_SetString(PyExc_ValueError,                                      \
     55             "operation forbidden on released memoryview object");              \
     56         return NULL;                                                           \
     57     }
     58 
     59 
     60 static inline _PyManagedBufferObject *
     61 mbuf_alloc(void)
     62 {
     63     _PyManagedBufferObject *mbuf;
     64 
     65     mbuf = (_PyManagedBufferObject *)
     66         PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type);
     67     if (mbuf == NULL)
     68         return NULL;
     69     mbuf->flags = 0;
     70     mbuf->exports = 0;
     71     mbuf->master.obj = NULL;
     72     _PyObject_GC_TRACK(mbuf);
     73 
     74     return mbuf;
     75 }
     76 
     77 static PyObject *
     78 _PyManagedBuffer_FromObject(PyObject *base)
     79 {
     80     _PyManagedBufferObject *mbuf;
     81 
     82     mbuf = mbuf_alloc();
     83     if (mbuf == NULL)
     84         return NULL;
     85 
     86     if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) {
     87         mbuf->master.obj = NULL;
     88         Py_DECREF(mbuf);
     89         return NULL;
     90     }
     91 
     92     return (PyObject *)mbuf;
     93 }
     94 
     95 static void
     96 mbuf_release(_PyManagedBufferObject *self)
     97 {
     98     if (self->flags&_Py_MANAGED_BUFFER_RELEASED)
     99         return;
    100 
    101     /* NOTE: at this point self->exports can still be > 0 if this function
    102        is called from mbuf_clear() to break up a reference cycle. */
    103     self->flags |= _Py_MANAGED_BUFFER_RELEASED;
    104 
    105     /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
    106     _PyObject_GC_UNTRACK(self);
    107     PyBuffer_Release(&self->master);
    108 }
    109 
    110 static void
    111 mbuf_dealloc(_PyManagedBufferObject *self)
    112 {
    113     assert(self->exports == 0);
    114     mbuf_release(self);
    115     if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT)
    116         PyMem_Free(self->master.format);
    117     PyObject_GC_Del(self);
    118 }
    119 
    120 static int
    121 mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg)
    122 {
    123     Py_VISIT(self->master.obj);
    124     return 0;
    125 }
    126 
    127 static int
    128 mbuf_clear(_PyManagedBufferObject *self)
    129 {
    130     assert(self->exports >= 0);
    131     mbuf_release(self);
    132     return 0;
    133 }
    134 
    135 PyTypeObject _PyManagedBuffer_Type = {
    136     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    137     "managedbuffer",
    138     sizeof(_PyManagedBufferObject),
    139     0,
    140     (destructor)mbuf_dealloc,                /* tp_dealloc */
    141     0,                                       /* tp_print */
    142     0,                                       /* tp_getattr */
    143     0,                                       /* tp_setattr */
    144     0,                                       /* tp_reserved */
    145     0,                                       /* tp_repr */
    146     0,                                       /* tp_as_number */
    147     0,                                       /* tp_as_sequence */
    148     0,                                       /* tp_as_mapping */
    149     0,                                       /* tp_hash */
    150     0,                                       /* tp_call */
    151     0,                                       /* tp_str */
    152     PyObject_GenericGetAttr,                 /* tp_getattro */
    153     0,                                       /* tp_setattro */
    154     0,                                       /* tp_as_buffer */
    155     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    156     0,                                       /* tp_doc */
    157     (traverseproc)mbuf_traverse,             /* tp_traverse */
    158     (inquiry)mbuf_clear                      /* tp_clear */
    159 };
    160 
    161 
    162 /****************************************************************************/
    163 /*                             MemoryView Object                            */
    164 /****************************************************************************/
    165 
    166 /* In the process of breaking reference cycles mbuf_release() can be
    167    called before memory_release(). */
    168 #define BASE_INACCESSIBLE(mv) \
    169     (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \
    170      ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED)
    171 
    172 #define CHECK_RELEASED(mv) \
    173     if (BASE_INACCESSIBLE(mv)) {                                  \
    174         PyErr_SetString(PyExc_ValueError,                         \
    175             "operation forbidden on released memoryview object"); \
    176         return NULL;                                              \
    177     }
    178 
    179 #define CHECK_RELEASED_INT(mv) \
    180     if (BASE_INACCESSIBLE(mv)) {                                  \
    181         PyErr_SetString(PyExc_ValueError,                         \
    182             "operation forbidden on released memoryview object"); \
    183         return -1;                                                \
    184     }
    185 
    186 #define CHECK_LIST_OR_TUPLE(v) \
    187     if (!PyList_Check(v) && !PyTuple_Check(v)) { \
    188         PyErr_SetString(PyExc_TypeError,         \
    189             #v " must be a list or a tuple");    \
    190         return NULL;                             \
    191     }
    192 
    193 #define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view)
    194 
    195 /* Check for the presence of suboffsets in the first dimension. */
    196 #define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0)
    197 /* Adjust ptr if suboffsets are present. */
    198 #define ADJUST_PTR(ptr, suboffsets, dim) \
    199     (HAVE_PTR(suboffsets, dim) ? *((char**)ptr) + suboffsets[dim] : ptr)
    200 
    201 /* Memoryview buffer properties */
    202 #define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
    203 #define MV_F_CONTIGUOUS(flags) \
    204     (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
    205 #define MV_ANY_CONTIGUOUS(flags) \
    206     (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
    207 
    208 /* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */
    209 #define MV_CONTIGUOUS_NDIM1(view) \
    210     ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize)
    211 
    212 /* getbuffer() requests */
    213 #define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
    214 #define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
    215 #define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
    216 #define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
    217 #define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
    218 #define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
    219 #define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
    220 #define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
    221 
    222 
    223 PyDoc_STRVAR(memory_doc,
    224 "memoryview(object)\n--\n\
    225 \n\
    226 Create a new memoryview object which references the given object.");
    227 
    228 
    229 /**************************************************************************/
    230 /*                       Copy memoryview buffers                          */
    231 /**************************************************************************/
    232 
    233 /* The functions in this section take a source and a destination buffer
    234    with the same logical structure: format, itemsize, ndim and shape
    235    are identical, with ndim > 0.
    236 
    237    NOTE: All buffers are assumed to have PyBUF_FULL information, which
    238    is the case for memoryviews! */
    239 
    240 
    241 /* Assumptions: ndim >= 1. The macro tests for a corner case that should
    242    perhaps be explicitly forbidden in the PEP. */
    243 #define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
    244     (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
    245 
    246 static inline int
    247 last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src)
    248 {
    249     assert(dest->ndim > 0 && src->ndim > 0);
    250     return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) &&
    251             !HAVE_SUBOFFSETS_IN_LAST_DIM(src) &&
    252             dest->strides[dest->ndim-1] == dest->itemsize &&
    253             src->strides[src->ndim-1] == src->itemsize);
    254 }
    255 
    256 /* This is not a general function for determining format equivalence.
    257    It is used in copy_single() and copy_buffer() to weed out non-matching
    258    formats. Skipping the '@' character is specifically used in slice
    259    assignments, where the lvalue is already known to have a single character
    260    format. This is a performance hack that could be rewritten (if properly
    261    benchmarked). */
    262 static inline int
    263 equiv_format(const Py_buffer *dest, const Py_buffer *src)
    264 {
    265     const char *dfmt, *sfmt;
    266 
    267     assert(dest->format && src->format);
    268     dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format;
    269     sfmt = src->format[0] == '@' ? src->format+1 : src->format;
    270 
    271     if (strcmp(dfmt, sfmt) != 0 ||
    272         dest->itemsize != src->itemsize) {
    273         return 0;
    274     }
    275 
    276     return 1;
    277 }
    278 
    279 /* Two shapes are equivalent if they are either equal or identical up
    280    to a zero element at the same position. For example, in NumPy arrays
    281    the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */
    282 static inline int
    283 equiv_shape(const Py_buffer *dest, const Py_buffer *src)
    284 {
    285     int i;
    286 
    287     if (dest->ndim != src->ndim)
    288         return 0;
    289 
    290     for (i = 0; i < dest->ndim; i++) {
    291         if (dest->shape[i] != src->shape[i])
    292             return 0;
    293         if (dest->shape[i] == 0)
    294             break;
    295     }
    296 
    297     return 1;
    298 }
    299 
    300 /* Check that the logical structure of the destination and source buffers
    301    is identical. */
    302 static int
    303 equiv_structure(const Py_buffer *dest, const Py_buffer *src)
    304 {
    305     if (!equiv_format(dest, src) ||
    306         !equiv_shape(dest, src)) {
    307         PyErr_SetString(PyExc_ValueError,
    308             "memoryview assignment: lvalue and rvalue have different "
    309             "structures");
    310         return 0;
    311     }
    312 
    313     return 1;
    314 }
    315 
    316 /* Base case for recursive multi-dimensional copying. Contiguous arrays are
    317    copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
    318    sizeof(mem) == shape[0] * itemsize. */
    319 static void
    320 copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
    321           char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
    322           char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
    323           char *mem)
    324 {
    325     if (mem == NULL) { /* contiguous */
    326         Py_ssize_t size = shape[0] * itemsize;
    327         if (dptr + size < sptr || sptr + size < dptr)
    328             memcpy(dptr, sptr, size); /* no overlapping */
    329         else
    330             memmove(dptr, sptr, size);
    331     }
    332     else {
    333         char *p;
    334         Py_ssize_t i;
    335         for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
    336             char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0);
    337             memcpy(p, xsptr, itemsize);
    338         }
    339         for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
    340             char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0);
    341             memcpy(xdptr, p, itemsize);
    342         }
    343     }
    344 
    345 }
    346 
    347 /* Recursively copy a source buffer to a destination buffer. The two buffers
    348    have the same ndim, shape and itemsize. */
    349 static void
    350 copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
    351          char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
    352          char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
    353          char *mem)
    354 {
    355     Py_ssize_t i;
    356 
    357     assert(ndim >= 1);
    358 
    359     if (ndim == 1) {
    360         copy_base(shape, itemsize,
    361                   dptr, dstrides, dsuboffsets,
    362                   sptr, sstrides, ssuboffsets,
    363                   mem);
    364         return;
    365     }
    366 
    367     for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
    368         char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0);
    369         char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0);
    370 
    371         copy_rec(shape+1, ndim-1, itemsize,
    372                  xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
    373                  xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
    374                  mem);
    375     }
    376 }
    377 
    378 /* Faster copying of one-dimensional arrays. */
    379 static int
    380 copy_single(Py_buffer *dest, Py_buffer *src)
    381 {
    382     char *mem = NULL;
    383 
    384     assert(dest->ndim == 1);
    385 
    386     if (!equiv_structure(dest, src))
    387         return -1;
    388 
    389     if (!last_dim_is_contiguous(dest, src)) {
    390         mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
    391         if (mem == NULL) {
    392             PyErr_NoMemory();
    393             return -1;
    394         }
    395     }
    396 
    397     copy_base(dest->shape, dest->itemsize,
    398               dest->buf, dest->strides, dest->suboffsets,
    399               src->buf, src->strides, src->suboffsets,
    400               mem);
    401 
    402     if (mem)
    403         PyMem_Free(mem);
    404 
    405     return 0;
    406 }
    407 
    408 /* Recursively copy src to dest. Both buffers must have the same basic
    409    structure. Copying is atomic, the function never fails with a partial
    410    copy. */
    411 static int
    412 copy_buffer(Py_buffer *dest, Py_buffer *src)
    413 {
    414     char *mem = NULL;
    415 
    416     assert(dest->ndim > 0);
    417 
    418     if (!equiv_structure(dest, src))
    419         return -1;
    420 
    421     if (!last_dim_is_contiguous(dest, src)) {
    422         mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
    423         if (mem == NULL) {
    424             PyErr_NoMemory();
    425             return -1;
    426         }
    427     }
    428 
    429     copy_rec(dest->shape, dest->ndim, dest->itemsize,
    430              dest->buf, dest->strides, dest->suboffsets,
    431              src->buf, src->strides, src->suboffsets,
    432              mem);
    433 
    434     if (mem)
    435         PyMem_Free(mem);
    436 
    437     return 0;
    438 }
    439 
    440 /* Initialize strides for a C-contiguous array. */
    441 static inline void
    442 init_strides_from_shape(Py_buffer *view)
    443 {
    444     Py_ssize_t i;
    445 
    446     assert(view->ndim > 0);
    447 
    448     view->strides[view->ndim-1] = view->itemsize;
    449     for (i = view->ndim-2; i >= 0; i--)
    450         view->strides[i] = view->strides[i+1] * view->shape[i+1];
    451 }
    452 
    453 /* Initialize strides for a Fortran-contiguous array. */
    454 static inline void
    455 init_fortran_strides_from_shape(Py_buffer *view)
    456 {
    457     Py_ssize_t i;
    458 
    459     assert(view->ndim > 0);
    460 
    461     view->strides[0] = view->itemsize;
    462     for (i = 1; i < view->ndim; i++)
    463         view->strides[i] = view->strides[i-1] * view->shape[i-1];
    464 }
    465 
    466 /* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran)
    467    or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1,
    468    len(mem) == src->len. */
    469 static int
    470 buffer_to_contiguous(char *mem, Py_buffer *src, char order)
    471 {
    472     Py_buffer dest;
    473     Py_ssize_t *strides;
    474     int ret;
    475 
    476     assert(src->ndim >= 1);
    477     assert(src->shape != NULL);
    478     assert(src->strides != NULL);
    479 
    480     strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
    481     if (strides == NULL) {
    482         PyErr_NoMemory();
    483         return -1;
    484     }
    485 
    486     /* initialize dest */
    487     dest = *src;
    488     dest.buf = mem;
    489     /* shape is constant and shared: the logical representation of the
    490        array is unaltered. */
    491 
    492     /* The physical representation determined by strides (and possibly
    493        suboffsets) may change. */
    494     dest.strides = strides;
    495     if (order == 'C' || order == 'A') {
    496         init_strides_from_shape(&dest);
    497     }
    498     else {
    499         init_fortran_strides_from_shape(&dest);
    500     }
    501 
    502     dest.suboffsets = NULL;
    503 
    504     ret = copy_buffer(&dest, src);
    505 
    506     PyMem_Free(strides);
    507     return ret;
    508 }
    509 
    510 
    511 /****************************************************************************/
    512 /*                               Constructors                               */
    513 /****************************************************************************/
    514 
    515 /* Initialize values that are shared with the managed buffer. */
    516 static inline void
    517 init_shared_values(Py_buffer *dest, const Py_buffer *src)
    518 {
    519     dest->obj = src->obj;
    520     dest->buf = src->buf;
    521     dest->len = src->len;
    522     dest->itemsize = src->itemsize;
    523     dest->readonly = src->readonly;
    524     dest->format = src->format ? src->format : "B";
    525     dest->internal = src->internal;
    526 }
    527 
    528 /* Copy shape and strides. Reconstruct missing values. */
    529 static void
    530 init_shape_strides(Py_buffer *dest, const Py_buffer *src)
    531 {
    532     Py_ssize_t i;
    533 
    534     if (src->ndim == 0) {
    535         dest->shape = NULL;
    536         dest->strides = NULL;
    537         return;
    538     }
    539     if (src->ndim == 1) {
    540         dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
    541         dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
    542         return;
    543     }
    544 
    545     for (i = 0; i < src->ndim; i++)
    546         dest->shape[i] = src->shape[i];
    547     if (src->strides) {
    548         for (i = 0; i < src->ndim; i++)
    549             dest->strides[i] = src->strides[i];
    550     }
    551     else {
    552         init_strides_from_shape(dest);
    553     }
    554 }
    555 
    556 static inline void
    557 init_suboffsets(Py_buffer *dest, const Py_buffer *src)
    558 {
    559     Py_ssize_t i;
    560 
    561     if (src->suboffsets == NULL) {
    562         dest->suboffsets = NULL;
    563         return;
    564     }
    565     for (i = 0; i < src->ndim; i++)
    566         dest->suboffsets[i] = src->suboffsets[i];
    567 }
    568 
    569 /* len = product(shape) * itemsize */
    570 static inline void
    571 init_len(Py_buffer *view)
    572 {
    573     Py_ssize_t i, len;
    574 
    575     len = 1;
    576     for (i = 0; i < view->ndim; i++)
    577         len *= view->shape[i];
    578     len *= view->itemsize;
    579 
    580     view->len = len;
    581 }
    582 
    583 /* Initialize memoryview buffer properties. */
    584 static void
    585 init_flags(PyMemoryViewObject *mv)
    586 {
    587     const Py_buffer *view = &mv->view;
    588     int flags = 0;
    589 
    590     switch (view->ndim) {
    591     case 0:
    592         flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
    593                   _Py_MEMORYVIEW_FORTRAN);
    594         break;
    595     case 1:
    596         if (MV_CONTIGUOUS_NDIM1(view))
    597             flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
    598         break;
    599     default:
    600         if (PyBuffer_IsContiguous(view, 'C'))
    601             flags |= _Py_MEMORYVIEW_C;
    602         if (PyBuffer_IsContiguous(view, 'F'))
    603             flags |= _Py_MEMORYVIEW_FORTRAN;
    604         break;
    605     }
    606 
    607     if (view->suboffsets) {
    608         flags |= _Py_MEMORYVIEW_PIL;
    609         flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
    610     }
    611 
    612     mv->flags = flags;
    613 }
    614 
    615 /* Allocate a new memoryview and perform basic initialization. New memoryviews
    616    are exclusively created through the mbuf_add functions. */
    617 static inline PyMemoryViewObject *
    618 memory_alloc(int ndim)
    619 {
    620     PyMemoryViewObject *mv;
    621 
    622     mv = (PyMemoryViewObject *)
    623         PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
    624     if (mv == NULL)
    625         return NULL;
    626 
    627     mv->mbuf = NULL;
    628     mv->hash = -1;
    629     mv->flags = 0;
    630     mv->exports = 0;
    631     mv->view.ndim = ndim;
    632     mv->view.shape = mv->ob_array;
    633     mv->view.strides = mv->ob_array + ndim;
    634     mv->view.suboffsets = mv->ob_array + 2 * ndim;
    635     mv->weakreflist = NULL;
    636 
    637     _PyObject_GC_TRACK(mv);
    638     return mv;
    639 }
    640 
    641 /*
    642    Return a new memoryview that is registered with mbuf. If src is NULL,
    643    use mbuf->master as the underlying buffer. Otherwise, use src.
    644 
    645    The new memoryview has full buffer information: shape and strides
    646    are always present, suboffsets as needed. Arrays are copied to
    647    the memoryview's ob_array field.
    648  */
    649 static PyObject *
    650 mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
    651 {
    652     PyMemoryViewObject *mv;
    653     Py_buffer *dest;
    654 
    655     if (src == NULL)
    656         src = &mbuf->master;
    657 
    658     if (src->ndim > PyBUF_MAX_NDIM) {
    659         PyErr_SetString(PyExc_ValueError,
    660             "memoryview: number of dimensions must not exceed "
    661             Py_STRINGIFY(PyBUF_MAX_NDIM));
    662         return NULL;
    663     }
    664 
    665     mv = memory_alloc(src->ndim);
    666     if (mv == NULL)
    667         return NULL;
    668 
    669     dest = &mv->view;
    670     init_shared_values(dest, src);
    671     init_shape_strides(dest, src);
    672     init_suboffsets(dest, src);
    673     init_flags(mv);
    674 
    675     mv->mbuf = mbuf;
    676     Py_INCREF(mbuf);
    677     mbuf->exports++;
    678 
    679     return (PyObject *)mv;
    680 }
    681 
    682 /* Register an incomplete view: shape, strides, suboffsets and flags still
    683    need to be initialized. Use 'ndim' instead of src->ndim to determine the
    684    size of the memoryview's ob_array.
    685 
    686    Assumption: ndim <= PyBUF_MAX_NDIM. */
    687 static PyObject *
    688 mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
    689                          int ndim)
    690 {
    691     PyMemoryViewObject *mv;
    692     Py_buffer *dest;
    693 
    694     if (src == NULL)
    695         src = &mbuf->master;
    696 
    697     assert(ndim <= PyBUF_MAX_NDIM);
    698 
    699     mv = memory_alloc(ndim);
    700     if (mv == NULL)
    701         return NULL;
    702 
    703     dest = &mv->view;
    704     init_shared_values(dest, src);
    705 
    706     mv->mbuf = mbuf;
    707     Py_INCREF(mbuf);
    708     mbuf->exports++;
    709 
    710     return (PyObject *)mv;
    711 }
    712 
    713 /* Expose a raw memory area as a view of contiguous bytes. flags can be
    714    PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
    715    The memoryview has complete buffer information. */
    716 PyObject *
    717 PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
    718 {
    719     _PyManagedBufferObject *mbuf;
    720     PyObject *mv;
    721     int readonly;
    722 
    723     assert(mem != NULL);
    724     assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
    725 
    726     mbuf = mbuf_alloc();
    727     if (mbuf == NULL)
    728         return NULL;
    729 
    730     readonly = (flags == PyBUF_WRITE) ? 0 : 1;
    731     (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
    732                             PyBUF_FULL_RO);
    733 
    734     mv = mbuf_add_view(mbuf, NULL);
    735     Py_DECREF(mbuf);
    736 
    737     return mv;
    738 }
    739 
    740 /* Create a memoryview from a given Py_buffer. For simple byte views,
    741    PyMemoryView_FromMemory() should be used instead.
    742    This function is the only entry point that can create a master buffer
    743    without full information. Because of this fact init_shape_strides()
    744    must be able to reconstruct missing values.  */
    745 PyObject *
    746 PyMemoryView_FromBuffer(Py_buffer *info)
    747 {
    748     _PyManagedBufferObject *mbuf;
    749     PyObject *mv;
    750 
    751     if (info->buf == NULL) {
    752         PyErr_SetString(PyExc_ValueError,
    753             "PyMemoryView_FromBuffer(): info->buf must not be NULL");
    754         return NULL;
    755     }
    756 
    757     mbuf = mbuf_alloc();
    758     if (mbuf == NULL)
    759         return NULL;
    760 
    761     /* info->obj is either NULL or a borrowed reference. This reference
    762        should not be decremented in PyBuffer_Release(). */
    763     mbuf->master = *info;
    764     mbuf->master.obj = NULL;
    765 
    766     mv = mbuf_add_view(mbuf, NULL);
    767     Py_DECREF(mbuf);
    768 
    769     return mv;
    770 }
    771 
    772 /* Create a memoryview from an object that implements the buffer protocol.
    773    If the object is a memoryview, the new memoryview must be registered
    774    with the same managed buffer. Otherwise, a new managed buffer is created. */
    775 PyObject *
    776 PyMemoryView_FromObject(PyObject *v)
    777 {
    778     _PyManagedBufferObject *mbuf;
    779 
    780     if (PyMemoryView_Check(v)) {
    781         PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
    782         CHECK_RELEASED(mv);
    783         return mbuf_add_view(mv->mbuf, &mv->view);
    784     }
    785     else if (PyObject_CheckBuffer(v)) {
    786         PyObject *ret;
    787         mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
    788         if (mbuf == NULL)
    789             return NULL;
    790         ret = mbuf_add_view(mbuf, NULL);
    791         Py_DECREF(mbuf);
    792         return ret;
    793     }
    794 
    795     PyErr_Format(PyExc_TypeError,
    796         "memoryview: a bytes-like object is required, not '%.200s'",
    797         Py_TYPE(v)->tp_name);
    798     return NULL;
    799 }
    800 
    801 /* Copy the format string from a base object that might vanish. */
    802 static int
    803 mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
    804 {
    805     if (fmt != NULL) {
    806         char *cp = PyMem_Malloc(strlen(fmt)+1);
    807         if (cp == NULL) {
    808             PyErr_NoMemory();
    809             return -1;
    810         }
    811         mbuf->master.format = strcpy(cp, fmt);
    812         mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
    813     }
    814 
    815     return 0;
    816 }
    817 
    818 /*
    819    Return a memoryview that is based on a contiguous copy of src.
    820    Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
    821 
    822    Ownership rules:
    823      1) As usual, the returned memoryview has a private copy
    824         of src->shape, src->strides and src->suboffsets.
    825      2) src->format is copied to the master buffer and released
    826         in mbuf_dealloc(). The releasebufferproc of the bytes
    827         object is NULL, so it does not matter that mbuf_release()
    828         passes the altered format pointer to PyBuffer_Release().
    829 */
    830 static PyObject *
    831 memory_from_contiguous_copy(Py_buffer *src, char order)
    832 {
    833     _PyManagedBufferObject *mbuf;
    834     PyMemoryViewObject *mv;
    835     PyObject *bytes;
    836     Py_buffer *dest;
    837     int i;
    838 
    839     assert(src->ndim > 0);
    840     assert(src->shape != NULL);
    841 
    842     bytes = PyBytes_FromStringAndSize(NULL, src->len);
    843     if (bytes == NULL)
    844         return NULL;
    845 
    846     mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
    847     Py_DECREF(bytes);
    848     if (mbuf == NULL)
    849         return NULL;
    850 
    851     if (mbuf_copy_format(mbuf, src->format) < 0) {
    852         Py_DECREF(mbuf);
    853         return NULL;
    854     }
    855 
    856     mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
    857     Py_DECREF(mbuf);
    858     if (mv == NULL)
    859         return NULL;
    860 
    861     dest = &mv->view;
    862 
    863     /* shared values are initialized correctly except for itemsize */
    864     dest->itemsize = src->itemsize;
    865 
    866     /* shape and strides */
    867     for (i = 0; i < src->ndim; i++) {
    868         dest->shape[i] = src->shape[i];
    869     }
    870     if (order == 'C' || order == 'A') {
    871         init_strides_from_shape(dest);
    872     }
    873     else {
    874         init_fortran_strides_from_shape(dest);
    875     }
    876     /* suboffsets */
    877     dest->suboffsets = NULL;
    878 
    879     /* flags */
    880     init_flags(mv);
    881 
    882     if (copy_buffer(dest, src) < 0) {
    883         Py_DECREF(mv);
    884         return NULL;
    885     }
    886 
    887     return (PyObject *)mv;
    888 }
    889 
    890 /*
    891    Return a new memoryview object based on a contiguous exporter with
    892    buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
    893    The logical structure of the input and output buffers is the same
    894    (i.e. tolist(input) == tolist(output)), but the physical layout in
    895    memory can be explicitly chosen.
    896 
    897    As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
    898    otherwise it may be writable or read-only.
    899 
    900    If the exporter is already contiguous with the desired target order,
    901    the memoryview will be directly based on the exporter.
    902 
    903    Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
    904    based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
    905    'F'ortran order otherwise.
    906 */
    907 PyObject *
    908 PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
    909 {
    910     PyMemoryViewObject *mv;
    911     PyObject *ret;
    912     Py_buffer *view;
    913 
    914     assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
    915     assert(order == 'C' || order == 'F' || order == 'A');
    916 
    917     mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
    918     if (mv == NULL)
    919         return NULL;
    920 
    921     view = &mv->view;
    922     if (buffertype == PyBUF_WRITE && view->readonly) {
    923         PyErr_SetString(PyExc_BufferError,
    924             "underlying buffer is not writable");
    925         Py_DECREF(mv);
    926         return NULL;
    927     }
    928 
    929     if (PyBuffer_IsContiguous(view, order))
    930         return (PyObject *)mv;
    931 
    932     if (buffertype == PyBUF_WRITE) {
    933         PyErr_SetString(PyExc_BufferError,
    934             "writable contiguous buffer requested "
    935             "for a non-contiguous object.");
    936         Py_DECREF(mv);
    937         return NULL;
    938     }
    939 
    940     ret = memory_from_contiguous_copy(view, order);
    941     Py_DECREF(mv);
    942     return ret;
    943 }
    944 
    945 
    946 static PyObject *
    947 memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
    948 {
    949     PyObject *obj;
    950     static char *kwlist[] = {"object", NULL};
    951 
    952     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
    953                                      &obj)) {
    954         return NULL;
    955     }
    956 
    957     return PyMemoryView_FromObject(obj);
    958 }
    959 
    960 
    961 /****************************************************************************/
    962 /*                         Previously in abstract.c                         */
    963 /****************************************************************************/
    964 
    965 typedef struct {
    966     Py_buffer view;
    967     Py_ssize_t array[1];
    968 } Py_buffer_full;
    969 
    970 int
    971 PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order)
    972 {
    973     Py_buffer_full *fb = NULL;
    974     int ret;
    975 
    976     assert(order == 'C' || order == 'F' || order == 'A');
    977 
    978     if (len != src->len) {
    979         PyErr_SetString(PyExc_ValueError,
    980             "PyBuffer_ToContiguous: len != view->len");
    981         return -1;
    982     }
    983 
    984     if (PyBuffer_IsContiguous(src, order)) {
    985         memcpy((char *)buf, src->buf, len);
    986         return 0;
    987     }
    988 
    989     /* buffer_to_contiguous() assumes PyBUF_FULL */
    990     fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array));
    991     if (fb == NULL) {
    992         PyErr_NoMemory();
    993         return -1;
    994     }
    995     fb->view.ndim = src->ndim;
    996     fb->view.shape = fb->array;
    997     fb->view.strides = fb->array + src->ndim;
    998     fb->view.suboffsets = fb->array + 2 * src->ndim;
    999 
   1000     init_shared_values(&fb->view, src);
   1001     init_shape_strides(&fb->view, src);
   1002     init_suboffsets(&fb->view, src);
   1003 
   1004     src = &fb->view;
   1005 
   1006     ret = buffer_to_contiguous(buf, src, order);
   1007     PyMem_Free(fb);
   1008     return ret;
   1009 }
   1010 
   1011 
   1012 /****************************************************************************/
   1013 /*                           Release/GC management                          */
   1014 /****************************************************************************/
   1015 
   1016 /* Inform the managed buffer that this particular memoryview will not access
   1017    the underlying buffer again. If no other memoryviews are registered with
   1018    the managed buffer, the underlying buffer is released instantly and
   1019    marked as inaccessible for both the memoryview and the managed buffer.
   1020 
   1021    This function fails if the memoryview itself has exported buffers. */
   1022 static int
   1023 _memory_release(PyMemoryViewObject *self)
   1024 {
   1025     if (self->flags & _Py_MEMORYVIEW_RELEASED)
   1026         return 0;
   1027 
   1028     if (self->exports == 0) {
   1029         self->flags |= _Py_MEMORYVIEW_RELEASED;
   1030         assert(self->mbuf->exports > 0);
   1031         if (--self->mbuf->exports == 0)
   1032             mbuf_release(self->mbuf);
   1033         return 0;
   1034     }
   1035     if (self->exports > 0) {
   1036         PyErr_Format(PyExc_BufferError,
   1037             "memoryview has %zd exported buffer%s", self->exports,
   1038             self->exports==1 ? "" : "s");
   1039         return -1;
   1040     }
   1041 
   1042     Py_FatalError("_memory_release(): negative export count");
   1043     return -1;
   1044 }
   1045 
   1046 static PyObject *
   1047 memory_release(PyMemoryViewObject *self, PyObject *noargs)
   1048 {
   1049     if (_memory_release(self) < 0)
   1050         return NULL;
   1051     Py_RETURN_NONE;
   1052 }
   1053 
   1054 static void
   1055 memory_dealloc(PyMemoryViewObject *self)
   1056 {
   1057     assert(self->exports == 0);
   1058     _PyObject_GC_UNTRACK(self);
   1059     (void)_memory_release(self);
   1060     Py_CLEAR(self->mbuf);
   1061     if (self->weakreflist != NULL)
   1062         PyObject_ClearWeakRefs((PyObject *) self);
   1063     PyObject_GC_Del(self);
   1064 }
   1065 
   1066 static int
   1067 memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
   1068 {
   1069     Py_VISIT(self->mbuf);
   1070     return 0;
   1071 }
   1072 
   1073 static int
   1074 memory_clear(PyMemoryViewObject *self)
   1075 {
   1076     (void)_memory_release(self);
   1077     Py_CLEAR(self->mbuf);
   1078     return 0;
   1079 }
   1080 
   1081 static PyObject *
   1082 memory_enter(PyObject *self, PyObject *args)
   1083 {
   1084     CHECK_RELEASED(self);
   1085     Py_INCREF(self);
   1086     return self;
   1087 }
   1088 
   1089 static PyObject *
   1090 memory_exit(PyObject *self, PyObject *args)
   1091 {
   1092     return memory_release((PyMemoryViewObject *)self, NULL);
   1093 }
   1094 
   1095 
   1096 /****************************************************************************/
   1097 /*                         Casting format and shape                         */
   1098 /****************************************************************************/
   1099 
   1100 #define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
   1101 
   1102 static inline Py_ssize_t
   1103 get_native_fmtchar(char *result, const char *fmt)
   1104 {
   1105     Py_ssize_t size = -1;
   1106 
   1107     if (fmt[0] == '@') fmt++;
   1108 
   1109     switch (fmt[0]) {
   1110     case 'c': case 'b': case 'B': size = sizeof(char); break;
   1111     case 'h': case 'H': size = sizeof(short); break;
   1112     case 'i': case 'I': size = sizeof(int); break;
   1113     case 'l': case 'L': size = sizeof(long); break;
   1114     case 'q': case 'Q': size = sizeof(long long); break;
   1115     case 'n': case 'N': size = sizeof(Py_ssize_t); break;
   1116     case 'f': size = sizeof(float); break;
   1117     case 'd': size = sizeof(double); break;
   1118     case '?': size = sizeof(_Bool); break;
   1119     case 'P': size = sizeof(void *); break;
   1120     }
   1121 
   1122     if (size > 0 && fmt[1] == '\0') {
   1123         *result = fmt[0];
   1124         return size;
   1125     }
   1126 
   1127     return -1;
   1128 }
   1129 
   1130 static inline const char *
   1131 get_native_fmtstr(const char *fmt)
   1132 {
   1133     int at = 0;
   1134 
   1135     if (fmt[0] == '@') {
   1136         at = 1;
   1137         fmt++;
   1138     }
   1139     if (fmt[0] == '\0' || fmt[1] != '\0') {
   1140         return NULL;
   1141     }
   1142 
   1143 #define RETURN(s) do { return at ? "@" s : s; } while (0)
   1144 
   1145     switch (fmt[0]) {
   1146     case 'c': RETURN("c");
   1147     case 'b': RETURN("b");
   1148     case 'B': RETURN("B");
   1149     case 'h': RETURN("h");
   1150     case 'H': RETURN("H");
   1151     case 'i': RETURN("i");
   1152     case 'I': RETURN("I");
   1153     case 'l': RETURN("l");
   1154     case 'L': RETURN("L");
   1155     case 'q': RETURN("q");
   1156     case 'Q': RETURN("Q");
   1157     case 'n': RETURN("n");
   1158     case 'N': RETURN("N");
   1159     case 'f': RETURN("f");
   1160     case 'd': RETURN("d");
   1161     case '?': RETURN("?");
   1162     case 'P': RETURN("P");
   1163     }
   1164 
   1165     return NULL;
   1166 }
   1167 
   1168 
   1169 /* Cast a memoryview's data type to 'format'. The input array must be
   1170    C-contiguous. At least one of input-format, output-format must have
   1171    byte size. The output array is 1-D, with the same byte length as the
   1172    input array. Thus, view->len must be a multiple of the new itemsize. */
   1173 static int
   1174 cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
   1175 {
   1176     Py_buffer *view = &mv->view;
   1177     PyObject *asciifmt;
   1178     char srcchar, destchar;
   1179     Py_ssize_t itemsize;
   1180     int ret = -1;
   1181 
   1182     assert(view->ndim >= 1);
   1183     assert(Py_SIZE(mv) == 3*view->ndim);
   1184     assert(view->shape == mv->ob_array);
   1185     assert(view->strides == mv->ob_array + view->ndim);
   1186     assert(view->suboffsets == mv->ob_array + 2*view->ndim);
   1187 
   1188     asciifmt = PyUnicode_AsASCIIString(format);
   1189     if (asciifmt == NULL)
   1190         return ret;
   1191 
   1192     itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
   1193     if (itemsize < 0) {
   1194         PyErr_SetString(PyExc_ValueError,
   1195             "memoryview: destination format must be a native single "
   1196             "character format prefixed with an optional '@'");
   1197         goto out;
   1198     }
   1199 
   1200     if ((get_native_fmtchar(&srcchar, view->format) < 0 ||
   1201          !IS_BYTE_FORMAT(srcchar)) && !IS_BYTE_FORMAT(destchar)) {
   1202         PyErr_SetString(PyExc_TypeError,
   1203             "memoryview: cannot cast between two non-byte formats");
   1204         goto out;
   1205     }
   1206     if (view->len % itemsize) {
   1207         PyErr_SetString(PyExc_TypeError,
   1208             "memoryview: length is not a multiple of itemsize");
   1209         goto out;
   1210     }
   1211 
   1212     view->format = (char *)get_native_fmtstr(PyBytes_AS_STRING(asciifmt));
   1213     if (view->format == NULL) {
   1214         /* NOT_REACHED: get_native_fmtchar() already validates the format. */
   1215         PyErr_SetString(PyExc_RuntimeError,
   1216             "memoryview: internal error");
   1217         goto out;
   1218     }
   1219     view->itemsize = itemsize;
   1220 
   1221     view->ndim = 1;
   1222     view->shape[0] = view->len / view->itemsize;
   1223     view->strides[0] = view->itemsize;
   1224     view->suboffsets = NULL;
   1225 
   1226     init_flags(mv);
   1227 
   1228     ret = 0;
   1229 
   1230 out:
   1231     Py_DECREF(asciifmt);
   1232     return ret;
   1233 }
   1234 
   1235 /* The memoryview must have space for 3*len(seq) elements. */
   1236 static Py_ssize_t
   1237 copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
   1238            Py_ssize_t itemsize)
   1239 {
   1240     Py_ssize_t x, i;
   1241     Py_ssize_t len = itemsize;
   1242 
   1243     for (i = 0; i < ndim; i++) {
   1244         PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
   1245         if (!PyLong_Check(tmp)) {
   1246             PyErr_SetString(PyExc_TypeError,
   1247                 "memoryview.cast(): elements of shape must be integers");
   1248             return -1;
   1249         }
   1250         x = PyLong_AsSsize_t(tmp);
   1251         if (x == -1 && PyErr_Occurred()) {
   1252             return -1;
   1253         }
   1254         if (x <= 0) {
   1255             /* In general elements of shape may be 0, but not for casting. */
   1256             PyErr_Format(PyExc_ValueError,
   1257                 "memoryview.cast(): elements of shape must be integers > 0");
   1258             return -1;
   1259         }
   1260         if (x > PY_SSIZE_T_MAX / len) {
   1261             PyErr_Format(PyExc_ValueError,
   1262                 "memoryview.cast(): product(shape) > SSIZE_MAX");
   1263             return -1;
   1264         }
   1265         len *= x;
   1266         shape[i] = x;
   1267     }
   1268 
   1269     return len;
   1270 }
   1271 
   1272 /* Cast a 1-D array to a new shape. The result array will be C-contiguous.
   1273    If the result array does not have exactly the same byte length as the
   1274    input array, raise ValueError. */
   1275 static int
   1276 cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
   1277 {
   1278     Py_buffer *view = &mv->view;
   1279     Py_ssize_t len;
   1280 
   1281     assert(view->ndim == 1); /* ndim from cast_to_1D() */
   1282     assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
   1283     assert(view->shape == mv->ob_array);
   1284     assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
   1285     assert(view->suboffsets == NULL);
   1286 
   1287     view->ndim = ndim;
   1288     if (view->ndim == 0) {
   1289         view->shape = NULL;
   1290         view->strides = NULL;
   1291         len = view->itemsize;
   1292     }
   1293     else {
   1294         len = copy_shape(view->shape, shape, ndim, view->itemsize);
   1295         if (len < 0)
   1296             return -1;
   1297         init_strides_from_shape(view);
   1298     }
   1299 
   1300     if (view->len != len) {
   1301         PyErr_SetString(PyExc_TypeError,
   1302             "memoryview: product(shape) * itemsize != buffer size");
   1303         return -1;
   1304     }
   1305 
   1306     init_flags(mv);
   1307 
   1308     return 0;
   1309 }
   1310 
   1311 static int
   1312 zero_in_shape(PyMemoryViewObject *mv)
   1313 {
   1314     Py_buffer *view = &mv->view;
   1315     Py_ssize_t i;
   1316 
   1317     for (i = 0; i < view->ndim; i++)
   1318         if (view->shape[i] == 0)
   1319             return 1;
   1320 
   1321     return 0;
   1322 }
   1323 
   1324 /*
   1325    Cast a copy of 'self' to a different view. The input view must
   1326    be C-contiguous. The function always casts the input view to a
   1327    1-D output according to 'format'. At least one of input-format,
   1328    output-format must have byte size.
   1329 
   1330    If 'shape' is given, the 1-D view from the previous step will
   1331    be cast to a C-contiguous view with new shape and strides.
   1332 
   1333    All casts must result in views that will have the exact byte
   1334    size of the original input. Otherwise, an error is raised.
   1335 */
   1336 static PyObject *
   1337 memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds)
   1338 {
   1339     static char *kwlist[] = {"format", "shape", NULL};
   1340     PyMemoryViewObject *mv = NULL;
   1341     PyObject *shape = NULL;
   1342     PyObject *format;
   1343     Py_ssize_t ndim = 1;
   1344 
   1345     CHECK_RELEASED(self);
   1346 
   1347     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
   1348                                      &format, &shape)) {
   1349         return NULL;
   1350     }
   1351     if (!PyUnicode_Check(format)) {
   1352         PyErr_SetString(PyExc_TypeError,
   1353             "memoryview: format argument must be a string");
   1354         return NULL;
   1355     }
   1356     if (!MV_C_CONTIGUOUS(self->flags)) {
   1357         PyErr_SetString(PyExc_TypeError,
   1358             "memoryview: casts are restricted to C-contiguous views");
   1359         return NULL;
   1360     }
   1361     if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
   1362         PyErr_SetString(PyExc_TypeError,
   1363             "memoryview: cannot cast view with zeros in shape or strides");
   1364         return NULL;
   1365     }
   1366     if (shape) {
   1367         CHECK_LIST_OR_TUPLE(shape)
   1368         ndim = PySequence_Fast_GET_SIZE(shape);
   1369         if (ndim > PyBUF_MAX_NDIM) {
   1370             PyErr_SetString(PyExc_ValueError,
   1371                 "memoryview: number of dimensions must not exceed "
   1372                 Py_STRINGIFY(PyBUF_MAX_NDIM));
   1373             return NULL;
   1374         }
   1375         if (self->view.ndim != 1 && ndim != 1) {
   1376             PyErr_SetString(PyExc_TypeError,
   1377                 "memoryview: cast must be 1D -> ND or ND -> 1D");
   1378             return NULL;
   1379         }
   1380     }
   1381 
   1382     mv = (PyMemoryViewObject *)
   1383         mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
   1384     if (mv == NULL)
   1385         return NULL;
   1386 
   1387     if (cast_to_1D(mv, format) < 0)
   1388         goto error;
   1389     if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
   1390         goto error;
   1391 
   1392     return (PyObject *)mv;
   1393 
   1394 error:
   1395     Py_DECREF(mv);
   1396     return NULL;
   1397 }
   1398 
   1399 
   1400 /**************************************************************************/
   1401 /*                               getbuffer                                */
   1402 /**************************************************************************/
   1403 
   1404 static int
   1405 memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
   1406 {
   1407     Py_buffer *base = &self->view;
   1408     int baseflags = self->flags;
   1409 
   1410     CHECK_RELEASED_INT(self);
   1411 
   1412     /* start with complete information */
   1413     *view = *base;
   1414     view->obj = NULL;
   1415 
   1416     if (REQ_WRITABLE(flags) && base->readonly) {
   1417         PyErr_SetString(PyExc_BufferError,
   1418             "memoryview: underlying buffer is not writable");
   1419         return -1;
   1420     }
   1421     if (!REQ_FORMAT(flags)) {
   1422         /* NULL indicates that the buffer's data type has been cast to 'B'.
   1423            view->itemsize is the _previous_ itemsize. If shape is present,
   1424            the equality product(shape) * itemsize = len still holds at this
   1425            point. The equality calcsize(format) = itemsize does _not_ hold
   1426            from here on! */
   1427         view->format = NULL;
   1428     }
   1429 
   1430     if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
   1431         PyErr_SetString(PyExc_BufferError,
   1432             "memoryview: underlying buffer is not C-contiguous");
   1433         return -1;
   1434     }
   1435     if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
   1436         PyErr_SetString(PyExc_BufferError,
   1437             "memoryview: underlying buffer is not Fortran contiguous");
   1438         return -1;
   1439     }
   1440     if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
   1441         PyErr_SetString(PyExc_BufferError,
   1442             "memoryview: underlying buffer is not contiguous");
   1443         return -1;
   1444     }
   1445     if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
   1446         PyErr_SetString(PyExc_BufferError,
   1447             "memoryview: underlying buffer requires suboffsets");
   1448         return -1;
   1449     }
   1450     if (!REQ_STRIDES(flags)) {
   1451         if (!MV_C_CONTIGUOUS(baseflags)) {
   1452             PyErr_SetString(PyExc_BufferError,
   1453                 "memoryview: underlying buffer is not C-contiguous");
   1454             return -1;
   1455         }
   1456         view->strides = NULL;
   1457     }
   1458     if (!REQ_SHAPE(flags)) {
   1459         /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
   1460            so base->buf = ndbuf->data. */
   1461         if (view->format != NULL) {
   1462             /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
   1463                not make sense. */
   1464             PyErr_Format(PyExc_BufferError,
   1465                 "memoryview: cannot cast to unsigned bytes if the format flag "
   1466                 "is present");
   1467             return -1;
   1468         }
   1469         /* product(shape) * itemsize = len and calcsize(format) = itemsize
   1470            do _not_ hold from here on! */
   1471         view->ndim = 1;
   1472         view->shape = NULL;
   1473     }
   1474 
   1475 
   1476     view->obj = (PyObject *)self;
   1477     Py_INCREF(view->obj);
   1478     self->exports++;
   1479 
   1480     return 0;
   1481 }
   1482 
   1483 static void
   1484 memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
   1485 {
   1486     self->exports--;
   1487     return;
   1488     /* PyBuffer_Release() decrements view->obj after this function returns. */
   1489 }
   1490 
   1491 /* Buffer methods */
   1492 static PyBufferProcs memory_as_buffer = {
   1493     (getbufferproc)memory_getbuf,         /* bf_getbuffer */
   1494     (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
   1495 };
   1496 
   1497 
   1498 /****************************************************************************/
   1499 /*           Optimized pack/unpack for all native format specifiers         */
   1500 /****************************************************************************/
   1501 
   1502 /*
   1503   Fix exceptions:
   1504      1) Include format string in the error message.
   1505      2) OverflowError -> ValueError.
   1506      3) The error message from PyNumber_Index() is not ideal.
   1507 */
   1508 static int
   1509 type_error_int(const char *fmt)
   1510 {
   1511     PyErr_Format(PyExc_TypeError,
   1512         "memoryview: invalid type for format '%s'", fmt);
   1513     return -1;
   1514 }
   1515 
   1516 static int
   1517 value_error_int(const char *fmt)
   1518 {
   1519     PyErr_Format(PyExc_ValueError,
   1520         "memoryview: invalid value for format '%s'", fmt);
   1521     return -1;
   1522 }
   1523 
   1524 static int
   1525 fix_error_int(const char *fmt)
   1526 {
   1527     assert(PyErr_Occurred());
   1528     if (PyErr_ExceptionMatches(PyExc_TypeError)) {
   1529         PyErr_Clear();
   1530         return type_error_int(fmt);
   1531     }
   1532     else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
   1533              PyErr_ExceptionMatches(PyExc_ValueError)) {
   1534         PyErr_Clear();
   1535         return value_error_int(fmt);
   1536     }
   1537 
   1538     return -1;
   1539 }
   1540 
   1541 /* Accept integer objects or objects with an __index__() method. */
   1542 static long
   1543 pylong_as_ld(PyObject *item)
   1544 {
   1545     PyObject *tmp;
   1546     long ld;
   1547 
   1548     tmp = PyNumber_Index(item);
   1549     if (tmp == NULL)
   1550         return -1;
   1551 
   1552     ld = PyLong_AsLong(tmp);
   1553     Py_DECREF(tmp);
   1554     return ld;
   1555 }
   1556 
   1557 static unsigned long
   1558 pylong_as_lu(PyObject *item)
   1559 {
   1560     PyObject *tmp;
   1561     unsigned long lu;
   1562 
   1563     tmp = PyNumber_Index(item);
   1564     if (tmp == NULL)
   1565         return (unsigned long)-1;
   1566 
   1567     lu = PyLong_AsUnsignedLong(tmp);
   1568     Py_DECREF(tmp);
   1569     return lu;
   1570 }
   1571 
   1572 static long long
   1573 pylong_as_lld(PyObject *item)
   1574 {
   1575     PyObject *tmp;
   1576     long long lld;
   1577 
   1578     tmp = PyNumber_Index(item);
   1579     if (tmp == NULL)
   1580         return -1;
   1581 
   1582     lld = PyLong_AsLongLong(tmp);
   1583     Py_DECREF(tmp);
   1584     return lld;
   1585 }
   1586 
   1587 static unsigned long long
   1588 pylong_as_llu(PyObject *item)
   1589 {
   1590     PyObject *tmp;
   1591     unsigned long long llu;
   1592 
   1593     tmp = PyNumber_Index(item);
   1594     if (tmp == NULL)
   1595         return (unsigned long long)-1;
   1596 
   1597     llu = PyLong_AsUnsignedLongLong(tmp);
   1598     Py_DECREF(tmp);
   1599     return llu;
   1600 }
   1601 
   1602 static Py_ssize_t
   1603 pylong_as_zd(PyObject *item)
   1604 {
   1605     PyObject *tmp;
   1606     Py_ssize_t zd;
   1607 
   1608     tmp = PyNumber_Index(item);
   1609     if (tmp == NULL)
   1610         return -1;
   1611 
   1612     zd = PyLong_AsSsize_t(tmp);
   1613     Py_DECREF(tmp);
   1614     return zd;
   1615 }
   1616 
   1617 static size_t
   1618 pylong_as_zu(PyObject *item)
   1619 {
   1620     PyObject *tmp;
   1621     size_t zu;
   1622 
   1623     tmp = PyNumber_Index(item);
   1624     if (tmp == NULL)
   1625         return (size_t)-1;
   1626 
   1627     zu = PyLong_AsSize_t(tmp);
   1628     Py_DECREF(tmp);
   1629     return zu;
   1630 }
   1631 
   1632 /* Timings with the ndarray from _testbuffer.c indicate that using the
   1633    struct module is around 15x slower than the two functions below. */
   1634 
   1635 #define UNPACK_SINGLE(dest, ptr, type) \
   1636     do {                                   \
   1637         type x;                            \
   1638         memcpy((char *)&x, ptr, sizeof x); \
   1639         dest = x;                          \
   1640     } while (0)
   1641 
   1642 /* Unpack a single item. 'fmt' can be any native format character in struct
   1643    module syntax. This function is very sensitive to small changes. With this
   1644    layout gcc automatically generates a fast jump table. */
   1645 static inline PyObject *
   1646 unpack_single(const char *ptr, const char *fmt)
   1647 {
   1648     unsigned long long llu;
   1649     unsigned long lu;
   1650     size_t zu;
   1651     long long lld;
   1652     long ld;
   1653     Py_ssize_t zd;
   1654     double d;
   1655     unsigned char uc;
   1656     void *p;
   1657 
   1658     switch (fmt[0]) {
   1659 
   1660     /* signed integers and fast path for 'B' */
   1661     case 'B': uc = *((unsigned char *)ptr); goto convert_uc;
   1662     case 'b': ld =   *((signed char *)ptr); goto convert_ld;
   1663     case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
   1664     case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
   1665     case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
   1666 
   1667     /* boolean */
   1668     case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
   1669 
   1670     /* unsigned integers */
   1671     case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
   1672     case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
   1673     case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
   1674 
   1675     /* native 64-bit */
   1676     case 'q': UNPACK_SINGLE(lld, ptr, long long); goto convert_lld;
   1677     case 'Q': UNPACK_SINGLE(llu, ptr, unsigned long long); goto convert_llu;
   1678 
   1679     /* ssize_t and size_t */
   1680     case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
   1681     case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
   1682 
   1683     /* floats */
   1684     case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
   1685     case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
   1686 
   1687     /* bytes object */
   1688     case 'c': goto convert_bytes;
   1689 
   1690     /* pointer */
   1691     case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
   1692 
   1693     /* default */
   1694     default: goto err_format;
   1695     }
   1696 
   1697 convert_uc:
   1698     /* PyLong_FromUnsignedLong() is slower */
   1699     return PyLong_FromLong(uc);
   1700 convert_ld:
   1701     return PyLong_FromLong(ld);
   1702 convert_lu:
   1703     return PyLong_FromUnsignedLong(lu);
   1704 convert_lld:
   1705     return PyLong_FromLongLong(lld);
   1706 convert_llu:
   1707     return PyLong_FromUnsignedLongLong(llu);
   1708 convert_zd:
   1709     return PyLong_FromSsize_t(zd);
   1710 convert_zu:
   1711     return PyLong_FromSize_t(zu);
   1712 convert_double:
   1713     return PyFloat_FromDouble(d);
   1714 convert_bool:
   1715     return PyBool_FromLong(ld);
   1716 convert_bytes:
   1717     return PyBytes_FromStringAndSize(ptr, 1);
   1718 convert_pointer:
   1719     return PyLong_FromVoidPtr(p);
   1720 err_format:
   1721     PyErr_Format(PyExc_NotImplementedError,
   1722         "memoryview: format %s not supported", fmt);
   1723     return NULL;
   1724 }
   1725 
   1726 #define PACK_SINGLE(ptr, src, type) \
   1727     do {                                     \
   1728         type x;                              \
   1729         x = (type)src;                       \
   1730         memcpy(ptr, (char *)&x, sizeof x);   \
   1731     } while (0)
   1732 
   1733 /* Pack a single item. 'fmt' can be any native format character in
   1734    struct module syntax. */
   1735 static int
   1736 pack_single(char *ptr, PyObject *item, const char *fmt)
   1737 {
   1738     unsigned long long llu;
   1739     unsigned long lu;
   1740     size_t zu;
   1741     long long lld;
   1742     long ld;
   1743     Py_ssize_t zd;
   1744     double d;
   1745     void *p;
   1746 
   1747     switch (fmt[0]) {
   1748     /* signed integers */
   1749     case 'b': case 'h': case 'i': case 'l':
   1750         ld = pylong_as_ld(item);
   1751         if (ld == -1 && PyErr_Occurred())
   1752             goto err_occurred;
   1753         switch (fmt[0]) {
   1754         case 'b':
   1755             if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
   1756             *((signed char *)ptr) = (signed char)ld; break;
   1757         case 'h':
   1758             if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
   1759             PACK_SINGLE(ptr, ld, short); break;
   1760         case 'i':
   1761             if (ld < INT_MIN || ld > INT_MAX) goto err_range;
   1762             PACK_SINGLE(ptr, ld, int); break;
   1763         default: /* 'l' */
   1764             PACK_SINGLE(ptr, ld, long); break;
   1765         }
   1766         break;
   1767 
   1768     /* unsigned integers */
   1769     case 'B': case 'H': case 'I': case 'L':
   1770         lu = pylong_as_lu(item);
   1771         if (lu == (unsigned long)-1 && PyErr_Occurred())
   1772             goto err_occurred;
   1773         switch (fmt[0]) {
   1774         case 'B':
   1775             if (lu > UCHAR_MAX) goto err_range;
   1776             *((unsigned char *)ptr) = (unsigned char)lu; break;
   1777         case 'H':
   1778             if (lu > USHRT_MAX) goto err_range;
   1779             PACK_SINGLE(ptr, lu, unsigned short); break;
   1780         case 'I':
   1781             if (lu > UINT_MAX) goto err_range;
   1782             PACK_SINGLE(ptr, lu, unsigned int); break;
   1783         default: /* 'L' */
   1784             PACK_SINGLE(ptr, lu, unsigned long); break;
   1785         }
   1786         break;
   1787 
   1788     /* native 64-bit */
   1789     case 'q':
   1790         lld = pylong_as_lld(item);
   1791         if (lld == -1 && PyErr_Occurred())
   1792             goto err_occurred;
   1793         PACK_SINGLE(ptr, lld, long long);
   1794         break;
   1795     case 'Q':
   1796         llu = pylong_as_llu(item);
   1797         if (llu == (unsigned long long)-1 && PyErr_Occurred())
   1798             goto err_occurred;
   1799         PACK_SINGLE(ptr, llu, unsigned long long);
   1800         break;
   1801 
   1802     /* ssize_t and size_t */
   1803     case 'n':
   1804         zd = pylong_as_zd(item);
   1805         if (zd == -1 && PyErr_Occurred())
   1806             goto err_occurred;
   1807         PACK_SINGLE(ptr, zd, Py_ssize_t);
   1808         break;
   1809     case 'N':
   1810         zu = pylong_as_zu(item);
   1811         if (zu == (size_t)-1 && PyErr_Occurred())
   1812             goto err_occurred;
   1813         PACK_SINGLE(ptr, zu, size_t);
   1814         break;
   1815 
   1816     /* floats */
   1817     case 'f': case 'd':
   1818         d = PyFloat_AsDouble(item);
   1819         if (d == -1.0 && PyErr_Occurred())
   1820             goto err_occurred;
   1821         if (fmt[0] == 'f') {
   1822             PACK_SINGLE(ptr, d, float);
   1823         }
   1824         else {
   1825             PACK_SINGLE(ptr, d, double);
   1826         }
   1827         break;
   1828 
   1829     /* bool */
   1830     case '?':
   1831         ld = PyObject_IsTrue(item);
   1832         if (ld < 0)
   1833             return -1; /* preserve original error */
   1834         PACK_SINGLE(ptr, ld, _Bool);
   1835          break;
   1836 
   1837     /* bytes object */
   1838     case 'c':
   1839         if (!PyBytes_Check(item))
   1840             return type_error_int(fmt);
   1841         if (PyBytes_GET_SIZE(item) != 1)
   1842             return value_error_int(fmt);
   1843         *ptr = PyBytes_AS_STRING(item)[0];
   1844         break;
   1845 
   1846     /* pointer */
   1847     case 'P':
   1848         p = PyLong_AsVoidPtr(item);
   1849         if (p == NULL && PyErr_Occurred())
   1850             goto err_occurred;
   1851         PACK_SINGLE(ptr, p, void *);
   1852         break;
   1853 
   1854     /* default */
   1855     default: goto err_format;
   1856     }
   1857 
   1858     return 0;
   1859 
   1860 err_occurred:
   1861     return fix_error_int(fmt);
   1862 err_range:
   1863     return value_error_int(fmt);
   1864 err_format:
   1865     PyErr_Format(PyExc_NotImplementedError,
   1866         "memoryview: format %s not supported", fmt);
   1867     return -1;
   1868 }
   1869 
   1870 
   1871 /****************************************************************************/
   1872 /*                       unpack using the struct module                     */
   1873 /****************************************************************************/
   1874 
   1875 /* For reasonable performance it is necessary to cache all objects required
   1876    for unpacking. An unpacker can handle the format passed to unpack_from().
   1877    Invariant: All pointer fields of the struct should either be NULL or valid
   1878    pointers. */
   1879 struct unpacker {
   1880     PyObject *unpack_from; /* Struct.unpack_from(format) */
   1881     PyObject *mview;       /* cached memoryview */
   1882     char *item;            /* buffer for mview */
   1883     Py_ssize_t itemsize;   /* len(item) */
   1884 };
   1885 
   1886 static struct unpacker *
   1887 unpacker_new(void)
   1888 {
   1889     struct unpacker *x = PyMem_Malloc(sizeof *x);
   1890 
   1891     if (x == NULL) {
   1892         PyErr_NoMemory();
   1893         return NULL;
   1894     }
   1895 
   1896     x->unpack_from = NULL;
   1897     x->mview = NULL;
   1898     x->item = NULL;
   1899     x->itemsize = 0;
   1900 
   1901     return x;
   1902 }
   1903 
   1904 static void
   1905 unpacker_free(struct unpacker *x)
   1906 {
   1907     if (x) {
   1908         Py_XDECREF(x->unpack_from);
   1909         Py_XDECREF(x->mview);
   1910         PyMem_Free(x->item);
   1911         PyMem_Free(x);
   1912     }
   1913 }
   1914 
   1915 /* Return a new unpacker for the given format. */
   1916 static struct unpacker *
   1917 struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
   1918 {
   1919     PyObject *structmodule;     /* XXX cache these two */
   1920     PyObject *Struct = NULL;    /* XXX in globals?     */
   1921     PyObject *structobj = NULL;
   1922     PyObject *format = NULL;
   1923     struct unpacker *x = NULL;
   1924 
   1925     structmodule = PyImport_ImportModule("struct");
   1926     if (structmodule == NULL)
   1927         return NULL;
   1928 
   1929     Struct = PyObject_GetAttrString(structmodule, "Struct");
   1930     Py_DECREF(structmodule);
   1931     if (Struct == NULL)
   1932         return NULL;
   1933 
   1934     x = unpacker_new();
   1935     if (x == NULL)
   1936         goto error;
   1937 
   1938     format = PyBytes_FromString(fmt);
   1939     if (format == NULL)
   1940         goto error;
   1941 
   1942     structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
   1943     if (structobj == NULL)
   1944         goto error;
   1945 
   1946     x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
   1947     if (x->unpack_from == NULL)
   1948         goto error;
   1949 
   1950     x->item = PyMem_Malloc(itemsize);
   1951     if (x->item == NULL) {
   1952         PyErr_NoMemory();
   1953         goto error;
   1954     }
   1955     x->itemsize = itemsize;
   1956 
   1957     x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
   1958     if (x->mview == NULL)
   1959         goto error;
   1960 
   1961 
   1962 out:
   1963     Py_XDECREF(Struct);
   1964     Py_XDECREF(format);
   1965     Py_XDECREF(structobj);
   1966     return x;
   1967 
   1968 error:
   1969     unpacker_free(x);
   1970     x = NULL;
   1971     goto out;
   1972 }
   1973 
   1974 /* unpack a single item */
   1975 static PyObject *
   1976 struct_unpack_single(const char *ptr, struct unpacker *x)
   1977 {
   1978     PyObject *v;
   1979 
   1980     memcpy(x->item, ptr, x->itemsize);
   1981     v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL);
   1982     if (v == NULL)
   1983         return NULL;
   1984 
   1985     if (PyTuple_GET_SIZE(v) == 1) {
   1986         PyObject *tmp = PyTuple_GET_ITEM(v, 0);
   1987         Py_INCREF(tmp);
   1988         Py_DECREF(v);
   1989         return tmp;
   1990     }
   1991 
   1992     return v;
   1993 }
   1994 
   1995 
   1996 /****************************************************************************/
   1997 /*                              Representations                             */
   1998 /****************************************************************************/
   1999 
   2000 /* allow explicit form of native format */
   2001 static inline const char *
   2002 adjust_fmt(const Py_buffer *view)
   2003 {
   2004     const char *fmt;
   2005 
   2006     fmt = (view->format[0] == '@') ? view->format+1 : view->format;
   2007     if (fmt[0] && fmt[1] == '\0')
   2008         return fmt;
   2009 
   2010     PyErr_Format(PyExc_NotImplementedError,
   2011         "memoryview: unsupported format %s", view->format);
   2012     return NULL;
   2013 }
   2014 
   2015 /* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
   2016 static PyObject *
   2017 tolist_base(const char *ptr, const Py_ssize_t *shape,
   2018             const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
   2019             const char *fmt)
   2020 {
   2021     PyObject *lst, *item;
   2022     Py_ssize_t i;
   2023 
   2024     lst = PyList_New(shape[0]);
   2025     if (lst == NULL)
   2026         return NULL;
   2027 
   2028     for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
   2029         const char *xptr = ADJUST_PTR(ptr, suboffsets, 0);
   2030         item = unpack_single(xptr, fmt);
   2031         if (item == NULL) {
   2032             Py_DECREF(lst);
   2033             return NULL;
   2034         }
   2035         PyList_SET_ITEM(lst, i, item);
   2036     }
   2037 
   2038     return lst;
   2039 }
   2040 
   2041 /* Unpack a multi-dimensional array into a nested list.
   2042    Assumption: ndim >= 1. */
   2043 static PyObject *
   2044 tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
   2045            const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
   2046            const char *fmt)
   2047 {
   2048     PyObject *lst, *item;
   2049     Py_ssize_t i;
   2050 
   2051     assert(ndim >= 1);
   2052     assert(shape != NULL);
   2053     assert(strides != NULL);
   2054 
   2055     if (ndim == 1)
   2056         return tolist_base(ptr, shape, strides, suboffsets, fmt);
   2057 
   2058     lst = PyList_New(shape[0]);
   2059     if (lst == NULL)
   2060         return NULL;
   2061 
   2062     for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
   2063         const char *xptr = ADJUST_PTR(ptr, suboffsets, 0);
   2064         item = tolist_rec(xptr, ndim-1, shape+1,
   2065                           strides+1, suboffsets ? suboffsets+1 : NULL,
   2066                           fmt);
   2067         if (item == NULL) {
   2068             Py_DECREF(lst);
   2069             return NULL;
   2070         }
   2071         PyList_SET_ITEM(lst, i, item);
   2072     }
   2073 
   2074     return lst;
   2075 }
   2076 
   2077 /* Return a list representation of the memoryview. Currently only buffers
   2078    with native format strings are supported. */
   2079 static PyObject *
   2080 memory_tolist(PyMemoryViewObject *mv, PyObject *noargs)
   2081 {
   2082     const Py_buffer *view = &(mv->view);
   2083     const char *fmt;
   2084 
   2085     CHECK_RELEASED(mv);
   2086 
   2087     fmt = adjust_fmt(view);
   2088     if (fmt == NULL)
   2089         return NULL;
   2090     if (view->ndim == 0) {
   2091         return unpack_single(view->buf, fmt);
   2092     }
   2093     else if (view->ndim == 1) {
   2094         return tolist_base(view->buf, view->shape,
   2095                            view->strides, view->suboffsets,
   2096                            fmt);
   2097     }
   2098     else {
   2099         return tolist_rec(view->buf, view->ndim, view->shape,
   2100                           view->strides, view->suboffsets,
   2101                           fmt);
   2102     }
   2103 }
   2104 
   2105 static PyObject *
   2106 memory_tobytes(PyMemoryViewObject *self, PyObject *dummy)
   2107 {
   2108     Py_buffer *src = VIEW_ADDR(self);
   2109     PyObject *bytes = NULL;
   2110 
   2111     CHECK_RELEASED(self);
   2112 
   2113     if (MV_C_CONTIGUOUS(self->flags)) {
   2114         return PyBytes_FromStringAndSize(src->buf, src->len);
   2115     }
   2116 
   2117     bytes = PyBytes_FromStringAndSize(NULL, src->len);
   2118     if (bytes == NULL)
   2119         return NULL;
   2120 
   2121     if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) {
   2122         Py_DECREF(bytes);
   2123         return NULL;
   2124     }
   2125 
   2126     return bytes;
   2127 }
   2128 
   2129 static PyObject *
   2130 memory_hex(PyMemoryViewObject *self, PyObject *dummy)
   2131 {
   2132     Py_buffer *src = VIEW_ADDR(self);
   2133     PyObject *bytes;
   2134     PyObject *ret;
   2135 
   2136     CHECK_RELEASED(self);
   2137 
   2138     if (MV_C_CONTIGUOUS(self->flags)) {
   2139         return _Py_strhex(src->buf, src->len);
   2140     }
   2141 
   2142     bytes = memory_tobytes(self, dummy);
   2143     if (bytes == NULL)
   2144         return NULL;
   2145 
   2146     ret = _Py_strhex(PyBytes_AS_STRING(bytes), Py_SIZE(bytes));
   2147     Py_DECREF(bytes);
   2148 
   2149     return ret;
   2150 }
   2151 
   2152 static PyObject *
   2153 memory_repr(PyMemoryViewObject *self)
   2154 {
   2155     if (self->flags & _Py_MEMORYVIEW_RELEASED)
   2156         return PyUnicode_FromFormat("<released memory at %p>", self);
   2157     else
   2158         return PyUnicode_FromFormat("<memory at %p>", self);
   2159 }
   2160 
   2161 
   2162 /**************************************************************************/
   2163 /*                          Indexing and slicing                          */
   2164 /**************************************************************************/
   2165 
   2166 static char *
   2167 lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index)
   2168 {
   2169     Py_ssize_t nitems; /* items in the given dimension */
   2170 
   2171     assert(view->shape);
   2172     assert(view->strides);
   2173 
   2174     nitems = view->shape[dim];
   2175     if (index < 0) {
   2176         index += nitems;
   2177     }
   2178     if (index < 0 || index >= nitems) {
   2179         PyErr_Format(PyExc_IndexError,
   2180                      "index out of bounds on dimension %d", dim + 1);
   2181         return NULL;
   2182     }
   2183 
   2184     ptr += view->strides[dim] * index;
   2185 
   2186     ptr = ADJUST_PTR(ptr, view->suboffsets, dim);
   2187 
   2188     return ptr;
   2189 }
   2190 
   2191 /* Get the pointer to the item at index. */
   2192 static char *
   2193 ptr_from_index(Py_buffer *view, Py_ssize_t index)
   2194 {
   2195     char *ptr = (char *)view->buf;
   2196     return lookup_dimension(view, ptr, 0, index);
   2197 }
   2198 
   2199 /* Get the pointer to the item at tuple. */
   2200 static char *
   2201 ptr_from_tuple(Py_buffer *view, PyObject *tup)
   2202 {
   2203     char *ptr = (char *)view->buf;
   2204     Py_ssize_t dim, nindices = PyTuple_GET_SIZE(tup);
   2205 
   2206     if (nindices > view->ndim) {
   2207         PyErr_Format(PyExc_TypeError,
   2208                      "cannot index %zd-dimension view with %zd-element tuple",
   2209                      view->ndim, nindices);
   2210         return NULL;
   2211     }
   2212 
   2213     for (dim = 0; dim < nindices; dim++) {
   2214         Py_ssize_t index;
   2215         index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, dim),
   2216                                    PyExc_IndexError);
   2217         if (index == -1 && PyErr_Occurred())
   2218             return NULL;
   2219         ptr = lookup_dimension(view, ptr, (int)dim, index);
   2220         if (ptr == NULL)
   2221             return NULL;
   2222     }
   2223     return ptr;
   2224 }
   2225 
   2226 /* Return the item at index. In a one-dimensional view, this is an object
   2227    with the type specified by view->format. Otherwise, the item is a sub-view.
   2228    The function is used in memory_subscript() and memory_as_sequence. */
   2229 static PyObject *
   2230 memory_item(PyMemoryViewObject *self, Py_ssize_t index)
   2231 {
   2232     Py_buffer *view = &(self->view);
   2233     const char *fmt;
   2234 
   2235     CHECK_RELEASED(self);
   2236 
   2237     fmt = adjust_fmt(view);
   2238     if (fmt == NULL)
   2239         return NULL;
   2240 
   2241     if (view->ndim == 0) {
   2242         PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
   2243         return NULL;
   2244     }
   2245     if (view->ndim == 1) {
   2246         char *ptr = ptr_from_index(view, index);
   2247         if (ptr == NULL)
   2248             return NULL;
   2249         return unpack_single(ptr, fmt);
   2250     }
   2251 
   2252     PyErr_SetString(PyExc_NotImplementedError,
   2253         "multi-dimensional sub-views are not implemented");
   2254     return NULL;
   2255 }
   2256 
   2257 /* Return the item at position *key* (a tuple of indices). */
   2258 static PyObject *
   2259 memory_item_multi(PyMemoryViewObject *self, PyObject *tup)
   2260 {
   2261     Py_buffer *view = &(self->view);
   2262     const char *fmt;
   2263     Py_ssize_t nindices = PyTuple_GET_SIZE(tup);
   2264     char *ptr;
   2265 
   2266     CHECK_RELEASED(self);
   2267 
   2268     fmt = adjust_fmt(view);
   2269     if (fmt == NULL)
   2270         return NULL;
   2271 
   2272     if (nindices < view->ndim) {
   2273         PyErr_SetString(PyExc_NotImplementedError,
   2274                         "sub-views are not implemented");
   2275         return NULL;
   2276     }
   2277     ptr = ptr_from_tuple(view, tup);
   2278     if (ptr == NULL)
   2279         return NULL;
   2280     return unpack_single(ptr, fmt);
   2281 }
   2282 
   2283 static inline int
   2284 init_slice(Py_buffer *base, PyObject *key, int dim)
   2285 {
   2286     Py_ssize_t start, stop, step, slicelength;
   2287 
   2288     if (PySlice_GetIndicesEx(key, base->shape[dim],
   2289                              &start, &stop, &step, &slicelength) < 0) {
   2290         return -1;
   2291     }
   2292 
   2293 
   2294     if (base->suboffsets == NULL || dim == 0) {
   2295     adjust_buf:
   2296         base->buf = (char *)base->buf + base->strides[dim] * start;
   2297     }
   2298     else {
   2299         Py_ssize_t n = dim-1;
   2300         while (n >= 0 && base->suboffsets[n] < 0)
   2301             n--;
   2302         if (n < 0)
   2303             goto adjust_buf; /* all suboffsets are negative */
   2304         base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
   2305     }
   2306     base->shape[dim] = slicelength;
   2307     base->strides[dim] = base->strides[dim] * step;
   2308 
   2309     return 0;
   2310 }
   2311 
   2312 static int
   2313 is_multislice(PyObject *key)
   2314 {
   2315     Py_ssize_t size, i;
   2316 
   2317     if (!PyTuple_Check(key))
   2318         return 0;
   2319     size = PyTuple_GET_SIZE(key);
   2320     if (size == 0)
   2321         return 0;
   2322 
   2323     for (i = 0; i < size; i++) {
   2324         PyObject *x = PyTuple_GET_ITEM(key, i);
   2325         if (!PySlice_Check(x))
   2326             return 0;
   2327     }
   2328     return 1;
   2329 }
   2330 
   2331 static Py_ssize_t
   2332 is_multiindex(PyObject *key)
   2333 {
   2334     Py_ssize_t size, i;
   2335 
   2336     if (!PyTuple_Check(key))
   2337         return 0;
   2338     size = PyTuple_GET_SIZE(key);
   2339     for (i = 0; i < size; i++) {
   2340         PyObject *x = PyTuple_GET_ITEM(key, i);
   2341         if (!PyIndex_Check(x))
   2342             return 0;
   2343     }
   2344     return 1;
   2345 }
   2346 
   2347 /* mv[obj] returns an object holding the data for one element if obj
   2348    fully indexes the memoryview or another memoryview object if it
   2349    does not.
   2350 
   2351    0-d memoryview objects can be referenced using mv[...] or mv[()]
   2352    but not with anything else. */
   2353 static PyObject *
   2354 memory_subscript(PyMemoryViewObject *self, PyObject *key)
   2355 {
   2356     Py_buffer *view;
   2357     view = &(self->view);
   2358 
   2359     CHECK_RELEASED(self);
   2360 
   2361     if (view->ndim == 0) {
   2362         if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
   2363             const char *fmt = adjust_fmt(view);
   2364             if (fmt == NULL)
   2365                 return NULL;
   2366             return unpack_single(view->buf, fmt);
   2367         }
   2368         else if (key == Py_Ellipsis) {
   2369             Py_INCREF(self);
   2370             return (PyObject *)self;
   2371         }
   2372         else {
   2373             PyErr_SetString(PyExc_TypeError,
   2374                 "invalid indexing of 0-dim memory");
   2375             return NULL;
   2376         }
   2377     }
   2378 
   2379     if (PyIndex_Check(key)) {
   2380         Py_ssize_t index;
   2381         index = PyNumber_AsSsize_t(key, PyExc_IndexError);
   2382         if (index == -1 && PyErr_Occurred())
   2383             return NULL;
   2384         return memory_item(self, index);
   2385     }
   2386     else if (PySlice_Check(key)) {
   2387         PyMemoryViewObject *sliced;
   2388 
   2389         sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
   2390         if (sliced == NULL)
   2391             return NULL;
   2392 
   2393         if (init_slice(&sliced->view, key, 0) < 0) {
   2394             Py_DECREF(sliced);
   2395             return NULL;
   2396         }
   2397         init_len(&sliced->view);
   2398         init_flags(sliced);
   2399 
   2400         return (PyObject *)sliced;
   2401     }
   2402     else if (is_multiindex(key)) {
   2403         return memory_item_multi(self, key);
   2404     }
   2405     else if (is_multislice(key)) {
   2406         PyErr_SetString(PyExc_NotImplementedError,
   2407             "multi-dimensional slicing is not implemented");
   2408         return NULL;
   2409     }
   2410 
   2411     PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
   2412     return NULL;
   2413 }
   2414 
   2415 static int
   2416 memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
   2417 {
   2418     Py_buffer *view = &(self->view);
   2419     Py_buffer src;
   2420     const char *fmt;
   2421     char *ptr;
   2422 
   2423     CHECK_RELEASED_INT(self);
   2424 
   2425     fmt = adjust_fmt(view);
   2426     if (fmt == NULL)
   2427         return -1;
   2428 
   2429     if (view->readonly) {
   2430         PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
   2431         return -1;
   2432     }
   2433     if (value == NULL) {
   2434         PyErr_SetString(PyExc_TypeError, "cannot delete memory");
   2435         return -1;
   2436     }
   2437     if (view->ndim == 0) {
   2438         if (key == Py_Ellipsis ||
   2439             (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
   2440             ptr = (char *)view->buf;
   2441             return pack_single(ptr, value, fmt);
   2442         }
   2443         else {
   2444             PyErr_SetString(PyExc_TypeError,
   2445                 "invalid indexing of 0-dim memory");
   2446             return -1;
   2447         }
   2448     }
   2449 
   2450     if (PyIndex_Check(key)) {
   2451         Py_ssize_t index;
   2452         if (1 < view->ndim) {
   2453             PyErr_SetString(PyExc_NotImplementedError,
   2454                             "sub-views are not implemented");
   2455             return -1;
   2456         }
   2457         index = PyNumber_AsSsize_t(key, PyExc_IndexError);
   2458         if (index == -1 && PyErr_Occurred())
   2459             return -1;
   2460         ptr = ptr_from_index(view, index);
   2461         if (ptr == NULL)
   2462             return -1;
   2463         return pack_single(ptr, value, fmt);
   2464     }
   2465     /* one-dimensional: fast path */
   2466     if (PySlice_Check(key) && view->ndim == 1) {
   2467         Py_buffer dest; /* sliced view */
   2468         Py_ssize_t arrays[3];
   2469         int ret = -1;
   2470 
   2471         /* rvalue must be an exporter */
   2472         if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
   2473             return ret;
   2474 
   2475         dest = *view;
   2476         dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
   2477         dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
   2478         if (view->suboffsets) {
   2479             dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
   2480         }
   2481 
   2482         if (init_slice(&dest, key, 0) < 0)
   2483             goto end_block;
   2484         dest.len = dest.shape[0] * dest.itemsize;
   2485 
   2486         ret = copy_single(&dest, &src);
   2487 
   2488     end_block:
   2489         PyBuffer_Release(&src);
   2490         return ret;
   2491     }
   2492     if (is_multiindex(key)) {
   2493         char *ptr;
   2494         if (PyTuple_GET_SIZE(key) < view->ndim) {
   2495             PyErr_SetString(PyExc_NotImplementedError,
   2496                             "sub-views are not implemented");
   2497             return -1;
   2498         }
   2499         ptr = ptr_from_tuple(view, key);
   2500         if (ptr == NULL)
   2501             return -1;
   2502         return pack_single(ptr, value, fmt);
   2503     }
   2504     if (PySlice_Check(key) || is_multislice(key)) {
   2505         /* Call memory_subscript() to produce a sliced lvalue, then copy
   2506            rvalue into lvalue. This is already implemented in _testbuffer.c. */
   2507         PyErr_SetString(PyExc_NotImplementedError,
   2508             "memoryview slice assignments are currently restricted "
   2509             "to ndim = 1");
   2510         return -1;
   2511     }
   2512 
   2513     PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
   2514     return -1;
   2515 }
   2516 
   2517 static Py_ssize_t
   2518 memory_length(PyMemoryViewObject *self)
   2519 {
   2520     CHECK_RELEASED_INT(self);
   2521     return self->view.ndim == 0 ? 1 : self->view.shape[0];
   2522 }
   2523 
   2524 /* As mapping */
   2525 static PyMappingMethods memory_as_mapping = {
   2526     (lenfunc)memory_length,               /* mp_length */
   2527     (binaryfunc)memory_subscript,         /* mp_subscript */
   2528     (objobjargproc)memory_ass_sub,        /* mp_ass_subscript */
   2529 };
   2530 
   2531 /* As sequence */
   2532 static PySequenceMethods memory_as_sequence = {
   2533         (lenfunc)memory_length,           /* sq_length */
   2534         0,                                /* sq_concat */
   2535         0,                                /* sq_repeat */
   2536         (ssizeargfunc)memory_item,        /* sq_item */
   2537 };
   2538 
   2539 
   2540 /**************************************************************************/
   2541 /*                             Comparisons                                */
   2542 /**************************************************************************/
   2543 
   2544 #define MV_COMPARE_EX -1       /* exception */
   2545 #define MV_COMPARE_NOT_IMPL -2 /* not implemented */
   2546 
   2547 /* Translate a StructError to "not equal". Preserve other exceptions. */
   2548 static int
   2549 fix_struct_error_int(void)
   2550 {
   2551     assert(PyErr_Occurred());
   2552     /* XXX Cannot get at StructError directly? */
   2553     if (PyErr_ExceptionMatches(PyExc_ImportError) ||
   2554         PyErr_ExceptionMatches(PyExc_MemoryError)) {
   2555         return MV_COMPARE_EX;
   2556     }
   2557     /* StructError: invalid or unknown format -> not equal */
   2558     PyErr_Clear();
   2559     return 0;
   2560 }
   2561 
   2562 /* Unpack and compare single items of p and q using the struct module. */
   2563 static int
   2564 struct_unpack_cmp(const char *p, const char *q,
   2565                   struct unpacker *unpack_p, struct unpacker *unpack_q)
   2566 {
   2567     PyObject *v, *w;
   2568     int ret;
   2569 
   2570     /* At this point any exception from the struct module should not be
   2571        StructError, since both formats have been accepted already. */
   2572     v = struct_unpack_single(p, unpack_p);
   2573     if (v == NULL)
   2574         return MV_COMPARE_EX;
   2575 
   2576     w = struct_unpack_single(q, unpack_q);
   2577     if (w == NULL) {
   2578         Py_DECREF(v);
   2579         return MV_COMPARE_EX;
   2580     }
   2581 
   2582     /* MV_COMPARE_EX == -1: exceptions are preserved */
   2583     ret = PyObject_RichCompareBool(v, w, Py_EQ);
   2584     Py_DECREF(v);
   2585     Py_DECREF(w);
   2586 
   2587     return ret;
   2588 }
   2589 
   2590 /* Unpack and compare single items of p and q. If both p and q have the same
   2591    single element native format, the comparison uses a fast path (gcc creates
   2592    a jump table and converts memcpy into simple assignments on x86/x64).
   2593 
   2594    Otherwise, the comparison is delegated to the struct module, which is
   2595    30-60x slower. */
   2596 #define CMP_SINGLE(p, q, type) \
   2597     do {                                 \
   2598         type x;                          \
   2599         type y;                          \
   2600         memcpy((char *)&x, p, sizeof x); \
   2601         memcpy((char *)&y, q, sizeof y); \
   2602         equal = (x == y);                \
   2603     } while (0)
   2604 
   2605 static inline int
   2606 unpack_cmp(const char *p, const char *q, char fmt,
   2607            struct unpacker *unpack_p, struct unpacker *unpack_q)
   2608 {
   2609     int equal;
   2610 
   2611     switch (fmt) {
   2612 
   2613     /* signed integers and fast path for 'B' */
   2614     case 'B': return *((unsigned char *)p) == *((unsigned char *)q);
   2615     case 'b': return *((signed char *)p) == *((signed char *)q);
   2616     case 'h': CMP_SINGLE(p, q, short); return equal;
   2617     case 'i': CMP_SINGLE(p, q, int); return equal;
   2618     case 'l': CMP_SINGLE(p, q, long); return equal;
   2619 
   2620     /* boolean */
   2621     case '?': CMP_SINGLE(p, q, _Bool); return equal;
   2622 
   2623     /* unsigned integers */
   2624     case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
   2625     case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
   2626     case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
   2627 
   2628     /* native 64-bit */
   2629     case 'q': CMP_SINGLE(p, q, long long); return equal;
   2630     case 'Q': CMP_SINGLE(p, q, unsigned long long); return equal;
   2631 
   2632     /* ssize_t and size_t */
   2633     case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
   2634     case 'N': CMP_SINGLE(p, q, size_t); return equal;
   2635 
   2636     /* floats */
   2637     /* XXX DBL_EPSILON? */
   2638     case 'f': CMP_SINGLE(p, q, float); return equal;
   2639     case 'd': CMP_SINGLE(p, q, double); return equal;
   2640 
   2641     /* bytes object */
   2642     case 'c': return *p == *q;
   2643 
   2644     /* pointer */
   2645     case 'P': CMP_SINGLE(p, q, void *); return equal;
   2646 
   2647     /* use the struct module */
   2648     case '_':
   2649         assert(unpack_p);
   2650         assert(unpack_q);
   2651         return struct_unpack_cmp(p, q, unpack_p, unpack_q);
   2652     }
   2653 
   2654     /* NOT REACHED */
   2655     PyErr_SetString(PyExc_RuntimeError,
   2656         "memoryview: internal error in richcompare");
   2657     return MV_COMPARE_EX;
   2658 }
   2659 
   2660 /* Base case for recursive array comparisons. Assumption: ndim == 1. */
   2661 static int
   2662 cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
   2663          const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
   2664          const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
   2665          char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
   2666 {
   2667     Py_ssize_t i;
   2668     int equal;
   2669 
   2670     for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
   2671         const char *xp = ADJUST_PTR(p, psuboffsets, 0);
   2672         const char *xq = ADJUST_PTR(q, qsuboffsets, 0);
   2673         equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
   2674         if (equal <= 0)
   2675             return equal;
   2676     }
   2677 
   2678     return 1;
   2679 }
   2680 
   2681 /* Recursively compare two multi-dimensional arrays that have the same
   2682    logical structure. Assumption: ndim >= 1. */
   2683 static int
   2684 cmp_rec(const char *p, const char *q,
   2685         Py_ssize_t ndim, const Py_ssize_t *shape,
   2686         const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
   2687         const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
   2688         char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
   2689 {
   2690     Py_ssize_t i;
   2691     int equal;
   2692 
   2693     assert(ndim >= 1);
   2694     assert(shape != NULL);
   2695     assert(pstrides != NULL);
   2696     assert(qstrides != NULL);
   2697 
   2698     if (ndim == 1) {
   2699         return cmp_base(p, q, shape,
   2700                         pstrides, psuboffsets,
   2701                         qstrides, qsuboffsets,
   2702                         fmt, unpack_p, unpack_q);
   2703     }
   2704 
   2705     for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
   2706         const char *xp = ADJUST_PTR(p, psuboffsets, 0);
   2707         const char *xq = ADJUST_PTR(q, qsuboffsets, 0);
   2708         equal = cmp_rec(xp, xq, ndim-1, shape+1,
   2709                         pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
   2710                         qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
   2711                         fmt, unpack_p, unpack_q);
   2712         if (equal <= 0)
   2713             return equal;
   2714     }
   2715 
   2716     return 1;
   2717 }
   2718 
   2719 static PyObject *
   2720 memory_richcompare(PyObject *v, PyObject *w, int op)
   2721 {
   2722     PyObject *res;
   2723     Py_buffer wbuf, *vv;
   2724     Py_buffer *ww = NULL;
   2725     struct unpacker *unpack_v = NULL;
   2726     struct unpacker *unpack_w = NULL;
   2727     char vfmt, wfmt;
   2728     int equal = MV_COMPARE_NOT_IMPL;
   2729 
   2730     if (op != Py_EQ && op != Py_NE)
   2731         goto result; /* Py_NotImplemented */
   2732 
   2733     assert(PyMemoryView_Check(v));
   2734     if (BASE_INACCESSIBLE(v)) {
   2735         equal = (v == w);
   2736         goto result;
   2737     }
   2738     vv = VIEW_ADDR(v);
   2739 
   2740     if (PyMemoryView_Check(w)) {
   2741         if (BASE_INACCESSIBLE(w)) {
   2742             equal = (v == w);
   2743             goto result;
   2744         }
   2745         ww = VIEW_ADDR(w);
   2746     }
   2747     else {
   2748         if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
   2749             PyErr_Clear();
   2750             goto result; /* Py_NotImplemented */
   2751         }
   2752         ww = &wbuf;
   2753     }
   2754 
   2755     if (!equiv_shape(vv, ww)) {
   2756         PyErr_Clear();
   2757         equal = 0;
   2758         goto result;
   2759     }
   2760 
   2761     /* Use fast unpacking for identical primitive C type formats. */
   2762     if (get_native_fmtchar(&vfmt, vv->format) < 0)
   2763         vfmt = '_';
   2764     if (get_native_fmtchar(&wfmt, ww->format) < 0)
   2765         wfmt = '_';
   2766     if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
   2767         /* Use struct module unpacking. NOTE: Even for equal format strings,
   2768            memcmp() cannot be used for item comparison since it would give
   2769            incorrect results in the case of NaNs or uninitialized padding
   2770            bytes. */
   2771         vfmt = '_';
   2772         unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
   2773         if (unpack_v == NULL) {
   2774             equal = fix_struct_error_int();
   2775             goto result;
   2776         }
   2777         unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
   2778         if (unpack_w == NULL) {
   2779             equal = fix_struct_error_int();
   2780             goto result;
   2781         }
   2782     }
   2783 
   2784     if (vv->ndim == 0) {
   2785         equal = unpack_cmp(vv->buf, ww->buf,
   2786                            vfmt, unpack_v, unpack_w);
   2787     }
   2788     else if (vv->ndim == 1) {
   2789         equal = cmp_base(vv->buf, ww->buf, vv->shape,
   2790                          vv->strides, vv->suboffsets,
   2791                          ww->strides, ww->suboffsets,
   2792                          vfmt, unpack_v, unpack_w);
   2793     }
   2794     else {
   2795         equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
   2796                         vv->strides, vv->suboffsets,
   2797                         ww->strides, ww->suboffsets,
   2798                         vfmt, unpack_v, unpack_w);
   2799     }
   2800 
   2801 result:
   2802     if (equal < 0) {
   2803         if (equal == MV_COMPARE_NOT_IMPL)
   2804             res = Py_NotImplemented;
   2805         else /* exception */
   2806             res = NULL;
   2807     }
   2808     else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
   2809         res = Py_True;
   2810     else
   2811         res = Py_False;
   2812 
   2813     if (ww == &wbuf)
   2814         PyBuffer_Release(ww);
   2815 
   2816     unpacker_free(unpack_v);
   2817     unpacker_free(unpack_w);
   2818 
   2819     Py_XINCREF(res);
   2820     return res;
   2821 }
   2822 
   2823 /**************************************************************************/
   2824 /*                                Hash                                    */
   2825 /**************************************************************************/
   2826 
   2827 static Py_hash_t
   2828 memory_hash(PyMemoryViewObject *self)
   2829 {
   2830     if (self->hash == -1) {
   2831         Py_buffer *view = &self->view;
   2832         char *mem = view->buf;
   2833         Py_ssize_t ret;
   2834         char fmt;
   2835 
   2836         CHECK_RELEASED_INT(self);
   2837 
   2838         if (!view->readonly) {
   2839             PyErr_SetString(PyExc_ValueError,
   2840                 "cannot hash writable memoryview object");
   2841             return -1;
   2842         }
   2843         ret = get_native_fmtchar(&fmt, view->format);
   2844         if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
   2845             PyErr_SetString(PyExc_ValueError,
   2846                 "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
   2847             return -1;
   2848         }
   2849         if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
   2850             /* Keep the original error message */
   2851             return -1;
   2852         }
   2853 
   2854         if (!MV_C_CONTIGUOUS(self->flags)) {
   2855             mem = PyMem_Malloc(view->len);
   2856             if (mem == NULL) {
   2857                 PyErr_NoMemory();
   2858                 return -1;
   2859             }
   2860             if (buffer_to_contiguous(mem, view, 'C') < 0) {
   2861                 PyMem_Free(mem);
   2862                 return -1;
   2863             }
   2864         }
   2865 
   2866         /* Can't fail */
   2867         self->hash = _Py_HashBytes(mem, view->len);
   2868 
   2869         if (mem != view->buf)
   2870             PyMem_Free(mem);
   2871     }
   2872 
   2873     return self->hash;
   2874 }
   2875 
   2876 
   2877 /**************************************************************************/
   2878 /*                                 getters                                */
   2879 /**************************************************************************/
   2880 
   2881 static PyObject *
   2882 _IntTupleFromSsizet(int len, Py_ssize_t *vals)
   2883 {
   2884     int i;
   2885     PyObject *o;
   2886     PyObject *intTuple;
   2887 
   2888     if (vals == NULL)
   2889         return PyTuple_New(0);
   2890 
   2891     intTuple = PyTuple_New(len);
   2892     if (!intTuple)
   2893         return NULL;
   2894     for (i=0; i<len; i++) {
   2895         o = PyLong_FromSsize_t(vals[i]);
   2896         if (!o) {
   2897             Py_DECREF(intTuple);
   2898             return NULL;
   2899         }
   2900         PyTuple_SET_ITEM(intTuple, i, o);
   2901     }
   2902     return intTuple;
   2903 }
   2904 
   2905 static PyObject *
   2906 memory_obj_get(PyMemoryViewObject *self)
   2907 {
   2908     Py_buffer *view = &self->view;
   2909 
   2910     CHECK_RELEASED(self);
   2911     if (view->obj == NULL) {
   2912         Py_RETURN_NONE;
   2913     }
   2914     Py_INCREF(view->obj);
   2915     return view->obj;
   2916 }
   2917 
   2918 static PyObject *
   2919 memory_nbytes_get(PyMemoryViewObject *self)
   2920 {
   2921     CHECK_RELEASED(self);
   2922     return PyLong_FromSsize_t(self->view.len);
   2923 }
   2924 
   2925 static PyObject *
   2926 memory_format_get(PyMemoryViewObject *self)
   2927 {
   2928     CHECK_RELEASED(self);
   2929     return PyUnicode_FromString(self->view.format);
   2930 }
   2931 
   2932 static PyObject *
   2933 memory_itemsize_get(PyMemoryViewObject *self)
   2934 {
   2935     CHECK_RELEASED(self);
   2936     return PyLong_FromSsize_t(self->view.itemsize);
   2937 }
   2938 
   2939 static PyObject *
   2940 memory_shape_get(PyMemoryViewObject *self)
   2941 {
   2942     CHECK_RELEASED(self);
   2943     return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
   2944 }
   2945 
   2946 static PyObject *
   2947 memory_strides_get(PyMemoryViewObject *self)
   2948 {
   2949     CHECK_RELEASED(self);
   2950     return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
   2951 }
   2952 
   2953 static PyObject *
   2954 memory_suboffsets_get(PyMemoryViewObject *self)
   2955 {
   2956     CHECK_RELEASED(self);
   2957     return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
   2958 }
   2959 
   2960 static PyObject *
   2961 memory_readonly_get(PyMemoryViewObject *self)
   2962 {
   2963     CHECK_RELEASED(self);
   2964     return PyBool_FromLong(self->view.readonly);
   2965 }
   2966 
   2967 static PyObject *
   2968 memory_ndim_get(PyMemoryViewObject *self)
   2969 {
   2970     CHECK_RELEASED(self);
   2971     return PyLong_FromLong(self->view.ndim);
   2972 }
   2973 
   2974 static PyObject *
   2975 memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
   2976 {
   2977     CHECK_RELEASED(self);
   2978     return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
   2979 }
   2980 
   2981 static PyObject *
   2982 memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
   2983 {
   2984     CHECK_RELEASED(self);
   2985     return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
   2986 }
   2987 
   2988 static PyObject *
   2989 memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
   2990 {
   2991     CHECK_RELEASED(self);
   2992     return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
   2993 }
   2994 
   2995 PyDoc_STRVAR(memory_obj_doc,
   2996              "The underlying object of the memoryview.");
   2997 PyDoc_STRVAR(memory_nbytes_doc,
   2998              "The amount of space in bytes that the array would use in\n"
   2999              " a contiguous representation.");
   3000 PyDoc_STRVAR(memory_readonly_doc,
   3001              "A bool indicating whether the memory is read only.");
   3002 PyDoc_STRVAR(memory_itemsize_doc,
   3003              "The size in bytes of each element of the memoryview.");
   3004 PyDoc_STRVAR(memory_format_doc,
   3005              "A string containing the format (in struct module style)\n"
   3006              " for each element in the view.");
   3007 PyDoc_STRVAR(memory_ndim_doc,
   3008              "An integer indicating how many dimensions of a multi-dimensional\n"
   3009              " array the memory represents.");
   3010 PyDoc_STRVAR(memory_shape_doc,
   3011              "A tuple of ndim integers giving the shape of the memory\n"
   3012              " as an N-dimensional array.");
   3013 PyDoc_STRVAR(memory_strides_doc,
   3014              "A tuple of ndim integers giving the size in bytes to access\n"
   3015              " each element for each dimension of the array.");
   3016 PyDoc_STRVAR(memory_suboffsets_doc,
   3017              "A tuple of integers used internally for PIL-style arrays.");
   3018 PyDoc_STRVAR(memory_c_contiguous_doc,
   3019              "A bool indicating whether the memory is C contiguous.");
   3020 PyDoc_STRVAR(memory_f_contiguous_doc,
   3021              "A bool indicating whether the memory is Fortran contiguous.");
   3022 PyDoc_STRVAR(memory_contiguous_doc,
   3023              "A bool indicating whether the memory is contiguous.");
   3024 
   3025 
   3026 static PyGetSetDef memory_getsetlist[] = {
   3027     {"obj",             (getter)memory_obj_get,        NULL, memory_obj_doc},
   3028     {"nbytes",          (getter)memory_nbytes_get,     NULL, memory_nbytes_doc},
   3029     {"readonly",        (getter)memory_readonly_get,   NULL, memory_readonly_doc},
   3030     {"itemsize",        (getter)memory_itemsize_get,   NULL, memory_itemsize_doc},
   3031     {"format",          (getter)memory_format_get,     NULL, memory_format_doc},
   3032     {"ndim",            (getter)memory_ndim_get,       NULL, memory_ndim_doc},
   3033     {"shape",           (getter)memory_shape_get,      NULL, memory_shape_doc},
   3034     {"strides",         (getter)memory_strides_get,    NULL, memory_strides_doc},
   3035     {"suboffsets",      (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
   3036     {"c_contiguous",    (getter)memory_c_contiguous,   NULL, memory_c_contiguous_doc},
   3037     {"f_contiguous",    (getter)memory_f_contiguous,   NULL, memory_f_contiguous_doc},
   3038     {"contiguous",      (getter)memory_contiguous,     NULL, memory_contiguous_doc},
   3039     {NULL, NULL, NULL, NULL},
   3040 };
   3041 
   3042 PyDoc_STRVAR(memory_release_doc,
   3043 "release($self, /)\n--\n\
   3044 \n\
   3045 Release the underlying buffer exposed by the memoryview object.");
   3046 PyDoc_STRVAR(memory_tobytes_doc,
   3047 "tobytes($self, /)\n--\n\
   3048 \n\
   3049 Return the data in the buffer as a byte string.");
   3050 PyDoc_STRVAR(memory_hex_doc,
   3051 "hex($self, /)\n--\n\
   3052 \n\
   3053 Return the data in the buffer as a string of hexadecimal numbers.");
   3054 PyDoc_STRVAR(memory_tolist_doc,
   3055 "tolist($self, /)\n--\n\
   3056 \n\
   3057 Return the data in the buffer as a list of elements.");
   3058 PyDoc_STRVAR(memory_cast_doc,
   3059 "cast($self, /, format, *, shape)\n--\n\
   3060 \n\
   3061 Cast a memoryview to a new format or shape.");
   3062 
   3063 static PyMethodDef memory_methods[] = {
   3064     {"release",     (PyCFunction)memory_release, METH_NOARGS, memory_release_doc},
   3065     {"tobytes",     (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc},
   3066     {"hex",         (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc},
   3067     {"tolist",      (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc},
   3068     {"cast",        (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc},
   3069     {"__enter__",   memory_enter, METH_NOARGS, NULL},
   3070     {"__exit__",    memory_exit, METH_VARARGS, NULL},
   3071     {NULL,          NULL}
   3072 };
   3073 
   3074 
   3075 PyTypeObject PyMemoryView_Type = {
   3076     PyVarObject_HEAD_INIT(&PyType_Type, 0)
   3077     "memoryview",                             /* tp_name */
   3078     offsetof(PyMemoryViewObject, ob_array),   /* tp_basicsize */
   3079     sizeof(Py_ssize_t),                       /* tp_itemsize */
   3080     (destructor)memory_dealloc,               /* tp_dealloc */
   3081     0,                                        /* tp_print */
   3082     0,                                        /* tp_getattr */
   3083     0,                                        /* tp_setattr */
   3084     0,                                        /* tp_reserved */
   3085     (reprfunc)memory_repr,                    /* tp_repr */
   3086     0,                                        /* tp_as_number */
   3087     &memory_as_sequence,                      /* tp_as_sequence */
   3088     &memory_as_mapping,                       /* tp_as_mapping */
   3089     (hashfunc)memory_hash,                    /* tp_hash */
   3090     0,                                        /* tp_call */
   3091     0,                                        /* tp_str */
   3092     PyObject_GenericGetAttr,                  /* tp_getattro */
   3093     0,                                        /* tp_setattro */
   3094     &memory_as_buffer,                        /* tp_as_buffer */
   3095     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,  /* tp_flags */
   3096     memory_doc,                               /* tp_doc */
   3097     (traverseproc)memory_traverse,            /* tp_traverse */
   3098     (inquiry)memory_clear,                    /* tp_clear */
   3099     memory_richcompare,                       /* tp_richcompare */
   3100     offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
   3101     0,                                        /* tp_iter */
   3102     0,                                        /* tp_iternext */
   3103     memory_methods,                           /* tp_methods */
   3104     0,                                        /* tp_members */
   3105     memory_getsetlist,                        /* tp_getset */
   3106     0,                                        /* tp_base */
   3107     0,                                        /* tp_dict */
   3108     0,                                        /* tp_descr_get */
   3109     0,                                        /* tp_descr_set */
   3110     0,                                        /* tp_dictoffset */
   3111     0,                                        /* tp_init */
   3112     0,                                        /* tp_alloc */
   3113     memory_new,                               /* tp_new */
   3114 };
   3115