History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Modules/arraymodule.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Modules/arraymodule.c+2141−0
@@ -0,0 +1,2141 @@
1+/* 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+
6+#define PY_SSIZE_T_CLEAN
7+#include "Python.h"
8+#include "structmember.h"
9+
10+#ifdef STDC_HEADERS
11+#include <stddef.h>
12+#else /* !STDC_HEADERS */
13+#ifdef HAVE_SYS_TYPES_H
14+#include <sys/types.h> /* For size_t */
15+#endif /* HAVE_SYS_TYPES_H */
16+#endif /* !STDC_HEADERS */
17+
18+struct arrayobject; /* Forward */
19+
20+/* All possible arraydescr values are defined in the vector "descriptors"
21+ * below. That's defined later because the appropriate get and set
22+ * functions aren't visible yet.
23+ */
24+struct arraydescr {
25+ int typecode;
26+ int itemsize;
27+ PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
28+ int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
29+};
30+
31+typedef struct arrayobject {
32+ PyObject_VAR_HEAD
33+ char *ob_item;
34+ Py_ssize_t allocated;
35+ struct arraydescr *ob_descr;
36+ PyObject *weakreflist; /* List of weak references */
37+} arrayobject;
38+
39+static PyTypeObject Arraytype;
40+
41+#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
42+#define array_CheckExact(op) ((op)->ob_type == &Arraytype)
43+
44+static int
45+array_resize(arrayobject *self, Py_ssize_t newsize)
46+{
47+ char *items;
48+ size_t _new_size;
49+
50+ /* Bypass realloc() when a previous overallocation is large enough
51+ to accommodate the newsize. If the newsize is 16 smaller than the
52+ current size, then proceed with the realloc() to shrink the list.
53+ */
54+
55+ if (self->allocated >= newsize &&
56+ self->ob_size < newsize + 16 &&
57+ self->ob_item != NULL) {
58+ self->ob_size = newsize;
59+ return 0;
60+ }
61+
62+ /* This over-allocates proportional to the array size, making room
63+ * for additional growth. The over-allocation is mild, but is
64+ * enough to give linear-time amortized behavior over a long
65+ * sequence of appends() in the presence of a poorly-performing
66+ * system realloc().
67+ * The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
68+ * Note, the pattern starts out the same as for lists but then
69+ * grows at a smaller rate so that larger arrays only overallocate
70+ * by about 1/16th -- this is done because arrays are presumed to be more
71+ * memory critical.
72+ */
73+
74+ _new_size = (newsize >> 4) + (self->ob_size < 8 ? 3 : 7) + newsize;
75+ items = self->ob_item;
76+ /* XXX The following multiplication and division does not optimize away
77+ like it does for lists since the size is not known at compile time */
78+ if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
79+ PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
80+ else
81+ items = NULL;
82+ if (items == NULL) {
83+ PyErr_NoMemory();
84+ return -1;
85+ }
86+ self->ob_item = items;
87+ self->ob_size = newsize;
88+ self->allocated = _new_size;
89+ return 0;
90+}
91+
92+/****************************************************************************
93+Get and Set functions for each type.
94+A Get function takes an arrayobject* and an integer index, returning the
95+array value at that index wrapped in an appropriate PyObject*.
96+A Set function takes an arrayobject, integer index, and PyObject*; sets
97+the array value at that index to the raw C data extracted from the PyObject*,
98+and returns 0 if successful, else nonzero on failure (PyObject* not of an
99+appropriate type or value).
100+Note that the basic Get and Set functions do NOT check that the index is
101+in bounds; that's the responsibility of the caller.
102+****************************************************************************/
103+
104+static PyObject *
105+c_getitem(arrayobject *ap, Py_ssize_t i)
106+{
107+ return PyString_FromStringAndSize(&((char *)ap->ob_item)[i], 1);
108+}
109+
110+static int
111+c_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
112+{
113+ char x;
114+ if (!PyArg_Parse(v, "c;array item must be char", &x))
115+ return -1;
116+ if (i >= 0)
117+ ((char *)ap->ob_item)[i] = x;
118+ return 0;
119+}
120+
121+static PyObject *
122+b_getitem(arrayobject *ap, Py_ssize_t i)
123+{
124+ long x = ((char *)ap->ob_item)[i];
125+ if (x >= 128)
126+ x -= 256;
127+ return PyInt_FromLong(x);
128+}
129+
130+static int
131+b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
132+{
133+ short x;
134+ /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
135+ must use the next size up that is signed ('h') and manually do
136+ the overflow checking */
137+ if (!PyArg_Parse(v, "h;array item must be integer", &x))
138+ return -1;
139+ else if (x < -128) {
140+ PyErr_SetString(PyExc_OverflowError,
141+ "signed char is less than minimum");
142+ return -1;
143+ }
144+ else if (x > 127) {
145+ PyErr_SetString(PyExc_OverflowError,
146+ "signed char is greater than maximum");
147+ return -1;
148+ }
149+ if (i >= 0)
150+ ((char *)ap->ob_item)[i] = (char)x;
151+ return 0;
152+}
153+
154+static PyObject *
155+BB_getitem(arrayobject *ap, Py_ssize_t i)
156+{
157+ long x = ((unsigned char *)ap->ob_item)[i];
158+ return PyInt_FromLong(x);
159+}
160+
161+static int
162+BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
163+{
164+ unsigned char x;
165+ /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
166+ if (!PyArg_Parse(v, "b;array item must be integer", &x))
167+ return -1;
168+ if (i >= 0)
169+ ((char *)ap->ob_item)[i] = x;
170+ return 0;
171+}
172+
173+#ifdef Py_USING_UNICODE
174+static PyObject *
175+u_getitem(arrayobject *ap, Py_ssize_t i)
176+{
177+ return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
178+}
179+
180+static int
181+u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
182+{
183+ Py_UNICODE *p;
184+ Py_ssize_t len;
185+
186+ if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
187+ return -1;
188+ if (len != 1) {
189+ PyErr_SetString(PyExc_TypeError,
190+ "array item must be unicode character");
191+ return -1;
192+ }
193+ if (i >= 0)
194+ ((Py_UNICODE *)ap->ob_item)[i] = p[0];
195+ return 0;
196+}
197+#endif
198+
199+static PyObject *
200+h_getitem(arrayobject *ap, Py_ssize_t i)
201+{
202+ return PyInt_FromLong((long) ((short *)ap->ob_item)[i]);
203+}
204+
205+static int
206+h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
207+{
208+ short x;
209+ /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
210+ if (!PyArg_Parse(v, "h;array item must be integer", &x))
211+ return -1;
212+ if (i >= 0)
213+ ((short *)ap->ob_item)[i] = x;
214+ return 0;
215+}
216+
217+static PyObject *
218+HH_getitem(arrayobject *ap, Py_ssize_t i)
219+{
220+ return PyInt_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
221+}
222+
223+static int
224+HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
225+{
226+ int x;
227+ /* PyArg_Parse's 'h' formatter is for a signed short, therefore
228+ must use the next size up and manually do the overflow checking */
229+ if (!PyArg_Parse(v, "i;array item must be integer", &x))
230+ return -1;
231+ else if (x < 0) {
232+ PyErr_SetString(PyExc_OverflowError,
233+ "unsigned short is less than minimum");
234+ return -1;
235+ }
236+ else if (x > USHRT_MAX) {
237+ PyErr_SetString(PyExc_OverflowError,
238+ "unsigned short is greater than maximum");
239+ return -1;
240+ }
241+ if (i >= 0)
242+ ((short *)ap->ob_item)[i] = (short)x;
243+ return 0;
244+}
245+
246+static PyObject *
247+i_getitem(arrayobject *ap, Py_ssize_t i)
248+{
249+ return PyInt_FromLong((long) ((int *)ap->ob_item)[i]);
250+}
251+
252+static int
253+i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
254+{
255+ int x;
256+ /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
257+ if (!PyArg_Parse(v, "i;array item must be integer", &x))
258+ return -1;
259+ if (i >= 0)
260+ ((int *)ap->ob_item)[i] = x;
261+ return 0;
262+}
263+
264+static PyObject *
265+II_getitem(arrayobject *ap, Py_ssize_t i)
266+{
267+ return PyLong_FromUnsignedLong(
268+ (unsigned long) ((unsigned int *)ap->ob_item)[i]);
269+}
270+
271+static int
272+II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
273+{
274+ unsigned long x;
275+ if (PyLong_Check(v)) {
276+ x = PyLong_AsUnsignedLong(v);
277+ if (x == (unsigned long) -1 && PyErr_Occurred())
278+ return -1;
279+ }
280+ else {
281+ long y;
282+ if (!PyArg_Parse(v, "l;array item must be integer", &y))
283+ return -1;
284+ if (y < 0) {
285+ PyErr_SetString(PyExc_OverflowError,
286+ "unsigned int is less than minimum");
287+ return -1;
288+ }
289+ x = (unsigned long)y;
290+
291+ }
292+ if (x > UINT_MAX) {
293+ PyErr_SetString(PyExc_OverflowError,
294+ "unsigned int is greater than maximum");
295+ return -1;
296+ }
297+
298+ if (i >= 0)
299+ ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
300+ return 0;
301+}
302+
303+static PyObject *
304+l_getitem(arrayobject *ap, Py_ssize_t i)
305+{
306+ return PyInt_FromLong(((long *)ap->ob_item)[i]);
307+}
308+
309+static int
310+l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
311+{
312+ long x;
313+ if (!PyArg_Parse(v, "l;array item must be integer", &x))
314+ return -1;
315+ if (i >= 0)
316+ ((long *)ap->ob_item)[i] = x;
317+ return 0;
318+}
319+
320+static PyObject *
321+LL_getitem(arrayobject *ap, Py_ssize_t i)
322+{
323+ return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
324+}
325+
326+static int
327+LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
328+{
329+ unsigned long x;
330+ if (PyLong_Check(v)) {
331+ x = PyLong_AsUnsignedLong(v);
332+ if (x == (unsigned long) -1 && PyErr_Occurred())
333+ return -1;
334+ }
335+ else {
336+ long y;
337+ if (!PyArg_Parse(v, "l;array item must be integer", &y))
338+ return -1;
339+ if (y < 0) {
340+ PyErr_SetString(PyExc_OverflowError,
341+ "unsigned long is less than minimum");
342+ return -1;
343+ }
344+ x = (unsigned long)y;
345+
346+ }
347+ if (x > ULONG_MAX) {
348+ PyErr_SetString(PyExc_OverflowError,
349+ "unsigned long is greater than maximum");
350+ return -1;
351+ }
352+
353+ if (i >= 0)
354+ ((unsigned long *)ap->ob_item)[i] = x;
355+ return 0;
356+}
357+
358+static PyObject *
359+f_getitem(arrayobject *ap, Py_ssize_t i)
360+{
361+ return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
362+}
363+
364+static int
365+f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
366+{
367+ float x;
368+ if (!PyArg_Parse(v, "f;array item must be float", &x))
369+ return -1;
370+ if (i >= 0)
371+ ((float *)ap->ob_item)[i] = x;
372+ return 0;
373+}
374+
375+static PyObject *
376+d_getitem(arrayobject *ap, Py_ssize_t i)
377+{
378+ return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
379+}
380+
381+static int
382+d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
383+{
384+ double x;
385+ if (!PyArg_Parse(v, "d;array item must be float", &x))
386+ return -1;
387+ if (i >= 0)
388+ ((double *)ap->ob_item)[i] = x;
389+ return 0;
390+}
391+
392+/* Description of types */
393+static struct arraydescr descriptors[] = {
394+ {'c', sizeof(char), c_getitem, c_setitem},
395+ {'b', sizeof(char), b_getitem, b_setitem},
396+ {'B', sizeof(char), BB_getitem, BB_setitem},
397+#ifdef Py_USING_UNICODE
398+ {'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
399+#endif
400+ {'h', sizeof(short), h_getitem, h_setitem},
401+ {'H', sizeof(short), HH_getitem, HH_setitem},
402+ {'i', sizeof(int), i_getitem, i_setitem},
403+ {'I', sizeof(int), II_getitem, II_setitem},
404+ {'l', sizeof(long), l_getitem, l_setitem},
405+ {'L', sizeof(long), LL_getitem, LL_setitem},
406+ {'f', sizeof(float), f_getitem, f_setitem},
407+ {'d', sizeof(double), d_getitem, d_setitem},
408+ {'\0', 0, 0, 0} /* Sentinel */
409+};
410+
411+/****************************************************************************
412+Implementations of array object methods.
413+****************************************************************************/
414+
415+static PyObject *
416+newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
417+{
418+ arrayobject *op;
419+ size_t nbytes;
420+
421+ if (size < 0) {
422+ PyErr_BadInternalCall();
423+ return NULL;
424+ }
425+
426+ nbytes = size * descr->itemsize;
427+ /* Check for overflow */
428+ if (nbytes / descr->itemsize != (size_t)size) {
429+ return PyErr_NoMemory();
430+ }
431+ op = (arrayobject *) type->tp_alloc(type, 0);
432+ if (op == NULL) {
433+ return NULL;
434+ }
435+ op->ob_size = size;
436+ if (size <= 0) {
437+ op->ob_item = NULL;
438+ }
439+ else {
440+ op->ob_item = PyMem_NEW(char, nbytes);
441+ if (op->ob_item == NULL) {
442+ PyObject_Del(op);
443+ return PyErr_NoMemory();
444+ }
445+ }
446+ op->ob_descr = descr;
447+ op->allocated = size;
448+ op->weakreflist = NULL;
449+ return (PyObject *) op;
450+}
451+
452+static PyObject *
453+getarrayitem(PyObject *op, Py_ssize_t i)
454+{
455+ register arrayobject *ap;
456+ assert(array_Check(op));
457+ ap = (arrayobject *)op;
458+ assert(i>=0 && i<ap->ob_size);
459+ return (*ap->ob_descr->getitem)(ap, i);
460+}
461+
462+static int
463+ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
464+{
465+ char *items;
466+ Py_ssize_t n = self->ob_size;
467+ if (v == NULL) {
468+ PyErr_BadInternalCall();
469+ return -1;
470+ }
471+ if ((*self->ob_descr->setitem)(self, -1, v) < 0)
472+ return -1;
473+
474+ if (array_resize(self, n+1) == -1)
475+ return -1;
476+ items = self->ob_item;
477+ if (where < 0) {
478+ where += n;
479+ if (where < 0)
480+ where = 0;
481+ }
482+ if (where > n)
483+ where = n;
484+ /* appends don't need to call memmove() */
485+ if (where != n)
486+ memmove(items + (where+1)*self->ob_descr->itemsize,
487+ items + where*self->ob_descr->itemsize,
488+ (n-where)*self->ob_descr->itemsize);
489+ return (*self->ob_descr->setitem)(self, where, v);
490+}
491+
492+/* Methods */
493+
494+static void
495+array_dealloc(arrayobject *op)
496+{
497+ if (op->weakreflist != NULL)
498+ PyObject_ClearWeakRefs((PyObject *) op);
499+ if (op->ob_item != NULL)
500+ PyMem_DEL(op->ob_item);
501+ op->ob_type->tp_free((PyObject *)op);
502+}
503+
504+static PyObject *
505+array_richcompare(PyObject *v, PyObject *w, int op)
506+{
507+ arrayobject *va, *wa;
508+ PyObject *vi = NULL;
509+ PyObject *wi = NULL;
510+ Py_ssize_t i, k;
511+ PyObject *res;
512+
513+ if (!array_Check(v) || !array_Check(w)) {
514+ Py_INCREF(Py_NotImplemented);
515+ return Py_NotImplemented;
516+ }
517+
518+ va = (arrayobject *)v;
519+ wa = (arrayobject *)w;
520+
521+ if (va->ob_size != wa->ob_size && (op == Py_EQ || op == Py_NE)) {
522+ /* Shortcut: if the lengths differ, the arrays differ */
523+ if (op == Py_EQ)
524+ res = Py_False;
525+ else
526+ res = Py_True;
527+ Py_INCREF(res);
528+ return res;
529+ }
530+
531+ /* Search for the first index where items are different */
532+ k = 1;
533+ for (i = 0; i < va->ob_size && i < wa->ob_size; i++) {
534+ vi = getarrayitem(v, i);
535+ wi = getarrayitem(w, i);
536+ if (vi == NULL || wi == NULL) {
537+ Py_XDECREF(vi);
538+ Py_XDECREF(wi);
539+ return NULL;
540+ }
541+ k = PyObject_RichCompareBool(vi, wi, Py_EQ);
542+ if (k == 0)
543+ break; /* Keeping vi and wi alive! */
544+ Py_DECREF(vi);
545+ Py_DECREF(wi);
546+ if (k < 0)
547+ return NULL;
548+ }
549+
550+ if (k) {
551+ /* No more items to compare -- compare sizes */
552+ Py_ssize_t vs = va->ob_size;
553+ Py_ssize_t ws = wa->ob_size;
554+ int cmp;
555+ switch (op) {
556+ case Py_LT: cmp = vs < ws; break;
557+ case Py_LE: cmp = vs <= ws; break;
558+ case Py_EQ: cmp = vs == ws; break;
559+ case Py_NE: cmp = vs != ws; break;
560+ case Py_GT: cmp = vs > ws; break;
561+ case Py_GE: cmp = vs >= ws; break;
562+ default: return NULL; /* cannot happen */
563+ }
564+ if (cmp)
565+ res = Py_True;
566+ else
567+ res = Py_False;
568+ Py_INCREF(res);
569+ return res;
570+ }
571+
572+ /* We have an item that differs. First, shortcuts for EQ/NE */
573+ if (op == Py_EQ) {
574+ Py_INCREF(Py_False);
575+ res = Py_False;
576+ }
577+ else if (op == Py_NE) {
578+ Py_INCREF(Py_True);
579+ res = Py_True;
580+ }
581+ else {
582+ /* Compare the final item again using the proper operator */
583+ res = PyObject_RichCompare(vi, wi, op);
584+ }
585+ Py_DECREF(vi);
586+ Py_DECREF(wi);
587+ return res;
588+}
589+
590+static Py_ssize_t
591+array_length(arrayobject *a)
592+{
593+ return a->ob_size;
594+}
595+
596+static PyObject *
597+array_item(arrayobject *a, Py_ssize_t i)
598+{
599+ if (i < 0 || i >= a->ob_size) {
600+ PyErr_SetString(PyExc_IndexError, "array index out of range");
601+ return NULL;
602+ }
603+ return getarrayitem((PyObject *)a, i);
604+}
605+
606+static PyObject *
607+array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
608+{
609+ arrayobject *np;
610+ if (ilow < 0)
611+ ilow = 0;
612+ else if (ilow > a->ob_size)
613+ ilow = a->ob_size;
614+ if (ihigh < 0)
615+ ihigh = 0;
616+ if (ihigh < ilow)
617+ ihigh = ilow;
618+ else if (ihigh > a->ob_size)
619+ ihigh = a->ob_size;
620+ np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
621+ if (np == NULL)
622+ return NULL;
623+ memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
624+ (ihigh-ilow) * a->ob_descr->itemsize);
625+ return (PyObject *)np;
626+}
627+
628+static PyObject *
629+array_copy(arrayobject *a, PyObject *unused)
630+{
631+ return array_slice(a, 0, a->ob_size);
632+}
633+
634+PyDoc_STRVAR(copy_doc,
635+"copy(array)\n\
636+\n\
637+ Return a copy of the array.");
638+
639+static PyObject *
640+array_concat(arrayobject *a, PyObject *bb)
641+{
642+ Py_ssize_t size;
643+ arrayobject *np;
644+ if (!array_Check(bb)) {
645+ PyErr_Format(PyExc_TypeError,
646+ "can only append array (not \"%.200s\") to array",
647+ bb->ob_type->tp_name);
648+ return NULL;
649+ }
650+#define b ((arrayobject *)bb)
651+ if (a->ob_descr != b->ob_descr) {
652+ PyErr_BadArgument();
653+ return NULL;
654+ }
655+ size = a->ob_size + b->ob_size;
656+ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
657+ if (np == NULL) {
658+ return NULL;
659+ }
660+ memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
661+ memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
662+ b->ob_item, b->ob_size*b->ob_descr->itemsize);
663+ return (PyObject *)np;
664+#undef b
665+}
666+
667+static PyObject *
668+array_repeat(arrayobject *a, Py_ssize_t n)
669+{
670+ Py_ssize_t i;
671+ Py_ssize_t size;
672+ arrayobject *np;
673+ char *p;
674+ Py_ssize_t nbytes;
675+ if (n < 0)
676+ n = 0;
677+ size = a->ob_size * n;
678+ np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
679+ if (np == NULL)
680+ return NULL;
681+ p = np->ob_item;
682+ nbytes = a->ob_size * a->ob_descr->itemsize;
683+ for (i = 0; i < n; i++) {
684+ memcpy(p, a->ob_item, nbytes);
685+ p += nbytes;
686+ }
687+ return (PyObject *) np;
688+}
689+
690+static int
691+array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
692+{
693+ char *item;
694+ Py_ssize_t n; /* Size of replacement array */
695+ Py_ssize_t d; /* Change in size */
696+#define b ((arrayobject *)v)
697+ if (v == NULL)
698+ n = 0;
699+ else if (array_Check(v)) {
700+ n = b->ob_size;
701+ if (a == b) {
702+ /* Special case "a[i:j] = a" -- copy b first */
703+ int ret;
704+ v = array_slice(b, 0, n);
705+ if (!v)
706+ return -1;
707+ ret = array_ass_slice(a, ilow, ihigh, v);
708+ Py_DECREF(v);
709+ return ret;
710+ }
711+ if (b->ob_descr != a->ob_descr) {
712+ PyErr_BadArgument();
713+ return -1;
714+ }
715+ }
716+ else {
717+ PyErr_Format(PyExc_TypeError,
718+ "can only assign array (not \"%.200s\") to array slice",
719+ v->ob_type->tp_name);
720+ return -1;
721+ }
722+ if (ilow < 0)
723+ ilow = 0;
724+ else if (ilow > a->ob_size)
725+ ilow = a->ob_size;
726+ if (ihigh < 0)
727+ ihigh = 0;
728+ if (ihigh < ilow)
729+ ihigh = ilow;
730+ else if (ihigh > a->ob_size)
731+ ihigh = a->ob_size;
732+ item = a->ob_item;
733+ d = n - (ihigh-ilow);
734+ if (d < 0) { /* Delete -d items */
735+ memmove(item + (ihigh+d)*a->ob_descr->itemsize,
736+ item + ihigh*a->ob_descr->itemsize,
737+ (a->ob_size-ihigh)*a->ob_descr->itemsize);
738+ a->ob_size += d;
739+ PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
740+ /* Can't fail */
741+ a->ob_item = item;
742+ a->allocated = a->ob_size;
743+ }
744+ else if (d > 0) { /* Insert d items */
745+ PyMem_RESIZE(item, char,
746+ (a->ob_size + d)*a->ob_descr->itemsize);
747+ if (item == NULL) {
748+ PyErr_NoMemory();
749+ return -1;
750+ }
751+ memmove(item + (ihigh+d)*a->ob_descr->itemsize,
752+ item + ihigh*a->ob_descr->itemsize,
753+ (a->ob_size-ihigh)*a->ob_descr->itemsize);
754+ a->ob_item = item;
755+ a->ob_size += d;
756+ a->allocated = a->ob_size;
757+ }
758+ if (n > 0)
759+ memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
760+ n*b->ob_descr->itemsize);
761+ return 0;
762+#undef b
763+}
764+
765+static int
766+array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
767+{
768+ if (i < 0 || i >= a->ob_size) {
769+ PyErr_SetString(PyExc_IndexError,
770+ "array assignment index out of range");
771+ return -1;
772+ }
773+ if (v == NULL)
774+ return array_ass_slice(a, i, i+1, v);
775+ return (*a->ob_descr->setitem)(a, i, v);
776+}
777+
778+static int
779+setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
780+{
781+ assert(array_Check(a));
782+ return array_ass_item((arrayobject *)a, i, v);
783+}
784+
785+static int
786+array_iter_extend(arrayobject *self, PyObject *bb)
787+{
788+ PyObject *it, *v;
789+
790+ it = PyObject_GetIter(bb);
791+ if (it == NULL)
792+ return -1;
793+
794+ while ((v = PyIter_Next(it)) != NULL) {
795+ if (ins1(self, (int) self->ob_size, v) != 0) {
796+ Py_DECREF(v);
797+ Py_DECREF(it);
798+ return -1;
799+ }
800+ Py_DECREF(v);
801+ }
802+ Py_DECREF(it);
803+ if (PyErr_Occurred())
804+ return -1;
805+ return 0;
806+}
807+
808+static int
809+array_do_extend(arrayobject *self, PyObject *bb)
810+{
811+ Py_ssize_t size;
812+
813+ if (!array_Check(bb))
814+ return array_iter_extend(self, bb);
815+#define b ((arrayobject *)bb)
816+ if (self->ob_descr != b->ob_descr) {
817+ PyErr_SetString(PyExc_TypeError,
818+ "can only extend with array of same kind");
819+ return -1;
820+ }
821+ size = self->ob_size + b->ob_size;
822+ PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
823+ if (self->ob_item == NULL) {
824+ PyObject_Del(self);
825+ PyErr_NoMemory();
826+ return -1;
827+ }
828+ memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
829+ b->ob_item, b->ob_size*b->ob_descr->itemsize);
830+ self->ob_size = size;
831+ self->allocated = size;
832+
833+ return 0;
834+#undef b
835+}
836+
837+static PyObject *
838+array_inplace_concat(arrayobject *self, PyObject *bb)
839+{
840+ if (!array_Check(bb)) {
841+ PyErr_Format(PyExc_TypeError,
842+ "can only extend array with array (not \"%.200s\")",
843+ bb->ob_type->tp_name);
844+ return NULL;
845+ }
846+ if (array_do_extend(self, bb) == -1)
847+ return NULL;
848+ Py_INCREF(self);
849+ return (PyObject *)self;
850+}
851+
852+static PyObject *
853+array_inplace_repeat(arrayobject *self, Py_ssize_t n)
854+{
855+ char *items, *p;
856+ Py_ssize_t size, i;
857+
858+ if (self->ob_size > 0) {
859+ if (n < 0)
860+ n = 0;
861+ items = self->ob_item;
862+ size = self->ob_size * self->ob_descr->itemsize;
863+ if (n == 0) {
864+ PyMem_FREE(items);
865+ self->ob_item = NULL;
866+ self->ob_size = 0;
867+ self->allocated = 0;
868+ }
869+ else {
870+ PyMem_Resize(items, char, n * size);
871+ if (items == NULL)
872+ return PyErr_NoMemory();
873+ p = items;
874+ for (i = 1; i < n; i++) {
875+ p += size;
876+ memcpy(p, items, size);
877+ }
878+ self->ob_item = items;
879+ self->ob_size *= n;
880+ self->allocated = self->ob_size;
881+ }
882+ }
883+ Py_INCREF(self);
884+ return (PyObject *)self;
885+}
886+
887+
888+static PyObject *
889+ins(arrayobject *self, Py_ssize_t where, PyObject *v)
890+{
891+ if (ins1(self, where, v) != 0)
892+ return NULL;
893+ Py_INCREF(Py_None);
894+ return Py_None;
895+}
896+
897+static PyObject *
898+array_count(arrayobject *self, PyObject *v)
899+{
900+ Py_ssize_t count = 0;
901+ Py_ssize_t i;
902+
903+ for (i = 0; i < self->ob_size; i++) {
904+ PyObject *selfi = getarrayitem((PyObject *)self, i);
905+ int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
906+ Py_DECREF(selfi);
907+ if (cmp > 0)
908+ count++;
909+ else if (cmp < 0)
910+ return NULL;
911+ }
912+ return PyInt_FromSsize_t(count);
913+}
914+
915+PyDoc_STRVAR(count_doc,
916+"count(x)\n\
917+\n\
918+Return number of occurences of x in the array.");
919+
920+static PyObject *
921+array_index(arrayobject *self, PyObject *v)
922+{
923+ Py_ssize_t i;
924+
925+ for (i = 0; i < self->ob_size; i++) {
926+ PyObject *selfi = getarrayitem((PyObject *)self, i);
927+ int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
928+ Py_DECREF(selfi);
929+ if (cmp > 0) {
930+ return PyInt_FromLong((long)i);
931+ }
932+ else if (cmp < 0)
933+ return NULL;
934+ }
935+ PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
936+ return NULL;
937+}
938+
939+PyDoc_STRVAR(index_doc,
940+"index(x)\n\
941+\n\
942+Return index of first occurence of x in the array.");
943+
944+static int
945+array_contains(arrayobject *self, PyObject *v)
946+{
947+ Py_ssize_t i;
948+ int cmp;
949+
950+ for (i = 0, cmp = 0 ; cmp == 0 && i < self->ob_size; i++) {
951+ PyObject *selfi = getarrayitem((PyObject *)self, i);
952+ cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
953+ Py_DECREF(selfi);
954+ }
955+ return cmp;
956+}
957+
958+static PyObject *
959+array_remove(arrayobject *self, PyObject *v)
960+{
961+ int i;
962+
963+ for (i = 0; i < self->ob_size; i++) {
964+ PyObject *selfi = getarrayitem((PyObject *)self,i);
965+ int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
966+ Py_DECREF(selfi);
967+ if (cmp > 0) {
968+ if (array_ass_slice(self, i, i+1,
969+ (PyObject *)NULL) != 0)
970+ return NULL;
971+ Py_INCREF(Py_None);
972+ return Py_None;
973+ }
974+ else if (cmp < 0)
975+ return NULL;
976+ }
977+ PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
978+ return NULL;
979+}
980+
981+PyDoc_STRVAR(remove_doc,
982+"remove(x)\n\
983+\n\
984+Remove the first occurence of x in the array.");
985+
986+static PyObject *
987+array_pop(arrayobject *self, PyObject *args)
988+{
989+ Py_ssize_t i = -1;
990+ PyObject *v;
991+ if (!PyArg_ParseTuple(args, "|n:pop", &i))
992+ return NULL;
993+ if (self->ob_size == 0) {
994+ /* Special-case most common failure cause */
995+ PyErr_SetString(PyExc_IndexError, "pop from empty array");
996+ return NULL;
997+ }
998+ if (i < 0)
999+ i += self->ob_size;
1000+ if (i < 0 || i >= self->ob_size) {
1001+ PyErr_SetString(PyExc_IndexError, "pop index out of range");
1002+ return NULL;
1003+ }
1004+ v = getarrayitem((PyObject *)self,i);
1005+ if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
1006+ Py_DECREF(v);
1007+ return NULL;
1008+ }
1009+ return v;
1010+}
1011+
1012+PyDoc_STRVAR(pop_doc,
1013+"pop([i])\n\
1014+\n\
1015+Return the i-th element and delete it from the array. i defaults to -1.");
1016+
1017+static PyObject *
1018+array_extend(arrayobject *self, PyObject *bb)
1019+{
1020+ if (array_do_extend(self, bb) == -1)
1021+ return NULL;
1022+ Py_INCREF(Py_None);
1023+ return Py_None;
1024+}
1025+
1026+PyDoc_STRVAR(extend_doc,
1027+"extend(array or iterable)\n\
1028+\n\
1029+ Append items to the end of the array.");
1030+
1031+static PyObject *
1032+array_insert(arrayobject *self, PyObject *args)
1033+{
1034+ Py_ssize_t i;
1035+ PyObject *v;
1036+ if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
1037+ return NULL;
1038+ return ins(self, i, v);
1039+}
1040+
1041+PyDoc_STRVAR(insert_doc,
1042+"insert(i,x)\n\
1043+\n\
1044+Insert a new item x into the array before position i.");
1045+
1046+
1047+static PyObject *
1048+array_buffer_info(arrayobject *self, PyObject *unused)
1049+{
1050+ PyObject* retval = NULL;
1051+ retval = PyTuple_New(2);
1052+ if (!retval)
1053+ return NULL;
1054+
1055+ PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
1056+ PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));
1057+
1058+ return retval;
1059+}
1060+
1061+PyDoc_STRVAR(buffer_info_doc,
1062+"buffer_info() -> (address, length)\n\
1063+\n\
1064+Return a tuple (address, length) giving the current memory address and\n\
1065+the length in items of the buffer used to hold array's contents\n\
1066+The length should be multiplied by the itemsize attribute to calculate\n\
1067+the buffer length in bytes.");
1068+
1069+
1070+static PyObject *
1071+array_append(arrayobject *self, PyObject *v)
1072+{
1073+ return ins(self, (int) self->ob_size, v);
1074+}
1075+
1076+PyDoc_STRVAR(append_doc,
1077+"append(x)\n\
1078+\n\
1079+Append new value x to the end of the array.");
1080+
1081+
1082+static PyObject *
1083+array_byteswap(arrayobject *self, PyObject *unused)
1084+{
1085+ char *p;
1086+ Py_ssize_t i;
1087+
1088+ switch (self->ob_descr->itemsize) {
1089+ case 1:
1090+ break;
1091+ case 2:
1092+ for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
1093+ char p0 = p[0];
1094+ p[0] = p[1];
1095+ p[1] = p0;
1096+ }
1097+ break;
1098+ case 4:
1099+ for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 4) {
1100+ char p0 = p[0];
1101+ char p1 = p[1];
1102+ p[0] = p[3];
1103+ p[1] = p[2];
1104+ p[2] = p1;
1105+ p[3] = p0;
1106+ }
1107+ break;
1108+ case 8:
1109+ for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 8) {
1110+ char p0 = p[0];
1111+ char p1 = p[1];
1112+ char p2 = p[2];
1113+ char p3 = p[3];
1114+ p[0] = p[7];
1115+ p[1] = p[6];
1116+ p[2] = p[5];
1117+ p[3] = p[4];
1118+ p[4] = p3;
1119+ p[5] = p2;
1120+ p[6] = p1;
1121+ p[7] = p0;
1122+ }
1123+ break;
1124+ default:
1125+ PyErr_SetString(PyExc_RuntimeError,
1126+ "don't know how to byteswap this array type");
1127+ return NULL;
1128+ }
1129+ Py_INCREF(Py_None);
1130+ return Py_None;
1131+}
1132+
1133+PyDoc_STRVAR(byteswap_doc,
1134+"byteswap()\n\
1135+\n\
1136+Byteswap all items of the array. If the items in the array are not 1, 2,\n\
1137+4, or 8 bytes in size, RuntimeError is raised.");
1138+
1139+static PyObject *
1140+array_reduce(arrayobject *array)
1141+{
1142+ PyObject *dict, *result;
1143+
1144+ dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
1145+ if (dict == NULL) {
1146+ PyErr_Clear();
1147+ dict = Py_None;
1148+ Py_INCREF(dict);
1149+ }
1150+ if (array->ob_size > 0) {
1151+ result = Py_BuildValue("O(cs#)O",
1152+ array->ob_type,
1153+ array->ob_descr->typecode,
1154+ array->ob_item,
1155+ array->ob_size * array->ob_descr->itemsize,
1156+ dict);
1157+ } else {
1158+ result = Py_BuildValue("O(c)O",
1159+ array->ob_type,
1160+ array->ob_descr->typecode,
1161+ dict);
1162+ }
1163+ Py_DECREF(dict);
1164+ return result;
1165+}
1166+
1167+PyDoc_STRVAR(array_doc, "Return state information for pickling.");
1168+
1169+static PyObject *
1170+array_reverse(arrayobject *self, PyObject *unused)
1171+{
1172+ register Py_ssize_t itemsize = self->ob_descr->itemsize;
1173+ register char *p, *q;
1174+ /* little buffer to hold items while swapping */
1175+ char tmp[256]; /* 8 is probably enough -- but why skimp */
1176+ assert((size_t)itemsize <= sizeof(tmp));
1177+
1178+ if (self->ob_size > 1) {
1179+ for (p = self->ob_item,
1180+ q = self->ob_item + (self->ob_size - 1)*itemsize;
1181+ p < q;
1182+ p += itemsize, q -= itemsize) {
1183+ /* memory areas guaranteed disjoint, so memcpy
1184+ * is safe (& memmove may be slower).
1185+ */
1186+ memcpy(tmp, p, itemsize);
1187+ memcpy(p, q, itemsize);
1188+ memcpy(q, tmp, itemsize);
1189+ }
1190+ }
1191+
1192+ Py_INCREF(Py_None);
1193+ return Py_None;
1194+}
1195+
1196+PyDoc_STRVAR(reverse_doc,
1197+"reverse()\n\
1198+\n\
1199+Reverse the order of the items in the array.");
1200+
1201+static PyObject *
1202+array_fromfile(arrayobject *self, PyObject *args)
1203+{
1204+ PyObject *f;
1205+ Py_ssize_t n;
1206+ FILE *fp;
1207+ if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
1208+ return NULL;
1209+ fp = PyFile_AsFile(f);
1210+ if (fp == NULL) {
1211+ PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
1212+ return NULL;
1213+ }
1214+ if (n > 0) {
1215+ char *item = self->ob_item;
1216+ Py_ssize_t itemsize = self->ob_descr->itemsize;
1217+ size_t nread;
1218+ Py_ssize_t newlength;
1219+ size_t newbytes;
1220+ /* Be careful here about overflow */
1221+ if ((newlength = self->ob_size + n) <= 0 ||
1222+ (newbytes = newlength * itemsize) / itemsize !=
1223+ (size_t)newlength)
1224+ goto nomem;
1225+ PyMem_RESIZE(item, char, newbytes);
1226+ if (item == NULL) {
1227+ nomem:
1228+ PyErr_NoMemory();
1229+ return NULL;
1230+ }
1231+ self->ob_item = item;
1232+ self->ob_size += n;
1233+ self->allocated = self->ob_size;
1234+ nread = fread(item + (self->ob_size - n) * itemsize,
1235+ itemsize, n, fp);
1236+ if (nread < (size_t)n) {
1237+ self->ob_size -= (n - nread);
1238+ PyMem_RESIZE(item, char, self->ob_size*itemsize);
1239+ self->ob_item = item;
1240+ self->allocated = self->ob_size;
1241+ PyErr_SetString(PyExc_EOFError,
1242+ "not enough items in file");
1243+ return NULL;
1244+ }
1245+ }
1246+ Py_INCREF(Py_None);
1247+ return Py_None;
1248+}
1249+
1250+PyDoc_STRVAR(fromfile_doc,
1251+"fromfile(f, n)\n\
1252+\n\
1253+Read n objects from the file object f and append them to the end of the\n\
1254+array. Also called as read.");
1255+
1256+
1257+static PyObject *
1258+array_tofile(arrayobject *self, PyObject *f)
1259+{
1260+ FILE *fp;
1261+
1262+ fp = PyFile_AsFile(f);
1263+ if (fp == NULL) {
1264+ PyErr_SetString(PyExc_TypeError, "arg must be open file");
1265+ return NULL;
1266+ }
1267+ if (self->ob_size > 0) {
1268+ if (fwrite(self->ob_item, self->ob_descr->itemsize,
1269+ self->ob_size, fp) != (size_t)self->ob_size) {
1270+ PyErr_SetFromErrno(PyExc_IOError);
1271+ clearerr(fp);
1272+ return NULL;
1273+ }
1274+ }
1275+ Py_INCREF(Py_None);
1276+ return Py_None;
1277+}
1278+
1279+PyDoc_STRVAR(tofile_doc,
1280+"tofile(f)\n\
1281+\n\
1282+Write all items (as machine values) to the file object f. Also called as\n\
1283+write.");
1284+
1285+
1286+static PyObject *
1287+array_fromlist(arrayobject *self, PyObject *list)
1288+{
1289+ Py_ssize_t n;
1290+ Py_ssize_t itemsize = self->ob_descr->itemsize;
1291+
1292+ if (!PyList_Check(list)) {
1293+ PyErr_SetString(PyExc_TypeError, "arg must be list");
1294+ return NULL;
1295+ }
1296+ n = PyList_Size(list);
1297+ if (n > 0) {
1298+ char *item = self->ob_item;
1299+ Py_ssize_t i;
1300+ PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
1301+ if (item == NULL) {
1302+ PyErr_NoMemory();
1303+ return NULL;
1304+ }
1305+ self->ob_item = item;
1306+ self->ob_size += n;
1307+ self->allocated = self->ob_size;
1308+ for (i = 0; i < n; i++) {
1309+ PyObject *v = PyList_GetItem(list, i);
1310+ if ((*self->ob_descr->setitem)(self,
1311+ self->ob_size - n + i, v) != 0) {
1312+ self->ob_size -= n;
1313+ PyMem_RESIZE(item, char,
1314+ self->ob_size * itemsize);
1315+ self->ob_item = item;
1316+ self->allocated = self->ob_size;
1317+ return NULL;
1318+ }
1319+ }
1320+ }
1321+ Py_INCREF(Py_None);
1322+ return Py_None;
1323+}
1324+
1325+PyDoc_STRVAR(fromlist_doc,
1326+"fromlist(list)\n\
1327+\n\
1328+Append items to array from list.");
1329+
1330+
1331+static PyObject *
1332+array_tolist(arrayobject *self, PyObject *unused)
1333+{
1334+ PyObject *list = PyList_New(self->ob_size);
1335+ Py_ssize_t i;
1336+
1337+ if (list == NULL)
1338+ return NULL;
1339+ for (i = 0; i < self->ob_size; i++) {
1340+ PyObject *v = getarrayitem((PyObject *)self, i);
1341+ if (v == NULL) {
1342+ Py_DECREF(list);
1343+ return NULL;
1344+ }
1345+ PyList_SetItem(list, i, v);
1346+ }
1347+ return list;
1348+}
1349+
1350+PyDoc_STRVAR(tolist_doc,
1351+"tolist() -> list\n\
1352+\n\
1353+Convert array to an ordinary list with the same items.");
1354+
1355+
1356+static PyObject *
1357+array_fromstring(arrayobject *self, PyObject *args)
1358+{
1359+ char *str;
1360+ Py_ssize_t n;
1361+ int itemsize = self->ob_descr->itemsize;
1362+ if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n))
1363+ return NULL;
1364+ if (n % itemsize != 0) {
1365+ PyErr_SetString(PyExc_ValueError,
1366+ "string length not a multiple of item size");
1367+ return NULL;
1368+ }
1369+ n = n / itemsize;
1370+ if (n > 0) {
1371+ char *item = self->ob_item;
1372+ PyMem_RESIZE(item, char, (self->ob_size + n) * itemsize);
1373+ if (item == NULL) {
1374+ PyErr_NoMemory();
1375+ return NULL;
1376+ }
1377+ self->ob_item = item;
1378+ self->ob_size += n;
1379+ self->allocated = self->ob_size;
1380+ memcpy(item + (self->ob_size - n) * itemsize,
1381+ str, itemsize*n);
1382+ }
1383+ Py_INCREF(Py_None);
1384+ return Py_None;
1385+}
1386+
1387+PyDoc_STRVAR(fromstring_doc,
1388+"fromstring(string)\n\
1389+\n\
1390+Appends items from the string, interpreting it as an array of machine\n\
1391+values,as if it had been read from a file using the fromfile() method).");
1392+
1393+
1394+static PyObject *
1395+array_tostring(arrayobject *self, PyObject *unused)
1396+{
1397+ return PyString_FromStringAndSize(self->ob_item,
1398+ self->ob_size * self->ob_descr->itemsize);
1399+}
1400+
1401+PyDoc_STRVAR(tostring_doc,
1402+"tostring() -> string\n\
1403+\n\
1404+Convert the array to an array of machine values and return the string\n\
1405+representation.");
1406+
1407+
1408+
1409+#ifdef Py_USING_UNICODE
1410+static PyObject *
1411+array_fromunicode(arrayobject *self, PyObject *args)
1412+{
1413+ Py_UNICODE *ustr;
1414+ Py_ssize_t n;
1415+
1416+ if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
1417+ return NULL;
1418+ if (self->ob_descr->typecode != 'u') {
1419+ PyErr_SetString(PyExc_ValueError,
1420+ "fromunicode() may only be called on "
1421+ "type 'u' arrays");
1422+ return NULL;
1423+ }
1424+ if (n > 0) {
1425+ Py_UNICODE *item = (Py_UNICODE *) self->ob_item;
1426+ PyMem_RESIZE(item, Py_UNICODE, self->ob_size + n);
1427+ if (item == NULL) {
1428+ PyErr_NoMemory();
1429+ return NULL;
1430+ }
1431+ self->ob_item = (char *) item;
1432+ self->ob_size += n;
1433+ self->allocated = self->ob_size;
1434+ memcpy(item + self->ob_size - n,
1435+ ustr, n * sizeof(Py_UNICODE));
1436+ }
1437+
1438+ Py_INCREF(Py_None);
1439+ return Py_None;
1440+}
1441+
1442+PyDoc_STRVAR(fromunicode_doc,
1443+"fromunicode(ustr)\n\
1444+\n\
1445+Extends this array with data from the unicode string ustr.\n\
1446+The array must be a type 'u' array; otherwise a ValueError\n\
1447+is raised. Use array.fromstring(ustr.decode(...)) to\n\
1448+append Unicode data to an array of some other type.");
1449+
1450+
1451+static PyObject *
1452+array_tounicode(arrayobject *self, PyObject *unused)
1453+{
1454+ if (self->ob_descr->typecode != 'u') {
1455+ PyErr_SetString(PyExc_ValueError,
1456+ "tounicode() may only be called on type 'u' arrays");
1457+ return NULL;
1458+ }
1459+ return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, self->ob_size);
1460+}
1461+
1462+PyDoc_STRVAR(tounicode_doc,
1463+"tounicode() -> unicode\n\
1464+\n\
1465+Convert the array to a unicode string. The array must be\n\
1466+a type 'u' array; otherwise a ValueError is raised. Use\n\
1467+array.tostring().decode() to obtain a unicode string from\n\
1468+an array of some other type.");
1469+
1470+#endif /* Py_USING_UNICODE */
1471+
1472+
1473+static PyObject *
1474+array_get_typecode(arrayobject *a, void *closure)
1475+{
1476+ char tc = a->ob_descr->typecode;
1477+ return PyString_FromStringAndSize(&tc, 1);
1478+}
1479+
1480+static PyObject *
1481+array_get_itemsize(arrayobject *a, void *closure)
1482+{
1483+ return PyInt_FromLong((long)a->ob_descr->itemsize);
1484+}
1485+
1486+static PyGetSetDef array_getsets [] = {
1487+ {"typecode", (getter) array_get_typecode, NULL,
1488+ "the typecode character used to create the array"},
1489+ {"itemsize", (getter) array_get_itemsize, NULL,
1490+ "the size, in bytes, of one array item"},
1491+ {NULL}
1492+};
1493+
1494+PyMethodDef array_methods[] = {
1495+ {"append", (PyCFunction)array_append, METH_O,
1496+ append_doc},
1497+ {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,
1498+ buffer_info_doc},
1499+ {"byteswap", (PyCFunction)array_byteswap, METH_NOARGS,
1500+ byteswap_doc},
1501+ {"__copy__", (PyCFunction)array_copy, METH_NOARGS,
1502+ copy_doc},
1503+ {"count", (PyCFunction)array_count, METH_O,
1504+ count_doc},
1505+ {"__deepcopy__",(PyCFunction)array_copy, METH_O,
1506+ copy_doc},
1507+ {"extend", (PyCFunction)array_extend, METH_O,
1508+ extend_doc},
1509+ {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS,
1510+ fromfile_doc},
1511+ {"fromlist", (PyCFunction)array_fromlist, METH_O,
1512+ fromlist_doc},
1513+ {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS,
1514+ fromstring_doc},
1515+#ifdef Py_USING_UNICODE
1516+ {"fromunicode", (PyCFunction)array_fromunicode, METH_VARARGS,
1517+ fromunicode_doc},
1518+#endif
1519+ {"index", (PyCFunction)array_index, METH_O,
1520+ index_doc},
1521+ {"insert", (PyCFunction)array_insert, METH_VARARGS,
1522+ insert_doc},
1523+ {"pop", (PyCFunction)array_pop, METH_VARARGS,
1524+ pop_doc},
1525+ {"read", (PyCFunction)array_fromfile, METH_VARARGS,
1526+ fromfile_doc},
1527+ {"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
1528+ array_doc},
1529+ {"remove", (PyCFunction)array_remove, METH_O,
1530+ remove_doc},
1531+ {"reverse", (PyCFunction)array_reverse, METH_NOARGS,
1532+ reverse_doc},
1533+/* {"sort", (PyCFunction)array_sort, METH_VARARGS,
1534+ sort_doc},*/
1535+ {"tofile", (PyCFunction)array_tofile, METH_O,
1536+ tofile_doc},
1537+ {"tolist", (PyCFunction)array_tolist, METH_NOARGS,
1538+ tolist_doc},
1539+ {"tostring", (PyCFunction)array_tostring, METH_NOARGS,
1540+ tostring_doc},
1541+#ifdef Py_USING_UNICODE
1542+ {"tounicode", (PyCFunction)array_tounicode, METH_NOARGS,
1543+ tounicode_doc},
1544+#endif
1545+ {"write", (PyCFunction)array_tofile, METH_O,
1546+ tofile_doc},
1547+ {NULL, NULL} /* sentinel */
1548+};
1549+
1550+static PyObject *
1551+array_repr(arrayobject *a)
1552+{
1553+ char buf[256], typecode;
1554+ PyObject *s, *t, *v = NULL;
1555+ Py_ssize_t len;
1556+
1557+ len = a->ob_size;
1558+ typecode = a->ob_descr->typecode;
1559+ if (len == 0) {
1560+ PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
1561+ return PyString_FromString(buf);
1562+ }
1563+
1564+ if (typecode == 'c')
1565+ v = array_tostring(a, NULL);
1566+#ifdef Py_USING_UNICODE
1567+ else if (typecode == 'u')
1568+ v = array_tounicode(a, NULL);
1569+#endif
1570+ else
1571+ v = array_tolist(a, NULL);
1572+ t = PyObject_Repr(v);
1573+ Py_XDECREF(v);
1574+
1575+ PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode);
1576+ s = PyString_FromString(buf);
1577+ PyString_ConcatAndDel(&s, t);
1578+ PyString_ConcatAndDel(&s, PyString_FromString(")"));
1579+ return s;
1580+}
1581+
1582+static PyObject*
1583+array_subscr(arrayobject* self, PyObject* item)
1584+{
1585+ if (PyIndex_Check(item)) {
1586+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1587+ if (i==-1 && PyErr_Occurred()) {
1588+ return NULL;
1589+ }
1590+ if (i < 0)
1591+ i += self->ob_size;
1592+ return array_item(self, i);
1593+ }
1594+ else if (PySlice_Check(item)) {
1595+ Py_ssize_t start, stop, step, slicelength, cur, i;
1596+ PyObject* result;
1597+ arrayobject* ar;
1598+ int itemsize = self->ob_descr->itemsize;
1599+
1600+ if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
1601+ &start, &stop, &step, &slicelength) < 0) {
1602+ return NULL;
1603+ }
1604+
1605+ if (slicelength <= 0) {
1606+ return newarrayobject(&Arraytype, 0, self->ob_descr);
1607+ }
1608+ else {
1609+ result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
1610+ if (!result) return NULL;
1611+
1612+ ar = (arrayobject*)result;
1613+
1614+ for (cur = start, i = 0; i < slicelength;
1615+ cur += step, i++) {
1616+ memcpy(ar->ob_item + i*itemsize,
1617+ self->ob_item + cur*itemsize,
1618+ itemsize);
1619+ }
1620+
1621+ return result;
1622+ }
1623+ }
1624+ else {
1625+ PyErr_SetString(PyExc_TypeError,
1626+ "list indices must be integers");
1627+ return NULL;
1628+ }
1629+}
1630+
1631+static int
1632+array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
1633+{
1634+ if (PyIndex_Check(item)) {
1635+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1636+ if (i==-1 && PyErr_Occurred())
1637+ return -1;
1638+ if (i < 0)
1639+ i += self->ob_size;
1640+ return array_ass_item(self, i, value);
1641+ }
1642+ else if (PySlice_Check(item)) {
1643+ Py_ssize_t start, stop, step, slicelength;
1644+ int itemsize = self->ob_descr->itemsize;
1645+
1646+ if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
1647+ &start, &stop, &step, &slicelength) < 0) {
1648+ return -1;
1649+ }
1650+
1651+ /* treat A[slice(a,b)] = v _exactly_ like A[a:b] = v */
1652+ if (step == 1 && ((PySliceObject*)item)->step == Py_None)
1653+ return array_ass_slice(self, start, stop, value);
1654+
1655+ if (value == NULL) {
1656+ /* delete slice */
1657+ Py_ssize_t cur, i, extra;
1658+
1659+ if (slicelength <= 0)
1660+ return 0;
1661+
1662+ if (step < 0) {
1663+ stop = start + 1;
1664+ start = stop + step*(slicelength - 1) - 1;
1665+ step = -step;
1666+ }
1667+
1668+ for (cur = start, i = 0; i < slicelength - 1;
1669+ cur += step, i++) {
1670+ memmove(self->ob_item + (cur - i)*itemsize,
1671+ self->ob_item + (cur + 1)*itemsize,
1672+ (step - 1) * itemsize);
1673+ }
1674+ extra = self->ob_size - (cur + 1);
1675+ if (extra > 0) {
1676+ memmove(self->ob_item + (cur - i)*itemsize,
1677+ self->ob_item + (cur + 1)*itemsize,
1678+ extra*itemsize);
1679+ }
1680+
1681+ self->ob_size -= slicelength;
1682+ self->ob_item = (char *)PyMem_REALLOC(self->ob_item,
1683+ itemsize*self->ob_size);
1684+ self->allocated = self->ob_size;
1685+
1686+ return 0;
1687+ }
1688+ else {
1689+ /* assign slice */
1690+ Py_ssize_t cur, i;
1691+ arrayobject* av;
1692+
1693+ if (!array_Check(value)) {
1694+ PyErr_Format(PyExc_TypeError,
1695+ "must assign array (not \"%.200s\") to slice",
1696+ value->ob_type->tp_name);
1697+ return -1;
1698+ }
1699+
1700+ av = (arrayobject*)value;
1701+
1702+ if (av->ob_size != slicelength) {
1703+ PyErr_Format(PyExc_ValueError,
1704+ "attempt to assign array of size %ld to extended slice of size %ld",
1705+ /*XXX*/(long)av->ob_size, /*XXX*/(long)slicelength);
1706+ return -1;
1707+ }
1708+
1709+ if (!slicelength)
1710+ return 0;
1711+
1712+ /* protect against a[::-1] = a */
1713+ if (self == av) {
1714+ value = array_slice(av, 0, av->ob_size);
1715+ av = (arrayobject*)value;
1716+ if (!av)
1717+ return -1;
1718+ }
1719+ else {
1720+ Py_INCREF(value);
1721+ }
1722+
1723+ for (cur = start, i = 0; i < slicelength;
1724+ cur += step, i++) {
1725+ memcpy(self->ob_item + cur*itemsize,
1726+ av->ob_item + i*itemsize,
1727+ itemsize);
1728+ }
1729+
1730+ Py_DECREF(value);
1731+
1732+ return 0;
1733+ }
1734+ }
1735+ else {
1736+ PyErr_SetString(PyExc_TypeError,
1737+ "list indices must be integers");
1738+ return -1;
1739+ }
1740+}
1741+
1742+static PyMappingMethods array_as_mapping = {
1743+ (lenfunc)array_length,
1744+ (binaryfunc)array_subscr,
1745+ (objobjargproc)array_ass_subscr
1746+};
1747+
1748+static const void *emptybuf = "";
1749+
1750+static Py_ssize_t
1751+array_buffer_getreadbuf(arrayobject *self, Py_ssize_t index, const void **ptr)
1752+{
1753+ if ( index != 0 ) {
1754+ PyErr_SetString(PyExc_SystemError,
1755+ "Accessing non-existent array segment");
1756+ return -1;
1757+ }
1758+ *ptr = (void *)self->ob_item;
1759+ if (*ptr == NULL)
1760+ *ptr = emptybuf;
1761+ return self->ob_size*self->ob_descr->itemsize;
1762+}
1763+
1764+static Py_ssize_t
1765+array_buffer_getwritebuf(arrayobject *self, Py_ssize_t index, const void **ptr)
1766+{
1767+ if ( index != 0 ) {
1768+ PyErr_SetString(PyExc_SystemError,
1769+ "Accessing non-existent array segment");
1770+ return -1;
1771+ }
1772+ *ptr = (void *)self->ob_item;
1773+ if (*ptr == NULL)
1774+ *ptr = emptybuf;
1775+ return self->ob_size*self->ob_descr->itemsize;
1776+}
1777+
1778+static Py_ssize_t
1779+array_buffer_getsegcount(arrayobject *self, Py_ssize_t *lenp)
1780+{
1781+ if ( lenp )
1782+ *lenp = self->ob_size*self->ob_descr->itemsize;
1783+ return 1;
1784+}
1785+
1786+static PySequenceMethods array_as_sequence = {
1787+ (lenfunc)array_length, /*sq_length*/
1788+ (binaryfunc)array_concat, /*sq_concat*/
1789+ (ssizeargfunc)array_repeat, /*sq_repeat*/
1790+ (ssizeargfunc)array_item, /*sq_item*/
1791+ (ssizessizeargfunc)array_slice, /*sq_slice*/
1792+ (ssizeobjargproc)array_ass_item, /*sq_ass_item*/
1793+ (ssizessizeobjargproc)array_ass_slice, /*sq_ass_slice*/
1794+ (objobjproc)array_contains, /*sq_contains*/
1795+ (binaryfunc)array_inplace_concat, /*sq_inplace_concat*/
1796+ (ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/
1797+};
1798+
1799+static PyBufferProcs array_as_buffer = {
1800+ (readbufferproc)array_buffer_getreadbuf,
1801+ (writebufferproc)array_buffer_getwritebuf,
1802+ (segcountproc)array_buffer_getsegcount,
1803+ NULL,
1804+};
1805+
1806+static PyObject *
1807+array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1808+{
1809+ char c;
1810+ PyObject *initial = NULL, *it = NULL;
1811+ struct arraydescr *descr;
1812+
1813+ if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
1814+ return NULL;
1815+
1816+ if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
1817+ return NULL;
1818+
1819+ if (!(initial == NULL || PyList_Check(initial)
1820+ || PyString_Check(initial) || PyTuple_Check(initial)
1821+ || (c == 'u' && PyUnicode_Check(initial)))) {
1822+ it = PyObject_GetIter(initial);
1823+ if (it == NULL)
1824+ return NULL;
1825+ /* We set initial to NULL so that the subsequent code
1826+ will create an empty array of the appropriate type
1827+ and afterwards we can use array_iter_extend to populate
1828+ the array.
1829+ */
1830+ initial = NULL;
1831+ }
1832+ for (descr = descriptors; descr->typecode != '\0'; descr++) {
1833+ if (descr->typecode == c) {
1834+ PyObject *a;
1835+ Py_ssize_t len;
1836+
1837+ if (initial == NULL || !(PyList_Check(initial)
1838+ || PyTuple_Check(initial)))
1839+ len = 0;
1840+ else
1841+ len = PySequence_Size(initial);
1842+
1843+ a = newarrayobject(type, len, descr);
1844+ if (a == NULL)
1845+ return NULL;
1846+
1847+ if (len > 0) {
1848+ Py_ssize_t i;
1849+ for (i = 0; i < len; i++) {
1850+ PyObject *v =
1851+ PySequence_GetItem(initial, i);
1852+ if (v == NULL) {
1853+ Py_DECREF(a);
1854+ return NULL;
1855+ }
1856+ if (setarrayitem(a, i, v) != 0) {
1857+ Py_DECREF(v);
1858+ Py_DECREF(a);
1859+ return NULL;
1860+ }
1861+ Py_DECREF(v);
1862+ }
1863+ } else if (initial != NULL && PyString_Check(initial)) {
1864+ PyObject *t_initial, *v;
1865+ t_initial = PyTuple_Pack(1, initial);
1866+ if (t_initial == NULL) {
1867+ Py_DECREF(a);
1868+ return NULL;
1869+ }
1870+ v = array_fromstring((arrayobject *)a,
1871+ t_initial);
1872+ Py_DECREF(t_initial);
1873+ if (v == NULL) {
1874+ Py_DECREF(a);
1875+ return NULL;
1876+ }
1877+ Py_DECREF(v);
1878+#ifdef Py_USING_UNICODE
1879+ } else if (initial != NULL && PyUnicode_Check(initial)) {
1880+ Py_ssize_t n = PyUnicode_GET_DATA_SIZE(initial);
1881+ if (n > 0) {
1882+ arrayobject *self = (arrayobject *)a;
1883+ char *item = self->ob_item;
1884+ item = (char *)PyMem_Realloc(item, n);
1885+ if (item == NULL) {
1886+ PyErr_NoMemory();
1887+ Py_DECREF(a);
1888+ return NULL;
1889+ }
1890+ self->ob_item = item;
1891+ self->ob_size = n / sizeof(Py_UNICODE);
1892+ memcpy(item, PyUnicode_AS_DATA(initial), n);
1893+ self->allocated = self->ob_size;
1894+ }
1895+#endif
1896+ }
1897+ if (it != NULL) {
1898+ if (array_iter_extend((arrayobject *)a, it) == -1) {
1899+ Py_DECREF(it);
1900+ Py_DECREF(a);
1901+ return NULL;
1902+ }
1903+ Py_DECREF(it);
1904+ }
1905+ return a;
1906+ }
1907+ }
1908+ PyErr_SetString(PyExc_ValueError,
1909+ "bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)");
1910+ return NULL;
1911+}
1912+
1913+
1914+PyDoc_STRVAR(module_doc,
1915+"This module defines an object type which can efficiently represent\n\
1916+an array of basic values: characters, integers, floating point\n\
1917+numbers. Arrays are sequence types and behave very much like lists,\n\
1918+except that the type of objects stored in them is constrained. The\n\
1919+type is specified at object creation time by using a type code, which\n\
1920+is a single character. The following type codes are defined:\n\
1921+\n\
1922+ Type code C Type Minimum size in bytes \n\
1923+ 'c' character 1 \n\
1924+ 'b' signed integer 1 \n\
1925+ 'B' unsigned integer 1 \n\
1926+ 'u' Unicode character 2 \n\
1927+ 'h' signed integer 2 \n\
1928+ 'H' unsigned integer 2 \n\
1929+ 'i' signed integer 2 \n\
1930+ 'I' unsigned integer 2 \n\
1931+ 'l' signed integer 4 \n\
1932+ 'L' unsigned integer 4 \n\
1933+ 'f' floating point 4 \n\
1934+ 'd' floating point 8 \n\
1935+\n\
1936+The constructor is:\n\
1937+\n\
1938+array(typecode [, initializer]) -- create a new array\n\
1939+");
1940+
1941+PyDoc_STRVAR(arraytype_doc,
1942+"array(typecode [, initializer]) -> array\n\
1943+\n\
1944+Return a new array whose items are restricted by typecode, and\n\
1945+initialized from the optional initializer value, which must be a list,\n\
1946+string. or iterable over elements of the appropriate type.\n\
1947+\n\
1948+Arrays represent basic values and behave very much like lists, except\n\
1949+the type of objects stored in them is constrained.\n\
1950+\n\
1951+Methods:\n\
1952+\n\
1953+append() -- append a new item to the end of the array\n\
1954+buffer_info() -- return information giving the current memory info\n\
1955+byteswap() -- byteswap all the items of the array\n\
1956+count() -- return number of occurences of an object\n\
1957+extend() -- extend array by appending multiple elements from an iterable\n\
1958+fromfile() -- read items from a file object\n\
1959+fromlist() -- append items from the list\n\
1960+fromstring() -- append items from the string\n\
1961+index() -- return index of first occurence of an object\n\
1962+insert() -- insert a new item into the array at a provided position\n\
1963+pop() -- remove and return item (default last)\n\
1964+read() -- DEPRECATED, use fromfile()\n\
1965+remove() -- remove first occurence of an object\n\
1966+reverse() -- reverse the order of the items in the array\n\
1967+tofile() -- write all items to a file object\n\
1968+tolist() -- return the array converted to an ordinary list\n\
1969+tostring() -- return the array converted to a string\n\
1970+write() -- DEPRECATED, use tofile()\n\
1971+\n\
1972+Attributes:\n\
1973+\n\
1974+typecode -- the typecode character used to create the array\n\
1975+itemsize -- the length in bytes of one array item\n\
1976+");
1977+
1978+static PyObject *array_iter(arrayobject *ao);
1979+
1980+static PyTypeObject Arraytype = {
1981+ PyObject_HEAD_INIT(NULL)
1982+ 0,
1983+ "array.array",
1984+ sizeof(arrayobject),
1985+ 0,
1986+ (destructor)array_dealloc, /* tp_dealloc */
1987+ 0, /* tp_print */
1988+ 0, /* tp_getattr */
1989+ 0, /* tp_setattr */
1990+ 0, /* tp_compare */
1991+ (reprfunc)array_repr, /* tp_repr */
1992+ 0, /* tp_as_number*/
1993+ &array_as_sequence, /* tp_as_sequence*/
1994+ &array_as_mapping, /* tp_as_mapping*/
1995+ 0, /* tp_hash */
1996+ 0, /* tp_call */
1997+ 0, /* tp_str */
1998+ PyObject_GenericGetAttr, /* tp_getattro */
1999+ 0, /* tp_setattro */
2000+ &array_as_buffer, /* tp_as_buffer*/
2001+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
2002+ arraytype_doc, /* tp_doc */
2003+ 0, /* tp_traverse */
2004+ 0, /* tp_clear */
2005+ array_richcompare, /* tp_richcompare */
2006+ offsetof(arrayobject, weakreflist), /* tp_weaklistoffset */
2007+ (getiterfunc)array_iter, /* tp_iter */
2008+ 0, /* tp_iternext */
2009+ array_methods, /* tp_methods */
2010+ 0, /* tp_members */
2011+ array_getsets, /* tp_getset */
2012+ 0, /* tp_base */
2013+ 0, /* tp_dict */
2014+ 0, /* tp_descr_get */
2015+ 0, /* tp_descr_set */
2016+ 0, /* tp_dictoffset */
2017+ 0, /* tp_init */
2018+ PyType_GenericAlloc, /* tp_alloc */
2019+ array_new, /* tp_new */
2020+ PyObject_Del, /* tp_free */
2021+};
2022+
2023+
2024+/*********************** Array Iterator **************************/
2025+
2026+typedef struct {
2027+ PyObject_HEAD
2028+ Py_ssize_t index;
2029+ arrayobject *ao;
2030+ PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
2031+} arrayiterobject;
2032+
2033+static PyTypeObject PyArrayIter_Type;
2034+
2035+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
2036+
2037+static PyObject *
2038+array_iter(arrayobject *ao)
2039+{
2040+ arrayiterobject *it;
2041+
2042+ if (!array_Check(ao)) {
2043+ PyErr_BadInternalCall();
2044+ return NULL;
2045+ }
2046+
2047+ it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type);
2048+ if (it == NULL)
2049+ return NULL;
2050+
2051+ Py_INCREF(ao);
2052+ it->ao = ao;
2053+ it->index = 0;
2054+ it->getitem = ao->ob_descr->getitem;
2055+ PyObject_GC_Track(it);
2056+ return (PyObject *)it;
2057+}
2058+
2059+static PyObject *
2060+arrayiter_next(arrayiterobject *it)
2061+{
2062+ assert(PyArrayIter_Check(it));
2063+ if (it->index < it->ao->ob_size)
2064+ return (*it->getitem)(it->ao, it->index++);
2065+ return NULL;
2066+}
2067+
2068+static void
2069+arrayiter_dealloc(arrayiterobject *it)
2070+{
2071+ PyObject_GC_UnTrack(it);
2072+ Py_XDECREF(it->ao);
2073+ PyObject_GC_Del(it);
2074+}
2075+
2076+static int
2077+arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
2078+{
2079+ Py_VISIT(it->ao);
2080+ return 0;
2081+}
2082+
2083+static PyTypeObject PyArrayIter_Type = {
2084+ PyObject_HEAD_INIT(NULL)
2085+ 0, /* ob_size */
2086+ "arrayiterator", /* tp_name */
2087+ sizeof(arrayiterobject), /* tp_basicsize */
2088+ 0, /* tp_itemsize */
2089+ /* methods */
2090+ (destructor)arrayiter_dealloc, /* tp_dealloc */
2091+ 0, /* tp_print */
2092+ 0, /* tp_getattr */
2093+ 0, /* tp_setattr */
2094+ 0, /* tp_compare */
2095+ 0, /* tp_repr */
2096+ 0, /* tp_as_number */
2097+ 0, /* tp_as_sequence */
2098+ 0, /* tp_as_mapping */
2099+ 0, /* tp_hash */
2100+ 0, /* tp_call */
2101+ 0, /* tp_str */
2102+ PyObject_GenericGetAttr, /* tp_getattro */
2103+ 0, /* tp_setattro */
2104+ 0, /* tp_as_buffer */
2105+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
2106+ 0, /* tp_doc */
2107+ (traverseproc)arrayiter_traverse, /* tp_traverse */
2108+ 0, /* tp_clear */
2109+ 0, /* tp_richcompare */
2110+ 0, /* tp_weaklistoffset */
2111+ PyObject_SelfIter, /* tp_iter */
2112+ (iternextfunc)arrayiter_next, /* tp_iternext */
2113+ 0, /* tp_methods */
2114+};
2115+
2116+
2117+/*********************** Install Module **************************/
2118+
2119+/* No functions in array module. */
2120+static PyMethodDef a_methods[] = {
2121+ {NULL, NULL, 0, NULL} /* Sentinel */
2122+};
2123+
2124+
2125+PyMODINIT_FUNC
2126+initarray(void)
2127+{
2128+ PyObject *m;
2129+
2130+ Arraytype.ob_type = &PyType_Type;
2131+ PyArrayIter_Type.ob_type = &PyType_Type;
2132+ m = Py_InitModule3("array", a_methods, module_doc);
2133+ if (m == NULL)
2134+ return;
2135+
2136+ Py_INCREF((PyObject *)&Arraytype);
2137+ PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
2138+ Py_INCREF((PyObject *)&Arraytype);
2139+ PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
2140+ /* No need to check the error here, the caller will do that */
2141+}