/* C Extension module to test all aspects of PEP-3118.
   Written by Stefan Krah. */

#include "Python.h"


/* struct module */
static PyObject *structmodule = NULL;
static PyObject *Struct = NULL;
static PyObject *calcsize = NULL;

/* cache simple format string */
static const char *simple_fmt = "B";
static PyObject *simple_format = NULL;
#define SIMPLE_FORMAT(fmt) (fmt == NULL || strcmp(fmt, "B") == 0)
#define FIX_FORMAT(fmt) (fmt == NULL ? "B" : fmt)


/**************************************************************************/
/*                             NDArray Object                             */
/**************************************************************************/

static PyTypeObject NDArray_Type;
#define NDArray_Check(v) Py_IS_TYPE(v, &NDArray_Type)

#define CHECK_LIST_OR_TUPLE(v) \
    do { \
        if (!PyList_Check(v) && !PyTuple_Check(v)) { \
            PyErr_SetString(PyExc_TypeError, \
                            #v " must be a list or a tuple"); \
            return NULL; \
        } \
    } while (0)

#define PyMem_XFree(v) \
    do { if (v) PyMem_Free(v); } while (0)

/* Maximum number of dimensions. */
#define ND_MAX_NDIM (2 * PyBUF_MAX_NDIM)

/* Check for the presence of suboffsets in the first dimension. */
#define HAVE_PTR(suboffsets) (suboffsets && suboffsets[0] >= 0)
/* Adjust ptr if suboffsets are present. */
#define ADJUST_PTR(ptr, suboffsets) \
    (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr)

/* Default: NumPy style (strides), read-only, no var-export, C-style layout */
#define ND_DEFAULT          0x000
/* User configurable flags for the ndarray */
#define ND_VAREXPORT        0x001   /* change layout while buffers are exported */
/* User configurable flags for each base buffer */
#define ND_WRITABLE         0x002   /* mark base buffer as writable */
#define ND_FORTRAN          0x004   /* Fortran contiguous layout */
#define ND_SCALAR           0x008   /* scalar: ndim = 0 */
#define ND_PIL              0x010   /* convert to PIL-style array (suboffsets) */
#define ND_REDIRECT         0x020   /* redirect buffer requests */
#define ND_GETBUF_FAIL      0x040   /* trigger getbuffer failure */
#define ND_GETBUF_UNDEFINED 0x080   /* undefined view.obj */
/* Internal flags for the base buffer */
#define ND_C                0x100   /* C contiguous layout (default) */
#define ND_OWN_ARRAYS       0x200   /* consumer owns arrays */

/* ndarray properties */
#define ND_IS_CONSUMER(nd) \
    (((NDArrayObject *)nd)->head == &((NDArrayObject *)nd)->staticbuf)

/* ndbuf->flags properties */
#define ND_C_CONTIGUOUS(flags) (!!(flags&(ND_SCALAR|ND_C)))
#define ND_FORTRAN_CONTIGUOUS(flags) (!!(flags&(ND_SCALAR|ND_FORTRAN)))
#define ND_ANY_CONTIGUOUS(flags) (!!(flags&(ND_SCALAR|ND_C|ND_FORTRAN)))

/* getbuffer() requests */
#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)


/* Single node of a list of base buffers. The list is needed to implement
   changes in memory layout while exported buffers are active. */
static PyTypeObject NDArray_Type;

struct ndbuf;
typedef struct ndbuf {
    struct ndbuf *next;
    struct ndbuf *prev;
    Py_ssize_t len;     /* length of data */
    Py_ssize_t offset;  /* start of the array relative to data */
    char *data;         /* raw data */
    int flags;          /* capabilities of the base buffer */
    Py_ssize_t exports; /* number of exports */
    Py_buffer base;     /* base buffer */
} ndbuf_t;

typedef struct {
    PyObject_HEAD
    int flags;          /* ndarray flags */
    ndbuf_t staticbuf;  /* static buffer for re-exporting mode */
    ndbuf_t *head;      /* currently active base buffer */
} NDArrayObject;


static ndbuf_t *
ndbuf_new(Py_ssize_t nitems, Py_ssize_t itemsize, Py_ssize_t offset, int flags)
{
    ndbuf_t *ndbuf;
    Py_buffer *base;
    Py_ssize_t len;

    len = nitems * itemsize;
    if (offset % itemsize) {
        PyErr_SetString(PyExc_ValueError,
            "offset must be a multiple of itemsize");
        return NULL;
    }
    if (offset < 0 || offset+itemsize > len) {
        PyErr_SetString(PyExc_ValueError, "offset out of bounds");
        return NULL;
    }

    ndbuf = PyMem_Malloc(sizeof *ndbuf);
    if (ndbuf == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    ndbuf->next = NULL;
    ndbuf->prev = NULL;
    ndbuf->len = len;
    ndbuf->offset= offset;

    ndbuf->data = PyMem_Malloc(len);
    if (ndbuf->data == NULL) {
        PyErr_NoMemory();
        PyMem_Free(ndbuf);
        return NULL;
    }

    ndbuf->flags = flags;
    ndbuf->exports = 0;

    base = &ndbuf->base;
    base->obj = NULL;
    base->buf = ndbuf->data;
    base->len = len;
    base->itemsize = 1;
    base->readonly = 0;
    base->format = NULL;
    base->ndim = 1;
    base->shape = NULL;
    base->strides = NULL;
    base->suboffsets = NULL;
    base->internal = ndbuf;

    return ndbuf;
}

static void
ndbuf_free(ndbuf_t *ndbuf)
{
    Py_buffer *base = &ndbuf->base;

    PyMem_XFree(ndbuf->data);
    PyMem_XFree(base->format);
    PyMem_XFree(base->shape);
    PyMem_XFree(base->strides);
    PyMem_XFree(base->suboffsets);

    PyMem_Free(ndbuf);
}

static void
ndbuf_push(NDArrayObject *nd, ndbuf_t *elt)
{
    elt->next = nd->head;
    if (nd->head) nd->head->prev = elt;
    nd->head = elt;
    elt->prev = NULL;
}

static void
ndbuf_delete(NDArrayObject *nd, ndbuf_t *elt)
{
    if (elt->prev)
        elt->prev->next = elt->next;
    else
        nd->head = elt->next;

    if (elt->next)
        elt->next->prev = elt->prev;

    ndbuf_free(elt);
}

static void
ndbuf_pop(NDArrayObject *nd)
{
    ndbuf_delete(nd, nd->head);
}


static PyObject *
ndarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    NDArrayObject *nd;

    nd = PyObject_New(NDArrayObject, &NDArray_Type);
    if (nd == NULL)
        return NULL;

    nd->flags = 0;
    nd->head = NULL;
    return (PyObject *)nd;
}

static void
ndarray_dealloc(NDArrayObject *self)
{
    if (self->head) {
        if (ND_IS_CONSUMER(self)) {
            Py_buffer *base = &self->head->base;
            if (self->head->flags & ND_OWN_ARRAYS) {
                PyMem_XFree(base->shape);
                PyMem_XFree(base->strides);
                PyMem_XFree(base->suboffsets);
            }
            PyBuffer_Release(base);
        }
        else {
            while (self->head)
                ndbuf_pop(self);
        }
    }
    PyObject_Free(self);
}

static int
ndarray_init_staticbuf(PyObject *exporter, NDArrayObject *nd, int flags)
{
    Py_buffer *base = &nd->staticbuf.base;

    if (PyObject_GetBuffer(exporter, base, flags) < 0)
        return -1;

    nd->head = &nd->staticbuf;

    nd->head->next = NULL;
    nd->head->prev = NULL;
    nd->head->len = -1;
    nd->head->offset = -1;
    nd->head->data = NULL;

    nd->head->flags = base->readonly ? 0 : ND_WRITABLE;
    nd->head->exports = 0;

    return 0;
}

static void
init_flags(ndbuf_t *ndbuf)
{
    if (ndbuf->base.ndim == 0)
        ndbuf->flags |= ND_SCALAR;
    if (ndbuf->base.suboffsets)
        ndbuf->flags |= ND_PIL;
    if (PyBuffer_IsContiguous(&ndbuf->base, 'C'))
        ndbuf->flags |= ND_C;
    if (PyBuffer_IsContiguous(&ndbuf->base, 'F'))
        ndbuf->flags |= ND_FORTRAN;
}


/****************************************************************************/
/*                          Buffer/List conversions                         */
/****************************************************************************/

static Py_ssize_t *strides_from_shape(const ndbuf_t *, int flags);

/* Get number of members in a struct: see issue #12740 */
typedef struct {
    PyObject_HEAD
    Py_ssize_t s_size;
    Py_ssize_t s_len;
} PyPartialStructObject;

static Py_ssize_t
get_nmemb(PyObject *s)
{
    return ((PyPartialStructObject *)s)->s_len;
}

/* Pack all items into the buffer of 'obj'. The 'format' parameter must be
   in struct module syntax. For standard C types, a single item is an integer.
   For compound types, a single item is a tuple of integers. */
static int
pack_from_list(PyObject *obj, PyObject *items, PyObject *format,
               Py_ssize_t itemsize)
{
    PyObject *structobj, *pack_into;
    PyObject *args, *offset;
    PyObject *item, *tmp;
    Py_ssize_t nitems; /* number of items */
    Py_ssize_t nmemb;  /* number of members in a single item */
    Py_ssize_t i, j;
    int ret = 0;

    assert(PyObject_CheckBuffer(obj));
    assert(PyList_Check(items) || PyTuple_Check(items));

    structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
    if (structobj == NULL)
        return -1;

    nitems = PySequence_Fast_GET_SIZE(items);
    nmemb = get_nmemb(structobj);
    assert(nmemb >= 1);

    pack_into = PyObject_GetAttrString(structobj, "pack_into");
    if (pack_into == NULL) {
        Py_DECREF(structobj);
        return -1;
    }

    /* nmemb >= 1 */
    args = PyTuple_New(2 + nmemb);
    if (args == NULL) {
        Py_DECREF(pack_into);
        Py_DECREF(structobj);
        return -1;
    }

    offset = NULL;
    for (i = 0; i < nitems; i++) {
        /* Loop invariant: args[j] are borrowed references or NULL. */
        PyTuple_SET_ITEM(args, 0, obj);
        for (j = 1; j < 2+nmemb; j++)
            PyTuple_SET_ITEM(args, j, NULL);

        Py_XDECREF(offset);
        offset = PyLong_FromSsize_t(i*itemsize);
        if (offset == NULL) {
            ret = -1;
            break;
        }
        PyTuple_SET_ITEM(args, 1, offset);

        item = PySequence_Fast_GET_ITEM(items, i);
        if ((PyBytes_Check(item) || PyLong_Check(item) ||
             PyFloat_Check(item)) && nmemb == 1) {
            PyTuple_SET_ITEM(args, 2, item);
        }
        else if ((PyList_Check(item) || PyTuple_Check(item)) &&
                 PySequence_Length(item) == nmemb) {
            for (j = 0; j < nmemb; j++) {
                tmp = PySequence_Fast_GET_ITEM(item, j);
                PyTuple_SET_ITEM(args, 2+j, tmp);
            }
        }
        else {
            PyErr_SetString(PyExc_ValueError,
                "mismatch between initializer element and format string");
            ret = -1;
            break;
        }

        tmp = PyObject_CallObject(pack_into, args);
        if (tmp == NULL) {
            ret = -1;
            break;
        }
        Py_DECREF(tmp);
    }

    Py_INCREF(obj); /* args[0] */
    /* args[1]: offset is either NULL or should be dealloc'd */
    for (i = 2; i < 2+nmemb; i++) {
        tmp = PyTuple_GET_ITEM(args, i);
        Py_XINCREF(tmp);
    }
    Py_DECREF(args);

    Py_DECREF(pack_into);
    Py_DECREF(structobj);
    return ret;

}

/* Pack single element */
static int
pack_single(char *ptr, PyObject *item, const char *fmt, Py_ssize_t itemsize)
{
    PyObject *structobj = NULL, *pack_into = NULL, *args = NULL;
    PyObject *format = NULL, *mview = NULL, *zero = NULL;
    Py_ssize_t i, nmemb;
    int ret = -1;
    PyObject *x;

    if (fmt == NULL) fmt = "B";

    format = PyUnicode_FromString(fmt);
    if (format == NULL)
        goto out;

    structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
    if (structobj == NULL)
        goto out;

    nmemb = get_nmemb(structobj);
    assert(nmemb >= 1);

    mview = PyMemoryView_FromMemory(ptr, itemsize, PyBUF_WRITE);
    if (mview == NULL)
        goto out;

    zero = PyLong_FromLong(0);
    if (zero == NULL)
        goto out;

    pack_into = PyObject_GetAttrString(structobj, "pack_into");
    if (pack_into == NULL)
        goto out;

    args = PyTuple_New(2+nmemb);
    if (args == NULL)
        goto out;

    PyTuple_SET_ITEM(args, 0, mview);
    PyTuple_SET_ITEM(args, 1, zero);

    if ((PyBytes_Check(item) || PyLong_Check(item) ||
         PyFloat_Check(item)) && nmemb == 1) {
         PyTuple_SET_ITEM(args, 2, item);
    }
    else if ((PyList_Check(item) || PyTuple_Check(item)) &&
             PySequence_Length(item) == nmemb) {
        for (i = 0; i < nmemb; i++) {
            x = PySequence_Fast_GET_ITEM(item, i);
            PyTuple_SET_ITEM(args, 2+i, x);
        }
    }
    else {
        PyErr_SetString(PyExc_ValueError,
            "mismatch between initializer element and format string");
        goto args_out;
    }

    x = PyObject_CallObject(pack_into, args);
    if (x != NULL) {
        Py_DECREF(x);
        ret = 0;
    }


args_out:
    for (i = 0; i < 2+nmemb; i++)
        Py_XINCREF(PyTuple_GET_ITEM(args, i));
    Py_XDECREF(args);
out:
    Py_XDECREF(pack_into);
    Py_XDECREF(zero);
    Py_XDECREF(mview);
    Py_XDECREF(structobj);
    Py_XDECREF(format);
    return ret;
}

static void
copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
         char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
         char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
         char *mem)
{
    Py_ssize_t i;

    assert(ndim >= 1);

    if (ndim == 1) {
        if (!HAVE_PTR(dsuboffsets) && !HAVE_PTR(ssuboffsets) &&
            dstrides[0] == itemsize && sstrides[0] == itemsize) {
            memmove(dptr, sptr, shape[0] * itemsize);
        }
        else {
            char *p;
            assert(mem != NULL);
            for (i=0, p=mem; i<shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
                char *xsptr = ADJUST_PTR(sptr, ssuboffsets);
                memcpy(p, xsptr, itemsize);
            }
            for (i=0, p=mem; i<shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
                char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
                memcpy(xdptr, p, itemsize);
            }
        }
        return;
    }

    for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
        char *xdptr = ADJUST_PTR(dptr, dsuboffsets);
        char *xsptr = ADJUST_PTR(sptr, ssuboffsets);

        copy_rec(shape+1, ndim-1, itemsize,
                 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
                 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
                 mem);
    }
}

