Branch data Line data Source code
1 : : /* PyByteArray (bytearray) implementation */
2 : :
3 : : #define PY_SSIZE_T_CLEAN
4 : : #include "Python.h"
5 : : #include "pycore_abstract.h" // _PyIndex_Check()
6 : : #include "pycore_bytes_methods.h"
7 : : #include "pycore_bytesobject.h"
8 : : #include "pycore_object.h" // _PyObject_GC_UNTRACK()
9 : : #include "pycore_strhex.h" // _Py_strhex_with_sep()
10 : : #include "pycore_long.h" // _PyLong_FromUnsignedChar()
11 : : #include "bytesobject.h"
12 : :
13 : : /*[clinic input]
14 : : class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
15 : : [clinic start generated code]*/
16 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
17 : :
18 : : /* For PyByteArray_AS_STRING(). */
19 : : char _PyByteArray_empty_string[] = "";
20 : :
21 : : /* Helpers */
22 : :
23 : : static int
24 : 7383490 : _getbytevalue(PyObject* arg, int *value)
25 : : {
26 : : int overflow;
27 : 7383490 : long face_value = PyLong_AsLongAndOverflow(arg, &overflow);
28 : :
29 [ + + + + ]: 7383490 : if (face_value == -1 && PyErr_Occurred()) {
30 : 13 : *value = -1;
31 : 13 : return 0;
32 : : }
33 [ + + + + ]: 7383477 : if (face_value < 0 || face_value >= 256) {
34 : : /* this includes an overflow in converting to C long */
35 : 19 : PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
36 : 19 : *value = -1;
37 : 19 : return 0;
38 : : }
39 : :
40 : 7383458 : *value = face_value;
41 : 7383458 : return 1;
42 : : }
43 : :
44 : : static int
45 : 1537893 : bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
46 : : {
47 : : void *ptr;
48 [ + + ]: 1537893 : if (view == NULL) {
49 : 1 : PyErr_SetString(PyExc_BufferError,
50 : : "bytearray_getbuffer: view==NULL argument is obsolete");
51 : 1 : return -1;
52 : : }
53 : 1537892 : ptr = (void *) PyByteArray_AS_STRING(obj);
54 : : /* cannot fail if view != NULL and readonly == 0 */
55 : 1537892 : (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
56 : 1537892 : obj->ob_exports++;
57 : 1537892 : return 0;
58 : : }
59 : :
60 : : static void
61 : 1537892 : bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
62 : : {
63 : 1537892 : obj->ob_exports--;
64 : 1537892 : }
65 : :
66 : : static int
67 : 1400682 : _canresize(PyByteArrayObject *self)
68 : : {
69 [ + + ]: 1400682 : if (self->ob_exports > 0) {
70 : 11 : PyErr_SetString(PyExc_BufferError,
71 : : "Existing exports of data: object cannot be re-sized");
72 : 11 : return 0;
73 : : }
74 : 1400671 : return 1;
75 : : }
76 : :
77 : : #include "clinic/bytearrayobject.c.h"
78 : :
79 : : /* Direct API functions */
80 : :
81 : : PyObject *
82 : 2256 : PyByteArray_FromObject(PyObject *input)
83 : : {
84 : 2256 : return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input);
85 : : }
86 : :
87 : : static PyObject *
88 : 15 : _PyByteArray_FromBufferObject(PyObject *obj)
89 : : {
90 : : PyObject *result;
91 : : Py_buffer view;
92 : :
93 [ + + ]: 15 : if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
94 : 4 : return NULL;
95 : : }
96 : 11 : result = PyByteArray_FromStringAndSize(NULL, view.len);
97 [ + - - + ]: 22 : if (result != NULL &&
98 : 11 : PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
99 : : &view, view.len, 'C') < 0)
100 : : {
101 [ # # ]: 0 : Py_CLEAR(result);
102 : : }
103 : 11 : PyBuffer_Release(&view);
104 : 11 : return result;
105 : : }
106 : :
107 : : PyObject *
108 : 519546 : PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
109 : : {
110 : : PyByteArrayObject *new;
111 : : Py_ssize_t alloc;
112 : :
113 [ - + ]: 519546 : if (size < 0) {
114 : 0 : PyErr_SetString(PyExc_SystemError,
115 : : "Negative size passed to PyByteArray_FromStringAndSize");
116 : 0 : return NULL;
117 : : }
118 : :
119 : : /* Prevent buffer overflow when setting alloc to size+1. */
120 [ - + ]: 519546 : if (size == PY_SSIZE_T_MAX) {
121 : : return PyErr_NoMemory();
122 : : }
123 : :
124 : 519546 : new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
125 [ - + ]: 519546 : if (new == NULL)
126 : 0 : return NULL;
127 : :
128 [ + + ]: 519546 : if (size == 0) {
129 : 16530 : new->ob_bytes = NULL;
130 : 16530 : alloc = 0;
131 : : }
132 : : else {
133 : 503016 : alloc = size + 1;
134 : 503016 : new->ob_bytes = PyObject_Malloc(alloc);
135 [ - + ]: 503016 : if (new->ob_bytes == NULL) {
136 : 0 : Py_DECREF(new);
137 : : return PyErr_NoMemory();
138 : : }
139 [ + + + - ]: 503016 : if (bytes != NULL && size > 0)
140 : 429324 : memcpy(new->ob_bytes, bytes, size);
141 : 503016 : new->ob_bytes[size] = '\0'; /* Trailing null byte */
142 : : }
143 : 519546 : Py_SET_SIZE(new, size);
144 : 519546 : new->ob_alloc = alloc;
145 : 519546 : new->ob_start = new->ob_bytes;
146 : 519546 : new->ob_exports = 0;
147 : :
148 : 519546 : return (PyObject *)new;
149 : : }
150 : :
151 : : Py_ssize_t
152 : 1 : PyByteArray_Size(PyObject *self)
153 : : {
154 : : assert(self != NULL);
155 : : assert(PyByteArray_Check(self));
156 : :
157 : 1 : return PyByteArray_GET_SIZE(self);
158 : : }
159 : :
160 : : char *
161 : 3805 : PyByteArray_AsString(PyObject *self)
162 : : {
163 : : assert(self != NULL);
164 : : assert(PyByteArray_Check(self));
165 : :
166 : 3805 : return PyByteArray_AS_STRING(self);
167 : : }
168 : :
169 : : int
170 : 1408382 : PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
171 : : {
172 : : void *sval;
173 : 1408382 : PyByteArrayObject *obj = ((PyByteArrayObject *)self);
174 : : /* All computations are done unsigned to avoid integer overflows
175 : : (see issue #22335). */
176 : 1408382 : size_t alloc = (size_t) obj->ob_alloc;
177 : 1408382 : size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
178 : 1408382 : size_t size = (size_t) requested_size;
179 : :
180 : : assert(self != NULL);
181 : : assert(PyByteArray_Check(self));
182 : : assert(logical_offset <= alloc);
183 : : assert(requested_size >= 0);
184 : :
185 [ + + ]: 1408382 : if (requested_size == Py_SIZE(self)) {
186 : 79738 : return 0;
187 : : }
188 [ + + ]: 1328644 : if (!_canresize(obj)) {
189 : 4 : return -1;
190 : : }
191 : :
192 [ + + ]: 1328640 : if (size + logical_offset + 1 <= alloc) {
193 : : /* Current buffer is large enough to host the requested size,
194 : : decide on a strategy. */
195 [ + + ]: 256455 : if (size < alloc / 2) {
196 : : /* Major downsize; resize down to exact size */
197 : 70818 : alloc = size + 1;
198 : : }
199 : : else {
200 : : /* Minor downsize; quick exit */
201 : 185637 : Py_SET_SIZE(self, size);
202 : 185637 : PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
203 : 185637 : return 0;
204 : : }
205 : : }
206 : : else {
207 : : /* Need growing, decide on a strategy */
208 [ + + ]: 1072185 : if (size <= alloc * 1.125) {
209 : : /* Moderate upsize; overallocate similar to list_resize() */
210 [ + + ]: 135423 : alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
211 : : }
212 : : else {
213 : : /* Major upsize; resize up to exact size */
214 : 936762 : alloc = size + 1;
215 : : }
216 : : }
217 [ - + ]: 1143003 : if (alloc > PY_SSIZE_T_MAX) {
218 : : PyErr_NoMemory();
219 : 0 : return -1;
220 : : }
221 : :
222 [ + + ]: 1143003 : if (logical_offset > 0) {
223 : 69546 : sval = PyObject_Malloc(alloc);
224 [ - + ]: 69546 : if (sval == NULL) {
225 : : PyErr_NoMemory();
226 : 0 : return -1;
227 : : }
228 : 69546 : memcpy(sval, PyByteArray_AS_STRING(self),
229 [ + + ]: 69546 : Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
230 : 69546 : PyObject_Free(obj->ob_bytes);
231 : : }
232 : : else {
233 : 1073457 : sval = PyObject_Realloc(obj->ob_bytes, alloc);
234 [ - + ]: 1073457 : if (sval == NULL) {
235 : : PyErr_NoMemory();
236 : 0 : return -1;
237 : : }
238 : : }
239 : :
240 : 1143003 : obj->ob_bytes = obj->ob_start = sval;
241 : 1143003 : Py_SET_SIZE(self, size);
242 : 1143003 : obj->ob_alloc = alloc;
243 : 1143003 : obj->ob_bytes[size] = '\0'; /* Trailing null byte */
244 : :
245 : 1143003 : return 0;
246 : : }
247 : :
248 : : PyObject *
249 : 160 : PyByteArray_Concat(PyObject *a, PyObject *b)
250 : : {
251 : : Py_buffer va, vb;
252 : 160 : PyByteArrayObject *result = NULL;
253 : :
254 : 160 : va.len = -1;
255 : 160 : vb.len = -1;
256 [ + - + + ]: 320 : if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
257 : 160 : PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
258 : 1 : PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
259 : 1 : Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
260 : 1 : goto done;
261 : : }
262 : :
263 [ - + ]: 159 : if (va.len > PY_SSIZE_T_MAX - vb.len) {
264 : : PyErr_NoMemory();
265 : 0 : goto done;
266 : : }
267 : :
268 : : result = (PyByteArrayObject *) \
269 : 159 : PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
270 : : // result->ob_bytes is NULL if result is an empty bytearray:
271 : : // if va.len + vb.len equals zero.
272 [ - + - + ]: 159 : if (result != NULL && result->ob_bytes != NULL) {
273 : 159 : memcpy(result->ob_bytes, va.buf, va.len);
274 : 159 : memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
275 : : }
276 : :
277 : 0 : done:
278 [ + - ]: 160 : if (va.len != -1)
279 : 160 : PyBuffer_Release(&va);
280 [ + + ]: 160 : if (vb.len != -1)
281 : 159 : PyBuffer_Release(&vb);
282 : 160 : return (PyObject *)result;
283 : : }
284 : :
285 : : /* Functions stuffed into the type object */
286 : :
287 : : static Py_ssize_t
288 : 1801038 : bytearray_length(PyByteArrayObject *self)
289 : : {
290 : 1801038 : return Py_SIZE(self);
291 : : }
292 : :
293 : : static PyObject *
294 : 33930 : bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
295 : : {
296 : : Py_ssize_t size;
297 : : Py_buffer vo;
298 : :
299 [ + + ]: 33930 : if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
300 : 3 : PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
301 : 3 : Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
302 : 3 : return NULL;
303 : : }
304 : :
305 : 33927 : size = Py_SIZE(self);
306 [ - + ]: 33927 : if (size > PY_SSIZE_T_MAX - vo.len) {
307 : 0 : PyBuffer_Release(&vo);
308 : : return PyErr_NoMemory();
309 : : }
310 [ - + ]: 33927 : if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
311 : 0 : PyBuffer_Release(&vo);
312 : 0 : return NULL;
313 : : }
314 : 33927 : memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
315 : 33927 : PyBuffer_Release(&vo);
316 : 33927 : Py_INCREF(self);
317 : 33927 : return (PyObject *)self;
318 : : }
319 : :
320 : : static PyObject *
321 : 191 : bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
322 : : {
323 [ + + ]: 191 : if (count < 0)
324 : 1 : count = 0;
325 : 191 : const Py_ssize_t mysize = Py_SIZE(self);
326 [ + + + + ]: 191 : if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
327 : : return PyErr_NoMemory();
328 : 190 : Py_ssize_t size = mysize * count;
329 : 190 : PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
330 : 190 : const char* buf = PyByteArray_AS_STRING(self);
331 [ + - + + ]: 190 : if (result != NULL && size != 0) {
332 : 188 : _PyBytes_Repeat(result->ob_bytes, size, buf, mysize);
333 : : }
334 : 190 : return (PyObject *)result;
335 : : }
336 : :
337 : : static PyObject *
338 : 3 : bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
339 : : {
340 [ - + ]: 3 : if (count < 0)
341 : 0 : count = 0;
342 [ - + ]: 3 : else if (count == 1) {
343 : 0 : Py_INCREF(self);
344 : 0 : return (PyObject*)self;
345 : : }
346 : :
347 : 3 : const Py_ssize_t mysize = Py_SIZE(self);
348 [ + - + + ]: 3 : if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
349 : : return PyErr_NoMemory();
350 : 2 : const Py_ssize_t size = mysize * count;
351 [ - + ]: 2 : if (PyByteArray_Resize((PyObject *)self, size) < 0)
352 : 0 : return NULL;
353 : :
354 : 2 : char* buf = PyByteArray_AS_STRING(self);
355 : 2 : _PyBytes_Repeat(buf, size, buf, mysize);
356 : :
357 : 2 : Py_INCREF(self);
358 : 2 : return (PyObject *)self;
359 : : }
360 : :
361 : : static PyObject *
362 : 8 : bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
363 : : {
364 [ + + + + ]: 8 : if (i < 0 || i >= Py_SIZE(self)) {
365 : 2 : PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
366 : 2 : return NULL;
367 : : }
368 : 6 : return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
369 : : }
370 : :
371 : : static PyObject *
372 : 1560841 : bytearray_subscript(PyByteArrayObject *self, PyObject *index)
373 : : {
374 [ + + ]: 1560841 : if (_PyIndex_Check(index)) {
375 : 1153032 : Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
376 : :
377 [ + + + + ]: 1153032 : if (i == -1 && PyErr_Occurred())
378 : 6 : return NULL;
379 : :
380 [ + + ]: 1153026 : if (i < 0)
381 : 10 : i += PyByteArray_GET_SIZE(self);
382 : :
383 [ + + + + ]: 1153026 : if (i < 0 || i >= Py_SIZE(self)) {
384 : 10 : PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
385 : 10 : return NULL;
386 : : }
387 : 1153016 : return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
388 : : }
389 [ + + ]: 407809 : else if (PySlice_Check(index)) {
390 : : Py_ssize_t start, stop, step, slicelength, i;
391 : : size_t cur;
392 [ + + ]: 407808 : if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
393 : 2 : return NULL;
394 : : }
395 : 407806 : slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
396 : : &start, &stop, step);
397 : :
398 [ + + ]: 407806 : if (slicelength <= 0)
399 : 11444 : return PyByteArray_FromStringAndSize("", 0);
400 [ + + ]: 396362 : else if (step == 1) {
401 : 363143 : return PyByteArray_FromStringAndSize(
402 : 363143 : PyByteArray_AS_STRING(self) + start, slicelength);
403 : : }
404 : : else {
405 : 33219 : char *source_buf = PyByteArray_AS_STRING(self);
406 : : char *result_buf;
407 : : PyObject *result;
408 : :
409 : 33219 : result = PyByteArray_FromStringAndSize(NULL, slicelength);
410 [ - + ]: 33219 : if (result == NULL)
411 : 0 : return NULL;
412 : :
413 : 33219 : result_buf = PyByteArray_AS_STRING(result);
414 [ + + ]: 9882474 : for (cur = start, i = 0; i < slicelength;
415 : 9849255 : cur += step, i++) {
416 : 9849255 : result_buf[i] = source_buf[cur];
417 : : }
418 : 33219 : return result;
419 : : }
420 : : }
421 : : else {
422 : 1 : PyErr_Format(PyExc_TypeError,
423 : : "bytearray indices must be integers or slices, not %.200s",
424 : 1 : Py_TYPE(index)->tp_name);
425 : 1 : return NULL;
426 : : }
427 : : }
428 : :
429 : : static int
430 : 292774 : bytearray_setslice_linear(PyByteArrayObject *self,
431 : : Py_ssize_t lo, Py_ssize_t hi,
432 : : char *bytes, Py_ssize_t bytes_len)
433 : : {
434 : 292774 : Py_ssize_t avail = hi - lo;
435 : 292774 : char *buf = PyByteArray_AS_STRING(self);
436 : 292774 : Py_ssize_t growth = bytes_len - avail;
437 : 292774 : int res = 0;
438 : : assert(avail >= 0);
439 : :
440 [ + + ]: 292774 : if (growth < 0) {
441 [ + + ]: 70044 : if (!_canresize(self))
442 : 4 : return -1;
443 : :
444 [ + + ]: 70040 : if (lo == 0) {
445 : : /* Shrink the buffer by advancing its logical start */
446 : 69935 : self->ob_start -= growth;
447 : : /*
448 : : 0 lo hi old_size
449 : : | |<----avail----->|<-----tail------>|
450 : : | |<-bytes_len->|<-----tail------>|
451 : : 0 new_lo new_hi new_size
452 : : */
453 : : }
454 : : else {
455 : : /*
456 : : 0 lo hi old_size
457 : : | |<----avail----->|<-----tomove------>|
458 : : | |<-bytes_len->|<-----tomove------>|
459 : : 0 lo new_hi new_size
460 : : */
461 : 105 : memmove(buf + lo + bytes_len, buf + hi,
462 : 105 : Py_SIZE(self) - hi);
463 : : }
464 [ - + ]: 70040 : if (PyByteArray_Resize((PyObject *)self,
465 : 70040 : Py_SIZE(self) + growth) < 0) {
466 : : /* Issue #19578: Handling the memory allocation failure here is
467 : : tricky here because the bytearray object has already been
468 : : modified. Depending on growth and lo, the behaviour is
469 : : different.
470 : :
471 : : If growth < 0 and lo != 0, the operation is completed, but a
472 : : MemoryError is still raised and the memory block is not
473 : : shrunk. Otherwise, the bytearray is restored in its previous
474 : : state and a MemoryError is raised. */
475 [ # # ]: 0 : if (lo == 0) {
476 : 0 : self->ob_start += growth;
477 : 0 : return -1;
478 : : }
479 : : /* memmove() removed bytes, the bytearray object cannot be
480 : : restored in its previous state. */
481 : 0 : Py_SET_SIZE(self, Py_SIZE(self) + growth);
482 : 0 : res = -1;
483 : : }
484 : 70040 : buf = PyByteArray_AS_STRING(self);
485 : : }
486 [ + + ]: 222730 : else if (growth > 0) {
487 [ - + ]: 221961 : if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
488 : : PyErr_NoMemory();
489 : 0 : return -1;
490 : : }
491 : :
492 [ + + ]: 221961 : if (PyByteArray_Resize((PyObject *)self,
493 : 221961 : Py_SIZE(self) + growth) < 0) {
494 : 3 : return -1;
495 : : }
496 : 221958 : buf = PyByteArray_AS_STRING(self);
497 : : /* Make the place for the additional bytes */
498 : : /*
499 : : 0 lo hi old_size
500 : : | |<-avail->|<-----tomove------>|
501 : : | |<---bytes_len-->|<-----tomove------>|
502 : : 0 lo new_hi new_size
503 : : */
504 : 221958 : memmove(buf + lo + bytes_len, buf + hi,
505 : 221958 : Py_SIZE(self) - lo - bytes_len);
506 : : }
507 : :
508 [ + + ]: 292767 : if (bytes_len > 0)
509 : 222385 : memcpy(buf + lo, bytes, bytes_len);
510 : 292767 : return res;
511 : : }
512 : :
513 : : static int
514 : 221575 : bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
515 : : PyObject *values)
516 : : {
517 : : Py_ssize_t needed;
518 : : void *bytes;
519 : : Py_buffer vbytes;
520 : 221575 : int res = 0;
521 : :
522 : 221575 : vbytes.len = -1;
523 [ + + ]: 221575 : if (values == (PyObject *)self) {
524 : : /* Make a copy and call this function recursively */
525 : : int err;
526 : 1 : values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
527 : : PyByteArray_GET_SIZE(values));
528 [ - + ]: 1 : if (values == NULL)
529 : 0 : return -1;
530 : 1 : err = bytearray_setslice(self, lo, hi, values);
531 : 1 : Py_DECREF(values);
532 : 1 : return err;
533 : : }
534 [ - + ]: 221574 : if (values == NULL) {
535 : : /* del b[lo:hi] */
536 : 0 : bytes = NULL;
537 : 0 : needed = 0;
538 : : }
539 : : else {
540 [ - + ]: 221574 : if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
541 : 0 : PyErr_Format(PyExc_TypeError,
542 : : "can't set bytearray slice from %.100s",
543 : 0 : Py_TYPE(values)->tp_name);
544 : 0 : return -1;
545 : : }
546 : 221574 : needed = vbytes.len;
547 : 221574 : bytes = vbytes.buf;
548 : : }
549 : :
550 [ - + ]: 221574 : if (lo < 0)
551 : 0 : lo = 0;
552 [ - + ]: 221574 : if (hi < lo)
553 : 0 : hi = lo;
554 [ - + ]: 221574 : if (hi > Py_SIZE(self))
555 : 0 : hi = Py_SIZE(self);
556 : :
557 : 221574 : res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
558 [ + - ]: 221574 : if (vbytes.len != -1)
559 : 221574 : PyBuffer_Release(&vbytes);
560 : 221574 : return res;
561 : : }
562 : :
563 : : static int
564 : 1 : bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
565 : : {
566 : 1 : int ival = -1;
567 : :
568 : : // GH-91153: We need to do this *before* the size check, in case value has a
569 : : // nasty __index__ method that changes the size of the bytearray:
570 [ + - - + ]: 1 : if (value && !_getbytevalue(value, &ival)) {
571 : 0 : return -1;
572 : : }
573 : :
574 [ - + ]: 1 : if (i < 0) {
575 : 0 : i += Py_SIZE(self);
576 : : }
577 : :
578 [ + - + - ]: 1 : if (i < 0 || i >= Py_SIZE(self)) {
579 : 1 : PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
580 : 1 : return -1;
581 : : }
582 : :
583 [ # # ]: 0 : if (value == NULL) {
584 : 0 : return bytearray_setslice(self, i, i+1, NULL);
585 : : }
586 : :
587 : : assert(0 <= ival && ival < 256);
588 : 0 : PyByteArray_AS_STRING(self)[i] = ival;
589 : 0 : return 0;
590 : : }
591 : :
592 : : static int
593 : 4359056 : bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
594 : : {
595 : : Py_ssize_t start, stop, step, slicelen, needed;
596 : : char *buf, *bytes;
597 : 4359056 : buf = PyByteArray_AS_STRING(self);
598 : :
599 [ + + ]: 4359056 : if (_PyIndex_Check(index)) {
600 : 4282964 : Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
601 : :
602 [ + + - + ]: 4282964 : if (i == -1 && PyErr_Occurred()) {
603 : 4282960 : return -1;
604 : : }
605 : :
606 : 4282964 : int ival = -1;
607 : :
608 : : // GH-91153: We need to do this *before* the size check, in case values
609 : : // has a nasty __index__ method that changes the size of the bytearray:
610 [ + + + + ]: 4282964 : if (values && !_getbytevalue(values, &ival)) {
611 : 3 : return -1;
612 : : }
613 : :
614 [ + + ]: 4282961 : if (i < 0) {
615 : 3 : i += PyByteArray_GET_SIZE(self);
616 : : }
617 : :
618 [ + + + + ]: 4282961 : if (i < 0 || i >= Py_SIZE(self)) {
619 : 3134 : PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
620 : 3134 : return -1;
621 : : }
622 : :
623 [ + + ]: 4279827 : if (values == NULL) {
624 : : /* Fall through to slice assignment */
625 : 4 : start = i;
626 : 4 : stop = i + 1;
627 : 4 : step = 1;
628 : 4 : slicelen = 1;
629 : : }
630 : : else {
631 : : assert(0 <= ival && ival < 256);
632 : 4279823 : buf[i] = (char)ival;
633 : 4279823 : return 0;
634 : : }
635 : : }
636 [ + + ]: 76092 : else if (PySlice_Check(index)) {
637 [ - + ]: 76091 : if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
638 : 0 : return -1;
639 : : }
640 : 76091 : slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
641 : : &stop, step);
642 : : }
643 : : else {
644 : 1 : PyErr_Format(PyExc_TypeError,
645 : : "bytearray indices must be integers or slices, not %.200s",
646 : 1 : Py_TYPE(index)->tp_name);
647 : 1 : return -1;
648 : : }
649 : :
650 [ + + ]: 76095 : if (values == NULL) {
651 : 71520 : bytes = NULL;
652 : 71520 : needed = 0;
653 : : }
654 [ + + + + ]: 4575 : else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
655 : : int err;
656 [ + + + + ]: 2262 : if (PyNumber_Check(values) || PyUnicode_Check(values)) {
657 : 6 : PyErr_SetString(PyExc_TypeError,
658 : : "can assign only bytes, buffers, or iterables "
659 : : "of ints in range(0, 256)");
660 : 6 : return -1;
661 : : }
662 : : /* Make a copy and call this function recursively */
663 : 2256 : values = PyByteArray_FromObject(values);
664 [ + + ]: 2256 : if (values == NULL)
665 : 5 : return -1;
666 : 2251 : err = bytearray_ass_subscript(self, index, values);
667 : 2251 : Py_DECREF(values);
668 : 2251 : return err;
669 : : }
670 : : else {
671 : : assert(PyByteArray_Check(values));
672 : 2313 : bytes = PyByteArray_AS_STRING(values);
673 : 2313 : needed = Py_SIZE(values);
674 : : }
675 : : /* Make sure b[5:2] = ... inserts before 5, not before 2. */
676 [ + + + + ]: 73833 : if ((step < 0 && start < stop) ||
677 [ + + + + ]: 73441 : (step > 0 && start > stop))
678 : 1107 : stop = start;
679 [ + + ]: 73833 : if (step == 1) {
680 : 71200 : return bytearray_setslice_linear(self, start, stop, bytes, needed);
681 : : }
682 : : else {
683 [ + + ]: 2633 : if (needed == 0) {
684 : : /* Delete slice */
685 : : size_t cur;
686 : : Py_ssize_t i;
687 : :
688 [ + + ]: 1980 : if (!_canresize(self))
689 : 1 : return -1;
690 : :
691 [ + + ]: 1979 : if (slicelen == 0)
692 : : /* Nothing to do here. */
693 : 1366 : return 0;
694 : :
695 [ + + ]: 613 : if (step < 0) {
696 : 268 : stop = start + 1;
697 : 268 : start = stop + step * (slicelen - 1) - 1;
698 : 268 : step = -step;
699 : : }
700 : 613 : for (cur = start, i = 0;
701 [ + + ]: 21420 : i < slicelen; cur += step, i++) {
702 : 20807 : Py_ssize_t lim = step - 1;
703 : :
704 [ + + ]: 20807 : if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
705 : 512 : lim = PyByteArray_GET_SIZE(self) - cur - 1;
706 : :
707 : 20807 : memmove(buf + cur - i,
708 : 20807 : buf + cur + 1, lim);
709 : : }
710 : : /* Move the tail of the bytes, in one chunk */
711 : 613 : cur = start + (size_t)slicelen*step;
712 [ + + ]: 613 : if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
713 : 101 : memmove(buf + cur - slicelen,
714 : 101 : buf + cur,
715 : 101 : PyByteArray_GET_SIZE(self) - cur);
716 : : }
717 [ - + ]: 613 : if (PyByteArray_Resize((PyObject *)self,
718 : 613 : PyByteArray_GET_SIZE(self) - slicelen) < 0)
719 : 0 : return -1;
720 : :
721 : 613 : return 0;
722 : : }
723 : : else {
724 : : /* Assign slice */
725 : : Py_ssize_t i;
726 : : size_t cur;
727 : :
728 [ - + ]: 653 : if (needed != slicelen) {
729 : 0 : PyErr_Format(PyExc_ValueError,
730 : : "attempt to assign bytes of size %zd "
731 : : "to extended slice of size %zd",
732 : : needed, slicelen);
733 : 0 : return -1;
734 : : }
735 [ + + ]: 21740 : for (cur = start, i = 0; i < slicelen; cur += step, i++)
736 : 21087 : buf[cur] = bytes[i];
737 : 653 : return 0;
738 : : }
739 : : }
740 : : }
741 : :
742 : : /*[clinic input]
743 : : bytearray.__init__
744 : :
745 : : source as arg: object = NULL
746 : : encoding: str = NULL
747 : : errors: str = NULL
748 : :
749 : : [clinic start generated code]*/
750 : :
751 : : static int
752 : 894853 : bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
753 : : const char *encoding, const char *errors)
754 : : /*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/
755 : : {
756 : : Py_ssize_t count;
757 : : PyObject *it;
758 : : PyObject *(*iternext)(PyObject *);
759 : :
760 [ - + ]: 894853 : if (Py_SIZE(self) != 0) {
761 : : /* Empty previous contents (yes, do this first of all!) */
762 [ # # ]: 0 : if (PyByteArray_Resize((PyObject *)self, 0) < 0)
763 : 0 : return -1;
764 : : }
765 : :
766 : : /* Make a quick exit if no first argument */
767 [ + + ]: 894853 : if (arg == NULL) {
768 [ + + + + ]: 633238 : if (encoding != NULL || errors != NULL) {
769 [ + + ]: 2 : PyErr_SetString(PyExc_TypeError,
770 : : encoding != NULL ?
771 : : "encoding without a string argument" :
772 : : "errors without a string argument");
773 : 2 : return -1;
774 : : }
775 : 633236 : return 0;
776 : : }
777 : :
778 [ + + ]: 261615 : if (PyUnicode_Check(arg)) {
779 : : /* Encode via the codec registry */
780 : : PyObject *encoded, *new;
781 [ + + ]: 36 : if (encoding == NULL) {
782 : 2 : PyErr_SetString(PyExc_TypeError,
783 : : "string argument without an encoding");
784 : 2 : return -1;
785 : : }
786 : 34 : encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
787 [ + + ]: 34 : if (encoded == NULL)
788 : 9 : return -1;
789 : : assert(PyBytes_Check(encoded));
790 : 25 : new = bytearray_iconcat(self, encoded);
791 : 25 : Py_DECREF(encoded);
792 [ - + ]: 25 : if (new == NULL)
793 : 0 : return -1;
794 : 25 : Py_DECREF(new);
795 : 25 : return 0;
796 : : }
797 : :
798 : : /* If it's not unicode, there can't be encoding or errors */
799 [ + + + + ]: 261579 : if (encoding != NULL || errors != NULL) {
800 [ + + ]: 4 : PyErr_SetString(PyExc_TypeError,
801 : : encoding != NULL ?
802 : : "encoding without a string argument" :
803 : : "errors without a string argument");
804 : 4 : return -1;
805 : : }
806 : :
807 : : /* Is it an int? */
808 [ + + ]: 261575 : if (_PyIndex_Check(arg)) {
809 : 161394 : count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
810 [ + + + + ]: 161394 : if (count == -1 && PyErr_Occurred()) {
811 [ + + ]: 3 : if (!PyErr_ExceptionMatches(PyExc_TypeError))
812 : 2 : return -1;
813 : 1 : PyErr_Clear(); /* fall through */
814 : : }
815 : : else {
816 [ + + ]: 161391 : if (count < 0) {
817 : 1 : PyErr_SetString(PyExc_ValueError, "negative count");
818 : 1 : return -1;
819 : : }
820 [ + + ]: 161390 : if (count > 0) {
821 [ - + ]: 161373 : if (PyByteArray_Resize((PyObject *)self, count))
822 : 0 : return -1;
823 : 161373 : memset(PyByteArray_AS_STRING(self), 0, count);
824 : : }
825 : 161390 : return 0;
826 : : }
827 : : }
828 : :
829 : : /* Use the buffer API */
830 [ + + ]: 100182 : if (PyObject_CheckBuffer(arg)) {
831 : : Py_ssize_t size;
832 : : Py_buffer view;
833 [ - + ]: 91305 : if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
834 : 0 : return -1;
835 : 91305 : size = view.len;
836 [ - + ]: 91305 : if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
837 [ - + ]: 91305 : if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
838 : : &view, size, 'C') < 0)
839 : 0 : goto fail;
840 : 91305 : PyBuffer_Release(&view);
841 : 91305 : return 0;
842 : 0 : fail:
843 : 0 : PyBuffer_Release(&view);
844 : 0 : return -1;
845 : : }
846 : :
847 [ + + + + ]: 8877 : if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) {
848 [ + + ]: 8822 : Py_ssize_t size = PySequence_Fast_GET_SIZE(arg);
849 [ - + ]: 8822 : if (PyByteArray_Resize((PyObject *)self, size) < 0) {
850 : 0 : return -1;
851 : : }
852 [ + + ]: 8822 : PyObject **items = PySequence_Fast_ITEMS(arg);
853 : 8822 : char *s = PyByteArray_AS_STRING(self);
854 [ + + ]: 2292405 : for (Py_ssize_t i = 0; i < size; i++) {
855 : : int value;
856 [ + + ]: 2283606 : if (!PyLong_CheckExact(items[i])) {
857 : : /* Resize to 0 and go through slowpath */
858 [ + - ]: 11 : if (Py_SIZE(self) != 0) {
859 [ - + ]: 11 : if (PyByteArray_Resize((PyObject *)self, 0) < 0) {
860 : 12 : return -1;
861 : : }
862 : : }
863 : 11 : goto slowpath;
864 : : }
865 : 2283595 : int rc = _getbytevalue(items[i], &value);
866 [ + + ]: 2283595 : if (!rc) {
867 : 12 : return -1;
868 : : }
869 : 2283583 : s[i] = value;
870 : : }
871 : 8799 : return 0;
872 : : }
873 : 55 : slowpath:
874 : : /* Get the iterator */
875 : 66 : it = PyObject_GetIter(arg);
876 [ + + ]: 66 : if (it == NULL) {
877 [ + + ]: 2 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
878 : 1 : PyErr_Format(PyExc_TypeError,
879 : : "cannot convert '%.200s' object to bytearray",
880 : 1 : Py_TYPE(arg)->tp_name);
881 : : }
882 : 2 : return -1;
883 : : }
884 : 64 : iternext = *Py_TYPE(it)->tp_iternext;
885 : :
886 : : /* Run the iterator to exhaustion */
887 : 1920 : for (;;) {
888 : : PyObject *item;
889 : : int rc, value;
890 : :
891 : : /* Get the next item */
892 : 1984 : item = iternext(it);
893 [ + + ]: 1984 : if (item == NULL) {
894 [ - + ]: 54 : if (PyErr_Occurred()) {
895 [ # # ]: 0 : if (!PyErr_ExceptionMatches(PyExc_StopIteration))
896 : 10 : goto error;
897 : 0 : PyErr_Clear();
898 : : }
899 : 54 : break;
900 : : }
901 : :
902 : : /* Interpret it as an int (__index__) */
903 : 1930 : rc = _getbytevalue(item, &value);
904 : 1930 : Py_DECREF(item);
905 [ + + ]: 1930 : if (!rc)
906 : 10 : goto error;
907 : :
908 : : /* Append the byte */
909 [ + + ]: 1920 : if (Py_SIZE(self) + 1 < self->ob_alloc) {
910 : 1639 : Py_SET_SIZE(self, Py_SIZE(self) + 1);
911 : 1639 : PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
912 : : }
913 [ - + ]: 281 : else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
914 : 0 : goto error;
915 : 1920 : PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
916 : : }
917 : :
918 : : /* Clean up and return success */
919 : 54 : Py_DECREF(it);
920 : 54 : return 0;
921 : :
922 : 10 : error:
923 : : /* Error handling when it != NULL */
924 : 10 : Py_DECREF(it);
925 : 10 : return -1;
926 : : }
927 : :
928 : : /* Mostly copied from string_repr, but without the
929 : : "smart quote" functionality. */
930 : : static PyObject *
931 : 454 : bytearray_repr(PyByteArrayObject *self)
932 : : {
933 : 454 : const char *className = _PyType_Name(Py_TYPE(self));
934 : 454 : const char *quote_prefix = "(b";
935 : 454 : const char *quote_postfix = ")";
936 : 454 : Py_ssize_t length = Py_SIZE(self);
937 : : /* 6 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
938 : : Py_ssize_t newsize;
939 : : PyObject *v;
940 : : Py_ssize_t i;
941 : : char *bytes;
942 : : char c;
943 : : char *p;
944 : : int quote;
945 : : char *test, *start;
946 : : char *buffer;
947 : :
948 : 454 : newsize = strlen(className);
949 [ - + ]: 454 : if (length > (PY_SSIZE_T_MAX - 6 - newsize) / 4) {
950 : 0 : PyErr_SetString(PyExc_OverflowError,
951 : : "bytearray object is too large to make repr");
952 : 0 : return NULL;
953 : : }
954 : :
955 : 454 : newsize += 6 + length * 4;
956 : 454 : buffer = PyObject_Malloc(newsize);
957 [ - + ]: 454 : if (buffer == NULL) {
958 : : PyErr_NoMemory();
959 : 0 : return NULL;
960 : : }
961 : :
962 : : /* Figure out which quote to use; single is preferred */
963 : 454 : quote = '\'';
964 : 454 : start = PyByteArray_AS_STRING(self);
965 [ + + ]: 24105 : for (test = start; test < start+length; ++test) {
966 [ - + ]: 23651 : if (*test == '"') {
967 : 0 : quote = '\''; /* back to single */
968 : 0 : break;
969 : : }
970 [ - + ]: 23651 : else if (*test == '\'')
971 : 0 : quote = '"';
972 : : }
973 : :
974 : 454 : p = buffer;
975 [ + + ]: 4546 : while (*className)
976 : 4092 : *p++ = *className++;
977 [ + + ]: 1362 : while (*quote_prefix)
978 : 908 : *p++ = *quote_prefix++;
979 : 454 : *p++ = quote;
980 : :
981 : 454 : bytes = PyByteArray_AS_STRING(self);
982 [ + + ]: 24105 : for (i = 0; i < length; i++) {
983 : : /* There's at least enough room for a hex escape
984 : : and a closing quote. */
985 : : assert(newsize - (p - buffer) >= 5);
986 : 23651 : c = bytes[i];
987 [ + - - + ]: 23651 : if (c == '\'' || c == '\\')
988 : 0 : *p++ = '\\', *p++ = c;
989 [ + + ]: 23651 : else if (c == '\t')
990 : 33 : *p++ = '\\', *p++ = 't';
991 [ + + ]: 23618 : else if (c == '\n')
992 : 33 : *p++ = '\\', *p++ = 'n';
993 [ + + ]: 23585 : else if (c == '\r')
994 : 33 : *p++ = '\\', *p++ = 'r';
995 [ + + ]: 23552 : else if (c == 0)
996 : 53 : *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
997 [ + + - + ]: 23499 : else if (c < ' ' || c >= 0x7f) {
998 : 534 : *p++ = '\\';
999 : 534 : *p++ = 'x';
1000 : 534 : *p++ = Py_hexdigits[(c & 0xf0) >> 4];
1001 : 534 : *p++ = Py_hexdigits[c & 0xf];
1002 : : }
1003 : : else
1004 : 22965 : *p++ = c;
1005 : : }
1006 : : assert(newsize - (p - buffer) >= 1);
1007 : 454 : *p++ = quote;
1008 [ + + ]: 908 : while (*quote_postfix) {
1009 : 454 : *p++ = *quote_postfix++;
1010 : : }
1011 : :
1012 : 454 : v = PyUnicode_FromStringAndSize(buffer, p - buffer);
1013 : 454 : PyObject_Free(buffer);
1014 : 454 : return v;
1015 : : }
1016 : :
1017 : : static PyObject *
1018 : 10 : bytearray_str(PyObject *op)
1019 : : {
1020 [ + - ]: 10 : if (_Py_GetConfig()->bytes_warning) {
1021 [ - + ]: 10 : if (PyErr_WarnEx(PyExc_BytesWarning,
1022 : : "str() on a bytearray instance", 1)) {
1023 : 0 : return NULL;
1024 : : }
1025 : : }
1026 : 10 : return bytearray_repr((PyByteArrayObject*)op);
1027 : : }
1028 : :
1029 : : static PyObject *
1030 : 61054 : bytearray_richcompare(PyObject *self, PyObject *other, int op)
1031 : : {
1032 : : Py_ssize_t self_size, other_size;
1033 : : Py_buffer self_bytes, other_bytes;
1034 : : int cmp;
1035 : :
1036 [ + - + + ]: 61054 : if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) {
1037 [ + - + + ]: 57 : if (PyUnicode_Check(self) || PyUnicode_Check(other)) {
1038 [ + - + + : 12 : if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
+ - ]
1039 [ - + ]: 12 : if (PyErr_WarnEx(PyExc_BytesWarning,
1040 : : "Comparison between bytearray and string", 1))
1041 : 0 : return NULL;
1042 : : }
1043 : : }
1044 : 57 : Py_RETURN_NOTIMPLEMENTED;
1045 : : }
1046 : :
1047 : : /* Bytearrays can be compared to anything that supports the buffer API. */
1048 [ - + ]: 60997 : if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1049 : 0 : PyErr_Clear();
1050 : 0 : Py_RETURN_NOTIMPLEMENTED;
1051 : : }
1052 : 60997 : self_size = self_bytes.len;
1053 : :
1054 [ - + ]: 60997 : if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1055 : 0 : PyErr_Clear();
1056 : 0 : PyBuffer_Release(&self_bytes);
1057 : 0 : Py_RETURN_NOTIMPLEMENTED;
1058 : : }
1059 : 60997 : other_size = other_bytes.len;
1060 : :
1061 [ + + + + : 60997 : if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
+ + ]
1062 : : /* Shortcut: if the lengths differ, the objects differ */
1063 : 3 : PyBuffer_Release(&self_bytes);
1064 : 3 : PyBuffer_Release(&other_bytes);
1065 : 3 : return PyBool_FromLong((op == Py_NE));
1066 : : }
1067 : : else {
1068 : 60994 : cmp = memcmp(self_bytes.buf, other_bytes.buf,
1069 : 60994 : Py_MIN(self_size, other_size));
1070 : : /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1071 : :
1072 : 60994 : PyBuffer_Release(&self_bytes);
1073 : 60994 : PyBuffer_Release(&other_bytes);
1074 : :
1075 [ + + ]: 60994 : if (cmp != 0) {
1076 [ + + + + : 97 : Py_RETURN_RICHCOMPARE(cmp, 0, op);
+ + - - +
+ - + + +
+ + + +
+ ]
1077 : : }
1078 : :
1079 [ + + + + : 60897 : Py_RETURN_RICHCOMPARE(self_size, other_size, op);
+ + - + -
- + - + -
+ + - +
- ]
1080 : : }
1081 : :
1082 : : }
1083 : :
1084 : : static void
1085 : 1414399 : bytearray_dealloc(PyByteArrayObject *self)
1086 : : {
1087 [ - + ]: 1414399 : if (self->ob_exports > 0) {
1088 : 0 : PyErr_SetString(PyExc_SystemError,
1089 : : "deallocated bytearray object has exported buffers");
1090 : 0 : PyErr_Print();
1091 : : }
1092 [ + + ]: 1414399 : if (self->ob_bytes != 0) {
1093 : 1314352 : PyObject_Free(self->ob_bytes);
1094 : : }
1095 : 1414399 : Py_TYPE(self)->tp_free((PyObject *)self);
1096 : 1414399 : }
1097 : :
1098 : :
1099 : : /* -------------------------------------------------------------------- */
1100 : : /* Methods */
1101 : :
1102 : : #define STRINGLIB_IS_UNICODE 0
1103 : : #define FASTSEARCH fastsearch
1104 : : #define STRINGLIB(F) stringlib_##F
1105 : : #define STRINGLIB_CHAR char
1106 : : #define STRINGLIB_SIZEOF_CHAR 1
1107 : : #define STRINGLIB_LEN PyByteArray_GET_SIZE
1108 : : #define STRINGLIB_STR PyByteArray_AS_STRING
1109 : : #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1110 : : #define STRINGLIB_ISSPACE Py_ISSPACE
1111 : : #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1112 : : #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1113 : : #define STRINGLIB_FAST_MEMCHR memchr
1114 : : #define STRINGLIB_MUTABLE 1
1115 : :
1116 : : #include "stringlib/fastsearch.h"
1117 : : #include "stringlib/count.h"
1118 : : #include "stringlib/find.h"
1119 : : #include "stringlib/join.h"
1120 : : #include "stringlib/partition.h"
1121 : : #include "stringlib/split.h"
1122 : : #include "stringlib/ctype.h"
1123 : : #include "stringlib/transmogrify.h"
1124 : :
1125 : :
1126 : : static PyObject *
1127 : 599665 : bytearray_find(PyByteArrayObject *self, PyObject *args)
1128 : : {
1129 : 599665 : return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1130 : : }
1131 : :
1132 : : static PyObject *
1133 : 65091 : bytearray_count(PyByteArrayObject *self, PyObject *args)
1134 : : {
1135 : 65091 : return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1136 : : }
1137 : :
1138 : : /*[clinic input]
1139 : : bytearray.clear
1140 : :
1141 : : Remove all items from the bytearray.
1142 : : [clinic start generated code]*/
1143 : :
1144 : : static PyObject *
1145 : 1519 : bytearray_clear_impl(PyByteArrayObject *self)
1146 : : /*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
1147 : : {
1148 [ + + ]: 1519 : if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1149 : 1 : return NULL;
1150 : 1518 : Py_RETURN_NONE;
1151 : : }
1152 : :
1153 : : /*[clinic input]
1154 : : bytearray.copy
1155 : :
1156 : : Return a copy of B.
1157 : : [clinic start generated code]*/
1158 : :
1159 : : static PyObject *
1160 : 5 : bytearray_copy_impl(PyByteArrayObject *self)
1161 : : /*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/
1162 : : {
1163 : 5 : return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1164 : : PyByteArray_GET_SIZE(self));
1165 : : }
1166 : :
1167 : : static PyObject *
1168 : 45 : bytearray_index(PyByteArrayObject *self, PyObject *args)
1169 : : {
1170 : 45 : return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1171 : : }
1172 : :
1173 : : static PyObject *
1174 : 132543 : bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1175 : : {
1176 : 132543 : return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1177 : : }
1178 : :
1179 : : static PyObject *
1180 : 47 : bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1181 : : {
1182 : 47 : return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1183 : : }
1184 : :
1185 : : static int
1186 : 265037 : bytearray_contains(PyObject *self, PyObject *arg)
1187 : : {
1188 : 265037 : return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg);
1189 : : }
1190 : :
1191 : : static PyObject *
1192 : 143 : bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1193 : : {
1194 : 143 : return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1195 : : }
1196 : :
1197 : : static PyObject *
1198 : 13493 : bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1199 : : {
1200 : 13493 : return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1201 : : }
1202 : :
1203 : : /*[clinic input]
1204 : : bytearray.removeprefix as bytearray_removeprefix
1205 : :
1206 : : prefix: Py_buffer
1207 : : /
1208 : :
1209 : : Return a bytearray with the given prefix string removed if present.
1210 : :
1211 : : If the bytearray starts with the prefix string, return
1212 : : bytearray[len(prefix):]. Otherwise, return a copy of the original
1213 : : bytearray.
1214 : : [clinic start generated code]*/
1215 : :
1216 : : static PyObject *
1217 : 9 : bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix)
1218 : : /*[clinic end generated code: output=6cabc585e7f502e0 input=968aada38aedd262]*/
1219 : : {
1220 : 9 : const char *self_start = PyByteArray_AS_STRING(self);
1221 : 9 : Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1222 : 9 : const char *prefix_start = prefix->buf;
1223 : 9 : Py_ssize_t prefix_len = prefix->len;
1224 : :
1225 [ + + ]: 9 : if (self_len >= prefix_len
1226 [ + - ]: 5 : && memcmp(self_start, prefix_start, prefix_len) == 0)
1227 : : {
1228 : 5 : return PyByteArray_FromStringAndSize(self_start + prefix_len,
1229 : : self_len - prefix_len);
1230 : : }
1231 : :
1232 : 4 : return PyByteArray_FromStringAndSize(self_start, self_len);
1233 : : }
1234 : :
1235 : : /*[clinic input]
1236 : : bytearray.removesuffix as bytearray_removesuffix
1237 : :
1238 : : suffix: Py_buffer
1239 : : /
1240 : :
1241 : : Return a bytearray with the given suffix string removed if present.
1242 : :
1243 : : If the bytearray ends with the suffix string and that suffix is not
1244 : : empty, return bytearray[:-len(suffix)]. Otherwise, return a copy of
1245 : : the original bytearray.
1246 : : [clinic start generated code]*/
1247 : :
1248 : : static PyObject *
1249 : 9 : bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
1250 : : /*[clinic end generated code: output=2bc8cfb79de793d3 input=c1827e810b2f6b99]*/
1251 : : {
1252 : 9 : const char *self_start = PyByteArray_AS_STRING(self);
1253 : 9 : Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1254 : 9 : const char *suffix_start = suffix->buf;
1255 : 9 : Py_ssize_t suffix_len = suffix->len;
1256 : :
1257 [ + + ]: 9 : if (self_len >= suffix_len
1258 [ + + ]: 6 : && memcmp(self_start + self_len - suffix_len,
1259 : : suffix_start, suffix_len) == 0)
1260 : : {
1261 : 5 : return PyByteArray_FromStringAndSize(self_start,
1262 : : self_len - suffix_len);
1263 : : }
1264 : :
1265 : 4 : return PyByteArray_FromStringAndSize(self_start, self_len);
1266 : : }
1267 : :
1268 : :
1269 : : /*[clinic input]
1270 : : bytearray.translate
1271 : :
1272 : : table: object
1273 : : Translation table, which must be a bytes object of length 256.
1274 : : /
1275 : : delete as deletechars: object(c_default="NULL") = b''
1276 : :
1277 : : Return a copy with each character mapped by the given translation table.
1278 : :
1279 : : All characters occurring in the optional argument delete are removed.
1280 : : The remaining characters are mapped through the given translation table.
1281 : : [clinic start generated code]*/
1282 : :
1283 : : static PyObject *
1284 : 32322 : bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1285 : : PyObject *deletechars)
1286 : : /*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/
1287 : : {
1288 : : char *input, *output;
1289 : : const char *table_chars;
1290 : : Py_ssize_t i, c;
1291 : 32322 : PyObject *input_obj = (PyObject*)self;
1292 : : const char *output_start;
1293 : : Py_ssize_t inlen;
1294 : 32322 : PyObject *result = NULL;
1295 : : int trans_table[256];
1296 : : Py_buffer vtable, vdel;
1297 : :
1298 [ + + ]: 32322 : if (table == Py_None) {
1299 : 3 : table_chars = NULL;
1300 : 3 : table = NULL;
1301 [ - + ]: 32319 : } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1302 : 0 : return NULL;
1303 : : } else {
1304 [ + + ]: 32319 : if (vtable.len != 256) {
1305 : 2 : PyErr_SetString(PyExc_ValueError,
1306 : : "translation table must be 256 characters long");
1307 : 2 : PyBuffer_Release(&vtable);
1308 : 2 : return NULL;
1309 : : }
1310 : 32317 : table_chars = (const char*)vtable.buf;
1311 : : }
1312 : :
1313 [ + + ]: 32320 : if (deletechars != NULL) {
1314 [ + + ]: 9 : if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1315 [ + + ]: 2 : if (table != NULL)
1316 : 1 : PyBuffer_Release(&vtable);
1317 : 2 : return NULL;
1318 : : }
1319 : : }
1320 : : else {
1321 : 32311 : vdel.buf = NULL;
1322 : 32311 : vdel.len = 0;
1323 : : }
1324 : :
1325 : 32318 : inlen = PyByteArray_GET_SIZE(input_obj);
1326 : 32318 : result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1327 [ - + ]: 32318 : if (result == NULL)
1328 : 0 : goto done;
1329 : 32318 : output_start = output = PyByteArray_AS_STRING(result);
1330 : 32318 : input = PyByteArray_AS_STRING(input_obj);
1331 : :
1332 [ + + + - ]: 32318 : if (vdel.len == 0 && table_chars != NULL) {
1333 : : /* If no deletions are required, use faster code */
1334 [ + + ]: 9867660 : for (i = inlen; --i >= 0; ) {
1335 : 9835347 : c = Py_CHARMASK(*input++);
1336 : 9835347 : *output++ = table_chars[c];
1337 : : }
1338 : 32313 : goto done;
1339 : : }
1340 : :
1341 [ + + ]: 5 : if (table_chars == NULL) {
1342 [ + + ]: 514 : for (i = 0; i < 256; i++)
1343 : 512 : trans_table[i] = Py_CHARMASK(i);
1344 : : } else {
1345 [ + + ]: 771 : for (i = 0; i < 256; i++)
1346 : 768 : trans_table[i] = Py_CHARMASK(table_chars[i]);
1347 : : }
1348 : :
1349 [ + + ]: 14 : for (i = 0; i < vdel.len; i++)
1350 : 9 : trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1351 : :
1352 [ + + ]: 30 : for (i = inlen; --i >= 0; ) {
1353 : 25 : c = Py_CHARMASK(*input++);
1354 [ + + ]: 25 : if (trans_table[c] != -1)
1355 : 14 : *output++ = (char)trans_table[c];
1356 : : }
1357 : : /* Fix the size of the resulting bytearray */
1358 [ - + ]: 5 : if (inlen > 0)
1359 [ + - ]: 5 : if (PyByteArray_Resize(result, output - output_start) < 0) {
1360 [ # # ]: 0 : Py_CLEAR(result);
1361 : 0 : goto done;
1362 : : }
1363 : :
1364 : 5 : done:
1365 [ + + ]: 32318 : if (table != NULL)
1366 : 32316 : PyBuffer_Release(&vtable);
1367 [ + + ]: 32318 : if (deletechars != NULL)
1368 : 7 : PyBuffer_Release(&vdel);
1369 : 32318 : return result;
1370 : : }
1371 : :
1372 : :
1373 : : /*[clinic input]
1374 : :
1375 : : @staticmethod
1376 : : bytearray.maketrans
1377 : :
1378 : : frm: Py_buffer
1379 : : to: Py_buffer
1380 : : /
1381 : :
1382 : : Return a translation table useable for the bytes or bytearray translate method.
1383 : :
1384 : : The returned table will be one where each byte in frm is mapped to the byte at
1385 : : the same position in to.
1386 : :
1387 : : The bytes objects frm and to must be of the same length.
1388 : : [clinic start generated code]*/
1389 : :
1390 : : static PyObject *
1391 : 75 : bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1392 : : /*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
1393 : : {
1394 : 75 : return _Py_bytes_maketrans(frm, to);
1395 : : }
1396 : :
1397 : :
1398 : : /*[clinic input]
1399 : : bytearray.replace
1400 : :
1401 : : old: Py_buffer
1402 : : new: Py_buffer
1403 : : count: Py_ssize_t = -1
1404 : : Maximum number of occurrences to replace.
1405 : : -1 (the default value) means replace all occurrences.
1406 : : /
1407 : :
1408 : : Return a copy with all occurrences of substring old replaced by new.
1409 : :
1410 : : If the optional argument count is given, only the first count occurrences are
1411 : : replaced.
1412 : : [clinic start generated code]*/
1413 : :
1414 : : static PyObject *
1415 : 64904 : bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
1416 : : Py_buffer *new, Py_ssize_t count)
1417 : : /*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
1418 : : {
1419 : 129808 : return stringlib_replace((PyObject *)self,
1420 : 64904 : (const char *)old->buf, old->len,
1421 : 64904 : (const char *)new->buf, new->len, count);
1422 : : }
1423 : :
1424 : : /*[clinic input]
1425 : : bytearray.split
1426 : :
1427 : : sep: object = None
1428 : : The delimiter according which to split the bytearray.
1429 : : None (the default value) means split on ASCII whitespace characters
1430 : : (space, tab, return, newline, formfeed, vertical tab).
1431 : : maxsplit: Py_ssize_t = -1
1432 : : Maximum number of splits to do.
1433 : : -1 (the default value) means no limit.
1434 : :
1435 : : Return a list of the sections in the bytearray, using sep as the delimiter.
1436 : : [clinic start generated code]*/
1437 : :
1438 : : static PyObject *
1439 : 2182 : bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1440 : : Py_ssize_t maxsplit)
1441 : : /*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
1442 : : {
1443 : 2182 : Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1444 : 2182 : const char *s = PyByteArray_AS_STRING(self), *sub;
1445 : : PyObject *list;
1446 : : Py_buffer vsub;
1447 : :
1448 [ + + ]: 2182 : if (maxsplit < 0)
1449 : 49 : maxsplit = PY_SSIZE_T_MAX;
1450 : :
1451 [ + + ]: 2182 : if (sep == Py_None)
1452 : 45 : return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
1453 : :
1454 [ + + ]: 2137 : if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1455 : 2 : return NULL;
1456 : 2135 : sub = vsub.buf;
1457 : 2135 : n = vsub.len;
1458 : :
1459 : 2135 : list = stringlib_split(
1460 : : (PyObject*) self, s, len, sub, n, maxsplit
1461 : : );
1462 : 2135 : PyBuffer_Release(&vsub);
1463 : 2135 : return list;
1464 : : }
1465 : :
1466 : : /*[clinic input]
1467 : : bytearray.partition
1468 : :
1469 : : sep: object
1470 : : /
1471 : :
1472 : : Partition the bytearray into three parts using the given separator.
1473 : :
1474 : : This will search for the separator sep in the bytearray. If the separator is
1475 : : found, returns a 3-tuple containing the part before the separator, the
1476 : : separator itself, and the part after it as new bytearray objects.
1477 : :
1478 : : If the separator is not found, returns a 3-tuple containing the copy of the
1479 : : original bytearray object and two empty bytearray objects.
1480 : : [clinic start generated code]*/
1481 : :
1482 : : static PyObject *
1483 : 7 : bytearray_partition(PyByteArrayObject *self, PyObject *sep)
1484 : : /*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
1485 : : {
1486 : : PyObject *bytesep, *result;
1487 : :
1488 : 7 : bytesep = _PyByteArray_FromBufferObject(sep);
1489 [ + + ]: 7 : if (! bytesep)
1490 : 2 : return NULL;
1491 : :
1492 : 15 : result = stringlib_partition(
1493 : : (PyObject*) self,
1494 : 5 : PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1495 : : bytesep,
1496 : 5 : PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1497 : : );
1498 : :
1499 : 5 : Py_DECREF(bytesep);
1500 : 5 : return result;
1501 : : }
1502 : :
1503 : : /*[clinic input]
1504 : : bytearray.rpartition
1505 : :
1506 : : sep: object
1507 : : /
1508 : :
1509 : : Partition the bytearray into three parts using the given separator.
1510 : :
1511 : : This will search for the separator sep in the bytearray, starting at the end.
1512 : : If the separator is found, returns a 3-tuple containing the part before the
1513 : : separator, the separator itself, and the part after it as new bytearray
1514 : : objects.
1515 : :
1516 : : If the separator is not found, returns a 3-tuple containing two empty bytearray
1517 : : objects and the copy of the original bytearray object.
1518 : : [clinic start generated code]*/
1519 : :
1520 : : static PyObject *
1521 : 8 : bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
1522 : : /*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
1523 : : {
1524 : : PyObject *bytesep, *result;
1525 : :
1526 : 8 : bytesep = _PyByteArray_FromBufferObject(sep);
1527 [ + + ]: 8 : if (! bytesep)
1528 : 2 : return NULL;
1529 : :
1530 : 18 : result = stringlib_rpartition(
1531 : : (PyObject*) self,
1532 : 6 : PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1533 : : bytesep,
1534 : 6 : PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1535 : : );
1536 : :
1537 : 6 : Py_DECREF(bytesep);
1538 : 6 : return result;
1539 : : }
1540 : :
1541 : : /*[clinic input]
1542 : : bytearray.rsplit = bytearray.split
1543 : :
1544 : : Return a list of the sections in the bytearray, using sep as the delimiter.
1545 : :
1546 : : Splitting is done starting at the end of the bytearray and working to the front.
1547 : : [clinic start generated code]*/
1548 : :
1549 : : static PyObject *
1550 : 87 : bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
1551 : : Py_ssize_t maxsplit)
1552 : : /*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
1553 : : {
1554 : 87 : Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1555 : 87 : const char *s = PyByteArray_AS_STRING(self), *sub;
1556 : : PyObject *list;
1557 : : Py_buffer vsub;
1558 : :
1559 [ + + ]: 87 : if (maxsplit < 0)
1560 : 42 : maxsplit = PY_SSIZE_T_MAX;
1561 : :
1562 [ + + ]: 87 : if (sep == Py_None)
1563 : 40 : return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
1564 : :
1565 [ + + ]: 47 : if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1566 : 2 : return NULL;
1567 : 45 : sub = vsub.buf;
1568 : 45 : n = vsub.len;
1569 : :
1570 : 45 : list = stringlib_rsplit(
1571 : : (PyObject*) self, s, len, sub, n, maxsplit
1572 : : );
1573 : 45 : PyBuffer_Release(&vsub);
1574 : 45 : return list;
1575 : : }
1576 : :
1577 : : /*[clinic input]
1578 : : bytearray.reverse
1579 : :
1580 : : Reverse the order of the values in B in place.
1581 : : [clinic start generated code]*/
1582 : :
1583 : : static PyObject *
1584 : 3 : bytearray_reverse_impl(PyByteArrayObject *self)
1585 : : /*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/
1586 : : {
1587 : : char swap, *head, *tail;
1588 : 3 : Py_ssize_t i, j, n = Py_SIZE(self);
1589 : :
1590 : 3 : j = n / 2;
1591 : 3 : head = PyByteArray_AS_STRING(self);
1592 : 3 : tail = head + n - 1;
1593 [ + + ]: 8 : for (i = 0; i < j; i++) {
1594 : 5 : swap = *head;
1595 : 5 : *head++ = *tail;
1596 : 5 : *tail-- = swap;
1597 : : }
1598 : :
1599 : 3 : Py_RETURN_NONE;
1600 : : }
1601 : :
1602 : :
1603 : : /*[python input]
1604 : : class bytesvalue_converter(CConverter):
1605 : : type = 'int'
1606 : : converter = '_getbytevalue'
1607 : : [python start generated code]*/
1608 : : /*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
1609 : :
1610 : :
1611 : : /*[clinic input]
1612 : : bytearray.insert
1613 : :
1614 : : index: Py_ssize_t
1615 : : The index where the value is to be inserted.
1616 : : item: bytesvalue
1617 : : The item to be inserted.
1618 : : /
1619 : :
1620 : : Insert a single item into the bytearray before the given index.
1621 : : [clinic start generated code]*/
1622 : :
1623 : : static PyObject *
1624 : 54 : bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
1625 : : /*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/
1626 : : {
1627 : 54 : Py_ssize_t n = Py_SIZE(self);
1628 : : char *buf;
1629 : :
1630 [ - + ]: 54 : if (n == PY_SSIZE_T_MAX) {
1631 : 0 : PyErr_SetString(PyExc_OverflowError,
1632 : : "cannot add more objects to bytearray");
1633 : 0 : return NULL;
1634 : : }
1635 [ - + ]: 54 : if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1636 : 0 : return NULL;
1637 : 54 : buf = PyByteArray_AS_STRING(self);
1638 : :
1639 [ + + ]: 54 : if (index < 0) {
1640 : 1 : index += n;
1641 [ - + ]: 1 : if (index < 0)
1642 : 0 : index = 0;
1643 : : }
1644 [ + + ]: 54 : if (index > n)
1645 : 1 : index = n;
1646 : 54 : memmove(buf + index + 1, buf + index, n - index);
1647 : 54 : buf[index] = item;
1648 : :
1649 : 54 : Py_RETURN_NONE;
1650 : : }
1651 : :
1652 : : /*[clinic input]
1653 : : bytearray.append
1654 : :
1655 : : item: bytesvalue
1656 : : The item to be appended.
1657 : : /
1658 : :
1659 : : Append a single item to the end of the bytearray.
1660 : : [clinic start generated code]*/
1661 : :
1662 : : static PyObject *
1663 : 814167 : bytearray_append_impl(PyByteArrayObject *self, int item)
1664 : : /*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/
1665 : : {
1666 : 814167 : Py_ssize_t n = Py_SIZE(self);
1667 : :
1668 [ - + ]: 814167 : if (n == PY_SSIZE_T_MAX) {
1669 : 0 : PyErr_SetString(PyExc_OverflowError,
1670 : : "cannot add more objects to bytearray");
1671 : 0 : return NULL;
1672 : : }
1673 [ - + ]: 814167 : if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1674 : 0 : return NULL;
1675 : :
1676 : 814167 : PyByteArray_AS_STRING(self)[n] = item;
1677 : :
1678 : 814167 : Py_RETURN_NONE;
1679 : : }
1680 : :
1681 : : /*[clinic input]
1682 : : bytearray.extend
1683 : :
1684 : : iterable_of_ints: object
1685 : : The iterable of items to append.
1686 : : /
1687 : :
1688 : : Append all the items from the iterator or sequence to the end of the bytearray.
1689 : : [clinic start generated code]*/
1690 : :
1691 : : static PyObject *
1692 : 221584 : bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
1693 : : /*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/
1694 : : {
1695 : : PyObject *it, *item, *bytearray_obj;
1696 : 221584 : Py_ssize_t buf_size = 0, len = 0;
1697 : : int value;
1698 : : char *buf;
1699 : :
1700 : : /* bytearray_setslice code only accepts something supporting PEP 3118. */
1701 [ + + ]: 221584 : if (PyObject_CheckBuffer(iterable_of_ints)) {
1702 [ + + ]: 221568 : if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
1703 : 1 : return NULL;
1704 : :
1705 : 221567 : Py_RETURN_NONE;
1706 : : }
1707 : :
1708 : 16 : it = PyObject_GetIter(iterable_of_ints);
1709 [ + + ]: 16 : if (it == NULL) {
1710 [ + - ]: 5 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1711 : 5 : PyErr_Format(PyExc_TypeError,
1712 : : "can't extend bytearray with %.100s",
1713 : 5 : Py_TYPE(iterable_of_ints)->tp_name);
1714 : : }
1715 : 5 : return NULL;
1716 : : }
1717 : :
1718 : : /* Try to determine the length of the argument. 32 is arbitrary. */
1719 : 11 : buf_size = PyObject_LengthHint(iterable_of_ints, 32);
1720 [ + + ]: 11 : if (buf_size == -1) {
1721 : 2 : Py_DECREF(it);
1722 : 2 : return NULL;
1723 : : }
1724 : :
1725 : 9 : bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
1726 [ - + ]: 9 : if (bytearray_obj == NULL) {
1727 : 0 : Py_DECREF(it);
1728 : 0 : return NULL;
1729 : : }
1730 : 9 : buf = PyByteArray_AS_STRING(bytearray_obj);
1731 : :
1732 [ + + ]: 776 : while ((item = PyIter_Next(it)) != NULL) {
1733 [ + + ]: 769 : if (! _getbytevalue(item, &value)) {
1734 : 2 : Py_DECREF(item);
1735 : 2 : Py_DECREF(it);
1736 : 2 : Py_DECREF(bytearray_obj);
1737 : 2 : return NULL;
1738 : : }
1739 : 767 : buf[len++] = value;
1740 : 767 : Py_DECREF(item);
1741 : :
1742 [ + + ]: 767 : if (len >= buf_size) {
1743 : : Py_ssize_t addition;
1744 [ - + ]: 16 : if (len == PY_SSIZE_T_MAX) {
1745 : 0 : Py_DECREF(it);
1746 : 0 : Py_DECREF(bytearray_obj);
1747 : : return PyErr_NoMemory();
1748 : : }
1749 : 16 : addition = len >> 1;
1750 [ - + ]: 16 : if (addition > PY_SSIZE_T_MAX - len - 1)
1751 : 0 : buf_size = PY_SSIZE_T_MAX;
1752 : : else
1753 : 16 : buf_size = len + addition + 1;
1754 [ - + ]: 16 : if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
1755 : 0 : Py_DECREF(it);
1756 : 0 : Py_DECREF(bytearray_obj);
1757 : 0 : return NULL;
1758 : : }
1759 : : /* Recompute the `buf' pointer, since the resizing operation may
1760 : : have invalidated it. */
1761 : 16 : buf = PyByteArray_AS_STRING(bytearray_obj);
1762 : : }
1763 : : }
1764 : 7 : Py_DECREF(it);
1765 : :
1766 [ + + ]: 7 : if (PyErr_Occurred()) {
1767 : 1 : Py_DECREF(bytearray_obj);
1768 : 1 : return NULL;
1769 : : }
1770 : :
1771 : : /* Resize down to exact size. */
1772 [ - + ]: 6 : if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
1773 : 0 : Py_DECREF(bytearray_obj);
1774 : 0 : return NULL;
1775 : : }
1776 : :
1777 [ - + ]: 6 : if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
1778 : 0 : Py_DECREF(bytearray_obj);
1779 : 0 : return NULL;
1780 : : }
1781 : 6 : Py_DECREF(bytearray_obj);
1782 : :
1783 : : assert(!PyErr_Occurred());
1784 : 6 : Py_RETURN_NONE;
1785 : : }
1786 : :
1787 : : /*[clinic input]
1788 : : bytearray.pop
1789 : :
1790 : : index: Py_ssize_t = -1
1791 : : The index from where to remove the item.
1792 : : -1 (the default value) means remove the last item.
1793 : : /
1794 : :
1795 : : Remove and return a single item from B.
1796 : :
1797 : : If no index argument is given, will pop the last item.
1798 : : [clinic start generated code]*/
1799 : :
1800 : : static PyObject *
1801 : 8 : bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
1802 : : /*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/
1803 : : {
1804 : : int value;
1805 : 8 : Py_ssize_t n = Py_SIZE(self);
1806 : : char *buf;
1807 : :
1808 [ + + ]: 8 : if (n == 0) {
1809 : 1 : PyErr_SetString(PyExc_IndexError,
1810 : : "pop from empty bytearray");
1811 : 1 : return NULL;
1812 : : }
1813 [ + + ]: 7 : if (index < 0)
1814 : 4 : index += Py_SIZE(self);
1815 [ + - + + ]: 7 : if (index < 0 || index >= Py_SIZE(self)) {
1816 : 1 : PyErr_SetString(PyExc_IndexError, "pop index out of range");
1817 : 1 : return NULL;
1818 : : }
1819 [ + + ]: 6 : if (!_canresize(self))
1820 : 1 : return NULL;
1821 : :
1822 : 5 : buf = PyByteArray_AS_STRING(self);
1823 : 5 : value = buf[index];
1824 : 5 : memmove(buf + index, buf + index + 1, n - index);
1825 [ - + ]: 5 : if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1826 : 0 : return NULL;
1827 : :
1828 : 5 : return _PyLong_FromUnsignedChar((unsigned char)value);
1829 : : }
1830 : :
1831 : : /*[clinic input]
1832 : : bytearray.remove
1833 : :
1834 : : value: bytesvalue
1835 : : The value to remove.
1836 : : /
1837 : :
1838 : : Remove the first occurrence of a value in the bytearray.
1839 : : [clinic start generated code]*/
1840 : :
1841 : : static PyObject *
1842 : 9 : bytearray_remove_impl(PyByteArrayObject *self, int value)
1843 : : /*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/
1844 : : {
1845 : 9 : Py_ssize_t where, n = Py_SIZE(self);
1846 : 9 : char *buf = PyByteArray_AS_STRING(self);
1847 : :
1848 : 9 : where = stringlib_find_char(buf, n, value);
1849 [ + + ]: 9 : if (where < 0) {
1850 : 1 : PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
1851 : 1 : return NULL;
1852 : : }
1853 [ + + ]: 8 : if (!_canresize(self))
1854 : 1 : return NULL;
1855 : :
1856 : 7 : memmove(buf + where, buf + where + 1, n - where);
1857 [ - + ]: 7 : if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1858 : 0 : return NULL;
1859 : :
1860 : 7 : Py_RETURN_NONE;
1861 : : }
1862 : :
1863 : : #define LEFTSTRIP 0
1864 : : #define RIGHTSTRIP 1
1865 : : #define BOTHSTRIP 2
1866 : :
1867 : : static PyObject*
1868 : 116 : bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int striptype)
1869 : : {
1870 : : Py_ssize_t mysize, byteslen;
1871 : : const char* myptr;
1872 : : const char* bytesptr;
1873 : : Py_buffer vbytes;
1874 : :
1875 [ + + ]: 116 : if (bytes == Py_None) {
1876 : 25 : bytesptr = "\t\n\r\f\v ";
1877 : 25 : byteslen = 6;
1878 : : }
1879 : : else {
1880 [ + + ]: 91 : if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1881 : 6 : return NULL;
1882 : 85 : bytesptr = (const char*)vbytes.buf;
1883 : 85 : byteslen = vbytes.len;
1884 : : }
1885 : 110 : myptr = PyByteArray_AS_STRING(self);
1886 : 110 : mysize = Py_SIZE(self);
1887 : :
1888 : 110 : Py_ssize_t left = 0;
1889 [ + + ]: 110 : if (striptype != RIGHTSTRIP) {
1890 [ + + + + ]: 23219 : while (left < mysize && memchr(bytesptr, (unsigned char)myptr[left], byteslen))
1891 : 23190 : left++;
1892 : : }
1893 : 110 : Py_ssize_t right = mysize;
1894 [ + + ]: 110 : if (striptype != LEFTSTRIP) {
1895 : : do {
1896 : 23259 : right--;
1897 [ + + + + ]: 23259 : } while (right >= left && memchr(bytesptr, (unsigned char)myptr[right], byteslen));
1898 : 102 : right++;
1899 : : }
1900 [ + + ]: 110 : if (bytes != Py_None)
1901 : 85 : PyBuffer_Release(&vbytes);
1902 : 110 : return PyByteArray_FromStringAndSize(myptr + left, right - left);
1903 : : }
1904 : :
1905 : : /*[clinic input]
1906 : : bytearray.strip
1907 : :
1908 : : bytes: object = None
1909 : : /
1910 : :
1911 : : Strip leading and trailing bytes contained in the argument.
1912 : :
1913 : : If the argument is omitted or None, strip leading and trailing ASCII whitespace.
1914 : : [clinic start generated code]*/
1915 : :
1916 : : static PyObject *
1917 : 23 : bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
1918 : : /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
1919 : : {
1920 : 23 : return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP);
1921 : : }
1922 : :
1923 : : /*[clinic input]
1924 : : bytearray.lstrip
1925 : :
1926 : : bytes: object = None
1927 : : /
1928 : :
1929 : : Strip leading bytes contained in the argument.
1930 : :
1931 : : If the argument is omitted or None, strip leading ASCII whitespace.
1932 : : [clinic start generated code]*/
1933 : :
1934 : : static PyObject *
1935 : 10 : bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
1936 : : /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
1937 : : {
1938 : 10 : return bytearray_strip_impl_helper(self, bytes, LEFTSTRIP);
1939 : : }
1940 : :
1941 : : /*[clinic input]
1942 : : bytearray.rstrip
1943 : :
1944 : : bytes: object = None
1945 : : /
1946 : :
1947 : : Strip trailing bytes contained in the argument.
1948 : :
1949 : : If the argument is omitted or None, strip trailing ASCII whitespace.
1950 : : [clinic start generated code]*/
1951 : :
1952 : : static PyObject *
1953 : 83 : bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
1954 : : /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
1955 : : {
1956 : 83 : return bytearray_strip_impl_helper(self, bytes, RIGHTSTRIP);
1957 : : }
1958 : :
1959 : : /*[clinic input]
1960 : : bytearray.decode
1961 : :
1962 : : encoding: str(c_default="NULL") = 'utf-8'
1963 : : The encoding with which to decode the bytearray.
1964 : : errors: str(c_default="NULL") = 'strict'
1965 : : The error handling scheme to use for the handling of decoding errors.
1966 : : The default is 'strict' meaning that decoding errors raise a
1967 : : UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
1968 : : as well as any other name registered with codecs.register_error that
1969 : : can handle UnicodeDecodeErrors.
1970 : :
1971 : : Decode the bytearray using the codec registered for encoding.
1972 : : [clinic start generated code]*/
1973 : :
1974 : : static PyObject *
1975 : 552234 : bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
1976 : : const char *errors)
1977 : : /*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
1978 : : {
1979 [ + + ]: 552234 : if (encoding == NULL)
1980 : 2088 : encoding = PyUnicode_GetDefaultEncoding();
1981 : 552234 : return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
1982 : : }
1983 : :
1984 : : PyDoc_STRVAR(alloc_doc,
1985 : : "B.__alloc__() -> int\n\
1986 : : \n\
1987 : : Return the number of bytes actually allocated.");
1988 : :
1989 : : static PyObject *
1990 : 203 : bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
1991 : : {
1992 : 203 : return PyLong_FromSsize_t(self->ob_alloc);
1993 : : }
1994 : :
1995 : : /*[clinic input]
1996 : : bytearray.join
1997 : :
1998 : : iterable_of_bytes: object
1999 : : /
2000 : :
2001 : : Concatenate any number of bytes/bytearray objects.
2002 : :
2003 : : The bytearray whose method is called is inserted in between each pair.
2004 : :
2005 : : The result is returned as a new bytearray object.
2006 : : [clinic start generated code]*/
2007 : :
2008 : : static PyObject *
2009 : 49 : bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
2010 : : /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
2011 : : {
2012 : 49 : return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
2013 : : }
2014 : :
2015 : : /*[clinic input]
2016 : : bytearray.splitlines
2017 : :
2018 : : keepends: bool(accept={int}) = False
2019 : :
2020 : : Return a list of the lines in the bytearray, breaking at line boundaries.
2021 : :
2022 : : Line breaks are not included in the resulting list unless keepends is given and
2023 : : true.
2024 : : [clinic start generated code]*/
2025 : :
2026 : : static PyObject *
2027 : 20 : bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
2028 : : /*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/
2029 : : {
2030 : 40 : return stringlib_splitlines(
2031 : 20 : (PyObject*) self, PyByteArray_AS_STRING(self),
2032 : : PyByteArray_GET_SIZE(self), keepends
2033 : : );
2034 : : }
2035 : :
2036 : : /*[clinic input]
2037 : : @classmethod
2038 : : bytearray.fromhex
2039 : :
2040 : : string: unicode
2041 : : /
2042 : :
2043 : : Create a bytearray object from a string of hexadecimal numbers.
2044 : :
2045 : : Spaces between two numbers are accepted.
2046 : : Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2047 : : [clinic start generated code]*/
2048 : :
2049 : : static PyObject *
2050 : 35 : bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2051 : : /*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/
2052 : : {
2053 : 35 : PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2054 [ + + + - ]: 35 : if (type != &PyByteArray_Type && result != NULL) {
2055 : 6 : Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result));
2056 : : }
2057 : 35 : return result;
2058 : : }
2059 : :
2060 : : /*[clinic input]
2061 : : bytearray.hex
2062 : :
2063 : : sep: object = NULL
2064 : : An optional single character or byte to separate hex bytes.
2065 : : bytes_per_sep: int = 1
2066 : : How many bytes between separators. Positive values count from the
2067 : : right, negative values count from the left.
2068 : :
2069 : : Create a string of hexadecimal numbers from a bytearray object.
2070 : :
2071 : : Example:
2072 : : >>> value = bytearray([0xb9, 0x01, 0xef])
2073 : : >>> value.hex()
2074 : : 'b901ef'
2075 : : >>> value.hex(':')
2076 : : 'b9:01:ef'
2077 : : >>> value.hex(':', 2)
2078 : : 'b9:01ef'
2079 : : >>> value.hex(':', -2)
2080 : : 'b901:ef'
2081 : : [clinic start generated code]*/
2082 : :
2083 : : static PyObject *
2084 : 46 : bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
2085 : : /*[clinic end generated code: output=29c4e5ef72c565a0 input=808667e49bcccb54]*/
2086 : : {
2087 : 46 : char* argbuf = PyByteArray_AS_STRING(self);
2088 : 46 : Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2089 : 46 : return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
2090 : : }
2091 : :
2092 : : static PyObject *
2093 : 30 : _common_reduce(PyByteArrayObject *self, int proto)
2094 : : {
2095 : : PyObject *state;
2096 : : const char *buf;
2097 : :
2098 : 30 : state = _PyObject_GetState((PyObject *)self);
2099 [ - + ]: 30 : if (state == NULL) {
2100 : 0 : return NULL;
2101 : : }
2102 : :
2103 [ - + ]: 30 : if (!Py_SIZE(self)) {
2104 : 0 : return Py_BuildValue("(O()N)", Py_TYPE(self), state);
2105 : : }
2106 : 30 : buf = PyByteArray_AS_STRING(self);
2107 [ + + ]: 30 : if (proto < 3) {
2108 : : /* use str based reduction for backwards compatibility with Python 2.x */
2109 : 12 : PyObject *latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2110 : 12 : return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", state);
2111 : : }
2112 : : else {
2113 : : /* use more efficient byte based reduction */
2114 : 18 : return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), state);
2115 : : }
2116 : : }
2117 : :
2118 : : /*[clinic input]
2119 : : bytearray.__reduce__ as bytearray_reduce
2120 : :
2121 : : Return state information for pickling.
2122 : : [clinic start generated code]*/
2123 : :
2124 : : static PyObject *
2125 : 0 : bytearray_reduce_impl(PyByteArrayObject *self)
2126 : : /*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/
2127 : : {
2128 : 0 : return _common_reduce(self, 2);
2129 : : }
2130 : :
2131 : : /*[clinic input]
2132 : : bytearray.__reduce_ex__ as bytearray_reduce_ex
2133 : :
2134 : : proto: int = 0
2135 : : /
2136 : :
2137 : : Return state information for pickling.
2138 : : [clinic start generated code]*/
2139 : :
2140 : : static PyObject *
2141 : 30 : bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2142 : : /*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/
2143 : : {
2144 : 30 : return _common_reduce(self, proto);
2145 : : }
2146 : :
2147 : : /*[clinic input]
2148 : : bytearray.__sizeof__ as bytearray_sizeof
2149 : :
2150 : : Returns the size of the bytearray object in memory, in bytes.
2151 : : [clinic start generated code]*/
2152 : :
2153 : : static PyObject *
2154 : 6 : bytearray_sizeof_impl(PyByteArrayObject *self)
2155 : : /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
2156 : : {
2157 : : Py_ssize_t res;
2158 : :
2159 : 6 : res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
2160 : 6 : return PyLong_FromSsize_t(res);
2161 : : }
2162 : :
2163 : : static PySequenceMethods bytearray_as_sequence = {
2164 : : (lenfunc)bytearray_length, /* sq_length */
2165 : : (binaryfunc)PyByteArray_Concat, /* sq_concat */
2166 : : (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2167 : : (ssizeargfunc)bytearray_getitem, /* sq_item */
2168 : : 0, /* sq_slice */
2169 : : (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2170 : : 0, /* sq_ass_slice */
2171 : : (objobjproc)bytearray_contains, /* sq_contains */
2172 : : (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2173 : : (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
2174 : : };
2175 : :
2176 : : static PyMappingMethods bytearray_as_mapping = {
2177 : : (lenfunc)bytearray_length,
2178 : : (binaryfunc)bytearray_subscript,
2179 : : (objobjargproc)bytearray_ass_subscript,
2180 : : };
2181 : :
2182 : : static PyBufferProcs bytearray_as_buffer = {
2183 : : (getbufferproc)bytearray_getbuffer,
2184 : : (releasebufferproc)bytearray_releasebuffer,
2185 : : };
2186 : :
2187 : : static PyMethodDef
2188 : : bytearray_methods[] = {
2189 : : {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2190 : : BYTEARRAY_REDUCE_METHODDEF
2191 : : BYTEARRAY_REDUCE_EX_METHODDEF
2192 : : BYTEARRAY_SIZEOF_METHODDEF
2193 : : BYTEARRAY_APPEND_METHODDEF
2194 : : {"capitalize", stringlib_capitalize, METH_NOARGS,
2195 : : _Py_capitalize__doc__},
2196 : : STRINGLIB_CENTER_METHODDEF
2197 : : BYTEARRAY_CLEAR_METHODDEF
2198 : : BYTEARRAY_COPY_METHODDEF
2199 : : {"count", (PyCFunction)bytearray_count, METH_VARARGS,
2200 : : _Py_count__doc__},
2201 : : BYTEARRAY_DECODE_METHODDEF
2202 : : {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS,
2203 : : _Py_endswith__doc__},
2204 : : STRINGLIB_EXPANDTABS_METHODDEF
2205 : : BYTEARRAY_EXTEND_METHODDEF
2206 : : {"find", (PyCFunction)bytearray_find, METH_VARARGS,
2207 : : _Py_find__doc__},
2208 : : BYTEARRAY_FROMHEX_METHODDEF
2209 : : BYTEARRAY_HEX_METHODDEF
2210 : : {"index", (PyCFunction)bytearray_index, METH_VARARGS, _Py_index__doc__},
2211 : : BYTEARRAY_INSERT_METHODDEF
2212 : : {"isalnum", stringlib_isalnum, METH_NOARGS,
2213 : : _Py_isalnum__doc__},
2214 : : {"isalpha", stringlib_isalpha, METH_NOARGS,
2215 : : _Py_isalpha__doc__},
2216 : : {"isascii", stringlib_isascii, METH_NOARGS,
2217 : : _Py_isascii__doc__},
2218 : : {"isdigit", stringlib_isdigit, METH_NOARGS,
2219 : : _Py_isdigit__doc__},
2220 : : {"islower", stringlib_islower, METH_NOARGS,
2221 : : _Py_islower__doc__},
2222 : : {"isspace", stringlib_isspace, METH_NOARGS,
2223 : : _Py_isspace__doc__},
2224 : : {"istitle", stringlib_istitle, METH_NOARGS,
2225 : : _Py_istitle__doc__},
2226 : : {"isupper", stringlib_isupper, METH_NOARGS,
2227 : : _Py_isupper__doc__},
2228 : : BYTEARRAY_JOIN_METHODDEF
2229 : : STRINGLIB_LJUST_METHODDEF
2230 : : {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__},
2231 : : BYTEARRAY_LSTRIP_METHODDEF
2232 : : BYTEARRAY_MAKETRANS_METHODDEF
2233 : : BYTEARRAY_PARTITION_METHODDEF
2234 : : BYTEARRAY_POP_METHODDEF
2235 : : BYTEARRAY_REMOVE_METHODDEF
2236 : : BYTEARRAY_REPLACE_METHODDEF
2237 : : BYTEARRAY_REMOVEPREFIX_METHODDEF
2238 : : BYTEARRAY_REMOVESUFFIX_METHODDEF
2239 : : BYTEARRAY_REVERSE_METHODDEF
2240 : : {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, _Py_rfind__doc__},
2241 : : {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, _Py_rindex__doc__},
2242 : : STRINGLIB_RJUST_METHODDEF
2243 : : BYTEARRAY_RPARTITION_METHODDEF
2244 : : BYTEARRAY_RSPLIT_METHODDEF
2245 : : BYTEARRAY_RSTRIP_METHODDEF
2246 : : BYTEARRAY_SPLIT_METHODDEF
2247 : : BYTEARRAY_SPLITLINES_METHODDEF
2248 : : {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
2249 : : _Py_startswith__doc__},
2250 : : BYTEARRAY_STRIP_METHODDEF
2251 : : {"swapcase", stringlib_swapcase, METH_NOARGS,
2252 : : _Py_swapcase__doc__},
2253 : : {"title", stringlib_title, METH_NOARGS, _Py_title__doc__},
2254 : : BYTEARRAY_TRANSLATE_METHODDEF
2255 : : {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2256 : : STRINGLIB_ZFILL_METHODDEF
2257 : : {NULL}
2258 : : };
2259 : :
2260 : : static PyObject *
2261 : 167 : bytearray_mod(PyObject *v, PyObject *w)
2262 : : {
2263 [ + + ]: 167 : if (!PyByteArray_Check(v))
2264 : 2 : Py_RETURN_NOTIMPLEMENTED;
2265 : 165 : return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
2266 : : }
2267 : :
2268 : : static PyNumberMethods bytearray_as_number = {
2269 : : 0, /*nb_add*/
2270 : : 0, /*nb_subtract*/
2271 : : 0, /*nb_multiply*/
2272 : : bytearray_mod, /*nb_remainder*/
2273 : : };
2274 : :
2275 : : PyDoc_STRVAR(bytearray_doc,
2276 : : "bytearray(iterable_of_ints) -> bytearray\n\
2277 : : bytearray(string, encoding[, errors]) -> bytearray\n\
2278 : : bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2279 : : bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2280 : : bytearray() -> empty bytes array\n\
2281 : : \n\
2282 : : Construct a mutable bytearray object from:\n\
2283 : : - an iterable yielding integers in range(256)\n\
2284 : : - a text string encoded using the specified encoding\n\
2285 : : - a bytes or a buffer object\n\
2286 : : - any object implementing the buffer API.\n\
2287 : : - an integer");
2288 : :
2289 : :
2290 : : static PyObject *bytearray_iter(PyObject *seq);
2291 : :
2292 : : PyTypeObject PyByteArray_Type = {
2293 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
2294 : : "bytearray",
2295 : : sizeof(PyByteArrayObject),
2296 : : 0,
2297 : : (destructor)bytearray_dealloc, /* tp_dealloc */
2298 : : 0, /* tp_vectorcall_offset */
2299 : : 0, /* tp_getattr */
2300 : : 0, /* tp_setattr */
2301 : : 0, /* tp_as_async */
2302 : : (reprfunc)bytearray_repr, /* tp_repr */
2303 : : &bytearray_as_number, /* tp_as_number */
2304 : : &bytearray_as_sequence, /* tp_as_sequence */
2305 : : &bytearray_as_mapping, /* tp_as_mapping */
2306 : : 0, /* tp_hash */
2307 : : 0, /* tp_call */
2308 : : bytearray_str, /* tp_str */
2309 : : PyObject_GenericGetAttr, /* tp_getattro */
2310 : : 0, /* tp_setattro */
2311 : : &bytearray_as_buffer, /* tp_as_buffer */
2312 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2313 : : _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
2314 : : bytearray_doc, /* tp_doc */
2315 : : 0, /* tp_traverse */
2316 : : 0, /* tp_clear */
2317 : : (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
2318 : : 0, /* tp_weaklistoffset */
2319 : : bytearray_iter, /* tp_iter */
2320 : : 0, /* tp_iternext */
2321 : : bytearray_methods, /* tp_methods */
2322 : : 0, /* tp_members */
2323 : : 0, /* tp_getset */
2324 : : 0, /* tp_base */
2325 : : 0, /* tp_dict */
2326 : : 0, /* tp_descr_get */
2327 : : 0, /* tp_descr_set */
2328 : : 0, /* tp_dictoffset */
2329 : : (initproc)bytearray___init__, /* tp_init */
2330 : : PyType_GenericAlloc, /* tp_alloc */
2331 : : PyType_GenericNew, /* tp_new */
2332 : : PyObject_Del, /* tp_free */
2333 : : };
2334 : :
2335 : : /*********************** Bytearray Iterator ****************************/
2336 : :
2337 : : typedef struct {
2338 : : PyObject_HEAD
2339 : : Py_ssize_t it_index;
2340 : : PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2341 : : } bytesiterobject;
2342 : :
2343 : : static void
2344 : 14765 : bytearrayiter_dealloc(bytesiterobject *it)
2345 : : {
2346 : 14765 : _PyObject_GC_UNTRACK(it);
2347 : 14765 : Py_XDECREF(it->it_seq);
2348 : 14765 : PyObject_GC_Del(it);
2349 : 14765 : }
2350 : :
2351 : : static int
2352 : 10 : bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2353 : : {
2354 [ + + - + ]: 10 : Py_VISIT(it->it_seq);
2355 : 10 : return 0;
2356 : : }
2357 : :
2358 : : static PyObject *
2359 : 382792 : bytearrayiter_next(bytesiterobject *it)
2360 : : {
2361 : : PyByteArrayObject *seq;
2362 : :
2363 : : assert(it != NULL);
2364 : 382792 : seq = it->it_seq;
2365 [ + + ]: 382792 : if (seq == NULL)
2366 : 2 : return NULL;
2367 : : assert(PyByteArray_Check(seq));
2368 : :
2369 [ + + ]: 382790 : if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2370 : 371204 : return _PyLong_FromUnsignedChar(
2371 : 371204 : (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index++]);
2372 : : }
2373 : :
2374 : 11586 : it->it_seq = NULL;
2375 : 11586 : Py_DECREF(seq);
2376 : 11586 : return NULL;
2377 : : }
2378 : :
2379 : : static PyObject *
2380 : 81 : bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2381 : : {
2382 : 81 : Py_ssize_t len = 0;
2383 [ + + ]: 81 : if (it->it_seq) {
2384 : 80 : len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2385 [ + + ]: 80 : if (len < 0) {
2386 : 1 : len = 0;
2387 : : }
2388 : : }
2389 : 81 : return PyLong_FromSsize_t(len);
2390 : : }
2391 : :
2392 : : PyDoc_STRVAR(length_hint_doc,
2393 : : "Private method returning an estimate of len(list(it)).");
2394 : :
2395 : : static PyObject *
2396 : 78 : bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2397 : : {
2398 [ + + ]: 78 : if (it->it_seq != NULL) {
2399 : 72 : return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)),
2400 : : it->it_seq, it->it_index);
2401 : : } else {
2402 : 6 : return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter)));
2403 : : }
2404 : : }
2405 : :
2406 : : static PyObject *
2407 : 102 : bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2408 : : {
2409 : 102 : Py_ssize_t index = PyLong_AsSsize_t(state);
2410 [ - + - - ]: 102 : if (index == -1 && PyErr_Occurred())
2411 : 0 : return NULL;
2412 [ + - ]: 102 : if (it->it_seq != NULL) {
2413 [ - + ]: 102 : if (index < 0)
2414 : 0 : index = 0;
2415 [ - + ]: 102 : else if (index > PyByteArray_GET_SIZE(it->it_seq))
2416 : 0 : index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
2417 : 102 : it->it_index = index;
2418 : : }
2419 : 102 : Py_RETURN_NONE;
2420 : : }
2421 : :
2422 : : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2423 : :
2424 : : static PyMethodDef bytearrayiter_methods[] = {
2425 : : {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
2426 : : length_hint_doc},
2427 : : {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
2428 : : bytearray_reduce__doc__},
2429 : : {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
2430 : : setstate_doc},
2431 : : {NULL, NULL} /* sentinel */
2432 : : };
2433 : :
2434 : : PyTypeObject PyByteArrayIter_Type = {
2435 : : PyVarObject_HEAD_INIT(&PyType_Type, 0)
2436 : : "bytearray_iterator", /* tp_name */
2437 : : sizeof(bytesiterobject), /* tp_basicsize */
2438 : : 0, /* tp_itemsize */
2439 : : /* methods */
2440 : : (destructor)bytearrayiter_dealloc, /* tp_dealloc */
2441 : : 0, /* tp_vectorcall_offset */
2442 : : 0, /* tp_getattr */
2443 : : 0, /* tp_setattr */
2444 : : 0, /* tp_as_async */
2445 : : 0, /* tp_repr */
2446 : : 0, /* tp_as_number */
2447 : : 0, /* tp_as_sequence */
2448 : : 0, /* tp_as_mapping */
2449 : : 0, /* tp_hash */
2450 : : 0, /* tp_call */
2451 : : 0, /* tp_str */
2452 : : PyObject_GenericGetAttr, /* tp_getattro */
2453 : : 0, /* tp_setattro */
2454 : : 0, /* tp_as_buffer */
2455 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2456 : : 0, /* tp_doc */
2457 : : (traverseproc)bytearrayiter_traverse, /* tp_traverse */
2458 : : 0, /* tp_clear */
2459 : : 0, /* tp_richcompare */
2460 : : 0, /* tp_weaklistoffset */
2461 : : PyObject_SelfIter, /* tp_iter */
2462 : : (iternextfunc)bytearrayiter_next, /* tp_iternext */
2463 : : bytearrayiter_methods, /* tp_methods */
2464 : : 0,
2465 : : };
2466 : :
2467 : : static PyObject *
2468 : 14765 : bytearray_iter(PyObject *seq)
2469 : : {
2470 : : bytesiterobject *it;
2471 : :
2472 [ - + ]: 14765 : if (!PyByteArray_Check(seq)) {
2473 : 0 : PyErr_BadInternalCall();
2474 : 0 : return NULL;
2475 : : }
2476 : 14765 : it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2477 [ - + ]: 14765 : if (it == NULL)
2478 : 0 : return NULL;
2479 : 14765 : it->it_index = 0;
2480 : 14765 : Py_INCREF(seq);
2481 : 14765 : it->it_seq = (PyByteArrayObject *)seq;
2482 : 14765 : _PyObject_GC_TRACK(it);
2483 : 14765 : return (PyObject *)it;
2484 : : }
|