• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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