Ditched '_find_SET()', since it was a no-value-added wrapper around
[python/dscho.git] / Modules / arraymodule.c
blobdcd931b2823e17b044b100a2e296a8a50d258405
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Array object implementation */
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 */
37 #include "Python.h"
39 #ifdef STDC_HEADERS
40 #include <stddef.h>
41 #else /* !STDC_HEADERS */
42 #ifndef DONT_HAVE_SYS_TYPES_H
43 #include <sys/types.h> /* For size_t */
44 #endif /* DONT_HAVE_SYS_TYPES_H */
45 #endif /* !STDC_HEADERS */
47 struct arrayobject; /* Forward */
49 struct arraydescr {
50 int typecode;
51 int itemsize;
52 PyObject * (*getitem) Py_FPROTO((struct arrayobject *, int));
53 int (*setitem) Py_FPROTO((struct arrayobject *, int, PyObject *));
56 typedef struct arrayobject {
57 PyObject_VAR_HEAD
58 char *ob_item;
59 struct arraydescr *ob_descr;
60 } arrayobject;
62 staticforward PyTypeObject Arraytype;
64 #define is_arrayobject(op) ((op)->ob_type == &Arraytype)
66 /* Forward */
67 static PyObject *newarrayobject Py_PROTO((int, struct arraydescr *));
68 #if 0
69 static int getarraysize Py_PROTO((PyObject *));
70 #endif
71 static PyObject *getarrayitem Py_PROTO((PyObject *, int));
72 static int setarrayitem Py_PROTO((PyObject *, int, PyObject *));
73 #if 0
74 static int insarrayitem Py_PROTO((PyObject *, int, PyObject *));
75 static int addarrayitem Py_PROTO((PyObject *, PyObject *));
76 #endif
78 static PyObject *
79 c_getitem(ap, i)
80 arrayobject *ap;
81 int i;
83 return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
86 static int
87 c_setitem(ap, i, v)
88 arrayobject *ap;
89 int i;
90 PyObject *v;
92 char x;
93 if (!PyArg_Parse(v, "c;array item must be char", &x))
94 return -1;
95 if (i >= 0)
96 ((char *)ap->ob_item)[i] = x;
97 return 0;
100 static PyObject *
101 b_getitem(ap, i)
102 arrayobject *ap;
103 int i;
105 long x = ((char *)ap->ob_item)[i];
106 if (x >= 128)
107 x -= 256;
108 return PyInt_FromLong(x);
111 static int
112 b_setitem(ap, i, v)
113 arrayobject *ap;
114 int i;
115 PyObject *v;
117 char x;
118 if (!PyArg_Parse(v, "b;array item must be integer", &x))
119 return -1;
120 if (i >= 0)
121 ((char *)ap->ob_item)[i] = x;
122 return 0;
125 static PyObject *
126 BB_getitem(ap, i)
127 arrayobject *ap;
128 int i;
130 long x = ((unsigned char *)ap->ob_item)[i];
131 return PyInt_FromLong(x);
134 #define BB_setitem b_setitem
136 static PyObject *
137 h_getitem(ap, i)
138 arrayobject *ap;
139 int i;
141 return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
144 static int
145 h_setitem(ap, i, v)
146 arrayobject *ap;
147 int i;
148 PyObject *v;
150 short x;
151 if (!PyArg_Parse(v, "h;array item must be integer", &x))
152 return -1;
153 if (i >= 0)
154 ((short *)ap->ob_item)[i] = x;
155 return 0;
158 static PyObject *
159 HH_getitem(ap, i)
160 arrayobject *ap;
161 int i;
163 return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
166 #define HH_setitem h_setitem
168 static PyObject *
169 i_getitem(ap, i)
170 arrayobject *ap;
171 int i;
173 return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
176 static int
177 i_setitem(ap, i, v)
178 arrayobject *ap;
179 int i;
180 PyObject *v;
182 int x;
183 if (!PyArg_Parse(v, "i;array item must be integer", &x))
184 return -1;
185 if (i >= 0)
186 ((int *)ap->ob_item)[i] = x;
187 return 0;
190 static PyObject *
191 II_getitem(ap, i)
192 arrayobject *ap;
193 int i;
195 return PyLong_FromUnsignedLong(
196 (unsigned long) ((unsigned int *)ap->ob_item)[i]);
199 static int
200 II_setitem(ap, i, v)
201 arrayobject *ap;
202 int i;
203 PyObject *v;
205 unsigned long x;
206 if (PyLong_Check(v)) {
207 x = PyLong_AsUnsignedLong(v);
208 if (x == (unsigned long) -1 && PyErr_Occurred())
209 return -1;
211 else {
212 if (!PyArg_Parse(v, "l;array item must be integer", &x))
213 return -1;
215 if (i >= 0)
216 ((unsigned int *)ap->ob_item)[i] = x;
217 return 0;
220 static PyObject *
221 l_getitem(ap, i)
222 arrayobject *ap;
223 int i;
225 return PyInt_FromLong(((long *)ap->ob_item)[i]);
228 static int
229 l_setitem(ap, i, v)
230 arrayobject *ap;
231 int i;
232 PyObject *v;
234 long x;
235 if (!PyArg_Parse(v, "l;array item must be integer", &x))
236 return -1;
237 if (i >= 0)
238 ((long *)ap->ob_item)[i] = x;
239 return 0;
242 static PyObject *
243 LL_getitem(ap, i)
244 arrayobject *ap;
245 int i;
247 return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
250 static int
251 LL_setitem(ap, i, v)
252 arrayobject *ap;
253 int i;
254 PyObject *v;
256 unsigned long x;
257 if (PyLong_Check(v)) {
258 x = PyLong_AsUnsignedLong(v);
259 if (x == (unsigned long) -1 && PyErr_Occurred())
260 return -1;
262 else {
263 if (!PyArg_Parse(v, "l;array item must be integer", &x))
264 return -1;
266 if (i >= 0)
267 ((unsigned long *)ap->ob_item)[i] = x;
268 return 0;
271 static PyObject *
272 f_getitem(ap, i)
273 arrayobject *ap;
274 int i;
276 return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
279 static int
280 f_setitem(ap, i, v)
281 arrayobject *ap;
282 int i;
283 PyObject *v;
285 float x;
286 if (!PyArg_Parse(v, "f;array item must be float", &x))
287 return -1;
288 if (i >= 0)
289 ((float *)ap->ob_item)[i] = x;
290 return 0;
293 static PyObject *
294 d_getitem(ap, i)
295 arrayobject *ap;
296 int i;
298 return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
301 static int
302 d_setitem(ap, i, v)
303 arrayobject *ap;
304 int i;
305 PyObject *v;
307 double x;
308 if (!PyArg_Parse(v, "d;array item must be float", &x))
309 return -1;
310 if (i >= 0)
311 ((double *)ap->ob_item)[i] = x;
312 return 0;
315 /* Description of types */
316 static struct arraydescr descriptors[] = {
317 {'c', sizeof(char), c_getitem, c_setitem},
318 {'b', sizeof(char), b_getitem, b_setitem},
319 {'B', sizeof(char), BB_getitem, BB_setitem},
320 {'h', sizeof(short), h_getitem, h_setitem},
321 {'H', sizeof(short), HH_getitem, HH_setitem},
322 {'i', sizeof(int), i_getitem, i_setitem},
323 {'I', sizeof(int), II_getitem, II_setitem},
324 {'l', sizeof(long), l_getitem, l_setitem},
325 {'L', sizeof(long), LL_getitem, LL_setitem},
326 {'f', sizeof(float), f_getitem, f_setitem},
327 {'d', sizeof(double), d_getitem, d_setitem},
328 {'\0', 0, 0, 0} /* Sentinel */
330 /* If we ever allow items larger than double, we must change reverse()! */
333 static PyObject *
334 newarrayobject(size, descr)
335 int size;
336 struct arraydescr *descr;
338 arrayobject *op;
339 size_t nbytes;
340 if (size < 0) {
341 PyErr_BadInternalCall();
342 return NULL;
344 nbytes = size * descr->itemsize;
345 /* Check for overflow */
346 if (nbytes / descr->itemsize != (size_t)size) {
347 return PyErr_NoMemory();
349 op = PyMem_NEW(arrayobject, 1);
350 if (op == NULL) {
351 return PyErr_NoMemory();
353 if (size <= 0) {
354 op->ob_item = NULL;
356 else {
357 op->ob_item = PyMem_NEW(char, nbytes);
358 if (op->ob_item == NULL) {
359 PyMem_DEL(op);
360 return PyErr_NoMemory();
363 op->ob_type = &Arraytype;
364 op->ob_size = size;
365 op->ob_descr = descr;
366 _Py_NewReference((PyObject *)op);
367 return (PyObject *) op;
370 #if 0
371 static int
372 getarraysize(op)
373 PyObject *op;
375 if (!is_arrayobject(op)) {
376 PyErr_BadInternalCall();
377 return -1;
379 return ((arrayobject *)op) -> ob_size;
381 #endif
383 static PyObject *
384 getarrayitem(op, i)
385 PyObject *op;
386 int i;
388 register arrayobject *ap;
389 if (!is_arrayobject(op)) {
390 PyErr_BadInternalCall();
391 return NULL;
393 ap = (arrayobject *)op;
394 if (i < 0 || i >= ap->ob_size) {
395 PyErr_SetString(PyExc_IndexError, "array index out of range");
396 return NULL;
398 return (*ap->ob_descr->getitem)(ap, i);
401 static int
402 ins1(self, where, v)
403 arrayobject *self;
404 int where;
405 PyObject *v;
407 char *items;
408 if (v == NULL) {
409 PyErr_BadInternalCall();
410 return -1;
412 if ((*self->ob_descr->setitem)(self, -1, v) < 0)
413 return -1;
414 items = self->ob_item;
415 PyMem_RESIZE(items, char,
416 (self->ob_size+1) * self->ob_descr->itemsize);
417 if (items == NULL) {
418 PyErr_NoMemory();
419 return -1;
421 if (where < 0)
422 where = 0;
423 if (where > self->ob_size)
424 where = self->ob_size;
425 memmove(items + (where+1)*self->ob_descr->itemsize,
426 items + where*self->ob_descr->itemsize,
427 (self->ob_size-where)*self->ob_descr->itemsize);
428 self->ob_item = items;
429 self->ob_size++;
430 return (*self->ob_descr->setitem)(self, where, v);
433 #if 0
434 static int
435 insarrayitem(op, where, newitem)
436 PyObject *op;
437 int where;
438 PyObject *newitem;
440 if (!is_arrayobject(op)) {
441 PyErr_BadInternalCall();
442 return -1;
444 return ins1((arrayobject *)op, where, newitem);
447 static int
448 addarrayitem(op, newitem)
449 PyObject *op;
450 PyObject *newitem;
452 if (!is_arrayobject(op)) {
453 PyErr_BadInternalCall();
454 return -1;
456 return ins1((arrayobject *)op,
457 (int) ((arrayobject *)op)->ob_size, newitem);
459 #endif
461 /* Methods */
463 static void
464 array_dealloc(op)
465 arrayobject *op;
467 if (op->ob_item != NULL)
468 PyMem_DEL(op->ob_item);
469 PyMem_DEL(op);
472 static int
473 array_compare(v, w)
474 arrayobject *v, *w;
476 int len = (v->ob_size < w->ob_size) ? v->ob_size : w->ob_size;
477 int i;
478 for (i = 0; i < len; i++) {
479 PyObject *ai, *bi;
480 int cmp;
481 ai = getarrayitem((PyObject *)v, i);
482 bi = getarrayitem((PyObject *)w, i);
483 if (ai && bi)
484 cmp = PyObject_Compare(ai, bi);
485 else
486 cmp = -1;
487 Py_XDECREF(ai);
488 Py_XDECREF(bi);
489 if (cmp != 0)
490 return cmp;
492 return v->ob_size - w->ob_size;
495 static int
496 array_length(a)
497 arrayobject *a;
499 return a->ob_size;
502 static PyObject *
503 array_item(a, i)
504 arrayobject *a;
505 int i;
507 if (i < 0 || i >= a->ob_size) {
508 PyErr_SetString(PyExc_IndexError, "array index out of range");
509 return NULL;
511 return getarrayitem((PyObject *)a, i);
514 static PyObject *
515 array_slice(a, ilow, ihigh)
516 arrayobject *a;
517 int ilow, ihigh;
519 arrayobject *np;
520 if (ilow < 0)
521 ilow = 0;
522 else if (ilow > a->ob_size)
523 ilow = a->ob_size;
524 if (ihigh < 0)
525 ihigh = 0;
526 if (ihigh < ilow)
527 ihigh = ilow;
528 else if (ihigh > a->ob_size)
529 ihigh = a->ob_size;
530 np = (arrayobject *) newarrayobject(ihigh - ilow, a->ob_descr);
531 if (np == NULL)
532 return NULL;
533 memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
534 (ihigh-ilow) * a->ob_descr->itemsize);
535 return (PyObject *)np;
538 static PyObject *
539 array_concat(a, bb)
540 arrayobject *a;
541 PyObject *bb;
543 int size;
544 arrayobject *np;
545 if (!is_arrayobject(bb)) {
546 PyErr_BadArgument();
547 return NULL;
549 #define b ((arrayobject *)bb)
550 if (a->ob_descr != b->ob_descr) {
551 PyErr_BadArgument();
552 return NULL;
554 size = a->ob_size + b->ob_size;
555 np = (arrayobject *) newarrayobject(size, a->ob_descr);
556 if (np == NULL) {
557 return NULL;
559 memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
560 memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
561 b->ob_item, b->ob_size*b->ob_descr->itemsize);
562 return (PyObject *)np;
563 #undef b
566 static PyObject *
567 array_repeat(a, n)
568 arrayobject *a;
569 int n;
571 int i;
572 int size;
573 arrayobject *np;
574 char *p;
575 int nbytes;
576 if (n < 0)
577 n = 0;
578 size = a->ob_size * n;
579 np = (arrayobject *) newarrayobject(size, a->ob_descr);
580 if (np == NULL)
581 return NULL;
582 p = np->ob_item;
583 nbytes = a->ob_size * a->ob_descr->itemsize;
584 for (i = 0; i < n; i++) {
585 memcpy(p, a->ob_item, nbytes);
586 p += nbytes;
588 return (PyObject *) np;
591 static int
592 array_ass_slice(a, ilow, ihigh, v)
593 arrayobject *a;
594 int ilow, ihigh;
595 PyObject *v;
597 char *item;
598 int n; /* Size of replacement array */
599 int d; /* Change in size */
600 #define b ((arrayobject *)v)
601 if (v == NULL)
602 n = 0;
603 else if (is_arrayobject(v)) {
604 n = b->ob_size;
605 if (a == b) {
606 /* Special case "a[i:j] = a" -- copy b first */
607 int ret;
608 v = array_slice(b, 0, n);
609 ret = array_ass_slice(a, ilow, ihigh, v);
610 Py_DECREF(v);
611 return ret;
613 if (b->ob_descr != a->ob_descr) {
614 PyErr_BadArgument();
615 return -1;
618 else {
619 PyErr_BadArgument();
620 return -1;
622 if (ilow < 0)
623 ilow = 0;
624 else if (ilow > a->ob_size)
625 ilow = a->ob_size;
626 if (ihigh < 0)
627 ihigh = 0;
628 if (ihigh < ilow)
629 ihigh = ilow;
630 else if (ihigh > a->ob_size)
631 ihigh = a->ob_size;
632 item = a->ob_item;
633 d = n - (ihigh-ilow);
634 if (d < 0) { /* Delete -d items */
635 memmove(item + (ihigh+d)*a->ob_descr->itemsize,
636 item + ihigh*a->ob_descr->itemsize,
637 (a->ob_size-ihigh)*a->ob_descr->itemsize);
638 a->ob_size += d;
639 PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
640 /* Can't fail */
641 a->ob_item = item;
643 else if (d > 0) { /* Insert d items */
644 PyMem_RESIZE(item, char,
645 (a->ob_size + d)*a->ob_descr->itemsize);
646 if (item == NULL) {
647 PyErr_NoMemory();
648 return -1;
650 memmove(item + (ihigh+d)*a->ob_descr->itemsize,
651 item + ihigh*a->ob_descr->itemsize,
652 (a->ob_size-ihigh)*a->ob_descr->itemsize);
653 a->ob_item = item;
654 a->ob_size += d;
656 if (n > 0)
657 memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
658 n*b->ob_descr->itemsize);
659 return 0;
660 #undef b
663 static int
664 array_ass_item(a, i, v)
665 arrayobject *a;
666 int i;
667 PyObject *v;
669 if (i < 0 || i >= a->ob_size) {
670 PyErr_SetString(PyExc_IndexError,
671 "array assignment index out of range");
672 return -1;
674 if (v == NULL)
675 return array_ass_slice(a, i, i+1, v);
676 return (*a->ob_descr->setitem)(a, i, v);
679 static int
680 setarrayitem(a, i, v)
681 PyObject *a;
682 int i;
683 PyObject *v;
685 if (!is_arrayobject(a)) {
686 PyErr_BadInternalCall();
687 return -1;
689 return array_ass_item((arrayobject *)a, i, v);
692 static PyObject *
693 ins(self, where, v)
694 arrayobject *self;
695 int where;
696 PyObject *v;
698 if (ins1(self, where, v) != 0)
699 return NULL;
700 Py_INCREF(Py_None);
701 return Py_None;
704 static PyObject *
705 array_insert(self, args)
706 arrayobject *self;
707 PyObject *args;
709 int i;
710 PyObject *v;
711 if (!PyArg_Parse(args, "(iO)", &i, &v))
712 return NULL;
713 return ins(self, i, v);
716 static char insert_doc [] =
717 "insert (i,x)\n\
719 Insert a new item x into the array before position i.";
722 static PyObject *
723 array_buffer_info(self, args)
724 arrayobject *self;
725 PyObject *args;
727 return Py_BuildValue("ll",
728 (long)(self->ob_item), (long)(self->ob_size));
731 static char buffer_info_doc [] =
732 "buffer_info -> (address, length)\n\
734 Return a tuple (address, length) giving the current memory address and\n\
735 the length in bytes of the buffer used to hold array's contents.";
738 static PyObject *
739 array_append(self, args)
740 arrayobject *self;
741 PyObject *args;
743 PyObject *v;
744 if (!PyArg_Parse(args, "O", &v))
745 return NULL;
746 return ins(self, (int) self->ob_size, v);
749 static char append_doc [] =
750 "append(x)\n\
752 Append new value x to the end of the array.";
755 static PyObject *
756 array_byteswap(self, args)
757 arrayobject *self;
758 PyObject *args;
760 char *p;
761 int i;
763 if (!PyArg_ParseTuple(args, ":byteswap"))
764 return NULL;
766 switch (self->ob_descr->itemsize) {
767 case 1:
768 break;
769 case 2:
770 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
771 char p0 = p[0];
772 p[0] = p[1];
773 p[1] = p0;
775 break;
776 case 4:
777 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
778 char p0 = p[0];
779 char p1 = p[1];
780 p[0] = p[3];
781 p[1] = p[2];
782 p[2] = p1;
783 p[3] = p0;
785 break;
786 case 8:
787 for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
788 char p0 = p[0];
789 char p1 = p[1];
790 char p2 = p[2];
791 char p3 = p[3];
792 p[0] = p[7];
793 p[1] = p[6];
794 p[2] = p[5];
795 p[3] = p[4];
796 p[4] = p3;
797 p[5] = p2;
798 p[6] = p1;
799 p[7] = p0;
801 break;
802 default:
803 PyErr_SetString(PyExc_RuntimeError,
804 "don't know how to byteswap this array type");
805 return NULL;
807 Py_INCREF(Py_None);
808 return Py_None;
811 static char byteswap_doc [] =
812 "byteswap()\n\
814 Byteswap all items of the array. If the items in the array are not 1, 2,\n\
815 4, or 8 bytes in size, RuntimeError is raised.";
817 static PyObject *
818 array_reverse(self, args)
819 arrayobject *self;
820 PyObject *args;
822 register int itemsize = self->ob_descr->itemsize;
823 register char *p, *q;
824 char tmp[sizeof(double)]; /* Assume that's the max item size */
826 if (args != NULL) {
827 PyErr_BadArgument();
828 return NULL;
831 if (self->ob_size > 1) {
832 for (p = self->ob_item,
833 q = self->ob_item + (self->ob_size - 1)*itemsize;
834 p < q;
835 p += itemsize, q -= itemsize) {
836 memmove(tmp, p, itemsize);
837 memmove(p, q, itemsize);
838 memmove(q, tmp, itemsize);
842 Py_INCREF(Py_None);
843 return Py_None;
846 static char reverse_doc [] =
847 "reverse()\n\
849 Reverse the order of the items in the array.";
851 /* The following routines were adapted from listobject.c but not converted.
852 To make them work you will have to work! */
854 #if 0
855 static PyObject *
856 array_index(self, args)
857 arrayobject *self;
858 PyObject *args;
860 int i;
862 if (args == NULL) {
863 PyErr_BadArgument();
864 return NULL;
866 for (i = 0; i < self->ob_size; i++) {
867 if (PyObject_Compare(self->ob_item[i], args) == 0)
868 return PyInt_FromLong((long)i);
869 /* XXX PyErr_Occurred */
871 PyErr_SetString(PyExc_ValueError, "array.index(x): x not in array");
872 return NULL;
874 #endif
876 #if 0
877 static PyObject *
878 array_count(self, args)
879 arrayobject *self;
880 PyObject *args;
882 int count = 0;
883 int i;
885 if (args == NULL) {
886 PyErr_BadArgument();
887 return NULL;
889 for (i = 0; i < self->ob_size; i++) {
890 if (PyObject_Compare(self->ob_item[i], args) == 0)
891 count++;
892 /* XXX PyErr_Occurred */
894 return PyInt_FromLong((long)count);
896 #endif
898 #if 0
899 static PyObject *
900 array_remove(self, args)
901 arrayobject *self;
902 PyObject *args;
904 int i;
906 if (args == NULL) {
907 PyErr_BadArgument();
908 return NULL;
910 for (i = 0; i < self->ob_size; i++) {
911 if (PyObject_Compare(self->ob_item[i], args) == 0) {
912 if (array_ass_slice(self, i, i+1,
913 (PyObject *)NULL) != 0)
914 return NULL;
915 Py_INCREF(Py_None);
916 return Py_None;
918 /* XXX PyErr_Occurred */
920 PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in array");
921 return NULL;
923 #endif
925 static PyObject *
926 array_fromfile(self, args)
927 arrayobject *self;
928 PyObject *args;
930 PyObject *f;
931 int n;
932 FILE *fp;
933 if (!PyArg_Parse(args, "(Oi)", &f, &n))
934 return NULL;
935 fp = PyFile_AsFile(f);
936 if (fp == NULL) {
937 PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
938 return NULL;
940 if (n > 0) {
941 char *item = self->ob_item;
942 int itemsize = self->ob_descr->itemsize;
943 int nread;
944 int newlength;
945 size_t newbytes;
946 /* Be careful here about overflow */
947 if ((newlength = self->ob_size + n) <= 0 ||
948 (newbytes = newlength * itemsize) / itemsize !=
949 (size_t)newlength)
950 goto nomem;
951 PyMem_RESIZE(item, char, newbytes);
952 if (item == NULL) {
953 nomem:
954 PyErr_NoMemory();
955 return NULL;
957 self->ob_item = item;
958 self->ob_size += n;
959 nread = fread(item + (self->ob_size - n) * itemsize,
960 itemsize, n, fp);
961 if (nread < n) {
962 self->ob_size -= (n - nread);
963 PyMem_RESIZE(item, char, self->ob_size*itemsize);
964 self->ob_item = item;
965 PyErr_SetString(PyExc_EOFError,
966 "not enough items in file");
967 return NULL;
970 Py_INCREF(Py_None);
971 return Py_None;
974 static char fromfile_doc [] =
975 "fromfile(f, n)\n\
977 Read n objects from the file object f and append them to the end of the\n\
978 array. Also called as read.";
981 static PyObject *
982 array_tofile(self, args)
983 arrayobject *self;
984 PyObject *args;
986 PyObject *f;
987 FILE *fp;
988 if (!PyArg_Parse(args, "O", &f))
989 return NULL;
990 fp = PyFile_AsFile(f);
991 if (fp == NULL) {
992 PyErr_SetString(PyExc_TypeError, "arg must be open file");
993 return NULL;
995 if (self->ob_size > 0) {
996 if ((int)fwrite(self->ob_item, self->ob_descr->itemsize,
997 self->ob_size, fp) != self->ob_size) {
998 PyErr_SetFromErrno(PyExc_IOError);
999 clearerr(fp);
1000 return NULL;
1003 Py_INCREF(Py_None);
1004 return Py_None;
1007 static char tofile_doc [] =
1008 "tofile(f)\n\
1010 Write all items (as machine values) to the file object f. Also called as\n\
1011 write.";
1014 static PyObject *
1015 array_fromlist(self, args)
1016 arrayobject *self;
1017 PyObject *args;
1019 int n;
1020 PyObject *list;
1021 int itemsize = self->ob_descr->itemsize;
1022 if (!PyArg_Parse(args, "O", &list))
1023 return NULL;
1024 if (!PyList_Check(list)) {
1025 PyErr_SetString(PyExc_TypeError, "arg must be list");
1026 return NULL;
1028 n = PyList_Size(list);
1029 if (n > 0) {
1030 char *item = self->ob_item;
1031 int i;
1032 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
1033 if (item == NULL) {
1034 PyErr_NoMemory();
1035 return NULL;
1037 self->ob_item = item;
1038 self->ob_size += n;
1039 for (i = 0; i < n; i++) {
1040 PyObject *v = PyList_GetItem(list, i);
1041 if ((*self->ob_descr->setitem)(self,
1042 self->ob_size - n + i, v) != 0) {
1043 self->ob_size -= n;
1044 PyMem_RESIZE(item, char,
1045 self->ob_size * itemsize);
1046 self->ob_item = item;
1047 return NULL;
1051 Py_INCREF(Py_None);
1052 return Py_None;
1055 static char fromlist_doc [] =
1056 "fromlist(list)\n\
1058 Append items to array from list.";
1061 static PyObject *
1062 array_tolist(self, args)
1063 arrayobject *self;
1064 PyObject *args;
1066 PyObject *list = PyList_New(self->ob_size);
1067 int i;
1068 if (list == NULL)
1069 return NULL;
1070 for (i = 0; i < self->ob_size; i++) {
1071 PyObject *v = getarrayitem((PyObject *)self, i);
1072 if (v == NULL) {
1073 Py_DECREF(list);
1074 return NULL;
1076 PyList_SetItem(list, i, v);
1078 return list;
1081 static char tolist_doc [] =
1082 "tolist() -> list\n\
1084 Convert array to an ordinary list with the same items.";
1087 static PyObject *
1088 array_fromstring(self, args)
1089 arrayobject *self;
1090 PyObject *args;
1092 char *str;
1093 int n;
1094 int itemsize = self->ob_descr->itemsize;
1095 if (!PyArg_Parse(args, "s#", &str, &n))
1096 return NULL;
1097 if (n % itemsize != 0) {
1098 PyErr_SetString(PyExc_ValueError,
1099 "string length not a multiple of item size");
1100 return NULL;
1102 n = n / itemsize;
1103 if (n > 0) {
1104 char *item = self->ob_item;
1105 PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
1106 if (item == NULL) {
1107 PyErr_NoMemory();
1108 return NULL;
1110 self->ob_item = item;
1111 self->ob_size += n;
1112 memcpy(item + (self->ob_size - n) * itemsize,
1113 str, itemsize*n);
1115 Py_INCREF(Py_None);
1116 return Py_None;
1119 static char fromstring_doc [] =
1120 "fromstring(string)\n\
1122 Appends items from the string, interpreting it as an array of machine\n\
1123 values,as if it had been read from a file using the fromfile() method).";
1126 static PyObject *
1127 array_tostring(self, args)
1128 arrayobject *self;
1129 PyObject *args;
1131 if (!PyArg_Parse(args, ""))
1132 return NULL;
1133 return PyString_FromStringAndSize(self->ob_item,
1134 self->ob_size * self->ob_descr->itemsize);
1137 static char tostring_doc [] =
1138 "tostring() -> string\n\
1140 Convert the array to an array of machine values and return the string\n\
1141 representation.";
1143 PyMethodDef array_methods[] = {
1144 {"append", (PyCFunction)array_append, 0, append_doc},
1145 {"buffer_info", (PyCFunction)array_buffer_info, 0, buffer_info_doc},
1146 {"byteswap", (PyCFunction)array_byteswap, METH_VARARGS,
1147 byteswap_doc},
1148 /* {"count", (method)array_count},*/
1149 {"fromfile", (PyCFunction)array_fromfile, 0, fromfile_doc},
1150 {"fromlist", (PyCFunction)array_fromlist, 0, fromlist_doc},
1151 {"fromstring", (PyCFunction)array_fromstring, 0, fromstring_doc},
1152 /* {"index", (method)array_index},*/
1153 {"insert", (PyCFunction)array_insert, 0, insert_doc},
1154 {"read", (PyCFunction)array_fromfile, 0, fromfile_doc},
1155 /* {"remove", (method)array_remove},*/
1156 {"reverse", (PyCFunction)array_reverse, 0, reverse_doc},
1157 /* {"sort", (method)array_sort},*/
1158 {"tofile", (PyCFunction)array_tofile, 0, tofile_doc},
1159 {"tolist", (PyCFunction)array_tolist, 0, tolist_doc},
1160 {"tostring", (PyCFunction)array_tostring, 0, tostring_doc},
1161 {"write", (PyCFunction)array_tofile, 0, tofile_doc},
1162 {NULL, NULL} /* sentinel */
1165 static PyObject *
1166 array_getattr(a, name)
1167 arrayobject *a;
1168 char *name;
1170 if (strcmp(name, "typecode") == 0) {
1171 char tc = a->ob_descr->typecode;
1172 return PyString_FromStringAndSize(&tc, 1);
1174 if (strcmp(name, "itemsize") == 0) {
1175 return PyInt_FromLong((long)a->ob_descr->itemsize);
1177 if (strcmp(name, "__members__") == 0) {
1178 PyObject *list = PyList_New(2);
1179 if (list) {
1180 PyList_SetItem(list, 0,
1181 PyString_FromString("typecode"));
1182 PyList_SetItem(list, 1,
1183 PyString_FromString("itemsize"));
1184 if (PyErr_Occurred()) {
1185 Py_DECREF(list);
1186 list = NULL;
1189 return list;
1191 return Py_FindMethod(array_methods, (PyObject *)a, name);
1194 static int
1195 array_print(a, fp, flags)
1196 arrayobject *a;
1197 FILE *fp;
1198 int flags;
1200 int ok = 0;
1201 int i, len;
1202 PyObject *v;
1203 len = a->ob_size;
1204 if (len == 0) {
1205 fprintf(fp, "array('%c')", a->ob_descr->typecode);
1206 return ok;
1208 if (a->ob_descr->typecode == 'c') {
1209 fprintf(fp, "array('c', ");
1210 v = array_tostring(a, (PyObject *)NULL);
1211 ok = PyObject_Print(v, fp, 0);
1212 Py_XDECREF(v);
1213 fprintf(fp, ")");
1214 return ok;
1216 fprintf(fp, "array('%c', [", a->ob_descr->typecode);
1217 for (i = 0; i < len && ok == 0; i++) {
1218 if (i > 0)
1219 fprintf(fp, ", ");
1220 v = (a->ob_descr->getitem)(a, i);
1221 ok = PyObject_Print(v, fp, 0);
1222 Py_XDECREF(v);
1224 fprintf(fp, "])");
1225 return ok;
1228 static PyObject *
1229 array_repr(a)
1230 arrayobject *a;
1232 char buf[256];
1233 PyObject *s, *t, *comma, *v;
1234 int i, len;
1235 len = a->ob_size;
1236 if (len == 0) {
1237 sprintf(buf, "array('%c')", a->ob_descr->typecode);
1238 return PyString_FromString(buf);
1240 if (a->ob_descr->typecode == 'c') {
1241 sprintf(buf, "array('c', ");
1242 s = PyString_FromString(buf);
1243 v = array_tostring(a, (PyObject *)NULL);
1244 t = PyObject_Repr(v);
1245 Py_XDECREF(v);
1246 PyString_ConcatAndDel(&s, t);
1247 PyString_ConcatAndDel(&s, PyString_FromString(")"));
1248 return s;
1250 sprintf(buf, "array('%c', [", a->ob_descr->typecode);
1251 s = PyString_FromString(buf);
1252 comma = PyString_FromString(", ");
1253 for (i = 0; i < len && !PyErr_Occurred(); i++) {
1254 if (i > 0)
1255 PyString_Concat(&s, comma);
1256 v = (a->ob_descr->getitem)(a, i);
1257 t = PyObject_Repr(v);
1258 Py_XDECREF(v);
1259 PyString_ConcatAndDel(&s, t);
1261 Py_XDECREF(comma);
1262 PyString_ConcatAndDel(&s, PyString_FromString("])"));
1263 return s;
1266 static int
1267 array_buffer_getreadbuf(self, index, ptr)
1268 arrayobject *self;
1269 int index;
1270 const void **ptr;
1272 if ( index != 0 ) {
1273 PyErr_SetString(PyExc_SystemError,
1274 "Accessing non-existent array segment");
1275 return -1;
1277 *ptr = (void *)self->ob_item;
1278 return self->ob_size*self->ob_descr->itemsize;
1281 static int
1282 array_buffer_getwritebuf(self, index, ptr)
1283 arrayobject *self;
1284 int index;
1285 const void **ptr;
1287 if ( index != 0 ) {
1288 PyErr_SetString(PyExc_SystemError,
1289 "Accessing non-existent array segment");
1290 return -1;
1292 *ptr = (void *)self->ob_item;
1293 return self->ob_size*self->ob_descr->itemsize;
1296 static int
1297 array_buffer_getsegcount(self, lenp)
1298 arrayobject *self;
1299 int *lenp;
1301 if ( lenp )
1302 *lenp = self->ob_size*self->ob_descr->itemsize;
1303 return 1;
1306 static PySequenceMethods array_as_sequence = {
1307 (inquiry)array_length, /*sq_length*/
1308 (binaryfunc)array_concat, /*sq_concat*/
1309 (intargfunc)array_repeat, /*sq_repeat*/
1310 (intargfunc)array_item, /*sq_item*/
1311 (intintargfunc)array_slice, /*sq_slice*/
1312 (intobjargproc)array_ass_item, /*sq_ass_item*/
1313 (intintobjargproc)array_ass_slice, /*sq_ass_slice*/
1316 static PyBufferProcs array_as_buffer = {
1317 (getreadbufferproc)array_buffer_getreadbuf,
1318 (getwritebufferproc)array_buffer_getwritebuf,
1319 (getsegcountproc)array_buffer_getsegcount,
1325 static PyObject *
1326 a_array(self, args)
1327 PyObject *self;
1328 PyObject *args;
1330 char c;
1331 PyObject *initial = NULL;
1332 struct arraydescr *descr;
1333 if (!PyArg_Parse(args, "c", &c)) {
1334 PyErr_Clear();
1335 if (!PyArg_Parse(args, "(cO)", &c, &initial))
1336 return NULL;
1337 if (!PyList_Check(initial) && !PyString_Check(initial)) {
1338 PyErr_SetString(PyExc_TypeError,
1339 "array initializer must be list or string");
1340 return NULL;
1343 for (descr = descriptors; descr->typecode != '\0'; descr++) {
1344 if (descr->typecode == c) {
1345 PyObject *a;
1346 int len;
1347 if (initial == NULL || !PyList_Check(initial))
1348 len = 0;
1349 else
1350 len = PyList_Size(initial);
1351 a = newarrayobject(len, descr);
1352 if (a == NULL)
1353 return NULL;
1354 if (len > 0) {
1355 int i;
1356 for (i = 0; i < len; i++) {
1357 PyObject *v =
1358 PyList_GetItem(initial, i);
1359 if (setarrayitem(a, i, v) != 0) {
1360 Py_DECREF(a);
1361 return NULL;
1365 if (initial != NULL && PyString_Check(initial)) {
1366 PyObject *v =
1367 array_fromstring((arrayobject *)a, initial);
1368 if (v == NULL) {
1369 Py_DECREF(a);
1370 return NULL;
1372 Py_DECREF(v);
1374 return a;
1377 PyErr_SetString(PyExc_ValueError,
1378 "bad typecode (must be c, b, B, h, H, i, I, l, L, f or d)");
1379 return NULL;
1382 static char a_array_doc [] =
1383 "array(typecode [, initializer]) -> array\n\
1385 Return a new array whose items are restricted by typecode, and\n\
1386 initialized from the optional initializer value, which must be a list\n\
1387 or a string.";
1389 static PyMethodDef a_methods[] = {
1390 {"array", a_array, 0, a_array_doc},
1391 {NULL, NULL} /* sentinel */
1394 static char module_doc [] =
1395 "This module defines a new object type which can efficiently represent\n\
1396 an array of basic values: characters, integers, floating point\n\
1397 numbers. Arrays are sequence types and behave very much like lists,\n\
1398 except that the type of objects stored in them is constrained. The\n\
1399 type is specified at object creation time by using a type code, which\n\
1400 is a single character. The following type codes are defined:\n\
1402 Type code C Type Minimum size in bytes \n\
1403 'c' character 1 \n\
1404 'b' signed integer 1 \n\
1405 'B' unsigned integer 1 \n\
1406 'h' signed integer 2 \n\
1407 'H' unsigned integer 2 \n\
1408 'i' signed integer 2 \n\
1409 'I' unsigned integer 2 \n\
1410 'l' signed integer 4 \n\
1411 'L' unsigned integer 4 \n\
1412 'f' floating point 4 \n\
1413 'd' floating point 8 \n\
1415 Functions:\n\
1417 array(typecode [, initializer]) -- create a new array\n\
1419 Special Objects:\n\
1421 ArrayType -- type object for array objects\n\
1424 static char arraytype_doc [] =
1425 "An array represents basic values and behave very much like lists, except\n\
1426 the type of objects stored in them is constrained.\n\
1428 Methods:\n\
1430 append() -- append a new item to the end of the array\n\
1431 buffer_info() -- return information giving the current memory info\n\
1432 byteswap() -- byteswap all the items of the array\n\
1433 fromfile() -- read items from a file object\n\
1434 fromlist() -- append items from the list\n\
1435 fromstring() -- append items from the string\n\
1436 insert() -- insert a new item into the array at a provided position\n\
1437 read() -- DEPRECATED, use fromfile()\n\
1438 reverse() -- reverse the order of the items in the array\n\
1439 tofile() -- write all items to a file object\n\
1440 tolist() -- return the array converted to an ordinary list\n\
1441 tostring() -- return the array converted to a string\n\
1442 write() -- DEPRECATED, use tofile()\n\
1444 Variables:\n\
1446 typecode -- the typecode character used to create the array\n\
1447 itemsize -- the length in bytes of one array item\n\
1450 statichere PyTypeObject Arraytype = {
1451 PyObject_HEAD_INIT(NULL)
1453 "array",
1454 sizeof(arrayobject),
1456 (destructor)array_dealloc, /*tp_dealloc*/
1457 (printfunc)array_print, /*tp_print*/
1458 (getattrfunc)array_getattr, /*tp_getattr*/
1459 0, /*tp_setattr*/
1460 (cmpfunc)array_compare, /*tp_compare*/
1461 (reprfunc)array_repr, /*tp_repr*/
1462 0, /*tp_as_number*/
1463 &array_as_sequence, /*tp_as_sequence*/
1464 0, /*tp_as_mapping*/
1465 0, /*tp_hash*/
1466 0, /*tp_call*/
1467 0, /*tp_str*/
1468 0, /*tp_getattro*/
1469 0, /*tp_setattro*/
1470 &array_as_buffer, /*tp_as_buffer*/
1471 0, /*tp_xxx4*/
1472 arraytype_doc, /*tp_doc*/
1475 DL_EXPORT(void)
1476 initarray()
1478 PyObject *m, *d;
1480 Arraytype.ob_type = &PyType_Type;
1481 m = Py_InitModule3("array", a_methods, module_doc);
1482 d = PyModule_GetDict(m);
1483 PyDict_SetItemString(d, "ArrayType", (PyObject *)&Arraytype);
1484 /* No need to check the error here, the caller will do that */