static int
cmp_structure(Py_buffer *dest, Py_buffer *src)
{
    Py_ssize_t i;

    if (strcmp(FIX_FORMAT(dest->format), FIX_FORMAT(src->format)) != 0 ||
        dest->itemsize != src->itemsize ||
        dest->ndim != src->ndim)
        return -1;

    for (i = 0; i < dest->ndim; i++) {
        if (dest->shape[i] != src->shape[i])
            return -1;
        if (dest->shape[i] == 0)
            break;
    }

    return 0;
}

/* Copy src to dest. Both buffers must have the same format, itemsize,
   ndim and shape. Copying is atomic, the function never fails with
   a partial copy. */
static int
copy_buffer(Py_buffer *dest, Py_buffer *src)
{
    char *mem = NULL;

    assert(dest->ndim > 0);

    if (cmp_structure(dest, src) < 0) {
        PyErr_SetString(PyExc_ValueError,
            "ndarray assignment: lvalue and rvalue have different structures");
        return -1;
    }

    if ((dest->suboffsets && dest->suboffsets[dest->ndim-1] >= 0) ||
        (src->suboffsets && src->suboffsets[src->ndim-1] >= 0) ||
        dest->strides[dest->ndim-1] != dest->itemsize ||
        src->strides[src->ndim-1] != src->itemsize) {
        mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
        if (mem == NULL) {
            PyErr_NoMemory();
            return -1;
        }
    }

    copy_rec(dest->shape, dest->ndim, dest->itemsize,
             dest->buf, dest->strides, dest->suboffsets,
             src->buf, src->strides, src->suboffsets,
             mem);

    PyMem_XFree(mem);
    return 0;
}


/* Unpack single element */
static PyObject *
unpack_single(char *ptr, const char *fmt, Py_ssize_t itemsize)
{
    PyObject *x, *unpack_from, *mview;

    if (fmt == NULL) {
        fmt = "B";
        itemsize = 1;
    }

    unpack_from = PyObject_GetAttrString(structmodule, "unpack_from");
    if (unpack_from == NULL)
        return NULL;

    mview = PyMemoryView_FromMemory(ptr, itemsize, PyBUF_READ);
    if (mview == NULL) {
        Py_DECREF(unpack_from);
        return NULL;
    }

    x = PyObject_CallFunction(unpack_from, "sO", fmt, mview);
    Py_DECREF(unpack_from);
    Py_DECREF(mview);
    if (x == NULL)
        return NULL;

    if (PyTuple_GET_SIZE(x) == 1) {
        PyObject *tmp = PyTuple_GET_ITEM(x, 0);
        Py_INCREF(tmp);
        Py_DECREF(x);
        return tmp;
    }

    return x;
}

/* Unpack a multi-dimensional matrix into a nested list. Return a scalar
   for ndim = 0. */
static PyObject *
unpack_rec(PyObject *unpack_from, char *ptr, PyObject *mview, char *item,
           const Py_ssize_t *shape, const Py_ssize_t *strides,
           const Py_ssize_t *suboffsets, Py_ssize_t ndim, Py_ssize_t itemsize)
{
    PyObject *lst, *x;
    Py_ssize_t i;

    assert(ndim >= 0);
    assert(shape != NULL);
    assert(strides != NULL);

    if (ndim == 0) {
        memcpy(item, ptr, itemsize);
        x = PyObject_CallFunctionObjArgs(unpack_from, mview, NULL);
        if (x == NULL)
            return NULL;
        if (PyTuple_GET_SIZE(x) == 1) {
            PyObject *tmp = PyTuple_GET_ITEM(x, 0);
            Py_INCREF(tmp);
            Py_DECREF(x);
            return tmp;
        }
        return x;
    }

    lst = PyList_New(shape[0]);
    if (lst == NULL)
        return NULL;

    for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
        char *nextptr = ADJUST_PTR(ptr, suboffsets);

        x = unpack_rec(unpack_from, nextptr, mview, item,
                       shape+1, strides+1, suboffsets ? suboffsets+1 : NULL,
                       ndim-1, itemsize);
        if (x == NULL) {
            Py_DECREF(lst);
            return NULL;
        }

        PyList_SET_ITEM(lst, i, x);
    }

    return lst;
}


static PyObject *
ndarray_as_list(NDArrayObject *nd)
{
    PyObject *structobj = NULL, *unpack_from = NULL;
    PyObject *lst = NULL, *mview = NULL;
    Py_buffer *base = &nd->head->base;
    Py_ssize_t *shape = base->shape;
    Py_ssize_t *strides = base->strides;
    Py_ssize_t simple_shape[1];
    Py_ssize_t simple_strides[1];
    char *item = NULL;
    PyObject *format;
    char *fmt = base->format;

    base = &nd->head->base;

    if (fmt == NULL) {
        PyErr_SetString(PyExc_ValueError,
            "ndarray: tolist() does not support format=NULL, use "
            "tobytes()");
        return NULL;
    }
    if (shape == NULL) {
        assert(ND_C_CONTIGUOUS(nd->head->flags));
        assert(base->strides == NULL);
        assert(base->ndim <= 1);
        shape = simple_shape;
        shape[0] = base->len;
        strides = simple_strides;
        strides[0] = base->itemsize;
    }
    else if (strides == NULL) {
        assert(ND_C_CONTIGUOUS(nd->head->flags));
        strides = strides_from_shape(nd->head, 0);
        if (strides == NULL)
            return NULL;
    }

    format = PyUnicode_FromString(fmt);
    if (format == NULL)
        goto out;

    structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL);
    Py_DECREF(format);
    if (structobj == NULL)
        goto out;

    unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
    if (unpack_from == NULL)
        goto out;

    item = PyMem_Malloc(base->itemsize);
    if (item == NULL) {
        PyErr_NoMemory();
        goto out;
    }

    mview = PyMemoryView_FromMemory(item, base->itemsize, PyBUF_WRITE);
    if (mview == NULL)
        goto out;

    lst = unpack_rec(unpack_from, base->buf, mview, item,
                     shape, strides, base->suboffsets,
                     base->ndim, base->itemsize);

out:
    Py_XDECREF(mview);
    PyMem_XFree(item);
    Py_XDECREF(unpack_from);
    Py_XDECREF(structobj);
    if (strides != base->strides && strides != simple_strides)
        PyMem_XFree(strides);

    return lst;
}


/****************************************************************************/
/*                            Initialize ndbuf                              */
/****************************************************************************/

