1 /////////////// ArrayAPI.proto ///////////////
2
3 // arrayarray.h
4 //
5 // Artificial C-API for Python's <array.array> type,
6 // used by array.pxd
7 //
8 // last changes: 2009-05-15 rk
9 // 2012-05-02 andreasvc
10 // (see revision control)
11 //
12
13 #ifndef _ARRAYARRAY_H
14 #define _ARRAYARRAY_H
15
16 // These two forward declarations are explicitly handled in the type
17 // declaration code, as including them here is too late for cython-defined
18 // types to use them.
19 // struct arrayobject;
20 // typedef struct arrayobject arrayobject;
21
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 {
26 int typecode;
27 int itemsize;
28 PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
29 int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
30 #if PY_MAJOR_VERSION >= 3
31 char *formats;
32 #endif
33 } arraydescr;
34
35
36 struct arrayobject {
37 PyObject_HEAD
38 Py_ssize_t ob_size;
39 union {
40 char *ob_item;
41 float *as_floats;
42 double *as_doubles;
43 int *as_ints;
44 unsigned int *as_uints;
45 unsigned char *as_uchars;
46 signed char *as_schars;
47 char *as_chars;
48 unsigned long *as_ulongs;
49 long *as_longs;
50 #if PY_MAJOR_VERSION >= 3
51 unsigned long long *as_ulonglongs;
52 long long *as_longlongs;
53 #endif
54 short *as_shorts;
55 unsigned short *as_ushorts;
56 Py_UNICODE *as_pyunicodes;
57 void *as_voidptr;
58 } data;
59 Py_ssize_t allocated;
60 struct arraydescr *ob_descr;
61 PyObject *weakreflist; /* List of weak references */
62 #if PY_MAJOR_VERSION >= 3
63 int ob_exports; /* Number of exported buffers */
64 #endif
65 };
66
67 #ifndef NO_NEWARRAY_INLINE
68 // fast creation of a new array
newarrayobject(PyTypeObject * type,Py_ssize_t size,struct arraydescr * descr)69 static CYTHON_INLINE PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size,
70 struct arraydescr *descr) {
71 arrayobject *op;
72 size_t nbytes;
73
74 if (size < 0) {
75 PyErr_BadInternalCall();
76 return NULL;
77 }
78
79 nbytes = size * descr->itemsize;
80 // Check for overflow
81 if (nbytes / descr->itemsize != (size_t)size) {
82 return PyErr_NoMemory();
83 }
84 op = (arrayobject *) type->tp_alloc(type, 0);
85 if (op == NULL) {
86 return NULL;
87 }
88 op->ob_descr = descr;
89 op->allocated = size;
90 op->weakreflist = NULL;
91 __Pyx_SET_SIZE(op, size);
92 if (size <= 0) {
93 op->data.ob_item = NULL;
94 }
95 else {
96 op->data.ob_item = PyMem_NEW(char, nbytes);
97 if (op->data.ob_item == NULL) {
98 Py_DECREF(op);
99 return PyErr_NoMemory();
100 }
101 }
102 return (PyObject *) op;
103 }
104 #else
105 PyObject* newarrayobject(PyTypeObject *type, Py_ssize_t size,
106 struct arraydescr *descr);
107 #endif /* ifndef NO_NEWARRAY_INLINE */
108
109 // fast resize (reallocation to the point)
110 // not designed for filing small increments (but for fast opaque array apps)
resize(arrayobject * self,Py_ssize_t n)111 static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) {
112 void *items = (void*) self->data.ob_item;
113 PyMem_Resize(items, char, (size_t)(n * self->ob_descr->itemsize));
114 if (items == NULL) {
115 PyErr_NoMemory();
116 return -1;
117 }
118 self->data.ob_item = (char*) items;
119 __Pyx_SET_SIZE(self, n);
120 self->allocated = n;
121 return 0;
122 }
123
124 // suitable for small increments; over allocation 50% ;
resize_smart(arrayobject * self,Py_ssize_t n)125 static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) {
126 void *items = (void*) self->data.ob_item;
127 Py_ssize_t newsize;
128 if (n < self->allocated && n*4 > self->allocated) {
129 __Pyx_SET_SIZE(self, n);
130 return 0;
131 }
132 newsize = n + (n / 2) + 1;
133 if (newsize <= n) { /* overflow */
134 PyErr_NoMemory();
135 return -1;
136 }
137 PyMem_Resize(items, char, (size_t)(newsize * self->ob_descr->itemsize));
138 if (items == NULL) {
139 PyErr_NoMemory();
140 return -1;
141 }
142 self->data.ob_item = (char*) items;
143 __Pyx_SET_SIZE(self, n);
144 self->allocated = newsize;
145 return 0;
146 }
147
148 #endif
149 /* _ARRAYARRAY_H */
150