blob: 991fdc22e3f56a80da5e4e529b18f4e1c0c826d3 [file] [log] [blame]
Guido van Rossum778983b1993-02-19 15:55:02 +00001/* Array object implementation */
2
3/* An array is a uniform list -- all items have the same type.
4 The item type is restricted to simple C types like int or float */
5
Roger E. Masse2919eaa1996-12-09 20:10:36 +00006#include "Python.h"
Roger E. Masse5817f8f1996-12-09 22:24:19 +00007
Guido van Rossum0c709541994-08-19 12:01:32 +00008#ifdef STDC_HEADERS
9#include <stddef.h>
Guido van Rossum7f1de831999-08-27 20:33:52 +000010#else /* !STDC_HEADERS */
11#ifndef DONT_HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000012#include <sys/types.h> /* For size_t */
Guido van Rossum7f1de831999-08-27 20:33:52 +000013#endif /* DONT_HAVE_SYS_TYPES_H */
14#endif /* !STDC_HEADERS */
Guido van Rossumdb677392000-07-01 01:09:43 +000015#ifdef HAVE_LIMITS_H
16#include <limits.h>
17#endif /* HAVE_LIMITS_H */
Guido van Rossum778983b1993-02-19 15:55:02 +000018
19struct arrayobject; /* Forward */
20
Tim Petersbb307342000-09-10 05:22:54 +000021/* All possible arraydescr values are defined in the vector "descriptors"
22 * below. That's defined later because the appropriate get and set
23 * functions aren't visible yet.
24 */
Guido van Rossum778983b1993-02-19 15:55:02 +000025struct arraydescr {
26 int typecode;
27 int itemsize;
Tim Petersdbd9ba62000-07-09 03:09:57 +000028 PyObject * (*getitem)(struct arrayobject *, int);
29 int (*setitem)(struct arrayobject *, int, PyObject *);
Guido van Rossum778983b1993-02-19 15:55:02 +000030};
31
32typedef struct arrayobject {
Roger E. Masse2919eaa1996-12-09 20:10:36 +000033 PyObject_VAR_HEAD
Guido van Rossum778983b1993-02-19 15:55:02 +000034 char *ob_item;
35 struct arraydescr *ob_descr;
36} arrayobject;
37
Roger E. Masse2919eaa1996-12-09 20:10:36 +000038staticforward PyTypeObject Arraytype;
Guido van Rossum778983b1993-02-19 15:55:02 +000039
40#define is_arrayobject(op) ((op)->ob_type == &Arraytype)
41
Tim Petersbb307342000-09-10 05:22:54 +000042/****************************************************************************
43Get and Set functions for each type.
44A Get function takes an arrayobject* and an integer index, returning the
45array value at that index wrapped in an appropriate PyObject*.
46A Set function takes an arrayobject, integer index, and PyObject*; sets
47the array value at that index to the raw C data extracted from the PyObject*,
48and returns 0 if successful, else nonzero on failure (PyObject* not of an
49appropriate type or value).
50Note that the basic Get and Set functions do NOT check that the index is
51in bounds; that's the responsibility of the caller.
52****************************************************************************/
Guido van Rossum778983b1993-02-19 15:55:02 +000053
Roger E. Masse2919eaa1996-12-09 20:10:36 +000054static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +000055c_getitem(arrayobject *ap, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +000056{
Roger E. Masse2919eaa1996-12-09 20:10:36 +000057 return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
Guido van Rossum778983b1993-02-19 15:55:02 +000058}
59
60static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +000061c_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +000062{
63 char x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +000064 if (!PyArg_Parse(v, "c;array item must be char", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +000065 return -1;
66 if (i >= 0)
67 ((char *)ap->ob_item)[i] = x;
68 return 0;
69}
70
Roger E. Masse2919eaa1996-12-09 20:10:36 +000071static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +000072b_getitem(arrayobject *ap, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +000073{
74 long x = ((char *)ap->ob_item)[i];
75 if (x >= 128)
76 x -= 256;
Roger E. Masse2919eaa1996-12-09 20:10:36 +000077 return PyInt_FromLong(x);
Guido van Rossum778983b1993-02-19 15:55:02 +000078}
79
80static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +000081b_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +000082{
Fred Drake541dc3b2000-06-28 17:49:30 +000083 short x;
84 /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
85 must use the next size up that is signed ('h') and manually do
86 the overflow checking */
87 if (!PyArg_Parse(v, "h;array item must be integer", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +000088 return -1;
Guido van Rossum9f754e02000-07-01 00:38:19 +000089 else if (x < -128) {
Fred Drake541dc3b2000-06-28 17:49:30 +000090 PyErr_SetString(PyExc_OverflowError,
91 "signed char is less than minimum");
92 return -1;
93 }
Guido van Rossum9f754e02000-07-01 00:38:19 +000094 else if (x > 127) {
Fred Drake541dc3b2000-06-28 17:49:30 +000095 PyErr_SetString(PyExc_OverflowError,
96 "signed char is greater than maximum");
97 return -1;
98 }
Guido van Rossum778983b1993-02-19 15:55:02 +000099 if (i >= 0)
Fred Drake541dc3b2000-06-28 17:49:30 +0000100 ((char *)ap->ob_item)[i] = (char)x;
Guido van Rossum778983b1993-02-19 15:55:02 +0000101 return 0;
102}
103
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000104static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000105BB_getitem(arrayobject *ap, int i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000106{
107 long x = ((unsigned char *)ap->ob_item)[i];
108 return PyInt_FromLong(x);
109}
110
Fred Drake541dc3b2000-06-28 17:49:30 +0000111static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000112BB_setitem(arrayobject *ap, int i, PyObject *v)
Fred Drake541dc3b2000-06-28 17:49:30 +0000113{
114 unsigned char x;
115 /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
116 if (!PyArg_Parse(v, "b;array item must be integer", &x))
117 return -1;
118 if (i >= 0)
119 ((char *)ap->ob_item)[i] = x;
120 return 0;
121}
Guido van Rossum549ab711997-01-03 19:09:47 +0000122
123static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000124h_getitem(arrayobject *ap, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000125{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000126 return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000127}
128
129static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000130h_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000131{
132 short x;
Fred Drake541dc3b2000-06-28 17:49:30 +0000133 /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000134 if (!PyArg_Parse(v, "h;array item must be integer", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000135 return -1;
136 if (i >= 0)
137 ((short *)ap->ob_item)[i] = x;
138 return 0;
139}
140
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000141static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000142HH_getitem(arrayobject *ap, int i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000143{
144 return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
145}
146
Fred Drake541dc3b2000-06-28 17:49:30 +0000147static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000148HH_setitem(arrayobject *ap, int i, PyObject *v)
Fred Drake541dc3b2000-06-28 17:49:30 +0000149{
150 int x;
151 /* PyArg_Parse's 'h' formatter is for a signed short, therefore
152 must use the next size up and manually do the overflow checking */
153 if (!PyArg_Parse(v, "i;array item must be integer", &x))
154 return -1;
155 else if (x < 0) {
156 PyErr_SetString(PyExc_OverflowError,
157 "unsigned short is less than minimum");
158 return -1;
159 }
160 else if (x > USHRT_MAX) {
161 PyErr_SetString(PyExc_OverflowError,
162 "unsigned short is greater than maximum");
163 return -1;
164 }
165 if (i >= 0)
166 ((short *)ap->ob_item)[i] = (short)x;
167 return 0;
168}
Guido van Rossum549ab711997-01-03 19:09:47 +0000169
170static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000171i_getitem(arrayobject *ap, int i)
Guido van Rossume77a7571993-11-03 15:01:26 +0000172{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000173 return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
Guido van Rossume77a7571993-11-03 15:01:26 +0000174}
175
176static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000177i_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossume77a7571993-11-03 15:01:26 +0000178{
179 int x;
Fred Drake541dc3b2000-06-28 17:49:30 +0000180 /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000181 if (!PyArg_Parse(v, "i;array item must be integer", &x))
Guido van Rossume77a7571993-11-03 15:01:26 +0000182 return -1;
183 if (i >= 0)
184 ((int *)ap->ob_item)[i] = x;
185 return 0;
186}
187
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000188static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000189II_getitem(arrayobject *ap, int i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000190{
191 return PyLong_FromUnsignedLong(
192 (unsigned long) ((unsigned int *)ap->ob_item)[i]);
193}
194
195static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000196II_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum549ab711997-01-03 19:09:47 +0000197{
198 unsigned long x;
199 if (PyLong_Check(v)) {
200 x = PyLong_AsUnsignedLong(v);
201 if (x == (unsigned long) -1 && PyErr_Occurred())
202 return -1;
203 }
204 else {
Fred Drake541dc3b2000-06-28 17:49:30 +0000205 long y;
206 if (!PyArg_Parse(v, "l;array item must be integer", &y))
Guido van Rossum549ab711997-01-03 19:09:47 +0000207 return -1;
Fred Drake541dc3b2000-06-28 17:49:30 +0000208 if (y < 0) {
209 PyErr_SetString(PyExc_OverflowError,
210 "unsigned int is less than minimum");
211 return -1;
212 }
213 x = (unsigned long)y;
Tim Petersbb307342000-09-10 05:22:54 +0000214
Guido van Rossum549ab711997-01-03 19:09:47 +0000215 }
Fred Drake541dc3b2000-06-28 17:49:30 +0000216 if (x > UINT_MAX) {
217 PyErr_SetString(PyExc_OverflowError,
218 "unsigned int is greater than maximum");
219 return -1;
220 }
221
Guido van Rossum549ab711997-01-03 19:09:47 +0000222 if (i >= 0)
Fred Drake541dc3b2000-06-28 17:49:30 +0000223 ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
Guido van Rossum549ab711997-01-03 19:09:47 +0000224 return 0;
225}
226
227static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000228l_getitem(arrayobject *ap, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000229{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000230 return PyInt_FromLong(((long *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000231}
232
233static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000234l_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000235{
236 long x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000237 if (!PyArg_Parse(v, "l;array item must be integer", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000238 return -1;
239 if (i >= 0)
240 ((long *)ap->ob_item)[i] = x;
241 return 0;
242}
243
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000244static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000245LL_getitem(arrayobject *ap, int i)
Guido van Rossum549ab711997-01-03 19:09:47 +0000246{
247 return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
248}
249
250static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000251LL_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum549ab711997-01-03 19:09:47 +0000252{
253 unsigned long x;
254 if (PyLong_Check(v)) {
255 x = PyLong_AsUnsignedLong(v);
256 if (x == (unsigned long) -1 && PyErr_Occurred())
257 return -1;
258 }
259 else {
Fred Drake541dc3b2000-06-28 17:49:30 +0000260 long y;
261 if (!PyArg_Parse(v, "l;array item must be integer", &y))
Guido van Rossum549ab711997-01-03 19:09:47 +0000262 return -1;
Fred Drake541dc3b2000-06-28 17:49:30 +0000263 if (y < 0) {
264 PyErr_SetString(PyExc_OverflowError,
265 "unsigned long is less than minimum");
266 return -1;
267 }
268 x = (unsigned long)y;
Tim Petersbb307342000-09-10 05:22:54 +0000269
Guido van Rossum549ab711997-01-03 19:09:47 +0000270 }
Fred Drake541dc3b2000-06-28 17:49:30 +0000271 if (x > ULONG_MAX) {
272 PyErr_SetString(PyExc_OverflowError,
273 "unsigned long is greater than maximum");
274 return -1;
275 }
Tim Petersbb307342000-09-10 05:22:54 +0000276
Guido van Rossum549ab711997-01-03 19:09:47 +0000277 if (i >= 0)
278 ((unsigned long *)ap->ob_item)[i] = x;
279 return 0;
280}
281
282static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000283f_getitem(arrayobject *ap, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000284{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000285 return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000286}
287
288static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000289f_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000290{
291 float x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000292 if (!PyArg_Parse(v, "f;array item must be float", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000293 return -1;
294 if (i >= 0)
295 ((float *)ap->ob_item)[i] = x;
296 return 0;
297}
298
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000299static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000300d_getitem(arrayobject *ap, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000301{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000302 return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000303}
304
305static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000306d_setitem(arrayobject *ap, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000307{
308 double x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000309 if (!PyArg_Parse(v, "d;array item must be float", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000310 return -1;
311 if (i >= 0)
312 ((double *)ap->ob_item)[i] = x;
313 return 0;
314}
315
316/* Description of types */
Guido van Rossum234f9421993-06-17 12:35:49 +0000317static struct arraydescr descriptors[] = {
Guido van Rossum778983b1993-02-19 15:55:02 +0000318 {'c', sizeof(char), c_getitem, c_setitem},
319 {'b', sizeof(char), b_getitem, b_setitem},
Guido van Rossum1a747f81997-05-16 16:21:38 +0000320 {'B', sizeof(char), BB_getitem, BB_setitem},
Guido van Rossum778983b1993-02-19 15:55:02 +0000321 {'h', sizeof(short), h_getitem, h_setitem},
Guido van Rossum1a747f81997-05-16 16:21:38 +0000322 {'H', sizeof(short), HH_getitem, HH_setitem},
Guido van Rossume77a7571993-11-03 15:01:26 +0000323 {'i', sizeof(int), i_getitem, i_setitem},
Guido van Rossum1a747f81997-05-16 16:21:38 +0000324 {'I', sizeof(int), II_getitem, II_setitem},
Guido van Rossum778983b1993-02-19 15:55:02 +0000325 {'l', sizeof(long), l_getitem, l_setitem},
Guido van Rossum1a747f81997-05-16 16:21:38 +0000326 {'L', sizeof(long), LL_getitem, LL_setitem},
Guido van Rossum778983b1993-02-19 15:55:02 +0000327 {'f', sizeof(float), f_getitem, f_setitem},
328 {'d', sizeof(double), d_getitem, d_setitem},
329 {'\0', 0, 0, 0} /* Sentinel */
330};
Tim Petersbb307342000-09-10 05:22:54 +0000331
332/****************************************************************************
333Implementations of array object methods.
334****************************************************************************/
Guido van Rossum778983b1993-02-19 15:55:02 +0000335
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000336static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000337newarrayobject(int size, struct arraydescr *descr)
Guido van Rossum778983b1993-02-19 15:55:02 +0000338{
Guido van Rossum778983b1993-02-19 15:55:02 +0000339 arrayobject *op;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000340 size_t nbytes;
Guido van Rossum778983b1993-02-19 15:55:02 +0000341 if (size < 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000342 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000343 return NULL;
344 }
345 nbytes = size * descr->itemsize;
346 /* Check for overflow */
Guido van Rossum7844e381997-04-11 20:44:04 +0000347 if (nbytes / descr->itemsize != (size_t)size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000348 return PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000349 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000350 op = PyObject_NewVar(arrayobject, &Arraytype, size);
Guido van Rossum778983b1993-02-19 15:55:02 +0000351 if (op == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000352 return PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000353 }
354 if (size <= 0) {
355 op->ob_item = NULL;
356 }
357 else {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000358 op->ob_item = PyMem_NEW(char, nbytes);
Guido van Rossum778983b1993-02-19 15:55:02 +0000359 if (op->ob_item == NULL) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000360 PyObject_Del(op);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000361 return PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000362 }
363 }
Guido van Rossum778983b1993-02-19 15:55:02 +0000364 op->ob_descr = descr;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000365 return (PyObject *) op;
Guido van Rossum778983b1993-02-19 15:55:02 +0000366}
367
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000368static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000369getarrayitem(PyObject *op, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000370{
371 register arrayobject *ap;
Tim Petersbb307342000-09-10 05:22:54 +0000372 assert(is_arrayobject(op));
Guido van Rossum778983b1993-02-19 15:55:02 +0000373 ap = (arrayobject *)op;
374 if (i < 0 || i >= ap->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000375 PyErr_SetString(PyExc_IndexError, "array index out of range");
Guido van Rossum778983b1993-02-19 15:55:02 +0000376 return NULL;
377 }
378 return (*ap->ob_descr->getitem)(ap, i);
379}
380
381static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000382ins1(arrayobject *self, int where, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000383{
Guido van Rossum778983b1993-02-19 15:55:02 +0000384 char *items;
385 if (v == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000386 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000387 return -1;
388 }
389 if ((*self->ob_descr->setitem)(self, -1, v) < 0)
390 return -1;
391 items = self->ob_item;
Roger E. Masse5817f8f1996-12-09 22:24:19 +0000392 PyMem_RESIZE(items, char,
393 (self->ob_size+1) * self->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000394 if (items == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000395 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000396 return -1;
397 }
398 if (where < 0)
399 where = 0;
400 if (where > self->ob_size)
401 where = self->ob_size;
402 memmove(items + (where+1)*self->ob_descr->itemsize,
403 items + where*self->ob_descr->itemsize,
404 (self->ob_size-where)*self->ob_descr->itemsize);
405 self->ob_item = items;
406 self->ob_size++;
407 return (*self->ob_descr->setitem)(self, where, v);
408}
409
Guido van Rossum778983b1993-02-19 15:55:02 +0000410/* Methods */
411
412static void
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000413array_dealloc(arrayobject *op)
Guido van Rossum778983b1993-02-19 15:55:02 +0000414{
Guido van Rossum778983b1993-02-19 15:55:02 +0000415 if (op->ob_item != NULL)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000416 PyMem_DEL(op->ob_item);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000417 PyObject_Del(op);
Guido van Rossum778983b1993-02-19 15:55:02 +0000418}
419
420static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000421array_compare(arrayobject *v, arrayobject *w)
Guido van Rossum778983b1993-02-19 15:55:02 +0000422{
423 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
424 int i;
425 for (i = 0; i < len; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000426 PyObject *ai, *bi;
Guido van Rossum778983b1993-02-19 15:55:02 +0000427 int cmp;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000428 ai = getarrayitem((PyObject *)v, i);
429 bi = getarrayitem((PyObject *)w, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000430 if (ai && bi)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000431 cmp = PyObject_Compare(ai, bi);
Guido van Rossum778983b1993-02-19 15:55:02 +0000432 else
433 cmp = -1;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000434 Py_XDECREF(ai);
435 Py_XDECREF(bi);
Guido van Rossumc8b6df91997-05-23 00:06:51 +0000436 if (cmp != 0)
Guido van Rossum778983b1993-02-19 15:55:02 +0000437 return cmp;
Guido van Rossum778983b1993-02-19 15:55:02 +0000438 }
439 return v->ob_size - w->ob_size;
440}
441
442static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000443array_length(arrayobject *a)
Guido van Rossum778983b1993-02-19 15:55:02 +0000444{
445 return a->ob_size;
446}
447
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000448static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000449array_item(arrayobject *a, int i)
Guido van Rossum778983b1993-02-19 15:55:02 +0000450{
451 if (i < 0 || i >= a->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000452 PyErr_SetString(PyExc_IndexError, "array index out of range");
Guido van Rossum778983b1993-02-19 15:55:02 +0000453 return NULL;
454 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000455 return getarrayitem((PyObject *)a, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000456}
457
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000458static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000459array_slice(arrayobject *a, int ilow, int ihigh)
Guido van Rossum778983b1993-02-19 15:55:02 +0000460{
461 arrayobject *np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000462 if (ilow < 0)
463 ilow = 0;
464 else if (ilow > a->ob_size)
465 ilow = a->ob_size;
466 if (ihigh < 0)
467 ihigh = 0;
468 if (ihigh < ilow)
469 ihigh = ilow;
470 else if (ihigh > a->ob_size)
471 ihigh = a->ob_size;
472 np = (arrayobject *) newarrayobject(ihigh - ilow, a->ob_descr);
473 if (np == NULL)
474 return NULL;
475 memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
476 (ihigh-ilow) * a->ob_descr->itemsize);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000477 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000478}
479
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000480static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000481array_concat(arrayobject *a, PyObject *bb)
Guido van Rossum778983b1993-02-19 15:55:02 +0000482{
483 int size;
Guido van Rossum778983b1993-02-19 15:55:02 +0000484 arrayobject *np;
485 if (!is_arrayobject(bb)) {
Fred Drake137507e2000-06-01 02:02:46 +0000486 PyErr_Format(PyExc_TypeError,
487 "can only append array (not \"%.200s\") to array",
488 bb->ob_type->tp_name);
Guido van Rossum778983b1993-02-19 15:55:02 +0000489 return NULL;
490 }
491#define b ((arrayobject *)bb)
492 if (a->ob_descr != b->ob_descr) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000493 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000494 return NULL;
495 }
496 size = a->ob_size + b->ob_size;
497 np = (arrayobject *) newarrayobject(size, a->ob_descr);
498 if (np == NULL) {
499 return NULL;
500 }
501 memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
502 memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
Guido van Rossum32be3a71993-11-05 10:16:27 +0000503 b->ob_item, b->ob_size*b->ob_descr->itemsize);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000504 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000505#undef b
506}
507
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000508static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000509array_repeat(arrayobject *a, int n)
Guido van Rossum778983b1993-02-19 15:55:02 +0000510{
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000511 int i;
Guido van Rossum778983b1993-02-19 15:55:02 +0000512 int size;
513 arrayobject *np;
514 char *p;
515 int nbytes;
516 if (n < 0)
517 n = 0;
518 size = a->ob_size * n;
519 np = (arrayobject *) newarrayobject(size, a->ob_descr);
520 if (np == NULL)
521 return NULL;
522 p = np->ob_item;
523 nbytes = a->ob_size * a->ob_descr->itemsize;
524 for (i = 0; i < n; i++) {
525 memcpy(p, a->ob_item, nbytes);
526 p += nbytes;
527 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000528 return (PyObject *) np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000529}
530
531static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000532array_ass_slice(arrayobject *a, int ilow, int ihigh, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000533{
534 char *item;
535 int n; /* Size of replacement array */
536 int d; /* Change in size */
Guido van Rossum778983b1993-02-19 15:55:02 +0000537#define b ((arrayobject *)v)
538 if (v == NULL)
539 n = 0;
540 else if (is_arrayobject(v)) {
541 n = b->ob_size;
542 if (a == b) {
543 /* Special case "a[i:j] = a" -- copy b first */
544 int ret;
545 v = array_slice(b, 0, n);
546 ret = array_ass_slice(a, ilow, ihigh, v);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000547 Py_DECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +0000548 return ret;
549 }
550 if (b->ob_descr != a->ob_descr) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000551 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000552 return -1;
553 }
554 }
555 else {
Fred Drake137507e2000-06-01 02:02:46 +0000556 PyErr_Format(PyExc_TypeError,
557 "can only assign array (not \"%.200s\") to array slice",
558 v->ob_type->tp_name);
Guido van Rossum778983b1993-02-19 15:55:02 +0000559 return -1;
560 }
561 if (ilow < 0)
562 ilow = 0;
563 else if (ilow > a->ob_size)
564 ilow = a->ob_size;
565 if (ihigh < 0)
566 ihigh = 0;
567 if (ihigh < ilow)
568 ihigh = ilow;
569 else if (ihigh > a->ob_size)
570 ihigh = a->ob_size;
571 item = a->ob_item;
572 d = n - (ihigh-ilow);
573 if (d < 0) { /* Delete -d items */
574 memmove(item + (ihigh+d)*a->ob_descr->itemsize,
575 item + ihigh*a->ob_descr->itemsize,
576 (a->ob_size-ihigh)*a->ob_descr->itemsize);
577 a->ob_size += d;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000578 PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000579 /* Can't fail */
580 a->ob_item = item;
581 }
582 else if (d > 0) { /* Insert d items */
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000583 PyMem_RESIZE(item, char,
584 (a->ob_size + d)*a->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000585 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000586 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000587 return -1;
588 }
589 memmove(item + (ihigh+d)*a->ob_descr->itemsize,
590 item + ihigh*a->ob_descr->itemsize,
591 (a->ob_size-ihigh)*a->ob_descr->itemsize);
592 a->ob_item = item;
593 a->ob_size += d;
594 }
595 if (n > 0)
596 memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
597 n*b->ob_descr->itemsize);
598 return 0;
599#undef b
600}
601
602static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000603array_ass_item(arrayobject *a, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000604{
605 if (i < 0 || i >= a->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000606 PyErr_SetString(PyExc_IndexError,
607 "array assignment index out of range");
Guido van Rossum778983b1993-02-19 15:55:02 +0000608 return -1;
609 }
610 if (v == NULL)
611 return array_ass_slice(a, i, i+1, v);
612 return (*a->ob_descr->setitem)(a, i, v);
613}
614
615static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000616setarrayitem(PyObject *a, int i, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000617{
Tim Petersbb307342000-09-10 05:22:54 +0000618 assert(is_arrayobject(a));
Guido van Rossum778983b1993-02-19 15:55:02 +0000619 return array_ass_item((arrayobject *)a, i, v);
620}
621
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000622static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000623ins(arrayobject *self, int where, PyObject *v)
Guido van Rossum778983b1993-02-19 15:55:02 +0000624{
625 if (ins1(self, where, v) != 0)
626 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000627 Py_INCREF(Py_None);
628 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000629}
630
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000631static PyObject *
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000632array_count(arrayobject *self, PyObject *args)
633{
634 int count = 0;
635 int i;
636 PyObject *v;
637
638 if (!PyArg_ParseTuple(args, "O:count", &v))
639 return NULL;
640 for (i = 0; i < self->ob_size; i++) {
641 PyObject *selfi = getarrayitem((PyObject *)self, i);
642 if (PyObject_Compare(selfi, v) == 0)
643 count++;
644 Py_DECREF(selfi);
645 if (PyErr_Occurred())
646 return NULL;
647 }
648 return PyInt_FromLong((long)count);
649}
650
651static char count_doc [] =
Tim Peters077a11d2000-09-16 22:31:29 +0000652"count(x)\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000653\n\
654Return number of occurences of x in the array.";
655
656static PyObject *
657array_index(arrayobject *self, PyObject *args)
658{
659 int i;
660 PyObject *v;
661
662 if (!PyArg_ParseTuple(args, "O:index", &v))
663 return NULL;
664 for (i = 0; i < self->ob_size; i++) {
665 PyObject *selfi = getarrayitem((PyObject *)self, i);
666 if (PyObject_Compare(selfi, v) == 0) {
667 Py_DECREF(selfi);
668 return PyInt_FromLong((long)i);
669 }
670 Py_DECREF(selfi);
671 if (PyErr_Occurred())
672 return NULL;
673 }
674 PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
675 return NULL;
676}
677
678static char index_doc [] =
Tim Peters077a11d2000-09-16 22:31:29 +0000679"index(x)\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000680\n\
681Return index of first occurence of x in the array.";
682
683static PyObject *
684array_remove(arrayobject *self, PyObject *args)
685{
686 int i;
687 PyObject *v;
688
689 if (!PyArg_ParseTuple(args, "O:remove", &v))
690 return NULL;
691 for (i = 0; i < self->ob_size; i++) {
692 PyObject *selfi = getarrayitem((PyObject *)self,i);
693 if (PyObject_Compare(selfi, v) == 0) {
694 Py_DECREF(selfi);
695 if (array_ass_slice(self, i, i+1,
696 (PyObject *)NULL) != 0)
697 return NULL;
698 Py_INCREF(Py_None);
699 return Py_None;
700 }
701 Py_DECREF(selfi);
702 if (PyErr_Occurred())
703 return NULL;
704 }
705 PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
706 return NULL;
707}
708
709static char remove_doc [] =
Tim Peters077a11d2000-09-16 22:31:29 +0000710"remove(x)\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000711\n\
712Remove the first occurence of x in the array.";
713
714static PyObject *
715array_pop(arrayobject *self, PyObject *args)
716{
717 int i = -1;
718 PyObject *v;
719 if (!PyArg_ParseTuple(args, "|i:pop", &i))
720 return NULL;
721 if (self->ob_size == 0) {
722 /* Special-case most common failure cause */
723 PyErr_SetString(PyExc_IndexError, "pop from empty array");
724 return NULL;
725 }
726 if (i < 0)
727 i += self->ob_size;
728 if (i < 0 || i >= self->ob_size) {
729 PyErr_SetString(PyExc_IndexError, "pop index out of range");
730 return NULL;
731 }
732 v = getarrayitem((PyObject *)self,i);
733 if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
734 Py_DECREF(v);
735 return NULL;
736 }
737 return v;
738}
739
740static char pop_doc [] =
Tim Peters077a11d2000-09-16 22:31:29 +0000741"pop([i])\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000742\n\
743Return the i-th element and delete it from the array. i defaults to -1.";
744
745static PyObject *
Fred Drake8ce159a2000-08-31 05:18:54 +0000746array_extend(arrayobject *self, PyObject *args)
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000747{
748 int size;
749 PyObject *bb;
Tim Petersbb307342000-09-10 05:22:54 +0000750
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000751 if (!PyArg_ParseTuple(args, "O:extend", &bb))
752 return NULL;
Tim Petersbb307342000-09-10 05:22:54 +0000753
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000754 if (!is_arrayobject(bb)) {
755 PyErr_Format(PyExc_TypeError,
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +0000756 "can only extend array with array (not \"%.200s\")",
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000757 bb->ob_type->tp_name);
758 return NULL;
759 }
760#define b ((arrayobject *)bb)
761 if (self->ob_descr != b->ob_descr) {
762 PyErr_SetString(PyExc_TypeError,
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +0000763 "can only extend with array of same kind");
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +0000764 return NULL;
765 }
766 size = self->ob_size + b->ob_size;
767 PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
768 if (self->ob_item == NULL) {
769 PyObject_Del(self);
770 return PyErr_NoMemory();
771 }
772 memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
773 b->ob_item, b->ob_size*b->ob_descr->itemsize);
774 self->ob_size = size;
775 Py_INCREF(Py_None);
776 return Py_None;
777#undef b
778}
779
780static char extend_doc [] =
781"extend(array)\n\
782\n\
783 Append array items to the end of the array.";
784
785static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000786array_insert(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000787{
788 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000789 PyObject *v;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +0000790 if (!PyArg_ParseTuple(args, "iO:insert", &i, &v))
Guido van Rossum778983b1993-02-19 15:55:02 +0000791 return NULL;
792 return ins(self, i, v);
793}
794
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000795static char insert_doc [] =
Tim Peters077a11d2000-09-16 22:31:29 +0000796"insert(i,x)\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000797\n\
798Insert a new item x into the array before position i.";
799
800
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000801static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000802array_buffer_info(arrayobject *self, PyObject *args)
Guido van Rossumde4a4ca1997-08-12 14:55:56 +0000803{
Tim Peters077a11d2000-09-16 22:31:29 +0000804 PyObject* retval = NULL;
805 if (!PyArg_ParseTuple(args, ":buffer_info"))
806 return NULL;
807 retval = PyTuple_New(2);
808 if (!retval)
809 return NULL;
Fred Drake541dc3b2000-06-28 17:49:30 +0000810
811 PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
812 PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
813
814 return retval;
Guido van Rossumde4a4ca1997-08-12 14:55:56 +0000815}
816
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000817static char buffer_info_doc [] =
Tim Peters077a11d2000-09-16 22:31:29 +0000818"buffer_info() -> (address, length)\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000819\n\
820Return a tuple (address, length) giving the current memory address and\n\
821the length in bytes of the buffer used to hold array's contents.";
822
823
Guido van Rossumde4a4ca1997-08-12 14:55:56 +0000824static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000825array_append(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000826{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000827 PyObject *v;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +0000828 if (!PyArg_ParseTuple(args, "O:append", &v))
Guido van Rossum778983b1993-02-19 15:55:02 +0000829 return NULL;
830 return ins(self, (int) self->ob_size, v);
831}
832
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000833static char append_doc [] =
834"append(x)\n\
835\n\
836Append new value x to the end of the array.";
837
838
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000839static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000840array_byteswap(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000841{
842 char *p;
843 int i;
Fred Drakebf272981999-12-03 17:15:30 +0000844
845 if (!PyArg_ParseTuple(args, ":byteswap"))
846 return NULL;
847
Guido van Rossum778983b1993-02-19 15:55:02 +0000848 switch (self->ob_descr->itemsize) {
849 case 1:
850 break;
851 case 2:
852 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
853 char p0 = p[0];
854 p[0] = p[1];
855 p[1] = p0;
856 }
857 break;
858 case 4:
859 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
860 char p0 = p[0];
861 char p1 = p[1];
862 p[0] = p[3];
863 p[1] = p[2];
864 p[2] = p1;
865 p[3] = p0;
866 }
867 break;
Guido van Rossume77a7571993-11-03 15:01:26 +0000868 case 8:
869 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
870 char p0 = p[0];
871 char p1 = p[1];
872 char p2 = p[2];
873 char p3 = p[3];
874 p[0] = p[7];
875 p[1] = p[6];
876 p[2] = p[5];
877 p[3] = p[4];
878 p[4] = p3;
879 p[5] = p2;
880 p[6] = p1;
881 p[7] = p0;
882 }
883 break;
Guido van Rossum778983b1993-02-19 15:55:02 +0000884 default:
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000885 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum778983b1993-02-19 15:55:02 +0000886 "don't know how to byteswap this array type");
887 return NULL;
888 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000889 Py_INCREF(Py_None);
890 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000891}
892
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000893static char byteswap_doc [] =
Fred Drakebf272981999-12-03 17:15:30 +0000894"byteswap()\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000895\n\
Fred Drakebf272981999-12-03 17:15:30 +0000896Byteswap all items of the array. If the items in the array are not 1, 2,\n\
8974, or 8 bytes in size, RuntimeError is raised.";
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000898
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000899static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000900array_reverse(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000901{
Guido van Rossume77a7571993-11-03 15:01:26 +0000902 register int itemsize = self->ob_descr->itemsize;
903 register char *p, *q;
Tim Peters077a11d2000-09-16 22:31:29 +0000904 /* little buffer to hold items while swapping */
905 char tmp[256]; /* 8 is probably enough -- but why skimp */
906 assert(itemsize <= sizeof(tmp));
Guido van Rossume77a7571993-11-03 15:01:26 +0000907
Tim Peters077a11d2000-09-16 22:31:29 +0000908 if (!PyArg_ParseTuple(args, ":reverse"))
909 return NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +0000910
911 if (self->ob_size > 1) {
Guido van Rossume77a7571993-11-03 15:01:26 +0000912 for (p = self->ob_item,
913 q = self->ob_item + (self->ob_size - 1)*itemsize;
914 p < q;
915 p += itemsize, q -= itemsize) {
Tim Peters077a11d2000-09-16 22:31:29 +0000916 /* memory areas guaranteed disjoint, so memcpy
917 * is safe (& memmove may be slower).
918 */
919 memcpy(tmp, p, itemsize);
920 memcpy(p, q, itemsize);
921 memcpy(q, tmp, itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000922 }
923 }
Tim Petersbb307342000-09-10 05:22:54 +0000924
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000925 Py_INCREF(Py_None);
926 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000927}
Guido van Rossume77a7571993-11-03 15:01:26 +0000928
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000929static char reverse_doc [] =
930"reverse()\n\
931\n\
932Reverse the order of the items in the array.";
933
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000934static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000935array_fromfile(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000936{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000937 PyObject *f;
Guido van Rossum778983b1993-02-19 15:55:02 +0000938 int n;
939 FILE *fp;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +0000940 if (!PyArg_ParseTuple(args, "Oi:fromfile", &f, &n))
Guido van Rossum778983b1993-02-19 15:55:02 +0000941 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000942 fp = PyFile_AsFile(f);
Guido van Rossum778983b1993-02-19 15:55:02 +0000943 if (fp == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000944 PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
Guido van Rossum778983b1993-02-19 15:55:02 +0000945 return NULL;
946 }
947 if (n > 0) {
948 char *item = self->ob_item;
949 int itemsize = self->ob_descr->itemsize;
Guido van Rossum7d0ae5e2000-06-28 21:27:21 +0000950 size_t nread;
Guido van Rossum3791b0d1999-02-23 18:05:22 +0000951 int newlength;
952 size_t newbytes;
953 /* Be careful here about overflow */
954 if ((newlength = self->ob_size + n) <= 0 ||
Guido van Rossum481ac881999-03-19 21:50:11 +0000955 (newbytes = newlength * itemsize) / itemsize !=
956 (size_t)newlength)
Guido van Rossum3791b0d1999-02-23 18:05:22 +0000957 goto nomem;
958 PyMem_RESIZE(item, char, newbytes);
Guido van Rossum778983b1993-02-19 15:55:02 +0000959 if (item == NULL) {
Guido van Rossum3791b0d1999-02-23 18:05:22 +0000960 nomem:
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000961 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000962 return NULL;
963 }
964 self->ob_item = item;
965 self->ob_size += n;
966 nread = fread(item + (self->ob_size - n) * itemsize,
967 itemsize, n, fp);
Guido van Rossum7d0ae5e2000-06-28 21:27:21 +0000968 if (nread < (size_t)n) {
Guido van Rossum778983b1993-02-19 15:55:02 +0000969 self->ob_size -= (n - nread);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000970 PyMem_RESIZE(item, char, self->ob_size*itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000971 self->ob_item = item;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000972 PyErr_SetString(PyExc_EOFError,
973 "not enough items in file");
Guido van Rossum778983b1993-02-19 15:55:02 +0000974 return NULL;
975 }
976 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000977 Py_INCREF(Py_None);
978 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000979}
980
Guido van Rossumb39b90d1998-10-13 14:27:22 +0000981static char fromfile_doc [] =
982"fromfile(f, n)\n\
983\n\
984Read n objects from the file object f and append them to the end of the\n\
985array. Also called as read.";
986
987
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000988static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +0000989array_tofile(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000990{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000991 PyObject *f;
Guido van Rossum778983b1993-02-19 15:55:02 +0000992 FILE *fp;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +0000993 if (!PyArg_ParseTuple(args, "O:tofile", &f))
Guido van Rossum778983b1993-02-19 15:55:02 +0000994 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000995 fp = PyFile_AsFile(f);
Guido van Rossum778983b1993-02-19 15:55:02 +0000996 if (fp == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000997 PyErr_SetString(PyExc_TypeError, "arg must be open file");
Guido van Rossum778983b1993-02-19 15:55:02 +0000998 return NULL;
999 }
1000 if (self->ob_size > 0) {
Trent Mick6c116dd2000-08-12 20:58:11 +00001001 if (fwrite(self->ob_item, self->ob_descr->itemsize,
1002 self->ob_size, fp) != (size_t)self->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001003 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum778983b1993-02-19 15:55:02 +00001004 clearerr(fp);
1005 return NULL;
1006 }
1007 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001008 Py_INCREF(Py_None);
1009 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +00001010}
1011
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001012static char tofile_doc [] =
1013"tofile(f)\n\
1014\n\
1015Write all items (as machine values) to the file object f. Also called as\n\
1016write.";
1017
1018
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001019static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001020array_fromlist(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +00001021{
1022 int n;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001023 PyObject *list;
Guido van Rossum778983b1993-02-19 15:55:02 +00001024 int itemsize = self->ob_descr->itemsize;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001025 if (!PyArg_ParseTuple(args, "O:fromlist", &list))
Guido van Rossum778983b1993-02-19 15:55:02 +00001026 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001027 if (!PyList_Check(list)) {
1028 PyErr_SetString(PyExc_TypeError, "arg must be list");
Guido van Rossum778983b1993-02-19 15:55:02 +00001029 return NULL;
1030 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001031 n = PyList_Size(list);
Guido van Rossum778983b1993-02-19 15:55:02 +00001032 if (n > 0) {
1033 char *item = self->ob_item;
1034 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001035 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +00001036 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001037 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +00001038 return NULL;
1039 }
1040 self->ob_item = item;
1041 self->ob_size += n;
1042 for (i = 0; i < n; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001043 PyObject *v = PyList_GetItem(list, i);
Guido van Rossum778983b1993-02-19 15:55:02 +00001044 if ((*self->ob_descr->setitem)(self,
1045 self->ob_size - n + i, v) != 0) {
1046 self->ob_size -= n;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001047 PyMem_RESIZE(item, char,
1048 self->ob_size * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +00001049 self->ob_item = item;
1050 return NULL;
1051 }
1052 }
1053 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001054 Py_INCREF(Py_None);
1055 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +00001056}
1057
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001058static char fromlist_doc [] =
1059"fromlist(list)\n\
1060\n\
1061Append items to array from list.";
1062
1063
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001064static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001065array_tolist(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +00001066{
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001067 PyObject *list = PyList_New(self->ob_size);
Guido van Rossum778983b1993-02-19 15:55:02 +00001068 int i;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001069 if (!PyArg_ParseTuple(args, ":tolist"))
1070 return NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00001071 if (list == NULL)
1072 return NULL;
1073 for (i = 0; i < self->ob_size; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001074 PyObject *v = getarrayitem((PyObject *)self, i);
Guido van Rossum778983b1993-02-19 15:55:02 +00001075 if (v == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001076 Py_DECREF(list);
Guido van Rossum778983b1993-02-19 15:55:02 +00001077 return NULL;
1078 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001079 PyList_SetItem(list, i, v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001080 }
1081 return list;
1082}
1083
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001084static char tolist_doc [] =
Guido van Rossumfc6aba51998-10-14 02:52:31 +00001085"tolist() -> list\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001086\n\
1087Convert array to an ordinary list with the same items.";
1088
1089
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001090static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001091array_fromstring(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +00001092{
1093 char *str;
1094 int n;
1095 int itemsize = self->ob_descr->itemsize;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001096 if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n))
Guido van Rossum778983b1993-02-19 15:55:02 +00001097 return NULL;
1098 if (n % itemsize != 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001099 PyErr_SetString(PyExc_ValueError,
Guido van Rossum778983b1993-02-19 15:55:02 +00001100 "string length not a multiple of item size");
1101 return NULL;
1102 }
1103 n = n / itemsize;
1104 if (n > 0) {
1105 char *item = self->ob_item;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001106 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +00001107 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001108 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +00001109 return NULL;
1110 }
1111 self->ob_item = item;
1112 self->ob_size += n;
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001113 memcpy(item + (self->ob_size - n) * itemsize,
1114 str, itemsize*n);
Guido van Rossum778983b1993-02-19 15:55:02 +00001115 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001116 Py_INCREF(Py_None);
1117 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +00001118}
1119
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001120static char fromstring_doc [] =
1121"fromstring(string)\n\
1122\n\
1123Appends items from the string, interpreting it as an array of machine\n\
1124values,as if it had been read from a file using the fromfile() method).";
1125
1126
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001127static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001128array_tostring(arrayobject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +00001129{
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001130 if (!PyArg_ParseTuple(args, ":tostring"))
Guido van Rossum778983b1993-02-19 15:55:02 +00001131 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001132 return PyString_FromStringAndSize(self->ob_item,
Guido van Rossum778983b1993-02-19 15:55:02 +00001133 self->ob_size * self->ob_descr->itemsize);
1134}
1135
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001136static char tostring_doc [] =
1137"tostring() -> string\n\
1138\n\
1139Convert the array to an array of machine values and return the string\n\
1140representation.";
1141
1142PyMethodDef array_methods[] = {
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001143 {"append", (PyCFunction)array_append, METH_VARARGS, append_doc},
1144 {"buffer_info", (PyCFunction)array_buffer_info, METH_VARARGS, buffer_info_doc},
1145 {"byteswap", (PyCFunction)array_byteswap, METH_VARARGS, byteswap_doc},
1146 {"count", (PyCFunction)array_count, METH_VARARGS, count_doc},
1147 {"extend", (PyCFunction)array_extend, METH_VARARGS, extend_doc},
1148 {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS, fromfile_doc},
1149 {"fromlist", (PyCFunction)array_fromlist, METH_VARARGS, fromlist_doc},
1150 {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS, fromstring_doc},
1151 {"index", (PyCFunction)array_index, METH_VARARGS, index_doc},
1152 {"insert", (PyCFunction)array_insert, METH_VARARGS, insert_doc},
1153 {"pop", (PyCFunction)array_pop, METH_VARARGS, pop_doc},
1154 {"read", (PyCFunction)array_fromfile, METH_VARARGS, fromfile_doc},
1155 {"remove", (PyCFunction)array_remove, METH_VARARGS, remove_doc},
1156 {"reverse", (PyCFunction)array_reverse, METH_VARARGS, reverse_doc},
1157/* {"sort", (PyCFunction)array_sort, METH_VARARGS, sort_doc},*/
1158 {"tofile", (PyCFunction)array_tofile, METH_VARARGS, tofile_doc},
1159 {"tolist", (PyCFunction)array_tolist, METH_VARARGS, tolist_doc},
1160 {"tostring", (PyCFunction)array_tostring, METH_VARARGS, tostring_doc},
1161 {"write", (PyCFunction)array_tofile, METH_VARARGS, tofile_doc},
Guido van Rossum778983b1993-02-19 15:55:02 +00001162 {NULL, NULL} /* sentinel */
1163};
1164
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001165static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001166array_getattr(arrayobject *a, char *name)
Guido van Rossum778983b1993-02-19 15:55:02 +00001167{
1168 if (strcmp(name, "typecode") == 0) {
1169 char tc = a->ob_descr->typecode;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001170 return PyString_FromStringAndSize(&tc, 1);
Guido van Rossum778983b1993-02-19 15:55:02 +00001171 }
1172 if (strcmp(name, "itemsize") == 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001173 return PyInt_FromLong((long)a->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +00001174 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001175 if (strcmp(name, "__members__") == 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001176 PyObject *list = PyList_New(2);
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001177 if (list) {
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001178 PyList_SetItem(list, 0,
1179 PyString_FromString("typecode"));
1180 PyList_SetItem(list, 1,
1181 PyString_FromString("itemsize"));
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001182 if (PyErr_Occurred()) {
1183 Py_DECREF(list);
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001184 list = NULL;
1185 }
1186 }
1187 return list;
1188 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001189 return Py_FindMethod(array_methods, (PyObject *)a, name);
Guido van Rossum778983b1993-02-19 15:55:02 +00001190}
1191
1192static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001193array_print(arrayobject *a, FILE *fp, int flags)
Guido van Rossum778983b1993-02-19 15:55:02 +00001194{
1195 int ok = 0;
1196 int i, len;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001197 PyObject *t_empty = PyTuple_New(0);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001198 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +00001199 len = a->ob_size;
1200 if (len == 0) {
1201 fprintf(fp, "array('%c')", a->ob_descr->typecode);
1202 return ok;
1203 }
1204 if (a->ob_descr->typecode == 'c') {
1205 fprintf(fp, "array('c', ");
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001206 v = array_tostring(a, t_empty);
1207 Py_DECREF(t_empty);;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001208 ok = PyObject_Print(v, fp, 0);
1209 Py_XDECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001210 fprintf(fp, ")");
1211 return ok;
1212 }
1213 fprintf(fp, "array('%c', [", a->ob_descr->typecode);
1214 for (i = 0; i < len && ok == 0; i++) {
1215 if (i > 0)
1216 fprintf(fp, ", ");
1217 v = (a->ob_descr->getitem)(a, i);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001218 ok = PyObject_Print(v, fp, 0);
1219 Py_XDECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001220 }
1221 fprintf(fp, "])");
1222 return ok;
1223}
1224
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001225static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001226array_repr(arrayobject *a)
Guido van Rossum778983b1993-02-19 15:55:02 +00001227{
1228 char buf[256];
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001229 PyObject *s, *t, *comma, *v;
Guido van Rossum778983b1993-02-19 15:55:02 +00001230 int i, len;
1231 len = a->ob_size;
1232 if (len == 0) {
1233 sprintf(buf, "array('%c')", a->ob_descr->typecode);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001234 return PyString_FromString(buf);
Guido van Rossum778983b1993-02-19 15:55:02 +00001235 }
1236 if (a->ob_descr->typecode == 'c') {
1237 sprintf(buf, "array('c', ");
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001238 s = PyString_FromString(buf);
1239 v = array_tostring(a, (PyObject *)NULL);
1240 t = PyObject_Repr(v);
1241 Py_XDECREF(v);
1242 PyString_ConcatAndDel(&s, t);
1243 PyString_ConcatAndDel(&s, PyString_FromString(")"));
Guido van Rossum778983b1993-02-19 15:55:02 +00001244 return s;
1245 }
1246 sprintf(buf, "array('%c', [", a->ob_descr->typecode);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001247 s = PyString_FromString(buf);
1248 comma = PyString_FromString(", ");
1249 for (i = 0; i < len && !PyErr_Occurred(); i++) {
Guido van Rossumb6775db1994-08-01 11:34:53 +00001250 if (i > 0)
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001251 PyString_Concat(&s, comma);
Guido van Rossum778983b1993-02-19 15:55:02 +00001252 v = (a->ob_descr->getitem)(a, i);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001253 t = PyObject_Repr(v);
1254 Py_XDECREF(v);
1255 PyString_ConcatAndDel(&s, t);
Guido van Rossum778983b1993-02-19 15:55:02 +00001256 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001257 Py_XDECREF(comma);
1258 PyString_ConcatAndDel(&s, PyString_FromString("])"));
Guido van Rossum778983b1993-02-19 15:55:02 +00001259 return s;
1260}
1261
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001262static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001263array_buffer_getreadbuf(arrayobject *self, int index, const void **ptr)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001264{
1265 if ( index != 0 ) {
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001266 PyErr_SetString(PyExc_SystemError,
1267 "Accessing non-existent array segment");
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001268 return -1;
1269 }
1270 *ptr = (void *)self->ob_item;
1271 return self->ob_size*self->ob_descr->itemsize;
1272}
1273
1274static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001275array_buffer_getwritebuf(arrayobject *self, int index, const void **ptr)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001276{
1277 if ( index != 0 ) {
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001278 PyErr_SetString(PyExc_SystemError,
1279 "Accessing non-existent array segment");
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001280 return -1;
1281 }
1282 *ptr = (void *)self->ob_item;
1283 return self->ob_size*self->ob_descr->itemsize;
1284}
1285
1286static int
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001287array_buffer_getsegcount(arrayobject *self, int *lenp)
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001288{
1289 if ( lenp )
1290 *lenp = self->ob_size*self->ob_descr->itemsize;
1291 return 1;
1292}
1293
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001294static PySequenceMethods array_as_sequence = {
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001295 (inquiry)array_length, /*sq_length*/
1296 (binaryfunc)array_concat, /*sq_concat*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297 (intargfunc)array_repeat, /*sq_repeat*/
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001298 (intargfunc)array_item, /*sq_item*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001299 (intintargfunc)array_slice, /*sq_slice*/
1300 (intobjargproc)array_ass_item, /*sq_ass_item*/
1301 (intintobjargproc)array_ass_slice, /*sq_ass_slice*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001302};
1303
Guido van Rossumfdf95dd1997-05-05 22:15:02 +00001304static PyBufferProcs array_as_buffer = {
1305 (getreadbufferproc)array_buffer_getreadbuf,
1306 (getwritebufferproc)array_buffer_getwritebuf,
1307 (getsegcountproc)array_buffer_getsegcount,
1308};
1309
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001310static PyObject *
Peter Schneider-Kamp9656abd2000-07-13 21:10:57 +00001311a_array(PyObject *self, PyObject *args)
Guido van Rossum778983b1993-02-19 15:55:02 +00001312{
1313 char c;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001314 PyObject *initial = NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00001315 struct arraydescr *descr;
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001316 if (!PyArg_ParseTuple(args, "c:array", &c)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001317 PyErr_Clear();
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001318 if (!PyArg_ParseTuple(args, "cO:array", &c, &initial))
Guido van Rossum778983b1993-02-19 15:55:02 +00001319 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001320 if (!PyList_Check(initial) && !PyString_Check(initial)) {
1321 PyErr_SetString(PyExc_TypeError,
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001322 "array initializer must be list or string");
Guido van Rossum778983b1993-02-19 15:55:02 +00001323 return NULL;
1324 }
1325 }
1326 for (descr = descriptors; descr->typecode != '\0'; descr++) {
1327 if (descr->typecode == c) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001328 PyObject *a;
Guido van Rossum778983b1993-02-19 15:55:02 +00001329 int len;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001330 if (initial == NULL || !PyList_Check(initial))
Guido van Rossum778983b1993-02-19 15:55:02 +00001331 len = 0;
1332 else
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001333 len = PyList_Size(initial);
Guido van Rossum778983b1993-02-19 15:55:02 +00001334 a = newarrayobject(len, descr);
1335 if (a == NULL)
1336 return NULL;
1337 if (len > 0) {
1338 int i;
1339 for (i = 0; i < len; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001340 PyObject *v =
1341 PyList_GetItem(initial, i);
Guido van Rossum778983b1993-02-19 15:55:02 +00001342 if (setarrayitem(a, i, v) != 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001343 Py_DECREF(a);
Guido van Rossum778983b1993-02-19 15:55:02 +00001344 return NULL;
1345 }
1346 }
1347 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001348 if (initial != NULL && PyString_Check(initial)) {
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001349 PyObject *t_initial = Py_BuildValue("(O)", initial);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001350 PyObject *v =
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001351 array_fromstring((arrayobject *)a, t_initial);
1352 Py_DECREF(t_initial);
Guido van Rossum778983b1993-02-19 15:55:02 +00001353 if (v == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001354 Py_DECREF(a);
Guido van Rossum778983b1993-02-19 15:55:02 +00001355 return NULL;
1356 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001357 Py_DECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001358 }
1359 return a;
1360 }
1361 }
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001362 PyErr_SetString(PyExc_ValueError,
Guido van Rossum549ab711997-01-03 19:09:47 +00001363 "bad typecode (must be c, b, B, h, H, i, I, l, L, f or d)");
Guido van Rossum778983b1993-02-19 15:55:02 +00001364 return NULL;
1365}
1366
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001367static char a_array_doc [] =
1368"array(typecode [, initializer]) -> array\n\
1369\n\
1370Return a new array whose items are restricted by typecode, and\n\
1371initialized from the optional initializer value, which must be a list\n\
1372or a string.";
1373
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001374static PyMethodDef a_methods[] = {
Peter Schneider-Kampdc71cac2000-07-31 21:57:30 +00001375 {"array", a_array, METH_VARARGS, a_array_doc},
Guido van Rossum778983b1993-02-19 15:55:02 +00001376 {NULL, NULL} /* sentinel */
1377};
1378
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001379static char module_doc [] =
1380"This module defines a new object type which can efficiently represent\n\
1381an array of basic values: characters, integers, floating point\n\
1382numbers. Arrays are sequence types and behave very much like lists,\n\
1383except that the type of objects stored in them is constrained. The\n\
1384type is specified at object creation time by using a type code, which\n\
1385is a single character. The following type codes are defined:\n\
1386\n\
1387 Type code C Type Minimum size in bytes \n\
1388 'c' character 1 \n\
1389 'b' signed integer 1 \n\
1390 'B' unsigned integer 1 \n\
1391 'h' signed integer 2 \n\
1392 'H' unsigned integer 2 \n\
1393 'i' signed integer 2 \n\
1394 'I' unsigned integer 2 \n\
1395 'l' signed integer 4 \n\
1396 'L' unsigned integer 4 \n\
1397 'f' floating point 4 \n\
1398 'd' floating point 8 \n\
1399\n\
1400Functions:\n\
1401\n\
1402array(typecode [, initializer]) -- create a new array\n\
1403\n\
1404Special Objects:\n\
1405\n\
1406ArrayType -- type object for array objects\n\
1407";
1408
1409static char arraytype_doc [] =
1410"An array represents basic values and behave very much like lists, except\n\
1411the type of objects stored in them is constrained.\n\
1412\n\
1413Methods:\n\
1414\n\
1415append() -- append a new item to the end of the array\n\
1416buffer_info() -- return information giving the current memory info\n\
1417byteswap() -- byteswap all the items of the array\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001418count() -- return number of occurences of an object\n\
1419extend() -- extend array by appending array elements\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001420fromfile() -- read items from a file object\n\
1421fromlist() -- append items from the list\n\
1422fromstring() -- append items from the string\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001423index() -- return index of first occurence of an object\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001424insert() -- insert a new item into the array at a provided position\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001425pop() -- remove and return item (default last)\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001426read() -- DEPRECATED, use fromfile()\n\
Peter Schneider-Kamp5a65c2d2000-07-31 20:52:21 +00001427remove() -- remove first occurence of an object\n\
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001428reverse() -- reverse the order of the items in the array\n\
1429tofile() -- write all items to a file object\n\
1430tolist() -- return the array converted to an ordinary list\n\
1431tostring() -- return the array converted to a string\n\
1432write() -- DEPRECATED, use tofile()\n\
1433\n\
1434Variables:\n\
1435\n\
1436typecode -- the typecode character used to create the array\n\
1437itemsize -- the length in bytes of one array item\n\
1438";
1439
1440statichere PyTypeObject Arraytype = {
Fred Drake0d40ba42000-02-04 20:33:49 +00001441 PyObject_HEAD_INIT(NULL)
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001442 0,
1443 "array",
1444 sizeof(arrayobject),
1445 0,
1446 (destructor)array_dealloc, /*tp_dealloc*/
1447 (printfunc)array_print, /*tp_print*/
1448 (getattrfunc)array_getattr, /*tp_getattr*/
1449 0, /*tp_setattr*/
1450 (cmpfunc)array_compare, /*tp_compare*/
1451 (reprfunc)array_repr, /*tp_repr*/
1452 0, /*tp_as_number*/
1453 &array_as_sequence, /*tp_as_sequence*/
1454 0, /*tp_as_mapping*/
1455 0, /*tp_hash*/
1456 0, /*tp_call*/
1457 0, /*tp_str*/
1458 0, /*tp_getattro*/
1459 0, /*tp_setattro*/
1460 &array_as_buffer, /*tp_as_buffer*/
1461 0, /*tp_xxx4*/
1462 arraytype_doc, /*tp_doc*/
1463};
1464
Guido van Rossum3886bb61998-12-04 18:50:17 +00001465DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001466initarray(void)
Guido van Rossum778983b1993-02-19 15:55:02 +00001467{
Guido van Rossumb6190d31997-05-22 14:56:36 +00001468 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +00001469
1470 Arraytype.ob_type = &PyType_Type;
Guido van Rossumb39b90d1998-10-13 14:27:22 +00001471 m = Py_InitModule3("array", a_methods, module_doc);
Guido van Rossumb6190d31997-05-22 14:56:36 +00001472 d = PyModule_GetDict(m);
Guido van Rossuma0deb641998-10-14 13:45:06 +00001473 PyDict_SetItemString(d, "ArrayType", (PyObject *)&Arraytype);
1474 /* No need to check the error here, the caller will do that */
Guido van Rossum778983b1993-02-19 15:55:02 +00001475}