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