⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arraymodule.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		ilow = 0;
	else if (ilow > a->ob_size)
		ilow = a->ob_size;
	if (ihigh < 0)
		ihigh = 0;
	if (ihigh < ilow)
		ihigh = ilow;
	else if (ihigh > a->ob_size)
		ihigh = a->ob_size;
	np = (arrayobject *) newarrayobject(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_concat(arrayobject *a, PyObject *bb)
{
	int size;
	arrayobject *np;
	if (!is_arrayobject(bb)) {
		PyErr_Format(PyExc_TypeError,
		     "can only append array (not \"%.200s\") to array",
			     bb->ob_type->tp_name);
		return NULL;
	}
#define b ((arrayobject *)bb)
	if (a->ob_descr != b->ob_descr) {
		PyErr_BadArgument();
		return NULL;
	}
	size = a->ob_size + b->ob_size;
	np = (arrayobject *) newarrayobject(size, a->ob_descr);
	if (np == NULL) {
		return NULL;
	}
	memcpy(np->ob_item, a->ob_item, a->ob_size*a->ob_descr->itemsize);
	memcpy(np->ob_item + a->ob_size*a->ob_descr->itemsize,
	       b->ob_item, b->ob_size*b->ob_descr->itemsize);
	return (PyObject *)np;
#undef b
}

static PyObject *
array_repeat(arrayobject *a, int n)
{
	int i;
	int size;
	arrayobject *np;
	char *p;
	int nbytes;
	if (n < 0)
		n = 0;
	size = a->ob_size * n;
	np = (arrayobject *) newarrayobject(size, a->ob_descr);
	if (np == NULL)
		return NULL;
	p = np->ob_item;
	nbytes = a->ob_size * 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, int ilow, int ihigh, PyObject *v)
{
	char *item;
	int n; /* Size of replacement array */
	int d; /* Change in size */
#define b ((arrayobject *)v)
	if (v == NULL)
		n = 0;
	else if (is_arrayobject(v)) {
		n = b->ob_size;
		if (a == b) {
			/* Special case "a[i:j] = a" -- copy b first */
			int ret;
			v = array_slice(b, 0, n);
			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",
			     v->ob_type->tp_name);
		return -1;
	}
	if (ilow < 0)
		ilow = 0;
	else if (ilow > a->ob_size)
		ilow = a->ob_size;
	if (ihigh < 0)
		ihigh = 0;
	if (ihigh < ilow)
		ihigh = ilow;
	else if (ihigh > a->ob_size)
		ihigh = a->ob_size;
	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,
			(a->ob_size-ihigh)*a->ob_descr->itemsize);
		a->ob_size += d;
		PyMem_RESIZE(item, char, a->ob_size*a->ob_descr->itemsize);
						/* Can't fail */
		a->ob_item = item;
	}
	else if (d > 0) { /* Insert d items */
		PyMem_RESIZE(item, char,
			     (a->ob_size + d)*a->ob_descr->itemsize);
		if (item == NULL) {
			PyErr_NoMemory();
			return -1;
		}
		memmove(item + (ihigh+d)*a->ob_descr->itemsize,
			item + ihigh*a->ob_descr->itemsize,
			(a->ob_size-ihigh)*a->ob_descr->itemsize);
		a->ob_item = item;
		a->ob_size += d;
	}
	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, int i, PyObject *v)
{
	if (i < 0 || i >= a->ob_size) {
		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, int i, PyObject *v)
{
	assert(is_arrayobject(a));
	return array_ass_item((arrayobject *)a, i, v);
}

static PyObject *
ins(arrayobject *self, int 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 *args)
{
	int count = 0;
	int i;
	PyObject *v;

        if (!PyArg_ParseTuple(args, "O:count", &v))
		return NULL;
	for (i = 0; i < self->ob_size; 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 PyInt_FromLong((long)count);
}

static char count_doc [] =
"count(x)\n\
\n\
Return number of occurences of x in the array.";

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

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

static char index_doc [] =
"index(x)\n\
\n\
Return index of first occurence of x in the array.";

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

        if (!PyArg_ParseTuple(args, "O:remove", &v))
		return NULL;
	for (i = 0; i < self->ob_size; 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;
}

static char remove_doc [] =
"remove(x)\n\
\n\
Remove the first occurence of x in the array.";

static PyObject *
array_pop(arrayobject *self, PyObject *args)
{
	int i = -1;
	PyObject *v;
	if (!PyArg_ParseTuple(args, "|i:pop", &i))
		return NULL;
	if (self->ob_size == 0) {
		/* Special-case most common failure cause */
		PyErr_SetString(PyExc_IndexError, "pop from empty array");
		return NULL;
	}
	if (i < 0)
		i += self->ob_size;
	if (i < 0 || i >= self->ob_size) {
		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;
}

static char 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 *args)
{
	int size;
        PyObject    *bb;

	if (!PyArg_ParseTuple(args, "O:extend", &bb))
            return NULL;

	if (!is_arrayobject(bb)) {
		PyErr_Format(PyExc_TypeError,
			"can only extend array with array (not \"%.200s\")",
			bb->ob_type->tp_name);
		return NULL;
	}
#define b ((arrayobject *)bb)
	if (self->ob_descr != b->ob_descr) {
		PyErr_SetString(PyExc_TypeError,
			     "can only extend with array of same kind");
		return NULL;
	}
	size = self->ob_size + b->ob_size;
        PyMem_RESIZE(self->ob_item, char, size*self->ob_descr->itemsize);
        if (self->ob_item == NULL) {
                PyObject_Del(self);
                return PyErr_NoMemory();
        }
	memcpy(self->ob_item + self->ob_size*self->ob_descr->itemsize,
               b->ob_item, b->ob_size*b->ob_descr->itemsize);
        self->ob_size = size;
        Py_INCREF(Py_None);
	return Py_None;
#undef b
}

static char extend_doc [] =
"extend(array)\n\
\n\
 Append array items to the end of the array.";

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

static char 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 *args)
{
	PyObject* retval = NULL;
        if (!PyArg_ParseTuple(args, ":buffer_info"))
                return NULL;
	retval = PyTuple_New(2);
	if (!retval)
		return NULL;

	PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
	PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(self->ob_size)));

	return retval;
}