/*
   State of a new ndbuf during initialization. 'OK' means that initialization
   is complete. 'PTR' means that a pointer has been initialized, but the
   state of the memory is still undefined and ndbuf->offset is disregarded.

  +-----------------+-----------+-------------+----------------+
  |                 | ndbuf_new | init_simple | init_structure |
  +-----------------+-----------+-------------+----------------+
  | next            | OK (NULL) |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | prev            | OK (NULL) |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | len             |    OK     |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | offset          |    OK     |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | data            |    PTR    |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | flags           |    user   |    user     |       OK       |
  +-----------------+-----------+-------------+----------------+
  | exports         |   OK (0)  |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.obj        | OK (NULL) |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.buf        |    PTR    |     PTR     |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.len        | len(data) |  len(data)  |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.itemsize   |     1     |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.readonly   |     0     |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.format     |    NULL   |     OK      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.ndim       |     1     |      1      |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.shape      |    NULL   |    NULL     |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.strides    |    NULL   |    NULL     |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.suboffsets |    NULL   |    NULL     |       OK       |
  +-----------------+-----------+-------------+----------------+
  | base.internal   |    OK     |    OK       |       OK       |
  +-----------------+-----------+-------------+----------------+

*/

static Py_ssize_t
get_itemsize(PyObject *format)
{
    PyObject *tmp;
    Py_ssize_t itemsize;

    tmp = PyObject_CallFunctionObjArgs(calcsize, format, NULL);
    if (tmp == NULL)
        return -1;
    itemsize = PyLong_AsSsize_t(tmp);
    Py_DECREF(tmp);

    return itemsize;
}

static char *
get_format(PyObject *format)
{
    PyObject *tmp;
    char *fmt;

    tmp = PyUnicode_AsASCIIString(format);
    if (tmp == NULL)
        return NULL;
    fmt = PyMem_Malloc(PyBytes_GET_SIZE(tmp)+1);
    if (fmt == NULL) {
        PyErr_NoMemory();
        Py_DECREF(tmp);
        return NULL;
    }
    strcpy(fmt, PyBytes_AS_STRING(tmp));
    Py_DECREF(tmp);

    return fmt;
}

static int
init_simple(ndbuf_t *ndbuf, PyObject *items, PyObject *format,
            Py_ssize_t itemsize)
{
    PyObject *mview;
    Py_buffer *base = &ndbuf->base;
    int ret;

    mview = PyMemoryView_FromBuffer(base);
    if (mview == NULL)
        return -1;

    ret = pack_from_list(mview, items, format, itemsize);
    Py_DECREF(mview);
    if (ret < 0)
        return -1;

    base->readonly = !(ndbuf->flags & ND_WRITABLE);
    base->itemsize = itemsize;
    base->format = get_format(format);
    if (base->format == NULL)
        return -1;

    return 0;
}

static Py_ssize_t *
seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape)
{
    Py_ssize_t *dest;
    Py_ssize_t x, i;

    /* ndim = len <= ND_MAX_NDIM, so PyMem_New() is actually not needed. */
    dest = PyMem_New(Py_ssize_t, len);
    if (dest == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    for (i = 0; i < len; i++) {
        PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
        if (!PyLong_Check(tmp)) {
            PyErr_Format(PyExc_ValueError,
                "elements of %s must be integers",
                is_shape ? "shape" : "strides");
            PyMem_Free(dest);
            return NULL;
        }
        x = PyLong_AsSsize_t(tmp);
        if (PyErr_Occurred()) {
            PyMem_Free(dest);
            return NULL;
        }
        if (is_shape && x < 0) {
            PyErr_Format(PyExc_ValueError,
                "elements of shape must be integers >= 0");
            PyMem_Free(dest);
            return NULL;
        }
        dest[i] = x;
    }

    return dest;
}

static Py_ssize_t *
strides_from_shape(const ndbuf_t *ndbuf, int flags)
{
    const Py_buffer *base = &ndbuf->base;
    Py_ssize_t *s, i;

    s = PyMem_Malloc(base->ndim * (sizeof *s));
    if (s == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    if (flags & ND_FORTRAN) {
        s[0] = base->itemsize;
        for (i = 1; i < base->ndim; i++)
            s[i] = s[i-1] * base->shape[i-1];
    }
    else {
        s[base->ndim-1] = base->itemsize;
        for (i = base->ndim-2; i >= 0; i--)
            s[i] = s[i+1] * base->shape[i+1];
    }

    return s;
}

/* Bounds check:

     len := complete length of allocated memory
     offset := start of the array

     A single array element is indexed by:

       i = indices[0] * strides[0] + indices[1] * strides[1] + ...

     imin is reached when all indices[n] combined with positive strides are 0
     and all indices combined with negative strides are shape[n]-1, which is
     the maximum index for the nth dimension.

     imax is reached when all indices[n] combined with negative strides are 0
     and all indices combined with positive strides are shape[n]-1.
*/
static int
verify_structure(Py_ssize_t len, Py_ssize_t itemsize, Py_ssize_t offset,
                 const Py_ssize_t *shape, const Py_ssize_t *strides,
                 Py_ssize_t ndim)
{
    Py_ssize_t imin, imax;
    Py_ssize_t n;

    assert(ndim >= 0);

    if (ndim == 0 && (offset < 0 || offset+itemsize > len))
        goto invalid_combination;

    for (n = 0; n < ndim; n++)
        if (strides[n] % itemsize) {
            PyErr_SetString(PyExc_ValueError,
            "strides must be a multiple of itemsize");
            return -1;
        }

    for (n = 0; n < ndim; n++)
        if (shape[n] == 0)
            return 0;

    imin = imax = 0;
    for (n = 0; n < ndim; n++)
        if (strides[n] <= 0)
            imin += (shape[n]-1) * strides[n];
        else
            imax += (shape[n]-1) * strides[n];

    if (imin + offset < 0 || imax + offset + itemsize > len)
        goto invalid_combination;

    return 0;


invalid_combination:
    PyErr_SetString(PyExc_ValueError,
        "invalid combination of buffer, shape and strides");
    return -1;
}

/*
   Convert a NumPy-style array to an array using suboffsets to stride in
   the first dimension. Requirements: ndim > 0.

   Contiguous example
   ==================

     Input:
     ------
       shape      = {2, 2, 3};
       strides    = {6, 3, 1};
       suboffsets = NULL;
       data       = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
       buf        = &data[0]

     Output:
     -------
       shape      = {2, 2, 3};
       strides    = {sizeof(char *), 3, 1};
       suboffsets = {0, -1, -1};
       data       = {p1, p2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
                     |   |   ^                 ^
                     `---'---'                 |
                         |                     |
                         `---------------------'
       buf        = &data[0]

     So, in the example the input resembles the three-dimensional array
     char v[2][2][3], while the output resembles an array of two pointers
     to two-dimensional arrays: char (*v[2])[2][3].


   Non-contiguous example:
   =======================

     Input (with offset and negative strides):
     -----------------------------------------
       shape      = {2, 2, 3};
       strides    = {-6, 3, -1};
       offset     = 8
       suboffsets = NULL;
       data       = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

     Output:
     -------
       shape      = {2, 2, 3};
       strides    = {-sizeof(char *), 3, -1};
       suboffsets = {2, -1, -1};
       newdata    = {p1, p2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
                     |   |   ^     ^           ^     ^
                     `---'---'     |           |     `- p2+suboffsets[0]
                         |         `-----------|--- p1+suboffsets[0]
                         `---------------------'
       buf        = &newdata[1]  # striding backwards over the pointers.

     suboffsets[0] is the same as the offset that one would specify if
     the two {2, 3} subarrays were created directly, hence the name.
*/
static int
init_suboffsets(ndbuf_t *ndbuf)
{
    Py_buffer *base = &ndbuf->base;
    Py_ssize_t start, step;
    Py_ssize_t imin, suboffset0;
    Py_ssize_t addsize;
    Py_ssize_t n;
    char *data;

    assert(base->ndim > 0);
    assert(base->suboffsets == NULL);

    /* Allocate new data with additional space for shape[0] pointers. */
    addsize = base->shape[0] * (sizeof (char *));

    /* Align array start to a multiple of 8. */
    addsize = 8 * ((addsize + 7) / 8);

    data = PyMem_Malloc(ndbuf->len + addsize);
    if (data == NULL) {
        PyErr_NoMemory();
        return -1;
    }

    memcpy(data + addsize, ndbuf->data, ndbuf->len);

    PyMem_Free(ndbuf->data);
    ndbuf->data = data;
    ndbuf->len += addsize;
    base->buf = ndbuf->data;

    /* imin: minimum index of the input array relative to ndbuf->offset.
       suboffset0: offset for each sub-array of the output. This is the
                   same as calculating -imin' for a sub-array of ndim-1. */
    imin = suboffset0 = 0;
    for (n = 0; n < base->ndim; n++) {
        if (base->shape[n] == 0)
            break;
        if (base->strides[n] <= 0) {
            Py_ssize_t x = (base->shape[n]-1) * base->strides[n];
            imin += x;
            suboffset0 += (n >= 1) ? -x : 0;
        }
    }

    /* Initialize the array of pointers to the sub-arrays. */
    start = addsize + ndbuf->offset + imin;
    step = base->strides[0] < 0 ? -base->strides[0] : base->strides[0];

    for (n = 0; n < base->shape[0]; n++)
        ((char **)base->buf)[n] = (char *)base->buf + start + n*step;

    /* Initialize suboffsets. */
    base->suboffsets = PyMem_Malloc(base->ndim * (sizeof *base->suboffsets));
    if (base->suboffsets == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    base->suboffsets[0] = suboffset0;
    for (n = 1; n < base->ndim; n++)
        base->suboffsets[n] = -1;

    /* Adjust strides for the first (zeroth) dimension. */
    if (base->strides[0] >= 0) {
        base->strides[0] = sizeof(char *);
    }
    else {
        /* Striding backwards. */
        base->strides[0] = -(Py_ssize_t)sizeof(char *);
        if (base->shape[0] > 0)
            base->buf = (char *)base->buf + (base->shape[0]-1) * sizeof(char *);
    }

    ndbuf->flags &= ~(ND_C|ND_FORTRAN);
    ndbuf->offset = 0;
    return 0;
}

static void
init_len(Py_buffer *base)
{
    Py_ssize_t i;

    base->len = 1;
    for (i = 0; i < base->ndim; i++)
        base->len *= base->shape[i];
    base->len *= base->itemsize;
}

static int
init_structure(ndbuf_t *ndbuf, PyObject *shape, PyObject *strides,
               Py_ssize_t ndim)
{
    Py_buffer *base = &ndbuf->base;

    base->ndim = (int)ndim;
    if (ndim == 0) {
        if (ndbuf->flags & ND_PIL) {
            PyErr_SetString(PyExc_TypeError,
                "ndim = 0 cannot be used in conjunction with ND_PIL");
            return -1;
        }
        ndbuf->flags |= (ND_SCALAR|ND_C|ND_FORTRAN);
        return 0;
    }

    /* shape */
    base->shape = seq_as_ssize_array(shape, ndim, 1);
    if (base->shape == NULL)
        return -1;

    /* strides */
    if (strides) {
        base->strides = seq_as_ssize_array(strides, ndim, 0);
    }
    else {
        base->strides = strides_from_shape(ndbuf, ndbuf->flags);
    }
    if (base->strides == NULL)
        return -1;
    if (verify_structure(base->len, base->itemsize, ndbuf->offset,
                         base->shape, base->strides, ndim) < 0)
        return -1;

    /* buf */
    base->buf = ndbuf->data + ndbuf->offset;

    /* len */
    init_len(base);

    /* ndbuf->flags */
    if (PyBuffer_IsContiguous(base, 'C'))
        ndbuf->flags |= ND_C;
    if (PyBuffer_IsContiguous(base, 'F'))
        ndbuf->flags |= ND_FORTRAN;


    /* convert numpy array to suboffset representation */
    if (ndbuf->flags & ND_PIL) {
        /* modifies base->buf, base->strides and base->suboffsets **/
        return init_suboffsets(ndbuf);
    }

    return 0;
}

static ndbuf_t *
init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides,
           Py_ssize_t offset, PyObject *format, int flags)
{
    ndbuf_t *ndbuf;
    Py_ssize_t ndim;
    Py_ssize_t nitems;
    Py_ssize_t itemsize;

    /* ndim = len(shape) */
    CHECK_LIST_OR_TUPLE(shape);
    ndim = PySequence_Fast_GET_SIZE(shape);
    if (ndim > ND_MAX_NDIM) {
        PyErr_Format(PyExc_ValueError,
            "ndim must not exceed %d", ND_MAX_NDIM);
        return NULL;
    }

    /* len(strides) = len(shape) */
    if (strides) {
        CHECK_LIST_OR_TUPLE(strides);
        if (PySequence_Fast_GET_SIZE(strides) == 0)
            strides = NULL;
        else if (flags & ND_FORTRAN) {
            PyErr_SetString(PyExc_TypeError,
                "ND_FORTRAN cannot be used together with strides");
            return NULL;
        }
        else if (PySequence_Fast_GET_SIZE(strides) != ndim) {
            PyErr_SetString(PyExc_ValueError,
                "len(shape) != len(strides)");
            return NULL;
        }
    }

    /* itemsize */
    itemsize = get_itemsize(format);
    if (itemsize <= 0) {
        if (itemsize == 0) {
            PyErr_SetString(PyExc_ValueError,
                "itemsize must not be zero");
        }
        return NULL;
    }

    /* convert scalar to list */
    if (ndim == 0) {
        items = PyTuple_Pack(1, items);
        if (items == NULL)
            return NULL;
    }
    else {
        CHECK_LIST_OR_TUPLE(items);
        Py_INCREF(items);
    }

    /* number of items */
    nitems = PySequence_Fast_GET_SIZE(items);
    if (nitems == 0) {
        PyErr_SetString(PyExc_ValueError,
            "initializer list or tuple must not be empty");
        Py_DECREF(items);
        return NULL;
    }

    ndbuf = ndbuf_new(nitems, itemsize, offset, flags);
    if (ndbuf == NULL) {
        Py_DECREF(items);
        return NULL;
    }


    if (init_simple(ndbuf, items, format, itemsize) < 0)
        goto error;
    if (init_structure(ndbuf, shape, strides, ndim) < 0)
        goto error;

    Py_DECREF(items);
    return ndbuf;

error:
    Py_DECREF(items);
    ndbuf_free(ndbuf);
    return NULL;
}

/* initialize and push a new base onto the linked list */
static int
ndarray_push_base(NDArrayObject *nd, PyObject *items,
                  PyObject *shape, PyObject *strides,
                  Py_ssize_t offset, PyObject *format, int flags)
{
    ndbuf_t *ndbuf;

    ndbuf = init_ndbuf(items, shape, strides, offset, format, flags);
    if (ndbuf == NULL)
        return -1;

    ndbuf_push(nd, ndbuf);
    return 0;
}

#define PyBUF_UNUSED 0x10000
static int
ndarray_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    static char *kwlist[] = {
        "obj", "shape", "strides", "offset", "format", "flags", "getbuf", NULL
    };
    PyObject *v = NULL;  /* initializer: scalar, list, tuple or base object */
    PyObject *shape = NULL;   /* size of each dimension */
    PyObject *strides = NULL; /* number of bytes to the next elt in each dim */
    Py_ssize_t offset = 0;            /* buffer offset */
    PyObject *format = simple_format; /* struct module specifier: "B" */
    int flags = ND_DEFAULT;           /* base buffer and ndarray flags */

    int getbuf = PyBUF_UNUSED; /* re-exporter: getbuffer request flags */


    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOnOii", kwlist,
            &v, &shape, &strides, &offset, &format, &flags, &getbuf))
        return -1;

    /* NDArrayObject is re-exporter */
    if (PyObject_CheckBuffer(v) && shape == NULL) {
        if (strides || offset || format != simple_format ||
            !(flags == ND_DEFAULT || flags == ND_REDIRECT)) {
            PyErr_SetString(PyExc_TypeError,
               "construction from exporter object only takes 'obj', 'getbuf' "
               "and 'flags' arguments");
            return -1;
        }

        getbuf = (getbuf == PyBUF_UNUSED) ? PyBUF_FULL_RO : getbuf;

        if (ndarray_init_staticbuf(v, nd, getbuf) < 0)
            return -1;

        init_flags(nd->head);
        nd->head->flags |= flags;

        return 0;
    }

    /* NDArrayObject is the original base object. */
    if (getbuf != PyBUF_UNUSED) {
        PyErr_SetString(PyExc_TypeError,
            "getbuf argument only valid for construction from exporter "
            "object");
        return -1;
    }
    if (shape == NULL) {
        PyErr_SetString(PyExc_TypeError,
            "shape is a required argument when constructing from "
            "list, tuple or scalar");
        return -1;
    }

    if (flags & ND_VAREXPORT) {
        nd->flags |= ND_VAREXPORT;
        flags &= ~ND_VAREXPORT;
    }

    /* Initialize and push the first base buffer onto the linked list. */
    return ndarray_push_base(nd, v, shape, strides, offset, format, flags);
}

