Coverage Report

Created: 2022-07-08 09:39

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