/* Array object implementation */

/* An array is a uniform list -- all items have the same type.
   The item type is restricted to simple C types like int or float */

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"

#ifdef STDC_HEADERS
#include <stddef.h>
#else /* !STDC_HEADERS */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>		/* For size_t */
#endif /* HAVE_SYS_TYPES_H */
#endif /* !STDC_HEADERS */

struct arrayobject; /* Forward */

/* All possible arraydescr values are defined in the vector "descriptors"
 * below.  That's defined later because the appropriate get and set
 * functions aren't visible yet.
 */
struct arraydescr {
	int typecode;
	int itemsize;
	PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
	int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
        char *formats;
};

typedef struct arrayobject {
	PyObject_VAR_HEAD
	char *ob_item;
	Py_ssize_t allocated;
	struct arraydescr *ob_descr;
	PyObject *weakreflist; /* List of weak references */
        int ob_exports;  /* Number of exported buffers */
} arrayobject;

static PyTypeObject Arraytype;

#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
#define array_CheckExact(op) (Py_TYPE(op) == &Arraytype)

static int
array_resize(arrayobject *self, Py_ssize_t newsize)
{
	char *items;
	size_t _new_size;

	if (self->ob_exports > 0 && newsize != Py_SIZE(self)) {
		PyErr_SetString(PyExc_BufferError, 
			"cannot resize an array that is exporting buffers");
		return -1;
	}

	/* Bypass realloc() when a previous overallocation is large enough
	   to accommodate the newsize.  If the newsize is 16 smaller than the
	   current size, then proceed with the realloc() to shrink the array.
	*/

	if (self->allocated >= newsize &&
	    Py_SIZE(self) < newsize + 16 &&
	    self->ob_item != NULL) {
		Py_SIZE(self) = newsize;
		return 0;
	}

	if (newsize == 0) {
		PyMem_FREE(self->ob_item);
		self->ob_item = NULL;
		Py_SIZE(self) = 0;
		self->allocated = 0;
		return 0;
	}

	/* This over-allocates proportional to the array size, making room
	 * for additional growth.  The over-allocation is mild, but is
	 * enough to give linear-time amortized behavior over a long
	 * sequence of appends() in the presence of a poorly-performing
	 * system realloc().
	 * The growth pattern is:  0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
	 * Note, the pattern starts out the same as for lists but then
	 * grows at a smaller rate so that larger arrays only overallocate
	 * by about 1/16th -- this is done because arrays are presumed to be more
	 * memory critical.
	 */

	_new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
	items = self->ob_item;
	/* XXX The following multiplication and division does not optimize away 
	   like it does for lists since the size is not known at compile time */
	if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
		PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
	else
		items = NULL;
	if (items == NULL) {
		PyErr_NoMemory();
		return -1;
	}
	self->ob_item = items;
	Py_SIZE(self) = newsize;
	self->allocated = _new_size;
	return 0;
}

/****************************************************************************
Get and Set functions for each type.
A Get function takes an arrayobject* and an integer index, returning the
array value at that index wrapped in an appropriate PyObject*.
A Set function takes an arrayobject, integer index, and PyObject*; sets
the array value at that index to the raw C data extracted from the PyObject*,
and returns 0 if successful, else nonzero on failure (PyObject* not of an
appropriate type or value).
Note that the basic Get and Set functions do NOT check that the index is
in bounds; that's the responsibility of the caller.
****************************************************************************/

static PyObject *
b_getitem(arrayobject *ap, Py_ssize_t i)
{
	long x = ((char *)ap->ob_item)[i];
	if (x >= 128)
		x -= 256;
	return PyLong_FromLong(x);
}

static int
b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	short x;
	/* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
	   must use the next size up that is signed ('h') and manually do
	   the overflow checking */
	if (!PyArg_Parse(v, "h;array item must be integer", &x))
		return -1;
	else if (x < -128) {
		PyErr_SetString(PyExc_OverflowError,
			"signed char is less than minimum");
		return -1;
	}
	else if (x > 127) {
		PyErr_SetString(PyExc_OverflowError,
			"signed char is greater than maximum");
		return -1;
	}
	if (i >= 0)
		((char *)ap->ob_item)[i] = (char)x;
	return 0;
}

static PyObject *
BB_getitem(arrayobject *ap, Py_ssize_t i)
{
	long x = ((unsigned char *)ap->ob_item)[i];
	return PyLong_FromLong(x);
}

static int
BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	unsigned char x;
	/* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
	if (!PyArg_Parse(v, "b;array item must be integer", &x))
		return -1;
	if (i >= 0)
		((char *)ap->ob_item)[i] = x;
	return 0;
}

static PyObject *
u_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
}

static int
u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	Py_UNICODE *p;
	Py_ssize_t len;

	if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
		return -1;
	if (len != 1) {
		PyErr_SetString(PyExc_TypeError,
				"array item must be unicode character");
		return -1;
	}
	if (i >= 0)
		((Py_UNICODE *)ap->ob_item)[i] = p[0];
	return 0;
}


static PyObject *
h_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyLong_FromLong((long) ((short *)ap->ob_item)[i]);
}


static int
h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	short x;
	/* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
	if (!PyArg_Parse(v, "h;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((short *)ap->ob_item)[i] = x;
	return 0;
}

static PyObject *
HH_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
}

static int
HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	int x;
	/* PyArg_Parse's 'h' formatter is for a signed short, therefore
	   must use the next size up and manually do the overflow checking */
	if (!PyArg_Parse(v, "i;array item must be integer", &x))
		return -1;
	else if (x < 0) {
		PyErr_SetString(PyExc_OverflowError,
			"unsigned short is less than minimum");
		return -1;
	}
	else if (x > USHRT_MAX) {
		PyErr_SetString(PyExc_OverflowError,
			"unsigned short is greater than maximum");
		return -1;
	}
	if (i >= 0)
		((short *)ap->ob_item)[i] = (short)x;
	return 0;
}

static PyObject *
i_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyLong_FromLong((long) ((int *)ap->ob_item)[i]);
}