/* Push an additional base onto the linked list. */
static PyObject *
ndarray_push(PyObject *self, PyObject *args, PyObject *kwds)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    static char *kwlist[] = {
        "items", "shape", "strides", "offset", "format", "flags", NULL
    };
    PyObject *items = NULL;   /* initializer: scalar, list or tuple */
    PyObject *shape = NULL;   /* size of each dimension */
    PyObject *strides = NULL; /* number of bytes to the next elt in each dim */
    PyObject *format = simple_format;  /* struct module specifier: "B" */
    Py_ssize_t offset = 0;             /* buffer offset */
    int flags = ND_DEFAULT;            /* base buffer flags */

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OnOi", kwlist,
            &items, &shape, &strides, &offset, &format, &flags))
        return NULL;

    if (flags & ND_VAREXPORT) {
        PyErr_SetString(PyExc_ValueError,
            "ND_VAREXPORT flag can only be used during object creation");
        return NULL;
    }
    if (ND_IS_CONSUMER(nd)) {
        PyErr_SetString(PyExc_BufferError,
            "structure of re-exporting object is immutable");
        return NULL;
    }
    if (!(nd->flags&ND_VAREXPORT) && nd->head->exports > 0) {
        PyErr_Format(PyExc_BufferError,
            "cannot change structure: %zd exported buffer%s",
            nd->head->exports, nd->head->exports==1 ? "" : "s");
        return NULL;
    }

    if (ndarray_push_base(nd, items, shape, strides,
                          offset, format, flags) < 0)
        return NULL;
    Py_RETURN_NONE;
}

/* Pop a base from the linked list (if possible). */
static PyObject *
ndarray_pop(PyObject *self, PyObject *dummy)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    if (ND_IS_CONSUMER(nd)) {
        PyErr_SetString(PyExc_BufferError,
            "structure of re-exporting object is immutable");
        return NULL;
    }
    if (nd->head->exports > 0) {
        PyErr_Format(PyExc_BufferError,
            "cannot change structure: %zd exported buffer%s",
            nd->head->exports, nd->head->exports==1 ? "" : "s");
        return NULL;
    }
    if (nd->head->next == NULL) {
        PyErr_SetString(PyExc_BufferError,
            "list only has a single base");
        return NULL;
    }

    ndbuf_pop(nd);
    Py_RETURN_NONE;
}

/**************************************************************************/
/*                               getbuffer                                */
/**************************************************************************/

static int
ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags)
{
    ndbuf_t *ndbuf = self->head;
    Py_buffer *base = &ndbuf->base;
    int baseflags = ndbuf->flags;

    /* redirect mode */
    if (base->obj != NULL && (baseflags&ND_REDIRECT)) {
        return PyObject_GetBuffer(base->obj, view, flags);
    }

    /* start with complete information */
    *view = *base;
    view->obj = NULL;

    /* reconstruct format */
    if (view->format == NULL)
        view->format = "B";

    if (base->ndim != 0 &&
        ((REQ_SHAPE(flags) && base->shape == NULL) ||
         (REQ_STRIDES(flags) && base->strides == NULL))) {
        /* The ndarray is a re-exporter that has been created without full
           information for testing purposes. In this particular case the
           ndarray is not a PEP-3118 compliant buffer provider. */
        PyErr_SetString(PyExc_BufferError,
            "re-exporter does not provide format, shape or strides");
        return -1;
    }

    if (baseflags & ND_GETBUF_FAIL) {
        PyErr_SetString(PyExc_BufferError,
            "ND_GETBUF_FAIL: forced test exception");
        if (baseflags & ND_GETBUF_UNDEFINED)
            view->obj = (PyObject *)0x1; /* wrong but permitted in <= 3.2 */
        return -1;
    }

    if (REQ_WRITABLE(flags) && base->readonly) {
        PyErr_SetString(PyExc_BufferError,
            "ndarray is not writable");
        return -1;
    }
    if (!REQ_FORMAT(flags)) {
        /* NULL indicates that the buffer's data type has been cast to 'B'.
           view->itemsize is the _previous_ itemsize. If shape is present,
           the equality product(shape) * itemsize = len still holds at this
           point. The equality calcsize(format) = itemsize does _not_ hold
           from here on! */
        view->format = NULL;
    }

    if (REQ_C_CONTIGUOUS(flags) && !ND_C_CONTIGUOUS(baseflags)) {
        PyErr_SetString(PyExc_BufferError,
            "ndarray is not C-contiguous");
        return -1;
    }
    if (REQ_F_CONTIGUOUS(flags) && !ND_FORTRAN_CONTIGUOUS(baseflags)) {
        PyErr_SetString(PyExc_BufferError,
            "ndarray is not Fortran contiguous");
        return -1;
    }
    if (REQ_ANY_CONTIGUOUS(flags) && !ND_ANY_CONTIGUOUS(baseflags)) {
        PyErr_SetString(PyExc_BufferError,
            "ndarray is not contiguous");
        return -1;
    }
    if (!REQ_INDIRECT(flags) && (baseflags & ND_PIL)) {
        PyErr_SetString(PyExc_BufferError,
            "ndarray cannot be represented without suboffsets");
        return -1;
    }
    if (!REQ_STRIDES(flags)) {
        if (!ND_C_CONTIGUOUS(baseflags)) {
            PyErr_SetString(PyExc_BufferError,
                "ndarray is not C-contiguous");
            return -1;
        }
        view->strides = NULL;
    }
    if (!REQ_SHAPE(flags)) {
        /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
           so base->buf = ndbuf->data. */
        if (view->format != NULL) {
            /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
               not make sense. */
            PyErr_Format(PyExc_BufferError,
                "ndarray: cannot cast to unsigned bytes if the format flag "
                "is present");
            return -1;
        }
        /* product(shape) * itemsize = len and calcsize(format) = itemsize
           do _not_ hold from here on! */
        view->ndim = 1;
        view->shape = NULL;
    }

    /* Ascertain that the new buffer has the same contiguity as the exporter */
    if (ND_C_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'C') ||
        /* skip cast to 1-d */
        (view->format != NULL && view->shape != NULL &&
         ND_FORTRAN_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'F')) ||
        /* cast to 1-d */
        (view->format == NULL && view->shape == NULL &&
         !PyBuffer_IsContiguous(view, 'F'))) {
        PyErr_SetString(PyExc_BufferError,
            "ndarray: contiguity mismatch in getbuf()");
            return -1;
    }

    view->obj = Py_NewRef(self);
    self->head->exports++;

    return 0;
}

