## arrays and pointers
(c_double * 4, "<d", (4,), c_double),
+ (c_double * 0, "<d", (0,), c_double),
(c_float * 4 * 3 * 2, "<f", (2,3,4), c_float),
+ (c_float * 4 * 0 * 2, "<f", (2,0,4), c_float),
(POINTER(c_short) * 2, "&<" + s_short, (2,), POINTER(c_short)),
(POINTER(c_short) * 2 * 3, "&<" + s_short, (3,2,), POINTER(c_short)),
(POINTER(c_short * 2), "&(2)<" + s_short, (), POINTER(c_short)),
{ NULL },
};
-static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
+/* Find the innermost type of an array type, returning a borrowed reference */
+static PyObject *
+PyCData_item_type(PyObject *type)
+{
+ if (PyCArrayTypeObject_Check(type)) {
+ StgDictObject *stg_dict;
+ PyObject *elem_type;
+
+ /* asserts used here as these are all guaranteed by construction */
+ stg_dict = PyType_stgdict(type);
+ assert(stg_dict);
+ elem_type = stg_dict->proto;
+ assert(elem_type);
+ return PyCData_item_type(elem_type);
+ }
+ else {
+ return type;
+ }
+}
+
+static int
+PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
{
CDataObject *self = (CDataObject *)myself;
StgDictObject *dict = PyObject_stgdict(myself);
- Py_ssize_t i;
+ PyObject *item_type = PyCData_item_type((PyObject*)Py_TYPE(myself));
+ StgDictObject *item_dict = PyType_stgdict(item_type);
if (view == NULL) return 0;
view->format = dict->format ? dict->format : "B";
view->ndim = dict->ndim;
view->shape = dict->shape;
- view->itemsize = self->b_size;
- if (view->itemsize) {
- for (i = 0; i < view->ndim; ++i) {
- view->itemsize /= dict->shape[i];
- }
- }
+ view->itemsize = item_dict->size;
view->strides = NULL;
view->suboffsets = NULL;
view->internal = NULL;