static int
i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	int x;
	/* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
	if (!PyArg_Parse(v, "i;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((int *)ap->ob_item)[i] = x;
	return 0;
}

static PyObject *
II_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyLong_FromUnsignedLong(
		(unsigned long) ((unsigned int *)ap->ob_item)[i]);
}

static int
II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	unsigned long x;
	if (PyLong_Check(v)) {
		x = PyLong_AsUnsignedLong(v);
		if (x == (unsigned long) -1 && PyErr_Occurred())
			return -1;
	}
	else {
		long y;
		if (!PyArg_Parse(v, "l;array item must be integer", &y))
			return -1;
		if (y < 0) {
			PyErr_SetString(PyExc_OverflowError,
				"unsigned int is less than minimum");
			return -1;
		}
		x = (unsigned long)y;

	}
	if (x > UINT_MAX) {
		PyErr_SetString(PyExc_OverflowError,
			"unsigned int is greater than maximum");
		return -1;
	}

	if (i >= 0)
		((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
	return 0;
}

static PyObject *
l_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyLong_FromLong(((long *)ap->ob_item)[i]);
}

static int
l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	long x;
	if (!PyArg_Parse(v, "l;array item must be integer", &x))
		return -1;
	if (i >= 0)
		     ((long *)ap->ob_item)[i] = x;
	return 0;
}

static PyObject *
LL_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
}

static int
LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	unsigned long x;
	if (PyLong_Check(v)) {
		x = PyLong_AsUnsignedLong(v);
		if (x == (unsigned long) -1 && PyErr_Occurred())
			return -1;
	}
	else {
		long y;
		if (!PyArg_Parse(v, "l;array item must be integer", &y))
			return -1;
		if (y < 0) {
			PyErr_SetString(PyExc_OverflowError,
				"unsigned long is less than minimum");
			return -1;
		}
		x = (unsigned long)y;

	}
	if (x > ULONG_MAX) {
		PyErr_SetString(PyExc_OverflowError,
			"unsigned long is greater than maximum");
		return -1;
	}

	if (i >= 0)
		((unsigned long *)ap->ob_item)[i] = x;
	return 0;
}

static PyObject *
f_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
}

static int
f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	float x;
	if (!PyArg_Parse(v, "f;array item must be float", &x))
		return -1;
	if (i >= 0)
		     ((float *)ap->ob_item)[i] = x;
	return 0;
}

static PyObject *
d_getitem(arrayobject *ap, Py_ssize_t i)
{
	return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
}

static int
d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
{
	double x;
	if (!PyArg_Parse(v, "d;array item must be float", &x))
		return -1;
	if (i >= 0)
		     ((double *)ap->ob_item)[i] = x;
	return 0;
}


/* Description of types */
static struct arraydescr descriptors[] = {
	{'b', 1, b_getitem, b_setitem, "b"},
	{'B', 1, BB_getitem, BB_setitem, "B"},
	{'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u"},
	{'h', sizeof(short), h_getitem, h_setitem, "h"},
	{'H', sizeof(short), HH_getitem, HH_setitem, "H"},
	{'i', sizeof(int), i_getitem, i_setitem, "i"},
	{'I', sizeof(int), II_getitem, II_setitem, "I"},
	{'l', sizeof(long), l_getitem, l_setitem, "l"},
	{'L', sizeof(long), LL_getitem, LL_setitem, "L"},
	{'f', sizeof(float), f_getitem, f_setitem, "f"},
	{'d', sizeof(double), d_getitem, d_setitem, "d"},
	{'\0', 0, 0, 0, 0} /* Sentinel */
};

/****************************************************************************
Implementations of array object methods.
****************************************************************************/

static PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
{
	arrayobject *op;
	size_t nbytes;

	if (size < 0) {
		PyErr_BadInternalCall();
		return NULL;
	}

	nbytes = size * descr->itemsize;
	/* Check for overflow */
	if (nbytes / descr->itemsize != (size_t)size) {
		return PyErr_NoMemory();
	}
	op = (arrayobject *) type->tp_alloc(type, 0);
	if (op == NULL) {
		return NULL;
	}
	op->ob_descr = descr;
	op->allocated = size;
	op->weakreflist = NULL;
	Py_SIZE(op) = size;
	if (size <= 0) {
		op->ob_item = NULL;
	}
	else {
		op->ob_item = PyMem_NEW(char, nbytes);
		if (op->ob_item == NULL) {
			Py_DECREF(op);
			return PyErr_NoMemory();
		}
	}
        op->ob_exports = 0;
	return (PyObject *) op;
}

static PyObject *
getarrayitem(PyObject *op, Py_ssize_t i)
{
	register arrayobject *ap;
	assert(array_Check(op));
	ap = (arrayobject *)op;
	assert(i>=0 && i<Py_SIZE(ap));
	return (*ap->ob_descr->getitem)(ap, i);
}

static int
ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
{
	char *items;
	Py_ssize_t n = Py_SIZE(self);
	if (v == NULL) {
		PyErr_BadInternalCall();
		return -1;
	}
	if ((*self->ob_descr->setitem)(self, -1, v) < 0)
		return -1;

	if (array_resize(self, n+1) == -1)
		return -1;
	items = self->ob_item;
	if (where < 0) {
		where += n;
		if (where < 0)
			where = 0;
	}
	if (where > n)
		where = n;
	/* appends don't need to call memmove() */
	if (where != n)
		memmove(items + (where+1)*self->ob_descr->itemsize,
			items + where*self->ob_descr->itemsize,
			(n-where)*self->ob_descr->itemsize);
	return (*self->ob_descr->setitem)(self, where, v);
}

/* Methods */

static void
array_dealloc(arrayobject *op)
{
	if (op->weakreflist != NULL)
		PyObject_ClearWeakRefs((PyObject *) op);
	if (op->ob_item != NULL)
		PyMem_DEL(op->ob_item);
	Py_TYPE(op)->tp_free((PyObject *)op);
}

static PyObject *
array_richcompare(PyObject *v, PyObject *w, int op)
{
	arrayobject *va, *wa;
	PyObject *vi = NULL;
	PyObject *wi = NULL;
	Py_ssize_t i, k;
	PyObject *res;

	if (!array_Check(v) || !array_Check(w)) {
		Py_INCREF(Py_NotImplemented);
		return Py_NotImplemented;
	}

	va = (arrayobject *)v;
	wa = (arrayobject *)w;

	if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) {
		/* Shortcut: if the lengths differ, the arrays differ */
		if (op == Py_EQ)
			res = Py_False;
		else
			res = Py_True;
		Py_INCREF(res);
		return res;
	}

	/* Search for the first index where items are different */
	k = 1;
	for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
		vi = getarrayitem(v, i);
		wi = getarrayitem(w, i);
		if (vi == NULL || wi == NULL) {
			Py_XDECREF(vi);
			Py_XDECREF(wi);
			return NULL;
		}
		k = PyObject_RichCompareBool(vi, wi, Py_EQ);
		if (k == 0)
			break; /* Keeping vi and wi alive! */
		Py_DECREF(vi);
		Py_DECREF(wi);
		if (k < 0)
			return NULL;
	}

	if (k) {
		/* No more items to compare -- compare sizes */
		Py_ssize_t vs = Py_SIZE(va);
		Py_ssize_t ws = Py_SIZE(wa);
		int cmp;
		switch (op) {
		case Py_LT: cmp = vs <  ws; break;
		case Py_LE: cmp = vs <= ws; break;
		case Py_EQ: cmp = vs == ws; break;
		case Py_NE: cmp = vs != ws; break;
		case Py_GT: cmp = vs >  ws; break;
		case Py_GE: cmp = vs >= ws; break;
		default: return NULL; /* cannot happen */
		}
		if (cmp)
			res = Py_True;
		else
			res = Py_False;
		Py_INCREF(res);
		return res;
	}

	/* We have an item that differs.  First, shortcuts for EQ/NE */
	if (op == Py_EQ) {
		Py_INCREF(Py_False);
		res = Py_False;
	}
	else if (op == Py_NE) {
		Py_INCREF(Py_True);
		res = Py_True;
	}
	else {
		/* Compare the final item again using the proper operator */
		res = PyObject_RichCompare(vi, wi, op);
	}
	Py_DECREF(vi);
	Py_DECREF(wi);
	return res;
}

static Py_ssize_t
array_length(arrayobject *a)
{
	return Py_SIZE(a);
}

static PyObject *
array_item(arrayobject *a, Py_ssize_t i)
{
	if (i < 0 || i >= Py_SIZE(a)) {
		PyErr_SetString(PyExc_IndexError, "array index out of range");
		return NULL;
	}
	return getarrayitem((PyObject *)a, i);
}