static char 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 *args)
{
	PyObject *v;
        if (!PyArg_ParseTuple(args, "O:append", &v))
		return NULL;
	return ins(self, (int) self->ob_size, v);
}

static char append_doc [] =
"append(x)\n\
\n\
Append new value x to the end of the array.";


static PyObject *
array_byteswap(arrayobject *self, PyObject *args)
{
	char *p;
	int i;

        if (!PyArg_ParseTuple(args, ":byteswap"))
                return NULL;

	switch (self->ob_descr->itemsize) {
	case 1:
		break;
	case 2:
		for (p = self->ob_item, i = self->ob_size; --i >= 0; p += 2) {
			char p0 = p[0];
			p[0] = p[1];
			p[1] = p0;
		}
		break;
	case 4:
		for (p = self->ob_item, i = self->ob_size; --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 = self->ob_size; --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;
}

static char 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_reverse(arrayobject *self, PyObject *args)
{
	register int 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(itemsize <= sizeof(tmp));

        if (!PyArg_ParseTuple(args, ":reverse"))
                return NULL;

	if (self->ob_size > 1) {
		for (p = self->ob_item,
		     q = self->ob_item + (self->ob_size - 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;
}

static char reverse_doc [] =
"reverse()\n\
\n\
Reverse the order of the items in the array.";

static PyObject *
array_fromfile(arrayobject *self, PyObject *args)
{
	PyObject *f;
	int n;
	FILE *fp;
        if (!PyArg_ParseTuple(args, "Oi:fromfile", &f, &n))
		return NULL;
	fp = PyFile_AsFile(f);
	if (fp == NULL) {
		PyErr_SetString(PyExc_TypeError, "arg1 must be open file");
		return NULL;
	}
	if (n > 0) {
		char *item = self->ob_item;
		int itemsize = self->ob_descr->itemsize;
		size_t nread;
		int newlength;
		size_t newbytes;
		/* Be careful here about overflow */
		if ((newlength = self->ob_size + n) <= 0 ||
		    (newbytes = newlength * itemsize) / itemsize !=
		    (size_t)newlength)
			goto nomem;
		PyMem_RESIZE(item, char, newbytes);
		if (item == NULL) {
		  nomem:
			PyErr_NoMemory();
			return NULL;
		}
		self->ob_item = item;
		self->ob_size += n;
		nread = fread(item + (self->ob_size - n) * itemsize,
			      itemsize, n, fp);
		if (nread < (size_t)n) {
			self->ob_size -= (n - nread);
			PyMem_RESIZE(item, char, self->ob_size*itemsize);
			self->ob_item = item;
			PyErr_SetString(PyExc_EOFError,
				         "not enough items in file");
			return NULL;
		}
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static char fromfile_doc [] =
"fromfile(f, n)\n\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -