Implement portable array pickling. - Code Review (original) (raw)
OLD
NEW
1 /* Array object implementation */
1 /* Array object implementation */
2
2
3 /* An array is a uniform list -- all items have the same type.
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 */
4 The item type is restricted to simple C types like int or float */
5
5
6 #define PY_SSIZE_T_CLEAN
6 #define PY_SSIZE_T_CLEAN
7 #include "Python.h"
7 #include "Python.h"
8 #include "structmember.h"
8 #include "structmember.h"
9
9
10 #ifdef STDC_HEADERS
10 #ifdef STDC_HEADERS
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
382 d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
382 d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
383 {
383 {
384 double x;
384 double x;
385 if (!PyArg_Parse(v, "d;array item must be float", &x))
385 if (!PyArg_Parse(v, "d;array item must be float", &x))
386 return -1;
386 return -1;
387 if (i >= 0)
387 if (i >= 0)
388 ((double *)ap->ob_item)[i] = x;
388 ((double *)ap->ob_item)[i] = x;
389 return 0;
389 return 0;
390 }
390 }
391
391
392 /* Description of types */
392 /* Description of types.
393 Don't forget to update allowed_typecode in array_reduce() and·
394 typecode_to_mformat_code() if you add a new typecode.
395 */
393 static struct arraydescr descriptors[] = {
396 static struct arraydescr descriptors[] = {
394 {'c', sizeof(char), c_getitem, c_setitem},
397 {'c', sizeof(char), c_getitem, c_setitem},
395 {'b', sizeof(char), b_getitem, b_setitem},
398 {'b', sizeof(char), b_getitem, b_setitem},
396 {'B', sizeof(char), BB_getitem, BB_setitem},
399 {'B', sizeof(char), BB_getitem, BB_setitem},
397 #ifdef Py_USING_UNICODE
400 #ifdef Py_USING_UNICODE
398 {'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
401 {'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
399 #endif
402 #endif
400 {'h', sizeof(short), h_getitem, h_setitem},
403 {'h', sizeof(short), h_getitem, h_setitem},
401 {'H', sizeof(short), HH_getitem, HH_setitem},
404 {'H', sizeof(short), HH_getitem, HH_setitem},
402 {'i', sizeof(int), i_getitem, i_setitem},
405 {'i', sizeof(int), i_getitem, i_setitem},
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
619 ihigh = Py_SIZE(a);
622 ihigh = Py_SIZE(a);
620 np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_desc r);
623 np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_desc r);
621 if (np == NULL)
624 if (np == NULL)
622 return NULL;
625 return NULL;
623 memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
626 memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
624 (ihigh-ilow) * a->ob_descr->itemsize);
627 (ihigh-ilow) * a->ob_descr->itemsize);
625 return (PyObject *)np;
628 return (PyObject *)np;
626 }
629 }
627
630
628 static PyObject *
631 static PyObject *
629 array_copy(arrayobject *a, PyObject *unused)
632 array_copy(arrayobject *a)
630 {
633 {
631 return array_slice(a, 0, Py_SIZE(a));
634 return array_slice(a, 0, Py_SIZE(a));
632 }
635 }
633
636
634 PyDoc_STRVAR(copy_doc,
637 PyDoc_STRVAR(copy_doc,
635 "copy(array)\n\
638 "copy(array)\n\
636 \n\
639 \n\
637 Return a copy of the array.");
640 Return a copy of the array.");
638
641
639 static PyObject *
642 static PyObject *
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
1046 PyDoc_STRVAR(extend_doc,
1049 PyDoc_STRVAR(extend_doc,
1047 "extend(array or iterable)\n\
1050 "extend(array or iterable)\n\
1048 \n\
1051 \n\
1049 Append items to the end of the array.");
1052 Append items to the end of the array.");
1050
1053
1051 static PyObject *
1054 static PyObject *
1052 array_insert(arrayobject *self, PyObject *args)
1055 array_insert(arrayobject *self, PyObject *args)
1053 {
1056 {
1054 Py_ssize_t i;
1057 Py_ssize_t i;
1055 PyObject *v;
1058 PyObject *v;
1059
1056 if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
1060 if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
1057 return NULL;
1061 return NULL;
1058 return ins(self, i, v);
1062 return ins(self, i, v);
1059 }
1063 }
1060
1064
1061 PyDoc_STRVAR(insert_doc,
1065 PyDoc_STRVAR(insert_doc,
1062 "insert(i,x)\n\
1066 "insert(i,x)\n\
1063 \n\
1067 \n\
1064 Insert a new item x into the array before position i.");
1068 Insert a new item x into the array before position i.");
1065
1069
1066
1070
1067 static PyObject *
1071 static PyObject *
1068 array_buffer_info(arrayobject *self, PyObject *unused)
1072 array_buffer_info(arrayobject *self)
1069 {
1073 {
1070 PyObject* retval = NULL;
1074 PyObject* retval = NULL;
1071 retval = PyTuple_New(2);
1075 retval = PyTuple_New(2);
1072 if (!retval)
1076 if (!retval)
1073 return NULL;
1077 return NULL;
1074
1078
1075 PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
1079 PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
1076 PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(Py_SIZE(self))));
1080 PyTuple_SET_ITEM(retval, 1, PyInt_FromLong((long)(Py_SIZE(self))));
1077
1081
1078 return retval;
1082 return retval;
(...skipping 14 matching lines...) Expand all Loading...
1093 return ins(self, (int) Py_SIZE(self), v);
1097 return ins(self, (int) Py_SIZE(self), v);
1094 }
1098 }
1095
1099
1096 PyDoc_STRVAR(append_doc,
1100 PyDoc_STRVAR(append_doc,
1097 "append(x)\n\
1101 "append(x)\n\
1098 \n\
1102 \n\
1099 Append new value x to the end of the array.");
1103 Append new value x to the end of the array.");
1100
1104
1101
1105
1102 static PyObject *
1106 static PyObject *
1103 array_byteswap(arrayobject *self, PyObject *unused)
1107 array_byteswap(arrayobject *self)
1104 {
1108 {
1105 char *p;
1109 char *p;
1106 Py_ssize_t i;
1110 Py_ssize_t i;
1107
1111
1108 switch (self->ob_descr->itemsize) {
1112 switch (self->ob_descr->itemsize) {
1109 case 1:
1113 case 1:
1110 break;
1114 break;
1111 case 2:
1115 case 2:
1112 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
1116 for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
1113 char p0 = p[0];
1117 char p0 = p[0];
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
1150 return Py_None;
1154 return Py_None;
1151 }
1155 }
1152
1156
1153 PyDoc_STRVAR(byteswap_doc,
1157 PyDoc_STRVAR(byteswap_doc,
1154 "byteswap()\n\
1158 "byteswap()\n\
1155 \n\
1159 \n\
1156 Byteswap all items of the array. If the items in the array are not 1, 2,\n\
1160 Byteswap all items of the array. If the items in the array are not 1, 2,\n\
1157 4, or 8 bytes in size, RuntimeError is raised.");
1161 4, or 8 bytes in size, RuntimeError is raised.");
1158
1162
1159 static PyObject *
1163 static PyObject *
1160 array_reduce(arrayobject *array)
1164 array_reverse(arrayobject *self)
1161 {
1162 » PyObject *dict, *result;
1163
1164 » dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
1165 » if (dict == NULL) {
1166 » » PyErr_Clear();
1167 » » dict = Py_None;
1168 » » Py_INCREF(dict);
1169 » }
1170 » if (Py_SIZE(array) > 0) {
1171 » » if (array->ob_descr->itemsize·
1172 » » » » > PY_SSIZE_T_MAX / array->ob_size) {
1173 » » » return PyErr_NoMemory();
1174 » » }
1175 » » result = Py_BuildValue("O(cs#)O",·
1176 » » » Py_TYPE(array),·
1177 » » » array->ob_descr->typecode,
1178 » » » array->ob_item,
1179 » » » Py_SIZE(array) * array->ob_descr->itemsize,
1180 » » » dict);
1181 » } else {
1182 » » result = Py_BuildValue("O(c)O",·
1183 » » » Py_TYPE(array),·
1184 » » » array->ob_descr->typecode,
1185 » » » dict);
1186 » }
1187 » Py_DECREF(dict);
1188 » return result;
1189 }
1190
1191 PyDoc_STRVAR(array_doc, "Return state information for pickling.");
1192
1193 static PyObject *
1194 array_reverse(arrayobject *self, PyObject *unused)
1195 {
1165 {
1196 register Py_ssize_t itemsize = self->ob_descr->itemsize;
1166 register Py_ssize_t itemsize = self->ob_descr->itemsize;
1197 register char *p, *q;
1167 register char *p, *q;
1198 /* little buffer to hold items while swapping */
1168 /* little buffer to hold items while swapping */
1199 char tmp[256]; /* 8 is probably enough -- but why skimp */
1169 char tmp[256]; /* 8 is probably enough -- but why skimp */
1200 assert((size_t)itemsize <= sizeof(tmp));
1170 assert((size_t)itemsize <= sizeof(tmp));
1201
1171
1202 if (Py_SIZE(self) > 1) {
1172 if (Py_SIZE(self) > 1) {
1203 for (p = self->ob_item,
1173 for (p = self->ob_item,
1204 q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
1174 q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
1369 return Py_None;
1339 return Py_None;
1370 }
1340 }
1371
1341
1372 PyDoc_STRVAR(fromlist_doc,
1342 PyDoc_STRVAR(fromlist_doc,
1373 "fromlist(list)\n\
1343 "fromlist(list)\n\
1374 \n\
1344 \n\
1375 Append items to array from list.");
1345 Append items to array from list.");
1376
1346
1377
1347
1378 static PyObject *
1348 static PyObject *
1379 array_tolist(arrayobject *self, PyObject *unused)
1349 array_tolist(arrayobject *self)
1380 {
1350 {
1381 PyObject *list = PyList_New(Py_SIZE(self));
1351 PyObject *list = PyList_New(Py_SIZE(self));
1382 Py_ssize_t i;
1352 Py_ssize_t i;
1383
1353
1384 if (list == NULL)
1354 if (list == NULL)
1385 return NULL;
1355 return NULL;
1386 for (i = 0; i < Py_SIZE(self); i++) {
1356 for (i = 0; i < Py_SIZE(self); i++) {
1387 PyObject *v = getarrayitem((PyObject *)self, i);
1357 PyObject *v = getarrayitem((PyObject *)self, i);
1388 if (v == NULL) {
1358 if (v == NULL) {
1389 Py_DECREF(list);
1359 Py_DECREF(list);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
1436 }
1406 }
1437
1407
1438 PyDoc_STRVAR(fromstring_doc,
1408 PyDoc_STRVAR(fromstring_doc,
1439 "fromstring(string)\n\
1409 "fromstring(string)\n\
1440 \n\
1410 \n\
1441 Appends items from the string, interpreting it as an array of machine\n\
1411 Appends items from the string, interpreting it as an array of machine\n\
1442 values,as if it had been read from a file using the fromfile() method).");
1412 values,as if it had been read from a file using the fromfile() method).");
1443
1413
1444
1414
1445 static PyObject *
1415 static PyObject *
1446 array_tostring(arrayobject *self, PyObject *unused)
1416 array_tostring(arrayobject *self)
1447 {
1417 {
1448 if (self->ob_size <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
1418 if (self->ob_size <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
1449 return PyString_FromStringAndSize(self->ob_item,
1419 return PyString_FromStringAndSize(self->ob_item,
1450 Py_SIZE(self) * self->ob_descr->itemsize);
1420 Py_SIZE(self) * self->ob_descr->itemsize);
1451 } else {
1421 } else {
1452 return PyErr_NoMemory();
1422 return PyErr_NoMemory();
1453 }
1423 }
1454 }
1424 }
1455
1425
1456 PyDoc_STRVAR(tostring_doc,
1426 PyDoc_STRVAR(tostring_doc,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
1500 PyDoc_STRVAR(fromunicode_doc,
1470 PyDoc_STRVAR(fromunicode_doc,
1501 "fromunicode(ustr)\n\
1471 "fromunicode(ustr)\n\
1502 \n\
1472 \n\
1503 Extends this array with data from the unicode string ustr.\n\
1473 Extends this array with data from the unicode string ustr.\n\
1504 The array must be a type 'u' array; otherwise a ValueError\n\
1474 The array must be a type 'u' array; otherwise a ValueError\n\
1505 is raised. Use array.fromstring(ustr.decode(...)) to\n\
1475 is raised. Use array.fromstring(ustr.decode(...)) to\n\
1506 append Unicode data to an array of some other type.");
1476 append Unicode data to an array of some other type.");
1507
1477
1508
1478
1509 static PyObject *
1479 static PyObject *
1510 array_tounicode(arrayobject *self, PyObject *unused)
1480 array_tounicode(arrayobject *self)
1511 {
1481 {
1512 if (self->ob_descr->typecode != 'u') {
1482 if (self->ob_descr->typecode != 'u') {
1513 PyErr_SetString(PyExc_ValueError,
1483 PyErr_SetString(PyExc_ValueError,
1514 "tounicode() may only be called on type 'u' arrays");
1484 "tounicode() may only be called on type 'u' arrays");
1515 return NULL;
1485 return NULL;
1516 }
1486 }
1517 return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self) );
1487 return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self) );
1518 }
1488 }
1519
1489
1520 PyDoc_STRVAR(tounicode_doc,
1490 PyDoc_STRVAR(tounicode_doc,
1521 "tounicode() -> unicode\n\
1491 "tounicode() -> unicode\n\
1522 \n\
1492 \n\
1523 Convert the array to a unicode string. The array must be\n\
1493 Convert the array to a unicode string. The array must be\n\
1524 a type 'u' array; otherwise a ValueError is raised. Use\n\
1494 a type 'u' array; otherwise a ValueError is raised. Use\n\
1525 array.tostring().decode() to obtain a unicode string from\n\
1495 array.tostring().decode() to obtain a unicode string from\n\
1526 an array of some other type.");
1496 an array of some other type.");
1527
1497
1528 #endif /* Py_USING_UNICODE */
1498 #endif /* Py_USING_UNICODE */
1529
1499
1530
1500
1501 /*********************** Pickling support ************************/
1502
1503 enum machine_format_code {
1504 UNKNOWN_FORMAT = -1,
1505 CHARACTER = 0,
1506 UNSIGNED_INT8 = 1,
1507 SIGNED_INT8 = 2,
1508 UNSIGNED_INT16_LE = 3,
1509 UNSIGNED_INT16_BE = 4,
1510 SIGNED_INT16_LE = 5,
1511 SIGNED_INT16_BE = 6,
1512 UNSIGNED_INT32_LE = 7,
1513 UNSIGNED_INT32_BE = 8,
1514 SIGNED_INT32_LE = 9,
1515 SIGNED_INT32_BE = 10,
1516 UNSIGNED_INT64_LE = 11,
1517 UNSIGNED_INT64_BE = 12,
1518 SIGNED_INT64_LE = 13,
1519 SIGNED_INT64_BE = 14,
1520 IEEE_754_FLOAT_LE = 15,
1521 IEEE_754_FLOAT_BE = 16,
1522 IEEE_754_DOUBLE_LE = 17,
1523 IEEE_754_DOUBLE_BE = 18,
1524 UTF16_LE = 19,
1525 UTF16_BE = 20,
1526 UTF32_LE = 21,
1527 UTF32_BE = 22
1528 };
1529 #define MACHINE_FORMAT_CODE_MIN -1
1530 #define MACHINE_FORMAT_CODE_MAX 22
1531
1532 static const struct {
1533 size_t size;
1534 int is_signed;
1535 int is_big_endian;
1536 } mformat_descriptors[] = {
1537 {1, 1, 0}, /* 0: CHARACTER */
1538 {1, 0, 0}, /* 1: UNSIGNED_INT8 */
1539 {1, 1, 0}, /* 2: SIGNED_INT8 */
1540 {2, 0, 0}, /* 3: UNSIGNED_INT16_LE */
1541 {2, 0, 1}, /* 4: UNSIGNED_INT16_BE */
1542 {2, 1, 0}, /* 5: SIGNED_INT16_LE */
1543 {2, 1, 1}, /* 6: SIGNED_INT16_BE */
1544 {4, 0, 0}, /* 7: UNSIGNED_INT32_LE */
1545 {4, 0, 1}, /* 8: UNSIGNED_INT32_BE */
1546 {4, 1, 0}, /* 9: SIGNED_INT32_LE */
1547 {4, 1, 1}, /* 10: SIGNED_INT32_BE */
1548 {8, 0, 0}, /* 11: UNSIGNED_INT64_LE */
1549 {8, 0, 1}, /* 12: UNSIGNED_INT64_BE */
1550 {8, 1, 0}, /* 13: SIGNED_INT64_LE */
1551 {8, 1, 1}, /* 14: SIGNED_INT64_BE */
1552 {4, 0, 0}, /* 15: IEEE_754_FLOAT_LE */
1553 {4, 0, 1}, /* 16: IEEE_754_FLOAT_BE */
1554 {8, 0, 0}, /* 17: IEEE_754_DOUBLE_LE */
1555 {8, 0, 1}, /* 18: IEEE_754_DOUBLE_BE */
1556 {4, 0, 0}, /* 19: UTF16_LE */
1557 {4, 0, 1}, /* 20: UTF16_BE */
1558 {8, 0, 0}, /* 21: UTF32_LE */
1559 {8, 0, 1} /* 22: UTF32_BE */
1560 };
1561
1562 static enum machine_format_code
1563 typecode_to_mformat_code(int typecode)
1564 {
1565 #ifdef BYTEORDER_IS_BIG_ENDIAN
1566 const int is_big_endian = 1;
1567 #else
1568 const int is_big_endian = 0;
1569 #endif
1570 size_t intsize;
1571 int is_signed;
1572
1573 switch (typecode) {
1574 case 'c':
1575 return CHARACTER;
1576 case 'b':
1577 return SIGNED_INT8;
1578 case 'B':
1579 return UNSIGNED_INT8;
1580
1581 #ifdef Py_USING_UNICODE
1582 case 'u':
1583 if (sizeof(Py_UNICODE) == 2) {
1584 return UTF16_LE + is_big_endian;
1585 }
1586 if (sizeof(Py_UNICODE) == 4) {
1587 return UTF32_LE + is_big_endian;
1588 }
1589 return UNKNOWN_FORMAT;
1590 #endif
1591 case 'f':
1592 if (sizeof(float) == 4) {
1593 const float y = 16711938.0;
1594 if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
1595 return IEEE_754_FLOAT_BE;
1596 if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
1597 return IEEE_754_FLOAT_LE;
1598 }
1599 return UNKNOWN_FORMAT;
1600
1601 case 'd':
1602 if (sizeof(double) == 8) {
1603 const double x = 9006104071832581.0;
1604 if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
1605 return IEEE_754_DOUBLE_BE;
1606 if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
1607 return IEEE_754_DOUBLE_LE;
1608 }
1609 return UNKNOWN_FORMAT;
1610
1611 /* Integers */
1612 case 'h':
1613 intsize = sizeof(short);
1614 is_signed = 1;
1615 break;
1616 case 'H':
1617 intsize = sizeof(short);
1618 is_signed = 0;
1619 break;
1620 case 'i':
1621 intsize = sizeof(int);
1622 is_signed = 1;
1623 break;
1624 case 'I':
1625 intsize = sizeof(int);
1626 is_signed = 0;
1627 break;
1628 case 'l':
1629 intsize = sizeof(long);
1630 is_signed = 1;
1631 break;
1632 case 'L':
1633 intsize = sizeof(long);
1634 is_signed = 0;
1635 break;
1636 default:
1637 return UNKNOWN_FORMAT;
1638 }
1639 switch (intsize) {
1640 case 2:
1641 return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed);
1642 case 4:
1643 return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed);
1644 case 8:
1645 return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed);
1646 default:
1647 return UNKNOWN_FORMAT;
1648 }
1649 }
1650
1651 /* Forward declaration. */
1652 static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
1653
1654 static PyObject *
1655 make_array(PyTypeObject *arraytype, int typecode, PyObject *items)
1656 {
1657 PyObject *new_args;
1658 PyObject *array_obj;
1659 PyObject *typecode_obj;
1660
1661 assert(arraytype != NULL);
1662 assert(items != NULL);
1663
1664 typecode_obj = PyString_FromStringAndSize((char *)&typecode, 1);
1665 if (typecode_obj == NULL)
1666 return NULL;
1667
1668 new_args = PyTuple_New(2);
1669 if (new_args == NULL)
1670 return NULL;
1671 Py_INCREF(items);
1672 PyTuple_SET_ITEM(new_args, 0, typecode_obj);
1673 PyTuple_SET_ITEM(new_args, 1, items);
1674
1675 array_obj = array_new(arraytype, new_args, NULL);
1676 Py_DECREF(new_args);
1677 if (array_obj == NULL)
1678 return NULL;
1679
1680 return array_obj;
1681 }
1682
1683 static PyObject *
1684 array_reconstructor(PyObject *self, PyObject *args)
1685 {
1686 PyTypeObject *arraytype;
1687 PyObject *items;
1688 PyObject *converted_items;
1689 PyObject *result;
1690 int typecode;
1691 enum machine_format_code mformat_code;
1692 const char allowed_typecode[] = "cbBuhHiIlLfd";
1693
1694 if (!PyArg_ParseTuple(args, "OciO:array._array_reconstructor",
1695 &arraytype, &typecode, &mformat_code, &items))
1696 return NULL;
1697
1698 if (!PyType_Check(arraytype)) {
1699 PyErr_Format(PyExc_TypeError,
1700 "first argument must a type object, not %.200s",
1701 Py_TYPE(arraytype)->tp_name);
1702 return NULL;
1703 }
1704 if (!PyType_IsSubtype(arraytype, &Arraytype)) {
1705 PyErr_Format(PyExc_TypeError,
1706 "%.200s is not a subtype of %.200s",
1707 arraytype->tp_name, Arraytype.tp_name);
1708 return NULL;
1709 }
1710 if (strchr(allowed_typecode, typecode) == NULL) {
1711 PyErr_SetString(PyExc_ValueError,
1712 "second argument must be a valid typecode");
1713 return NULL;
1714 }
1715 if (mformat_code < MACHINE_FORMAT_CODE_MIN ||
1716 mformat_code > MACHINE_FORMAT_CODE_MAX) {
1717 PyErr_SetString(PyExc_ValueError,
1718 "third argument must be a valid machine format code.");
1719 return NULL;
1720 }
1721 if (mformat_code != UNKNOWN_FORMAT && !PyString_Check(items)) {
1722 PyErr_Format(PyExc_TypeError,
1723 "fourth argument should be bytes, not %.200s",
1724 Py_TYPE(items)->tp_name);
1725 return NULL;
1726 }
1727
1728 /* Fast path: No decoding has to be done or items is a list */
1729 if (mformat_code == typecode_to_mformat_code(typecode) ||
1730 mformat_code == UNKNOWN_FORMAT || mformat_code == CHARACTER) {
1731 return make_array(arraytype, typecode, items);
1732 }
1733
1734 /* Slow path: Decode the byte string according to the given machine
1735 format code. This occurs when the computer unpickling the array·
1736 object is architecturally different from the one that pickled the
1737 array. */
1738
1739 if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) {
1740 PyErr_SetString(PyExc_ValueError,
1741 "string length not a multiple of item size");
1742 return NULL;
1743 }
1744 switch (mformat_code) {
1745 case IEEE_754_FLOAT_LE:
1746 case IEEE_754_FLOAT_BE: {
1747 int i;
1748 int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
1749 Py_ssize_t itemcount = Py_SIZE(items) / 4;
1750 const unsigned char *memstr = \
1751 (unsigned char *)PyString_AS_STRING(items);
1752
1753 converted_items = PyList_New(itemcount);
1754 if (converted_items == NULL)
1755 return NULL;
1756 for (i = 0; i < itemcount; i++) {
1757 PyObject *pyfloat = PyFloat_FromDouble(
1758 _PyFloat_Unpack4(&memstr[i * 4], le));
1759 if (pyfloat == NULL)
1760 return NULL;
1761 PyList_SET_ITEM(converted_items, i, pyfloat);
1762 }
1763 break;
1764 }
1765 case IEEE_754_DOUBLE_LE:
1766 case IEEE_754_DOUBLE_BE: {
1767 int i;
1768 int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0;
1769 Py_ssize_t itemcount = Py_SIZE(items) / 8;
1770 const unsigned char *memstr = \
1771 (unsigned char *)PyString_AS_STRING(items);
1772
1773 converted_items = PyList_New(itemcount);
1774 if (converted_items == NULL)
1775 return NULL;
1776 for (i = 0; i < itemcount; i++) {
1777 PyObject *pyfloat = PyFloat_FromDouble(
1778 _PyFloat_Unpack8(&memstr[i * 8], le));
1779 if (pyfloat == NULL)
1780 return NULL;
1781 PyList_SET_ITEM(converted_items, i, pyfloat);
1782 }
1783 break;
1784 }
1785 case UTF16_LE:
1786 case UTF16_BE: {
1787 int byteorder = (mformat_code == UTF16_LE) ? -1 : 1;
1788 converted_items = PyUnicode_DecodeUTF16(
1789 PyString_AS_STRING(items), Py_SIZE(items),
1790 "strict", &byteorder);
1791 if (converted_items == NULL)
1792 return NULL;
1793 break;
1794 }
1795 case UTF32_LE:
1796 case UTF32_BE: {
1797 int byteorder = (mformat_code == UTF32_LE) ? -1 : 1;
1798 converted_items = PyUnicode_DecodeUTF32(
1799 PyString_AS_STRING(items), Py_SIZE(items),
1800 "strict", &byteorder);
1801 if (converted_items == NULL)
1802 return NULL;
1803 break;
1804 }
1805
1806 case UNSIGNED_INT8:
1807 case SIGNED_INT8:
1808 case UNSIGNED_INT16_LE:
1809 case UNSIGNED_INT16_BE:
1810 case SIGNED_INT16_LE:
1811 case SIGNED_INT16_BE:
1812 case UNSIGNED_INT32_LE:
1813 case UNSIGNED_INT32_BE:
1814 case SIGNED_INT32_LE:
1815 case SIGNED_INT32_BE:
1816 case UNSIGNED_INT64_LE:
1817 case UNSIGNED_INT64_BE:
1818 case SIGNED_INT64_LE:
1819 case SIGNED_INT64_BE: {
1820 int i;
1821 const int width = mformat_descriptors[mformat_code].size;
1822 Py_ssize_t itemcount = Py_SIZE(items) / width;
1823 const unsigned char *memstr = \
1824 (unsigned char *)PyString_AS_STRING(items);
1825
1826 converted_items = PyList_New(itemcount);
1827 if (converted_items == NULL)
1828 return NULL;
1829 for (i = 0; i < itemcount; i++) {
1830 PyObject *pylong;
1831
1832 pylong = _PyLong_FromByteArray(
1833 &memstr[i * width],
1834 width,
1835 !mformat_descriptors[mformat_code].is_big_endian ,
1836 mformat_descriptors[mformat_code].is_signed);
1837 if (pylong == NULL)
1838 return NULL;
1839 PyList_SET_ITEM(converted_items, i, pylong);
1840 }
1841 break;
1842 }
1843 case CHARACTER:
1844 case UNKNOWN_FORMAT:
1845 /* Impossible, but needed to shut up GCC about the unhandled
1846 enumeration value.*/
1847 return NULL;
1848 }
1849
1850 result = make_array(arraytype, typecode, converted_items);
1851 Py_DECREF(converted_items);
1852 return result;
1853 }
1854
1855 static PyObject *
1856 array_reduce(arrayobject *array)
1857 {
1858 PyObject *dict;
1859 PyObject *result;
1860 PyObject *array_str;
1861 int typecode = array->ob_descr->typecode;
1862 int mformat_code;
1863 static PyObject *array_reconstructor = NULL;
1864
1865 if (array_reconstructor == NULL) {
1866 PyObject *array_module = PyImport_ImportModule("array");
1867 if (array_module == NULL)
1868 return NULL;
1869 array_reconstructor = PyObject_GetAttrString(
1870 array_module,
1871 "_array_reconstructor");
1872 Py_DECREF(array_module);
1873 if (array_reconstructor == NULL)
1874 return NULL;
1875 }
1876
1877 dict = PyObject_GetAttrString((PyObject *)array, "__dict__");
1878 if (dict == NULL) {
1879 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
1880 return NULL;
1881 PyErr_Clear();
1882 dict = Py_None;
1883 Py_INCREF(dict);
1884 }
1885
1886 mformat_code = typecode_to_mformat_code(typecode);
1887 if (mformat_code == UNKNOWN_FORMAT) {
1888 /* We got something wierd; so convert the array to a list
1889 to get a platform-independent representation. */
1890 PyObject *list;
1891 list = array_tolist(array);
1892 if (list == NULL)
1893 return NULL;
1894 result = Py_BuildValue("O(cO)O",
1895 Py_TYPE(array),
1896 typecode,
1897 list,
1898 dict);
1899 Py_DECREF(list);
1900 Py_DECREF(dict);
1901 return result;
1902 }
1903
1904 array_str = array_tostring(array);
1905 if (array == NULL)
1906 return NULL;
1907 result = Py_BuildValue("O(OciN)O", array_reconstructor, Py_TYPE(array),
1908 typecode, mformat_code, array_str, dict);
1909 Py_DECREF(dict);
1910 return result;
1911 }
1912
1913 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
1914
1531 static PyObject *
1915 static PyObject *
1532 array_get_typecode(arrayobject *a, void *closure)
1916 array_get_typecode(arrayobject *a, void *closure)
1533 {
1917 {
1534 char tc = a->ob_descr->typecode;
1918 char tc = a->ob_descr->typecode;
1535 return PyString_FromStringAndSize(&tc, 1);
1919 return PyString_FromStringAndSize(&tc, 1);
1536 }
1920 }
1537
1921
1538 static PyObject *
1922 static PyObject *
1539 array_get_itemsize(arrayobject *a, void *closure)
1923 array_get_itemsize(arrayobject *a, void *closure)
1540 {
1924 {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
1576 #endif
1960 #endif
1577 {"index", (PyCFunction)array_index, METH_O,
1961 {"index", (PyCFunction)array_index, METH_O,
1578 index_doc},
1962 index_doc},
1579 {"insert", (PyCFunction)array_insert, METH_VARARGS,
1963 {"insert", (PyCFunction)array_insert, METH_VARARGS,
1580 insert_doc},
1964 insert_doc},
1581 {"pop", (PyCFunction)array_pop, METH_VARARGS,
1965 {"pop", (PyCFunction)array_pop, METH_VARARGS,
1582 pop_doc},
1966 pop_doc},
1583 {"read", (PyCFunction)array_fromfile_as_read, METH_VARARGS,
1967 {"read", (PyCFunction)array_fromfile_as_read, METH_VARARGS,
1584 fromfile_doc},
1968 fromfile_doc},
1585 {"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
1969 {"__reduce__", (PyCFunction)array_reduce, METH_NOARGS,
1586 » array_doc},
1970 » reduce_doc},
1587 {"remove", (PyCFunction)array_remove, METH_O,
1971 {"remove", (PyCFunction)array_remove, METH_O,
1588 remove_doc},
1972 remove_doc},
1589 {"reverse", (PyCFunction)array_reverse, METH_NOARGS,
1973 {"reverse", (PyCFunction)array_reverse, METH_NOARGS,
1590 reverse_doc},
1974 reverse_doc},
1591 /* {"sort", (PyCFunction)array_sort, METH_VARARGS,
1975 /* {"sort", (PyCFunction)array_sort, METH_VARARGS,
1592 sort_doc},*/
1976 sort_doc},*/
1593 {"tofile", (PyCFunction)array_tofile, METH_O,
1977 {"tofile", (PyCFunction)array_tofile, METH_O,
1594 tofile_doc},
1978 tofile_doc},
1595 {"tolist", (PyCFunction)array_tolist, METH_NOARGS,
1979 {"tolist", (PyCFunction)array_tolist, METH_NOARGS,
1596 tolist_doc},
1980 tolist_doc},
(...skipping 16 matching lines...) Expand all Loading...
1613 Py_ssize_t len;
1997 Py_ssize_t len;
1614
1998
1615 len = Py_SIZE(a);
1999 len = Py_SIZE(a);
1616 typecode = a->ob_descr->typecode;
2000 typecode = a->ob_descr->typecode;
1617 if (len == 0) {
2001 if (len == 0) {
1618 PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
2002 PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
1619 return PyString_FromString(buf);
2003 return PyString_FromString(buf);
1620 }
2004 }
1621 ················
2005 ················
1622 if (typecode == 'c')
2006 if (typecode == 'c')
1623 » » v = array_tostring(a, NULL);
2007 » » v = array_tostring(a);
1624 #ifdef Py_USING_UNICODE
2008 #ifdef Py_USING_UNICODE
1625 else if (typecode == 'u')
2009 else if (typecode == 'u')
1626 » » v = array_tounicode(a, NULL);
2010 » » v = array_tounicode(a);
1627 #endif
2011 #endif
1628 else
2012 else
1629 » » v = array_tolist(a, NULL);
2013 » » v = array_tolist(a);
1630 t = PyObject_Repr(v);
2014 t = PyObject_Repr(v);
1631 Py_XDECREF(v);
2015 Py_XDECREF(v);
1632
2016
1633 PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode);
2017 PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode);
1634 s = PyString_FromString(buf);
2018 s = PyString_FromString(buf);
1635 PyString_ConcatAndDel(&s, t);
2019 PyString_ConcatAndDel(&s, t);
1636 PyString_ConcatAndDel(&s, PyString_FromString(")"));
2020 PyString_ConcatAndDel(&s, PyString_FromString(")"));
1637 return s;
2021 return s;
1638 }
2022 }
1639
2023
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading...
2207 (traverseproc)arrayiter_traverse, /* tp_traverse */
2591 (traverseproc)arrayiter_traverse, /* tp_traverse */
2208 0, /* tp_clear */
2592 0, /* tp_clear */
2209 0, /* tp_richcompare */
2593 0, /* tp_richcompare */
2210 0, /* tp_weaklistoffset */
2594 0, /* tp_weaklistoffset */
2211 PyObject_SelfIter, /* tp_iter */
2595 PyObject_SelfIter, /* tp_iter */
2212 (iternextfunc)arrayiter_next, /* tp_iternext */
2596 (iternextfunc)arrayiter_next, /* tp_iternext */
2213 0, /* tp_methods */
2597 0, /* tp_methods */
2214 };
2598 };
2215
2599
2216
2600
2601
2217 /*********************** Install Module **************************/
2602 /*********************** Install Module **************************/
2218
2603
2219 /* No functions in array module. */
2220 static PyMethodDef a_methods[] = {
2604 static PyMethodDef a_methods[] = {
2221 {NULL, NULL, 0, NULL} /* Sentinel */
2605 » {"_array_reconstructor", array_reconstructor, METH_VARARGS,·
2606 » PyDoc_STR("Internal. Used for pickling support.")},
2607 » {NULL, NULL, 0, NULL} /* Sentinel */
2222 };
2608 };
2223
2609
2224
2225 PyMODINIT_FUNC
2610 PyMODINIT_FUNC
2226 initarray(void)
2611 initarray(void)
2227 {
2612 {
2228 PyObject *m;
2613 PyObject *m;
2229
2614
2230 Arraytype.ob_type = &PyType_Type;
2615 Arraytype.ob_type = &PyType_Type;
2231 PyArrayIter_Type.ob_type = &PyType_Type;
2616 PyArrayIter_Type.ob_type = &PyType_Type;
2232 m = Py_InitModule3("array", a_methods, module_doc);
2617 m = Py_InitModule3("array", a_methods, module_doc);
2233 if (m == NULL)
2618 if (m == NULL)
2234 return;
2619 return;
2235
2620
2236 Py_INCREF((PyObject *)&Arraytype);
2621 Py_INCREF((PyObject *)&Arraytype);
2237 PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
2622 PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
2238 Py_INCREF((PyObject *)&Arraytype);
2623 Py_INCREF((PyObject *)&Arraytype);
2239 PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
2624 PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
2240 /* No need to check the error here, the caller will do that */
2625 /* No need to check the error here, the caller will do that */
2241 }
2626 }
OLD
NEW