static void
ndarray_releasebuf(NDArrayObject *self, Py_buffer *view)
{
    if (!ND_IS_CONSUMER(self)) {
        ndbuf_t *ndbuf = view->internal;
        if (--ndbuf->exports == 0 && ndbuf != self->head)
            ndbuf_delete(self, ndbuf);
    }
}

static PyBufferProcs ndarray_as_buffer = {
    (getbufferproc)ndarray_getbuf,        /* bf_getbuffer */
    (releasebufferproc)ndarray_releasebuf /* bf_releasebuffer */
};


/**************************************************************************/
/*                           indexing/slicing                             */
/**************************************************************************/

static char *
ptr_from_index(Py_buffer *base, Py_ssize_t index)
{
    char *ptr;
    Py_ssize_t nitems; /* items in the first dimension */

    if (base->shape)
        nitems = base->shape[0];
    else {
        assert(base->ndim == 1 && SIMPLE_FORMAT(base->format));
        nitems = base->len;
    }

    if (index < 0) {
        index += nitems;
    }
    if (index < 0 || index >= nitems) {
        PyErr_SetString(PyExc_IndexError, "index out of bounds");
        return NULL;
    }

    ptr = (char *)base->buf;

    if (base->strides == NULL)
         ptr += base->itemsize * index;
    else
         ptr += base->strides[0] * index;

    ptr = ADJUST_PTR(ptr, base->suboffsets);

    return ptr;
}

static PyObject *
ndarray_item(NDArrayObject *self, Py_ssize_t index)
{
    ndbuf_t *ndbuf = self->head;
    Py_buffer *base = &ndbuf->base;
    char *ptr;

    if (base->ndim == 0) {
        PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar");
        return NULL;
    }

    ptr = ptr_from_index(base, index);
    if (ptr == NULL)
        return NULL;

    if (base->ndim == 1) {
        return unpack_single(ptr, base->format, base->itemsize);
    }
    else {
        NDArrayObject *nd;
        Py_buffer *subview;

        nd = (NDArrayObject *)ndarray_new(&NDArray_Type, NULL, NULL);
        if (nd == NULL)
            return NULL;

        if (ndarray_init_staticbuf((PyObject *)self, nd, PyBUF_FULL_RO) < 0) {
            Py_DECREF(nd);
            return NULL;
        }

        subview = &nd->staticbuf.base;

        subview->buf = ptr;
        subview->len /= subview->shape[0];

        subview->ndim--;
        subview->shape++;
        if (subview->strides) subview->strides++;
        if (subview->suboffsets) subview->suboffsets++;

        init_flags(&nd->staticbuf);

        return (PyObject *)nd;
    }
}

/*
  For each dimension, we get valid (start, stop, step, slicelength) quadruples
  from PySlice_GetIndicesEx().

  Slicing NumPy arrays
  ====================

    A pointer to an element in a NumPy array is defined by:

      ptr = (char *)buf + indices[0] * strides[0] +
                          ... +
                          indices[ndim-1] * strides[ndim-1]

    Adjust buf:
    -----------
      Adding start[n] for each dimension effectively adds the constant:

        c = start[0] * strides[0] + ... + start[ndim-1] * strides[ndim-1]

      Therefore init_slice() adds all start[n] directly to buf.

    Adjust shape:
    -------------
      Obviously shape[n] = slicelength[n]

    Adjust strides:
    ---------------
      In the original array, the next element in a dimension is reached
      by adding strides[n] to the pointer. In the sliced array, elements
      may be skipped, so the next element is reached by adding:

        strides[n] * step[n]

  Slicing PIL arrays
  ==================

    Layout:
    -------
      In the first (zeroth) dimension, PIL arrays have an array of pointers
      to sub-arrays of ndim-1. Striding in the first dimension is done by
      getting the index of the nth pointer, dereference it and then add a
      suboffset to it. The arrays pointed to can best be seen a regular
      NumPy arrays.

    Adjust buf:
    -----------
      In the original array, buf points to a location (usually the start)
      in the array of pointers. For the sliced array, start[0] can be
      added to buf in the same manner as for NumPy arrays.

    Adjust suboffsets:
    ------------------
      Due to the dereferencing step in the addressing scheme, it is not
      possible to adjust buf for higher dimensions. Recall that the
      sub-arrays pointed to are regular NumPy arrays, so for each of
      those arrays adding start[n] effectively adds the constant:

        c = start[1] * strides[1] + ... + start[ndim-1] * strides[ndim-1]

      This constant is added to suboffsets[0]. suboffsets[0] in turn is
      added to each pointer right after dereferencing.

    Adjust shape and strides:
    -------------------------
      Shape and strides are not influenced by the dereferencing step, so
      they are adjusted in the same manner as for NumPy arrays.

  Multiple levels of suboffsets
  =============================

      For a construct like an array of pointers to array of pointers to
      sub-arrays of ndim-2:

        suboffsets[0] = start[1] * strides[1]
        suboffsets[1] = start[2] * strides[2] + ...
*/
static int
init_slice(Py_buffer *base, PyObject *key, int dim)
{
    Py_ssize_t start, stop, step, slicelength;

    if (PySlice_Unpack(key, &start, &stop, &step) < 0) {
        return -1;
    }
    slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step);


    if (base->suboffsets == NULL || dim == 0) {
    adjust_buf:
        base->buf = (char *)base->buf + base->strides[dim] * start;
    }
    else {
        Py_ssize_t n = dim-1;
        while (n >= 0 && base->suboffsets[n] < 0)
            n--;
        if (n < 0)
            goto adjust_buf; /* all suboffsets are negative */
        base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
    }
    base->shape[dim] = slicelength;
    base->strides[dim] = base->strides[dim] * step;

    return 0;
}

static int
copy_structure(Py_buffer *base)
{
    Py_ssize_t *shape = NULL, *strides = NULL, *suboffsets = NULL;
    Py_ssize_t i;

    shape = PyMem_Malloc(base->ndim * (sizeof *shape));
    strides = PyMem_Malloc(base->ndim * (sizeof *strides));
    if (shape == NULL || strides == NULL)
        goto err_nomem;

    suboffsets = NULL;
    if (base->suboffsets) {
        suboffsets = PyMem_Malloc(base->ndim * (sizeof *suboffsets));
        if (suboffsets == NULL)
            goto err_nomem;
    }

    for (i = 0; i < base->ndim; i++) {
        shape[i] = base->shape[i];
        strides[i] = base->strides[i];
        if (suboffsets)
            suboffsets[i] = base->suboffsets[i];
    }

    base->shape = shape;
    base->strides = strides;
    base->suboffsets = suboffsets;

    return 0;

err_nomem:
    PyErr_NoMemory();
    PyMem_XFree(shape);
    PyMem_XFree(strides);
    PyMem_XFree(suboffsets);
    return -1;
}

static PyObject *
ndarray_subscript(NDArrayObject *self, PyObject *key)
{
    NDArrayObject *nd;
    ndbuf_t *ndbuf;
    Py_buffer *base = &self->head->base;

    if (base->ndim == 0) {
        if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
            return unpack_single(base->buf, base->format, base->itemsize);
        }
        else if (key == Py_Ellipsis) {
            return Py_NewRef(self);
        }
        else {
            PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar");
            return NULL;
        }
    }
    if (PyIndex_Check(key)) {
        Py_ssize_t index = PyLong_AsSsize_t(key);
        if (index == -1 && PyErr_Occurred())
            return NULL;
        return ndarray_item(self, index);
    }

    nd = (NDArrayObject *)ndarray_new(&NDArray_Type, NULL, NULL);
    if (nd == NULL)
        return NULL;

    /* new ndarray is a consumer */
    if (ndarray_init_staticbuf((PyObject *)self, nd, PyBUF_FULL_RO) < 0) {
        Py_DECREF(nd);
        return NULL;
    }

    /* copy shape, strides and suboffsets */
    ndbuf = nd->head;
    base = &ndbuf->base;
    if (copy_structure(base) < 0) {
        Py_DECREF(nd);
        return NULL;
    }
    ndbuf->flags |= ND_OWN_ARRAYS;

    if (PySlice_Check(key)) {
        /* one-dimensional slice */
        if (init_slice(base, key, 0) < 0)
            goto err_occurred;
    }
    else if (PyTuple_Check(key)) {
        /* multi-dimensional slice */
        PyObject *tuple = key;
        Py_ssize_t i, n;

        n = PyTuple_GET_SIZE(tuple);
        for (i = 0; i < n; i++) {
            key = PyTuple_GET_ITEM(tuple, i);
            if (!PySlice_Check(key))
                goto type_error;
            if (init_slice(base, key, (int)i) < 0)
                goto err_occurred;
        }
    }
    else {
        goto type_error;
    }

    init_len(base);
    init_flags(ndbuf);

    return (PyObject *)nd;


type_error:
    PyErr_Format(PyExc_TypeError,
        "cannot index memory using \"%.200s\"",
        Py_TYPE(key)->tp_name);