static PyObject *
array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
	arrayobject *np;
	if (ilow < 0)
		ilow = 0;
	else if (ilow > Py_SIZE(a))
		ilow = Py_SIZE(a);
	if (ihigh < 0)
		ihigh = 0;
	if (ihigh < ilow)
		ihigh = ilow;
	else if (ihigh > Py_SIZE(a))
		ihigh = Py_SIZE(a);
	np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
	if (np == NULL)
		return NULL;
	memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
	       (ihigh-ilow) * a->ob_descr->itemsize);
	return (PyObject *)np;
}

static PyObject *
array_copy(arrayobject *a, PyObject *unused)
{
	return array_slice(a, 0, Py_SIZE(a));
}

PyDoc_STRVAR(copy_doc,
"copy(array)\n\
\n\
 Return a copy of the array.");

static PyObject *
array_concat(arrayobject *a, PyObject *bb)
{
	Py_ssize_t size;
	arrayobject *np;
	if (!array_Check(bb)) {
		PyErr_Format(PyExc_TypeError,
		     "can only append array (not \"%.200s\") to array",
			     Py_TYPE(bb)->tp_name);
		return NULL;
	}
#define b ((arrayobject *)bb)
	if (a->ob_descr != b->ob_descr) {
		PyErr_BadArgument();
		return NULL;
	}
	if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
		return PyErr_NoMemory();
	}
	size = Py_SIZE(a) + Py_SIZE(b);
	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
	if (np == NULL) {
		return NULL;
	}
	memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize);
	memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
	       b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
	return (PyObject *)np;
#undef b
}

static PyObject *
array_repeat(arrayobject *a, Py_ssize_t n)
{
	Py_ssize_t i;
	Py_ssize_t size;
	arrayobject *np;
	char *p;
	Py_ssize_t nbytes;
	if (n < 0)
		n = 0;
	if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
		return PyErr_NoMemory();
	}
	size = Py_SIZE(a) * n;
	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
	if (np == NULL)
		return NULL;
	p = np->ob_item;
	nbytes = Py_SIZE(a) * a->ob_descr->itemsize;
	for (i = 0; i < n; i++) {
		memcpy(p, a->ob_item, nbytes);
		p += nbytes;
	}
	return (PyObject *) np;
}

static int
array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
	char *item;
	Py_ssize_t n; /* Size of replacement array */
	Py_ssize_t d; /* Change in size */
#define b ((arrayobject *)v)
	if (v == NULL)
		n = 0;
	else if (array_Check(v)) {
		n = Py_SIZE(b);
		if (a == b) {
			/* Special case "a[i:j] = a" -- copy b first */
			int ret;
			v = array_slice(b, 0, n);
			if (!v)
				return -1;
			ret = array_ass_slice(a, ilow, ihigh, v);
			Py_DECREF(v);
			return ret;
		}
		if (b->ob_descr != a->ob_descr) {
			PyErr_BadArgument();
			return -1;
		}
	}
	else {
		PyErr_Format(PyExc_TypeError,
	     "can only assign array (not \"%.200s\") to array slice",
			     Py_TYPE(v)->tp_name);
		return -1;
	}
	if (ilow < 0)
		ilow = 0;
	else if (ilow > Py_SIZE(a))
		ilow = Py_SIZE(a);
	if (ihigh < 0)
		ihigh = 0;
	if (ihigh < ilow)
		ihigh = ilow;
	else if (ihigh > Py_SIZE(a))
		ihigh = Py_SIZE(a);
	item = a->ob_item;
	d = n - (ihigh-ilow);
	if (d < 0) { /* Delete -d items */
		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
			item + ihigh*a->ob_descr->itemsize,
			(Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
		if (array_resize(a, Py_SIZE(a) + d) == -1)
		    return -1;
	}
	else if (d > 0) { /* Insert d items */
		if (array_resize(a, Py_SIZE(a) + d))
			return -1;
		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
			item + ihigh*a->ob_descr->itemsize,
			(Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
	}
	if (n > 0)
		memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
		       n*b->ob_descr->itemsize);
	return 0;
#undef b
}

static int
array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
{
	if (i < 0 || i >= Py_SIZE(a)) {
		PyErr_SetString(PyExc_IndexError,
			         "array assignment index out of range");
		return -1;
	}
	if (v == NULL)
		return array_ass_slice(a, i, i+1, v);
	return (*a->ob_descr->setitem)(a, i, v);
}

static int
setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
{
	assert(array_Check(a));
	return array_ass_item((arrayobject *)a, i, v);
}

static int
array_iter_extend(arrayobject *self, PyObject *bb)
{
	PyObject *it, *v;

	it = PyObject_GetIter(bb);
	if (it == NULL)
		return -1;

	while ((v = PyIter_Next(it)) != NULL) {
		if (ins1(self, (int) Py_SIZE(self), v) != 0) {
			Py_DECREF(v);
			Py_DECREF(it);
			return -1;
		}
		Py_DECREF(v);
	}
	Py_DECREF(it);
	if (PyErr_Occurred())
		return -1;
	return 0;
}

static int
array_do_extend(arrayobject *self, PyObject *bb)
{
	Py_ssize_t size, oldsize;

	if (!array_Check(bb))
		return array_iter_extend(self, bb);
#define b ((arrayobject *)bb)
	if (self->ob_descr != b->ob_descr) {
		PyErr_SetString(PyExc_TypeError,
			     "can only extend with array of same kind");
		return -1;
	}
	if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) ||
		((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
		PyErr_NoMemory();
		return -1;
	}
	oldsize = Py_SIZE(self);
	size = oldsize + Py_SIZE(b);
	if (array_resize(self, size) == -1)
		return -1;
	memcpy(self->ob_item + oldsize * self->ob_descr->itemsize,
		b->ob_item, Py_SIZE(b) * b->ob_descr->itemsize);

	return 0;
#undef b
}

static PyObject *
array_inplace_concat(arrayobject *self, PyObject *bb)
{
	if (!array_Check(bb)) {
		PyErr_Format(PyExc_TypeError,
			"can only extend array with array (not \"%.200s\")",
			Py_TYPE(bb)->tp_name);
		return NULL;
	}
	if (array_do_extend(self, bb) == -1)
		return NULL;
	Py_INCREF(self);
	return (PyObject *)self;
}

