1 /* Array object implementation */
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 */
10 #else /* !STDC_HEADERS */
11 #ifndef DONT_HAVE_SYS_TYPES_H
12 #include <sys/types.h> /* For size_t */
13 #endif /* DONT_HAVE_SYS_TYPES_H */
14 #endif /* !STDC_HEADERS */
16 struct arrayobject
; /* Forward */
18 /* All possible arraydescr values are defined in the vector "descriptors"
19 * below. That's defined later because the appropriate get and set
20 * functions aren't visible yet.
25 PyObject
* (*getitem
)(struct arrayobject
*, int);
26 int (*setitem
)(struct arrayobject
*, int, PyObject
*);
29 typedef struct arrayobject
{
32 struct arraydescr
*ob_descr
;
35 staticforward PyTypeObject Arraytype
;
37 #define is_arrayobject(op) ((op)->ob_type == &Arraytype)
39 /****************************************************************************
40 Get and Set functions for each type.
41 A Get function takes an arrayobject* and an integer index, returning the
42 array value at that index wrapped in an appropriate PyObject*.
43 A Set function takes an arrayobject, integer index, and PyObject*; sets
44 the array value at that index to the raw C data extracted from the PyObject*,
45 and returns 0 if successful, else nonzero on failure (PyObject* not of an
46 appropriate type or value).
47 Note that the basic Get and Set functions do NOT check that the index is
48 in bounds; that's the responsibility of the caller.
49 ****************************************************************************/
52 c_getitem(arrayobject
*ap
, int i
)
54 return PyString_FromStringAndSize(&((char *)ap
->ob_item
)[i
], 1);
58 c_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
61 if (!PyArg_Parse(v
, "c;array item must be char", &x
))
64 ((char *)ap
->ob_item
)[i
] = x
;
69 b_getitem(arrayobject
*ap
, int i
)
71 long x
= ((char *)ap
->ob_item
)[i
];
74 return PyInt_FromLong(x
);
78 b_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
81 /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
82 must use the next size up that is signed ('h') and manually do
83 the overflow checking */
84 if (!PyArg_Parse(v
, "h;array item must be integer", &x
))
87 PyErr_SetString(PyExc_OverflowError
,
88 "signed char is less than minimum");
92 PyErr_SetString(PyExc_OverflowError
,
93 "signed char is greater than maximum");
97 ((char *)ap
->ob_item
)[i
] = (char)x
;
102 BB_getitem(arrayobject
*ap
, int i
)
104 long x
= ((unsigned char *)ap
->ob_item
)[i
];
105 return PyInt_FromLong(x
);
109 BB_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
112 /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
113 if (!PyArg_Parse(v
, "b;array item must be integer", &x
))
116 ((char *)ap
->ob_item
)[i
] = x
;
121 h_getitem(arrayobject
*ap
, int i
)
123 return PyInt_FromLong((long) ((short *)ap
->ob_item
)[i
]);
127 h_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
130 /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
131 if (!PyArg_Parse(v
, "h;array item must be integer", &x
))
134 ((short *)ap
->ob_item
)[i
] = x
;
139 HH_getitem(arrayobject
*ap
, int i
)
141 return PyInt_FromLong((long) ((unsigned short *)ap
->ob_item
)[i
]);
145 HH_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
148 /* PyArg_Parse's 'h' formatter is for a signed short, therefore
149 must use the next size up and manually do the overflow checking */
150 if (!PyArg_Parse(v
, "i;array item must be integer", &x
))
153 PyErr_SetString(PyExc_OverflowError
,
154 "unsigned short is less than minimum");
157 else if (x
> USHRT_MAX
) {
158 PyErr_SetString(PyExc_OverflowError
,
159 "unsigned short is greater than maximum");
163 ((short *)ap
->ob_item
)[i
] = (short)x
;
168 i_getitem(arrayobject
*ap
, int i
)
170 return PyInt_FromLong((long) ((int *)ap
->ob_item
)[i
]);
174 i_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
177 /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
178 if (!PyArg_Parse(v
, "i;array item must be integer", &x
))
181 ((int *)ap
->ob_item
)[i
] = x
;
186 II_getitem(arrayobject
*ap
, int i
)
188 return PyLong_FromUnsignedLong(
189 (unsigned long) ((unsigned int *)ap
->ob_item
)[i
]);
193 II_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
196 if (PyLong_Check(v
)) {
197 x
= PyLong_AsUnsignedLong(v
);
198 if (x
== (unsigned long) -1 && PyErr_Occurred())
203 if (!PyArg_Parse(v
, "l;array item must be integer", &y
))
206 PyErr_SetString(PyExc_OverflowError
,
207 "unsigned int is less than minimum");
210 x
= (unsigned long)y
;
214 PyErr_SetString(PyExc_OverflowError
,
215 "unsigned int is greater than maximum");
220 ((unsigned int *)ap
->ob_item
)[i
] = (unsigned int)x
;
225 l_getitem(arrayobject
*ap
, int i
)
227 return PyInt_FromLong(((long *)ap
->ob_item
)[i
]);
231 l_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
234 if (!PyArg_Parse(v
, "l;array item must be integer", &x
))
237 ((long *)ap
->ob_item
)[i
] = x
;
242 LL_getitem(arrayobject
*ap
, int i
)
244 return PyLong_FromUnsignedLong(((unsigned long *)ap
->ob_item
)[i
]);
248 LL_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
251 if (PyLong_Check(v
)) {
252 x
= PyLong_AsUnsignedLong(v
);
253 if (x
== (unsigned long) -1 && PyErr_Occurred())
258 if (!PyArg_Parse(v
, "l;array item must be integer", &y
))
261 PyErr_SetString(PyExc_OverflowError
,
262 "unsigned long is less than minimum");
265 x
= (unsigned long)y
;
269 PyErr_SetString(PyExc_OverflowError
,
270 "unsigned long is greater than maximum");
275 ((unsigned long *)ap
->ob_item
)[i
] = x
;
280 f_getitem(arrayobject
*ap
, int i
)
282 return PyFloat_FromDouble((double) ((float *)ap
->ob_item
)[i
]);
286 f_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
289 if (!PyArg_Parse(v
, "f;array item must be float", &x
))
292 ((float *)ap
->ob_item
)[i
] = x
;
297 d_getitem(arrayobject
*ap
, int i
)
299 return PyFloat_FromDouble(((double *)ap
->ob_item
)[i
]);
303 d_setitem(arrayobject
*ap
, int i
, PyObject
*v
)
306 if (!PyArg_Parse(v
, "d;array item must be float", &x
))
309 ((double *)ap
->ob_item
)[i
] = x
;
313 /* Description of types */
314 static struct arraydescr descriptors
[] = {
315 {'c', sizeof(char), c_getitem
, c_setitem
},
316 {'b', sizeof(char), b_getitem
, b_setitem
},
317 {'B', sizeof(char), BB_getitem
, BB_setitem
},
318 {'h', sizeof(short), h_getitem
, h_setitem
},
319 {'H', sizeof(short), HH_getitem
, HH_setitem
},
320 {'i', sizeof(int), i_getitem
, i_setitem
},
321 {'I', sizeof(int), II_getitem
, II_setitem
},
322 {'l', sizeof(long), l_getitem
, l_setitem
},
323 {'L', sizeof(long), LL_getitem
, LL_setitem
},
324 {'f', sizeof(float), f_getitem
, f_setitem
},
325 {'d', sizeof(double), d_getitem
, d_setitem
},
326 {'\0', 0, 0, 0} /* Sentinel */
329 /****************************************************************************
330 Implementations of array object methods.
331 ****************************************************************************/
334 newarrayobject(int size
, struct arraydescr
*descr
)
339 PyErr_BadInternalCall();
342 nbytes
= size
* descr
->itemsize
;
343 /* Check for overflow */
344 if (nbytes
/ descr
->itemsize
!= (size_t)size
) {
345 return PyErr_NoMemory();
347 op
= PyObject_NewVar(arrayobject
, &Arraytype
, size
);
349 return PyErr_NoMemory();
355 op
->ob_item
= PyMem_NEW(char, nbytes
);
356 if (op
->ob_item
== NULL
) {
358 return PyErr_NoMemory();
361 op
->ob_descr
= descr
;
362 return (PyObject
*) op
;
366 getarrayitem(PyObject
*op
, int i
)
368 register arrayobject
*ap
;
369 assert(is_arrayobject(op
));
370 ap
= (arrayobject
*)op
;
371 if (i
< 0 || i
>= ap
->ob_size
) {
372 PyErr_SetString(PyExc_IndexError
, "array index out of range");
375 return (*ap
->ob_descr
->getitem
)(ap
, i
);
379 ins1(arrayobject
*self
, int where
, PyObject
*v
)
383 PyErr_BadInternalCall();
386 if ((*self
->ob_descr
->setitem
)(self
, -1, v
) < 0)
388 items
= self
->ob_item
;
389 PyMem_RESIZE(items
, char,
390 (self
->ob_size
+1) * self
->ob_descr
->itemsize
);
397 if (where
> self
->ob_size
)
398 where
= self
->ob_size
;
399 memmove(items
+ (where
+1)*self
->ob_descr
->itemsize
,
400 items
+ where
*self
->ob_descr
->itemsize
,
401 (self
->ob_size
-where
)*self
->ob_descr
->itemsize
);
402 self
->ob_item
= items
;
404 return (*self
->ob_descr
->setitem
)(self
, where
, v
);
410 array_dealloc(arrayobject
*op
)
412 if (op
->ob_item
!= NULL
)
413 PyMem_DEL(op
->ob_item
);
418 array_richcompare(PyObject
*v
, PyObject
*w
, int op
)
420 arrayobject
*va
, *wa
;
426 if (!is_arrayobject(v
) || !is_arrayobject(w
)) {
427 Py_INCREF(Py_NotImplemented
);
428 return Py_NotImplemented
;
431 va
= (arrayobject
*)v
;
432 wa
= (arrayobject
*)w
;
434 if (va
->ob_size
!= wa
->ob_size
&& (op
== Py_EQ
|| op
== Py_NE
)) {
435 /* Shortcut: if the lengths differ, the arrays differ */
444 /* Search for the first index where items are different */
446 for (i
= 0; i
< va
->ob_size
&& i
< wa
->ob_size
; i
++) {
447 vi
= getarrayitem(v
, i
);
448 wi
= getarrayitem(w
, i
);
449 if (vi
== NULL
|| wi
== NULL
) {
454 k
= PyObject_RichCompareBool(vi
, wi
, Py_EQ
);
456 break; /* Keeping vi and wi alive! */
464 /* No more items to compare -- compare sizes */
465 int vs
= va
->ob_size
;
466 int ws
= wa
->ob_size
;
469 case Py_LT
: cmp
= vs
< ws
; break;
470 case Py_LE
: cmp
= vs
<= ws
; break;
471 case Py_EQ
: cmp
= vs
== ws
; break;
472 case Py_NE
: cmp
= vs
!= ws
; break;
473 case Py_GT
: cmp
= vs
> ws
; break;
474 case Py_GE
: cmp
= vs
>= ws
; break;
475 default: return NULL
; /* cannot happen */
485 /* We have an item that differs. First, shortcuts for EQ/NE */
490 else if (op
== Py_NE
) {
495 /* Compare the final item again using the proper operator */
496 res
= PyObject_RichCompare(vi
, wi
, op
);
504 array_length(arrayobject
*a
)
510 array_item(arrayobject
*a
, int i
)
512 if (i
< 0 || i
>= a
->ob_size
) {
513 PyErr_SetString(PyExc_IndexError
, "array index out of range");
516 return getarrayitem((PyObject
*)a
, i
);
520 array_slice(arrayobject
*a
, int ilow
, int ihigh
)
525 else if (ilow
> a
->ob_size
)
531 else if (ihigh
> a
->ob_size
)
533 np
= (arrayobject
*) newarrayobject(ihigh
- ilow
, a
->ob_descr
);
536 memcpy(np
->ob_item
, a
->ob_item
+ ilow
* a
->ob_descr
->itemsize
,
537 (ihigh
-ilow
) * a
->ob_descr
->itemsize
);
538 return (PyObject
*)np
;
542 array_concat(arrayobject
*a
, PyObject
*bb
)
546 if (!is_arrayobject(bb
)) {
547 PyErr_Format(PyExc_TypeError
,
548 "can only append array (not \"%.200s\") to array",
549 bb
->ob_type
->tp_name
);
552 #define b ((arrayobject *)bb)
553 if (a
->ob_descr
!= b
->ob_descr
) {
557 size
= a
->ob_size
+ b
->ob_size
;
558 np
= (arrayobject
*) newarrayobject(size
, a
->ob_descr
);
562 memcpy(np
->ob_item
, a
->ob_item
, a
->ob_size
*a
->ob_descr
->itemsize
);
563 memcpy(np
->ob_item
+ a
->ob_size
*a
->ob_descr
->itemsize
,
564 b
->ob_item
, b
->ob_size
*b
->ob_descr
->itemsize
);
565 return (PyObject
*)np
;
570 array_repeat(arrayobject
*a
, int n
)
579 size
= a
->ob_size
* n
;
580 np
= (arrayobject
*) newarrayobject(size
, a
->ob_descr
);
584 nbytes
= a
->ob_size
* a
->ob_descr
->itemsize
;
585 for (i
= 0; i
< n
; i
++) {
586 memcpy(p
, a
->ob_item
, nbytes
);
589 return (PyObject
*) np
;
593 array_ass_slice(arrayobject
*a
, int ilow
, int ihigh
, PyObject
*v
)
596 int n
; /* Size of replacement array */
597 int d
; /* Change in size */
598 #define b ((arrayobject *)v)
601 else if (is_arrayobject(v
)) {
604 /* Special case "a[i:j] = a" -- copy b first */
606 v
= array_slice(b
, 0, n
);
607 ret
= array_ass_slice(a
, ilow
, ihigh
, v
);
611 if (b
->ob_descr
!= a
->ob_descr
) {
617 PyErr_Format(PyExc_TypeError
,
618 "can only assign array (not \"%.200s\") to array slice",
619 v
->ob_type
->tp_name
);
624 else if (ilow
> a
->ob_size
)
630 else if (ihigh
> a
->ob_size
)
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
);
639 PyMem_RESIZE(item
, char, a
->ob_size
*a
->ob_descr
->itemsize
);
643 else if (d
> 0) { /* Insert d items */
644 PyMem_RESIZE(item
, char,
645 (a
->ob_size
+ d
)*a
->ob_descr
->itemsize
);
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
);
657 memcpy(item
+ ilow
*a
->ob_descr
->itemsize
, b
->ob_item
,
658 n
*b
->ob_descr
->itemsize
);
664 array_ass_item(arrayobject
*a
, int i
, PyObject
*v
)
666 if (i
< 0 || i
>= a
->ob_size
) {
667 PyErr_SetString(PyExc_IndexError
,
668 "array assignment index out of range");
672 return array_ass_slice(a
, i
, i
+1, v
);
673 return (*a
->ob_descr
->setitem
)(a
, i
, v
);
677 setarrayitem(PyObject
*a
, int i
, PyObject
*v
)
679 assert(is_arrayobject(a
));
680 return array_ass_item((arrayobject
*)a
, i
, v
);
684 ins(arrayobject
*self
, int where
, PyObject
*v
)
686 if (ins1(self
, where
, v
) != 0)
693 array_count(arrayobject
*self
, PyObject
*args
)
699 if (!PyArg_ParseTuple(args
, "O:count", &v
))
701 for (i
= 0; i
< self
->ob_size
; i
++) {
702 PyObject
*selfi
= getarrayitem((PyObject
*)self
, i
);
703 int cmp
= PyObject_RichCompareBool(selfi
, v
, Py_EQ
);
710 return PyInt_FromLong((long)count
);
713 static char count_doc
[] =
716 Return number of occurences of x in the array.";
719 array_index(arrayobject
*self
, PyObject
*args
)
724 if (!PyArg_ParseTuple(args
, "O:index", &v
))
726 for (i
= 0; i
< self
->ob_size
; i
++) {
727 PyObject
*selfi
= getarrayitem((PyObject
*)self
, i
);
728 int cmp
= PyObject_RichCompareBool(selfi
, v
, Py_EQ
);
731 return PyInt_FromLong((long)i
);
736 PyErr_SetString(PyExc_ValueError
, "array.index(x): x not in list");
740 static char index_doc
[] =
743 Return index of first occurence of x in the array.";
746 array_remove(arrayobject
*self
, PyObject
*args
)
751 if (!PyArg_ParseTuple(args
, "O:remove", &v
))
753 for (i
= 0; i
< self
->ob_size
; i
++) {
754 PyObject
*selfi
= getarrayitem((PyObject
*)self
,i
);
755 int cmp
= PyObject_RichCompareBool(selfi
, v
, Py_EQ
);
758 if (array_ass_slice(self
, i
, i
+1,
759 (PyObject
*)NULL
) != 0)
767 PyErr_SetString(PyExc_ValueError
, "array.remove(x): x not in list");
771 static char remove_doc
[] =
774 Remove the first occurence of x in the array.";
777 array_pop(arrayobject
*self
, PyObject
*args
)
781 if (!PyArg_ParseTuple(args
, "|i:pop", &i
))
783 if (self
->ob_size
== 0) {
784 /* Special-case most common failure cause */
785 PyErr_SetString(PyExc_IndexError
, "pop from empty array");
790 if (i
< 0 || i
>= self
->ob_size
) {
791 PyErr_SetString(PyExc_IndexError
, "pop index out of range");
794 v
= getarrayitem((PyObject
*)self
,i
);
795 if (array_ass_slice(self
, i
, i
+1, (PyObject
*)NULL
) != 0) {
802 static char pop_doc
[] =
805 Return the i-th element and delete it from the array. i defaults to -1.";
808 array_extend(arrayobject
*self
, PyObject
*args
)
813 if (!PyArg_ParseTuple(args
, "O:extend", &bb
))
816 if (!is_arrayobject(bb
)) {
817 PyErr_Format(PyExc_TypeError
,
818 "can only extend array with array (not \"%.200s\")",
819 bb
->ob_type
->tp_name
);
822 #define b ((arrayobject *)bb)
823 if (self
->ob_descr
!= b
->ob_descr
) {
824 PyErr_SetString(PyExc_TypeError
,
825 "can only extend with array of same kind");
828 size
= self
->ob_size
+ b
->ob_size
;
829 PyMem_RESIZE(self
->ob_item
, char, size
*self
->ob_descr
->itemsize
);
830 if (self
->ob_item
== NULL
) {
832 return PyErr_NoMemory();
834 memcpy(self
->ob_item
+ self
->ob_size
*self
->ob_descr
->itemsize
,
835 b
->ob_item
, b
->ob_size
*b
->ob_descr
->itemsize
);
836 self
->ob_size
= size
;
842 static char extend_doc
[] =
845 Append array items to the end of the array.";
848 array_insert(arrayobject
*self
, PyObject
*args
)
852 if (!PyArg_ParseTuple(args
, "iO:insert", &i
, &v
))
854 return ins(self
, i
, v
);
857 static char insert_doc
[] =
860 Insert a new item x into the array before position i.";
864 array_buffer_info(arrayobject
*self
, PyObject
*args
)
866 PyObject
* retval
= NULL
;
867 if (!PyArg_ParseTuple(args
, ":buffer_info"))
869 retval
= PyTuple_New(2);
873 PyTuple_SET_ITEM(retval
, 0, PyLong_FromVoidPtr(self
->ob_item
));
874 PyTuple_SET_ITEM(retval
, 1, PyInt_FromLong((long)(self
->ob_size
)));
879 static char buffer_info_doc
[] =
880 "buffer_info() -> (address, length)\n\
882 Return a tuple (address, length) giving the current memory address and\n\
883 the length in items of the buffer used to hold array's contents\n\
884 The length should be multiplied by the itemsize attribute to calculate\n\
885 the buffer length in bytes.";
889 array_append(arrayobject
*self
, PyObject
*args
)
892 if (!PyArg_ParseTuple(args
, "O:append", &v
))
894 return ins(self
, (int) self
->ob_size
, v
);
897 static char append_doc
[] =
900 Append new value x to the end of the array.";
904 array_byteswap(arrayobject
*self
, PyObject
*args
)
909 if (!PyArg_ParseTuple(args
, ":byteswap"))
912 switch (self
->ob_descr
->itemsize
) {
916 for (p
= self
->ob_item
, i
= self
->ob_size
; --i
>= 0; p
+= 2) {
923 for (p
= self
->ob_item
, i
= self
->ob_size
; --i
>= 0; p
+= 4) {
933 for (p
= self
->ob_item
, i
= self
->ob_size
; --i
>= 0; p
+= 8) {
949 PyErr_SetString(PyExc_RuntimeError
,
950 "don't know how to byteswap this array type");
957 static char byteswap_doc
[] =
960 Byteswap all items of the array. If the items in the array are not 1, 2,\n\
961 4, or 8 bytes in size, RuntimeError is raised.";
964 array_reverse(arrayobject
*self
, PyObject
*args
)
966 register int itemsize
= self
->ob_descr
->itemsize
;
967 register char *p
, *q
;
968 /* little buffer to hold items while swapping */
969 char tmp
[256]; /* 8 is probably enough -- but why skimp */
970 assert(itemsize
<= sizeof(tmp
));
972 if (!PyArg_ParseTuple(args
, ":reverse"))
975 if (self
->ob_size
> 1) {
976 for (p
= self
->ob_item
,
977 q
= self
->ob_item
+ (self
->ob_size
- 1)*itemsize
;
979 p
+= itemsize
, q
-= itemsize
) {
980 /* memory areas guaranteed disjoint, so memcpy
981 * is safe (& memmove may be slower).
983 memcpy(tmp
, p
, itemsize
);
984 memcpy(p
, q
, itemsize
);
985 memcpy(q
, tmp
, itemsize
);
993 static char reverse_doc
[] =
996 Reverse the order of the items in the array.";
999 array_fromfile(arrayobject
*self
, PyObject
*args
)
1004 if (!PyArg_ParseTuple(args
, "Oi:fromfile", &f
, &n
))
1006 fp
= PyFile_AsFile(f
);
1008 PyErr_SetString(PyExc_TypeError
, "arg1 must be open file");
1012 char *item
= self
->ob_item
;
1013 int itemsize
= self
->ob_descr
->itemsize
;
1017 /* Be careful here about overflow */
1018 if ((newlength
= self
->ob_size
+ n
) <= 0 ||
1019 (newbytes
= newlength
* itemsize
) / itemsize
!=
1022 PyMem_RESIZE(item
, char, newbytes
);
1028 self
->ob_item
= item
;
1030 nread
= fread(item
+ (self
->ob_size
- n
) * itemsize
,
1032 if (nread
< (size_t)n
) {
1033 self
->ob_size
-= (n
- nread
);
1034 PyMem_RESIZE(item
, char, self
->ob_size
*itemsize
);
1035 self
->ob_item
= item
;
1036 PyErr_SetString(PyExc_EOFError
,
1037 "not enough items in file");
1045 static char fromfile_doc
[] =
1048 Read n objects from the file object f and append them to the end of the\n\
1049 array. Also called as read.";
1053 array_tofile(arrayobject
*self
, PyObject
*args
)
1057 if (!PyArg_ParseTuple(args
, "O:tofile", &f
))
1059 fp
= PyFile_AsFile(f
);
1061 PyErr_SetString(PyExc_TypeError
, "arg must be open file");
1064 if (self
->ob_size
> 0) {
1065 if (fwrite(self
->ob_item
, self
->ob_descr
->itemsize
,
1066 self
->ob_size
, fp
) != (size_t)self
->ob_size
) {
1067 PyErr_SetFromErrno(PyExc_IOError
);
1076 static char tofile_doc
[] =
1079 Write all items (as machine values) to the file object f. Also called as\n\
1084 array_fromlist(arrayobject
*self
, PyObject
*args
)
1088 int itemsize
= self
->ob_descr
->itemsize
;
1089 if (!PyArg_ParseTuple(args
, "O:fromlist", &list
))
1091 if (!PyList_Check(list
)) {
1092 PyErr_SetString(PyExc_TypeError
, "arg must be list");
1095 n
= PyList_Size(list
);
1097 char *item
= self
->ob_item
;
1099 PyMem_RESIZE(item
, char, (self
->ob_size
+ n
) * itemsize
);
1104 self
->ob_item
= item
;
1106 for (i
= 0; i
< n
; i
++) {
1107 PyObject
*v
= PyList_GetItem(list
, i
);
1108 if ((*self
->ob_descr
->setitem
)(self
,
1109 self
->ob_size
- n
+ i
, v
) != 0) {
1111 PyMem_RESIZE(item
, char,
1112 self
->ob_size
* itemsize
);
1113 self
->ob_item
= item
;
1122 static char fromlist_doc
[] =
1125 Append items to array from list.";
1129 array_tolist(arrayobject
*self
, PyObject
*args
)
1131 PyObject
*list
= PyList_New(self
->ob_size
);
1133 if (!PyArg_ParseTuple(args
, ":tolist"))
1137 for (i
= 0; i
< self
->ob_size
; i
++) {
1138 PyObject
*v
= getarrayitem((PyObject
*)self
, i
);
1143 PyList_SetItem(list
, i
, v
);
1148 static char tolist_doc
[] =
1149 "tolist() -> list\n\
1151 Convert array to an ordinary list with the same items.";
1155 array_fromstring(arrayobject
*self
, PyObject
*args
)
1159 int itemsize
= self
->ob_descr
->itemsize
;
1160 if (!PyArg_ParseTuple(args
, "s#:fromstring", &str
, &n
))
1162 if (n
% itemsize
!= 0) {
1163 PyErr_SetString(PyExc_ValueError
,
1164 "string length not a multiple of item size");
1169 char *item
= self
->ob_item
;
1170 PyMem_RESIZE(item
, char, (self
->ob_size
+ n
) * itemsize
);
1175 self
->ob_item
= item
;
1177 memcpy(item
+ (self
->ob_size
- n
) * itemsize
,
1184 static char fromstring_doc
[] =
1185 "fromstring(string)\n\
1187 Appends items from the string, interpreting it as an array of machine\n\
1188 values,as if it had been read from a file using the fromfile() method).";
1192 array_tostring(arrayobject
*self
, PyObject
*args
)
1194 if (!PyArg_ParseTuple(args
, ":tostring"))
1196 return PyString_FromStringAndSize(self
->ob_item
,
1197 self
->ob_size
* self
->ob_descr
->itemsize
);
1200 static char tostring_doc
[] =
1201 "tostring() -> string\n\
1203 Convert the array to an array of machine values and return the string\n\
1206 PyMethodDef array_methods
[] = {
1207 {"append", (PyCFunction
)array_append
, METH_VARARGS
,
1209 {"buffer_info", (PyCFunction
)array_buffer_info
, METH_VARARGS
,
1211 {"byteswap", (PyCFunction
)array_byteswap
, METH_VARARGS
,
1213 {"count", (PyCFunction
)array_count
, METH_VARARGS
,
1215 {"extend", (PyCFunction
)array_extend
, METH_VARARGS
,
1217 {"fromfile", (PyCFunction
)array_fromfile
, METH_VARARGS
,
1219 {"fromlist", (PyCFunction
)array_fromlist
, METH_VARARGS
,
1221 {"fromstring", (PyCFunction
)array_fromstring
, METH_VARARGS
,
1223 {"index", (PyCFunction
)array_index
, METH_VARARGS
,
1225 {"insert", (PyCFunction
)array_insert
, METH_VARARGS
,
1227 {"pop", (PyCFunction
)array_pop
, METH_VARARGS
,
1229 {"read", (PyCFunction
)array_fromfile
, METH_VARARGS
,
1231 {"remove", (PyCFunction
)array_remove
, METH_VARARGS
,
1233 {"reverse", (PyCFunction
)array_reverse
, METH_VARARGS
,
1235 /* {"sort", (PyCFunction)array_sort, METH_VARARGS,
1237 {"tofile", (PyCFunction
)array_tofile
, METH_VARARGS
,
1239 {"tolist", (PyCFunction
)array_tolist
, METH_VARARGS
,
1241 {"tostring", (PyCFunction
)array_tostring
, METH_VARARGS
,
1243 {"write", (PyCFunction
)array_tofile
, METH_VARARGS
,
1245 {NULL
, NULL
} /* sentinel */
1249 array_getattr(arrayobject
*a
, char *name
)
1251 if (strcmp(name
, "typecode") == 0) {
1252 char tc
= a
->ob_descr
->typecode
;
1253 return PyString_FromStringAndSize(&tc
, 1);
1255 if (strcmp(name
, "itemsize") == 0) {
1256 return PyInt_FromLong((long)a
->ob_descr
->itemsize
);
1258 if (strcmp(name
, "__members__") == 0) {
1259 PyObject
*list
= PyList_New(2);
1261 PyList_SetItem(list
, 0,
1262 PyString_FromString("typecode"));
1263 PyList_SetItem(list
, 1,
1264 PyString_FromString("itemsize"));
1265 if (PyErr_Occurred()) {
1272 return Py_FindMethod(array_methods
, (PyObject
*)a
, name
);
1276 array_print(arrayobject
*a
, FILE *fp
, int flags
)
1283 fprintf(fp
, "array('%c')", a
->ob_descr
->typecode
);
1286 if (a
->ob_descr
->typecode
== 'c') {
1287 PyObject
*t_empty
= PyTuple_New(0);
1288 fprintf(fp
, "array('c', ");
1289 v
= array_tostring(a
, t_empty
);
1291 ok
= PyObject_Print(v
, fp
, 0);
1296 fprintf(fp
, "array('%c', [", a
->ob_descr
->typecode
);
1297 for (i
= 0; i
< len
&& ok
== 0; i
++) {
1300 v
= (a
->ob_descr
->getitem
)(a
, i
);
1301 ok
= PyObject_Print(v
, fp
, 0);
1309 array_repr(arrayobject
*a
)
1312 PyObject
*s
, *t
, *comma
, *v
;
1316 sprintf(buf
, "array('%c')", a
->ob_descr
->typecode
);
1317 return PyString_FromString(buf
);
1319 if (a
->ob_descr
->typecode
== 'c') {
1320 PyObject
*t_empty
= PyTuple_New(0);
1321 sprintf(buf
, "array('c', ");
1322 s
= PyString_FromString(buf
);
1323 v
= array_tostring(a
, t_empty
);
1325 t
= PyObject_Repr(v
);
1327 PyString_ConcatAndDel(&s
, t
);
1328 PyString_ConcatAndDel(&s
, PyString_FromString(")"));
1331 sprintf(buf
, "array('%c', [", a
->ob_descr
->typecode
);
1332 s
= PyString_FromString(buf
);
1333 comma
= PyString_FromString(", ");
1334 for (i
= 0; i
< len
&& !PyErr_Occurred(); i
++) {
1336 PyString_Concat(&s
, comma
);
1337 v
= (a
->ob_descr
->getitem
)(a
, i
);
1338 t
= PyObject_Repr(v
);
1340 PyString_ConcatAndDel(&s
, t
);
1343 PyString_ConcatAndDel(&s
, PyString_FromString("])"));
1348 array_buffer_getreadbuf(arrayobject
*self
, int index
, const void **ptr
)
1351 PyErr_SetString(PyExc_SystemError
,
1352 "Accessing non-existent array segment");
1355 *ptr
= (void *)self
->ob_item
;
1356 return self
->ob_size
*self
->ob_descr
->itemsize
;
1360 array_buffer_getwritebuf(arrayobject
*self
, int index
, const void **ptr
)
1363 PyErr_SetString(PyExc_SystemError
,
1364 "Accessing non-existent array segment");
1367 *ptr
= (void *)self
->ob_item
;
1368 return self
->ob_size
*self
->ob_descr
->itemsize
;
1372 array_buffer_getsegcount(arrayobject
*self
, int *lenp
)
1375 *lenp
= self
->ob_size
*self
->ob_descr
->itemsize
;
1379 static PySequenceMethods array_as_sequence
= {
1380 (inquiry
)array_length
, /*sq_length*/
1381 (binaryfunc
)array_concat
, /*sq_concat*/
1382 (intargfunc
)array_repeat
, /*sq_repeat*/
1383 (intargfunc
)array_item
, /*sq_item*/
1384 (intintargfunc
)array_slice
, /*sq_slice*/
1385 (intobjargproc
)array_ass_item
, /*sq_ass_item*/
1386 (intintobjargproc
)array_ass_slice
, /*sq_ass_slice*/
1389 static PyBufferProcs array_as_buffer
= {
1390 (getreadbufferproc
)array_buffer_getreadbuf
,
1391 (getwritebufferproc
)array_buffer_getwritebuf
,
1392 (getsegcountproc
)array_buffer_getsegcount
,
1396 a_array(PyObject
*self
, PyObject
*args
)
1399 PyObject
*initial
= NULL
;
1400 struct arraydescr
*descr
;
1401 if (!PyArg_ParseTuple(args
, "c:array", &c
)) {
1403 if (!PyArg_ParseTuple(args
, "cO:array", &c
, &initial
))
1405 if (!PyList_Check(initial
) && !PyString_Check(initial
)) {
1406 PyErr_SetString(PyExc_TypeError
,
1407 "array initializer must be list or string");
1411 for (descr
= descriptors
; descr
->typecode
!= '\0'; descr
++) {
1412 if (descr
->typecode
== c
) {
1415 if (initial
== NULL
|| !PyList_Check(initial
))
1418 len
= PyList_Size(initial
);
1419 a
= newarrayobject(len
, descr
);
1424 for (i
= 0; i
< len
; i
++) {
1426 PyList_GetItem(initial
, i
);
1427 if (setarrayitem(a
, i
, v
) != 0) {
1433 if (initial
!= NULL
&& PyString_Check(initial
)) {
1434 PyObject
*t_initial
= Py_BuildValue("(O)",
1437 array_fromstring((arrayobject
*)a
,
1439 Py_DECREF(t_initial
);
1449 PyErr_SetString(PyExc_ValueError
,
1450 "bad typecode (must be c, b, B, h, H, i, I, l, L, f or d)");
1454 static char a_array_doc
[] =
1455 "array(typecode [, initializer]) -> array\n\
1457 Return a new array whose items are restricted by typecode, and\n\
1458 initialized from the optional initializer value, which must be a list\n\
1461 static PyMethodDef a_methods
[] = {
1462 {"array", a_array
, METH_VARARGS
, a_array_doc
},
1463 {NULL
, NULL
} /* sentinel */
1466 static char module_doc
[] =
1467 "This module defines a new object type which can efficiently represent\n\
1468 an array of basic values: characters, integers, floating point\n\
1469 numbers. Arrays are sequence types and behave very much like lists,\n\
1470 except that the type of objects stored in them is constrained. The\n\
1471 type is specified at object creation time by using a type code, which\n\
1472 is a single character. The following type codes are defined:\n\
1474 Type code C Type Minimum size in bytes \n\
1476 'b' signed integer 1 \n\
1477 'B' unsigned integer 1 \n\
1478 'h' signed integer 2 \n\
1479 'H' unsigned integer 2 \n\
1480 'i' signed integer 2 \n\
1481 'I' unsigned integer 2 \n\
1482 'l' signed integer 4 \n\
1483 'L' unsigned integer 4 \n\
1484 'f' floating point 4 \n\
1485 'd' floating point 8 \n\
1489 array(typecode [, initializer]) -- create a new array\n\
1493 ArrayType -- type object for array objects\n\
1496 static char arraytype_doc
[] =
1497 "An array represents basic values and behave very much like lists, except\n\
1498 the type of objects stored in them is constrained.\n\
1502 append() -- append a new item to the end of the array\n\
1503 buffer_info() -- return information giving the current memory info\n\
1504 byteswap() -- byteswap all the items of the array\n\
1505 count() -- return number of occurences of an object\n\
1506 extend() -- extend array by appending array elements\n\
1507 fromfile() -- read items from a file object\n\
1508 fromlist() -- append items from the list\n\
1509 fromstring() -- append items from the string\n\
1510 index() -- return index of first occurence of an object\n\
1511 insert() -- insert a new item into the array at a provided position\n\
1512 pop() -- remove and return item (default last)\n\
1513 read() -- DEPRECATED, use fromfile()\n\
1514 remove() -- remove first occurence of an object\n\
1515 reverse() -- reverse the order of the items in the array\n\
1516 tofile() -- write all items to a file object\n\
1517 tolist() -- return the array converted to an ordinary list\n\
1518 tostring() -- return the array converted to a string\n\
1519 write() -- DEPRECATED, use tofile()\n\
1523 typecode -- the typecode character used to create the array\n\
1524 itemsize -- the length in bytes of one array item\n\
1527 statichere PyTypeObject Arraytype
= {
1528 PyObject_HEAD_INIT(NULL
)
1531 sizeof(arrayobject
),
1533 (destructor
)array_dealloc
, /* tp_dealloc */
1534 (printfunc
)array_print
, /* tp_print */
1535 (getattrfunc
)array_getattr
, /* tp_getattr */
1538 (reprfunc
)array_repr
, /* tp_repr */
1539 0, /* tp_as _number*/
1540 &array_as_sequence
, /* tp_as _sequence*/
1541 0, /* tp_as _mapping*/
1545 0, /* tp_getattro */
1546 0, /* tp_setattro */
1547 &array_as_buffer
, /* tp_as_buffer*/
1548 Py_TPFLAGS_DEFAULT
, /* tp_flags */
1549 arraytype_doc
, /* tp_doc */
1550 0, /* tp_traverse */
1552 array_richcompare
, /* tp_richcompare */
1560 Arraytype
.ob_type
= &PyType_Type
;
1561 m
= Py_InitModule3("array", a_methods
, module_doc
);
1562 d
= PyModule_GetDict(m
);
1563 PyDict_SetItemString(d
, "ArrayType", (PyObject
*)&Arraytype
);
1564 /* No need to check the error here, the caller will do that */