err_occurred:
    Py_DECREF(nd);
    return NULL;
}


static int
ndarray_ass_subscript(NDArrayObject *self, PyObject *key, PyObject *value)
{
    NDArrayObject *nd;
    Py_buffer *dest = &self->head->base;
    Py_buffer src;
    char *ptr;
    Py_ssize_t index;
    int ret = -1;

    if (dest->readonly) {
        PyErr_SetString(PyExc_TypeError, "ndarray is not writable");
        return -1;
    }
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError, "ndarray data cannot be deleted");
        return -1;
    }
    if (dest->ndim == 0) {
        if (key == Py_Ellipsis ||
            (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0)) {
            ptr = (char *)dest->buf;
            return pack_single(ptr, value, dest->format, dest->itemsize);
        }
        else {
            PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar");
            return -1;
        }
    }
    if (dest->ndim == 1 && PyIndex_Check(key)) {
        /* rvalue must be a single item */
        index = PyLong_AsSsize_t(key);
        if (index == -1 && PyErr_Occurred())
            return -1;
        else {
            ptr = ptr_from_index(dest, index);
            if (ptr == NULL)
                return -1;
        }
        return pack_single(ptr, value, dest->format, dest->itemsize);
    }

    /* rvalue must be an exporter */
    if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) == -1)
        return -1;

    nd = (NDArrayObject *)ndarray_subscript(self, key);
    if (nd != NULL) {
        dest = &nd->head->base;
        ret = copy_buffer(dest, &src);
        Py_DECREF(nd);
    }

    PyBuffer_Release(&src);
    return ret;
}

static PyObject *
slice_indices(PyObject *self, PyObject *args)
{
    PyObject *ret, *key, *tmp;
    Py_ssize_t s[4]; /* start, stop, step, slicelength */
    Py_ssize_t i, len;

    if (!PyArg_ParseTuple(args, "On", &key, &len)) {
        return NULL;
    }
    if (!PySlice_Check(key)) {
        PyErr_SetString(PyExc_TypeError,
            "first argument must be a slice object");
        return NULL;
    }
    if (PySlice_Unpack(key, &s[0], &s[1], &s[2]) < 0) {
        return NULL;
    }
    s[3] = PySlice_AdjustIndices(len, &s[0], &s[1], s[2]);

    ret = PyTuple_New(4);
    if (ret == NULL)
        return NULL;

    for (i = 0; i < 4; i++) {
        tmp = PyLong_FromSsize_t(s[i]);
        if (tmp == NULL)
            goto error;
        PyTuple_SET_ITEM(ret, i, tmp);
    }

    return ret;

error:
    Py_DECREF(ret);
    return NULL;
}


static PyMappingMethods ndarray_as_mapping = {
    NULL,                                 /* mp_length */
    (binaryfunc)ndarray_subscript,        /* mp_subscript */
    (objobjargproc)ndarray_ass_subscript  /* mp_ass_subscript */
};

static PySequenceMethods ndarray_as_sequence = {
        0,                                /* sq_length */
        0,                                /* sq_concat */
        0,                                /* sq_repeat */
        (ssizeargfunc)ndarray_item,       /* sq_item */
};


/**************************************************************************/
/*                                 getters                                */
/**************************************************************************/

static PyObject *
ssize_array_as_tuple(Py_ssize_t *array, Py_ssize_t len)
{
    PyObject *tuple, *x;
    Py_ssize_t i;

    if (array == NULL)
        return PyTuple_New(0);

    tuple = PyTuple_New(len);
    if (tuple == NULL)
        return NULL;

    for (i = 0; i < len; i++) {
        x = PyLong_FromSsize_t(array[i]);
        if (x == NULL) {
            Py_DECREF(tuple);
            return NULL;
        }
        PyTuple_SET_ITEM(tuple, i, x);
    }

    return tuple;
}

static PyObject *
ndarray_get_flags(NDArrayObject *self, void *closure)
{
    return PyLong_FromLong(self->head->flags);
}

static PyObject *
ndarray_get_offset(NDArrayObject *self, void *closure)
{
    ndbuf_t *ndbuf = self->head;
    return PyLong_FromSsize_t(ndbuf->offset);
}

static PyObject *
ndarray_get_obj(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;

    if (base->obj == NULL) {
        Py_RETURN_NONE;
    }
    return Py_NewRef(base->obj);
}

static PyObject *
ndarray_get_nbytes(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return PyLong_FromSsize_t(base->len);
}

static PyObject *
ndarray_get_readonly(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return PyBool_FromLong(base->readonly);
}

static PyObject *
ndarray_get_itemsize(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return PyLong_FromSsize_t(base->itemsize);
}

static PyObject *
ndarray_get_format(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    const char *fmt = base->format ? base->format : "";
    return PyUnicode_FromString(fmt);
}

static PyObject *
ndarray_get_ndim(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return PyLong_FromSsize_t(base->ndim);
}

static PyObject *
ndarray_get_shape(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return ssize_array_as_tuple(base->shape, base->ndim);
}

static PyObject *
ndarray_get_strides(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return ssize_array_as_tuple(base->strides, base->ndim);
}

static PyObject *
ndarray_get_suboffsets(NDArrayObject *self, void *closure)
{
    Py_buffer *base = &self->head->base;
    return ssize_array_as_tuple(base->suboffsets, base->ndim);
}

static PyObject *
ndarray_c_contig(PyObject *self, PyObject *dummy)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    int ret = PyBuffer_IsContiguous(&nd->head->base, 'C');

    if (ret != ND_C_CONTIGUOUS(nd->head->flags)) {
        PyErr_SetString(PyExc_RuntimeError,
            "results from PyBuffer_IsContiguous() and flags differ");
        return NULL;
    }
    return PyBool_FromLong(ret);
}

static PyObject *
ndarray_fortran_contig(PyObject *self, PyObject *dummy)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    int ret = PyBuffer_IsContiguous(&nd->head->base, 'F');

    if (ret != ND_FORTRAN_CONTIGUOUS(nd->head->flags)) {
        PyErr_SetString(PyExc_RuntimeError,
            "results from PyBuffer_IsContiguous() and flags differ");
        return NULL;
    }
    return PyBool_FromLong(ret);
}

static PyObject *
ndarray_contig(PyObject *self, PyObject *dummy)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    int ret = PyBuffer_IsContiguous(&nd->head->base, 'A');

    if (ret != ND_ANY_CONTIGUOUS(nd->head->flags)) {
        PyErr_SetString(PyExc_RuntimeError,
            "results from PyBuffer_IsContiguous() and flags differ");
        return NULL;
    }
    return PyBool_FromLong(ret);
}


static PyGetSetDef ndarray_getset [] =
{
  /* ndbuf */
  { "flags",        (getter)ndarray_get_flags,      NULL, NULL, NULL},
  { "offset",       (getter)ndarray_get_offset,     NULL, NULL, NULL},
  /* ndbuf.base */
  { "obj",          (getter)ndarray_get_obj,        NULL, NULL, NULL},
  { "nbytes",       (getter)ndarray_get_nbytes,     NULL, NULL, NULL},
  { "readonly",     (getter)ndarray_get_readonly,   NULL, NULL, NULL},
  { "itemsize",     (getter)ndarray_get_itemsize,   NULL, NULL, NULL},
  { "format",       (getter)ndarray_get_format,     NULL, NULL, NULL},
  { "ndim",         (getter)ndarray_get_ndim,       NULL, NULL, NULL},
  { "shape",        (getter)ndarray_get_shape,      NULL, NULL, NULL},
  { "strides",      (getter)ndarray_get_strides,    NULL, NULL, NULL},
  { "suboffsets",   (getter)ndarray_get_suboffsets, NULL, NULL, NULL},
  { "c_contiguous", (getter)ndarray_c_contig,       NULL, NULL, NULL},
  { "f_contiguous", (getter)ndarray_fortran_contig, NULL, NULL, NULL},
  { "contiguous",   (getter)ndarray_contig,         NULL, NULL, NULL},
  {NULL}
};

static PyObject *
ndarray_tolist(PyObject *self, PyObject *dummy)
{
    return ndarray_as_list((NDArrayObject *)self);
}