static PyObject *
array_inplace_repeat(arrayobject *self, Py_ssize_t n)
{
	char *items, *p;
	Py_ssize_t size, i;

	if (Py_SIZE(self) > 0) {
		if (n < 0)
			n = 0;
		items = self->ob_item;
		if ((self->ob_descr->itemsize != 0) && 
			(Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
			return PyErr_NoMemory();
		}
		size = Py_SIZE(self) * self->ob_descr->itemsize;
		if (n > 0 && size > PY_SSIZE_T_MAX / n) {
			return PyErr_NoMemory();
		}
		if (array_resize(self, n * Py_SIZE(self)) == -1)
			return NULL;
		items = p = self->ob_item;
		for (i = 1; i < n; i++) {
			p += size;
			memcpy(p, items, size);
		}
	}
	Py_INCREF(self);
	return (PyObject *)self;
}


static PyObject *
ins(arrayobject *self, Py_ssize_t where, PyObject *v)
{
	if (ins1(self, where, v) != 0)
		return NULL;
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
array_count(arrayobject *self, PyObject *v)
{
	Py_ssize_t count = 0;
	Py_ssize_t i;

	for (i = 0; i < Py_SIZE(self); i++) {
		PyObject *selfi = getarrayitem((PyObject *)self, i);
		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
		Py_DECREF(selfi);
		if (cmp > 0)
			count++;
		else if (cmp < 0)
			return NULL;
	}
	return PyLong_FromSsize_t(count);
}

PyDoc_STRVAR(count_doc,
"count(x)\n\
\n\
Return number of occurrences of x in the array.");

static PyObject *
array_index(arrayobject *self, PyObject *v)
{
	Py_ssize_t i;

	for (i = 0; i < Py_SIZE(self); i++) {
		PyObject *selfi = getarrayitem((PyObject *)self, i);
		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
		Py_DECREF(selfi);
		if (cmp > 0) {
			return PyLong_FromLong((long)i);
		}
		else if (cmp < 0)
			return NULL;
	}
	PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
	return NULL;
}

PyDoc_STRVAR(index_doc,
"index(x)\n\
\n\
Return index of first occurrence of x in the array.");

static int
array_contains(arrayobject *self, PyObject *v)
{
	Py_ssize_t i;
	int cmp;

	for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
		PyObject *selfi = getarrayitem((PyObject *)self, i);
		cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
		Py_DECREF(selfi);
	}
	return cmp;
}

static PyObject *
array_remove(arrayobject *self, PyObject *v)
{
	int i;

	for (i = 0; i < Py_SIZE(self); i++) {
		PyObject *selfi = getarrayitem((PyObject *)self,i);
		int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
		Py_DECREF(selfi);
		if (cmp > 0) {
			if (array_ass_slice(self, i, i+1,
					   (PyObject *)NULL) != 0)
				return NULL;
			Py_INCREF(Py_None);
			return Py_None;
		}
		else if (cmp < 0)
			return NULL;
	}
	PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
	return NULL;
}

PyDoc_STRVAR(remove_doc,
"remove(x)\n\
\n\
Remove the first occurrence of x in the array.");

static PyObject *
array_pop(arrayobject *self, PyObject *args)
{
	Py_ssize_t i = -1;
	PyObject *v;
	if (!PyArg_ParseTuple(args, "|n:pop", &i))
		return NULL;
	if (Py_SIZE(self) == 0) {
		/* Special-case most common failure cause */
		PyErr_SetString(PyExc_IndexError, "pop from empty array");
		return NULL;
	}
	if (i < 0)
		i += Py_SIZE(self);
	if (i < 0 || i >= Py_SIZE(self)) {
		PyErr_SetString(PyExc_IndexError, "pop index out of range");
		return NULL;
	}
	v = getarrayitem((PyObject *)self,i);
	if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
		Py_DECREF(v);
		return NULL;
	}
	return v;
}

PyDoc_STRVAR(pop_doc,
"pop([i])\n\
\n\
Return the i-th element and delete it from the array. i defaults to -1.");

static PyObject *
array_extend(arrayobject *self, PyObject *bb)
{
	if (array_do_extend(self, bb) == -1)
		return NULL;
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(extend_doc,
"extend(array or iterable)\n\
\n\
 Append items to the end of the array.");

static PyObject *
array_insert(arrayobject *self, PyObject *args)
{
	Py_ssize_t i;
	PyObject *v;
        if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
		return NULL;
	return ins(self, i, v);
}

PyDoc_STRVAR(insert_doc,
"insert(i,x)\n\
\n\
Insert a new item x into the array before position i.");


static PyObject *
array_buffer_info(arrayobject *self, PyObject *unused)
{
	PyObject* retval = NULL;
	retval = PyTuple_New(2);
	if (!retval)
		return NULL;

	PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
	PyTuple_SET_ITEM(retval, 1, PyLong_FromLong((long)(Py_SIZE(self))));

	return retval;
}

PyDoc_STRVAR(buffer_info_doc,
"buffer_info() -> (address, length)\n\
\n\
Return a tuple (address, length) giving the current memory address and\n\
the length in items of the buffer used to hold array's contents\n\
The length should be multiplied by the itemsize attribute to calculate\n\
the buffer length in bytes.");


static PyObject *
array_append(arrayobject *self, PyObject *v)
{
	return ins(self, (int) Py_SIZE(self), v);
}

PyDoc_STRVAR(append_doc,
"append(x)\n\
\n\
Append new value x to the end of the array.");


static PyObject *
array_byteswap(arrayobject *self, PyObject *unused)
{
	char *p;
	Py_ssize_t i;

	switch (self->ob_descr->itemsize) {
	case 1:
		break;
	case 2:
		for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
			char p0 = p[0];
			p[0] = p[1];
			p[1] = p0;
		}
		break;
	case 4:
		for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) {
			char p0 = p[0];
			char p1 = p[1];
			p[0] = p[3];
			p[1] = p[2];
			p[2] = p1;
			p[3] = p0;
		}
		break;
	case 8:
		for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
			char p0 = p[0];
			char p1 = p[1];
			char p2 = p[2];
			char p3 = p[3];
			p[0] = p[7];
			p[1] = p[6];
			p[2] = p[5];
			p[3] = p[4];
			p[4] = p3;
			p[5] = p2;
			p[6] = p1;
			p[7] = p0;
		}
		break;
	default:
		PyErr_SetString(PyExc_RuntimeError,
			   "don't know how to byteswap this array type");
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(byteswap_doc,
"byteswap()\n\
\n\
Byteswap all items of the array.  If the items in the array are not 1, 2,\n\
4, or 8 bytes in size, RuntimeError is raised.");

static PyObject *
array_reduce(arrayobject *array)
{
	PyObject *dict, *result;

	dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
	if (dict == NULL) {
		PyErr_Clear();
		dict = Py_None;
		Py_INCREF(dict);
	}
	if (Py_SIZE(array) > 0) {
		if (array->ob_descr->itemsize 
				> PY_SSIZE_T_MAX / Py_SIZE(array)) {
			return PyErr_NoMemory();
		}
		result = Py_BuildValue("O(Cy#)O",
			Py_TYPE(array), 
			array->ob_descr->typecode,
			array->ob_item,
			Py_SIZE(array) * array->ob_descr->itemsize,
			dict);
	} else {
		result = Py_BuildValue("O(C)O",
			Py_TYPE(array), 
			array->ob_descr->typecode,
			dict);
	}
	Py_DECREF(dict);
	return result;
}

PyDoc_STRVAR(array_doc, "Return state information for pickling.");

