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