Mercurial > cpython-lru_cache-weakref
comparison Modules/arraymodule.c @ 55259:edc714ffe6cc
Issue #2389: Implement a portable mechanism for pickling array objects.
Reviewed by: Martin v. Löwis
| author | Alexandre Vassalotti <alexandre@peadrop.com> |
|---|---|
| date | Wed, 15 Jul 2009 17:49:23 +0000 |
| parents | 67f5e01d5a6a |
| children | a8922723a92d |
comparison
equal
deleted
inserted
replaced
| 55258:a50eb596a6d3 | 55259:edc714ffe6cc |
|---|---|
| 25 int typecode; | 25 int typecode; |
| 26 int itemsize; | 26 int itemsize; |
| 27 PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); | 27 PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); |
| 28 int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); | 28 int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); |
| 29 char *formats; | 29 char *formats; |
| 30 int is_integer_type; | |
| 31 int is_signed; | |
| 30 }; | 32 }; |
| 31 | 33 |
| 32 typedef struct arrayobject { | 34 typedef struct arrayobject { |
| 33 PyObject_VAR_HEAD | 35 PyObject_VAR_HEAD |
| 34 char *ob_item; | 36 char *ob_item; |
| 387 ((double *)ap->ob_item)[i] = x; | 389 ((double *)ap->ob_item)[i] = x; |
| 388 return 0; | 390 return 0; |
| 389 } | 391 } |
| 390 | 392 |
| 391 | 393 |
| 392 /* Description of types */ | 394 /* Description of types. |
| 395 * | |
| 396 * Don't forget to update typecode_to_mformat_code() if you add a new | |
| 397 * typecode. | |
| 398 */ | |
| 393 static struct arraydescr descriptors[] = { | 399 static struct arraydescr descriptors[] = { |
| 394 {'b', 1, b_getitem, b_setitem, "b"}, | 400 {'b', 1, b_getitem, b_setitem, "b", 1, 1}, |
| 395 {'B', 1, BB_getitem, BB_setitem, "B"}, | 401 {'B', 1, BB_getitem, BB_setitem, "B", 1, 0}, |
| 396 {'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u"}, | 402 {'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u", 0, 0}, |
| 397 {'h', sizeof(short), h_getitem, h_setitem, "h"}, | 403 {'h', sizeof(short), h_getitem, h_setitem, "h", 1, 1}, |
| 398 {'H', sizeof(short), HH_getitem, HH_setitem, "H"}, | 404 {'H', sizeof(short), HH_getitem, HH_setitem, "H", 1, 0}, |
| 399 {'i', sizeof(int), i_getitem, i_setitem, "i"}, | 405 {'i', sizeof(int), i_getitem, i_setitem, "i", 1, 1}, |
| 400 {'I', sizeof(int), II_getitem, II_setitem, "I"}, | 406 {'I', sizeof(int), II_getitem, II_setitem, "I", 1, 0}, |
| 401 {'l', sizeof(long), l_getitem, l_setitem, "l"}, | 407 {'l', sizeof(long), l_getitem, l_setitem, "l", 1, 1}, |
| 402 {'L', sizeof(long), LL_getitem, LL_setitem, "L"}, | 408 {'L', sizeof(long), LL_getitem, LL_setitem, "L", 1, 0}, |
| 403 {'f', sizeof(float), f_getitem, f_setitem, "f"}, | 409 {'f', sizeof(float), f_getitem, f_setitem, "f", 0, 0}, |
| 404 {'d', sizeof(double), d_getitem, d_setitem, "d"}, | 410 {'d', sizeof(double), d_getitem, d_setitem, "d", 0, 0}, |
| 405 {'\0', 0, 0, 0, 0} /* Sentinel */ | 411 {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */ |
| 406 }; | 412 }; |
| 407 | 413 |
| 408 /**************************************************************************** | 414 /**************************************************************************** |
| 409 Implementations of array object methods. | 415 Implementations of array object methods. |
| 410 ****************************************************************************/ | 416 ****************************************************************************/ |
| 1134 \n\ | 1140 \n\ |
| 1135 Byteswap all items of the array. If the items in the array are not 1, 2,\n\ | 1141 Byteswap all items of the array. If the items in the array are not 1, 2,\n\ |
| 1136 4, or 8 bytes in size, RuntimeError is raised."); | 1142 4, or 8 bytes in size, RuntimeError is raised."); |
| 1137 | 1143 |
| 1138 static PyObject * | 1144 static PyObject * |
| 1139 array_reduce(arrayobject *array) | |
| 1140 { | |
| 1141 PyObject *dict, *result; | |
| 1142 | |
| 1143 dict = PyObject_GetAttrString((PyObject *)array, "__dict__"); | |
| 1144 if (dict == NULL) { | |
| 1145 PyErr_Clear(); | |
| 1146 dict = Py_None; | |
| 1147 Py_INCREF(dict); | |
| 1148 } | |
| 1149 if (Py_SIZE(array) > 0) { | |
| 1150 if (array->ob_descr->itemsize | |
| 1151 > PY_SSIZE_T_MAX / Py_SIZE(array)) { | |
| 1152 return PyErr_NoMemory(); | |
| 1153 } | |
| 1154 result = Py_BuildValue("O(Cy#)O", | |
| 1155 Py_TYPE(array), | |
| 1156 array->ob_descr->typecode, | |
| 1157 array->ob_item, | |
| 1158 Py_SIZE(array) * array->ob_descr->itemsize, | |
| 1159 dict); | |
| 1160 } else { | |
| 1161 result = Py_BuildValue("O(C)O", | |
| 1162 Py_TYPE(array), | |
| 1163 array->ob_descr->typecode, | |
| 1164 dict); | |
| 1165 } | |
| 1166 Py_DECREF(dict); | |
| 1167 return result; | |
| 1168 } | |
| 1169 | |
| 1170 PyDoc_STRVAR(array_doc, "Return state information for pickling."); | |
| 1171 | |
| 1172 static PyObject * | |
| 1173 array_reverse(arrayobject *self, PyObject *unused) | 1145 array_reverse(arrayobject *self, PyObject *unused) |
| 1174 { | 1146 { |
| 1175 register Py_ssize_t itemsize = self->ob_descr->itemsize; | 1147 register Py_ssize_t itemsize = self->ob_descr->itemsize; |
| 1176 register char *p, *q; | 1148 register char *p, *q; |
| 1177 /* little buffer to hold items while swapping */ | 1149 /* little buffer to hold items while swapping */ |
| 1472 a unicode type array; otherwise a ValueError is raised. Use\n\ | 1444 a unicode type array; otherwise a ValueError is raised. Use\n\ |
| 1473 array.tostring().decode() to obtain a unicode string from\n\ | 1445 array.tostring().decode() to obtain a unicode string from\n\ |
| 1474 an array of some other type."); | 1446 an array of some other type."); |
| 1475 | 1447 |
| 1476 | 1448 |
| 1449 | |
| 1450 /*********************** Pickling support ************************/ | |
| 1451 | |
| 1452 enum machine_format_code { | |
| 1453 UNKNOWN_FORMAT = -1, | |
| 1454 /* UNKNOWN_FORMAT is used to indicate that the machine format for an | |
| 1455 * array type code cannot be interpreted. When this occurs, a list of | |
| 1456 * Python objects is used to represent the content of the array | |
| 1457 * instead of using the memory content of the array directly. In that | |
| 1458 * case, the array_reconstructor mechanism is bypassed completely, and | |
| 1459 * the standard array constructor is used instead. | |
| 1460 * | |
| 1461 * This is will most likely occur when the machine doesn't use IEEE | |
| 1462 * floating-point numbers. | |
| 1463 */ | |
| 1464 | |
| 1465 UNSIGNED_INT8 = 0, | |
| 1466 SIGNED_INT8 = 1, | |
| 1467 UNSIGNED_INT16_LE = 2, | |
| 1468 UNSIGNED_INT16_BE = 3, | |
| 1469 SIGNED_INT16_LE = 4, | |
| 1470 SIGNED_INT16_BE = 5, | |
| 1471 UNSIGNED_INT32_LE = 6, | |
| 1472 UNSIGNED_INT32_BE = 7, | |
| 1473 SIGNED_INT32_LE = 8, | |
| 1474 SIGNED_INT32_BE = 9, | |
| 1475 UNSIGNED_INT64_LE = 10, | |
| 1476 UNSIGNED_INT64_BE = 11, | |
| 1477 SIGNED_INT64_LE = 12, | |
| 1478 SIGNED_INT64_BE = 13, | |
| 1479 IEEE_754_FLOAT_LE = 14, | |
| 1480 IEEE_754_FLOAT_BE = 15, | |
| 1481 IEEE_754_DOUBLE_LE = 16, | |
| 1482 IEEE_754_DOUBLE_BE = 17, | |
| 1483 UTF16_LE = 18, | |
| 1484 UTF16_BE = 19, | |
| 1485 UTF32_LE = 20, | |
| 1486 UTF32_BE = 21 | |
| 1487 }; | |
| 1488 #define MACHINE_FORMAT_CODE_MIN 0 | |
| 1489 #define MACHINE_FORMAT_CODE_MAX 21 | |
| 1490 | |
| 1491 static const struct mformatdescr { | |
| 1492 size_t size; | |
| 1493 int is_signed; | |
| 1494 int is_big_endian; | |
| 1495 } mformat_descriptors[] = { | |
| 1496 {1, 0, 0}, /* 0: UNSIGNED_INT8 */ | |
| 1497 {1, 1, 0}, /* 1: SIGNED_INT8 */ | |
| 1498 {2, 0, 0}, /* 2: UNSIGNED_INT16_LE */ | |
| 1499 {2, 0, 1}, /* 3: UNSIGNED_INT16_BE */ | |
| 1500 {2, 1, 0}, /* 4: SIGNED_INT16_LE */ | |
| 1501 {2, 1, 1}, /* 5: SIGNED_INT16_BE */ | |
| 1502 {4, 0, 0}, /* 6: UNSIGNED_INT32_LE */ | |
| 1503 {4, 0, 1}, /* 7: UNSIGNED_INT32_BE */ | |
| 1504 {4, 1, 0}, /* 8: SIGNED_INT32_LE */ | |
| 1505 {4, 1, 1}, /* 9: SIGNED_INT32_BE */ | |
| 1506 {8, 0, 0}, /* 10: UNSIGNED_INT64_LE */ | |
| 1507 {8, 0, 1}, /* 11: UNSIGNED_INT64_BE */ | |
| 1508 {8, 1, 0}, /* 12: SIGNED_INT64_LE */ | |
| 1509 {8, 1, 1}, /* 13: SIGNED_INT64_BE */ | |
| 1510 {4, 0, 0}, /* 14: IEEE_754_FLOAT_LE */ | |
| 1511 {4, 0, 1}, /* 15: IEEE_754_FLOAT_BE */ | |
| 1512 {8, 0, 0}, /* 16: IEEE_754_DOUBLE_LE */ | |
| 1513 {8, 0, 1}, /* 17: IEEE_754_DOUBLE_BE */ | |
| 1514 {4, 0, 0}, /* 18: UTF16_LE */ | |
| 1515 {4, 0, 1}, /* 19: UTF16_BE */ | |
| 1516 {8, 0, 0}, /* 20: UTF32_LE */ | |
| 1517 {8, 0, 1} /* 21: UTF32_BE */ | |
| 1518 }; | |
| 1519 | |
| 1520 | |
| 1521 /* | |
| 1522 * Internal: This function is used to find the machine format of a given | |
| 1523 * array type code. This returns UNKNOWN_FORMAT when the machine format cannot | |
| 1524 * be found. | |
| 1525 */ | |
| 1526 static enum machine_format_code | |
| 1527 typecode_to_mformat_code(int typecode) | |
| 1528 { | |
| 1529 #ifdef BYTEORDER_IS_BIG_ENDIAN | |
| 1530 const int is_big_endian = 1; | |
| 1531 #else | |
| 1532 const int is_big_endian = 0; | |
| 1533 #endif | |
| 1534 size_t intsize; | |
| 1535 int is_signed; | |
| 1536 | |
| 1537 switch (typecode) { | |
| 1538 case 'b': | |
| 1539 return SIGNED_INT8; | |
| 1540 case 'B': | |
| 1541 return UNSIGNED_INT8; | |
| 1542 | |
| 1543 case 'u': | |
| 1544 if (sizeof(Py_UNICODE) == 2) { | |
| 1545 return UTF16_LE + is_big_endian; | |
| 1546 } | |
| 1547 if (sizeof(Py_UNICODE) == 4) { | |
| 1548 return UTF32_LE + is_big_endian; | |
| 1549 } | |
| 1550 return UNKNOWN_FORMAT; | |
| 1551 | |
| 1552 case 'f': | |
| 1553 if (sizeof(float) == 4) { | |
| 1554 const float y = 16711938.0; | |
| 1555 if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) | |
| 1556 return IEEE_754_FLOAT_BE; | |
| 1557 if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) | |
| 1558 return IEEE_754_FLOAT_LE; | |
| 1559 } | |
| 1560 return UNKNOWN_FORMAT; | |
| 1561 | |
| 1562 case 'd': | |
| 1563 if (sizeof(double) == 8) { | |
| 1564 const double x = 9006104071832581.0; | |
| 1565 if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) | |
| 1566 return IEEE_754_DOUBLE_BE; | |
| 1567 if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) | |
| 1568 return IEEE_754_DOUBLE_LE; | |
| 1569 } | |
| 1570 return UNKNOWN_FORMAT; | |
| 1571 | |
| 1572 /* Integers */ | |
| 1573 case 'h': | |
| 1574 intsize = sizeof(short); | |
| 1575 is_signed = 1; | |
| 1576 break; | |
| 1577 case 'H': | |
| 1578 intsize = sizeof(short); | |
| 1579 is_signed = 0; | |
| 1580 break; | |
| 1581 case 'i': | |
| 1582 intsize = sizeof(int); | |
| 1583 is_signed = 1; | |
| 1584 break; | |
| 1585 case 'I': | |
| 1586 intsize = sizeof(int); | |
| 1587 is_signed = 0; | |
| 1588 break; | |
| 1589 case 'l': | |
| 1590 intsize = sizeof(long); | |
| 1591 is_signed = 1; | |
| 1592 break; | |
| 1593 case 'L': | |
| 1594 intsize = sizeof(long); | |
| 1595 is_signed = 0; | |
| 1596 break; | |
| 1597 default: | |
| 1598 return UNKNOWN_FORMAT; | |
| 1599 } | |
| 1600 switch (intsize) { | |
| 1601 case 2: | |
| 1602 return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed); | |
| 1603 case 4: | |
| 1604 return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed); | |
| 1605 case 8: | |
| 1606 return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed); | |
| 1607 default: | |
| 1608 return UNKNOWN_FORMAT; | |
| 1609 } | |
| 1610 } | |
| 1611 | |
| 1612 /* Forward declaration. */ | |
| 1613 static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | |
| 1614 | |
| 1615 /* | |
| 1616 * Internal: This function wraps the array constructor--i.e., array_new()--to | |
| 1617 * allow the creation of array objects from C code without having to deal | |
| 1618 * directly the tuple argument of array_new(). The typecode argument is a | |
| 1619 * Unicode character value, like 'i' or 'f' for example, representing an array | |
| 1620 * type code. The items argument is a bytes or a list object from which | |
| 1621 * contains the initial value of the array. | |
| 1622 * | |
| 1623 * On success, this functions returns the array object created. Otherwise, | |
| 1624 * NULL is returned to indicate a failure. | |
| 1625 */ | |
| 1626 static PyObject * | |
| 1627 make_array(PyTypeObject *arraytype, int typecode, PyObject *items) | |
| 1628 { | |
| 1629 PyObject *new_args; | |
| 1630 PyObject *array_obj; | |
| 1631 PyObject *typecode_obj; | |
| 1632 Py_UNICODE typecode_str[1] = {typecode}; | |
| 1633 | |
| 1634 assert(arraytype != NULL); | |
| 1635 assert(items != NULL); | |
| 1636 | |
| 1637 typecode_obj = PyUnicode_FromUnicode(typecode_str, 1); | |
| 1638 if (typecode_obj == NULL) | |
| 1639 return NULL; | |
| 1640 | |
| 1641 new_args = PyTuple_New(2); | |
| 1642 if (new_args == NULL) | |
| 1643 return NULL; | |
| 1644 Py_INCREF(items); | |
| 1645 PyTuple_SET_ITEM(new_args, 0, typecode_obj); | |
| 1646 PyTuple_SET_ITEM(new_args, 1, items); | |
| 1647 | |
| 1648 array_obj = array_new(arraytype, new_args, NULL); | |
| 1649 Py_DECREF(new_args); | |
| 1650 if (array_obj == NULL) | |
| 1651 return NULL; | |
| 1652 | |
| 1653 return array_obj; | |
| 1654 } | |
| 1655 | |
| 1656 /* | |
| 1657 * This functions is a special constructor used when unpickling an array. It | |
| 1658 * provides a portable way to rebuild an array from its memory representation. | |
| 1659 */ | |
| 1660 static PyObject * | |
| 1661 array_reconstructor(PyObject *self, PyObject *args) | |
| 1662 { | |
| 1663 PyTypeObject *arraytype; | |
| 1664 PyObject *items; | |
| 1665 PyObject *converted_items; | |
| 1666 PyObject *result; | |
| 1667 int typecode; | |
| 1668 enum machine_format_code mformat_code; | |
| 1669 struct arraydescr *descr; | |
| 1670 | |
| 1671 if (!PyArg_ParseTuple(args, "OCiO:array._array_reconstructor", | |
| 1672 &arraytype, &typecode, &mformat_code, &items)) | |
| 1673 return NULL; | |
| 1674 | |
| 1675 if (!PyType_Check(arraytype)) { | |
| 1676 PyErr_Format(PyExc_TypeError, | |
| 1677 "first argument must a type object, not %.200s", | |
| 1678 Py_TYPE(arraytype)->tp_name); | |
| 1679 return NULL; | |
| 1680 } | |
| 1681 if (!PyType_IsSubtype(arraytype, &Arraytype)) { | |
| 1682 PyErr_Format(PyExc_TypeError, | |
| 1683 "%.200s is not a subtype of %.200s", | |
| 1684 arraytype->tp_name, Arraytype.tp_name); | |
| 1685 return NULL; | |
| 1686 } | |
| 1687 for (descr = descriptors; descr->typecode != '\0'; descr++) { | |
| 1688 if (descr->typecode == typecode) | |
| 1689 break; | |
| 1690 } | |
| 1691 if (descr->typecode == '\0') { | |
| 1692 PyErr_SetString(PyExc_ValueError, | |
| 1693 "second argument must be a valid type code"); | |
| 1694 return NULL; | |
| 1695 } | |
| 1696 if (mformat_code < MACHINE_FORMAT_CODE_MIN || | |
| 1697 mformat_code > MACHINE_FORMAT_CODE_MAX) { | |
| 1698 PyErr_SetString(PyExc_ValueError, | |
| 1699 "third argument must be a valid machine format code."); | |
| 1700 return NULL; | |
| 1701 } | |
| 1702 if (!PyBytes_Check(items)) { | |
| 1703 PyErr_Format(PyExc_TypeError, | |
| 1704 "fourth argument should be bytes, not %.200s", | |
| 1705 Py_TYPE(items)->tp_name); | |
| 1706 return NULL; | |
| 1707 } | |
| 1708 | |
| 1709 /* Fast path: No decoding has to be done. */ | |
| 1710 if (mformat_code == typecode_to_mformat_code(typecode) || | |
| 1711 mformat_code == UNKNOWN_FORMAT) { | |
| 1712 return make_array(arraytype, typecode, items); | |
| 1713 } | |
| 1714 | |
| 1715 /* Slow path: Decode the byte string according to the given machine | |
| 1716 * format code. This occurs when the computer unpickling the array | |
| 1717 * object is architecturally different from the one that pickled the | |
| 1718 * array. | |
| 1719 */ | |
| 1720 if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) { | |
| 1721 PyErr_SetString(PyExc_ValueError, | |
| 1722 "string length not a multiple of item size"); | |
| 1723 return NULL; | |
| 1724 } | |
| 1725 switch (mformat_code) { | |
| 1726 case IEEE_754_FLOAT_LE: | |
| 1727 case IEEE_754_FLOAT_BE: { | |
| 1728 int i; | |
| 1729 int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; | |
| 1730 Py_ssize_t itemcount = Py_SIZE(items) / 4; | |
| 1731 const unsigned char *memstr = | |
| 1732 (unsigned char *)PyBytes_AS_STRING(items); | |
| 1733 | |
| 1734 converted_items = PyList_New(itemcount); | |
| 1735 if (converted_items == NULL) | |
| 1736 return NULL; | |
| 1737 for (i = 0; i < itemcount; i++) { | |
| 1738 PyObject *pyfloat = PyFloat_FromDouble( | |
| 1739 _PyFloat_Unpack4(&memstr[i * 4], le)); | |
| 1740 if (pyfloat == NULL) { | |
| 1741 Py_DECREF(converted_items); | |
| 1742 return NULL; | |
| 1743 } | |
| 1744 PyList_SET_ITEM(converted_items, i, pyfloat); | |
| 1745 } | |
| 1746 break; | |
| 1747 } | |
| 1748 case IEEE_754_DOUBLE_LE: | |
| 1749 case IEEE_754_DOUBLE_BE: { | |
| 1750 int i; | |
| 1751 int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0; | |
| 1752 Py_ssize_t itemcount = Py_SIZE(items) / 8; | |
| 1753 const unsigned char *memstr = | |
| 1754 (unsigned char *)PyBytes_AS_STRING(items); | |
| 1755 | |
| 1756 converted_items = PyList_New(itemcount); | |
| 1757 if (converted_items == NULL) | |
| 1758 return NULL; | |
| 1759 for (i = 0; i < itemcount; i++) { | |
| 1760 PyObject *pyfloat = PyFloat_FromDouble( | |
| 1761 _PyFloat_Unpack8(&memstr[i * 8], le)); | |
| 1762 if (pyfloat == NULL) { | |
| 1763 Py_DECREF(converted_items); | |
| 1764 return NULL; | |
| 1765 } | |
| 1766 PyList_SET_ITEM(converted_items, i, pyfloat); | |
| 1767 } | |
| 1768 break; | |
| 1769 } | |
| 1770 case UTF16_LE: | |
| 1771 case UTF16_BE: { | |
| 1772 int byteorder = (mformat_code == UTF16_LE) ? -1 : 1; | |
| 1773 converted_items = PyUnicode_DecodeUTF16( | |
| 1774 PyBytes_AS_STRING(items), Py_SIZE(items), | |
| 1775 "strict", &byteorder); | |
| 1776 if (converted_items == NULL) | |
| 1777 return NULL; | |
| 1778 break; | |
| 1779 } | |
| 1780 case UTF32_LE: | |
| 1781 case UTF32_BE: { | |
| 1782 int byteorder = (mformat_code == UTF32_LE) ? -1 : 1; | |
| 1783 converted_items = PyUnicode_DecodeUTF32( | |
| 1784 PyBytes_AS_STRING(items), Py_SIZE(items), | |
| 1785 "strict", &byteorder); | |
| 1786 if (converted_items == NULL) | |
| 1787 return NULL; | |
| 1788 break; | |
| 1789 } | |
| 1790 | |
| 1791 case UNSIGNED_INT8: | |
| 1792 case SIGNED_INT8: | |
| 1793 case UNSIGNED_INT16_LE: | |
| 1794 case UNSIGNED_INT16_BE: | |
| 1795 case SIGNED_INT16_LE: | |
| 1796 case SIGNED_INT16_BE: | |
| 1797 case UNSIGNED_INT32_LE: | |
| 1798 case UNSIGNED_INT32_BE: | |
| 1799 case SIGNED_INT32_LE: | |
| 1800 case SIGNED_INT32_BE: | |
| 1801 case UNSIGNED_INT64_LE: | |
| 1802 case UNSIGNED_INT64_BE: | |
| 1803 case SIGNED_INT64_LE: | |
| 1804 case SIGNED_INT64_BE: { | |
| 1805 int i; | |
| 1806 const struct mformatdescr mf_descr = | |
| 1807 mformat_descriptors[mformat_code]; | |
| 1808 Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; | |
| 1809 const unsigned char *memstr = | |
| 1810 (unsigned char *)PyBytes_AS_STRING(items); | |
| 1811 struct arraydescr *descr; | |
| 1812 | |
| 1813 /* If possible, try to pack array's items using a data type | |
| 1814 * that fits better. This may result in an array with narrower | |
| 1815 * or wider elements. | |
| 1816 * | |
| 1817 * For example, if a 32-bit machine pickles a L-code array of | |
| 1818 * unsigned longs, then the array will be unpickled by 64-bit | |
| 1819 * machine as an I-code array of unsigned ints. | |
| 1820 * | |
| 1821 * XXX: Is it possible to write a unit test for this? | |
| 1822 */ | |
| 1823 for (descr = descriptors; descr->typecode != '\0'; descr++) { | |
| 1824 if (descr->is_integer_type && | |
| 1825 descr->itemsize == mf_descr.size && | |
| 1826 descr->is_signed == mf_descr.is_signed) | |
| 1827 typecode = descr->typecode; | |
| 1828 } | |
| 1829 | |
| 1830 converted_items = PyList_New(itemcount); | |
| 1831 if (converted_items == NULL) | |
| 1832 return NULL; | |
| 1833 for (i = 0; i < itemcount; i++) { | |
| 1834 PyObject *pylong; | |
| 1835 | |
| 1836 pylong = _PyLong_FromByteArray( | |
| 1837 &memstr[i * mf_descr.size], | |
| 1838 mf_descr.size, | |
| 1839 !mf_descr.is_big_endian, | |
| 1840 mf_descr.is_signed); | |
| 1841 if (pylong == NULL) { | |
| 1842 Py_DECREF(converted_items); | |
| 1843 return NULL; | |
| 1844 } | |
| 1845 PyList_SET_ITEM(converted_items, i, pylong); | |
| 1846 } | |
| 1847 break; | |
| 1848 } | |
| 1849 case UNKNOWN_FORMAT: | |
| 1850 /* Impossible, but needed to shut up GCC about the unhandled | |
| 1851 * enumeration value. | |
| 1852 */ | |
| 1853 return NULL; | |
| 1854 } | |
| 1855 | |
| 1856 result = make_array(arraytype, typecode, converted_items); | |
| 1857 Py_DECREF(converted_items); | |
| 1858 return result; | |
| 1859 } | |
| 1860 | |
| 1861 static PyObject * | |
| 1862 array_reduce_ex(arrayobject *array, PyObject *value) | |
| 1863 { | |
| 1864 PyObject *dict; | |
| 1865 PyObject *result; | |
| 1866 PyObject *array_str; | |
| 1867 int typecode = array->ob_descr->typecode; | |
| 1868 int mformat_code; | |
| 1869 static PyObject *array_reconstructor = NULL; | |
| 1870 long protocol; | |
| 1871 | |
| 1872 if (array_reconstructor == NULL) { | |
| 1873 PyObject *array_module = PyImport_ImportModule("array"); | |
| 1874 if (array_module == NULL) | |
| 1875 return NULL; | |
| 1876 array_reconstructor = PyObject_GetAttrString( | |
| 1877 array_module, | |
| 1878 "_array_reconstructor"); | |
| 1879 Py_DECREF(array_module); | |
| 1880 if (array_reconstructor == NULL) | |
| 1881 return NULL; | |
| 1882 } | |
| 1883 | |
| 1884 if (!PyLong_Check(value)) { | |
| 1885 PyErr_SetString(PyExc_TypeError, | |
| 1886 "__reduce_ex__ argument should an integer"); | |
| 1887 return NULL; | |
| 1888 } | |
| 1889 protocol = PyLong_AsLong(value); | |
| 1890 if (protocol == -1 && PyErr_Occurred()) | |
| 1891 return NULL; | |
| 1892 | |
| 1893 dict = PyObject_GetAttrString((PyObject *)array, "__dict__"); | |
| 1894 if (dict == NULL) { | |
| 1895 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) | |
| 1896 return NULL; | |
| 1897 PyErr_Clear(); | |
| 1898 dict = Py_None; | |
| 1899 Py_INCREF(dict); | |
| 1900 } | |
| 1901 | |
| 1902 mformat_code = typecode_to_mformat_code(typecode); | |
| 1903 if (mformat_code == UNKNOWN_FORMAT || protocol < 3) { | |
| 1904 /* Convert the array to a list if we got something weird | |
| 1905 * (e.g., non-IEEE floats), or we are pickling the array using | |
| 1906 * a Python 2.x compatible protocol. | |
| 1907 * | |
| 1908 * It is necessary to a list representation for Python 2.x | |
| 1909 * compatible pickle protocol, since Python 2's str objects | |
| 1910 * are unpickled as unicode by Python 3. Thus it is impossible | |
| 1911 * to make arrays unpicklable by Python 3 by using their memory | |
| 1912 * representation, unless we resort to ugly hacks such as | |
| 1913 * coercing unicode objects to bytes in array_reconstructor. | |
| 1914 */ | |
| 1915 PyObject *list; | |
| 1916 list = array_tolist(array, NULL); | |
| 1917 if (list == NULL) { | |
| 1918 Py_DECREF(dict); | |
| 1919 return NULL; | |
| 1920 } | |
| 1921 result = Py_BuildValue( | |
| 1922 "O(CO)O", Py_TYPE(array), typecode, list, dict); | |
| 1923 Py_DECREF(list); | |
| 1924 Py_DECREF(dict); | |
| 1925 return result; | |
| 1926 } | |
| 1927 | |
| 1928 array_str = array_tostring(array, NULL); | |
| 1929 if (array_str == NULL) { | |
| 1930 Py_DECREF(dict); | |
| 1931 return NULL; | |
| 1932 } | |
| 1933 result = Py_BuildValue( | |
| 1934 "O(OCiN)O", array_reconstructor, Py_TYPE(array), typecode, | |
| 1935 mformat_code, array_str, dict); | |
| 1936 Py_DECREF(dict); | |
| 1937 return result; | |
| 1938 } | |
| 1939 | |
| 1940 PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); | |
| 1477 | 1941 |
| 1478 static PyObject * | 1942 static PyObject * |
| 1479 array_get_typecode(arrayobject *a, void *closure) | 1943 array_get_typecode(arrayobject *a, void *closure) |
| 1480 { | 1944 { |
| 1481 char tc = a->ob_descr->typecode; | 1945 char tc = a->ob_descr->typecode; |
| 1523 index_doc}, | 1987 index_doc}, |
| 1524 {"insert", (PyCFunction)array_insert, METH_VARARGS, | 1988 {"insert", (PyCFunction)array_insert, METH_VARARGS, |
| 1525 insert_doc}, | 1989 insert_doc}, |
| 1526 {"pop", (PyCFunction)array_pop, METH_VARARGS, | 1990 {"pop", (PyCFunction)array_pop, METH_VARARGS, |
| 1527 pop_doc}, | 1991 pop_doc}, |
| 1528 {"__reduce__", (PyCFunction)array_reduce, METH_NOARGS, | 1992 {"__reduce_ex__", (PyCFunction)array_reduce_ex, METH_O, |
| 1529 array_doc}, | 1993 reduce_doc}, |
| 1530 {"remove", (PyCFunction)array_remove, METH_O, | 1994 {"remove", (PyCFunction)array_remove, METH_O, |
| 1531 remove_doc}, | 1995 remove_doc}, |
| 1532 {"reverse", (PyCFunction)array_reverse, METH_NOARGS, | 1996 {"reverse", (PyCFunction)array_reverse, METH_NOARGS, |
| 1533 reverse_doc}, | 1997 reverse_doc}, |
| 1534 /* {"sort", (PyCFunction)array_sort, METH_VARARGS, | 1998 /* {"sort", (PyCFunction)array_sort, METH_VARARGS, |
| 2165 | 2629 |
| 2166 /*********************** Install Module **************************/ | 2630 /*********************** Install Module **************************/ |
| 2167 | 2631 |
| 2168 /* No functions in array module. */ | 2632 /* No functions in array module. */ |
| 2169 static PyMethodDef a_methods[] = { | 2633 static PyMethodDef a_methods[] = { |
| 2634 {"_array_reconstructor", array_reconstructor, METH_VARARGS, | |
| 2635 PyDoc_STR("Internal. Used for pickling support.")}, | |
| 2170 {NULL, NULL, 0, NULL} /* Sentinel */ | 2636 {NULL, NULL, 0, NULL} /* Sentinel */ |
| 2171 }; | 2637 }; |
| 2172 | 2638 |
| 2173 static struct PyModuleDef arraymodule = { | 2639 static struct PyModuleDef arraymodule = { |
| 2174 PyModuleDef_HEAD_INIT, | 2640 PyModuleDef_HEAD_INIT, |