static PyObject *
array_reverse(arrayobject *self, PyObject *unused)
{
	register Py_ssize_t itemsize = self->ob_descr->itemsize;
	register char *p, *q;
	/* little buffer to hold items while swapping */
	char tmp[256];	/* 8 is probably enough -- but why skimp */
	assert((size_t)itemsize <= sizeof(tmp));

	if (Py_SIZE(self) > 1) {
		for (p = self->ob_item,
		     q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
		     p < q;
		     p += itemsize, q -= itemsize) {
			/* memory areas guaranteed disjoint, so memcpy
			 * is safe (& memmove may be slower).
			 */
			memcpy(tmp, p, itemsize);
			memcpy(p, q, itemsize);
			memcpy(q, tmp, itemsize);
		}
	}

	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(reverse_doc,
"reverse()\n\
\n\
Reverse the order of the items in the array.");


/* Forward */
static PyObject *array_fromstring(arrayobject *self, PyObject *args);

static PyObject *
array_fromfile(arrayobject *self, PyObject *args)
{
	PyObject *f, *b, *res;
	Py_ssize_t itemsize = self->ob_descr->itemsize;
	Py_ssize_t n, nbytes;
	int not_enough_bytes;

        if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
		return NULL;

	nbytes = n * itemsize;
	if (nbytes < 0 || nbytes/itemsize != n) {
		PyErr_NoMemory();
		return NULL;
	}

	b = PyObject_CallMethod(f, "read", "n", nbytes);
	if (b == NULL)
		return NULL;

	if (!PyBytes_Check(b)) {
		PyErr_SetString(PyExc_TypeError,
				"read() didn't return bytes");
		Py_DECREF(b);
		return NULL;
	}

	not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes);

	args = Py_BuildValue("(O)", b);
	Py_DECREF(b);
	if (args == NULL)
		return NULL;

	res = array_fromstring(self, args);
	Py_DECREF(args);
	if (res == NULL)
		return NULL;

	if (not_enough_bytes) {
		PyErr_SetString(PyExc_EOFError,
				"read() didn't return enough bytes");
		Py_DECREF(res);
		return NULL;
	}

	return res;
}

PyDoc_STRVAR(fromfile_doc,
"fromfile(f, n)\n\
\n\
Read n objects from the file object f and append them to the end of the\n\
array.");