static PyObject *
ndarray_tobytes(PyObject *self, PyObject *dummy)
{
    ndbuf_t *ndbuf = ((NDArrayObject *)self)->head;
    Py_buffer *src = &ndbuf->base;
    Py_buffer dest;
    PyObject *ret = NULL;
    char *mem;

    if (ND_C_CONTIGUOUS(ndbuf->flags))
        return PyBytes_FromStringAndSize(src->buf, src->len);

    assert(src->shape != NULL);
    assert(src->strides != NULL);
    assert(src->ndim > 0);

    mem = PyMem_Malloc(src->len);
    if (mem == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    dest = *src;
    dest.buf = mem;
    dest.suboffsets = NULL;
    dest.strides = strides_from_shape(ndbuf, 0);
    if (dest.strides == NULL)
        goto out;
    if (copy_buffer(&dest, src) < 0)
        goto out;

    ret = PyBytes_FromStringAndSize(mem, src->len);

out:
    PyMem_XFree(dest.strides);
    PyMem_Free(mem);
    return ret;
}

/* add redundant (negative) suboffsets for testing */
static PyObject *
ndarray_add_suboffsets(PyObject *self, PyObject *dummy)
{
    NDArrayObject *nd = (NDArrayObject *)self;
    Py_buffer *base = &nd->head->base;
    Py_ssize_t i;

    if (base->suboffsets != NULL) {
        PyErr_SetString(PyExc_TypeError,
            "cannot add suboffsets to PIL-style array");
            return NULL;
    }
    if (base->strides == NULL) {
        PyErr_SetString(PyExc_TypeError,
            "cannot add suboffsets to array without strides");
            return NULL;
    }

    base->suboffsets = PyMem_Malloc(base->ndim * (sizeof *base->suboffsets));
    if (base->suboffsets == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    for (i = 0; i < base->ndim; i++)
        base->suboffsets[i] = -1;

    nd->head->flags &= ~(ND_C|ND_FORTRAN);

    Py_RETURN_NONE;
}

/* Test PyMemoryView_FromBuffer(): return a memoryview from a static buffer.
   Obviously this is fragile and only one such view may be active at any
   time. Never use anything like this in real code! */
static char *infobuf = NULL;
static PyObject *
ndarray_memoryview_from_buffer(PyObject *self, PyObject *dummy)
{
    const NDArrayObject *nd = (NDArrayObject *)self;
    const Py_buffer *view = &nd->head->base;
    const ndbuf_t *ndbuf;
    static char format[ND_MAX_NDIM+1];
    static Py_ssize_t shape[ND_MAX_NDIM];
    static Py_ssize_t strides[ND_MAX_NDIM];
    static Py_ssize_t suboffsets[ND_MAX_NDIM];
    static Py_buffer info;
    char *p;

    if (!ND_IS_CONSUMER(nd))
        ndbuf = nd->head; /* self is ndarray/original exporter */
    else if (NDArray_Check(view->obj) && !ND_IS_CONSUMER(view->obj))
        /* self is ndarray and consumer from ndarray/original exporter */
        ndbuf = ((NDArrayObject *)view->obj)->head;
    else {
        PyErr_SetString(PyExc_TypeError,
        "memoryview_from_buffer(): ndarray must be original exporter or "
        "consumer from ndarray/original exporter");
         return NULL;
    }

    info = *view;
    p = PyMem_Realloc(infobuf, ndbuf->len);
    if (p == NULL) {
        PyMem_Free(infobuf);
        PyErr_NoMemory();
        infobuf = NULL;
        return NULL;
    }
    else {
        infobuf = p;
    }
    /* copy the complete raw data */
    memcpy(infobuf, ndbuf->data, ndbuf->len);
    info.buf = infobuf + ((char *)view->buf - ndbuf->data);

    if (view->format) {
        if (strlen(view->format) > ND_MAX_NDIM) {
            PyErr_Format(PyExc_TypeError,
                "memoryview_from_buffer: format is limited to %d characters",
                ND_MAX_NDIM);
                return NULL;
        }
        strcpy(format, view->format);
        info.format = format;
    }
    if (view->ndim > ND_MAX_NDIM) {
        PyErr_Format(PyExc_TypeError,
            "memoryview_from_buffer: ndim is limited to %d", ND_MAX_NDIM);
            return NULL;
    }
    if (view->shape) {
        memcpy(shape, view->shape, view->ndim * sizeof(Py_ssize_t));
        info.shape = shape;
    }
    if (view->strides) {
        memcpy(strides, view->strides, view->ndim * sizeof(Py_ssize_t));
        info.strides = strides;
    }
    if (view->suboffsets) {
        memcpy(suboffsets, view->suboffsets, view->ndim * sizeof(Py_ssize_t));
        info.suboffsets = suboffsets;
    }

    return PyMemoryView_FromBuffer(&info);
}

/* Get a single item from bufobj at the location specified by seq.
   seq is a list or tuple of indices. The purpose of this function
   is to check other functions against PyBuffer_GetPointer(). */
static PyObject *
get_pointer(PyObject *self, PyObject *args)
{
    PyObject *ret = NULL, *bufobj, *seq;
    Py_buffer view;
    Py_ssize_t indices[ND_MAX_NDIM];
    Py_ssize_t i;
    void *ptr;

    if (!PyArg_ParseTuple(args, "OO", &bufobj, &seq)) {
        return NULL;
    }

    CHECK_LIST_OR_TUPLE(seq);
    if (PyObject_GetBuffer(bufobj, &view, PyBUF_FULL_RO) < 0)
        return NULL;

    if (view.ndim > ND_MAX_NDIM) {
        PyErr_Format(PyExc_ValueError,
            "get_pointer(): ndim > %d", ND_MAX_NDIM);
        goto out;
    }
    if (PySequence_Fast_GET_SIZE(seq) != view.ndim) {
        PyErr_SetString(PyExc_ValueError,
            "get_pointer(): len(indices) != ndim");
        goto out;
    }

    for (i = 0; i < view.ndim; i++) {
        PyObject *x = PySequence_Fast_GET_ITEM(seq, i);
        indices[i] = PyLong_AsSsize_t(x);
        if (PyErr_Occurred())
            goto out;
        if (indices[i] < 0 || indices[i] >= view.shape[i]) {
            PyErr_Format(PyExc_ValueError,
                "get_pointer(): invalid index %zd at position %zd",
                indices[i], i);
            goto out;
        }
    }

    ptr = PyBuffer_GetPointer(&view, indices);
    ret = unpack_single(ptr, view.format, view.itemsize);

out:
    PyBuffer_Release(&view);
    return ret;
}

static PyObject *
get_sizeof_void_p(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    return PyLong_FromSize_t(sizeof(void *));
}

static char
get_ascii_order(PyObject *order)
{
    PyObject *ascii_order;
    char ord;

    if (!PyUnicode_Check(order)) {
        PyErr_SetString(PyExc_TypeError,
            "order must be a string");
        return CHAR_MAX;
    }

    ascii_order = PyUnicode_AsASCIIString(order);
    if (ascii_order == NULL) {
        return CHAR_MAX;
    }

    ord = PyBytes_AS_STRING(ascii_order)[0];
    Py_DECREF(ascii_order);

    if (ord != 'C' && ord != 'F' && ord != 'A') {
        PyErr_SetString(PyExc_ValueError,
            "invalid order, must be C, F or A");
        return CHAR_MAX;
    }

    return ord;
}

/* Get a contiguous memoryview. */
static PyObject *
get_contiguous(PyObject *self, PyObject *args)
{
    PyObject *obj;
    PyObject *buffertype;
    PyObject *order;
    long type;
    char ord;

    if (!PyArg_ParseTuple(args, "OOO", &obj, &buffertype, &order)) {
        return NULL;
    }

    if (!PyLong_Check(buffertype)) {
        PyErr_SetString(PyExc_TypeError,
            "buffertype must be PyBUF_READ or PyBUF_WRITE");
        return NULL;
    }

    type = PyLong_AsLong(buffertype);
    if (type == -1 && PyErr_Occurred()) {
        return NULL;
    }
    if (type != PyBUF_READ && type != PyBUF_WRITE) {
        PyErr_SetString(PyExc_ValueError,
            "invalid buffer type");
        return NULL;
    }

    ord = get_ascii_order(order);
    if (ord == CHAR_MAX)
        return NULL;

    return PyMemoryView_GetContiguous(obj, (int)type, ord);
}

/* PyBuffer_ToContiguous() */
static PyObject *
py_buffer_to_contiguous(PyObject *self, PyObject *args)
{
    PyObject *obj;
    PyObject *order;
    PyObject *ret = NULL;
    int flags;
    char ord;
    Py_buffer view;
    char *buf = NULL;

    if (!PyArg_ParseTuple(args, "OOi", &obj, &order, &flags)) {
        return NULL;
    }

    if (PyObject_GetBuffer(obj, &view, flags) < 0) {
        return NULL;
    }

    ord = get_ascii_order(order);
    if (ord == CHAR_MAX) {
        goto out;
    }

    buf = PyMem_Malloc(view.len);
    if (buf == NULL) {
        PyErr_NoMemory();
        goto out;
    }

    if (PyBuffer_ToContiguous(buf, &view, view.len, ord) < 0) {
        goto out;
    }

    ret = PyBytes_FromStringAndSize(buf, view.len);

out:
    PyBuffer_Release(&view);
    PyMem_XFree(buf);
    return ret;
}

static int
fmtcmp(const char *fmt1, const char *fmt2)
{
    if (fmt1 == NULL) {
        return fmt2 == NULL || strcmp(fmt2, "B") == 0;
    }
    if (fmt2 == NULL) {
        return fmt1 == NULL || strcmp(fmt1, "B") == 0;
    }
    return strcmp(fmt1, fmt2) == 0;
}

static int
arraycmp(const Py_ssize_t *a1, const Py_ssize_t *a2, const Py_ssize_t *shape,
         Py_ssize_t ndim)
{
    Py_ssize_t i;


    for (i = 0; i < ndim; i++) {
        if (shape && shape[i] <= 1) {
            /* strides can differ if the dimension is less than 2 */
            continue;
        }
        if (a1[i] != a2[i]) {
            return 0;
        }
    }

    return 1;
}

/* Compare two contiguous buffers for physical equality. */
static PyObject *
cmp_contig(PyObject *self, PyObject *args)
{
    PyObject *b1, *b2; /* buffer objects */
    Py_buffer v1, v2;
    PyObject *ret;
    int equal = 0;

    if (!PyArg_ParseTuple(args, "OO", &b1, &b2)) {
        return NULL;
    }

    if (PyObject_GetBuffer(b1, &v1, PyBUF_FULL_RO) < 0) {
        PyErr_SetString(PyExc_TypeError,
            "cmp_contig: first argument does not implement the buffer "
            "protocol");
        return NULL;
    }
    if (PyObject_GetBuffer(b2, &v2, PyBUF_FULL_RO) < 0) {
        PyErr_SetString(PyExc_TypeError,
            "cmp_contig: second argument does not implement the buffer "
            "protocol");
        PyBuffer_Release(&v1);
        return NULL;
    }

    if (!(PyBuffer_IsContiguous(&v1, 'C')&&PyBuffer_IsContiguous(&v2, 'C')) &&
        !(PyBuffer_IsContiguous(&v1, 'F')&&PyBuffer_IsContiguous(&v2, 'F'))) {
        goto result;
    }

    /* readonly may differ if created from non-contiguous */
    if (v1.len != v2.len ||
        v1.itemsize != v2.itemsize ||
        v1.ndim != v2.ndim ||
        !fmtcmp(v1.format, v2.format) ||
        !!v1.shape != !!v2.shape ||
        !!v1.strides != !!v2.strides ||
        !!v1.suboffsets != !!v2.suboffsets) {
        goto result;
    }

    if ((v1.shape && !arraycmp(v1.shape, v2.shape, NULL, v1.ndim)) ||
        (v1.strides && !arraycmp(v1.strides, v2.strides, v1.shape, v1.ndim)) ||
        (v1.suboffsets && !arraycmp(v1.suboffsets, v2.suboffsets, NULL,
                                    v1.ndim))) {
        goto result;
    }

    if (memcmp((char *)v1.buf, (char *)v2.buf, v1.len) != 0) {
        goto result;
    }

    equal = 1;

result:
    PyBuffer_Release(&v1);
    PyBuffer_Release(&v2);

    ret = equal ? Py_True : Py_False;
    return Py_NewRef(ret);
}

static PyObject *
is_contiguous(PyObject *self, PyObject *args)
{
    PyObject *obj;
    PyObject *order;
    PyObject *ret = NULL;
    Py_buffer view, *base;
    char ord;

    if (!PyArg_ParseTuple(args, "OO", &obj, &order)) {
        return NULL;
    }

    ord = get_ascii_order(order);
    if (ord == CHAR_MAX) {
        return NULL;
    }

    if (NDArray_Check(obj)) {
        /* Skip the buffer protocol to check simple etc. buffers directly. */
        base = &((NDArrayObject *)obj)->head->base;
        ret = PyBuffer_IsContiguous(base, ord) ? Py_True : Py_False;
    }
    else {
        if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
            PyErr_SetString(PyExc_TypeError,
                "is_contiguous: object does not implement the buffer "
                "protocol");
            return NULL;
        }
        ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False;
        PyBuffer_Release(&view);
    }

    return Py_NewRef(ret);
}

static Py_hash_t
ndarray_hash(PyObject *self)
{
    const NDArrayObject *nd = (NDArrayObject *)self;
    const Py_buffer *view = &nd->head->base;
    PyObject *bytes;
    Py_hash_t hash;

    if (!view->readonly) {
         PyErr_SetString(PyExc_ValueError,
             "cannot hash writable ndarray object");
         return -1;
    }
    if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
         return -1;
    }

    bytes = ndarray_tobytes(self, NULL);
    if (bytes == NULL) {
        return -1;
    }

    hash = PyObject_Hash(bytes);
    Py_DECREF(bytes);
    return hash;
}


