Ticket #314: arrayarray.h

File arrayarray.h, 3.5 KB (added by rk, 6 years ago)
Line 
1/* arrayarray.h 
2
3    artificial C-API for Python's
4    <array.array> type.
5    copy this file to your -I path, e.g. .../pythonXX/include
6    See array.pxd next to this file
7   
8    last changes: 2009-05-14 rk
9
10*/
11
12#ifndef _ARRAYARRAY_H
13#define _ARRAYARRAY_H
14
15#include <Python.h>
16
17struct arrayobject; /* Forward */
18
19/* All possible arraydescr values are defined in the vector "descriptors"
20 * below.  That's defined later because the appropriate get and set
21 * functions aren't visible yet.
22 */
23typedef struct arraydescr {
24        int typecode;
25        int itemsize;
26        PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
27        int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
28} arraydescr;
29
30#if PY_VERSION_HEX < 0x02040000
31typedef struct arrayobject {
32        PyObject_HEAD
33        int ob_size;
34        char *ob_item;
35        struct arraydescr *ob_descr;
36} arrayobject;
37#else
38typedef struct arrayobject {
39        PyObject_HEAD       //includes ob_size!
40    union {
41        int ob_size;
42        unsigned length;
43    };
44    union {
45            char *ob_item;
46        float *_f;
47        double *_d;
48        int *_i;
49        unsigned *_I;
50        unsigned char *_B;
51        signed char *_b;
52        char *_c;
53        unsigned long *_L;
54        long *_l;
55        short *_h;
56        unsigned short *_H;
57        Py_UNICODE *_u;
58    };
59        Py_ssize_t allocated;
60        struct arraydescr *ob_descr;
61        PyObject *weakreflist; /* List of weak references */
62} arrayobject;
63#endif
64
65
66#ifndef NO_NEWARRAY_INLINE
67/*
68 *
69 *  fast creation of a new array - init with zeros
70 */
71 
72static inline PyObject *
73newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
74{
75        arrayobject *op;
76        size_t nbytes;
77
78        if (size < 0) {
79                PyErr_BadInternalCall();
80                return NULL;
81        }
82
83        nbytes = size * descr->itemsize;
84        /* Check for overflow */
85        if (nbytes / descr->itemsize != (size_t)size) {
86                return PyErr_NoMemory();
87        }
88        op = (arrayobject *) type->tp_alloc(type, 0);
89        if (op == NULL) {
90                return NULL;
91        }
92        op->ob_descr = descr;
93#if !( PY_VERSION_HEX < 0x02040000 )
94        op->allocated = size;
95        op->weakreflist = NULL;
96#endif
97        Py_SIZE(op) = size;
98        if (size <= 0) {
99                op->ob_item = NULL;
100        }
101        else {
102                op->ob_item = PyMem_NEW(char, nbytes);
103                if (op->ob_item == NULL) {
104                        Py_DECREF(op);
105                        return PyErr_NoMemory();
106                }
107//      memset(op->ob_item,0,nbytes);  // only in new_array_zeros
108        }
109        return (PyObject *) op;
110}
111#else
112PyObject *
113newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr);
114#endif
115
116// fast resize (realloc to the point)
117// not designed for filing small increments (but for fast opaque array apps)
118static inline void resize_array(arrayobject *self, Py_ssize_t n) 
119{
120    self->ob_item = PyMem_Realloc(self->ob_item, n * self->ob_descr->itemsize);
121    self->ob_size = n;
122#if PY_VERSION_HEX >= 0x02040000
123    self->allocated = n;  //$23
124#endif
125}
126
127#if PY_VERSION_HEX >= 0x02040000
128// suitable for small increments; over-alloc 50%
129static inline void resize_array_smart(arrayobject *self, Py_ssize_t n) 
130{
131    if (n < self->allocated) 
132        if (n*4 > self->allocated) {
133            self->ob_size = n;
134            return;
135        }
136    Py_ssize_t newsize = n  * 3 / 2 + 1;
137    self->ob_item = PyMem_Realloc(self->ob_item, newsize * self->ob_descr->itemsize );
138    self->ob_size = n;
139    self->allocated = newsize;  //$23
140}
141#endif
142
143
144// hack for Cython 2D buffer view set-up; needs GIL only during setup
145static Py_ssize_t _viewhelper_shape2=0; 
146
147#endif
148/* _ARRAYARRAY_H */