static PyObject *
array_tofile(arrayobject *self, PyObject *f)
{
	Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
	/* Write 64K blocks at a time */
	/* XXX Make the block size settable */
	int BLOCKSIZE = 64*1024;
	Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
	Py_ssize_t i;

        if (Py_SIZE(self) == 0)
		goto done;

	for (i = 0; i < nblocks; i++) {
		char* ptr = self->ob_item + i*BLOCKSIZE;
		Py_ssize_t size = BLOCKSIZE;
		PyObject *bytes, *res;
		if (i*BLOCKSIZE + size > nbytes)
			size = nbytes - i*BLOCKSIZE;
		bytes = PyBytes_FromStringAndSize(ptr, size);
		if (bytes == NULL)
			return NULL;
		res = PyObject_CallMethod(f, "write", "O", bytes);
		Py_DECREF(bytes);
		if (res == NULL)
			return NULL;
		Py_DECREF(res); /* drop write result */
	}

  done:
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(tofile_doc,
"tofile(f)\n\
\n\
Write all items (as machine values) to the file object f.");


static PyObject *
array_fromlist(arrayobject *self, PyObject *list)
{
	Py_ssize_t n;

	if (!PyList_Check(list)) {
		PyErr_SetString(PyExc_TypeError, "arg must be list");
		return NULL;
	}
	n = PyList_Size(list);
	if (n > 0) {
		Py_ssize_t i, old_size;
		old_size = Py_SIZE(self);
		if (array_resize(self, old_size + n) == -1)
			return NULL;
		for (i = 0; i < n; i++) {
			PyObject *v = PyList_GetItem(list, i);
			if ((*self->ob_descr->setitem)(self,
					Py_SIZE(self) - n + i, v) != 0) {
				array_resize(self, old_size);
				return NULL;
			}
		}
	}
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(fromlist_doc,
"fromlist(list)\n\
\n\
Append items to array from list.");

static PyObject *
array_tolist(arrayobject *self, PyObject *unused)
{
	PyObject *list = PyList_New(Py_SIZE(self));
	Py_ssize_t i;

	if (list == NULL)
		return NULL;
	for (i = 0; i < Py_SIZE(self); i++) {
		PyObject *v = getarrayitem((PyObject *)self, i);
		if (v == NULL) {
			Py_DECREF(list);
			return NULL;
		}
		PyList_SetItem(list, i, v);
	}
	return list;
}

PyDoc_STRVAR(tolist_doc,
"tolist() -> list\n\
\n\
Convert array to an ordinary list with the same items.");


static PyObject *
array_fromstring(arrayobject *self, PyObject *args)
{
	char *str;
	Py_ssize_t n;
	int itemsize = self->ob_descr->itemsize;
        if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n))
		return NULL;
	if (n % itemsize != 0) {
		PyErr_SetString(PyExc_ValueError,
			   "string length not a multiple of item size");
		return NULL;
	}
	n = n / itemsize;
	if (n > 0) {
        Py_ssize_t old_size = Py_SIZE(self);
		if ((n > PY_SSIZE_T_MAX - old_size) ||
			((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
				return PyErr_NoMemory();
		}
		if (array_resize(self, old_size + n) == -1)
			return NULL;
		memcpy(self->ob_item + old_size * itemsize,
			str, n * itemsize);
	}
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(fromstring_doc,
"fromstring(string)\n\
\n\
Appends items from the string, interpreting it as an array of machine\n\
values, as if it had been read from a file using the fromfile() method).");


static PyObject *
array_tostring(arrayobject *self, PyObject *unused)
{
	if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
		return PyBytes_FromStringAndSize(self->ob_item,
				    Py_SIZE(self) * self->ob_descr->itemsize);
	} else {
		return PyErr_NoMemory();
	}
}

PyDoc_STRVAR(tostring_doc,
"tostring() -> string\n\
\n\
Convert the array to an array of machine values and return the string\n\
representation.");



static PyObject *
array_fromunicode(arrayobject *self, PyObject *args)
{
	Py_UNICODE *ustr;
	Py_ssize_t n;
	char typecode;

        if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
		return NULL;
	typecode = self->ob_descr->typecode;
	if ((typecode != 'u')) {
	        PyErr_SetString(PyExc_ValueError,
			"fromunicode() may only be called on "
			"unicode type arrays");
		return NULL;
	}
	if (n > 0) {
		Py_ssize_t old_size = Py_SIZE(self);
		if (array_resize(self, old_size + n) == -1)
			return NULL;
		memcpy(self->ob_item + old_size * sizeof(Py_UNICODE),
		       ustr, n * sizeof(Py_UNICODE));
	}

	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(fromunicode_doc,
"fromunicode(ustr)\n\
\n\
Extends this array with data from the unicode string ustr.\n\
The array must be a unicode type array; otherwise a ValueError\n\
is raised.  Use array.fromstring(ustr.decode(...)) to\n\
append Unicode data to an array of some other type.");


static PyObject *
array_tounicode(arrayobject *self, PyObject *unused)
{
	char typecode;
	typecode = self->ob_descr->typecode;
	if ((typecode != 'u')) {
		PyErr_SetString(PyExc_ValueError,
		     "tounicode() may only be called on unicode type arrays");
		return NULL;
	}
	return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self));
}

PyDoc_STRVAR(tounicode_doc,
"tounicode() -> unicode\n\
\n\
Convert the array to a unicode string.  The array must be\n\
a unicode type array; otherwise a ValueError is raised.  Use\n\
array.tostring().decode() to obtain a unicode string from\n\
an array of some other type.");



static PyObject *
array_get_typecode(arrayobject *a, void *closure)
{
	char tc = a->ob_descr->typecode;
	return PyUnicode_FromStringAndSize(&tc, 1);
}

static PyObject *
array_get_itemsize(arrayobject *a, void *closure)
{
	return PyLong_FromLong((long)a->ob_descr->itemsize);
}

static PyGetSetDef array_getsets [] = {
	{"typecode", (getter) array_get_typecode, NULL,
	 "the typecode character used to create the array"},
	{"itemsize", (getter) array_get_itemsize, NULL,
	 "the size, in bytes, of one array item"},
	{NULL}
};

static PyMethodDef array_methods[] = {
	{"append",	(PyCFunction)array_append,	METH_O,
	 append_doc},
	{"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,
	 buffer_info_doc},
	{"byteswap",	(PyCFunction)array_byteswap,	METH_NOARGS,
	 byteswap_doc},
	{"__copy__",	(PyCFunction)array_copy,	METH_NOARGS,
	 copy_doc},
	{"count",	(PyCFunction)array_count,	METH_O,
	 count_doc},
	{"__deepcopy__",(PyCFunction)array_copy,	METH_O,
	 copy_doc},
	{"extend",      (PyCFunction)array_extend,	METH_O,
	 extend_doc},
	{"fromfile",	(PyCFunction)array_fromfile,	METH_VARARGS,
	 fromfile_doc},
	{"fromlist",	(PyCFunction)array_fromlist,	METH_O,
	 fromlist_doc},
	{"fromstring",	(PyCFunction)array_fromstring,	METH_VARARGS,
	 fromstring_doc},
	{"fromunicode",	(PyCFunction)array_fromunicode,	METH_VARARGS,
	 fromunicode_doc},
	{"index",	(PyCFunction)array_index,	METH_O,
	 index_doc},
	{"insert",	(PyCFunction)array_insert,	METH_VARARGS,
	 insert_doc},
	{"pop",		(PyCFunction)array_pop,		METH_VARARGS,
	 pop_doc},
	{"__reduce__",	(PyCFunction)array_reduce,	METH_NOARGS,
	 array_doc},
	{"remove",	(PyCFunction)array_remove,	METH_O,
	 remove_doc},
	{"reverse",	(PyCFunction)array_reverse,	METH_NOARGS,
	 reverse_doc},
/*	{"sort",	(PyCFunction)array_sort,	METH_VARARGS,
	sort_doc},*/
	{"tofile",	(PyCFunction)array_tofile,	METH_O,
	 tofile_doc},
	{"tolist",	(PyCFunction)array_tolist,	METH_NOARGS,
	 tolist_doc},
	{"tostring",	(PyCFunction)array_tostring,	METH_NOARGS,
	 tostring_doc},
	{"tounicode",   (PyCFunction)array_tounicode,	METH_NOARGS,
	 tounicode_doc},
	{NULL,		NULL}		/* sentinel */
};

static PyObject *
array_repr(arrayobject *a)
{
	char typecode;
	PyObject *s, *v = NULL;
	Py_ssize_t len;

	len = Py_SIZE(a);
	typecode = a->ob_descr->typecode;
	if (len == 0) {
		return PyUnicode_FromFormat("array('%c')", typecode);
	}
        if ((typecode == 'u'))
		v = array_tounicode(a, NULL);
	else
		v = array_tolist(a, NULL);

	s = PyUnicode_FromFormat("array('%c', %R)", typecode, v);
	Py_DECREF(v);
	return s;
}

static PyObject*
array_subscr(arrayobject* self, PyObject* item)
{
	if (PyIndex_Check(item)) {
		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
		if (i==-1 && PyErr_Occurred()) {
			return NULL;
		}
		if (i < 0)
			i += Py_SIZE(self);
		return array_item(self, i);
	}
	else if (PySlice_Check(item)) {
		Py_ssize_t start, stop, step, slicelength, cur, i;
		PyObject* result;
		arrayobject* ar;
		int itemsize = self->ob_descr->itemsize;

		if (PySlice_GetIndicesEx((PySliceObject*)item, Py_SIZE(self),
				 &start, &stop, &step, &slicelength) < 0) {
			return NULL;
		}

		if (slicelength <= 0) {
			return newarrayobject(&Arraytype, 0, self->ob_descr);
		}
		else if (step == 1) {
			PyObject *result = newarrayobject(&Arraytype,
						slicelength, self->ob_descr);
			if (result == NULL)
				return NULL;
			memcpy(((arrayobject *)result)->ob_item,
			       self->ob_item + start * itemsize,
			       slicelength * itemsize);
			return result;
		}
		else {
			result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
			if (!result) return NULL;

			ar = (arrayobject*)result;

			for (cur = start, i = 0; i < slicelength; 
			     cur += step, i++) {
				memcpy(ar->ob_item + i*itemsize,
				       self->ob_item + cur*itemsize,
				       itemsize);
			}
			
			return result;
		}		
	}
	else {
		PyErr_SetString(PyExc_TypeError, 
				"array indices must be integers");
		return NULL;
	}
}

static int
array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
{
	Py_ssize_t start, stop, step, slicelength, needed;
	arrayobject* other;
	int itemsize;

	if (PyIndex_Check(item)) {
		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
		
		if (i == -1 && PyErr_Occurred())
			return -1;
		if (i < 0)
			i += Py_SIZE(self);
		if (i < 0 || i >= Py_SIZE(self)) {
			PyErr_SetString(PyExc_IndexError,
				"array assignment index out of range");
			return -1;
		}
		if (value == NULL) {
			/* Fall through to slice assignment */
			start = i;
			stop = i + 1;
			step = 1;
			slicelength = 1;
		}
		else
			return (*self->ob_descr->setitem)(self, i, value);
	}
	else if (PySlice_Check(item)) {
		if (PySlice_GetIndicesEx((PySliceObject *)item,
					 Py_SIZE(self), &start, &stop,
					 &step, &slicelength) < 0) {
			return -1;
		}
	}
	else {
		PyErr_SetString(PyExc_TypeError,
				"array indices must be integer");
		return -1;
	}
	if (value == NULL) {
		other = NULL;
		needed = 0;
	}
	else if (array_Check(value)) {
		other = (arrayobject *)value;
		needed = Py_SIZE(other);
		if (self == other) {
			/* Special case "self[i:j] = self" -- copy self first */
			int ret;
			value = array_slice(other, 0, needed);
			if (value == NULL)
				return -1;
			ret = array_ass_subscr(self, item, value);
			Py_DECREF(value);
			return ret;
		}
		if (other->ob_descr != self->ob_descr) {
			PyErr_BadArgument();
			return -1;
		}
	}
	else {
		PyErr_Format(PyExc_TypeError,
	     "can only assign array (not \"%.200s\") to array slice",
			     Py_TYPE(value)->tp_name);
		return -1;
	}
	itemsize = self->ob_descr->itemsize;
	/* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
	if ((step > 0 && stop < start) ||
	    (step < 0 && stop > start))
		stop = start;
	if (step == 1) {
		if (slicelength > needed) {
			memmove(self->ob_item + (start + needed) * itemsize,
				self->ob_item + stop * itemsize,
				(Py_SIZE(self) - stop) * itemsize);
			if (array_resize(self, Py_SIZE(self) +
				needed - slicelength) < 0)
				return -1;
		}
		else if (slicelength < needed) {
			if (array_resize(self, Py_SIZE(self) +
				needed - slicelength) < 0)
				return -1;
			memmove(self->ob_item + (start + needed) * itemsize,
				self->ob_item + stop * itemsize,
				(Py_SIZE(self) - start - needed) * itemsize);
		}
		if (needed > 0)
			memcpy(self->ob_item + start * itemsize,
			       other->ob_item, needed * itemsize);
		return 0;
	}
	else if (needed == 0) {
		/* Delete slice */
		Py_ssize_t cur, i;
		
		if (step < 0) {
			stop = start + 1;
			start = stop + step * (slicelength - 1) - 1;
			step = -step;
		}
		for (cur = start, i = 0; i < slicelength;
		     cur += step, i++) {
			Py_ssize_t lim = step - 1;

			if (cur + step >= Py_SIZE(self))
				lim = Py_SIZE(self) - cur - 1;
			memmove(self->ob_item + (cur - i) * itemsize,
				self->ob_item + (cur + 1) * itemsize,
				lim * itemsize);
		}
		cur = start + slicelength * step;
		if (cur < Py_SIZE(self)) {
			memmove(self->ob_item + (cur-slicelength) * itemsize,
				self->ob_item + cur * itemsize,
				(Py_SIZE(self) - cur) * itemsize);
		}
		if (array_resize(self, Py_SIZE(self) - slicelength) < 0)
			return -1;
		return 0;
	}
	else {
		Py_ssize_t cur, i;

		if (needed != slicelength) {
			PyErr_Format(PyExc_ValueError,
				"attempt to assign array of size %zd "
				"to extended slice of size %zd",
				needed, slicelength);
			return -1;
		}
		for (cur = start, i = 0; i < slicelength;
		     cur += step, i++) {
			memcpy(self->ob_item + cur * itemsize,
			       other->ob_item + i * itemsize,
			       itemsize);
		}
		return 0;
	}
}

