LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules - arraymodule.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 141 1255 11.2 %
Date: 2012-12-17 Functions: 16 88 18.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Array object implementation */
       2             : 
       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 */
       5             : 
       6             : #define PY_SSIZE_T_CLEAN
       7             : #include "Python.h"
       8             : #include "structmember.h"
       9             : 
      10             : #ifdef STDC_HEADERS
      11             : #include <stddef.h>
      12             : #else /* !STDC_HEADERS */
      13             : #ifdef HAVE_SYS_TYPES_H
      14             : #include <sys/types.h>          /* For size_t */
      15             : #endif /* HAVE_SYS_TYPES_H */
      16             : #endif /* !STDC_HEADERS */
      17             : 
      18             : struct arrayobject; /* Forward */
      19             : 
      20             : /* All possible arraydescr values are defined in the vector "descriptors"
      21             :  * below.  That's defined later because the appropriate get and set
      22             :  * functions aren't visible yet.
      23             :  */
      24             : struct arraydescr {
      25             :     char typecode;
      26             :     int itemsize;
      27             :     PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
      28             :     int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
      29             :     char *formats;
      30             :     int is_integer_type;
      31             :     int is_signed;
      32             : };
      33             : 
      34             : typedef struct arrayobject {
      35             :     PyObject_VAR_HEAD
      36             :     char *ob_item;
      37             :     Py_ssize_t allocated;
      38             :     struct arraydescr *ob_descr;
      39             :     PyObject *weakreflist; /* List of weak references */
      40             :     int ob_exports;  /* Number of exported buffers */
      41             : } arrayobject;
      42             : 
      43             : static PyTypeObject Arraytype;
      44             : 
      45             : #define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
      46             : #define array_CheckExact(op) (Py_TYPE(op) == &Arraytype)
      47             : 
      48             : static int
      49          43 : array_resize(arrayobject *self, Py_ssize_t newsize)
      50             : {
      51             :     char *items;
      52             :     size_t _new_size;
      53             : 
      54          43 :     if (self->ob_exports > 0 && newsize != Py_SIZE(self)) {
      55           0 :         PyErr_SetString(PyExc_BufferError,
      56             :             "cannot resize an array that is exporting buffers");
      57           0 :         return -1;
      58             :     }
      59             : 
      60             :     /* Bypass realloc() when a previous overallocation is large enough
      61             :        to accommodate the newsize.  If the newsize is 16 smaller than the
      62             :        current size, then proceed with the realloc() to shrink the array.
      63             :     */
      64             : 
      65          43 :     if (self->allocated >= newsize &&
      66           0 :         Py_SIZE(self) < newsize + 16 &&
      67           0 :         self->ob_item != NULL) {
      68           0 :         Py_SIZE(self) = newsize;
      69           0 :         return 0;
      70             :     }
      71             : 
      72          43 :     if (newsize == 0) {
      73           0 :         PyMem_FREE(self->ob_item);
      74           0 :         self->ob_item = NULL;
      75           0 :         Py_SIZE(self) = 0;
      76           0 :         self->allocated = 0;
      77           0 :         return 0;
      78             :     }
      79             : 
      80             :     /* This over-allocates proportional to the array size, making room
      81             :      * for additional growth.  The over-allocation is mild, but is
      82             :      * enough to give linear-time amortized behavior over a long
      83             :      * sequence of appends() in the presence of a poorly-performing
      84             :      * system realloc().
      85             :      * The growth pattern is:  0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ...
      86             :      * Note, the pattern starts out the same as for lists but then
      87             :      * grows at a smaller rate so that larger arrays only overallocate
      88             :      * by about 1/16th -- this is done because arrays are presumed to be more
      89             :      * memory critical.
      90             :      */
      91             : 
      92          43 :     _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
      93          43 :     items = self->ob_item;
      94             :     /* XXX The following multiplication and division does not optimize away
      95             :        like it does for lists since the size is not known at compile time */
      96          43 :     if (_new_size <= ((~(size_t)0) / self->ob_descr->itemsize))
      97          43 :         PyMem_RESIZE(items, char, (_new_size * self->ob_descr->itemsize));
      98             :     else
      99           0 :         items = NULL;
     100          43 :     if (items == NULL) {
     101           0 :         PyErr_NoMemory();
     102           0 :         return -1;
     103             :     }
     104          43 :     self->ob_item = items;
     105          43 :     Py_SIZE(self) = newsize;
     106          43 :     self->allocated = _new_size;
     107          43 :     return 0;
     108             : }
     109             : 
     110             : /****************************************************************************
     111             : Get and Set functions for each type.
     112             : A Get function takes an arrayobject* and an integer index, returning the
     113             : array value at that index wrapped in an appropriate PyObject*.
     114             : A Set function takes an arrayobject, integer index, and PyObject*; sets
     115             : the array value at that index to the raw C data extracted from the PyObject*,
     116             : and returns 0 if successful, else nonzero on failure (PyObject* not of an
     117             : appropriate type or value).
     118             : Note that the basic Get and Set functions do NOT check that the index is
     119             : in bounds; that's the responsibility of the caller.
     120             : ****************************************************************************/
     121             : 
     122             : static PyObject *
     123           0 : b_getitem(arrayobject *ap, Py_ssize_t i)
     124             : {
     125           0 :     long x = ((char *)ap->ob_item)[i];
     126           0 :     if (x >= 128)
     127           0 :         x -= 256;
     128           0 :     return PyLong_FromLong(x);
     129             : }
     130             : 
     131             : static int
     132       11008 : b_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     133             : {
     134             :     short x;
     135             :     /* PyArg_Parse's 'b' formatter is for an unsigned char, therefore
     136             :        must use the next size up that is signed ('h') and manually do
     137             :        the overflow checking */
     138       11008 :     if (!PyArg_Parse(v, "h;array item must be integer", &x))
     139           0 :         return -1;
     140       11008 :     else if (x < -128) {
     141           0 :         PyErr_SetString(PyExc_OverflowError,
     142             :             "signed char is less than minimum");
     143           0 :         return -1;
     144             :     }
     145       11008 :     else if (x > 127) {
     146           0 :         PyErr_SetString(PyExc_OverflowError,
     147             :             "signed char is greater than maximum");
     148           0 :         return -1;
     149             :     }
     150       11008 :     if (i >= 0)
     151       11008 :         ((char *)ap->ob_item)[i] = (char)x;
     152       11008 :     return 0;
     153             : }
     154             : 
     155             : static PyObject *
     156           0 : BB_getitem(arrayobject *ap, Py_ssize_t i)
     157             : {
     158           0 :     long x = ((unsigned char *)ap->ob_item)[i];
     159           0 :     return PyLong_FromLong(x);
     160             : }
     161             : 
     162             : static int
     163           0 : BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     164             : {
     165             :     unsigned char x;
     166             :     /* 'B' == unsigned char, maps to PyArg_Parse's 'b' formatter */
     167           0 :     if (!PyArg_Parse(v, "b;array item must be integer", &x))
     168           0 :         return -1;
     169           0 :     if (i >= 0)
     170           0 :         ((char *)ap->ob_item)[i] = x;
     171           0 :     return 0;
     172             : }
     173             : 
     174             : static PyObject *
     175           0 : u_getitem(arrayobject *ap, Py_ssize_t i)
     176             : {
     177           0 :     return PyUnicode_FromUnicode(&((Py_UNICODE *) ap->ob_item)[i], 1);
     178             : }
     179             : 
     180             : static int
     181           0 : u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     182             : {
     183             :     Py_UNICODE *p;
     184             :     Py_ssize_t len;
     185             : 
     186           0 :     if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
     187           0 :         return -1;
     188           0 :     if (len != 1) {
     189           0 :         PyErr_SetString(PyExc_TypeError,
     190             :                         "array item must be unicode character");
     191           0 :         return -1;
     192             :     }
     193           0 :     if (i >= 0)
     194           0 :         ((Py_UNICODE *)ap->ob_item)[i] = p[0];
     195           0 :     return 0;
     196             : }
     197             : 
     198             : 
     199             : static PyObject *
     200           0 : h_getitem(arrayobject *ap, Py_ssize_t i)
     201             : {
     202           0 :     return PyLong_FromLong((long) ((short *)ap->ob_item)[i]);
     203             : }
     204             : 
     205             : 
     206             : static int
     207           0 : h_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     208             : {
     209             :     short x;
     210             :     /* 'h' == signed short, maps to PyArg_Parse's 'h' formatter */
     211           0 :     if (!PyArg_Parse(v, "h;array item must be integer", &x))
     212           0 :         return -1;
     213           0 :     if (i >= 0)
     214           0 :                  ((short *)ap->ob_item)[i] = x;
     215           0 :     return 0;
     216             : }
     217             : 
     218             : static PyObject *
     219           0 : HH_getitem(arrayobject *ap, Py_ssize_t i)
     220             : {
     221           0 :     return PyLong_FromLong((long) ((unsigned short *)ap->ob_item)[i]);
     222             : }
     223             : 
     224             : static int
     225           0 : HH_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     226             : {
     227             :     int x;
     228             :     /* PyArg_Parse's 'h' formatter is for a signed short, therefore
     229             :        must use the next size up and manually do the overflow checking */
     230           0 :     if (!PyArg_Parse(v, "i;array item must be integer", &x))
     231           0 :         return -1;
     232           0 :     else if (x < 0) {
     233           0 :         PyErr_SetString(PyExc_OverflowError,
     234             :             "unsigned short is less than minimum");
     235           0 :         return -1;
     236             :     }
     237           0 :     else if (x > USHRT_MAX) {
     238           0 :         PyErr_SetString(PyExc_OverflowError,
     239             :             "unsigned short is greater than maximum");
     240           0 :         return -1;
     241             :     }
     242           0 :     if (i >= 0)
     243           0 :         ((short *)ap->ob_item)[i] = (short)x;
     244           0 :     return 0;
     245             : }
     246             : 
     247             : static PyObject *
     248           0 : i_getitem(arrayobject *ap, Py_ssize_t i)
     249             : {
     250           0 :     return PyLong_FromLong((long) ((int *)ap->ob_item)[i]);
     251             : }
     252             : 
     253             : static int
     254           0 : i_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     255             : {
     256             :     int x;
     257             :     /* 'i' == signed int, maps to PyArg_Parse's 'i' formatter */
     258           0 :     if (!PyArg_Parse(v, "i;array item must be integer", &x))
     259           0 :         return -1;
     260           0 :     if (i >= 0)
     261           0 :                  ((int *)ap->ob_item)[i] = x;
     262           0 :     return 0;
     263             : }
     264             : 
     265             : static PyObject *
     266        2752 : II_getitem(arrayobject *ap, Py_ssize_t i)
     267             : {
     268        2752 :     return PyLong_FromUnsignedLong(
     269        2752 :         (unsigned long) ((unsigned int *)ap->ob_item)[i]);
     270             : }
     271             : 
     272             : static int
     273           0 : II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     274             : {
     275             :     unsigned long x;
     276           0 :     if (PyLong_Check(v)) {
     277           0 :         x = PyLong_AsUnsignedLong(v);
     278           0 :         if (x == (unsigned long) -1 && PyErr_Occurred())
     279           0 :             return -1;
     280             :     }
     281             :     else {
     282             :         long y;
     283           0 :         if (!PyArg_Parse(v, "l;array item must be integer", &y))
     284           0 :             return -1;
     285           0 :         if (y < 0) {
     286           0 :             PyErr_SetString(PyExc_OverflowError,
     287             :                 "unsigned int is less than minimum");
     288           0 :             return -1;
     289             :         }
     290           0 :         x = (unsigned long)y;
     291             : 
     292             :     }
     293             :     if (x > UINT_MAX) {
     294             :         PyErr_SetString(PyExc_OverflowError,
     295             :             "unsigned int is greater than maximum");
     296             :         return -1;
     297             :     }
     298             : 
     299           0 :     if (i >= 0)
     300           0 :         ((unsigned int *)ap->ob_item)[i] = (unsigned int)x;
     301           0 :     return 0;
     302             : }
     303             : 
     304             : static PyObject *
     305           0 : l_getitem(arrayobject *ap, Py_ssize_t i)
     306             : {
     307           0 :     return PyLong_FromLong(((long *)ap->ob_item)[i]);
     308             : }
     309             : 
     310             : static int
     311           0 : l_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     312             : {
     313             :     long x;
     314           0 :     if (!PyArg_Parse(v, "l;array item must be integer", &x))
     315           0 :         return -1;
     316           0 :     if (i >= 0)
     317           0 :                  ((long *)ap->ob_item)[i] = x;
     318           0 :     return 0;
     319             : }
     320             : 
     321             : static PyObject *
     322           0 : LL_getitem(arrayobject *ap, Py_ssize_t i)
     323             : {
     324           0 :     return PyLong_FromUnsignedLong(((unsigned long *)ap->ob_item)[i]);
     325             : }
     326             : 
     327             : static int
     328           0 : LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     329             : {
     330             :     unsigned long x;
     331           0 :     if (PyLong_Check(v)) {
     332           0 :         x = PyLong_AsUnsignedLong(v);
     333           0 :         if (x == (unsigned long) -1 && PyErr_Occurred())
     334           0 :             return -1;
     335             :     }
     336             :     else {
     337             :         long y;
     338           0 :         if (!PyArg_Parse(v, "l;array item must be integer", &y))
     339           0 :             return -1;
     340           0 :         if (y < 0) {
     341           0 :             PyErr_SetString(PyExc_OverflowError,
     342             :                 "unsigned long is less than minimum");
     343           0 :             return -1;
     344             :         }
     345           0 :         x = (unsigned long)y;
     346             : 
     347             :     }
     348             :     if (x > ULONG_MAX) {
     349             :         PyErr_SetString(PyExc_OverflowError,
     350             :             "unsigned long is greater than maximum");
     351             :         return -1;
     352             :     }
     353             : 
     354           0 :     if (i >= 0)
     355           0 :         ((unsigned long *)ap->ob_item)[i] = x;
     356           0 :     return 0;
     357             : }
     358             : 
     359             : #ifdef HAVE_LONG_LONG
     360             : 
     361             : static PyObject *
     362           0 : q_getitem(arrayobject *ap, Py_ssize_t i)
     363             : {
     364           0 :     return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]);
     365             : }
     366             : 
     367             : static int
     368           0 : q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     369             : {
     370             :     PY_LONG_LONG x;
     371           0 :     if (!PyArg_Parse(v, "L;array item must be integer", &x))
     372           0 :         return -1;
     373           0 :     if (i >= 0)
     374           0 :         ((PY_LONG_LONG *)ap->ob_item)[i] = x;
     375           0 :     return 0;
     376             : }
     377             : 
     378             : static PyObject *
     379           0 : QQ_getitem(arrayobject *ap, Py_ssize_t i)
     380             : {
     381           0 :     return PyLong_FromUnsignedLongLong(
     382           0 :         ((unsigned PY_LONG_LONG *)ap->ob_item)[i]);
     383             : }
     384             : 
     385             : static int
     386           0 : QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     387             : {
     388             :     unsigned PY_LONG_LONG x;
     389           0 :     if (PyLong_Check(v)) {
     390           0 :         x = PyLong_AsUnsignedLongLong(v);
     391           0 :         if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred())
     392           0 :             return -1;
     393             :     }
     394             :     else {
     395             :         PY_LONG_LONG y;
     396           0 :         if (!PyArg_Parse(v, "L;array item must be integer", &y))
     397           0 :             return -1;
     398           0 :         if (y < 0) {
     399           0 :             PyErr_SetString(PyExc_OverflowError,
     400             :                 "unsigned long long is less than minimum");
     401           0 :             return -1;
     402             :         }
     403           0 :         x = (unsigned PY_LONG_LONG)y;
     404             :     }
     405             : 
     406           0 :     if (i >= 0)
     407           0 :         ((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x;
     408           0 :     return 0;
     409             : }
     410             : #endif
     411             : 
     412             : static PyObject *
     413           0 : f_getitem(arrayobject *ap, Py_ssize_t i)
     414             : {
     415           0 :     return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]);
     416             : }
     417             : 
     418             : static int
     419           0 : f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     420             : {
     421             :     float x;
     422           0 :     if (!PyArg_Parse(v, "f;array item must be float", &x))
     423           0 :         return -1;
     424           0 :     if (i >= 0)
     425           0 :                  ((float *)ap->ob_item)[i] = x;
     426           0 :     return 0;
     427             : }
     428             : 
     429             : static PyObject *
     430           0 : d_getitem(arrayobject *ap, Py_ssize_t i)
     431             : {
     432           0 :     return PyFloat_FromDouble(((double *)ap->ob_item)[i]);
     433             : }
     434             : 
     435             : static int
     436           0 : d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     437             : {
     438             :     double x;
     439           0 :     if (!PyArg_Parse(v, "d;array item must be float", &x))
     440           0 :         return -1;
     441           0 :     if (i >= 0)
     442           0 :                  ((double *)ap->ob_item)[i] = x;
     443           0 :     return 0;
     444             : }
     445             : 
     446             : 
     447             : /* Description of types.
     448             :  *
     449             :  * Don't forget to update typecode_to_mformat_code() if you add a new
     450             :  * typecode.
     451             :  */
     452             : static struct arraydescr descriptors[] = {
     453             :     {'b', 1, b_getitem, b_setitem, "b", 1, 1},
     454             :     {'B', 1, BB_getitem, BB_setitem, "B", 1, 0},
     455             :     {'u', sizeof(Py_UNICODE), u_getitem, u_setitem, "u", 0, 0},
     456             :     {'h', sizeof(short), h_getitem, h_setitem, "h", 1, 1},
     457             :     {'H', sizeof(short), HH_getitem, HH_setitem, "H", 1, 0},
     458             :     {'i', sizeof(int), i_getitem, i_setitem, "i", 1, 1},
     459             :     {'I', sizeof(int), II_getitem, II_setitem, "I", 1, 0},
     460             :     {'l', sizeof(long), l_getitem, l_setitem, "l", 1, 1},
     461             :     {'L', sizeof(long), LL_getitem, LL_setitem, "L", 1, 0},
     462             : #ifdef HAVE_LONG_LONG
     463             :     {'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem, "q", 1, 1},
     464             :     {'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem, "Q", 1, 0},
     465             : #endif
     466             :     {'f', sizeof(float), f_getitem, f_setitem, "f", 0, 0},
     467             :     {'d', sizeof(double), d_getitem, d_setitem, "d", 0, 0},
     468             :     {'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */
     469             : };
     470             : 
     471             : /****************************************************************************
     472             : Implementations of array object methods.
     473             : ****************************************************************************/
     474             : 
     475             : static PyObject *
     476          86 : newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
     477             : {
     478             :     arrayobject *op;
     479             :     size_t nbytes;
     480             : 
     481          86 :     if (size < 0) {
     482           0 :         PyErr_BadInternalCall();
     483           0 :         return NULL;
     484             :     }
     485             : 
     486          86 :     nbytes = size * descr->itemsize;
     487             :     /* Check for overflow */
     488          86 :     if (nbytes / descr->itemsize != (size_t)size) {
     489           0 :         return PyErr_NoMemory();
     490             :     }
     491          86 :     op = (arrayobject *) type->tp_alloc(type, 0);
     492          86 :     if (op == NULL) {
     493           0 :         return NULL;
     494             :     }
     495          86 :     op->ob_descr = descr;
     496          86 :     op->allocated = size;
     497          86 :     op->weakreflist = NULL;
     498          86 :     Py_SIZE(op) = size;
     499          86 :     if (size <= 0) {
     500          43 :         op->ob_item = NULL;
     501             :     }
     502             :     else {
     503          43 :         op->ob_item = PyMem_NEW(char, nbytes);
     504          43 :         if (op->ob_item == NULL) {
     505           0 :             Py_DECREF(op);
     506           0 :             return PyErr_NoMemory();
     507             :         }
     508             :     }
     509          86 :     op->ob_exports = 0;
     510          86 :     return (PyObject *) op;
     511             : }
     512             : 
     513             : static PyObject *
     514        2752 : getarrayitem(PyObject *op, Py_ssize_t i)
     515             : {
     516             :     register arrayobject *ap;
     517             :     assert(array_Check(op));
     518        2752 :     ap = (arrayobject *)op;
     519             :     assert(i>=0 && i<Py_SIZE(ap));
     520        2752 :     return (*ap->ob_descr->getitem)(ap, i);
     521             : }
     522             : 
     523             : static int
     524           0 : ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
     525             : {
     526             :     char *items;
     527           0 :     Py_ssize_t n = Py_SIZE(self);
     528           0 :     if (v == NULL) {
     529           0 :         PyErr_BadInternalCall();
     530           0 :         return -1;
     531             :     }
     532           0 :     if ((*self->ob_descr->setitem)(self, -1, v) < 0)
     533           0 :         return -1;
     534             : 
     535           0 :     if (array_resize(self, n+1) == -1)
     536           0 :         return -1;
     537           0 :     items = self->ob_item;
     538           0 :     if (where < 0) {
     539           0 :         where += n;
     540           0 :         if (where < 0)
     541           0 :             where = 0;
     542             :     }
     543           0 :     if (where > n)
     544           0 :         where = n;
     545             :     /* appends don't need to call memmove() */
     546           0 :     if (where != n)
     547           0 :         memmove(items + (where+1)*self->ob_descr->itemsize,
     548           0 :             items + where*self->ob_descr->itemsize,
     549           0 :             (n-where)*self->ob_descr->itemsize);
     550           0 :     return (*self->ob_descr->setitem)(self, where, v);
     551             : }
     552             : 
     553             : /* Methods */
     554             : 
     555             : static void
     556          86 : array_dealloc(arrayobject *op)
     557             : {
     558          86 :     if (op->weakreflist != NULL)
     559           0 :         PyObject_ClearWeakRefs((PyObject *) op);
     560          86 :     if (op->ob_item != NULL)
     561          86 :         PyMem_DEL(op->ob_item);
     562          86 :     Py_TYPE(op)->tp_free((PyObject *)op);
     563          86 : }
     564             : 
     565             : static PyObject *
     566           0 : array_richcompare(PyObject *v, PyObject *w, int op)
     567             : {
     568             :     arrayobject *va, *wa;
     569           0 :     PyObject *vi = NULL;
     570           0 :     PyObject *wi = NULL;
     571             :     Py_ssize_t i, k;
     572             :     PyObject *res;
     573             : 
     574           0 :     if (!array_Check(v) || !array_Check(w))
     575           0 :         Py_RETURN_NOTIMPLEMENTED;
     576             : 
     577           0 :     va = (arrayobject *)v;
     578           0 :     wa = (arrayobject *)w;
     579             : 
     580           0 :     if (Py_SIZE(va) != Py_SIZE(wa) && (op == Py_EQ || op == Py_NE)) {
     581             :         /* Shortcut: if the lengths differ, the arrays differ */
     582           0 :         if (op == Py_EQ)
     583           0 :             res = Py_False;
     584             :         else
     585           0 :             res = Py_True;
     586           0 :         Py_INCREF(res);
     587           0 :         return res;
     588             :     }
     589             : 
     590             :     /* Search for the first index where items are different */
     591           0 :     k = 1;
     592           0 :     for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) {
     593           0 :         vi = getarrayitem(v, i);
     594           0 :         wi = getarrayitem(w, i);
     595           0 :         if (vi == NULL || wi == NULL) {
     596           0 :             Py_XDECREF(vi);
     597           0 :             Py_XDECREF(wi);
     598           0 :             return NULL;
     599             :         }
     600           0 :         k = PyObject_RichCompareBool(vi, wi, Py_EQ);
     601           0 :         if (k == 0)
     602           0 :             break; /* Keeping vi and wi alive! */
     603           0 :         Py_DECREF(vi);
     604           0 :         Py_DECREF(wi);
     605           0 :         if (k < 0)
     606           0 :             return NULL;
     607             :     }
     608             : 
     609           0 :     if (k) {
     610             :         /* No more items to compare -- compare sizes */
     611           0 :         Py_ssize_t vs = Py_SIZE(va);
     612           0 :         Py_ssize_t ws = Py_SIZE(wa);
     613             :         int cmp;
     614           0 :         switch (op) {
     615           0 :         case Py_LT: cmp = vs <  ws; break;
     616           0 :         case Py_LE: cmp = vs <= ws; break;
     617           0 :         case Py_EQ: cmp = vs == ws; break;
     618           0 :         case Py_NE: cmp = vs != ws; break;
     619           0 :         case Py_GT: cmp = vs >  ws; break;
     620           0 :         case Py_GE: cmp = vs >= ws; break;
     621           0 :         default: return NULL; /* cannot happen */
     622             :         }
     623           0 :         if (cmp)
     624           0 :             res = Py_True;
     625             :         else
     626           0 :             res = Py_False;
     627           0 :         Py_INCREF(res);
     628           0 :         return res;
     629             :     }
     630             : 
     631             :     /* We have an item that differs.  First, shortcuts for EQ/NE */
     632           0 :     if (op == Py_EQ) {
     633           0 :         Py_INCREF(Py_False);
     634           0 :         res = Py_False;
     635             :     }
     636           0 :     else if (op == Py_NE) {
     637           0 :         Py_INCREF(Py_True);
     638           0 :         res = Py_True;
     639             :     }
     640             :     else {
     641             :         /* Compare the final item again using the proper operator */
     642           0 :         res = PyObject_RichCompare(vi, wi, op);
     643             :     }
     644           0 :     Py_DECREF(vi);
     645           0 :     Py_DECREF(wi);
     646           0 :     return res;
     647             : }
     648             : 
     649             : static Py_ssize_t
     650          43 : array_length(arrayobject *a)
     651             : {
     652          43 :     return Py_SIZE(a);
     653             : }
     654             : 
     655             : static PyObject *
     656           0 : array_item(arrayobject *a, Py_ssize_t i)
     657             : {
     658           0 :     if (i < 0 || i >= Py_SIZE(a)) {
     659           0 :         PyErr_SetString(PyExc_IndexError, "array index out of range");
     660           0 :         return NULL;
     661             :     }
     662           0 :     return getarrayitem((PyObject *)a, i);
     663             : }
     664             : 
     665             : static PyObject *
     666           0 : array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
     667             : {
     668             :     arrayobject *np;
     669           0 :     if (ilow < 0)
     670           0 :         ilow = 0;
     671           0 :     else if (ilow > Py_SIZE(a))
     672           0 :         ilow = Py_SIZE(a);
     673           0 :     if (ihigh < 0)
     674           0 :         ihigh = 0;
     675           0 :     if (ihigh < ilow)
     676           0 :         ihigh = ilow;
     677           0 :     else if (ihigh > Py_SIZE(a))
     678           0 :         ihigh = Py_SIZE(a);
     679           0 :     np = (arrayobject *) newarrayobject(&Arraytype, ihigh - ilow, a->ob_descr);
     680           0 :     if (np == NULL)
     681           0 :         return NULL;
     682           0 :     memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
     683           0 :            (ihigh-ilow) * a->ob_descr->itemsize);
     684           0 :     return (PyObject *)np;
     685             : }
     686             : 
     687             : static PyObject *
     688           0 : array_copy(arrayobject *a, PyObject *unused)
     689             : {
     690           0 :     return array_slice(a, 0, Py_SIZE(a));
     691             : }
     692             : 
     693             : PyDoc_STRVAR(copy_doc,
     694             : "copy(array)\n\
     695             : \n\
     696             :  Return a copy of the array.");
     697             : 
     698             : static PyObject *
     699           0 : array_concat(arrayobject *a, PyObject *bb)
     700             : {
     701             :     Py_ssize_t size;
     702             :     arrayobject *np;
     703           0 :     if (!array_Check(bb)) {
     704           0 :         PyErr_Format(PyExc_TypeError,
     705             :              "can only append array (not \"%.200s\") to array",
     706           0 :                  Py_TYPE(bb)->tp_name);
     707           0 :         return NULL;
     708             :     }
     709             : #define b ((arrayobject *)bb)
     710           0 :     if (a->ob_descr != b->ob_descr) {
     711           0 :         PyErr_BadArgument();
     712           0 :         return NULL;
     713             :     }
     714           0 :     if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
     715           0 :         return PyErr_NoMemory();
     716             :     }
     717           0 :     size = Py_SIZE(a) + Py_SIZE(b);
     718           0 :     np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
     719           0 :     if (np == NULL) {
     720           0 :         return NULL;
     721             :     }
     722           0 :     memcpy(np->ob_item, a->ob_item, Py_SIZE(a)*a->ob_descr->itemsize);
     723           0 :     memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
     724           0 :            b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
     725           0 :     return (PyObject *)np;
     726             : #undef b
     727             : }
     728             : 
     729             : static PyObject *
     730           0 : array_repeat(arrayobject *a, Py_ssize_t n)
     731             : {
     732             :     Py_ssize_t size;
     733             :     arrayobject *np;
     734             :     Py_ssize_t oldbytes, newbytes;
     735           0 :     if (n < 0)
     736           0 :         n = 0;
     737           0 :     if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
     738           0 :         return PyErr_NoMemory();
     739             :     }
     740           0 :     size = Py_SIZE(a) * n;
     741           0 :     np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
     742           0 :     if (np == NULL)
     743           0 :         return NULL;
     744           0 :     if (n == 0)
     745           0 :         return (PyObject *)np;
     746           0 :     oldbytes = Py_SIZE(a) * a->ob_descr->itemsize;
     747           0 :     newbytes = oldbytes * n;
     748             :     /* this follows the code in unicode_repeat */
     749           0 :     if (oldbytes == 1) {
     750           0 :         memset(np->ob_item, a->ob_item[0], newbytes);
     751             :     } else {
     752           0 :         Py_ssize_t done = oldbytes;
     753           0 :         Py_MEMCPY(np->ob_item, a->ob_item, oldbytes);
     754           0 :         while (done < newbytes) {
     755           0 :             Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done;
     756           0 :             Py_MEMCPY(np->ob_item+done, np->ob_item, ncopy);
     757           0 :             done += ncopy;
     758             :         }
     759             :     }
     760           0 :     return (PyObject *)np;
     761             : }
     762             : 
     763             : static int
     764           0 : array_ass_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
     765             : {
     766             :     char *item;
     767             :     Py_ssize_t n; /* Size of replacement array */
     768             :     Py_ssize_t d; /* Change in size */
     769             : #define b ((arrayobject *)v)
     770           0 :     if (v == NULL)
     771           0 :         n = 0;
     772           0 :     else if (array_Check(v)) {
     773           0 :         n = Py_SIZE(b);
     774           0 :         if (a == b) {
     775             :             /* Special case "a[i:j] = a" -- copy b first */
     776             :             int ret;
     777           0 :             v = array_slice(b, 0, n);
     778           0 :             if (!v)
     779           0 :                 return -1;
     780           0 :             ret = array_ass_slice(a, ilow, ihigh, v);
     781           0 :             Py_DECREF(v);
     782           0 :             return ret;
     783             :         }
     784           0 :         if (b->ob_descr != a->ob_descr) {
     785           0 :             PyErr_BadArgument();
     786           0 :             return -1;
     787             :         }
     788             :     }
     789             :     else {
     790           0 :         PyErr_Format(PyExc_TypeError,
     791             :          "can only assign array (not \"%.200s\") to array slice",
     792           0 :                          Py_TYPE(v)->tp_name);
     793           0 :         return -1;
     794             :     }
     795           0 :     if (ilow < 0)
     796           0 :         ilow = 0;
     797           0 :     else if (ilow > Py_SIZE(a))
     798           0 :         ilow = Py_SIZE(a);
     799           0 :     if (ihigh < 0)
     800           0 :         ihigh = 0;
     801           0 :     if (ihigh < ilow)
     802           0 :         ihigh = ilow;
     803           0 :     else if (ihigh > Py_SIZE(a))
     804           0 :         ihigh = Py_SIZE(a);
     805           0 :     item = a->ob_item;
     806           0 :     d = n - (ihigh-ilow);
     807             :     /* Issue #4509: If the array has exported buffers and the slice
     808             :        assignment would change the size of the array, fail early to make
     809             :        sure we don't modify it. */
     810           0 :     if (d != 0 && a->ob_exports > 0) {
     811           0 :         PyErr_SetString(PyExc_BufferError,
     812             :             "cannot resize an array that is exporting buffers");
     813           0 :         return -1;
     814             :     }
     815           0 :     if (d < 0) { /* Delete -d items */
     816           0 :         memmove(item + (ihigh+d)*a->ob_descr->itemsize,
     817           0 :             item + ihigh*a->ob_descr->itemsize,
     818           0 :             (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
     819           0 :         if (array_resize(a, Py_SIZE(a) + d) == -1)
     820           0 :             return -1;
     821             :     }
     822           0 :     else if (d > 0) { /* Insert d items */
     823           0 :         if (array_resize(a, Py_SIZE(a) + d))
     824           0 :             return -1;
     825           0 :         memmove(item + (ihigh+d)*a->ob_descr->itemsize,
     826           0 :             item + ihigh*a->ob_descr->itemsize,
     827           0 :             (Py_SIZE(a)-ihigh)*a->ob_descr->itemsize);
     828             :     }
     829           0 :     if (n > 0)
     830           0 :         memcpy(item + ilow*a->ob_descr->itemsize, b->ob_item,
     831           0 :                n*b->ob_descr->itemsize);
     832           0 :     return 0;
     833             : #undef b
     834             : }
     835             : 
     836             : static int
     837       11008 : array_ass_item(arrayobject *a, Py_ssize_t i, PyObject *v)
     838             : {
     839       11008 :     if (i < 0 || i >= Py_SIZE(a)) {
     840           0 :         PyErr_SetString(PyExc_IndexError,
     841             :                          "array assignment index out of range");
     842           0 :         return -1;
     843             :     }
     844       11008 :     if (v == NULL)
     845           0 :         return array_ass_slice(a, i, i+1, v);
     846       11008 :     return (*a->ob_descr->setitem)(a, i, v);
     847             : }
     848             : 
     849             : static int
     850       11008 : setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
     851             : {
     852             :     assert(array_Check(a));
     853       11008 :     return array_ass_item((arrayobject *)a, i, v);
     854             : }
     855             : 
     856             : static int
     857           0 : array_iter_extend(arrayobject *self, PyObject *bb)
     858             : {
     859             :     PyObject *it, *v;
     860             : 
     861           0 :     it = PyObject_GetIter(bb);
     862           0 :     if (it == NULL)
     863           0 :         return -1;
     864             : 
     865           0 :     while ((v = PyIter_Next(it)) != NULL) {
     866           0 :         if (ins1(self, Py_SIZE(self), v) != 0) {
     867           0 :             Py_DECREF(v);
     868           0 :             Py_DECREF(it);
     869           0 :             return -1;
     870             :         }
     871           0 :         Py_DECREF(v);
     872             :     }
     873           0 :     Py_DECREF(it);
     874           0 :     if (PyErr_Occurred())
     875           0 :         return -1;
     876           0 :     return 0;
     877             : }
     878             : 
     879             : static int
     880           0 : array_do_extend(arrayobject *self, PyObject *bb)
     881             : {
     882             :     Py_ssize_t size, oldsize, bbsize;
     883             : 
     884           0 :     if (!array_Check(bb))
     885           0 :         return array_iter_extend(self, bb);
     886             : #define b ((arrayobject *)bb)
     887           0 :     if (self->ob_descr != b->ob_descr) {
     888           0 :         PyErr_SetString(PyExc_TypeError,
     889             :                      "can only extend with array of same kind");
     890           0 :         return -1;
     891             :     }
     892           0 :     if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) ||
     893           0 :         ((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
     894           0 :         PyErr_NoMemory();
     895           0 :         return -1;
     896             :     }
     897           0 :     oldsize = Py_SIZE(self);
     898             :     /* Get the size of bb before resizing the array since bb could be self. */
     899           0 :     bbsize = Py_SIZE(bb);
     900           0 :     size = oldsize + Py_SIZE(b);
     901           0 :     if (array_resize(self, size) == -1)
     902           0 :         return -1;
     903           0 :     memcpy(self->ob_item + oldsize * self->ob_descr->itemsize,
     904           0 :         b->ob_item, bbsize * b->ob_descr->itemsize);
     905             : 
     906           0 :     return 0;
     907             : #undef b
     908             : }
     909             : 
     910             : static PyObject *
     911           0 : array_inplace_concat(arrayobject *self, PyObject *bb)
     912             : {
     913           0 :     if (!array_Check(bb)) {
     914           0 :         PyErr_Format(PyExc_TypeError,
     915             :             "can only extend array with array (not \"%.200s\")",
     916           0 :             Py_TYPE(bb)->tp_name);
     917           0 :         return NULL;
     918             :     }
     919           0 :     if (array_do_extend(self, bb) == -1)
     920           0 :         return NULL;
     921           0 :     Py_INCREF(self);
     922           0 :     return (PyObject *)self;
     923             : }
     924             : 
     925             : static PyObject *
     926           0 : array_inplace_repeat(arrayobject *self, Py_ssize_t n)
     927             : {
     928             :     char *items, *p;
     929             :     Py_ssize_t size, i;
     930             : 
     931           0 :     if (Py_SIZE(self) > 0) {
     932           0 :         if (n < 0)
     933           0 :             n = 0;
     934           0 :         if ((self->ob_descr->itemsize != 0) &&
     935           0 :             (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
     936           0 :             return PyErr_NoMemory();
     937             :         }
     938           0 :         size = Py_SIZE(self) * self->ob_descr->itemsize;
     939           0 :         if (n > 0 && size > PY_SSIZE_T_MAX / n) {
     940           0 :             return PyErr_NoMemory();
     941             :         }
     942           0 :         if (array_resize(self, n * Py_SIZE(self)) == -1)
     943           0 :             return NULL;
     944           0 :         items = p = self->ob_item;
     945           0 :         for (i = 1; i < n; i++) {
     946           0 :             p += size;
     947           0 :             memcpy(p, items, size);
     948             :         }
     949             :     }
     950           0 :     Py_INCREF(self);
     951           0 :     return (PyObject *)self;
     952             : }
     953             : 
     954             : 
     955             : static PyObject *
     956           0 : ins(arrayobject *self, Py_ssize_t where, PyObject *v)
     957             : {
     958           0 :     if (ins1(self, where, v) != 0)
     959           0 :         return NULL;
     960           0 :     Py_INCREF(Py_None);
     961           0 :     return Py_None;
     962             : }
     963             : 
     964             : static PyObject *
     965           0 : array_count(arrayobject *self, PyObject *v)
     966             : {
     967           0 :     Py_ssize_t count = 0;
     968             :     Py_ssize_t i;
     969             : 
     970           0 :     for (i = 0; i < Py_SIZE(self); i++) {
     971           0 :         PyObject *selfi = getarrayitem((PyObject *)self, i);
     972           0 :         int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
     973           0 :         Py_DECREF(selfi);
     974           0 :         if (cmp > 0)
     975           0 :             count++;
     976           0 :         else if (cmp < 0)
     977           0 :             return NULL;
     978             :     }
     979           0 :     return PyLong_FromSsize_t(count);
     980             : }
     981             : 
     982             : PyDoc_STRVAR(count_doc,
     983             : "count(x)\n\
     984             : \n\
     985             : Return number of occurrences of x in the array.");
     986             : 
     987             : static PyObject *
     988           0 : array_index(arrayobject *self, PyObject *v)
     989             : {
     990             :     Py_ssize_t i;
     991             : 
     992           0 :     for (i = 0; i < Py_SIZE(self); i++) {
     993           0 :         PyObject *selfi = getarrayitem((PyObject *)self, i);
     994           0 :         int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
     995           0 :         Py_DECREF(selfi);
     996           0 :         if (cmp > 0) {
     997           0 :             return PyLong_FromLong((long)i);
     998             :         }
     999           0 :         else if (cmp < 0)
    1000           0 :             return NULL;
    1001             :     }
    1002           0 :     PyErr_SetString(PyExc_ValueError, "array.index(x): x not in list");
    1003           0 :     return NULL;
    1004             : }
    1005             : 
    1006             : PyDoc_STRVAR(index_doc,
    1007             : "index(x)\n\
    1008             : \n\
    1009             : Return index of first occurrence of x in the array.");
    1010             : 
    1011             : static int
    1012           0 : array_contains(arrayobject *self, PyObject *v)
    1013             : {
    1014             :     Py_ssize_t i;
    1015             :     int cmp;
    1016             : 
    1017           0 :     for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
    1018           0 :         PyObject *selfi = getarrayitem((PyObject *)self, i);
    1019           0 :         cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
    1020           0 :         Py_DECREF(selfi);
    1021             :     }
    1022           0 :     return cmp;
    1023             : }
    1024             : 
    1025             : static PyObject *
    1026           0 : array_remove(arrayobject *self, PyObject *v)
    1027             : {
    1028             :     int i;
    1029             : 
    1030           0 :     for (i = 0; i < Py_SIZE(self); i++) {
    1031           0 :         PyObject *selfi = getarrayitem((PyObject *)self,i);
    1032           0 :         int cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
    1033           0 :         Py_DECREF(selfi);
    1034           0 :         if (cmp > 0) {
    1035           0 :             if (array_ass_slice(self, i, i+1,
    1036             :                                (PyObject *)NULL) != 0)
    1037           0 :                 return NULL;
    1038           0 :             Py_INCREF(Py_None);
    1039           0 :             return Py_None;
    1040             :         }
    1041           0 :         else if (cmp < 0)
    1042           0 :             return NULL;
    1043             :     }
    1044           0 :     PyErr_SetString(PyExc_ValueError, "array.remove(x): x not in list");
    1045           0 :     return NULL;
    1046             : }
    1047             : 
    1048             : PyDoc_STRVAR(remove_doc,
    1049             : "remove(x)\n\
    1050             : \n\
    1051             : Remove the first occurrence of x in the array.");
    1052             : 
    1053             : static PyObject *
    1054           0 : array_pop(arrayobject *self, PyObject *args)
    1055             : {
    1056           0 :     Py_ssize_t i = -1;
    1057             :     PyObject *v;
    1058           0 :     if (!PyArg_ParseTuple(args, "|n:pop", &i))
    1059           0 :         return NULL;
    1060           0 :     if (Py_SIZE(self) == 0) {
    1061             :         /* Special-case most common failure cause */
    1062           0 :         PyErr_SetString(PyExc_IndexError, "pop from empty array");
    1063           0 :         return NULL;
    1064             :     }
    1065           0 :     if (i < 0)
    1066           0 :         i += Py_SIZE(self);
    1067           0 :     if (i < 0 || i >= Py_SIZE(self)) {
    1068           0 :         PyErr_SetString(PyExc_IndexError, "pop index out of range");
    1069           0 :         return NULL;
    1070             :     }
    1071           0 :     v = getarrayitem((PyObject *)self,i);
    1072           0 :     if (array_ass_slice(self, i, i+1, (PyObject *)NULL) != 0) {
    1073           0 :         Py_DECREF(v);
    1074           0 :         return NULL;
    1075             :     }
    1076           0 :     return v;
    1077             : }
    1078             : 
    1079             : PyDoc_STRVAR(pop_doc,
    1080             : "pop([i])\n\
    1081             : \n\
    1082             : Return the i-th element and delete it from the array. i defaults to -1.");
    1083             : 
    1084             : static PyObject *
    1085           0 : array_extend(arrayobject *self, PyObject *bb)
    1086             : {
    1087           0 :     if (array_do_extend(self, bb) == -1)
    1088           0 :         return NULL;
    1089           0 :     Py_INCREF(Py_None);
    1090           0 :     return Py_None;
    1091             : }
    1092             : 
    1093             : PyDoc_STRVAR(extend_doc,
    1094             : "extend(array or iterable)\n\
    1095             : \n\
    1096             :  Append items to the end of the array.");
    1097             : 
    1098             : static PyObject *
    1099           0 : array_insert(arrayobject *self, PyObject *args)
    1100             : {
    1101             :     Py_ssize_t i;
    1102             :     PyObject *v;
    1103           0 :     if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
    1104           0 :         return NULL;
    1105           0 :     return ins(self, i, v);
    1106             : }
    1107             : 
    1108             : PyDoc_STRVAR(insert_doc,
    1109             : "insert(i,x)\n\
    1110             : \n\
    1111             : Insert a new item x into the array before position i.");
    1112             : 
    1113             : 
    1114             : static PyObject *
    1115           0 : array_buffer_info(arrayobject *self, PyObject *unused)
    1116             : {
    1117           0 :     PyObject* retval = NULL;
    1118           0 :     retval = PyTuple_New(2);
    1119           0 :     if (!retval)
    1120           0 :         return NULL;
    1121             : 
    1122           0 :     PyTuple_SET_ITEM(retval, 0, PyLong_FromVoidPtr(self->ob_item));
    1123           0 :     PyTuple_SET_ITEM(retval, 1, PyLong_FromLong((long)(Py_SIZE(self))));
    1124             : 
    1125           0 :     return retval;
    1126             : }
    1127             : 
    1128             : PyDoc_STRVAR(buffer_info_doc,
    1129             : "buffer_info() -> (address, length)\n\
    1130             : \n\
    1131             : Return a tuple (address, length) giving the current memory address and\n\
    1132             : the length in items of the buffer used to hold array's contents\n\
    1133             : The length should be multiplied by the itemsize attribute to calculate\n\
    1134             : the buffer length in bytes.");
    1135             : 
    1136             : 
    1137             : static PyObject *
    1138           0 : array_append(arrayobject *self, PyObject *v)
    1139             : {
    1140           0 :     return ins(self, Py_SIZE(self), v);
    1141             : }
    1142             : 
    1143             : PyDoc_STRVAR(append_doc,
    1144             : "append(x)\n\
    1145             : \n\
    1146             : Append new value x to the end of the array.");
    1147             : 
    1148             : 
    1149             : static PyObject *
    1150           0 : array_byteswap(arrayobject *self, PyObject *unused)
    1151             : {
    1152             :     char *p;
    1153             :     Py_ssize_t i;
    1154             : 
    1155           0 :     switch (self->ob_descr->itemsize) {
    1156             :     case 1:
    1157           0 :         break;
    1158             :     case 2:
    1159           0 :         for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 2) {
    1160           0 :             char p0 = p[0];
    1161           0 :             p[0] = p[1];
    1162           0 :             p[1] = p0;
    1163             :         }
    1164           0 :         break;
    1165             :     case 4:
    1166           0 :         for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 4) {
    1167           0 :             char p0 = p[0];
    1168           0 :             char p1 = p[1];
    1169           0 :             p[0] = p[3];
    1170           0 :             p[1] = p[2];
    1171           0 :             p[2] = p1;
    1172           0 :             p[3] = p0;
    1173             :         }
    1174           0 :         break;
    1175             :     case 8:
    1176           0 :         for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) {
    1177           0 :             char p0 = p[0];
    1178           0 :             char p1 = p[1];
    1179           0 :             char p2 = p[2];
    1180           0 :             char p3 = p[3];
    1181           0 :             p[0] = p[7];
    1182           0 :             p[1] = p[6];
    1183           0 :             p[2] = p[5];
    1184           0 :             p[3] = p[4];
    1185           0 :             p[4] = p3;
    1186           0 :             p[5] = p2;
    1187           0 :             p[6] = p1;
    1188           0 :             p[7] = p0;
    1189             :         }
    1190           0 :         break;
    1191             :     default:
    1192           0 :         PyErr_SetString(PyExc_RuntimeError,
    1193             :                    "don't know how to byteswap this array type");
    1194           0 :         return NULL;
    1195             :     }
    1196           0 :     Py_INCREF(Py_None);
    1197           0 :     return Py_None;
    1198             : }
    1199             : 
    1200             : PyDoc_STRVAR(byteswap_doc,
    1201             : "byteswap()\n\
    1202             : \n\
    1203             : Byteswap all items of the array.  If the items in the array are not 1, 2,\n\
    1204             : 4, or 8 bytes in size, RuntimeError is raised.");
    1205             : 
    1206             : static PyObject *
    1207           0 : array_reverse(arrayobject *self, PyObject *unused)
    1208             : {
    1209           0 :     register Py_ssize_t itemsize = self->ob_descr->itemsize;
    1210             :     register char *p, *q;
    1211             :     /* little buffer to hold items while swapping */
    1212             :     char tmp[256];      /* 8 is probably enough -- but why skimp */
    1213             :     assert((size_t)itemsize <= sizeof(tmp));
    1214             : 
    1215           0 :     if (Py_SIZE(self) > 1) {
    1216           0 :         for (p = self->ob_item,
    1217           0 :              q = self->ob_item + (Py_SIZE(self) - 1)*itemsize;
    1218             :              p < q;
    1219           0 :              p += itemsize, q -= itemsize) {
    1220             :             /* memory areas guaranteed disjoint, so memcpy
    1221             :              * is safe (& memmove may be slower).
    1222             :              */
    1223           0 :             memcpy(tmp, p, itemsize);
    1224           0 :             memcpy(p, q, itemsize);
    1225           0 :             memcpy(q, tmp, itemsize);
    1226             :         }
    1227             :     }
    1228             : 
    1229           0 :     Py_INCREF(Py_None);
    1230           0 :     return Py_None;
    1231             : }
    1232             : 
    1233             : PyDoc_STRVAR(reverse_doc,
    1234             : "reverse()\n\
    1235             : \n\
    1236             : Reverse the order of the items in the array.");
    1237             : 
    1238             : 
    1239             : /* Forward */
    1240             : static PyObject *array_frombytes(arrayobject *self, PyObject *args);
    1241             : 
    1242             : static PyObject *
    1243           0 : array_fromfile(arrayobject *self, PyObject *args)
    1244             : {
    1245             :     PyObject *f, *b, *res;
    1246           0 :     Py_ssize_t itemsize = self->ob_descr->itemsize;
    1247             :     Py_ssize_t n, nbytes;
    1248             :     _Py_IDENTIFIER(read);
    1249             :     int not_enough_bytes;
    1250             : 
    1251           0 :     if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
    1252           0 :         return NULL;
    1253             : 
    1254           0 :     nbytes = n * itemsize;
    1255           0 :     if (nbytes < 0 || nbytes/itemsize != n) {
    1256           0 :         PyErr_NoMemory();
    1257           0 :         return NULL;
    1258             :     }
    1259             : 
    1260           0 :     b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
    1261           0 :     if (b == NULL)
    1262           0 :         return NULL;
    1263             : 
    1264           0 :     if (!PyBytes_Check(b)) {
    1265           0 :         PyErr_SetString(PyExc_TypeError,
    1266             :                         "read() didn't return bytes");
    1267           0 :         Py_DECREF(b);
    1268           0 :         return NULL;
    1269             :     }
    1270             : 
    1271           0 :     not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes);
    1272             : 
    1273           0 :     args = Py_BuildValue("(O)", b);
    1274           0 :     Py_DECREF(b);
    1275           0 :     if (args == NULL)
    1276           0 :         return NULL;
    1277             : 
    1278           0 :     res = array_frombytes(self, args);
    1279           0 :     Py_DECREF(args);
    1280           0 :     if (res == NULL)
    1281           0 :         return NULL;
    1282             : 
    1283           0 :     if (not_enough_bytes) {
    1284           0 :         PyErr_SetString(PyExc_EOFError,
    1285             :                         "read() didn't return enough bytes");
    1286           0 :         Py_DECREF(res);
    1287           0 :         return NULL;
    1288             :     }
    1289             : 
    1290           0 :     return res;
    1291             : }
    1292             : 
    1293             : PyDoc_STRVAR(fromfile_doc,
    1294             : "fromfile(f, n)\n\
    1295             : \n\
    1296             : Read n objects from the file object f and append them to the end of the\n\
    1297             : array.");
    1298             : 
    1299             : 
    1300             : static PyObject *
    1301           0 : array_tofile(arrayobject *self, PyObject *f)
    1302             : {
    1303           0 :     Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
    1304             :     /* Write 64K blocks at a time */
    1305             :     /* XXX Make the block size settable */
    1306           0 :     int BLOCKSIZE = 64*1024;
    1307           0 :     Py_ssize_t nblocks = (nbytes + BLOCKSIZE - 1) / BLOCKSIZE;
    1308             :     Py_ssize_t i;
    1309             : 
    1310           0 :     if (Py_SIZE(self) == 0)
    1311           0 :         goto done;
    1312             : 
    1313           0 :     for (i = 0; i < nblocks; i++) {
    1314           0 :         char* ptr = self->ob_item + i*BLOCKSIZE;
    1315           0 :         Py_ssize_t size = BLOCKSIZE;
    1316             :         PyObject *bytes, *res;
    1317             :         _Py_IDENTIFIER(write);
    1318             : 
    1319           0 :         if (i*BLOCKSIZE + size > nbytes)
    1320           0 :             size = nbytes - i*BLOCKSIZE;
    1321           0 :         bytes = PyBytes_FromStringAndSize(ptr, size);
    1322           0 :         if (bytes == NULL)
    1323           0 :             return NULL;
    1324           0 :         res = _PyObject_CallMethodId(f, &PyId_write, "O", bytes);
    1325           0 :         Py_DECREF(bytes);
    1326           0 :         if (res == NULL)
    1327           0 :             return NULL;
    1328           0 :         Py_DECREF(res); /* drop write result */
    1329             :     }
    1330             : 
    1331             :   done:
    1332           0 :     Py_INCREF(Py_None);
    1333           0 :     return Py_None;
    1334             : }
    1335             : 
    1336             : PyDoc_STRVAR(tofile_doc,
    1337             : "tofile(f)\n\
    1338             : \n\
    1339             : Write all items (as machine values) to the file object f.");
    1340             : 
    1341             : 
    1342             : static PyObject *
    1343           0 : array_fromlist(arrayobject *self, PyObject *list)
    1344             : {
    1345             :     Py_ssize_t n;
    1346             : 
    1347           0 :     if (!PyList_Check(list)) {
    1348           0 :         PyErr_SetString(PyExc_TypeError, "arg must be list");
    1349           0 :         return NULL;
    1350             :     }
    1351           0 :     n = PyList_Size(list);
    1352           0 :     if (n > 0) {
    1353             :         Py_ssize_t i, old_size;
    1354           0 :         old_size = Py_SIZE(self);
    1355           0 :         if (array_resize(self, old_size + n) == -1)
    1356           0 :             return NULL;
    1357           0 :         for (i = 0; i < n; i++) {
    1358           0 :             PyObject *v = PyList_GetItem(list, i);
    1359           0 :             if ((*self->ob_descr->setitem)(self,
    1360           0 :                             Py_SIZE(self) - n + i, v) != 0) {
    1361           0 :                 array_resize(self, old_size);
    1362           0 :                 return NULL;
    1363             :             }
    1364             :         }
    1365             :     }
    1366           0 :     Py_INCREF(Py_None);
    1367           0 :     return Py_None;
    1368             : }
    1369             : 
    1370             : PyDoc_STRVAR(fromlist_doc,
    1371             : "fromlist(list)\n\
    1372             : \n\
    1373             : Append items to array from list.");
    1374             : 
    1375             : static PyObject *
    1376          43 : array_tolist(arrayobject *self, PyObject *unused)
    1377             : {
    1378          43 :     PyObject *list = PyList_New(Py_SIZE(self));
    1379             :     Py_ssize_t i;
    1380             : 
    1381          43 :     if (list == NULL)
    1382           0 :         return NULL;
    1383        2795 :     for (i = 0; i < Py_SIZE(self); i++) {
    1384        2752 :         PyObject *v = getarrayitem((PyObject *)self, i);
    1385        2752 :         if (v == NULL) {
    1386           0 :             Py_DECREF(list);
    1387           0 :             return NULL;
    1388             :         }
    1389        2752 :         PyList_SetItem(list, i, v);
    1390             :     }
    1391          43 :     return list;
    1392             : }
    1393             : 
    1394             : PyDoc_STRVAR(tolist_doc,
    1395             : "tolist() -> list\n\
    1396             : \n\
    1397             : Convert array to an ordinary list with the same items.");
    1398             : 
    1399             : static PyObject *
    1400          43 : frombytes(arrayobject *self, Py_buffer *buffer)
    1401             : {
    1402          43 :     int itemsize = self->ob_descr->itemsize;
    1403             :     Py_ssize_t n;
    1404          43 :     if (buffer->itemsize != 1) {
    1405           0 :         PyBuffer_Release(buffer);
    1406           0 :         PyErr_SetString(PyExc_TypeError, "string/buffer of bytes required.");
    1407           0 :         return NULL;
    1408             :     }
    1409          43 :     n = buffer->len;
    1410          43 :     if (n % itemsize != 0) {
    1411           0 :         PyBuffer_Release(buffer);
    1412           0 :         PyErr_SetString(PyExc_ValueError,
    1413             :                    "string length not a multiple of item size");
    1414           0 :         return NULL;
    1415             :     }
    1416          43 :     n = n / itemsize;
    1417          43 :     if (n > 0) {
    1418          43 :         Py_ssize_t old_size = Py_SIZE(self);
    1419          86 :         if ((n > PY_SSIZE_T_MAX - old_size) ||
    1420          43 :             ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
    1421           0 :                 PyBuffer_Release(buffer);
    1422           0 :                 return PyErr_NoMemory();
    1423             :         }
    1424          43 :         if (array_resize(self, old_size + n) == -1) {
    1425           0 :             PyBuffer_Release(buffer);
    1426           0 :             return NULL;
    1427             :         }
    1428          86 :         memcpy(self->ob_item + old_size * itemsize,
    1429          86 :             buffer->buf, n * itemsize);
    1430             :     }
    1431          43 :     PyBuffer_Release(buffer);
    1432          43 :     Py_INCREF(Py_None);
    1433          43 :     return Py_None;
    1434             : }
    1435             : 
    1436             : static PyObject *
    1437           0 : array_fromstring(arrayobject *self, PyObject *args)
    1438             : {
    1439             :     Py_buffer buffer;
    1440           0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
    1441             :             "fromstring() is deprecated. Use frombytes() instead.", 2) != 0)
    1442           0 :         return NULL;
    1443           0 :     if (!PyArg_ParseTuple(args, "s*:fromstring", &buffer))
    1444           0 :         return NULL;
    1445             :     else
    1446           0 :         return frombytes(self, &buffer);
    1447             : }
    1448             : 
    1449             : PyDoc_STRVAR(fromstring_doc,
    1450             : "fromstring(string)\n\
    1451             : \n\
    1452             : Appends items from the string, interpreting it as an array of machine\n\
    1453             : values, as if it had been read from a file using the fromfile() method).\n\
    1454             : \n\
    1455             : This method is deprecated. Use frombytes instead.");
    1456             : 
    1457             : 
    1458             : static PyObject *
    1459          43 : array_frombytes(arrayobject *self, PyObject *args)
    1460             : {
    1461             :     Py_buffer buffer;
    1462          43 :     if (!PyArg_ParseTuple(args, "y*:frombytes", &buffer))
    1463           0 :         return NULL;
    1464             :     else
    1465          43 :         return frombytes(self, &buffer);
    1466             : }
    1467             : 
    1468             : PyDoc_STRVAR(frombytes_doc,
    1469             : "frombytes(bytestring)\n\
    1470             : \n\
    1471             : Appends items from the string, interpreting it as an array of machine\n\
    1472             : values, as if it had been read from a file using the fromfile() method).");
    1473             : 
    1474             : 
    1475             : static PyObject *
    1476          43 : array_tobytes(arrayobject *self, PyObject *unused)
    1477             : {
    1478          43 :     if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
    1479          43 :         return PyBytes_FromStringAndSize(self->ob_item,
    1480          43 :                             Py_SIZE(self) * self->ob_descr->itemsize);
    1481             :     } else {
    1482           0 :         return PyErr_NoMemory();
    1483             :     }
    1484             : }
    1485             : 
    1486             : PyDoc_STRVAR(tobytes_doc,
    1487             : "tobytes() -> bytes\n\
    1488             : \n\
    1489             : Convert the array to an array of machine values and return the bytes\n\
    1490             : representation.");
    1491             : 
    1492             : 
    1493             : static PyObject *
    1494           0 : array_tostring(arrayobject *self, PyObject *unused)
    1495             : {
    1496           0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
    1497             :             "tostring() is deprecated. Use tobytes() instead.", 2) != 0)
    1498           0 :         return NULL;
    1499           0 :     return array_tobytes(self, unused);
    1500             : }
    1501             : 
    1502             : PyDoc_STRVAR(tostring_doc,
    1503             : "tostring() -> bytes\n\
    1504             : \n\
    1505             : Convert the array to an array of machine values and return the bytes\n\
    1506             : representation.\n\
    1507             : \n\
    1508             : This method is deprecated. Use tobytes instead.");
    1509             : 
    1510             : 
    1511             : static PyObject *
    1512           0 : array_fromunicode(arrayobject *self, PyObject *args)
    1513             : {
    1514             :     Py_UNICODE *ustr;
    1515             :     Py_ssize_t n;
    1516             :     char typecode;
    1517             : 
    1518           0 :     if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
    1519           0 :         return NULL;
    1520           0 :     typecode = self->ob_descr->typecode;
    1521           0 :     if ((typecode != 'u')) {
    1522           0 :         PyErr_SetString(PyExc_ValueError,
    1523             :             "fromunicode() may only be called on "
    1524             :             "unicode type arrays");
    1525           0 :         return NULL;
    1526             :     }
    1527           0 :     if (n > 0) {
    1528           0 :         Py_ssize_t old_size = Py_SIZE(self);
    1529           0 :         if (array_resize(self, old_size + n) == -1)
    1530           0 :             return NULL;
    1531           0 :         memcpy(self->ob_item + old_size * sizeof(Py_UNICODE),
    1532             :                ustr, n * sizeof(Py_UNICODE));
    1533             :     }
    1534             : 
    1535           0 :     Py_INCREF(Py_None);
    1536           0 :     return Py_None;
    1537             : }
    1538             : 
    1539             : PyDoc_STRVAR(fromunicode_doc,
    1540             : "fromunicode(ustr)\n\
    1541             : \n\
    1542             : Extends this array with data from the unicode string ustr.\n\
    1543             : The array must be a unicode type array; otherwise a ValueError\n\
    1544             : is raised.  Use array.frombytes(ustr.encode(...)) to\n\
    1545             : append Unicode data to an array of some other type.");
    1546             : 
    1547             : 
    1548             : static PyObject *
    1549           0 : array_tounicode(arrayobject *self, PyObject *unused)
    1550             : {
    1551             :     char typecode;
    1552           0 :     typecode = self->ob_descr->typecode;
    1553           0 :     if ((typecode != 'u')) {
    1554           0 :         PyErr_SetString(PyExc_ValueError,
    1555             :              "tounicode() may only be called on unicode type arrays");
    1556           0 :         return NULL;
    1557             :     }
    1558           0 :     return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self));
    1559             : }
    1560             : 
    1561             : PyDoc_STRVAR(tounicode_doc,
    1562             : "tounicode() -> unicode\n\
    1563             : \n\
    1564             : Convert the array to a unicode string.  The array must be\n\
    1565             : a unicode type array; otherwise a ValueError is raised.  Use\n\
    1566             : array.tobytes().decode() to obtain a unicode string from\n\
    1567             : an array of some other type.");
    1568             : 
    1569             : 
    1570             : static PyObject *
    1571           0 : array_sizeof(arrayobject *self, PyObject *unused)
    1572             : {
    1573             :     Py_ssize_t res;
    1574           0 :     res = sizeof(arrayobject) + self->allocated * self->ob_descr->itemsize;
    1575           0 :     return PyLong_FromSsize_t(res);
    1576             : }
    1577             : 
    1578             : PyDoc_STRVAR(sizeof_doc,
    1579             : "__sizeof__() -> int\n\
    1580             : \n\
    1581             : Size of the array in memory, in bytes.");
    1582             : 
    1583             : 
    1584             : /*********************** Pickling support ************************/
    1585             : 
    1586             : enum machine_format_code {
    1587             :     UNKNOWN_FORMAT = -1,
    1588             :     /* UNKNOWN_FORMAT is used to indicate that the machine format for an
    1589             :      * array type code cannot be interpreted. When this occurs, a list of
    1590             :      * Python objects is used to represent the content of the array
    1591             :      * instead of using the memory content of the array directly. In that
    1592             :      * case, the array_reconstructor mechanism is bypassed completely, and
    1593             :      * the standard array constructor is used instead.
    1594             :      *
    1595             :      * This is will most likely occur when the machine doesn't use IEEE
    1596             :      * floating-point numbers.
    1597             :      */
    1598             : 
    1599             :     UNSIGNED_INT8 = 0,
    1600             :     SIGNED_INT8 = 1,
    1601             :     UNSIGNED_INT16_LE = 2,
    1602             :     UNSIGNED_INT16_BE = 3,
    1603             :     SIGNED_INT16_LE = 4,
    1604             :     SIGNED_INT16_BE = 5,
    1605             :     UNSIGNED_INT32_LE = 6,
    1606             :     UNSIGNED_INT32_BE = 7,
    1607             :     SIGNED_INT32_LE = 8,
    1608             :     SIGNED_INT32_BE = 9,
    1609             :     UNSIGNED_INT64_LE = 10,
    1610             :     UNSIGNED_INT64_BE = 11,
    1611             :     SIGNED_INT64_LE = 12,
    1612             :     SIGNED_INT64_BE = 13,
    1613             :     IEEE_754_FLOAT_LE = 14,
    1614             :     IEEE_754_FLOAT_BE = 15,
    1615             :     IEEE_754_DOUBLE_LE = 16,
    1616             :     IEEE_754_DOUBLE_BE = 17,
    1617             :     UTF16_LE = 18,
    1618             :     UTF16_BE = 19,
    1619             :     UTF32_LE = 20,
    1620             :     UTF32_BE = 21
    1621             : };
    1622             : #define MACHINE_FORMAT_CODE_MIN 0
    1623             : #define MACHINE_FORMAT_CODE_MAX 21
    1624             : 
    1625             : static const struct mformatdescr {
    1626             :     size_t size;
    1627             :     int is_signed;
    1628             :     int is_big_endian;
    1629             : } mformat_descriptors[] = {
    1630             :     {1, 0, 0},                  /* 0: UNSIGNED_INT8 */
    1631             :     {1, 1, 0},                  /* 1: SIGNED_INT8 */
    1632             :     {2, 0, 0},                  /* 2: UNSIGNED_INT16_LE */
    1633             :     {2, 0, 1},                  /* 3: UNSIGNED_INT16_BE */
    1634             :     {2, 1, 0},                  /* 4: SIGNED_INT16_LE */
    1635             :     {2, 1, 1},                  /* 5: SIGNED_INT16_BE */
    1636             :     {4, 0, 0},                  /* 6: UNSIGNED_INT32_LE */
    1637             :     {4, 0, 1},                  /* 7: UNSIGNED_INT32_BE */
    1638             :     {4, 1, 0},                  /* 8: SIGNED_INT32_LE */
    1639             :     {4, 1, 1},                  /* 9: SIGNED_INT32_BE */
    1640             :     {8, 0, 0},                  /* 10: UNSIGNED_INT64_LE */
    1641             :     {8, 0, 1},                  /* 11: UNSIGNED_INT64_BE */
    1642             :     {8, 1, 0},                  /* 12: SIGNED_INT64_LE */
    1643             :     {8, 1, 1},                  /* 13: SIGNED_INT64_BE */
    1644             :     {4, 0, 0},                  /* 14: IEEE_754_FLOAT_LE */
    1645             :     {4, 0, 1},                  /* 15: IEEE_754_FLOAT_BE */
    1646             :     {8, 0, 0},                  /* 16: IEEE_754_DOUBLE_LE */
    1647             :     {8, 0, 1},                  /* 17: IEEE_754_DOUBLE_BE */
    1648             :     {4, 0, 0},                  /* 18: UTF16_LE */
    1649             :     {4, 0, 1},                  /* 19: UTF16_BE */
    1650             :     {8, 0, 0},                  /* 20: UTF32_LE */
    1651             :     {8, 0, 1}                   /* 21: UTF32_BE */
    1652             : };
    1653             : 
    1654             : 
    1655             : /*
    1656             :  * Internal: This function is used to find the machine format of a given
    1657             :  * array type code. This returns UNKNOWN_FORMAT when the machine format cannot
    1658             :  * be found.
    1659             :  */
    1660             : static enum machine_format_code
    1661           0 : typecode_to_mformat_code(char typecode)
    1662             : {
    1663             : #ifdef WORDS_BIGENDIAN
    1664             :     const int is_big_endian = 1;
    1665             : #else
    1666           0 :     const int is_big_endian = 0;
    1667             : #endif
    1668             :     size_t intsize;
    1669             :     int is_signed;
    1670             : 
    1671           0 :     switch (typecode) {
    1672             :     case 'b':
    1673           0 :         return SIGNED_INT8;
    1674             :     case 'B':
    1675           0 :         return UNSIGNED_INT8;
    1676             : 
    1677             :     case 'u':
    1678             :         if (sizeof(Py_UNICODE) == 2) {
    1679             :             return UTF16_LE + is_big_endian;
    1680             :         }
    1681             :         if (sizeof(Py_UNICODE) == 4) {
    1682           0 :             return UTF32_LE + is_big_endian;
    1683             :         }
    1684             :         return UNKNOWN_FORMAT;
    1685             : 
    1686             :     case 'f':
    1687             :         if (sizeof(float) == 4) {
    1688           0 :             const float y = 16711938.0;
    1689           0 :             if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
    1690           0 :                 return IEEE_754_FLOAT_BE;
    1691           0 :             if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
    1692           0 :                 return IEEE_754_FLOAT_LE;
    1693             :         }
    1694           0 :         return UNKNOWN_FORMAT;
    1695             : 
    1696             :     case 'd':
    1697             :         if (sizeof(double) == 8) {
    1698           0 :             const double x = 9006104071832581.0;
    1699           0 :             if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
    1700           0 :                 return IEEE_754_DOUBLE_BE;
    1701           0 :             if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
    1702           0 :                 return IEEE_754_DOUBLE_LE;
    1703             :         }
    1704           0 :         return UNKNOWN_FORMAT;
    1705             : 
    1706             :     /* Integers */
    1707             :     case 'h':
    1708           0 :         intsize = sizeof(short);
    1709           0 :         is_signed = 1;
    1710           0 :         break;
    1711             :     case 'H':
    1712           0 :         intsize = sizeof(short);
    1713           0 :         is_signed = 0;
    1714           0 :         break;
    1715             :     case 'i':
    1716           0 :         intsize = sizeof(int);
    1717           0 :         is_signed = 1;
    1718           0 :         break;
    1719             :     case 'I':
    1720           0 :         intsize = sizeof(int);
    1721           0 :         is_signed = 0;
    1722           0 :         break;
    1723             :     case 'l':
    1724           0 :         intsize = sizeof(long);
    1725           0 :         is_signed = 1;
    1726           0 :         break;
    1727             :     case 'L':
    1728           0 :         intsize = sizeof(long);
    1729           0 :         is_signed = 0;
    1730           0 :         break;
    1731             : #if HAVE_LONG_LONG
    1732             :     case 'q':
    1733           0 :         intsize = sizeof(PY_LONG_LONG);
    1734           0 :         is_signed = 1;
    1735           0 :         break;
    1736             :     case 'Q':
    1737           0 :         intsize = sizeof(PY_LONG_LONG);
    1738           0 :         is_signed = 0;
    1739           0 :         break;
    1740             : #endif
    1741             :     default:
    1742           0 :         return UNKNOWN_FORMAT;
    1743             :     }
    1744           0 :     switch (intsize) {
    1745             :     case 2:
    1746           0 :         return UNSIGNED_INT16_LE + is_big_endian + (2 * is_signed);
    1747             :     case 4:
    1748           0 :         return UNSIGNED_INT32_LE + is_big_endian + (2 * is_signed);
    1749             :     case 8:
    1750           0 :         return UNSIGNED_INT64_LE + is_big_endian + (2 * is_signed);
    1751             :     default:
    1752           0 :         return UNKNOWN_FORMAT;
    1753             :     }
    1754             : }
    1755             : 
    1756             : /* Forward declaration. */
    1757             : static PyObject *array_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
    1758             : 
    1759             : /*
    1760             :  * Internal: This function wraps the array constructor--i.e., array_new()--to
    1761             :  * allow the creation of array objects from C code without having to deal
    1762             :  * directly the tuple argument of array_new(). The typecode argument is a
    1763             :  * Unicode character value, like 'i' or 'f' for example, representing an array
    1764             :  * type code. The items argument is a bytes or a list object from which
    1765             :  * contains the initial value of the array.
    1766             :  *
    1767             :  * On success, this functions returns the array object created. Otherwise,
    1768             :  * NULL is returned to indicate a failure.
    1769             :  */
    1770             : static PyObject *
    1771           0 : make_array(PyTypeObject *arraytype, char typecode, PyObject *items)
    1772             : {
    1773             :     PyObject *new_args;
    1774             :     PyObject *array_obj;
    1775             :     PyObject *typecode_obj;
    1776             : 
    1777             :     assert(arraytype != NULL);
    1778             :     assert(items != NULL);
    1779             : 
    1780           0 :     typecode_obj = PyUnicode_FromOrdinal(typecode);
    1781           0 :     if (typecode_obj == NULL)
    1782           0 :         return NULL;
    1783             : 
    1784           0 :     new_args = PyTuple_New(2);
    1785           0 :     if (new_args == NULL)
    1786           0 :         return NULL;
    1787           0 :     Py_INCREF(items);
    1788           0 :     PyTuple_SET_ITEM(new_args, 0, typecode_obj);
    1789           0 :     PyTuple_SET_ITEM(new_args, 1, items);
    1790             : 
    1791           0 :     array_obj = array_new(arraytype, new_args, NULL);
    1792           0 :     Py_DECREF(new_args);
    1793           0 :     if (array_obj == NULL)
    1794           0 :         return NULL;
    1795             : 
    1796           0 :     return array_obj;
    1797             : }
    1798             : 
    1799             : /*
    1800             :  * This functions is a special constructor used when unpickling an array. It
    1801             :  * provides a portable way to rebuild an array from its memory representation.
    1802             :  */
    1803             : static PyObject *
    1804           0 : array_reconstructor(PyObject *self, PyObject *args)
    1805             : {
    1806             :     PyTypeObject *arraytype;
    1807             :     PyObject *items;
    1808             :     PyObject *converted_items;
    1809             :     PyObject *result;
    1810             :     int typecode;
    1811             :     enum machine_format_code mformat_code;
    1812             :     struct arraydescr *descr;
    1813             : 
    1814           0 :     if (!PyArg_ParseTuple(args, "OCiO:array._array_reconstructor",
    1815             :                     &arraytype, &typecode, &mformat_code, &items))
    1816           0 :         return NULL;
    1817             : 
    1818           0 :     if (!PyType_Check(arraytype)) {
    1819           0 :         PyErr_Format(PyExc_TypeError,
    1820             :             "first argument must a type object, not %.200s",
    1821           0 :             Py_TYPE(arraytype)->tp_name);
    1822           0 :         return NULL;
    1823             :     }
    1824           0 :     if (!PyType_IsSubtype(arraytype, &Arraytype)) {
    1825           0 :         PyErr_Format(PyExc_TypeError,
    1826             :             "%.200s is not a subtype of %.200s",
    1827           0 :             arraytype->tp_name, Arraytype.tp_name);
    1828           0 :         return NULL;
    1829             :     }
    1830           0 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
    1831           0 :         if ((int)descr->typecode == typecode)
    1832           0 :             break;
    1833             :     }
    1834           0 :     if (descr->typecode == '\0') {
    1835           0 :         PyErr_SetString(PyExc_ValueError,
    1836             :                         "second argument must be a valid type code");
    1837           0 :         return NULL;
    1838             :     }
    1839           0 :     if (mformat_code < MACHINE_FORMAT_CODE_MIN ||
    1840           0 :         mformat_code > MACHINE_FORMAT_CODE_MAX) {
    1841           0 :         PyErr_SetString(PyExc_ValueError,
    1842             :             "third argument must be a valid machine format code.");
    1843           0 :         return NULL;
    1844             :     }
    1845           0 :     if (!PyBytes_Check(items)) {
    1846           0 :         PyErr_Format(PyExc_TypeError,
    1847             :             "fourth argument should be bytes, not %.200s",
    1848           0 :             Py_TYPE(items)->tp_name);
    1849           0 :         return NULL;
    1850             :     }
    1851             : 
    1852             :     /* Fast path: No decoding has to be done. */
    1853           0 :     if (mformat_code == typecode_to_mformat_code((char)typecode) ||
    1854           0 :         mformat_code == UNKNOWN_FORMAT) {
    1855           0 :         return make_array(arraytype, (char)typecode, items);
    1856             :     }
    1857             : 
    1858             :     /* Slow path: Decode the byte string according to the given machine
    1859             :      * format code. This occurs when the computer unpickling the array
    1860             :      * object is architecturally different from the one that pickled the
    1861             :      * array.
    1862             :      */
    1863           0 :     if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) {
    1864           0 :         PyErr_SetString(PyExc_ValueError,
    1865             :                         "string length not a multiple of item size");
    1866           0 :         return NULL;
    1867             :     }
    1868           0 :     switch (mformat_code) {
    1869             :     case IEEE_754_FLOAT_LE:
    1870             :     case IEEE_754_FLOAT_BE: {
    1871             :         int i;
    1872           0 :         int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
    1873           0 :         Py_ssize_t itemcount = Py_SIZE(items) / 4;
    1874           0 :         const unsigned char *memstr =
    1875           0 :             (unsigned char *)PyBytes_AS_STRING(items);
    1876             : 
    1877           0 :         converted_items = PyList_New(itemcount);
    1878           0 :         if (converted_items == NULL)
    1879           0 :             return NULL;
    1880           0 :         for (i = 0; i < itemcount; i++) {
    1881           0 :             PyObject *pyfloat = PyFloat_FromDouble(
    1882           0 :                 _PyFloat_Unpack4(&memstr[i * 4], le));
    1883           0 :             if (pyfloat == NULL) {
    1884           0 :                 Py_DECREF(converted_items);
    1885           0 :                 return NULL;
    1886             :             }
    1887           0 :             PyList_SET_ITEM(converted_items, i, pyfloat);
    1888             :         }
    1889           0 :         break;
    1890             :     }
    1891             :     case IEEE_754_DOUBLE_LE:
    1892             :     case IEEE_754_DOUBLE_BE: {
    1893             :         int i;
    1894           0 :         int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0;
    1895           0 :         Py_ssize_t itemcount = Py_SIZE(items) / 8;
    1896           0 :         const unsigned char *memstr =
    1897           0 :             (unsigned char *)PyBytes_AS_STRING(items);
    1898             : 
    1899           0 :         converted_items = PyList_New(itemcount);
    1900           0 :         if (converted_items == NULL)
    1901           0 :             return NULL;
    1902           0 :         for (i = 0; i < itemcount; i++) {
    1903           0 :             PyObject *pyfloat = PyFloat_FromDouble(
    1904           0 :                 _PyFloat_Unpack8(&memstr[i * 8], le));
    1905           0 :             if (pyfloat == NULL) {
    1906           0 :                 Py_DECREF(converted_items);
    1907           0 :                 return NULL;
    1908             :             }
    1909           0 :             PyList_SET_ITEM(converted_items, i, pyfloat);
    1910             :         }
    1911           0 :         break;
    1912             :     }
    1913             :     case UTF16_LE:
    1914             :     case UTF16_BE: {
    1915           0 :         int byteorder = (mformat_code == UTF16_LE) ? -1 : 1;
    1916           0 :         converted_items = PyUnicode_DecodeUTF16(
    1917           0 :             PyBytes_AS_STRING(items), Py_SIZE(items),
    1918             :             "strict", &byteorder);
    1919           0 :         if (converted_items == NULL)
    1920           0 :             return NULL;
    1921             :         break;
    1922             :     }
    1923             :     case UTF32_LE:
    1924             :     case UTF32_BE: {
    1925           0 :         int byteorder = (mformat_code == UTF32_LE) ? -1 : 1;
    1926           0 :         converted_items = PyUnicode_DecodeUTF32(
    1927           0 :             PyBytes_AS_STRING(items), Py_SIZE(items),
    1928             :             "strict", &byteorder);
    1929           0 :         if (converted_items == NULL)
    1930           0 :             return NULL;
    1931             :         break;
    1932             :     }
    1933             : 
    1934             :     case UNSIGNED_INT8:
    1935             :     case SIGNED_INT8:
    1936             :     case UNSIGNED_INT16_LE:
    1937             :     case UNSIGNED_INT16_BE:
    1938             :     case SIGNED_INT16_LE:
    1939             :     case SIGNED_INT16_BE:
    1940             :     case UNSIGNED_INT32_LE:
    1941             :     case UNSIGNED_INT32_BE:
    1942             :     case SIGNED_INT32_LE:
    1943             :     case SIGNED_INT32_BE:
    1944             :     case UNSIGNED_INT64_LE:
    1945             :     case UNSIGNED_INT64_BE:
    1946             :     case SIGNED_INT64_LE:
    1947             :     case SIGNED_INT64_BE: {
    1948             :         int i;
    1949           0 :         const struct mformatdescr mf_descr =
    1950           0 :             mformat_descriptors[mformat_code];
    1951           0 :         Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size;
    1952           0 :         const unsigned char *memstr =
    1953           0 :             (unsigned char *)PyBytes_AS_STRING(items);
    1954             :         struct arraydescr *descr;
    1955             : 
    1956             :         /* If possible, try to pack array's items using a data type
    1957             :          * that fits better. This may result in an array with narrower
    1958             :          * or wider elements.
    1959             :          *
    1960             :          * For example, if a 32-bit machine pickles a L-code array of
    1961             :          * unsigned longs, then the array will be unpickled by 64-bit
    1962             :          * machine as an I-code array of unsigned ints.
    1963             :          *
    1964             :          * XXX: Is it possible to write a unit test for this?
    1965             :          */
    1966           0 :         for (descr = descriptors; descr->typecode != '\0'; descr++) {
    1967           0 :             if (descr->is_integer_type &&
    1968           0 :                 descr->itemsize == mf_descr.size &&
    1969           0 :                 descr->is_signed == mf_descr.is_signed)
    1970           0 :                 typecode = descr->typecode;
    1971             :         }
    1972             : 
    1973           0 :         converted_items = PyList_New(itemcount);
    1974           0 :         if (converted_items == NULL)
    1975           0 :             return NULL;
    1976           0 :         for (i = 0; i < itemcount; i++) {
    1977             :             PyObject *pylong;
    1978             : 
    1979           0 :             pylong = _PyLong_FromByteArray(
    1980           0 :                 &memstr[i * mf_descr.size],
    1981             :                 mf_descr.size,
    1982           0 :                 !mf_descr.is_big_endian,
    1983             :                 mf_descr.is_signed);
    1984           0 :             if (pylong == NULL) {
    1985           0 :                 Py_DECREF(converted_items);
    1986           0 :                 return NULL;
    1987             :             }
    1988           0 :             PyList_SET_ITEM(converted_items, i, pylong);
    1989             :         }
    1990             :         break;
    1991             :     }
    1992             :     case UNKNOWN_FORMAT:
    1993             :         /* Impossible, but needed to shut up GCC about the unhandled
    1994             :          * enumeration value.
    1995             :          */
    1996             :     default:
    1997           0 :         PyErr_BadArgument();
    1998           0 :         return NULL;
    1999             :     }
    2000             : 
    2001           0 :     result = make_array(arraytype, (char)typecode, converted_items);
    2002           0 :     Py_DECREF(converted_items);
    2003           0 :     return result;
    2004             : }
    2005             : 
    2006             : static PyObject *
    2007           0 : array_reduce_ex(arrayobject *array, PyObject *value)
    2008             : {
    2009             :     PyObject *dict;
    2010             :     PyObject *result;
    2011             :     PyObject *array_str;
    2012           0 :     int typecode = array->ob_descr->typecode;
    2013             :     int mformat_code;
    2014             :     static PyObject *array_reconstructor = NULL;
    2015             :     long protocol;
    2016             :     _Py_IDENTIFIER(_array_reconstructor);
    2017             :     _Py_IDENTIFIER(__dict__);
    2018             : 
    2019           0 :     if (array_reconstructor == NULL) {
    2020           0 :         PyObject *array_module = PyImport_ImportModule("array");
    2021           0 :         if (array_module == NULL)
    2022           0 :             return NULL;
    2023           0 :         array_reconstructor = _PyObject_GetAttrId(
    2024             :             array_module,
    2025             :             &PyId__array_reconstructor);
    2026           0 :         Py_DECREF(array_module);
    2027           0 :         if (array_reconstructor == NULL)
    2028           0 :             return NULL;
    2029             :     }
    2030             : 
    2031           0 :     if (!PyLong_Check(value)) {
    2032           0 :         PyErr_SetString(PyExc_TypeError,
    2033             :                         "__reduce_ex__ argument should an integer");
    2034           0 :         return NULL;
    2035             :     }
    2036           0 :     protocol = PyLong_AsLong(value);
    2037           0 :     if (protocol == -1 && PyErr_Occurred())
    2038           0 :         return NULL;
    2039             : 
    2040           0 :     dict = _PyObject_GetAttrId((PyObject *)array, &PyId___dict__);
    2041           0 :     if (dict == NULL) {
    2042           0 :         if (!PyErr_ExceptionMatches(PyExc_AttributeError))
    2043           0 :             return NULL;
    2044           0 :         PyErr_Clear();
    2045           0 :         dict = Py_None;
    2046           0 :         Py_INCREF(dict);
    2047             :     }
    2048             : 
    2049           0 :     mformat_code = typecode_to_mformat_code(typecode);
    2050           0 :     if (mformat_code == UNKNOWN_FORMAT || protocol < 3) {
    2051             :         /* Convert the array to a list if we got something weird
    2052             :          * (e.g., non-IEEE floats), or we are pickling the array using
    2053             :          * a Python 2.x compatible protocol.
    2054             :          *
    2055             :          * It is necessary to use a list representation for Python 2.x
    2056             :          * compatible pickle protocol, since Python 2's str objects
    2057             :          * are unpickled as unicode by Python 3. Thus it is impossible
    2058             :          * to make arrays unpicklable by Python 3 by using their memory
    2059             :          * representation, unless we resort to ugly hacks such as
    2060             :          * coercing unicode objects to bytes in array_reconstructor.
    2061             :          */
    2062             :         PyObject *list;
    2063           0 :         list = array_tolist(array, NULL);
    2064           0 :         if (list == NULL) {
    2065           0 :             Py_DECREF(dict);
    2066           0 :             return NULL;
    2067             :         }
    2068           0 :         result = Py_BuildValue(
    2069             :             "O(CO)O", Py_TYPE(array), typecode, list, dict);
    2070           0 :         Py_DECREF(list);
    2071           0 :         Py_DECREF(dict);
    2072           0 :         return result;
    2073             :     }
    2074             : 
    2075           0 :     array_str = array_tobytes(array, NULL);
    2076           0 :     if (array_str == NULL) {
    2077           0 :         Py_DECREF(dict);
    2078           0 :         return NULL;
    2079             :     }
    2080           0 :     result = Py_BuildValue(
    2081             :         "O(OCiN)O", array_reconstructor, Py_TYPE(array), typecode,
    2082             :         mformat_code, array_str, dict);
    2083           0 :     Py_DECREF(dict);
    2084           0 :     return result;
    2085             : }
    2086             : 
    2087             : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
    2088             : 
    2089             : static PyObject *
    2090           0 : array_get_typecode(arrayobject *a, void *closure)
    2091             : {
    2092           0 :     char typecode = a->ob_descr->typecode;
    2093           0 :     return PyUnicode_FromOrdinal(typecode);
    2094             : }
    2095             : 
    2096             : static PyObject *
    2097          86 : array_get_itemsize(arrayobject *a, void *closure)
    2098             : {
    2099          86 :     return PyLong_FromLong((long)a->ob_descr->itemsize);
    2100             : }
    2101             : 
    2102             : static PyGetSetDef array_getsets [] = {
    2103             :     {"typecode", (getter) array_get_typecode, NULL,
    2104             :      "the typecode character used to create the array"},
    2105             :     {"itemsize", (getter) array_get_itemsize, NULL,
    2106             :      "the size, in bytes, of one array item"},
    2107             :     {NULL}
    2108             : };
    2109             : 
    2110             : static PyMethodDef array_methods[] = {
    2111             :     {"append",          (PyCFunction)array_append,      METH_O,
    2112             :      append_doc},
    2113             :     {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,
    2114             :      buffer_info_doc},
    2115             :     {"byteswap",        (PyCFunction)array_byteswap,    METH_NOARGS,
    2116             :      byteswap_doc},
    2117             :     {"__copy__",        (PyCFunction)array_copy,        METH_NOARGS,
    2118             :      copy_doc},
    2119             :     {"count",           (PyCFunction)array_count,       METH_O,
    2120             :      count_doc},
    2121             :     {"__deepcopy__",(PyCFunction)array_copy,            METH_O,
    2122             :      copy_doc},
    2123             :     {"extend",      (PyCFunction)array_extend,          METH_O,
    2124             :      extend_doc},
    2125             :     {"fromfile",        (PyCFunction)array_fromfile,    METH_VARARGS,
    2126             :      fromfile_doc},
    2127             :     {"fromlist",        (PyCFunction)array_fromlist,    METH_O,
    2128             :      fromlist_doc},
    2129             :     {"fromstring",      (PyCFunction)array_fromstring,  METH_VARARGS,
    2130             :      fromstring_doc},
    2131             :     {"frombytes",       (PyCFunction)array_frombytes,   METH_VARARGS,
    2132             :      frombytes_doc},
    2133             :     {"fromunicode",     (PyCFunction)array_fromunicode, METH_VARARGS,
    2134             :      fromunicode_doc},
    2135             :     {"index",           (PyCFunction)array_index,       METH_O,
    2136             :      index_doc},
    2137             :     {"insert",          (PyCFunction)array_insert,      METH_VARARGS,
    2138             :      insert_doc},
    2139             :     {"pop",             (PyCFunction)array_pop,         METH_VARARGS,
    2140             :      pop_doc},
    2141             :     {"__reduce_ex__", (PyCFunction)array_reduce_ex,     METH_O,
    2142             :      reduce_doc},
    2143             :     {"remove",          (PyCFunction)array_remove,      METH_O,
    2144             :      remove_doc},
    2145             :     {"reverse",         (PyCFunction)array_reverse,     METH_NOARGS,
    2146             :      reverse_doc},
    2147             : /*      {"sort",        (PyCFunction)array_sort,        METH_VARARGS,
    2148             :     sort_doc},*/
    2149             :     {"tofile",          (PyCFunction)array_tofile,      METH_O,
    2150             :      tofile_doc},
    2151             :     {"tolist",          (PyCFunction)array_tolist,      METH_NOARGS,
    2152             :      tolist_doc},
    2153             :     {"tostring",        (PyCFunction)array_tostring,    METH_NOARGS,
    2154             :      tostring_doc},
    2155             :     {"tobytes",         (PyCFunction)array_tobytes,     METH_NOARGS,
    2156             :      tobytes_doc},
    2157             :     {"tounicode",   (PyCFunction)array_tounicode,       METH_NOARGS,
    2158             :      tounicode_doc},
    2159             :     {"__sizeof__",      (PyCFunction)array_sizeof,      METH_NOARGS,
    2160             :      sizeof_doc},
    2161             :     {NULL,              NULL}           /* sentinel */
    2162             : };
    2163             : 
    2164             : static PyObject *
    2165           0 : array_repr(arrayobject *a)
    2166             : {
    2167             :     char typecode;
    2168           0 :     PyObject *s, *v = NULL;
    2169             :     Py_ssize_t len;
    2170             : 
    2171           0 :     len = Py_SIZE(a);
    2172           0 :     typecode = a->ob_descr->typecode;
    2173           0 :     if (len == 0) {
    2174           0 :         return PyUnicode_FromFormat("array('%c')", (int)typecode);
    2175             :     }
    2176           0 :     if (typecode == 'u')
    2177           0 :         v = array_tounicode(a, NULL);
    2178             :     else
    2179           0 :         v = array_tolist(a, NULL);
    2180             : 
    2181           0 :     s = PyUnicode_FromFormat("array('%c', %R)", (int)typecode, v);
    2182           0 :     Py_DECREF(v);
    2183           0 :     return s;
    2184             : }
    2185             : 
    2186             : static PyObject*
    2187           0 : array_subscr(arrayobject* self, PyObject* item)
    2188             : {
    2189           0 :     if (PyIndex_Check(item)) {
    2190           0 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
    2191           0 :         if (i==-1 && PyErr_Occurred()) {
    2192           0 :             return NULL;
    2193             :         }
    2194           0 :         if (i < 0)
    2195           0 :             i += Py_SIZE(self);
    2196           0 :         return array_item(self, i);
    2197             :     }
    2198           0 :     else if (PySlice_Check(item)) {
    2199             :         Py_ssize_t start, stop, step, slicelength, cur, i;
    2200             :         PyObject* result;
    2201             :         arrayobject* ar;
    2202           0 :         int itemsize = self->ob_descr->itemsize;
    2203             : 
    2204           0 :         if (PySlice_GetIndicesEx(item, Py_SIZE(self),
    2205             :                          &start, &stop, &step, &slicelength) < 0) {
    2206           0 :             return NULL;
    2207             :         }
    2208             : 
    2209           0 :         if (slicelength <= 0) {
    2210           0 :             return newarrayobject(&Arraytype, 0, self->ob_descr);
    2211             :         }
    2212           0 :         else if (step == 1) {
    2213           0 :             PyObject *result = newarrayobject(&Arraytype,
    2214             :                                     slicelength, self->ob_descr);
    2215           0 :             if (result == NULL)
    2216           0 :                 return NULL;
    2217           0 :             memcpy(((arrayobject *)result)->ob_item,
    2218           0 :                    self->ob_item + start * itemsize,
    2219           0 :                    slicelength * itemsize);
    2220           0 :             return result;
    2221             :         }
    2222             :         else {
    2223           0 :             result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
    2224           0 :             if (!result) return NULL;
    2225             : 
    2226           0 :             ar = (arrayobject*)result;
    2227             : 
    2228           0 :             for (cur = start, i = 0; i < slicelength;
    2229           0 :                  cur += step, i++) {
    2230           0 :                 memcpy(ar->ob_item + i*itemsize,
    2231           0 :                        self->ob_item + cur*itemsize,
    2232             :                        itemsize);
    2233             :             }
    2234             : 
    2235           0 :             return result;
    2236             :         }
    2237             :     }
    2238             :     else {
    2239           0 :         PyErr_SetString(PyExc_TypeError,
    2240             :                         "array indices must be integers");
    2241           0 :         return NULL;
    2242             :     }
    2243             : }
    2244             : 
    2245             : static int
    2246           0 : array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
    2247             : {
    2248             :     Py_ssize_t start, stop, step, slicelength, needed;
    2249             :     arrayobject* other;
    2250             :     int itemsize;
    2251             : 
    2252           0 :     if (PyIndex_Check(item)) {
    2253           0 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
    2254             : 
    2255           0 :         if (i == -1 && PyErr_Occurred())
    2256           0 :             return -1;
    2257           0 :         if (i < 0)
    2258           0 :             i += Py_SIZE(self);
    2259           0 :         if (i < 0 || i >= Py_SIZE(self)) {
    2260           0 :             PyErr_SetString(PyExc_IndexError,
    2261             :                 "array assignment index out of range");
    2262           0 :             return -1;
    2263             :         }
    2264           0 :         if (value == NULL) {
    2265             :             /* Fall through to slice assignment */
    2266           0 :             start = i;
    2267           0 :             stop = i + 1;
    2268           0 :             step = 1;
    2269           0 :             slicelength = 1;
    2270             :         }
    2271             :         else
    2272           0 :             return (*self->ob_descr->setitem)(self, i, value);
    2273             :     }
    2274           0 :     else if (PySlice_Check(item)) {
    2275           0 :         if (PySlice_GetIndicesEx(item,
    2276             :                                  Py_SIZE(self), &start, &stop,
    2277             :                                  &step, &slicelength) < 0) {
    2278           0 :             return -1;
    2279             :         }
    2280             :     }
    2281             :     else {
    2282           0 :         PyErr_SetString(PyExc_TypeError,
    2283             :                         "array indices must be integer");
    2284           0 :         return -1;
    2285             :     }
    2286           0 :     if (value == NULL) {
    2287           0 :         other = NULL;
    2288           0 :         needed = 0;
    2289             :     }
    2290           0 :     else if (array_Check(value)) {
    2291           0 :         other = (arrayobject *)value;
    2292           0 :         needed = Py_SIZE(other);
    2293           0 :         if (self == other) {
    2294             :             /* Special case "self[i:j] = self" -- copy self first */
    2295             :             int ret;
    2296           0 :             value = array_slice(other, 0, needed);
    2297           0 :             if (value == NULL)
    2298           0 :                 return -1;
    2299           0 :             ret = array_ass_subscr(self, item, value);
    2300           0 :             Py_DECREF(value);
    2301           0 :             return ret;
    2302             :         }
    2303           0 :         if (other->ob_descr != self->ob_descr) {
    2304           0 :             PyErr_BadArgument();
    2305           0 :             return -1;
    2306             :         }
    2307             :     }
    2308             :     else {
    2309           0 :         PyErr_Format(PyExc_TypeError,
    2310             :          "can only assign array (not \"%.200s\") to array slice",
    2311           0 :                          Py_TYPE(value)->tp_name);
    2312           0 :         return -1;
    2313             :     }
    2314           0 :     itemsize = self->ob_descr->itemsize;
    2315             :     /* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
    2316           0 :     if ((step > 0 && stop < start) ||
    2317           0 :         (step < 0 && stop > start))
    2318           0 :         stop = start;
    2319             : 
    2320             :     /* Issue #4509: If the array has exported buffers and the slice
    2321             :        assignment would change the size of the array, fail early to make
    2322             :        sure we don't modify it. */
    2323           0 :     if ((needed == 0 || slicelength != needed) && self->ob_exports > 0) {
    2324           0 :         PyErr_SetString(PyExc_BufferError,
    2325             :             "cannot resize an array that is exporting buffers");
    2326           0 :         return -1;
    2327             :     }
    2328             : 
    2329           0 :     if (step == 1) {
    2330           0 :         if (slicelength > needed) {
    2331           0 :             memmove(self->ob_item + (start + needed) * itemsize,
    2332           0 :                 self->ob_item + stop * itemsize,
    2333           0 :                 (Py_SIZE(self) - stop) * itemsize);
    2334           0 :             if (array_resize(self, Py_SIZE(self) +
    2335             :                 needed - slicelength) < 0)
    2336           0 :                 return -1;
    2337             :         }
    2338           0 :         else if (slicelength < needed) {
    2339           0 :             if (array_resize(self, Py_SIZE(self) +
    2340             :                 needed - slicelength) < 0)
    2341           0 :                 return -1;
    2342           0 :             memmove(self->ob_item + (start + needed) * itemsize,
    2343           0 :                 self->ob_item + stop * itemsize,
    2344           0 :                 (Py_SIZE(self) - start - needed) * itemsize);
    2345             :         }
    2346           0 :         if (needed > 0)
    2347           0 :             memcpy(self->ob_item + start * itemsize,
    2348           0 :                    other->ob_item, needed * itemsize);
    2349           0 :         return 0;
    2350             :     }
    2351           0 :     else if (needed == 0) {
    2352             :         /* Delete slice */
    2353             :         size_t cur;
    2354             :         Py_ssize_t i;
    2355             : 
    2356           0 :         if (step < 0) {
    2357           0 :             stop = start + 1;
    2358           0 :             start = stop + step * (slicelength - 1) - 1;
    2359           0 :             step = -step;
    2360             :         }
    2361           0 :         for (cur = start, i = 0; i < slicelength;
    2362           0 :              cur += step, i++) {
    2363           0 :             Py_ssize_t lim = step - 1;
    2364             : 
    2365           0 :             if (cur + step >= (size_t)Py_SIZE(self))
    2366           0 :                 lim = Py_SIZE(self) - cur - 1;
    2367           0 :             memmove(self->ob_item + (cur - i) * itemsize,
    2368           0 :                 self->ob_item + (cur + 1) * itemsize,
    2369           0 :                 lim * itemsize);
    2370             :         }
    2371           0 :         cur = start + (size_t)slicelength * step;
    2372           0 :         if (cur < (size_t)Py_SIZE(self)) {
    2373           0 :             memmove(self->ob_item + (cur-slicelength) * itemsize,
    2374           0 :                 self->ob_item + cur * itemsize,
    2375           0 :                 (Py_SIZE(self) - cur) * itemsize);
    2376             :         }
    2377           0 :         if (array_resize(self, Py_SIZE(self) - slicelength) < 0)
    2378           0 :             return -1;
    2379           0 :         return 0;
    2380             :     }
    2381             :     else {
    2382             :         Py_ssize_t cur, i;
    2383             : 
    2384           0 :         if (needed != slicelength) {
    2385           0 :             PyErr_Format(PyExc_ValueError,
    2386             :                 "attempt to assign array of size %zd "
    2387             :                 "to extended slice of size %zd",
    2388             :                 needed, slicelength);
    2389           0 :             return -1;
    2390             :         }
    2391           0 :         for (cur = start, i = 0; i < slicelength;
    2392           0 :              cur += step, i++) {
    2393           0 :             memcpy(self->ob_item + cur * itemsize,
    2394           0 :                    other->ob_item + i * itemsize,
    2395             :                    itemsize);
    2396             :         }
    2397           0 :         return 0;
    2398             :     }
    2399             : }
    2400             : 
    2401             : static PyMappingMethods array_as_mapping = {
    2402             :     (lenfunc)array_length,
    2403             :     (binaryfunc)array_subscr,
    2404             :     (objobjargproc)array_ass_subscr
    2405             : };
    2406             : 
    2407             : static const void *emptybuf = "";
    2408             : 
    2409             : 
    2410             : static int
    2411           0 : array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
    2412             : {
    2413           0 :     if (view==NULL) goto finish;
    2414             : 
    2415           0 :     view->buf = (void *)self->ob_item;
    2416           0 :     view->obj = (PyObject*)self;
    2417           0 :     Py_INCREF(self);
    2418           0 :     if (view->buf == NULL)
    2419           0 :         view->buf = (void *)emptybuf;
    2420           0 :     view->len = (Py_SIZE(self)) * self->ob_descr->itemsize;
    2421           0 :     view->readonly = 0;
    2422           0 :     view->ndim = 1;
    2423           0 :     view->itemsize = self->ob_descr->itemsize;
    2424           0 :     view->suboffsets = NULL;
    2425           0 :     view->shape = NULL;
    2426           0 :     if ((flags & PyBUF_ND)==PyBUF_ND) {
    2427           0 :         view->shape = &((Py_SIZE(self)));
    2428             :     }
    2429           0 :     view->strides = NULL;
    2430           0 :     if ((flags & PyBUF_STRIDES)==PyBUF_STRIDES)
    2431           0 :         view->strides = &(view->itemsize);
    2432           0 :     view->format = NULL;
    2433           0 :     view->internal = NULL;
    2434           0 :     if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
    2435           0 :         view->format = self->ob_descr->formats;
    2436             : #ifdef Py_UNICODE_WIDE
    2437           0 :         if (self->ob_descr->typecode == 'u') {
    2438           0 :             view->format = "w";
    2439             :         }
    2440             : #endif
    2441             :     }
    2442             : 
    2443             :  finish:
    2444           0 :     self->ob_exports++;
    2445           0 :     return 0;
    2446             : }
    2447             : 
    2448             : static void
    2449           0 : array_buffer_relbuf(arrayobject *self, Py_buffer *view)
    2450             : {
    2451           0 :     self->ob_exports--;
    2452           0 : }
    2453             : 
    2454             : static PySequenceMethods array_as_sequence = {
    2455             :     (lenfunc)array_length,                      /*sq_length*/
    2456             :     (binaryfunc)array_concat,               /*sq_concat*/
    2457             :     (ssizeargfunc)array_repeat,                 /*sq_repeat*/
    2458             :     (ssizeargfunc)array_item,                           /*sq_item*/
    2459             :     0,                                          /*sq_slice*/
    2460             :     (ssizeobjargproc)array_ass_item,                    /*sq_ass_item*/
    2461             :     0,                                          /*sq_ass_slice*/
    2462             :     (objobjproc)array_contains,                 /*sq_contains*/
    2463             :     (binaryfunc)array_inplace_concat,           /*sq_inplace_concat*/
    2464             :     (ssizeargfunc)array_inplace_repeat          /*sq_inplace_repeat*/
    2465             : };
    2466             : 
    2467             : static PyBufferProcs array_as_buffer = {
    2468             :     (getbufferproc)array_buffer_getbuf,
    2469             :     (releasebufferproc)array_buffer_relbuf
    2470             : };
    2471             : 
    2472             : static PyObject *
    2473          86 : array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    2474             : {
    2475             :     int c;
    2476          86 :     PyObject *initial = NULL, *it = NULL;
    2477             :     struct arraydescr *descr;
    2478             : 
    2479          86 :     if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
    2480           0 :         return NULL;
    2481             : 
    2482          86 :     if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
    2483           0 :         return NULL;
    2484             : 
    2485          86 :     if (!(initial == NULL || PyList_Check(initial)
    2486          43 :           || PyByteArray_Check(initial)
    2487          43 :           || PyBytes_Check(initial)
    2488           0 :           || PyTuple_Check(initial)
    2489           0 :           || ((c=='u') && PyUnicode_Check(initial))
    2490           0 :           || (array_Check(initial)
    2491           0 :               && c == ((arrayobject*)initial)->ob_descr->typecode))) {
    2492           0 :         it = PyObject_GetIter(initial);
    2493           0 :         if (it == NULL)
    2494           0 :             return NULL;
    2495             :         /* We set initial to NULL so that the subsequent code
    2496             :            will create an empty array of the appropriate type
    2497             :            and afterwards we can use array_iter_extend to populate
    2498             :            the array.
    2499             :         */
    2500           0 :         initial = NULL;
    2501             :     }
    2502         344 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
    2503         344 :         if (descr->typecode == c) {
    2504             :             PyObject *a;
    2505             :             Py_ssize_t len;
    2506             : 
    2507          86 :             if (initial == NULL)
    2508           0 :                 len = 0;
    2509          86 :             else if (PyList_Check(initial))
    2510          43 :                 len = PyList_GET_SIZE(initial);
    2511          43 :             else if (PyTuple_Check(initial) || array_Check(initial))
    2512           0 :                 len = Py_SIZE(initial);
    2513             :             else
    2514          43 :                 len = 0;
    2515             : 
    2516          86 :             a = newarrayobject(type, len, descr);
    2517          86 :             if (a == NULL)
    2518           0 :                 return NULL;
    2519             : 
    2520         129 :             if (len > 0 && !array_Check(initial)) {
    2521             :                 Py_ssize_t i;
    2522       11051 :                 for (i = 0; i < len; i++) {
    2523       11008 :                     PyObject *v =
    2524       11008 :                         PySequence_GetItem(initial, i);
    2525       11008 :                     if (v == NULL) {
    2526           0 :                         Py_DECREF(a);
    2527           0 :                         return NULL;
    2528             :                     }
    2529       11008 :                     if (setarrayitem(a, i, v) != 0) {
    2530           0 :                         Py_DECREF(v);
    2531           0 :                         Py_DECREF(a);
    2532           0 :                         return NULL;
    2533             :                     }
    2534       11008 :                     Py_DECREF(v);
    2535             :                 }
    2536             :             }
    2537          86 :             else if (initial != NULL && (PyByteArray_Check(initial) ||
    2538          86 :                                PyBytes_Check(initial))) {
    2539             :                 PyObject *t_initial, *v;
    2540          43 :                 t_initial = PyTuple_Pack(1, initial);
    2541          43 :                 if (t_initial == NULL) {
    2542           0 :                     Py_DECREF(a);
    2543           0 :                     return NULL;
    2544             :                 }
    2545          43 :                 v = array_frombytes((arrayobject *)a,
    2546             :                                          t_initial);
    2547          43 :                 Py_DECREF(t_initial);
    2548          43 :                 if (v == NULL) {
    2549           0 :                     Py_DECREF(a);
    2550           0 :                     return NULL;
    2551             :                 }
    2552          43 :                 Py_DECREF(v);
    2553             :             }
    2554           0 :             else if (initial != NULL && PyUnicode_Check(initial))  {
    2555             :                 Py_UNICODE *ustr;
    2556             :                 Py_ssize_t n;
    2557             : 
    2558           0 :                 ustr = PyUnicode_AsUnicode(initial);
    2559           0 :                 if (ustr == NULL) {
    2560           0 :                     PyErr_NoMemory();
    2561           0 :                     Py_DECREF(a);
    2562           0 :                     return NULL;
    2563             :                 }
    2564             : 
    2565           0 :                 n = PyUnicode_GET_DATA_SIZE(initial);
    2566           0 :                 if (n > 0) {
    2567           0 :                     arrayobject *self = (arrayobject *)a;
    2568           0 :                     char *item = self->ob_item;
    2569           0 :                     item = (char *)PyMem_Realloc(item, n);
    2570           0 :                     if (item == NULL) {
    2571           0 :                         PyErr_NoMemory();
    2572           0 :                         Py_DECREF(a);
    2573           0 :                         return NULL;
    2574             :                     }
    2575           0 :                     self->ob_item = item;
    2576           0 :                     Py_SIZE(self) = n / sizeof(Py_UNICODE);
    2577           0 :                     memcpy(item, ustr, n);
    2578           0 :                     self->allocated = Py_SIZE(self);
    2579             :                 }
    2580             :             }
    2581           0 :             else if (initial != NULL && array_Check(initial)) {
    2582           0 :                 arrayobject *self = (arrayobject *)a;
    2583           0 :                 arrayobject *other = (arrayobject *)initial;
    2584           0 :                 memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize);
    2585             :             }
    2586          86 :             if (it != NULL) {
    2587           0 :                 if (array_iter_extend((arrayobject *)a, it) == -1) {
    2588           0 :                     Py_DECREF(it);
    2589           0 :                     Py_DECREF(a);
    2590           0 :                     return NULL;
    2591             :                 }
    2592           0 :                 Py_DECREF(it);
    2593             :             }
    2594          86 :             return a;
    2595             :         }
    2596             :     }
    2597           0 :     PyErr_SetString(PyExc_ValueError,
    2598             : #ifdef HAVE_LONG_LONG
    2599             :         "bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)");
    2600             : #else
    2601             :         "bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)");
    2602             : #endif
    2603           0 :     return NULL;
    2604             : }
    2605             : 
    2606             : 
    2607             : PyDoc_STRVAR(module_doc,
    2608             : "This module defines an object type which can efficiently represent\n\
    2609             : an array of basic values: characters, integers, floating point\n\
    2610             : numbers.  Arrays are sequence types and behave very much like lists,\n\
    2611             : except that the type of objects stored in them is constrained.  The\n\
    2612             : type is specified at object creation time by using a type code, which\n\
    2613             : is a single character.  The following type codes are defined:\n\
    2614             : \n\
    2615             :     Type code   C Type             Minimum size in bytes \n\
    2616             :     'b'         signed integer     1 \n\
    2617             :     'B'         unsigned integer   1 \n\
    2618             :     'u'         Unicode character  2 (see note) \n\
    2619             :     'h'         signed integer     2 \n\
    2620             :     'H'         unsigned integer   2 \n\
    2621             :     'i'         signed integer     2 \n\
    2622             :     'I'         unsigned integer   2 \n\
    2623             :     'l'         signed integer     4 \n\
    2624             :     'L'         unsigned integer   4 \n\
    2625             :     'q'         signed integer     8 (see note) \n\
    2626             :     'Q'         unsigned integer   8 (see note) \n\
    2627             :     'f'         floating point     4 \n\
    2628             :     'd'         floating point     8 \n\
    2629             : \n\
    2630             : NOTE: The 'u' typecode corresponds to Python's unicode character. On \n\
    2631             : narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
    2632             : \n\
    2633             : NOTE: The 'q' and 'Q' type codes are only available if the platform \n\
    2634             : C compiler used to build Python supports 'long long', or, on Windows, \n\
    2635             : '__int64'.\n\
    2636             : \n\
    2637             : The constructor is:\n\
    2638             : \n\
    2639             : array(typecode [, initializer]) -- create a new array\n\
    2640             : ");
    2641             : 
    2642             : PyDoc_STRVAR(arraytype_doc,
    2643             : "array(typecode [, initializer]) -> array\n\
    2644             : \n\
    2645             : Return a new array whose items are restricted by typecode, and\n\
    2646             : initialized from the optional initializer value, which must be a list,\n\
    2647             : string or iterable over elements of the appropriate type.\n\
    2648             : \n\
    2649             : Arrays represent basic values and behave very much like lists, except\n\
    2650             : the type of objects stored in them is constrained.\n\
    2651             : \n\
    2652             : Methods:\n\
    2653             : \n\
    2654             : append() -- append a new item to the end of the array\n\
    2655             : buffer_info() -- return information giving the current memory info\n\
    2656             : byteswap() -- byteswap all the items of the array\n\
    2657             : count() -- return number of occurrences of an object\n\
    2658             : extend() -- extend array by appending multiple elements from an iterable\n\
    2659             : fromfile() -- read items from a file object\n\
    2660             : fromlist() -- append items from the list\n\
    2661             : frombytes() -- append items from the string\n\
    2662             : index() -- return index of first occurrence of an object\n\
    2663             : insert() -- insert a new item into the array at a provided position\n\
    2664             : pop() -- remove and return item (default last)\n\
    2665             : remove() -- remove first occurrence of an object\n\
    2666             : reverse() -- reverse the order of the items in the array\n\
    2667             : tofile() -- write all items to a file object\n\
    2668             : tolist() -- return the array converted to an ordinary list\n\
    2669             : tobytes() -- return the array converted to a string\n\
    2670             : \n\
    2671             : Attributes:\n\
    2672             : \n\
    2673             : typecode -- the typecode character used to create the array\n\
    2674             : itemsize -- the length in bytes of one array item\n\
    2675             : ");
    2676             : 
    2677             : static PyObject *array_iter(arrayobject *ao);
    2678             : 
    2679             : static PyTypeObject Arraytype = {
    2680             :     PyVarObject_HEAD_INIT(NULL, 0)
    2681             :     "array.array",
    2682             :     sizeof(arrayobject),
    2683             :     0,
    2684             :     (destructor)array_dealloc,                  /* tp_dealloc */
    2685             :     0,                                          /* tp_print */
    2686             :     0,                                          /* tp_getattr */
    2687             :     0,                                          /* tp_setattr */
    2688             :     0,                                          /* tp_reserved */
    2689             :     (reprfunc)array_repr,                       /* tp_repr */
    2690             :     0,                                          /* tp_as_number*/
    2691             :     &array_as_sequence,                         /* tp_as_sequence*/
    2692             :     &array_as_mapping,                          /* tp_as_mapping*/
    2693             :     0,                                          /* tp_hash */
    2694             :     0,                                          /* tp_call */
    2695             :     0,                                          /* tp_str */
    2696             :     PyObject_GenericGetAttr,                    /* tp_getattro */
    2697             :     0,                                          /* tp_setattro */
    2698             :     &array_as_buffer,                           /* tp_as_buffer*/
    2699             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    2700             :     arraytype_doc,                              /* tp_doc */
    2701             :     0,                                          /* tp_traverse */
    2702             :     0,                                          /* tp_clear */
    2703             :     array_richcompare,                          /* tp_richcompare */
    2704             :     offsetof(arrayobject, weakreflist),         /* tp_weaklistoffset */
    2705             :     (getiterfunc)array_iter,                    /* tp_iter */
    2706             :     0,                                          /* tp_iternext */
    2707             :     array_methods,                              /* tp_methods */
    2708             :     0,                                          /* tp_members */
    2709             :     array_getsets,                              /* tp_getset */
    2710             :     0,                                          /* tp_base */
    2711             :     0,                                          /* tp_dict */
    2712             :     0,                                          /* tp_descr_get */
    2713             :     0,                                          /* tp_descr_set */
    2714             :     0,                                          /* tp_dictoffset */
    2715             :     0,                                          /* tp_init */
    2716             :     PyType_GenericAlloc,                        /* tp_alloc */
    2717             :     array_new,                                  /* tp_new */
    2718             :     PyObject_Del,                               /* tp_free */
    2719             : };
    2720             : 
    2721             : 
    2722             : /*********************** Array Iterator **************************/
    2723             : 
    2724             : typedef struct {
    2725             :     PyObject_HEAD
    2726             :     Py_ssize_t                          index;
    2727             :     arrayobject                 *ao;
    2728             :     PyObject                    * (*getitem)(struct arrayobject *, Py_ssize_t);
    2729             : } arrayiterobject;
    2730             : 
    2731             : static PyTypeObject PyArrayIter_Type;
    2732             : 
    2733             : #define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
    2734             : 
    2735             : static PyObject *
    2736           0 : array_iter(arrayobject *ao)
    2737             : {
    2738             :     arrayiterobject *it;
    2739             : 
    2740           0 :     if (!array_Check(ao)) {
    2741           0 :         PyErr_BadInternalCall();
    2742           0 :         return NULL;
    2743             :     }
    2744             : 
    2745           0 :     it = PyObject_GC_New(arrayiterobject, &PyArrayIter_Type);
    2746           0 :     if (it == NULL)
    2747           0 :         return NULL;
    2748             : 
    2749           0 :     Py_INCREF(ao);
    2750           0 :     it->ao = ao;
    2751           0 :     it->index = 0;
    2752           0 :     it->getitem = ao->ob_descr->getitem;
    2753           0 :     PyObject_GC_Track(it);
    2754           0 :     return (PyObject *)it;
    2755             : }
    2756             : 
    2757             : static PyObject *
    2758           0 : arrayiter_next(arrayiterobject *it)
    2759             : {
    2760             :     assert(PyArrayIter_Check(it));
    2761           0 :     if (it->index < Py_SIZE(it->ao))
    2762           0 :         return (*it->getitem)(it->ao, it->index++);
    2763           0 :     return NULL;
    2764             : }
    2765             : 
    2766             : static void
    2767           0 : arrayiter_dealloc(arrayiterobject *it)
    2768             : {
    2769           0 :     PyObject_GC_UnTrack(it);
    2770           0 :     Py_XDECREF(it->ao);
    2771           0 :     PyObject_GC_Del(it);
    2772           0 : }
    2773             : 
    2774             : static int
    2775           0 : arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
    2776             : {
    2777           0 :     Py_VISIT(it->ao);
    2778           0 :     return 0;
    2779             : }
    2780             : 
    2781             : static PyObject *
    2782           0 : arrayiter_reduce(arrayiterobject *it)
    2783             : {
    2784           0 :     return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
    2785             :                          it->ao, it->index);
    2786             : }
    2787             : 
    2788             : static PyObject *
    2789           0 : arrayiter_setstate(arrayiterobject *it, PyObject *state)
    2790             : {
    2791           0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
    2792           0 :     if (index == -1 && PyErr_Occurred())
    2793           0 :         return NULL;
    2794           0 :     if (index < 0)
    2795           0 :         index = 0;
    2796           0 :     it->index = index;
    2797           0 :     Py_RETURN_NONE;
    2798             : }
    2799             : 
    2800             : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
    2801             : static PyMethodDef arrayiter_methods[] = {
    2802             :     {"__reduce__",      (PyCFunction)arrayiter_reduce, METH_NOARGS,
    2803             :      reduce_doc},
    2804             :     {"__setstate__",    (PyCFunction)arrayiter_setstate, METH_O,
    2805             :      setstate_doc},
    2806             :     {NULL, NULL} /* sentinel */
    2807             : };
    2808             : 
    2809             : static PyTypeObject PyArrayIter_Type = {
    2810             :     PyVarObject_HEAD_INIT(NULL, 0)
    2811             :     "arrayiterator",                        /* tp_name */
    2812             :     sizeof(arrayiterobject),                /* tp_basicsize */
    2813             :     0,                                      /* tp_itemsize */
    2814             :     /* methods */
    2815             :     (destructor)arrayiter_dealloc,              /* tp_dealloc */
    2816             :     0,                                      /* tp_print */
    2817             :     0,                                      /* tp_getattr */
    2818             :     0,                                      /* tp_setattr */
    2819             :     0,                                      /* tp_reserved */
    2820             :     0,                                      /* tp_repr */
    2821             :     0,                                      /* tp_as_number */
    2822             :     0,                                      /* tp_as_sequence */
    2823             :     0,                                      /* tp_as_mapping */
    2824             :     0,                                      /* tp_hash */
    2825             :     0,                                      /* tp_call */
    2826             :     0,                                      /* tp_str */
    2827             :     PyObject_GenericGetAttr,                /* tp_getattro */
    2828             :     0,                                      /* tp_setattro */
    2829             :     0,                                      /* tp_as_buffer */
    2830             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
    2831             :     0,                                      /* tp_doc */
    2832             :     (traverseproc)arrayiter_traverse,           /* tp_traverse */
    2833             :     0,                                          /* tp_clear */
    2834             :     0,                                      /* tp_richcompare */
    2835             :     0,                                      /* tp_weaklistoffset */
    2836             :     PyObject_SelfIter,                          /* tp_iter */
    2837             :     (iternextfunc)arrayiter_next,               /* tp_iternext */
    2838             :     arrayiter_methods,                      /* tp_methods */
    2839             : };
    2840             : 
    2841             : 
    2842             : /*********************** Install Module **************************/
    2843             : 
    2844             : /* No functions in array module. */
    2845             : static PyMethodDef a_methods[] = {
    2846             :     {"_array_reconstructor", array_reconstructor, METH_VARARGS,
    2847             :      PyDoc_STR("Internal. Used for pickling support.")},
    2848             :     {NULL, NULL, 0, NULL}        /* Sentinel */
    2849             : };
    2850             : 
    2851             : static struct PyModuleDef arraymodule = {
    2852             :     PyModuleDef_HEAD_INIT,
    2853             :     "array",
    2854             :     module_doc,
    2855             :     -1,
    2856             :     a_methods,
    2857             :     NULL,
    2858             :     NULL,
    2859             :     NULL,
    2860             :     NULL
    2861             : };
    2862             : 
    2863             : 
    2864             : PyMODINIT_FUNC
    2865           1 : PyInit_array(void)
    2866             : {
    2867             :     PyObject *m;
    2868             :     char buffer[Py_ARRAY_LENGTH(descriptors)], *p;
    2869             :     PyObject *typecodes;
    2870           1 :     Py_ssize_t size = 0;
    2871             :     struct arraydescr *descr;
    2872             : 
    2873           1 :     if (PyType_Ready(&Arraytype) < 0)
    2874           0 :         return NULL;
    2875           1 :     Py_TYPE(&PyArrayIter_Type) = &PyType_Type;
    2876           1 :     m = PyModule_Create(&arraymodule);
    2877           1 :     if (m == NULL)
    2878           0 :         return NULL;
    2879             : 
    2880           1 :     Py_INCREF((PyObject *)&Arraytype);
    2881           1 :     PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
    2882           1 :     Py_INCREF((PyObject *)&Arraytype);
    2883           1 :     PyModule_AddObject(m, "array", (PyObject *)&Arraytype);
    2884             : 
    2885          14 :     for (descr=descriptors; descr->typecode != '\0'; descr++) {
    2886          13 :         size++;
    2887             :     }
    2888             : 
    2889           1 :     p = buffer;
    2890          14 :     for (descr = descriptors; descr->typecode != '\0'; descr++) {
    2891          13 :         *p++ = (char)descr->typecode;
    2892             :     }
    2893           1 :     typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
    2894             : 
    2895           1 :     PyModule_AddObject(m, "typecodes", typecodes);
    2896             : 
    2897           1 :     if (PyErr_Occurred()) {
    2898           0 :         Py_DECREF(m);
    2899           0 :         m = NULL;
    2900             :     }
    2901           1 :     return m;
    2902             : }

Generated by: LCOV version 1.10