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