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