static PyMappingMethods array_as_mapping = {
	(lenfunc)array_length,
	(binaryfunc)array_subscr,
	(objobjargproc)array_ass_subscr
};

static const void *emptybuf = "";


static int
array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
{
        if (view==NULL) goto finish;

        view->buf = (void *)self->ob_item;
	view->obj = (PyObject*)self;
	Py_INCREF(self);
        if (view->buf == NULL)
                view->buf = (void *)emptybuf;
        view->len = (Py_SIZE(self)) * self->ob_descr->itemsize;
        view->readonly = 0;
        view->ndim = 1;
        view->itemsize = self->ob_descr->itemsize;
        view->suboffsets = NULL;
        view->shape = NULL;
        if ((flags & PyBUF_ND)==PyBUF_ND) {
                view->shape = &((Py_SIZE(self)));
        }
        view->strides = NULL;
        if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES)
                view->strides = &(view->itemsize);
        view->format = NULL;
        view->internal = NULL;
        if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
                view->format = self->ob_descr->formats;
#ifdef Py_UNICODE_WIDE
		if (self->ob_descr->typecode == 'u') {
			view->format = "w";
		}
#endif
        }

 finish:
        self->ob_exports++;
        return 0;
}

static void
array_buffer_relbuf(arrayobject *self, Py_buffer *view)
{
        self->ob_exports--;
}

static PySequenceMethods array_as_sequence = {
	(lenfunc)array_length,		        /*sq_length*/
	(binaryfunc)array_concat,               /*sq_concat*/
	(ssizeargfunc)array_repeat,		/*sq_repeat*/
	(ssizeargfunc)array_item,		        /*sq_item*/
	0,					/*sq_slice*/
	(ssizeobjargproc)array_ass_item,		/*sq_ass_item*/
	0,					/*sq_ass_slice*/
	(objobjproc)array_contains,		/*sq_contains*/
	(binaryfunc)array_inplace_concat,	/*sq_inplace_concat*/
	(ssizeargfunc)array_inplace_repeat	/*sq_inplace_repeat*/
};

static PyBufferProcs array_as_buffer = {
        (getbufferproc)array_buffer_getbuf,
        (releasebufferproc)array_buffer_relbuf
};

static PyObject *
array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	int c;
	PyObject *initial = NULL, *it = NULL;
	struct arraydescr *descr;
	
	if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
		return NULL;

	if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
		return NULL;

	if (!(initial == NULL || PyList_Check(initial)
	      || PyByteArray_Check(initial)
	      || PyBytes_Check(initial)
	      || PyTuple_Check(initial)
	      || ((c=='u') && PyUnicode_Check(initial)))) {
		it = PyObject_GetIter(initial);
		if (it == NULL)
			return NULL;
		/* We set initial to NULL so that the subsequent code
		   will create an empty array of the appropriate type
		   and afterwards we can use array_iter_extend to populate
		   the array.
		*/
		initial = NULL;
	}
	for (descr = descriptors; descr->typecode != '\0'; descr++) {
		if (descr->typecode == c) {
			PyObject *a;
			Py_ssize_t len;

			if (initial == NULL || !(PyList_Check(initial) 
				|| PyTuple_Check(initial)))
				len = 0;
			else
				len = PySequence_Size(initial);

			a = newarrayobject(type, len, descr);
			if (a == NULL)
				return NULL;

			if (len > 0) {
				Py_ssize_t i;
				for (i = 0; i < len; i++) {
					PyObject *v =
					        PySequence_GetItem(initial, i);
					if (v == NULL) {
						Py_DECREF(a);
						return NULL;
					}
					if (setarrayitem(a, i, v) != 0) {
						Py_DECREF(v);
						Py_DECREF(a);
						return NULL;
					}
					Py_DECREF(v);
				}
			}
			else if (initial != NULL && (PyByteArray_Check(initial) ||
					   PyBytes_Check(initial))) {
				PyObject *t_initial, *v;
				t_initial = PyTuple_Pack(1, initial);
				if (t_initial == NULL) {
					Py_DECREF(a);
					return NULL;
				}
				v = array_fromstring((arrayobject *)a,
							 t_initial);
				Py_DECREF(t_initial);
				if (v == NULL) {
					Py_DECREF(a);
					return NULL;
				}
				Py_DECREF(v);
			}
			else if (initial != NULL && PyUnicode_Check(initial))  {
				Py_ssize_t n = PyUnicode_GET_DATA_SIZE(initial);
				if (n > 0) {
					arrayobject *self = (arrayobject *)a;
					char *item = self->ob_item;
					item = (char *)PyMem_Realloc(item, n);
					if (item == NULL) {
						PyErr_NoMemory();
						Py_DECREF(a);
						return NULL;
					}
					self->ob_item = item;
					Py_SIZE(self) = n / sizeof(Py_UNICODE);
					memcpy(item, PyUnicode_AS_DATA(initial), n);
					self->allocated = Py_SIZE(self);
				}
			}
			if (it != NULL) {
				if (array_iter_extend((arrayobject *)a, it) == -1) {
					Py_DECREF(it);
					Py_DECREF(a);
					return NULL;
				}
				Py_DECREF(it);
			}
			return a;
		}
	}
	PyErr_SetString(PyExc_ValueError,
		"bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)");
	return NULL;
}


