15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/////////////// ArrayAPI.proto /////////////// 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// arrayarray.h 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Artificial C-API for Python's <array.array> type, 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// used by array.pxd 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// last changes: 2009-05-15 rk 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 2012-05-02 andreasvc 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// (see revision control) 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef _ARRAYARRAY_H 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define _ARRAYARRAY_H 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// These two forward declarations are explicitly handled in the type 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// declaration code, as including them here is too late for cython-defined 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// types to use them. 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// struct arrayobject; 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// typedef struct arrayobject arrayobject; 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// All possible arraydescr values are defined in the vector "descriptors" 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// below. That's defined later because the appropriate get and set 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// functions aren't visible yet. 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)typedef struct arraydescr { 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int typecode; 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int itemsize; 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if PY_VERSION_HEX >= 0x03000000 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *formats; 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} arraydescr; 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct arrayobject { 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyObject_HEAD 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_ssize_t ob_size; 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) union { 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *ob_item; 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) float *as_floats; 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) double *as_doubles; 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int *as_ints; 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned int *as_uints; 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned char *as_uchars; 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) signed char *as_schars; 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *as_chars; 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned long *as_ulongs; 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) long *as_longs; 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) short *as_shorts; 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned short *as_ushorts; 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_UNICODE *as_pyunicodes; 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void *as_voidptr; 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } data; 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_ssize_t allocated; 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct arraydescr *ob_descr; 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyObject *weakreflist; /* List of weak references */ 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if PY_VERSION_HEX >= 0x03000000 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int ob_exports; /* Number of exported buffers */ 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef NO_NEWARRAY_INLINE 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// fast creation of a new array 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static CYTHON_INLINE PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size, 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct arraydescr *descr) { 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arrayobject *op; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t nbytes; 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (size < 0) { 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyErr_BadInternalCall(); 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nbytes = size * descr->itemsize; 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Check for overflow 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (nbytes / descr->itemsize != (size_t)size) { 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyErr_NoMemory(); 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op = (arrayobject *) type->tp_alloc(type, 0); 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (op == NULL) { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op->ob_descr = descr; 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op->allocated = size; 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op->weakreflist = NULL; 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op->ob_size = size; 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (size <= 0) { 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op->data.ob_item = NULL; 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else { 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op->data.ob_item = PyMem_NEW(char, nbytes); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (op->data.ob_item == NULL) { 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_DECREF(op); 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyErr_NoMemory(); 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return (PyObject *) op; 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PyObject* newarrayobject(PyTypeObject *type, Py_ssize_t size, 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct arraydescr *descr); 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif /* ifndef NO_NEWARRAY_INLINE */ 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// fast resize (reallocation to the point) 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// not designed for filing small increments (but for fast opaque array apps) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) { 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void *items = (void*) self->data.ob_item; 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyMem_Resize(items, char, (size_t)(n * self->ob_descr->itemsize)); 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (items == NULL) { 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyErr_NoMemory(); 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return -1; 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->data.ob_item = (char*) items; 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->ob_size = n; 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->allocated = n; 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// suitable for small increments; over allocation 50% ; 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Remains non-smart in Python 2.3- ; but exists for compatibility 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) { 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void *items = (void*) self->data.ob_item; 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_ssize_t newsize; 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (n < self->allocated) { 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (n*4 > self->allocated) { 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->ob_size = n; 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) newsize = n * 3 / 2 + 1; 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyMem_Resize(items, char, (size_t)(newsize * self->ob_descr->itemsize)); 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (items == NULL) { 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyErr_NoMemory(); 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return -1; 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->data.ob_item = (char*) items; 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->ob_size = n; 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self->allocated = newsize; 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/* _ARRAYARRAY_H */ 145