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