blob: 7ac481b402f87f7f8ecd46c1c7bb55be775c9afd [file] [log] [blame]
Guido van Rossum778983b1993-02-19 15:55:02 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum778983b1993-02-19 15:55:02 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum778983b1993-02-19 15:55:02 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum778983b1993-02-19 15:55:02 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum778983b1993-02-19 15:55:02 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum778983b1993-02-19 15:55:02 +000029
30******************************************************************/
31
32/* Array object implementation */
33
34/* An array is a uniform list -- all items have the same type.
35 The item type is restricted to simple C types like int or float */
36
Roger E. Masse2919eaa1996-12-09 20:10:36 +000037#include "Python.h"
Roger E. Masse5817f8f1996-12-09 22:24:19 +000038
Guido van Rossum0c709541994-08-19 12:01:32 +000039#ifdef STDC_HEADERS
40#include <stddef.h>
41#else
Guido van Rossumb6775db1994-08-01 11:34:53 +000042#include <sys/types.h> /* For size_t */
Guido van Rossum0c709541994-08-19 12:01:32 +000043#endif
Guido van Rossum778983b1993-02-19 15:55:02 +000044
45struct arrayobject; /* Forward */
46
47struct arraydescr {
48 int typecode;
49 int itemsize;
Roger E. Masse2919eaa1996-12-09 20:10:36 +000050 PyObject * (*getitem) Py_FPROTO((struct arrayobject *, int));
51 int (*setitem) Py_FPROTO((struct arrayobject *, int, PyObject *));
Guido van Rossum778983b1993-02-19 15:55:02 +000052};
53
54typedef struct arrayobject {
Roger E. Masse2919eaa1996-12-09 20:10:36 +000055 PyObject_VAR_HEAD
Guido van Rossum778983b1993-02-19 15:55:02 +000056 char *ob_item;
57 struct arraydescr *ob_descr;
58} arrayobject;
59
Roger E. Masse2919eaa1996-12-09 20:10:36 +000060staticforward PyTypeObject Arraytype;
Guido van Rossum778983b1993-02-19 15:55:02 +000061
62#define is_arrayobject(op) ((op)->ob_type == &Arraytype)
63
Guido van Rossumb73cc041993-11-01 16:28:59 +000064/* Forward */
Roger E. Masse2919eaa1996-12-09 20:10:36 +000065static PyObject *newarrayobject Py_PROTO((int, struct arraydescr *));
Guido van Rossuma376cc51996-12-05 23:43:35 +000066#if 0
Roger E. Masse2919eaa1996-12-09 20:10:36 +000067static int getarraysize Py_PROTO((PyObject *));
Guido van Rossuma376cc51996-12-05 23:43:35 +000068#endif
Roger E. Masse2919eaa1996-12-09 20:10:36 +000069static PyObject *getarrayitem Py_PROTO((PyObject *, int));
70static int setarrayitem Py_PROTO((PyObject *, int, PyObject *));
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#if 0
Roger E. Masse2919eaa1996-12-09 20:10:36 +000072static int insarrayitem Py_PROTO((PyObject *, int, PyObject *));
73static int addarrayitem Py_PROTO((PyObject *, PyObject *));
Guido van Rossuma376cc51996-12-05 23:43:35 +000074#endif
Guido van Rossum778983b1993-02-19 15:55:02 +000075
Roger E. Masse2919eaa1996-12-09 20:10:36 +000076static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +000077c_getitem(ap, i)
78 arrayobject *ap;
79 int i;
80{
Roger E. Masse2919eaa1996-12-09 20:10:36 +000081 return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
Guido van Rossum778983b1993-02-19 15:55:02 +000082}
83
84static int
85c_setitem(ap, i, v)
86 arrayobject *ap;
87 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +000088 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +000089{
90 char x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +000091 if (!PyArg_Parse(v, "c;array item must be char", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +000092 return -1;
93 if (i >= 0)
94 ((char *)ap->ob_item)[i] = x;
95 return 0;
96}
97
Roger E. Masse2919eaa1996-12-09 20:10:36 +000098static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +000099b_getitem(ap, i)
100 arrayobject *ap;
101 int i;
102{
103 long x = ((char *)ap->ob_item)[i];
104 if (x >= 128)
105 x -= 256;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000106 return PyInt_FromLong(x);
Guido van Rossum778983b1993-02-19 15:55:02 +0000107}
108
109static int
110b_setitem(ap, i, v)
111 arrayobject *ap;
112 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000113 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000114{
115 char x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000116 if (!PyArg_Parse(v, "b;array item must be integer", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000117 return -1;
118 if (i >= 0)
119 ((char *)ap->ob_item)[i] = x;
120 return 0;
121}
122
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000123static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000124h_getitem(ap, i)
125 arrayobject *ap;
126 int i;
127{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000128 return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000129}
130
131static int
132h_setitem(ap, i, v)
133 arrayobject *ap;
134 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000135 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000136{
137 short x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000138 if (!PyArg_Parse(v, "h;array item must be integer", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000139 return -1;
140 if (i >= 0)
141 ((short *)ap->ob_item)[i] = x;
142 return 0;
143}
144
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000145static PyObject *
Guido van Rossume77a7571993-11-03 15:01:26 +0000146i_getitem(ap, i)
147 arrayobject *ap;
148 int i;
149{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000150 return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
Guido van Rossume77a7571993-11-03 15:01:26 +0000151}
152
153static int
154i_setitem(ap, i, v)
155 arrayobject *ap;
156 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000157 PyObject *v;
Guido van Rossume77a7571993-11-03 15:01:26 +0000158{
159 int x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000160 if (!PyArg_Parse(v, "i;array item must be integer", &x))
Guido van Rossume77a7571993-11-03 15:01:26 +0000161 return -1;
162 if (i >= 0)
163 ((int *)ap->ob_item)[i] = x;
164 return 0;
165}
166
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000167static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000168l_getitem(ap, i)
169 arrayobject *ap;
170 int i;
171{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000172 return PyInt_FromLong(((long *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000173}
174
175static int
176l_setitem(ap, i, v)
177 arrayobject *ap;
178 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000179 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000180{
181 long x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000182 if (!PyArg_Parse(v, "l;array item must be integer", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000183 return -1;
184 if (i >= 0)
185 ((long *)ap->ob_item)[i] = x;
186 return 0;
187}
188
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000189static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000190f_getitem(ap, i)
191 arrayobject *ap;
192 int i;
193{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000194 return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000195}
196
197static int
198f_setitem(ap, i, v)
199 arrayobject *ap;
200 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000201 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000202{
203 float x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000204 if (!PyArg_Parse(v, "f;array item must be float", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000205 return -1;
206 if (i >= 0)
207 ((float *)ap->ob_item)[i] = x;
208 return 0;
209}
210
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000211static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000212d_getitem(ap, i)
213 arrayobject *ap;
214 int i;
215{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000216 return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
Guido van Rossum778983b1993-02-19 15:55:02 +0000217}
218
219static int
220d_setitem(ap, i, v)
221 arrayobject *ap;
222 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000223 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000224{
225 double x;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000226 if (!PyArg_Parse(v, "d;array item must be float", &x))
Guido van Rossum778983b1993-02-19 15:55:02 +0000227 return -1;
228 if (i >= 0)
229 ((double *)ap->ob_item)[i] = x;
230 return 0;
231}
232
233/* Description of types */
Guido van Rossum234f9421993-06-17 12:35:49 +0000234static struct arraydescr descriptors[] = {
Guido van Rossum778983b1993-02-19 15:55:02 +0000235 {'c', sizeof(char), c_getitem, c_setitem},
236 {'b', sizeof(char), b_getitem, b_setitem},
237 {'h', sizeof(short), h_getitem, h_setitem},
Guido van Rossume77a7571993-11-03 15:01:26 +0000238 {'i', sizeof(int), i_getitem, i_setitem},
Guido van Rossum778983b1993-02-19 15:55:02 +0000239 {'l', sizeof(long), l_getitem, l_setitem},
240 {'f', sizeof(float), f_getitem, f_setitem},
241 {'d', sizeof(double), d_getitem, d_setitem},
242 {'\0', 0, 0, 0} /* Sentinel */
243};
Guido van Rossume77a7571993-11-03 15:01:26 +0000244/* If we ever allow items larger than double, we must change reverse()! */
Guido van Rossum778983b1993-02-19 15:55:02 +0000245
246
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000247static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000248newarrayobject(size, descr)
249 int size;
250 struct arraydescr *descr;
251{
Guido van Rossum778983b1993-02-19 15:55:02 +0000252 arrayobject *op;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253 size_t nbytes;
Guido van Rossum778983b1993-02-19 15:55:02 +0000254 if (size < 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000255 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000256 return NULL;
257 }
258 nbytes = size * descr->itemsize;
259 /* Check for overflow */
260 if (nbytes / descr->itemsize != size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000261 return PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000262 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000263 op = PyMem_NEW(arrayobject, 1);
Guido van Rossum778983b1993-02-19 15:55:02 +0000264 if (op == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000265 return PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000266 }
267 if (size <= 0) {
268 op->ob_item = NULL;
269 }
270 else {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000271 op->ob_item = PyMem_NEW(char, nbytes);
Guido van Rossum778983b1993-02-19 15:55:02 +0000272 if (op->ob_item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000273 PyMem_DEL(op);
274 return PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000275 }
276 }
Guido van Rossum778983b1993-02-19 15:55:02 +0000277 op->ob_type = &Arraytype;
278 op->ob_size = size;
279 op->ob_descr = descr;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000280 _Py_NewReference(op);
281 return (PyObject *) op;
Guido van Rossum778983b1993-02-19 15:55:02 +0000282}
283
Guido van Rossuma376cc51996-12-05 23:43:35 +0000284#if 0
Guido van Rossum62de97f1995-01-22 00:48:41 +0000285static int
Guido van Rossum778983b1993-02-19 15:55:02 +0000286getarraysize(op)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000287 PyObject *op;
Guido van Rossum778983b1993-02-19 15:55:02 +0000288{
289 if (!is_arrayobject(op)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000290 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000291 return -1;
292 }
293 return ((arrayobject *)op) -> ob_size;
294}
Guido van Rossuma376cc51996-12-05 23:43:35 +0000295#endif
Guido van Rossum778983b1993-02-19 15:55:02 +0000296
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000297static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000298getarrayitem(op, i)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000299 PyObject *op;
Guido van Rossum778983b1993-02-19 15:55:02 +0000300 int i;
301{
302 register arrayobject *ap;
303 if (!is_arrayobject(op)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000304 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000305 return NULL;
306 }
307 ap = (arrayobject *)op;
308 if (i < 0 || i >= ap->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000309 PyErr_SetString(PyExc_IndexError, "array index out of range");
Guido van Rossum778983b1993-02-19 15:55:02 +0000310 return NULL;
311 }
312 return (*ap->ob_descr->getitem)(ap, i);
313}
314
315static int
316ins1(self, where, v)
317 arrayobject *self;
318 int where;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000319 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000320{
Guido van Rossum778983b1993-02-19 15:55:02 +0000321 char *items;
322 if (v == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000323 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000324 return -1;
325 }
326 if ((*self->ob_descr->setitem)(self, -1, v) < 0)
327 return -1;
328 items = self->ob_item;
Roger E. Masse5817f8f1996-12-09 22:24:19 +0000329 PyMem_RESIZE(items, char,
330 (self->ob_size+1) * self->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000331 if (items == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000332 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000333 return -1;
334 }
335 if (where < 0)
336 where = 0;
337 if (where > self->ob_size)
338 where = self->ob_size;
339 memmove(items + (where+1)*self->ob_descr->itemsize,
340 items + where*self->ob_descr->itemsize,
341 (self->ob_size-where)*self->ob_descr->itemsize);
342 self->ob_item = items;
343 self->ob_size++;
344 return (*self->ob_descr->setitem)(self, where, v);
345}
346
Guido van Rossuma376cc51996-12-05 23:43:35 +0000347#if 0
Guido van Rossum62de97f1995-01-22 00:48:41 +0000348static int
Guido van Rossum778983b1993-02-19 15:55:02 +0000349insarrayitem(op, where, newitem)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000350 PyObject *op;
Guido van Rossum778983b1993-02-19 15:55:02 +0000351 int where;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000352 PyObject *newitem;
Guido van Rossum778983b1993-02-19 15:55:02 +0000353{
354 if (!is_arrayobject(op)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000355 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000356 return -1;
357 }
358 return ins1((arrayobject *)op, where, newitem);
359}
360
Guido van Rossum62de97f1995-01-22 00:48:41 +0000361static int
Guido van Rossum778983b1993-02-19 15:55:02 +0000362addarrayitem(op, newitem)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000363 PyObject *op;
364 PyObject *newitem;
Guido van Rossum778983b1993-02-19 15:55:02 +0000365{
366 if (!is_arrayobject(op)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000367 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000368 return -1;
369 }
370 return ins1((arrayobject *)op,
371 (int) ((arrayobject *)op)->ob_size, newitem);
372}
Guido van Rossuma376cc51996-12-05 23:43:35 +0000373#endif
Guido van Rossum778983b1993-02-19 15:55:02 +0000374
375/* Methods */
376
377static void
378array_dealloc(op)
379 arrayobject *op;
380{
Guido van Rossum778983b1993-02-19 15:55:02 +0000381 if (op->ob_item != NULL)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000382 PyMem_DEL(op->ob_item);
383 PyMem_DEL(op);
Guido van Rossum778983b1993-02-19 15:55:02 +0000384}
385
386static int
387array_compare(v, w)
388 arrayobject *v, *w;
389{
390 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
391 int i;
392 for (i = 0; i < len; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000393 PyObject *ai, *bi;
Guido van Rossum778983b1993-02-19 15:55:02 +0000394 int cmp;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000395 ai = getarrayitem((PyObject *)v, i);
396 bi = getarrayitem((PyObject *)w, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000397 if (ai && bi)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000398 cmp = PyObject_Compare(ai, bi);
Guido van Rossum778983b1993-02-19 15:55:02 +0000399 else
400 cmp = -1;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000401 Py_XDECREF(ai);
402 Py_XDECREF(bi);
Guido van Rossum778983b1993-02-19 15:55:02 +0000403 if (cmp != 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000404 PyErr_Clear(); /* XXX Can't report errors here */
Guido van Rossum778983b1993-02-19 15:55:02 +0000405 return cmp;
406 }
407 }
408 return v->ob_size - w->ob_size;
409}
410
411static int
412array_length(a)
413 arrayobject *a;
414{
415 return a->ob_size;
416}
417
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000418static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000419array_item(a, i)
420 arrayobject *a;
421 int i;
422{
423 if (i < 0 || i >= a->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000424 PyErr_SetString(PyExc_IndexError, "array index out of range");
Guido van Rossum778983b1993-02-19 15:55:02 +0000425 return NULL;
426 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000427 return getarrayitem((PyObject *)a, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000428}
429
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000430static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000431array_slice(a, ilow, ihigh)
432 arrayobject *a;
433 int ilow, ihigh;
434{
435 arrayobject *np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000436 if (ilow < 0)
437 ilow = 0;
438 else if (ilow > a->ob_size)
439 ilow = a->ob_size;
440 if (ihigh < 0)
441 ihigh = 0;
442 if (ihigh < ilow)
443 ihigh = ilow;
444 else if (ihigh > a->ob_size)
445 ihigh = a->ob_size;
446 np = (arrayobject *) newarrayobject(ihigh - ilow, a->ob_descr);
447 if (np == NULL)
448 return NULL;
449 memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
450 (ihigh-ilow) * a->ob_descr->itemsize);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000451 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000452}
453
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000454static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000455array_concat(a, bb)
456 arrayobject *a;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000457 PyObject *bb;
Guido van Rossum778983b1993-02-19 15:55:02 +0000458{
459 int size;
Guido van Rossum778983b1993-02-19 15:55:02 +0000460 arrayobject *np;
461 if (!is_arrayobject(bb)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000462 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000463 return NULL;
464 }
465#define b ((arrayobject *)bb)
466 if (a->ob_descr != b->ob_descr) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000467 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000468 return NULL;
469 }
470 size = a->ob_size + b->ob_size;
471 np = (arrayobject *) newarrayobject(size, a->ob_descr);
472 if (np == NULL) {
473 return NULL;
474 }
475 memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
476 memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
Guido van Rossum32be3a71993-11-05 10:16:27 +0000477 b->ob_item, b->ob_size*b->ob_descr->itemsize);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000478 return (PyObject *)np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000479#undef b
480}
481
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000482static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000483array_repeat(a, n)
484 arrayobject *a;
485 int n;
486{
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000487 int i;
Guido van Rossum778983b1993-02-19 15:55:02 +0000488 int size;
489 arrayobject *np;
490 char *p;
491 int nbytes;
492 if (n < 0)
493 n = 0;
494 size = a->ob_size * n;
495 np = (arrayobject *) newarrayobject(size, a->ob_descr);
496 if (np == NULL)
497 return NULL;
498 p = np->ob_item;
499 nbytes = a->ob_size * a->ob_descr->itemsize;
500 for (i = 0; i < n; i++) {
501 memcpy(p, a->ob_item, nbytes);
502 p += nbytes;
503 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000504 return (PyObject *) np;
Guido van Rossum778983b1993-02-19 15:55:02 +0000505}
506
507static int
508array_ass_slice(a, ilow, ihigh, v)
509 arrayobject *a;
510 int ilow, ihigh;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000511 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000512{
513 char *item;
514 int n; /* Size of replacement array */
515 int d; /* Change in size */
Guido van Rossum778983b1993-02-19 15:55:02 +0000516#define b ((arrayobject *)v)
517 if (v == NULL)
518 n = 0;
519 else if (is_arrayobject(v)) {
520 n = b->ob_size;
521 if (a == b) {
522 /* Special case "a[i:j] = a" -- copy b first */
523 int ret;
524 v = array_slice(b, 0, n);
525 ret = array_ass_slice(a, ilow, ihigh, v);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000526 Py_DECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +0000527 return ret;
528 }
529 if (b->ob_descr != a->ob_descr) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000530 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000531 return -1;
532 }
533 }
534 else {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000535 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000536 return -1;
537 }
538 if (ilow < 0)
539 ilow = 0;
540 else if (ilow > a->ob_size)
541 ilow = a->ob_size;
542 if (ihigh < 0)
543 ihigh = 0;
544 if (ihigh < ilow)
545 ihigh = ilow;
546 else if (ihigh > a->ob_size)
547 ihigh = a->ob_size;
548 item = a->ob_item;
549 d = n - (ihigh-ilow);
550 if (d < 0) { /* Delete -d items */
551 memmove(item + (ihigh+d)*a->ob_descr->itemsize,
552 item + ihigh*a->ob_descr->itemsize,
553 (a->ob_size-ihigh)*a->ob_descr->itemsize);
554 a->ob_size += d;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000555 PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000556 /* Can't fail */
557 a->ob_item = item;
558 }
559 else if (d > 0) { /* Insert d items */
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000560 PyMem_RESIZE(item, char,
561 (a->ob_size + d)*a->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000562 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000563 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000564 return -1;
565 }
566 memmove(item + (ihigh+d)*a->ob_descr->itemsize,
567 item + ihigh*a->ob_descr->itemsize,
568 (a->ob_size-ihigh)*a->ob_descr->itemsize);
569 a->ob_item = item;
570 a->ob_size += d;
571 }
572 if (n > 0)
573 memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
574 n*b->ob_descr->itemsize);
575 return 0;
576#undef b
577}
578
579static int
580array_ass_item(a, i, v)
581 arrayobject *a;
582 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000583 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000584{
585 if (i < 0 || i >= a->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000586 PyErr_SetString(PyExc_IndexError,
587 "array assignment index out of range");
Guido van Rossum778983b1993-02-19 15:55:02 +0000588 return -1;
589 }
590 if (v == NULL)
591 return array_ass_slice(a, i, i+1, v);
592 return (*a->ob_descr->setitem)(a, i, v);
593}
594
595static int
596setarrayitem(a, i, v)
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000597 PyObject *a;
Guido van Rossum778983b1993-02-19 15:55:02 +0000598 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000599 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000600{
601 if (!is_arrayobject(a)) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000602 PyErr_BadInternalCall();
Guido van Rossum778983b1993-02-19 15:55:02 +0000603 return -1;
604 }
605 return array_ass_item((arrayobject *)a, i, v);
606}
607
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000608static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000609ins(self, where, v)
610 arrayobject *self;
611 int where;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000612 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +0000613{
614 if (ins1(self, where, v) != 0)
615 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000616 Py_INCREF(Py_None);
617 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000618}
619
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000620static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000621array_insert(self, args)
622 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000623 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000624{
625 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000626 PyObject *v;
627 if (!PyArg_Parse(args, "(iO)", &i, &v))
Guido van Rossum778983b1993-02-19 15:55:02 +0000628 return NULL;
629 return ins(self, i, v);
630}
631
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000632static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000633array_append(self, args)
634 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000635 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000636{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000637 PyObject *v;
638 if (!PyArg_Parse(args, "O", &v))
Guido van Rossum778983b1993-02-19 15:55:02 +0000639 return NULL;
640 return ins(self, (int) self->ob_size, v);
641}
642
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000643static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000644array_byteswap(self, args)
645 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000646 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000647{
648 char *p;
649 int i;
650 switch (self->ob_descr->itemsize) {
651 case 1:
652 break;
653 case 2:
654 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
655 char p0 = p[0];
656 p[0] = p[1];
657 p[1] = p0;
658 }
659 break;
660 case 4:
661 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
662 char p0 = p[0];
663 char p1 = p[1];
664 p[0] = p[3];
665 p[1] = p[2];
666 p[2] = p1;
667 p[3] = p0;
668 }
669 break;
Guido van Rossume77a7571993-11-03 15:01:26 +0000670 case 8:
671 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
672 char p0 = p[0];
673 char p1 = p[1];
674 char p2 = p[2];
675 char p3 = p[3];
676 p[0] = p[7];
677 p[1] = p[6];
678 p[2] = p[5];
679 p[3] = p[4];
680 p[4] = p3;
681 p[5] = p2;
682 p[6] = p1;
683 p[7] = p0;
684 }
685 break;
Guido van Rossum778983b1993-02-19 15:55:02 +0000686 default:
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000687 PyErr_SetString(PyExc_RuntimeError,
Guido van Rossum778983b1993-02-19 15:55:02 +0000688 "don't know how to byteswap this array type");
689 return NULL;
690 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000691 Py_INCREF(Py_None);
692 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000693}
694
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000695static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000696array_reverse(self, args)
697 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000698 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000699{
Guido van Rossume77a7571993-11-03 15:01:26 +0000700 register int itemsize = self->ob_descr->itemsize;
701 register char *p, *q;
702 char tmp[sizeof(double)]; /* Assume that's the max item size */
703
Guido van Rossum778983b1993-02-19 15:55:02 +0000704 if (args != NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000705 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000706 return NULL;
707 }
708
709 if (self->ob_size > 1) {
Guido van Rossume77a7571993-11-03 15:01:26 +0000710 for (p = self->ob_item,
711 q = self->ob_item + (self->ob_size - 1)*itemsize;
712 p < q;
713 p += itemsize, q -= itemsize) {
714 memmove(tmp, p, itemsize);
715 memmove(p, q, itemsize);
716 memmove(q, tmp, itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000717 }
718 }
719
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000720 Py_INCREF(Py_None);
721 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000722}
Guido van Rossume77a7571993-11-03 15:01:26 +0000723
724/* The following routines were adapted from listobject.c but not converted.
725 To make them work you will have to work! */
Guido van Rossum778983b1993-02-19 15:55:02 +0000726
727#if 0
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000728static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000729array_index(self, args)
730 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000731 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000732{
733 int i;
734
735 if (args == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000736 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000737 return NULL;
738 }
739 for (i = 0; i < self->ob_size; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000740 if (PyObject_Compare(self->ob_item[i], args) == 0)
741 return PyInt_FromLong((long)i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000742 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000743 PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array");
Guido van Rossum778983b1993-02-19 15:55:02 +0000744 return NULL;
745}
746#endif
747
748#if 0
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000749static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000750array_count(self, args)
751 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000752 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000753{
754 int count = 0;
755 int i;
756
757 if (args == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000758 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000759 return NULL;
760 }
761 for (i = 0; i < self->ob_size; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000762 if (PyObject_Compare(self->ob_item[i], args) == 0)
Guido van Rossum778983b1993-02-19 15:55:02 +0000763 count++;
764 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000765 return PyInt_FromLong((long)count);
Guido van Rossum778983b1993-02-19 15:55:02 +0000766}
767#endif
768
769#if 0
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000770static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000771array_remove(self, args)
772 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000773 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000774{
775 int i;
776
777 if (args == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000778 PyErr_BadArgument();
Guido van Rossum778983b1993-02-19 15:55:02 +0000779 return NULL;
780 }
781 for (i = 0; i < self->ob_size; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000782 if (PyObject_Compare(self->ob_item[i], args) == 0) {
Roger E. Masse5817f8f1996-12-09 22:24:19 +0000783 if (array_ass_slice(self, i, i+1,
784 (PyObject *)NULL) != 0)
Guido van Rossum778983b1993-02-19 15:55:02 +0000785 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000786 Py_INCREF(Py_None);
787 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000788 }
789
790 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000791 PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array");
Guido van Rossum778983b1993-02-19 15:55:02 +0000792 return NULL;
793}
794#endif
795
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000796static PyObject *
Guido van Rossume77a7571993-11-03 15:01:26 +0000797array_fromfile(self, args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000798 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000799 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000800{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000801 PyObject *f;
Guido van Rossum778983b1993-02-19 15:55:02 +0000802 int n;
803 FILE *fp;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000804 if (!PyArg_Parse(args, "(Oi)", &f, &n))
Guido van Rossum778983b1993-02-19 15:55:02 +0000805 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000806 fp = PyFile_AsFile(f);
Guido van Rossum778983b1993-02-19 15:55:02 +0000807 if (fp == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000808 PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
Guido van Rossum778983b1993-02-19 15:55:02 +0000809 return NULL;
810 }
811 if (n > 0) {
812 char *item = self->ob_item;
813 int itemsize = self->ob_descr->itemsize;
814 int nread;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000815 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000816 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000817 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000818 return NULL;
819 }
820 self->ob_item = item;
821 self->ob_size += n;
822 nread = fread(item + (self->ob_size - n) * itemsize,
823 itemsize, n, fp);
824 if (nread < n) {
825 self->ob_size -= (n - nread);
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000826 PyMem_RESIZE(item, char, self->ob_size*itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000827 self->ob_item = item;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000828 PyErr_SetString(PyExc_EOFError,
829 "not enough items in file");
Guido van Rossum778983b1993-02-19 15:55:02 +0000830 return NULL;
831 }
832 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000833 Py_INCREF(Py_None);
834 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000835}
836
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000837static PyObject *
Guido van Rossume77a7571993-11-03 15:01:26 +0000838array_tofile(self, args)
Guido van Rossum778983b1993-02-19 15:55:02 +0000839 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000840 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000841{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000842 PyObject *f;
Guido van Rossum778983b1993-02-19 15:55:02 +0000843 FILE *fp;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000844 if (!PyArg_Parse(args, "O", &f))
Guido van Rossum778983b1993-02-19 15:55:02 +0000845 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000846 fp = PyFile_AsFile(f);
Guido van Rossum778983b1993-02-19 15:55:02 +0000847 if (fp == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000848 PyErr_SetString(PyExc_TypeError, "arg must be open file");
Guido van Rossum778983b1993-02-19 15:55:02 +0000849 return NULL;
850 }
851 if (self->ob_size > 0) {
852 if (fwrite(self->ob_item, self->ob_descr->itemsize,
853 self->ob_size, fp) != self->ob_size) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000854 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum778983b1993-02-19 15:55:02 +0000855 clearerr(fp);
856 return NULL;
857 }
858 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000859 Py_INCREF(Py_None);
860 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000861}
862
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000863static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000864array_fromlist(self, args)
865 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000866 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000867{
868 int n;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000869 PyObject *list;
Guido van Rossum778983b1993-02-19 15:55:02 +0000870 int itemsize = self->ob_descr->itemsize;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000871 if (!PyArg_Parse(args, "O", &list))
Guido van Rossum778983b1993-02-19 15:55:02 +0000872 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000873 if (!PyList_Check(list)) {
874 PyErr_SetString(PyExc_TypeError, "arg must be list");
Guido van Rossum778983b1993-02-19 15:55:02 +0000875 return NULL;
876 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000877 n = PyList_Size(list);
Guido van Rossum778983b1993-02-19 15:55:02 +0000878 if (n > 0) {
879 char *item = self->ob_item;
880 int i;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000881 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000882 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000883 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000884 return NULL;
885 }
886 self->ob_item = item;
887 self->ob_size += n;
888 for (i = 0; i < n; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000889 PyObject *v = PyList_GetItem(list, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000890 if ((*self->ob_descr->setitem)(self,
891 self->ob_size - n + i, v) != 0) {
892 self->ob_size -= n;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000893 PyMem_RESIZE(item, char,
894 self->ob_size * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000895 self->ob_item = item;
896 return NULL;
897 }
898 }
899 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000900 Py_INCREF(Py_None);
901 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000902}
903
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000904static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000905array_tolist(self, args)
906 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000907 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000908{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000909 PyObject *list = PyList_New(self->ob_size);
Guido van Rossum778983b1993-02-19 15:55:02 +0000910 int i;
911 if (list == NULL)
912 return NULL;
913 for (i = 0; i < self->ob_size; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000914 PyObject *v = getarrayitem((PyObject *)self, i);
Guido van Rossum778983b1993-02-19 15:55:02 +0000915 if (v == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000916 Py_DECREF(list);
Guido van Rossum778983b1993-02-19 15:55:02 +0000917 return NULL;
918 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000919 PyList_SetItem(list, i, v);
Guido van Rossum778983b1993-02-19 15:55:02 +0000920 }
921 return list;
922}
923
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000924static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000925array_fromstring(self, args)
926 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000927 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000928{
929 char *str;
930 int n;
931 int itemsize = self->ob_descr->itemsize;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000932 if (!PyArg_Parse(args, "s#", &str, &n))
Guido van Rossum778983b1993-02-19 15:55:02 +0000933 return NULL;
934 if (n % itemsize != 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000935 PyErr_SetString(PyExc_ValueError,
Guido van Rossum778983b1993-02-19 15:55:02 +0000936 "string length not a multiple of item size");
937 return NULL;
938 }
939 n = n / itemsize;
940 if (n > 0) {
941 char *item = self->ob_item;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000942 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000943 if (item == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000944 PyErr_NoMemory();
Guido van Rossum778983b1993-02-19 15:55:02 +0000945 return NULL;
946 }
947 self->ob_item = item;
948 self->ob_size += n;
Roger E. Masse5817f8f1996-12-09 22:24:19 +0000949 memcpy(item + (self->ob_size - n) * itemsize,
950 str, itemsize*n);
Guido van Rossum778983b1993-02-19 15:55:02 +0000951 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000952 Py_INCREF(Py_None);
953 return Py_None;
Guido van Rossum778983b1993-02-19 15:55:02 +0000954}
955
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000956static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000957array_tostring(self, args)
958 arrayobject *self;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000959 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +0000960{
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000961 if (!PyArg_Parse(args, ""))
Guido van Rossum778983b1993-02-19 15:55:02 +0000962 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000963 return PyString_FromStringAndSize(self->ob_item,
Guido van Rossum778983b1993-02-19 15:55:02 +0000964 self->ob_size * self->ob_descr->itemsize);
965}
966
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000967static PyMethodDef array_methods[] = {
968 {"append", (PyCFunction)array_append},
969 {"byteswap", (PyCFunction)array_byteswap},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000970/* {"count", (method)array_count},*/
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000971 {"fromfile", (PyCFunction)array_fromfile},
972 {"fromlist", (PyCFunction)array_fromlist},
973 {"fromstring", (PyCFunction)array_fromstring},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000974/* {"index", (method)array_index},*/
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000975 {"insert", (PyCFunction)array_insert},
976 {"read", (PyCFunction)array_fromfile},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000977/* {"remove", (method)array_remove},*/
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000978 {"reverse", (PyCFunction)array_reverse},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000979/* {"sort", (method)array_sort},*/
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000980 {"tofile", (PyCFunction)array_tofile},
981 {"tolist", (PyCFunction)array_tolist},
982 {"tostring", (PyCFunction)array_tostring},
983 {"write", (PyCFunction)array_tofile},
Guido van Rossum778983b1993-02-19 15:55:02 +0000984 {NULL, NULL} /* sentinel */
985};
986
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000987static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +0000988array_getattr(a, name)
989 arrayobject *a;
990 char *name;
991{
992 if (strcmp(name, "typecode") == 0) {
993 char tc = a->ob_descr->typecode;
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000994 return PyString_FromStringAndSize(&tc, 1);
Guido van Rossum778983b1993-02-19 15:55:02 +0000995 }
996 if (strcmp(name, "itemsize") == 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +0000997 return PyInt_FromLong((long)a->ob_descr->itemsize);
Guido van Rossum778983b1993-02-19 15:55:02 +0000998 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +0000999 if (strcmp(name, "__members__") == 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001000 PyObject *list = PyList_New(2);
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001001 if (list) {
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001002 PyList_SetItem(list, 0,
1003 PyString_FromString("typecode"));
1004 PyList_SetItem(list, 1,
1005 PyString_FromString("itemsize"));
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001006 if (PyErr_Occurred()) {
1007 Py_DECREF(list);
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00001008 list = NULL;
1009 }
1010 }
1011 return list;
1012 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001013 return Py_FindMethod(array_methods, (PyObject *)a, name);
Guido van Rossum778983b1993-02-19 15:55:02 +00001014}
1015
1016static int
1017array_print(a, fp, flags)
1018 arrayobject *a;
1019 FILE *fp;
1020 int flags;
1021{
1022 int ok = 0;
1023 int i, len;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001024 PyObject *v;
Guido van Rossum778983b1993-02-19 15:55:02 +00001025 len = a->ob_size;
1026 if (len == 0) {
1027 fprintf(fp, "array('%c')", a->ob_descr->typecode);
1028 return ok;
1029 }
1030 if (a->ob_descr->typecode == 'c') {
1031 fprintf(fp, "array('c', ");
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001032 v = array_tostring(a, (PyObject *)NULL);
1033 ok = PyObject_Print(v, fp, 0);
1034 Py_XDECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001035 fprintf(fp, ")");
1036 return ok;
1037 }
1038 fprintf(fp, "array('%c', [", a->ob_descr->typecode);
1039 for (i = 0; i < len && ok == 0; i++) {
1040 if (i > 0)
1041 fprintf(fp, ", ");
1042 v = (a->ob_descr->getitem)(a, i);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001043 ok = PyObject_Print(v, fp, 0);
1044 Py_XDECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001045 }
1046 fprintf(fp, "])");
1047 return ok;
1048}
1049
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001050static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +00001051array_repr(a)
1052 arrayobject *a;
1053{
1054 char buf[256];
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001055 PyObject *s, *t, *comma, *v;
Guido van Rossum778983b1993-02-19 15:55:02 +00001056 int i, len;
1057 len = a->ob_size;
1058 if (len == 0) {
1059 sprintf(buf, "array('%c')", a->ob_descr->typecode);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001060 return PyString_FromString(buf);
Guido van Rossum778983b1993-02-19 15:55:02 +00001061 }
1062 if (a->ob_descr->typecode == 'c') {
1063 sprintf(buf, "array('c', ");
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001064 s = PyString_FromString(buf);
1065 v = array_tostring(a, (PyObject *)NULL);
1066 t = PyObject_Repr(v);
1067 Py_XDECREF(v);
1068 PyString_ConcatAndDel(&s, t);
1069 PyString_ConcatAndDel(&s, PyString_FromString(")"));
Guido van Rossum778983b1993-02-19 15:55:02 +00001070 return s;
1071 }
1072 sprintf(buf, "array('%c', [", a->ob_descr->typecode);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001073 s = PyString_FromString(buf);
1074 comma = PyString_FromString(", ");
1075 for (i = 0; i < len && !PyErr_Occurred(); i++) {
Guido van Rossumb6775db1994-08-01 11:34:53 +00001076 if (i > 0)
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001077 PyString_Concat(&s, comma);
Guido van Rossum778983b1993-02-19 15:55:02 +00001078 v = (a->ob_descr->getitem)(a, i);
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001079 t = PyObject_Repr(v);
1080 Py_XDECREF(v);
1081 PyString_ConcatAndDel(&s, t);
Guido van Rossum778983b1993-02-19 15:55:02 +00001082 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001083 Py_XDECREF(comma);
1084 PyString_ConcatAndDel(&s, PyString_FromString("])"));
Guido van Rossum778983b1993-02-19 15:55:02 +00001085 return s;
1086}
1087
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001088static PySequenceMethods array_as_sequence = {
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001089 (inquiry)array_length, /*sq_length*/
1090 (binaryfunc)array_concat, /*sq_concat*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001091 (intargfunc)array_repeat, /*sq_repeat*/
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001092 (intargfunc)array_item, /*sq_item*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001093 (intintargfunc)array_slice, /*sq_slice*/
1094 (intobjargproc)array_ass_item, /*sq_ass_item*/
1095 (intintobjargproc)array_ass_slice, /*sq_ass_slice*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001096};
1097
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001098statichere PyTypeObject Arraytype = {
1099 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum778983b1993-02-19 15:55:02 +00001100 0,
1101 "array",
1102 sizeof(arrayobject),
1103 0,
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001104 (destructor)array_dealloc, /*tp_dealloc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001105 (printfunc)array_print, /*tp_print*/
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001106 (getattrfunc)array_getattr, /*tp_getattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +00001107 0, /*tp_setattr*/
1108 (cmpfunc)array_compare, /*tp_compare*/
1109 (reprfunc)array_repr, /*tp_repr*/
1110 0, /*tp_as_number*/
1111 &array_as_sequence, /*tp_as_sequence*/
1112 0, /*tp_as_mapping*/
Guido van Rossum778983b1993-02-19 15:55:02 +00001113};
1114
1115
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001116static PyObject *
Guido van Rossum778983b1993-02-19 15:55:02 +00001117a_array(self, args)
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001118 PyObject *self;
1119 PyObject *args;
Guido van Rossum778983b1993-02-19 15:55:02 +00001120{
1121 char c;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001122 PyObject *initial = NULL;
Guido van Rossum778983b1993-02-19 15:55:02 +00001123 struct arraydescr *descr;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001124 if (!PyArg_Parse(args, "c", &c)) {
1125 PyErr_Clear();
1126 if (!PyArg_Parse(args, "(cO)", &c, &initial))
Guido van Rossum778983b1993-02-19 15:55:02 +00001127 return NULL;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001128 if (!PyList_Check(initial) && !PyString_Check(initial)) {
1129 PyErr_SetString(PyExc_TypeError,
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001130 "array initializer must be list or string");
Guido van Rossum778983b1993-02-19 15:55:02 +00001131 return NULL;
1132 }
1133 }
1134 for (descr = descriptors; descr->typecode != '\0'; descr++) {
1135 if (descr->typecode == c) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001136 PyObject *a;
Guido van Rossum778983b1993-02-19 15:55:02 +00001137 int len;
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001138 if (initial == NULL || !PyList_Check(initial))
Guido van Rossum778983b1993-02-19 15:55:02 +00001139 len = 0;
1140 else
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001141 len = PyList_Size(initial);
Guido van Rossum778983b1993-02-19 15:55:02 +00001142 a = newarrayobject(len, descr);
1143 if (a == NULL)
1144 return NULL;
1145 if (len > 0) {
1146 int i;
1147 for (i = 0; i < len; i++) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001148 PyObject *v =
1149 PyList_GetItem(initial, i);
Guido van Rossum778983b1993-02-19 15:55:02 +00001150 if (setarrayitem(a, i, v) != 0) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001151 Py_DECREF(a);
Guido van Rossum778983b1993-02-19 15:55:02 +00001152 return NULL;
1153 }
1154 }
1155 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001156 if (initial != NULL && PyString_Check(initial)) {
1157 PyObject *v =
Guido van Rossum778983b1993-02-19 15:55:02 +00001158 array_fromstring((arrayobject *)a, initial);
1159 if (v == NULL) {
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001160 Py_DECREF(a);
Guido van Rossum778983b1993-02-19 15:55:02 +00001161 return NULL;
1162 }
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001163 Py_DECREF(v);
Guido van Rossum778983b1993-02-19 15:55:02 +00001164 }
1165 return a;
1166 }
1167 }
Roger E. Masse5817f8f1996-12-09 22:24:19 +00001168 PyErr_SetString(PyExc_ValueError,
1169 "bad typecode (must be c, b, h, l, f or d)");
Guido van Rossum778983b1993-02-19 15:55:02 +00001170 return NULL;
1171}
1172
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001173static PyMethodDef a_methods[] = {
Guido van Rossum778983b1993-02-19 15:55:02 +00001174 {"array", a_array},
1175 {NULL, NULL} /* sentinel */
1176};
1177
1178void
1179initarray()
1180{
Roger E. Masse2919eaa1996-12-09 20:10:36 +00001181 Py_InitModule("array", a_methods);
Guido van Rossum778983b1993-02-19 15:55:02 +00001182}