static PyMethodDef ndarray_methods [] =
{
    { "tolist", ndarray_tolist, METH_NOARGS, NULL },
    { "tobytes", ndarray_tobytes, METH_NOARGS, NULL },
    { "push", _PyCFunction_CAST(ndarray_push), METH_VARARGS|METH_KEYWORDS, NULL },
    { "pop", ndarray_pop, METH_NOARGS, NULL },
    { "add_suboffsets", ndarray_add_suboffsets, METH_NOARGS, NULL },
    { "memoryview_from_buffer", ndarray_memoryview_from_buffer, METH_NOARGS, NULL },
    {NULL}
};

static PyTypeObject NDArray_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "ndarray",                   /* Name of this type */
    sizeof(NDArrayObject),       /* Basic object size */
    0,                           /* Item size for varobject */
    (destructor)ndarray_dealloc, /* tp_dealloc */
    0,                           /* tp_vectorcall_offset */
    0,                           /* tp_getattr */
    0,                           /* tp_setattr */
    0,                           /* tp_as_async */
    0,                           /* tp_repr */
    0,                           /* tp_as_number */
    &ndarray_as_sequence,        /* tp_as_sequence */
    &ndarray_as_mapping,         /* tp_as_mapping */
    (hashfunc)ndarray_hash,      /* tp_hash */
    0,                           /* tp_call */
    0,                           /* tp_str */
    PyObject_GenericGetAttr,     /* tp_getattro */
    0,                           /* tp_setattro */
    &ndarray_as_buffer,          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,          /* tp_flags */
    0,                           /* tp_doc */
    0,                           /* tp_traverse */
    0,                           /* tp_clear */
    0,                           /* tp_richcompare */
    0,                           /* tp_weaklistoffset */
    0,                           /* tp_iter */
    0,                           /* tp_iternext */
    ndarray_methods,             /* tp_methods */
    0,                           /* tp_members */
    ndarray_getset,              /* tp_getset */
    0,                           /* tp_base */
    0,                           /* tp_dict */
    0,                           /* tp_descr_get */
    0,                           /* tp_descr_set */
    0,                           /* tp_dictoffset */
    ndarray_init,                /* tp_init */
    0,                           /* tp_alloc */
    ndarray_new,                 /* tp_new */
};

/**************************************************************************/
/*                          StaticArray Object                            */
/**************************************************************************/

static PyTypeObject StaticArray_Type;

typedef struct {
    PyObject_HEAD
    int legacy_mode; /* if true, use the view.obj==NULL hack */
} StaticArrayObject;

static char static_mem[12] = {0,1,2,3,4,5,6,7,8,9,10,11};
static Py_ssize_t static_shape[1] = {12};
static Py_ssize_t static_strides[1] = {1};
static Py_buffer static_buffer = {
    static_mem,     /* buf */
    NULL,           /* obj */
    12,             /* len */
    1,              /* itemsize */
    1,              /* readonly */
    1,              /* ndim */
    "B",            /* format */
    static_shape,   /* shape */
    static_strides, /* strides */
    NULL,           /* suboffsets */
    NULL            /* internal */
};

static PyObject *
staticarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return (PyObject *)PyObject_New(StaticArrayObject, &StaticArray_Type);
}

static int
staticarray_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    StaticArrayObject *a = (StaticArrayObject *)self;
    static char *kwlist[] = {
        "legacy_mode", NULL
    };
    PyObject *legacy_mode = Py_False;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &legacy_mode))
        return -1;

    a->legacy_mode = (legacy_mode != Py_False);
    return 0;
}

static void
staticarray_dealloc(StaticArrayObject *self)
{
    PyObject_Free(self);
}

/* Return a buffer for a PyBUF_FULL_RO request. Flags are not checked,
   which makes this object a non-compliant exporter! */
static int
staticarray_getbuf(StaticArrayObject *self, Py_buffer *view, int flags)
{
    *view = static_buffer;

    if (self->legacy_mode) {
        view->obj = NULL; /* Don't use this in new code. */
    }
    else {
        view->obj = Py_NewRef(self);
    }

    return 0;
}

static PyBufferProcs staticarray_as_buffer = {
    (getbufferproc)staticarray_getbuf, /* bf_getbuffer */
    NULL,                              /* bf_releasebuffer */
};

static PyTypeObject StaticArray_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "staticarray",                   /* Name of this type */
    sizeof(StaticArrayObject),       /* Basic object size */
    0,                               /* Item size for varobject */
    (destructor)staticarray_dealloc, /* tp_dealloc */
    0,                               /* tp_vectorcall_offset */
    0,                               /* tp_getattr */
    0,                               /* tp_setattr */
    0,                               /* tp_as_async */
    0,                               /* tp_repr */
    0,                               /* tp_as_number */
    0,                               /* tp_as_sequence */
    0,                               /* tp_as_mapping */
    0,                               /* tp_hash */
    0,                               /* tp_call */
    0,                               /* tp_str */
    0,                               /* tp_getattro */
    0,                               /* tp_setattro */
    &staticarray_as_buffer,          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,              /* tp_flags */
    0,                               /* tp_doc */
    0,                               /* tp_traverse */
    0,                               /* tp_clear */
    0,                               /* tp_richcompare */
    0,                               /* tp_weaklistoffset */
    0,                               /* tp_iter */
    0,                               /* tp_iternext */
    0,                               /* tp_methods */
    0,                               /* tp_members */
    0,                               /* tp_getset */
    0,                               /* tp_base */
    0,                               /* tp_dict */
    0,                               /* tp_descr_get */
    0,                               /* tp_descr_set */
    0,                               /* tp_dictoffset */
    staticarray_init,                /* tp_init */
    0,                               /* tp_alloc */
    staticarray_new,                 /* tp_new */
};


static struct PyMethodDef _testbuffer_functions[] = {
    {"slice_indices", slice_indices, METH_VARARGS, NULL},
    {"get_pointer", get_pointer, METH_VARARGS, NULL},
    {"get_sizeof_void_p", get_sizeof_void_p, METH_NOARGS, NULL},
    {"get_contiguous", get_contiguous, METH_VARARGS, NULL},
    {"py_buffer_to_contiguous", py_buffer_to_contiguous, METH_VARARGS, NULL},
    {"is_contiguous", is_contiguous, METH_VARARGS, NULL},
    {"cmp_contig", cmp_contig, METH_VARARGS, NULL},
    {NULL, NULL}
};

static struct PyModuleDef _testbuffermodule = {
    PyModuleDef_HEAD_INIT,
    "_testbuffer",
    NULL,
    -1,
    _testbuffer_functions,
    NULL,
    NULL,
    NULL,
    NULL
};

static int
_testbuffer_exec(PyObject *mod)
{
    Py_SET_TYPE(&NDArray_Type, &PyType_Type);
    if (PyType_Ready(&NDArray_Type)) {
        return -1;
    }
    if (PyModule_AddType(mod, &NDArray_Type) < 0) {
        return -1;
    }

    Py_SET_TYPE(&StaticArray_Type, &PyType_Type);
    if (PyModule_AddType(mod, &StaticArray_Type) < 0) {
        return -1;
    }

    structmodule = PyImport_ImportModule("struct");
    if (structmodule == NULL) {
        return -1;
    }

    Struct = PyObject_GetAttrString(structmodule, "Struct");
    if (Struct == NULL) {
        return -1;
    }
    calcsize = PyObject_GetAttrString(structmodule, "calcsize");
    if (calcsize == NULL) {
        return -1;
    }

    simple_format = PyUnicode_FromString(simple_fmt);
    if (simple_format == NULL) {
        return -1;
    }

#define ADD_INT_MACRO(mod, macro)                                             \
    do {                                                                    \
        if (PyModule_AddIntConstant(mod, #macro, macro) < 0) {                \
            return -1;                                                      \
        }                                                                   \
    } while (0)

    ADD_INT_MACRO(mod, ND_MAX_NDIM);
    ADD_INT_MACRO(mod, ND_VAREXPORT);
    ADD_INT_MACRO(mod, ND_WRITABLE);
    ADD_INT_MACRO(mod, ND_FORTRAN);
    ADD_INT_MACRO(mod, ND_SCALAR);
    ADD_INT_MACRO(mod, ND_PIL);
    ADD_INT_MACRO(mod, ND_GETBUF_FAIL);
    ADD_INT_MACRO(mod, ND_GETBUF_UNDEFINED);
    ADD_INT_MACRO(mod, ND_REDIRECT);

    ADD_INT_MACRO(mod, PyBUF_SIMPLE);
    ADD_INT_MACRO(mod, PyBUF_WRITABLE);
    ADD_INT_MACRO(mod, PyBUF_FORMAT);
    ADD_INT_MACRO(mod, PyBUF_ND);
    ADD_INT_MACRO(mod, PyBUF_STRIDES);
    ADD_INT_MACRO(mod, PyBUF_INDIRECT);
    ADD_INT_MACRO(mod, PyBUF_C_CONTIGUOUS);
    ADD_INT_MACRO(mod, PyBUF_F_CONTIGUOUS);
    ADD_INT_MACRO(mod, PyBUF_ANY_CONTIGUOUS);
    ADD_INT_MACRO(mod, PyBUF_FULL);
    ADD_INT_MACRO(mod, PyBUF_FULL_RO);
    ADD_INT_MACRO(mod, PyBUF_RECORDS);
    ADD_INT_MACRO(mod, PyBUF_RECORDS_RO);
    ADD_INT_MACRO(mod, PyBUF_STRIDED);
    ADD_INT_MACRO(mod, PyBUF_STRIDED_RO);
    ADD_INT_MACRO(mod, PyBUF_CONTIG);
    ADD_INT_MACRO(mod, PyBUF_CONTIG_RO);

    ADD_INT_MACRO(mod, PyBUF_READ);
    ADD_INT_MACRO(mod, PyBUF_WRITE);

#undef ADD_INT_MACRO

    return 0;
}

PyMODINIT_FUNC
PyInit__testbuffer(void)
{
    PyObject *mod = PyModule_Create(&_testbuffermodule);
    if (mod == NULL) {
        return NULL;
    }
#ifdef Py_GIL_DISABLED
    PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED);
#endif
    if (_testbuffer_exec(mod) < 0) {
        Py_DECREF(mod);
        return NULL;
    }
    return mod;
}
