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