1 /////////////// ArrayAPI.proto ///////////////
5 // Artificial C-API for Python's <array.array> type,
8 // last changes: 2009-05-15 rk
9 // 2012-05-02 andreasvc
10 // (see revision control)
16 // These two forward declarations are explicitly handled in the type
17 // declaration code, as including them here is too late for cython-defined
19 // struct arrayobject;
20 // typedef struct arrayobject arrayobject;
22 // All possible arraydescr values are defined in the vector "descriptors"
23 // below. That's defined later because the appropriate get and set
24 // functions aren't visible yet.
25 typedef struct arraydescr
{
28 PyObject
* (*getitem
)(struct arrayobject
*, Py_ssize_t
);
29 int (*setitem
)(struct arrayobject
*, Py_ssize_t
, PyObject
*);
30 #if PY_VERSION_HEX >= 0x03000000
44 unsigned int *as_uints
;
45 unsigned char *as_uchars
;
46 signed char *as_schars
;
48 unsigned long *as_ulongs
;
51 unsigned short *as_ushorts
;
52 Py_UNICODE
*as_pyunicodes
;
56 struct arraydescr
*ob_descr
;
57 PyObject
*weakreflist
; /* List of weak references */
58 #if PY_VERSION_HEX >= 0x03000000
59 int ob_exports
; /* Number of exported buffers */
63 #ifndef NO_NEWARRAY_INLINE
64 // fast creation of a new array
65 static CYTHON_INLINE PyObject
* newarrayobject(PyTypeObject
*type
, Py_ssize_t size
,
66 struct arraydescr
*descr
) {
71 PyErr_BadInternalCall();
75 nbytes
= size
* descr
->itemsize
;
77 if (nbytes
/ descr
->itemsize
!= (size_t)size
) {
78 return PyErr_NoMemory();
80 op
= (arrayobject
*) type
->tp_alloc(type
, 0);
86 op
->weakreflist
= NULL
;
89 op
->data
.ob_item
= NULL
;
92 op
->data
.ob_item
= PyMem_NEW(char, nbytes
);
93 if (op
->data
.ob_item
== NULL
) {
95 return PyErr_NoMemory();
98 return (PyObject
*) op
;
101 PyObject
* newarrayobject(PyTypeObject
*type
, Py_ssize_t size
,
102 struct arraydescr
*descr
);
103 #endif /* ifndef NO_NEWARRAY_INLINE */
105 // fast resize (reallocation to the point)
106 // not designed for filing small increments (but for fast opaque array apps)
107 static CYTHON_INLINE
int resize(arrayobject
*self
, Py_ssize_t n
) {
108 void *items
= (void*) self
->data
.ob_item
;
109 PyMem_Resize(items
, char, (size_t)(n
* self
->ob_descr
->itemsize
));
114 self
->data
.ob_item
= (char*) items
;
120 // suitable for small increments; over allocation 50% ;
121 // Remains non-smart in Python 2.3- ; but exists for compatibility
122 static CYTHON_INLINE
int resize_smart(arrayobject
*self
, Py_ssize_t n
) {
123 void *items
= (void*) self
->data
.ob_item
;
125 if (n
< self
->allocated
) {
126 if (n
*4 > self
->allocated
) {
131 newsize
= n
* 3 / 2 + 1;
132 PyMem_Resize(items
, char, (size_t)(newsize
* self
->ob_descr
->itemsize
));
137 self
->data
.ob_item
= (char*) items
;
139 self
->allocated
= newsize
;