LCOV - code coverage report
Current view: top level - Objects - bytearrayobject.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 834 958 87.1 %
Date: 2022-07-07 18:19:46 Functions: 71 73 97.3 %

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

Generated by: LCOV version 1.14