PyDoc_STRVAR(module_doc,
"This module defines an object type which can efficiently represent\n\
an array of basic values: characters, integers, floating point\n\
numbers.  Arrays are sequence types and behave very much like lists,\n\
except that the type of objects stored in them is constrained.  The\n\
type is specified at object creation time by using a type code, which\n\
is a single character.  The following type codes are defined:\n\
\n\
    Type code   C Type             Minimum size in bytes \n\
    'b'         signed integer     1 \n\
    'B'         unsigned integer   1 \n\
    'u'         Unicode character  2 (see note) \n\
    'h'         signed integer     2 \n\
    'H'         unsigned integer   2 \n\
    'i'         signed integer     2 \n\
    'I'         unsigned integer   2 \n\
    'w'         unicode character  4 \n\
    'l'         signed integer     4 \n\
    'L'         unsigned integer   4 \n\
    'f'         floating point     4 \n\
    'd'         floating point     8 \n\
\n\
NOTE: The 'u' typecode corresponds to Python's unicode character. On \n\
narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
\n\
The constructor is:\n\
\n\
array(typecode [, initializer]) -- create a new array\n\
");

PyDoc_STRVAR(arraytype_doc,
"array(typecode [, initializer]) -> array\n\
\n\
Return a new array whose items are restricted by typecode, and\n\
initialized from the optional initializer value, which must be a list,\n\
string. or iterable over elements of the appropriate type.\n\
\n\
Arrays represent basic values and behave very much like lists, except\n\
the type of objects stored in them is constrained.\n\
\n\
Methods:\n\
\n\
append() -- append a new item to the end of the array\n\
buffer_info() -- return information giving the current memory info\n\
byteswap() -- byteswap all the items of the array\n\
count() -- return number of occurrences of an object\n\
extend() -- extend array by appending multiple elements from an iterable\n\
fromfile() -- read items from a file object\n\
fromlist() -- append items from the list\n\
fromstring() -- append items from the string\n\
index() -- return index of first occurrence of an object\n\
insert() -- insert a new item into the array at a provided position\n\
pop() -- remove and return item (default last)\n\
remove() -- remove first occurrence of an object\n\
reverse() -- reverse the order of the items in the array\n\
tofile() -- write all items to a file object\n\
tolist() -- return the array converted to an ordinary list\n\
tostring() -- return the array converted to a string\n\
\n\
Attributes:\n\
\n\
typecode -- the typecode character used to create the array\n\
itemsize -- the length in bytes of one array item\n\
");

static PyObject *array_iter(arrayobject *ao);

static PyTypeObject Arraytype = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"array.array",
	sizeof(arrayobject),
	0,
	(destructor)array_dealloc,		/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_reserved */
	(reprfunc)array_repr,			/* tp_repr */
	0,					/* tp_as_number*/
	&array_as_sequence,			/* tp_as_sequence*/
	&array_as_mapping,			/* tp_as_mapping*/
	0, 					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	&array_as_buffer,			/* tp_as_buffer*/
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
	arraytype_doc,				/* tp_doc */
 	0,					/* tp_traverse */
	0,					/* tp_clear */
	array_richcompare,			/* tp_richcompare */
	offsetof(arrayobject, weakreflist),	/* tp_weaklistoffset */
	(getiterfunc)array_iter,		/* tp_iter */
	0,					/* tp_iternext */
	array_methods,				/* tp_methods */
	0,					/* tp_members */
	array_getsets,				/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	PyType_GenericAlloc,			/* tp_alloc */
	array_new,				/* tp_new */
	PyObject_Del,				/* tp_free */
};


/*********************** Array Iterator **************************/

typedef struct {
	PyObject_HEAD
	Py_ssize_t			index;
	arrayobject		*ao;
	PyObject		* (*getitem)(struct arrayobject *, Py_ssize_t);
} arrayiterobject;

static PyTypeObject PyArrayIter_Type;

#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)

static PyObject *
array_iter(arrayobject *ao)
{
	arrayiterobject *it;

	if (!array_Check(ao)) {
		PyErr_BadInternalCall();
		return NULL;
	}

	it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type);
	if (it == NULL)
		return NULL;

	Py_INCREF(ao);
	it->ao = ao;
	it->index = 0;
	it->getitem = ao->ob_descr->getitem;
	PyObject_GC_Track(it);
	return (PyObject *)it;
}

static PyObject *
arrayiter_next(arrayiterobject *it)
{
	assert(PyArrayIter_Check(it));
	if (it->index < Py_SIZE(it->ao))
		return (*it->getitem)(it->ao, it->index++);
	return NULL;
}

static void
arrayiter_dealloc(arrayiterobject *it)
{
	PyObject_GC_UnTrack(it);
	Py_XDECREF(it->ao);
	PyObject_GC_Del(it);
}

static int
arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
{
	Py_VISIT(it->ao);
	return 0;
}

static PyTypeObject PyArrayIter_Type = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"arrayiterator",                        /* tp_name */
	sizeof(arrayiterobject),                /* tp_basicsize */
	0,                                      /* tp_itemsize */
	/* methods */
	(destructor)arrayiter_dealloc,		/* tp_dealloc */
	0,                                      /* tp_print */
	0,                                      /* tp_getattr */
	0,                                      /* tp_setattr */
	0,                                      /* tp_reserved */
	0,                                      /* tp_repr */
	0,                                      /* tp_as_number */
	0,                                      /* tp_as_sequence */
	0,                                      /* tp_as_mapping */
	0,                                      /* tp_hash */
	0,                                      /* tp_call */
	0,                                      /* tp_str */
	PyObject_GenericGetAttr,                /* tp_getattro */
	0,                                      /* tp_setattro */
	0,                                      /* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
	0,                                      /* tp_doc */
	(traverseproc)arrayiter_traverse,	/* tp_traverse */
	0,					/* tp_clear */
	0,                                      /* tp_richcompare */
	0,                                      /* tp_weaklistoffset */
	PyObject_SelfIter,			/* tp_iter */
	(iternextfunc)arrayiter_next,		/* tp_iternext */
	0,					/* tp_methods */
};


/*********************** Install Module **************************/

/* No functions in array module. */
static PyMethodDef a_methods[] = {
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

static struct PyModuleDef arraymodule = {
	PyModuleDef_HEAD_INIT,
	"array",
	module_doc,
	-1,
	a_methods,
	NULL,
	NULL,
	NULL,
	NULL
};


PyMODINIT_FUNC
PyInit_array(void)
{
	PyObject *m;
	PyObject *typecodes;
	Py_ssize_t size = 0;
	register Py_UNICODE *p;
	struct arraydescr *descr;

	if (PyType_Ready(&Arraytype) < 0)
            return NULL;
	Py_TYPE(&PyArrayIter_Type) = &PyType_Type;
	m = PyModule_Create(&arraymodule);
	if (m == NULL)
		return NULL;

        Py_INCREF((PyObject *)&Arraytype);
	PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
        Py_INCREF((PyObject *)&Arraytype);
	PyModule_AddObject(m, "array", (PyObject *)&Arraytype);

	for (descr=descriptors; descr->typecode != '\0'; descr++) {
		size++;
	}
	
	typecodes = PyUnicode_FromStringAndSize(NULL, size);
	p = PyUnicode_AS_UNICODE(typecodes);
	for (descr = descriptors; descr->typecode != '\0'; descr++) {
		*p++ = (char)descr->typecode;
	}

	PyModule_AddObject(m, "typecodes", (PyObject *)typecodes);
	
	if (PyErr_Occurred()) {
		Py_DECREF(m);
		m = NULL;
	}
	return m;
}
