• 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 /* For PyByteArray_AS_STRING(). */
17 char _PyByteArray_empty_string[] = "";
18 
19 /* Helpers */
20 
21 static int
_getbytevalue(PyObject * arg,int * value)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 
42 static int
bytearray_getbuffer(PyByteArrayObject * obj,Py_buffer * view,int flags)43 bytearray_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 
58 static void
bytearray_releasebuffer(PyByteArrayObject * obj,Py_buffer * view)59 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
60 {
61     obj->ob_exports--;
62 }
63 
64 static int
_canresize(PyByteArrayObject * self)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 
79 PyObject *
PyByteArray_FromObject(PyObject * input)80 PyByteArray_FromObject(PyObject *input)
81 {
82     return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input);
83 }
84 
85 static PyObject *
_PyByteArray_FromBufferObject(PyObject * obj)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 
105 PyObject *
PyByteArray_FromStringAndSize(const char * bytes,Py_ssize_t size)106 PyByteArray_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 
149 Py_ssize_t
PyByteArray_Size(PyObject * self)150 PyByteArray_Size(PyObject *self)
151 {
152     assert(self != NULL);
153     assert(PyByteArray_Check(self));
154 
155     return PyByteArray_GET_SIZE(self);
156 }
157 
158 char  *
PyByteArray_AsString(PyObject * self)159 PyByteArray_AsString(PyObject *self)
160 {
161     assert(self != NULL);
162     assert(PyByteArray_Check(self));
163 
164     return PyByteArray_AS_STRING(self);
165 }
166 
167 int
PyByteArray_Resize(PyObject * self,Py_ssize_t requested_size)168 PyByteArray_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 
246 PyObject *
PyByteArray_Concat(PyObject * a,PyObject * b)247 PyByteArray_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 
285 static Py_ssize_t
bytearray_length(PyByteArrayObject * self)286 bytearray_length(PyByteArrayObject *self)
287 {
288     return Py_SIZE(self);
289 }
290 
291 static PyObject *
bytearray_iconcat(PyByteArrayObject * self,PyObject * other)292 bytearray_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 
318 static PyObject *
bytearray_repeat(PyByteArrayObject * self,Py_ssize_t count)319 bytearray_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 
346 static PyObject *
bytearray_irepeat(PyByteArrayObject * self,Py_ssize_t count)347 bytearray_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 
375 static PyObject *
bytearray_getitem(PyByteArrayObject * self,Py_ssize_t i)376 bytearray_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 
385 static PyObject *
bytearray_subscript(PyByteArrayObject * self,PyObject * index)386 bytearray_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 
443 static int
bytearray_setslice_linear(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,char * bytes,Py_ssize_t bytes_len)444 bytearray_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 
527 static int
bytearray_setslice(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,PyObject * values)528 bytearray_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 
577 static int
bytearray_setitem(PyByteArrayObject * self,Py_ssize_t i,PyObject * value)578 bytearray_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 
600 static int
bytearray_ass_subscript(PyByteArrayObject * self,PyObject * index,PyObject * values)601 bytearray_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]
743 bytearray.__init__
744 
745     source as arg: object = NULL
746     encoding: str = NULL
747     errors: str = NULL
748 
749 [clinic start generated code]*/
750 
751 static int
bytearray___init___impl(PyByteArrayObject * self,PyObject * arg,const char * encoding,const char * errors)752 bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
753                         const char *encoding, const char *errors)
754 /*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/
755 {
756     Py_ssize_t count;
757     PyObject *it;
758     PyObject *(*iternext)(PyObject *);
759 
760     if (Py_SIZE(self) != 0) {
761         /* Empty previous contents (yes, do this first of all!) */
762         if (PyByteArray_Resize((PyObject *)self, 0) < 0)
763             return -1;
764     }
765 
766     /* Make a quick exit if no first argument */
767     if (arg == NULL) {
768         if (encoding != NULL || errors != NULL) {
769             PyErr_SetString(PyExc_TypeError,
770                             encoding != NULL ?
771                             "encoding without a string argument" :
772                             "errors without a string argument");
773             return -1;
774         }
775         return 0;
776     }
777 
778     if (PyUnicode_Check(arg)) {
779         /* Encode via the codec registry */
780         PyObject *encoded, *new;
781         if (encoding == NULL) {
782             PyErr_SetString(PyExc_TypeError,
783                             "string argument without an encoding");
784             return -1;
785         }
786         encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
787         if (encoded == NULL)
788             return -1;
789         assert(PyBytes_Check(encoded));
790         new = bytearray_iconcat(self, encoded);
791         Py_DECREF(encoded);
792         if (new == NULL)
793             return -1;
794         Py_DECREF(new);
795         return 0;
796     }
797 
798     /* If it's not unicode, there can't be encoding or errors */
799     if (encoding != NULL || errors != NULL) {
800         PyErr_SetString(PyExc_TypeError,
801                         encoding != NULL ?
802                         "encoding without a string argument" :
803                         "errors without a string argument");
804         return -1;
805     }
806 
807     /* Is it an int? */
808     if (_PyIndex_Check(arg)) {
809         count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
810         if (count == -1 && PyErr_Occurred()) {
811             if (!PyErr_ExceptionMatches(PyExc_TypeError))
812                 return -1;
813             PyErr_Clear();  /* fall through */
814         }
815         else {
816             if (count < 0) {
817                 PyErr_SetString(PyExc_ValueError, "negative count");
818                 return -1;
819             }
820             if (count > 0) {
821                 if (PyByteArray_Resize((PyObject *)self, count))
822                     return -1;
823                 memset(PyByteArray_AS_STRING(self), 0, count);
824             }
825             return 0;
826         }
827     }
828 
829     /* Use the buffer API */
830     if (PyObject_CheckBuffer(arg)) {
831         Py_ssize_t size;
832         Py_buffer view;
833         if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
834             return -1;
835         size = view.len;
836         if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
837         if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
838             &view, size, 'C') < 0)
839             goto fail;
840         PyBuffer_Release(&view);
841         return 0;
842     fail:
843         PyBuffer_Release(&view);
844         return -1;
845     }
846 
847     /* 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. */
905 static PyObject *
bytearray_repr(PyByteArrayObject * self)906 bytearray_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 
992 static PyObject *
bytearray_str(PyObject * op)993 bytearray_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 
1004 static PyObject *
bytearray_richcompare(PyObject * self,PyObject * other,int op)1005 bytearray_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 
1059 static void
bytearray_dealloc(PyByteArrayObject * self)1060 bytearray_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 
1099 static PyObject *
bytearray_find(PyByteArrayObject * self,PyObject * args)1100 bytearray_find(PyByteArrayObject *self, PyObject *args)
1101 {
1102     return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1103 }
1104 
1105 static PyObject *
bytearray_count(PyByteArrayObject * self,PyObject * args)1106 bytearray_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]
1112 bytearray.clear
1113 
1114 Remove all items from the bytearray.
1115 [clinic start generated code]*/
1116 
1117 static PyObject *
bytearray_clear_impl(PyByteArrayObject * self)1118 bytearray_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]
1127 bytearray.copy
1128 
1129 Return a copy of B.
1130 [clinic start generated code]*/
1131 
1132 static PyObject *
bytearray_copy_impl(PyByteArrayObject * self)1133 bytearray_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 
1140 static PyObject *
bytearray_index(PyByteArrayObject * self,PyObject * args)1141 bytearray_index(PyByteArrayObject *self, PyObject *args)
1142 {
1143     return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1144 }
1145 
1146 static PyObject *
bytearray_rfind(PyByteArrayObject * self,PyObject * args)1147 bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1148 {
1149     return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1150 }
1151 
1152 static PyObject *
bytearray_rindex(PyByteArrayObject * self,PyObject * args)1153 bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1154 {
1155     return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1156 }
1157 
1158 static int
bytearray_contains(PyObject * self,PyObject * arg)1159 bytearray_contains(PyObject *self, PyObject *arg)
1160 {
1161     return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg);
1162 }
1163 
1164 static PyObject *
bytearray_startswith(PyByteArrayObject * self,PyObject * args)1165 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1166 {
1167     return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1168 }
1169 
1170 static PyObject *
bytearray_endswith(PyByteArrayObject * self,PyObject * args)1171 bytearray_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]
1177 bytearray.removeprefix as bytearray_removeprefix
1178 
1179     prefix: Py_buffer
1180     /
1181 
1182 Return a bytearray with the given prefix string removed if present.
1183 
1184 If the bytearray starts with the prefix string, return
1185 bytearray[len(prefix):].  Otherwise, return a copy of the original
1186 bytearray.
1187 [clinic start generated code]*/
1188 
1189 static PyObject *
bytearray_removeprefix_impl(PyByteArrayObject * self,Py_buffer * prefix)1190 bytearray_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]
1209 bytearray.removesuffix as bytearray_removesuffix
1210 
1211     suffix: Py_buffer
1212     /
1213 
1214 Return a bytearray with the given suffix string removed if present.
1215 
1216 If the bytearray ends with the suffix string and that suffix is not
1217 empty, return bytearray[:-len(suffix)].  Otherwise, return a copy of
1218 the original bytearray.
1219 [clinic start generated code]*/
1220 
1221 static PyObject *
bytearray_removesuffix_impl(PyByteArrayObject * self,Py_buffer * suffix)1222 bytearray_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]
1243 bytearray.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 
1250 Return a copy with each character mapped by the given translation table.
1251 
1252 All characters occurring in the optional argument delete are removed.
1253 The remaining characters are mapped through the given translation table.
1254 [clinic start generated code]*/
1255 
1256 static PyObject *
bytearray_translate_impl(PyByteArrayObject * self,PyObject * table,PyObject * deletechars)1257 bytearray_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 
1337 done:
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
1349 bytearray.maketrans
1350 
1351     frm: Py_buffer
1352     to: Py_buffer
1353     /
1354 
1355 Return a translation table useable for the bytes or bytearray translate method.
1356 
1357 The returned table will be one where each byte in frm is mapped to the byte at
1358 the same position in to.
1359 
1360 The bytes objects frm and to must be of the same length.
1361 [clinic start generated code]*/
1362 
1363 static PyObject *
bytearray_maketrans_impl(Py_buffer * frm,Py_buffer * to)1364 bytearray_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]
1372 bytearray.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 
1381 Return a copy with all occurrences of substring old replaced by new.
1382 
1383 If the optional argument count is given, only the first count occurrences are
1384 replaced.
1385 [clinic start generated code]*/
1386 
1387 static PyObject *
bytearray_replace_impl(PyByteArrayObject * self,Py_buffer * old,Py_buffer * new,Py_ssize_t count)1388 bytearray_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]
1398 bytearray.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 
1408 Return a list of the sections in the bytearray, using sep as the delimiter.
1409 [clinic start generated code]*/
1410 
1411 static PyObject *
bytearray_split_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1412 bytearray_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]
1440 bytearray.partition
1441 
1442     sep: object
1443     /
1444 
1445 Partition the bytearray into three parts using the given separator.
1446 
1447 This will search for the separator sep in the bytearray. If the separator is
1448 found, returns a 3-tuple containing the part before the separator, the
1449 separator itself, and the part after it as new bytearray objects.
1450 
1451 If the separator is not found, returns a 3-tuple containing the copy of the
1452 original bytearray object and two empty bytearray objects.
1453 [clinic start generated code]*/
1454 
1455 static PyObject *
bytearray_partition(PyByteArrayObject * self,PyObject * sep)1456 bytearray_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]
1477 bytearray.rpartition
1478 
1479     sep: object
1480     /
1481 
1482 Partition the bytearray into three parts using the given separator.
1483 
1484 This will search for the separator sep in the bytearray, starting at the end.
1485 If the separator is found, returns a 3-tuple containing the part before the
1486 separator, the separator itself, and the part after it as new bytearray
1487 objects.
1488 
1489 If the separator is not found, returns a 3-tuple containing two empty bytearray
1490 objects and the copy of the original bytearray object.
1491 [clinic start generated code]*/
1492 
1493 static PyObject *
bytearray_rpartition(PyByteArrayObject * self,PyObject * sep)1494 bytearray_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]
1515 bytearray.rsplit = bytearray.split
1516 
1517 Return a list of the sections in the bytearray, using sep as the delimiter.
1518 
1519 Splitting is done starting at the end of the bytearray and working to the front.
1520 [clinic start generated code]*/
1521 
1522 static PyObject *
bytearray_rsplit_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1523 bytearray_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]
1551 bytearray.reverse
1552 
1553 Reverse the order of the values in B in place.
1554 [clinic start generated code]*/
1555 
1556 static PyObject *
bytearray_reverse_impl(PyByteArrayObject * self)1557 bytearray_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]
1577 class 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]
1585 bytearray.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 
1593 Insert a single item into the bytearray before the given index.
1594 [clinic start generated code]*/
1595 
1596 static PyObject *
bytearray_insert_impl(PyByteArrayObject * self,Py_ssize_t index,int item)1597 bytearray_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]
1626 bytearray.append
1627 
1628     item: bytesvalue
1629         The item to be appended.
1630     /
1631 
1632 Append a single item to the end of the bytearray.
1633 [clinic start generated code]*/
1634 
1635 static PyObject *
bytearray_append_impl(PyByteArrayObject * self,int item)1636 bytearray_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]
1655 bytearray.extend
1656 
1657     iterable_of_ints: object
1658         The iterable of items to append.
1659     /
1660 
1661 Append all the items from the iterator or sequence to the end of the bytearray.
1662 [clinic start generated code]*/
1663 
1664 static PyObject *
bytearray_extend(PyByteArrayObject * self,PyObject * iterable_of_ints)1665 bytearray_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]
1761 bytearray.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 
1768 Remove and return a single item from B.
1769 
1770 If no index argument is given, will pop the last item.
1771 [clinic start generated code]*/
1772 
1773 static PyObject *
bytearray_pop_impl(PyByteArrayObject * self,Py_ssize_t index)1774 bytearray_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]
1805 bytearray.remove
1806 
1807     value: bytesvalue
1808         The value to remove.
1809     /
1810 
1811 Remove the first occurrence of a value in the bytearray.
1812 [clinic start generated code]*/
1813 
1814 static PyObject *
bytearray_remove_impl(PyByteArrayObject * self,int value)1815 bytearray_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 
1838 static Py_ssize_t
lstrip_helper(const char * myptr,Py_ssize_t mysize,const void * argptr,Py_ssize_t argsize)1839 lstrip_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 
1848 static Py_ssize_t
rstrip_helper(const char * myptr,Py_ssize_t mysize,const void * argptr,Py_ssize_t argsize)1849 rstrip_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]
1859 bytearray.strip
1860 
1861     bytes: object = None
1862     /
1863 
1864 Strip leading and trailing bytes contained in the argument.
1865 
1866 If the argument is omitted or None, strip leading and trailing ASCII whitespace.
1867 [clinic start generated code]*/
1868 
1869 static PyObject *
bytearray_strip_impl(PyByteArrayObject * self,PyObject * bytes)1870 bytearray_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]
1901 bytearray.lstrip
1902 
1903     bytes: object = None
1904     /
1905 
1906 Strip leading bytes contained in the argument.
1907 
1908 If the argument is omitted or None, strip leading ASCII whitespace.
1909 [clinic start generated code]*/
1910 
1911 static PyObject *
bytearray_lstrip_impl(PyByteArrayObject * self,PyObject * bytes)1912 bytearray_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]
1940 bytearray.rstrip
1941 
1942     bytes: object = None
1943     /
1944 
1945 Strip trailing bytes contained in the argument.
1946 
1947 If the argument is omitted or None, strip trailing ASCII whitespace.
1948 [clinic start generated code]*/
1949 
1950 static PyObject *
bytearray_rstrip_impl(PyByteArrayObject * self,PyObject * bytes)1951 bytearray_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]
1978 bytearray.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 
1989 Decode the bytearray using the codec registered for encoding.
1990 [clinic start generated code]*/
1991 
1992 static PyObject *
bytearray_decode_impl(PyByteArrayObject * self,const char * encoding,const char * errors)1993 bytearray_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 
2002 PyDoc_STRVAR(alloc_doc,
2003 "B.__alloc__() -> int\n\
2004 \n\
2005 Return the number of bytes actually allocated.");
2006 
2007 static PyObject *
bytearray_alloc(PyByteArrayObject * self,PyObject * Py_UNUSED (ignored))2008 bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
2009 {
2010     return PyLong_FromSsize_t(self->ob_alloc);
2011 }
2012 
2013 /*[clinic input]
2014 bytearray.join
2015 
2016     iterable_of_bytes: object
2017     /
2018 
2019 Concatenate any number of bytes/bytearray objects.
2020 
2021 The bytearray whose method is called is inserted in between each pair.
2022 
2023 The result is returned as a new bytearray object.
2024 [clinic start generated code]*/
2025 
2026 static PyObject *
bytearray_join(PyByteArrayObject * self,PyObject * iterable_of_bytes)2027 bytearray_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]
2034 bytearray.splitlines
2035 
2036     keepends: bool(accept={int}) = False
2037 
2038 Return a list of the lines in the bytearray, breaking at line boundaries.
2039 
2040 Line breaks are not included in the resulting list unless keepends is given and
2041 true.
2042 [clinic start generated code]*/
2043 
2044 static PyObject *
bytearray_splitlines_impl(PyByteArrayObject * self,int keepends)2045 bytearray_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
2056 bytearray.fromhex
2057 
2058     string: unicode
2059     /
2060 
2061 Create a bytearray object from a string of hexadecimal numbers.
2062 
2063 Spaces between two numbers are accepted.
2064 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2065 [clinic start generated code]*/
2066 
2067 static PyObject *
bytearray_fromhex_impl(PyTypeObject * type,PyObject * string)2068 bytearray_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]
2079 bytearray.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 
2087 Create a string of hexadecimal numbers from a bytearray object.
2088 
2089 Example:
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 
2101 static PyObject *
bytearray_hex_impl(PyByteArrayObject * self,PyObject * sep,int bytes_per_sep)2102 bytearray_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 
2110 static PyObject *
_common_reduce(PyByteArrayObject * self,int proto)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]
2147 bytearray.__reduce__ as bytearray_reduce
2148 
2149 Return state information for pickling.
2150 [clinic start generated code]*/
2151 
2152 static PyObject *
bytearray_reduce_impl(PyByteArrayObject * self)2153 bytearray_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]
2160 bytearray.__reduce_ex__ as bytearray_reduce_ex
2161 
2162     proto: int = 0
2163     /
2164 
2165 Return state information for pickling.
2166 [clinic start generated code]*/
2167 
2168 static PyObject *
bytearray_reduce_ex_impl(PyByteArrayObject * self,int proto)2169 bytearray_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]
2176 bytearray.__sizeof__ as bytearray_sizeof
2177 
2178 Returns the size of the bytearray object in memory, in bytes.
2179 [clinic start generated code]*/
2180 
2181 static PyObject *
bytearray_sizeof_impl(PyByteArrayObject * self)2182 bytearray_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 
2191 static 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 
2204 static PyMappingMethods bytearray_as_mapping = {
2205     (lenfunc)bytearray_length,
2206     (binaryfunc)bytearray_subscript,
2207     (objobjargproc)bytearray_ass_subscript,
2208 };
2209 
2210 static PyBufferProcs bytearray_as_buffer = {
2211     (getbufferproc)bytearray_getbuffer,
2212     (releasebufferproc)bytearray_releasebuffer,
2213 };
2214 
2215 static PyMethodDef
2216 bytearray_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 
2288 static PyObject *
bytearray_mod(PyObject * v,PyObject * w)2289 bytearray_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 
2296 static PyNumberMethods bytearray_as_number = {
2297     0,              /*nb_add*/
2298     0,              /*nb_subtract*/
2299     0,              /*nb_multiply*/
2300     bytearray_mod,  /*nb_remainder*/
2301 };
2302 
2303 PyDoc_STRVAR(bytearray_doc,
2304 "bytearray(iterable_of_ints) -> bytearray\n\
2305 bytearray(string, encoding[, errors]) -> bytearray\n\
2306 bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2307 bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2308 bytearray() -> empty bytes array\n\
2309 \n\
2310 Construct 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 
2318 static PyObject *bytearray_iter(PyObject *seq);
2319 
2320 PyTypeObject 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 
2365 typedef struct {
2366     PyObject_HEAD
2367     Py_ssize_t it_index;
2368     PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2369 } bytesiterobject;
2370 
2371 static void
bytearrayiter_dealloc(bytesiterobject * it)2372 bytearrayiter_dealloc(bytesiterobject *it)
2373 {
2374     _PyObject_GC_UNTRACK(it);
2375     Py_XDECREF(it->it_seq);
2376     PyObject_GC_Del(it);
2377 }
2378 
2379 static int
bytearrayiter_traverse(bytesiterobject * it,visitproc visit,void * arg)2380 bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2381 {
2382     Py_VISIT(it->it_seq);
2383     return 0;
2384 }
2385 
2386 static PyObject *
bytearrayiter_next(bytesiterobject * it)2387 bytearrayiter_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 
2411 static PyObject *
bytearrayiter_length_hint(bytesiterobject * it,PyObject * Py_UNUSED (ignored))2412 bytearrayiter_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 
2424 PyDoc_STRVAR(length_hint_doc,
2425     "Private method returning an estimate of len(list(it)).");
2426 
2427 static PyObject *
bytearrayiter_reduce(bytesiterobject * it,PyObject * Py_UNUSED (ignored))2428 bytearrayiter_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 
2439 static PyObject *
bytearrayiter_setstate(bytesiterobject * it,PyObject * state)2440 bytearrayiter_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 
2455 PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2456 
2457 static 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 
2467 PyTypeObject 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 
2500 static PyObject *
bytearray_iter(PyObject * seq)2501 bytearray_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