LCOV - code coverage report
Current view: | top level - Objects - bytearrayobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 200 | 942 | 21.2 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 19 | 73 | 26.0 %
|  |  | Branches: | 90 | 618 | 14.6 %

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

Generated by: LCOV version 1.14