Coverage Report

Created: 2025-07-11 06:59

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