summaryrefslogtreecommitdiff
path: root/Modules/arraymodule.c
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2012-12-10 20:22:31 -0800
committerGregory P. Smith <greg@krypto.org>2012-12-10 20:22:31 -0800
commit04813e97bfdc2c04c2b2b13b64e8bd0ba8151735 (patch)
treedfd5af8787073545794ce8a577319320e2c1e286 /Modules/arraymodule.c
parent1a01f697384c87d24e454f7908f984ffe87180a8 (diff)
parent08f293ce65292104f0b9ae387b11d81e7db09a68 (diff)
downloadcpython-04813e97bfdc2c04c2b2b13b64e8bd0ba8151735.tar.gz
Code style fixup: No need for double ((parenthesis)) and use {} on an if else.
Diffstat (limited to 'Modules/arraymodule.c')
-rw-r--r--Modules/arraymodule.c198
1 files changed, 158 insertions, 40 deletions
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 475acb4692..710761e52d 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -22,7 +22,7 @@ struct arrayobject; /* Forward */
* functions aren't visible yet.
*/
struct arraydescr {
- Py_UNICODE typecode;
+ char typecode;
int itemsize;
PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
@@ -356,6 +356,59 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
return 0;
}
+#ifdef HAVE_LONG_LONG
+
+static PyObject *
+q_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]);
+}
+
+static int
+q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ PY_LONG_LONG x;
+ if (!PyArg_Parse(v, "L;array item must be integer", &x))
+ return -1;
+ if (i >= 0)
+ ((PY_LONG_LONG *)ap->ob_item)[i] = x;
+ return 0;
+}
+
+static PyObject *
+QQ_getitem(arrayobject *ap, Py_ssize_t i)
+{
+ return PyLong_FromUnsignedLongLong(
+ ((unsigned PY_LONG_LONG *)ap->ob_item)[i]);
+}
+
+static int
+QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
+{
+ unsigned PY_LONG_LONG x;
+ if (PyLong_Check(v)) {
+ x = PyLong_AsUnsignedLongLong(v);
+ if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred())
+ return -1;
+ }
+ else {
+ PY_LONG_LONG y;
+ if (!PyArg_Parse(v, "L;array item must be integer", &y))
+ return -1;
+ if (y < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned long long is less than minimum");
+ return -1;
+ }
+ x = (unsigned PY_LONG_LONG)y;
+ }
+
+ if (i >= 0)
+ ((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x;
+ return 0;
+}
+#endif
+
static PyObject *
f_getitem(arrayobject *ap, Py_ssize_t i)
{
@@ -406,6 +459,10 @@ static struct arraydescr descriptors[] = {
{'I', sizeof(int), II_getitem, II_setitem, "I", 1, 0},
{'l', sizeof(long), l_getitem, l_setitem, "l", 1, 1},
{'L', sizeof(long), LL_getitem, LL_setitem, "L", 1, 0},
+#ifdef HAVE_LONG_LONG
+ {'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem, "q", 1, 1},
+ {'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem, "Q", 1, 0},
+#endif
{'f', sizeof(float), f_getitem, f_setitem, "f", 0, 0},
{'d', sizeof(double), d_getitem, d_setitem, "d", 0, 0},
{'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */
@@ -426,11 +483,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
return NULL;
}
- nbytes = size * descr->itemsize;
/* Check for overflow */
- if (nbytes / descr->itemsize != (size_t)size) {
+ if (size > PY_SSIZE_T_MAX / descr->itemsize) {
return PyErr_NoMemory();
}
+ nbytes = size * descr->itemsize;
op = (arrayobject *) type->tp_alloc(type, 0);
if (op == NULL) {
return NULL;
@@ -514,10 +571,8 @@ array_richcompare(PyObject *v, PyObject *w, int op)
Py_ssize_t i, k;
PyObject *res;
- if (!array_Check(v) || !array_Check(w)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
+ if (!array_Check(v) || !array_Check(w))
+ Py_RETURN_NOTIMPLEMENTED;
va = (arrayobject *)v;
wa = (arrayobject *)w;
@@ -876,7 +931,6 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n)
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();
@@ -1191,18 +1245,23 @@ array_fromfile(arrayobject *self, PyObject *args)
PyObject *f, *b, *res;
Py_ssize_t itemsize = self->ob_descr->itemsize;
Py_ssize_t n, nbytes;
+ _Py_IDENTIFIER(read);
int not_enough_bytes;
if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
return NULL;
- nbytes = n * itemsize;
- if (nbytes < 0 || nbytes/itemsize != n) {
+ if (n < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative count");
+ return NULL;
+ }
+ if (n > PY_SSIZE_T_MAX / itemsize) {
PyErr_NoMemory();
return NULL;
}
+ nbytes = n * itemsize;
- b = PyObject_CallMethod(f, "read", "n", nbytes);
+ b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
if (b == NULL)
return NULL;
@@ -1259,12 +1318,14 @@ array_tofile(arrayobject *self, PyObject *f)
char* ptr = self->ob_item + i*BLOCKSIZE;
Py_ssize_t size = BLOCKSIZE;
PyObject *bytes, *res;
+ _Py_IDENTIFIER(write);
+
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);
+ res = _PyObject_CallMethodId(f, &PyId_write, "O", bytes);
Py_DECREF(bytes);
if (res == NULL)
return NULL;
@@ -1456,7 +1517,7 @@ array_fromunicode(arrayobject *self, PyObject *args)
{
Py_UNICODE *ustr;
Py_ssize_t n;
- Py_UNICODE typecode;
+ char typecode;
if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
return NULL;
@@ -1491,7 +1552,7 @@ append Unicode data to an array of some other type.");
static PyObject *
array_tounicode(arrayobject *self, PyObject *unused)
{
- Py_UNICODE typecode;
+ char typecode;
typecode = self->ob_descr->typecode;
if (typecode != 'u') {
PyErr_SetString(PyExc_ValueError,
@@ -1601,7 +1662,7 @@ static const struct mformatdescr {
* be found.
*/
static enum machine_format_code
-typecode_to_mformat_code(int typecode)
+typecode_to_mformat_code(char typecode)
{
#ifdef WORDS_BIGENDIAN
const int is_big_endian = 1;
@@ -1671,6 +1732,16 @@ typecode_to_mformat_code(int typecode)
intsize = sizeof(long);
is_signed = 0;
break;
+#if HAVE_LONG_LONG
+ case 'q':
+ intsize = sizeof(PY_LONG_LONG);
+ is_signed = 1;
+ break;
+ case 'Q':
+ intsize = sizeof(PY_LONG_LONG);
+ is_signed = 0;
+ break;
+#endif
default:
return UNKNOWN_FORMAT;
}
@@ -1701,7 +1772,7 @@ static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
* NULL is returned to indicate a failure.
*/
static PyObject *
-make_array(PyTypeObject *arraytype, Py_UNICODE typecode, PyObject *items)
+make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
{
PyObject *new_args;
PyObject *array_obj;
@@ -1710,7 +1781,7 @@ make_array(PyTypeObject *arraytype, Py_UNICODE typecode, PyObject *items)
assert(arraytype != NULL);
assert(items != NULL);
- typecode_obj = PyUnicode_FromUnicode(&typecode, 1);
+ typecode_obj = PyUnicode_FromOrdinal(typecode);
if (typecode_obj == NULL)
return NULL;
@@ -1740,17 +1811,14 @@ array_reconstructor(PyObject *self, PyObject *args)
PyObject *items;
PyObject *converted_items;
PyObject *result;
- int typecode_int;
- Py_UNICODE typecode;
+ int typecode;
enum machine_format_code mformat_code;
struct arraydescr *descr;
if (!PyArg_ParseTuple(args, "OCiO:array._array_reconstructor",
- &arraytype, &typecode_int, &mformat_code, &items))
+ &arraytype, &typecode, &mformat_code, &items))
return NULL;
- typecode = (Py_UNICODE)typecode_int;
-
if (!PyType_Check(arraytype)) {
PyErr_Format(PyExc_TypeError,
"first argument must a type object, not %.200s",
@@ -1764,7 +1832,7 @@ array_reconstructor(PyObject *self, PyObject *args)
return NULL;
}
for (descr = descriptors; descr->typecode != '\0'; descr++) {
- if (descr->typecode == typecode)
+ if ((int)descr->typecode == typecode)
break;
}
if (descr->typecode == '\0') {
@@ -1786,9 +1854,9 @@ array_reconstructor(PyObject *self, PyObject *args)
}
/* Fast path: No decoding has to be done. */
- if (mformat_code == typecode_to_mformat_code(typecode) ||
+ if (mformat_code == typecode_to_mformat_code((char)typecode) ||
mformat_code == UNKNOWN_FORMAT) {
- return make_array(arraytype, typecode, items);
+ return make_array(arraytype, (char)typecode, items);
}
/* Slow path: Decode the byte string according to the given machine
@@ -1934,7 +2002,7 @@ array_reconstructor(PyObject *self, PyObject *args)
return NULL;
}
- result = make_array(arraytype, typecode, converted_items);
+ result = make_array(arraytype, (char)typecode, converted_items);
Py_DECREF(converted_items);
return result;
}
@@ -1949,14 +2017,16 @@ array_reduce_ex(arrayobject *array, PyObject *value)
int mformat_code;
static PyObject *array_reconstructor = NULL;
long protocol;
+ _Py_IDENTIFIER(_array_reconstructor);
+ _Py_IDENTIFIER(__dict__);
if (array_reconstructor == NULL) {
PyObject *array_module = PyImport_ImportModule("array");
if (array_module == NULL)
return NULL;
- array_reconstructor = PyObject_GetAttrString(
+ array_reconstructor = _PyObject_GetAttrId(
array_module,
- "_array_reconstructor");
+ &PyId__array_reconstructor);
Py_DECREF(array_module);
if (array_reconstructor == NULL)
return NULL;
@@ -1971,7 +2041,7 @@ array_reduce_ex(arrayobject *array, PyObject *value)
if (protocol == -1 && PyErr_Occurred())
return NULL;
- dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
+ dict = _PyObject_GetAttrId((PyObject *)array, &PyId___dict__);
if (dict == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return NULL;
@@ -2023,8 +2093,8 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
static PyObject *
array_get_typecode(arrayobject *a, void *closure)
{
- Py_UNICODE tc = a->ob_descr->typecode;
- return PyUnicode_FromUnicode(&tc, 1);
+ char typecode = a->ob_descr->typecode;
+ return PyUnicode_FromOrdinal(typecode);
}
static PyObject *
@@ -2098,7 +2168,7 @@ static PyMethodDef array_methods[] = {
static PyObject *
array_repr(arrayobject *a)
{
- Py_UNICODE typecode;
+ char typecode;
PyObject *s, *v = NULL;
Py_ssize_t len;
@@ -2303,7 +2373,7 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
self->ob_item + (cur + 1) * itemsize,
lim * itemsize);
}
- cur = start + slicelength * step;
+ cur = start + (size_t)slicelength * step;
if (cur < (size_t)Py_SIZE(self)) {
memmove(self->ob_item + (cur-slicelength) * itemsize,
self->ob_item + cur * itemsize,
@@ -2487,7 +2557,17 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Py_DECREF(v);
}
else if (initial != NULL && PyUnicode_Check(initial)) {
- Py_ssize_t n = PyUnicode_GET_DATA_SIZE(initial);
+ Py_UNICODE *ustr;
+ Py_ssize_t n;
+
+ ustr = PyUnicode_AsUnicode(initial);
+ if (ustr == NULL) {
+ PyErr_NoMemory();
+ Py_DECREF(a);
+ return NULL;
+ }
+
+ n = PyUnicode_GET_DATA_SIZE(initial);
if (n > 0) {
arrayobject *self = (arrayobject *)a;
char *item = self->ob_item;
@@ -2499,7 +2579,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
self->ob_item = item;
Py_SIZE(self) = n / sizeof(Py_UNICODE);
- memcpy(item, PyUnicode_AS_DATA(initial), n);
+ memcpy(item, ustr, n);
self->allocated = Py_SIZE(self);
}
}
@@ -2520,7 +2600,11 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
}
PyErr_SetString(PyExc_ValueError,
+#ifdef HAVE_LONG_LONG
+ "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)");
+#else
"bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)");
+#endif
return NULL;
}
@@ -2543,12 +2627,18 @@ is a single character. The following type codes are defined:\n\
'I' unsigned integer 2 \n\
'l' signed integer 4 \n\
'L' unsigned integer 4 \n\
+ 'q' signed integer 8 (see note) \n\
+ 'Q' unsigned integer 8 (see note) \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\
+NOTE: The 'q' and 'Q' type codes are only available if the platform \n\
+C compiler used to build Python supports 'long long', or, on Windows, \n\
+'__int64'.\n\
+\n\
The constructor is:\n\
\n\
array(typecode [, initializer]) -- create a new array\n\
@@ -2693,6 +2783,34 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
return 0;
}
+static PyObject *
+arrayiter_reduce(arrayiterobject *it)
+{
+ return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
+ it->ao, it->index);
+}
+
+static PyObject *
+arrayiter_setstate(arrayiterobject *it, PyObject *state)
+{
+ Py_ssize_t index = PyLong_AsSsize_t(state);
+ if (index == -1 && PyErr_Occurred())
+ return NULL;
+ if (index < 0)
+ index = 0;
+ it->index = index;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
+static PyMethodDef arrayiter_methods[] = {
+ {"__reduce__", (PyCFunction)arrayiter_reduce, METH_NOARGS,
+ reduce_doc},
+ {"__setstate__", (PyCFunction)arrayiter_setstate, METH_O,
+ setstate_doc},
+ {NULL, NULL} /* sentinel */
+};
+
static PyTypeObject PyArrayIter_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"arrayiterator", /* tp_name */
@@ -2722,7 +2840,7 @@ static PyTypeObject PyArrayIter_Type = {
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)arrayiter_next, /* tp_iternext */
- 0, /* tp_methods */
+ arrayiter_methods, /* tp_methods */
};
@@ -2752,9 +2870,9 @@ PyMODINIT_FUNC
PyInit_array(void)
{
PyObject *m;
+ char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
PyObject *typecodes;
Py_ssize_t size = 0;
- register Py_UNICODE *p;
struct arraydescr *descr;
if (PyType_Ready(&Arraytype) < 0)
@@ -2773,13 +2891,13 @@ PyInit_array(void)
size++;
}
- typecodes = PyUnicode_FromStringAndSize(NULL, size);
- p = PyUnicode_AS_UNICODE(typecodes);
+ p = buffer;
for (descr = descriptors; descr->typecode != '\0'; descr++) {
*p++ = (char)descr->typecode;
}
+ typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
- PyModule_AddObject(m, "typecodes", (PyObject *)typecodes);
+ PyModule_AddObject(m, "typecodes", typecodes);
if (PyErr_Occurred()) {
Py_DECREF(m);