OLD | NEW |
(Empty) | |
| 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_VERSION_HEX >= 0x03000000 |
| 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 short *as_shorts; |
| 51 unsigned short *as_ushorts; |
| 52 Py_UNICODE *as_pyunicodes; |
| 53 void *as_voidptr; |
| 54 } data; |
| 55 Py_ssize_t allocated; |
| 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 */ |
| 60 #endif |
| 61 }; |
| 62 |
| 63 #ifndef NO_NEWARRAY_INLINE |
| 64 // fast creation of a new array |
| 65 static CYTHON_INLINE PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t si
ze, |
| 66 struct arraydescr *descr) { |
| 67 arrayobject *op; |
| 68 size_t nbytes; |
| 69 |
| 70 if (size < 0) { |
| 71 PyErr_BadInternalCall(); |
| 72 return NULL; |
| 73 } |
| 74 |
| 75 nbytes = size * descr->itemsize; |
| 76 // Check for overflow |
| 77 if (nbytes / descr->itemsize != (size_t)size) { |
| 78 return PyErr_NoMemory(); |
| 79 } |
| 80 op = (arrayobject *) type->tp_alloc(type, 0); |
| 81 if (op == NULL) { |
| 82 return NULL; |
| 83 } |
| 84 op->ob_descr = descr; |
| 85 op->allocated = size; |
| 86 op->weakreflist = NULL; |
| 87 op->ob_size = size; |
| 88 if (size <= 0) { |
| 89 op->data.ob_item = NULL; |
| 90 } |
| 91 else { |
| 92 op->data.ob_item = PyMem_NEW(char, nbytes); |
| 93 if (op->data.ob_item == NULL) { |
| 94 Py_DECREF(op); |
| 95 return PyErr_NoMemory(); |
| 96 } |
| 97 } |
| 98 return (PyObject *) op; |
| 99 } |
| 100 #else |
| 101 PyObject* newarrayobject(PyTypeObject *type, Py_ssize_t size, |
| 102 struct arraydescr *descr); |
| 103 #endif /* ifndef NO_NEWARRAY_INLINE */ |
| 104 |
| 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)); |
| 110 if (items == NULL) { |
| 111 PyErr_NoMemory(); |
| 112 return -1; |
| 113 } |
| 114 self->data.ob_item = (char*) items; |
| 115 self->ob_size = n; |
| 116 self->allocated = n; |
| 117 return 0; |
| 118 } |
| 119 |
| 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; |
| 124 Py_ssize_t newsize; |
| 125 if (n < self->allocated) { |
| 126 if (n*4 > self->allocated) { |
| 127 self->ob_size = n; |
| 128 return 0; |
| 129 } |
| 130 } |
| 131 newsize = n * 3 / 2 + 1; |
| 132 PyMem_Resize(items, char, (size_t)(newsize * self->ob_descr->itemsize)); |
| 133 if (items == NULL) { |
| 134 PyErr_NoMemory(); |
| 135 return -1; |
| 136 } |
| 137 self->data.ob_item = (char*) items; |
| 138 self->ob_size = n; |
| 139 self->allocated = newsize; |
| 140 return 0; |
| 141 } |
| 142 |
| 143 #endif |
| 144 /* _ARRAYARRAY_H */ |
OLD | NEW |