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