• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
_getbytevalue(PyObject * arg,int * value)25 _getbytevalue(PyObject* arg, int *value)
26 {
27     long face_value;
28 
29     if (PyLong_Check(arg)) {
30         face_value = PyLong_AsLong(arg);
31     } else {
32         PyObject *index = PyNumber_Index(arg);
33         if (index == NULL) {
34             *value = -1;
35             return 0;
36         }
37         face_value = PyLong_AsLong(index);
38         Py_DECREF(index);
39     }
40 
41     if (face_value < 0 || face_value >= 256) {
42         /* this includes the OverflowError in case the long is too large */
43         PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
44         *value = -1;
45         return 0;
46     }
47 
48     *value = face_value;
49     return 1;
50 }
51 
52 static int
bytearray_getbuffer(PyByteArrayObject * obj,Py_buffer * view,int flags)53 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
54 {
55     void *ptr;
56     if (view == NULL) {
57         PyErr_SetString(PyExc_BufferError,
58             "bytearray_getbuffer: view==NULL argument is obsolete");
59         return -1;
60     }
61     ptr = (void *) PyByteArray_AS_STRING(obj);
62     /* cannot fail if view != NULL and readonly == 0 */
63     (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
64     obj->ob_exports++;
65     return 0;
66 }
67 
68 static void
bytearray_releasebuffer(PyByteArrayObject * obj,Py_buffer * view)69 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
70 {
71     obj->ob_exports--;
72 }
73 
74 static int
_canresize(PyByteArrayObject * self)75 _canresize(PyByteArrayObject *self)
76 {
77     if (self->ob_exports > 0) {
78         PyErr_SetString(PyExc_BufferError,
79                 "Existing exports of data: object cannot be re-sized");
80         return 0;
81     }
82     return 1;
83 }
84 
85 #include "clinic/bytearrayobject.c.h"
86 
87 /* Direct API functions */
88 
89 PyObject *
PyByteArray_FromObject(PyObject * input)90 PyByteArray_FromObject(PyObject *input)
91 {
92     return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
93                                         input, NULL);
94 }
95 
96 static PyObject *
_PyByteArray_FromBufferObject(PyObject * obj)97 _PyByteArray_FromBufferObject(PyObject *obj)
98 {
99     PyObject *result;
100     Py_buffer view;
101 
102     if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
103         return NULL;
104     }
105     result = PyByteArray_FromStringAndSize(NULL, view.len);
106     if (result != NULL &&
107         PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
108                               &view, view.len, 'C') < 0)
109     {
110         Py_CLEAR(result);
111     }
112     PyBuffer_Release(&view);
113     return result;
114 }
115 
116 PyObject *
PyByteArray_FromStringAndSize(const char * bytes,Py_ssize_t size)117 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
118 {
119     PyByteArrayObject *new;
120     Py_ssize_t alloc;
121 
122     if (size < 0) {
123         PyErr_SetString(PyExc_SystemError,
124             "Negative size passed to PyByteArray_FromStringAndSize");
125         return NULL;
126     }
127 
128     /* Prevent buffer overflow when setting alloc to size+1. */
129     if (size == PY_SSIZE_T_MAX) {
130         return PyErr_NoMemory();
131     }
132 
133     new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
134     if (new == NULL)
135         return NULL;
136 
137     if (size == 0) {
138         new->ob_bytes = NULL;
139         alloc = 0;
140     }
141     else {
142         alloc = size + 1;
143         new->ob_bytes = PyObject_Malloc(alloc);
144         if (new->ob_bytes == NULL) {
145             Py_DECREF(new);
146             return PyErr_NoMemory();
147         }
148         if (bytes != NULL && size > 0)
149             memcpy(new->ob_bytes, bytes, size);
150         new->ob_bytes[size] = '\0';  /* Trailing null byte */
151     }
152     Py_SIZE(new) = size;
153     new->ob_alloc = alloc;
154     new->ob_start = new->ob_bytes;
155     new->ob_exports = 0;
156 
157     return (PyObject *)new;
158 }
159 
160 Py_ssize_t
PyByteArray_Size(PyObject * self)161 PyByteArray_Size(PyObject *self)
162 {
163     assert(self != NULL);
164     assert(PyByteArray_Check(self));
165 
166     return PyByteArray_GET_SIZE(self);
167 }
168 
169 char  *
PyByteArray_AsString(PyObject * self)170 PyByteArray_AsString(PyObject *self)
171 {
172     assert(self != NULL);
173     assert(PyByteArray_Check(self));
174 
175     return PyByteArray_AS_STRING(self);
176 }
177 
178 int
PyByteArray_Resize(PyObject * self,Py_ssize_t requested_size)179 PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
180 {
181     void *sval;
182     PyByteArrayObject *obj = ((PyByteArrayObject *)self);
183     /* All computations are done unsigned to avoid integer overflows
184        (see issue #22335). */
185     size_t alloc = (size_t) obj->ob_alloc;
186     size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
187     size_t size = (size_t) requested_size;
188 
189     assert(self != NULL);
190     assert(PyByteArray_Check(self));
191     assert(logical_offset <= alloc);
192     assert(requested_size >= 0);
193 
194     if (requested_size == Py_SIZE(self)) {
195         return 0;
196     }
197     if (!_canresize(obj)) {
198         return -1;
199     }
200 
201     if (size + logical_offset + 1 <= alloc) {
202         /* Current buffer is large enough to host the requested size,
203            decide on a strategy. */
204         if (size < alloc / 2) {
205             /* Major downsize; resize down to exact size */
206             alloc = size + 1;
207         }
208         else {
209             /* Minor downsize; quick exit */
210             Py_SIZE(self) = size;
211             PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
212             return 0;
213         }
214     }
215     else {
216         /* Need growing, decide on a strategy */
217         if (size <= alloc * 1.125) {
218             /* Moderate upsize; overallocate similar to list_resize() */
219             alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
220         }
221         else {
222             /* Major upsize; resize up to exact size */
223             alloc = size + 1;
224         }
225     }
226     if (alloc > PY_SSIZE_T_MAX) {
227         PyErr_NoMemory();
228         return -1;
229     }
230 
231     if (logical_offset > 0) {
232         sval = PyObject_Malloc(alloc);
233         if (sval == NULL) {
234             PyErr_NoMemory();
235             return -1;
236         }
237         memcpy(sval, PyByteArray_AS_STRING(self),
238                Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
239         PyObject_Free(obj->ob_bytes);
240     }
241     else {
242         sval = PyObject_Realloc(obj->ob_bytes, alloc);
243         if (sval == NULL) {
244             PyErr_NoMemory();
245             return -1;
246         }
247     }
248 
249     obj->ob_bytes = obj->ob_start = sval;
250     Py_SIZE(self) = size;
251     obj->ob_alloc = alloc;
252     obj->ob_bytes[size] = '\0'; /* Trailing null byte */
253 
254     return 0;
255 }
256 
257 PyObject *
PyByteArray_Concat(PyObject * a,PyObject * b)258 PyByteArray_Concat(PyObject *a, PyObject *b)
259 {
260     Py_buffer va, vb;
261     PyByteArrayObject *result = NULL;
262 
263     va.len = -1;
264     vb.len = -1;
265     if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
266         PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
267             PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
268                          Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
269             goto done;
270     }
271 
272     if (va.len > PY_SSIZE_T_MAX - vb.len) {
273         PyErr_NoMemory();
274         goto done;
275     }
276 
277     result = (PyByteArrayObject *) \
278         PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
279     if (result != NULL) {
280         memcpy(result->ob_bytes, va.buf, va.len);
281         memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
282     }
283 
284   done:
285     if (va.len != -1)
286         PyBuffer_Release(&va);
287     if (vb.len != -1)
288         PyBuffer_Release(&vb);
289     return (PyObject *)result;
290 }
291 
292 /* Functions stuffed into the type object */
293 
294 static Py_ssize_t
bytearray_length(PyByteArrayObject * self)295 bytearray_length(PyByteArrayObject *self)
296 {
297     return Py_SIZE(self);
298 }
299 
300 static PyObject *
bytearray_iconcat(PyByteArrayObject * self,PyObject * other)301 bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
302 {
303     Py_ssize_t size;
304     Py_buffer vo;
305 
306     if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
307         PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
308                      Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
309         return NULL;
310     }
311 
312     size = Py_SIZE(self);
313     if (size > PY_SSIZE_T_MAX - vo.len) {
314         PyBuffer_Release(&vo);
315         return PyErr_NoMemory();
316     }
317     if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
318         PyBuffer_Release(&vo);
319         return NULL;
320     }
321     memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
322     PyBuffer_Release(&vo);
323     Py_INCREF(self);
324     return (PyObject *)self;
325 }
326 
327 static PyObject *
bytearray_repeat(PyByteArrayObject * self,Py_ssize_t count)328 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
329 {
330     PyByteArrayObject *result;
331     Py_ssize_t mysize;
332     Py_ssize_t size;
333 
334     if (count < 0)
335         count = 0;
336     mysize = Py_SIZE(self);
337     if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
338         return PyErr_NoMemory();
339     size = mysize * count;
340     result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
341     if (result != NULL && size != 0) {
342         if (mysize == 1)
343             memset(result->ob_bytes, self->ob_bytes[0], size);
344         else {
345             Py_ssize_t i;
346             for (i = 0; i < count; i++)
347                 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
348         }
349     }
350     return (PyObject *)result;
351 }
352 
353 static PyObject *
bytearray_irepeat(PyByteArrayObject * self,Py_ssize_t count)354 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
355 {
356     Py_ssize_t mysize;
357     Py_ssize_t size;
358     char *buf;
359 
360     if (count < 0)
361         count = 0;
362     mysize = Py_SIZE(self);
363     if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
364         return PyErr_NoMemory();
365     size = mysize * count;
366     if (PyByteArray_Resize((PyObject *)self, size) < 0)
367         return NULL;
368 
369     buf = PyByteArray_AS_STRING(self);
370     if (mysize == 1)
371         memset(buf, buf[0], size);
372     else {
373         Py_ssize_t i;
374         for (i = 1; i < count; i++)
375             memcpy(buf + i*mysize, buf, mysize);
376     }
377 
378     Py_INCREF(self);
379     return (PyObject *)self;
380 }
381 
382 static PyObject *
bytearray_getitem(PyByteArrayObject * self,Py_ssize_t i)383 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
384 {
385     if (i < 0)
386         i += Py_SIZE(self);
387     if (i < 0 || i >= Py_SIZE(self)) {
388         PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
389         return NULL;
390     }
391     return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
392 }
393 
394 static PyObject *
bytearray_subscript(PyByteArrayObject * self,PyObject * index)395 bytearray_subscript(PyByteArrayObject *self, PyObject *index)
396 {
397     if (PyIndex_Check(index)) {
398         Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
399 
400         if (i == -1 && PyErr_Occurred())
401             return NULL;
402 
403         if (i < 0)
404             i += PyByteArray_GET_SIZE(self);
405 
406         if (i < 0 || i >= Py_SIZE(self)) {
407             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
408             return NULL;
409         }
410         return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
411     }
412     else if (PySlice_Check(index)) {
413         Py_ssize_t start, stop, step, slicelength, i;
414         size_t cur;
415         if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
416             return NULL;
417         }
418         slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
419                                             &start, &stop, step);
420 
421         if (slicelength <= 0)
422             return PyByteArray_FromStringAndSize("", 0);
423         else if (step == 1) {
424             return PyByteArray_FromStringAndSize(
425                 PyByteArray_AS_STRING(self) + start, slicelength);
426         }
427         else {
428             char *source_buf = PyByteArray_AS_STRING(self);
429             char *result_buf;
430             PyObject *result;
431 
432             result = PyByteArray_FromStringAndSize(NULL, slicelength);
433             if (result == NULL)
434                 return NULL;
435 
436             result_buf = PyByteArray_AS_STRING(result);
437             for (cur = start, i = 0; i < slicelength;
438                  cur += step, i++) {
439                      result_buf[i] = source_buf[cur];
440             }
441             return result;
442         }
443     }
444     else {
445         PyErr_Format(PyExc_TypeError,
446                      "bytearray indices must be integers or slices, not %.200s",
447                      Py_TYPE(index)->tp_name);
448         return NULL;
449     }
450 }
451 
452 static int
bytearray_setslice_linear(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,char * bytes,Py_ssize_t bytes_len)453 bytearray_setslice_linear(PyByteArrayObject *self,
454                           Py_ssize_t lo, Py_ssize_t hi,
455                           char *bytes, Py_ssize_t bytes_len)
456 {
457     Py_ssize_t avail = hi - lo;
458     char *buf = PyByteArray_AS_STRING(self);
459     Py_ssize_t growth = bytes_len - avail;
460     int res = 0;
461     assert(avail >= 0);
462 
463     if (growth < 0) {
464         if (!_canresize(self))
465             return -1;
466 
467         if (lo == 0) {
468             /* Shrink the buffer by advancing its logical start */
469             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         }
477         else {
478             /*
479               0   lo               hi               old_size
480               |   |<----avail----->|<-----tomove------>|
481               |   |<-bytes_len->|<-----tomove------>|
482               0   lo         new_hi              new_size
483             */
484             memmove(buf + lo + bytes_len, buf + hi,
485                     Py_SIZE(self) - hi);
486         }
487         if (PyByteArray_Resize((PyObject *)self,
488                                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             if (lo == 0) {
499                 self->ob_start += growth;
500                 return -1;
501             }
502             /* memmove() removed bytes, the bytearray object cannot be
503                restored in its previous state. */
504             Py_SIZE(self) += growth;
505             res = -1;
506         }
507         buf = PyByteArray_AS_STRING(self);
508     }
509     else if (growth > 0) {
510         if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
511             PyErr_NoMemory();
512             return -1;
513         }
514 
515         if (PyByteArray_Resize((PyObject *)self,
516                                Py_SIZE(self) + growth) < 0) {
517             return -1;
518         }
519         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         memmove(buf + lo + bytes_len, buf + hi,
528                 Py_SIZE(self) - lo - bytes_len);
529     }
530 
531     if (bytes_len > 0)
532         memcpy(buf + lo, bytes, bytes_len);
533     return res;
534 }
535 
536 static int
bytearray_setslice(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,PyObject * values)537 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
538                PyObject *values)
539 {
540     Py_ssize_t needed;
541     void *bytes;
542     Py_buffer vbytes;
543     int res = 0;
544 
545     vbytes.len = -1;
546     if (values == (PyObject *)self) {
547         /* Make a copy and call this function recursively */
548         int err;
549         values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
550                                                PyByteArray_GET_SIZE(values));
551         if (values == NULL)
552             return -1;
553         err = bytearray_setslice(self, lo, hi, values);
554         Py_DECREF(values);
555         return err;
556     }
557     if (values == NULL) {
558         /* del b[lo:hi] */
559         bytes = NULL;
560         needed = 0;
561     }
562     else {
563         if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
564             PyErr_Format(PyExc_TypeError,
565                          "can't set bytearray slice from %.100s",
566                          Py_TYPE(values)->tp_name);
567             return -1;
568         }
569         needed = vbytes.len;
570         bytes = vbytes.buf;
571     }
572 
573     if (lo < 0)
574         lo = 0;
575     if (hi < lo)
576         hi = lo;
577     if (hi > Py_SIZE(self))
578         hi = Py_SIZE(self);
579 
580     res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
581     if (vbytes.len != -1)
582         PyBuffer_Release(&vbytes);
583     return res;
584 }
585 
586 static int
bytearray_setitem(PyByteArrayObject * self,Py_ssize_t i,PyObject * value)587 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
588 {
589     int ival;
590 
591     if (i < 0)
592         i += Py_SIZE(self);
593 
594     if (i < 0 || i >= Py_SIZE(self)) {
595         PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
596         return -1;
597     }
598 
599     if (value == NULL)
600         return bytearray_setslice(self, i, i+1, NULL);
601 
602     if (!_getbytevalue(value, &ival))
603         return -1;
604 
605     PyByteArray_AS_STRING(self)[i] = ival;
606     return 0;
607 }
608 
609 static int
bytearray_ass_subscript(PyByteArrayObject * self,PyObject * index,PyObject * values)610 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
611 {
612     Py_ssize_t start, stop, step, slicelen, needed;
613     char *buf, *bytes;
614     buf = PyByteArray_AS_STRING(self);
615 
616     if (PyIndex_Check(index)) {
617         Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
618 
619         if (i == -1 && PyErr_Occurred())
620             return -1;
621 
622         if (i < 0)
623             i += PyByteArray_GET_SIZE(self);
624 
625         if (i < 0 || i >= Py_SIZE(self)) {
626             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
627             return -1;
628         }
629 
630         if (values == NULL) {
631             /* Fall through to slice assignment */
632             start = i;
633             stop = i + 1;
634             step = 1;
635             slicelen = 1;
636         }
637         else {
638             int ival;
639             if (!_getbytevalue(values, &ival))
640                 return -1;
641             buf[i] = (char)ival;
642             return 0;
643         }
644     }
645     else if (PySlice_Check(index)) {
646         if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
647             return -1;
648         }
649         slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
650                                          &stop, step);
651     }
652     else {
653         PyErr_Format(PyExc_TypeError,
654                      "bytearray indices must be integers or slices, not %.200s",
655                       Py_TYPE(index)->tp_name);
656         return -1;
657     }
658 
659     if (values == NULL) {
660         bytes = NULL;
661         needed = 0;
662     }
663     else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
664         int err;
665         if (PyNumber_Check(values) || PyUnicode_Check(values)) {
666             PyErr_SetString(PyExc_TypeError,
667                             "can assign only bytes, buffers, or iterables "
668                             "of ints in range(0, 256)");
669             return -1;
670         }
671         /* Make a copy and call this function recursively */
672         values = PyByteArray_FromObject(values);
673         if (values == NULL)
674             return -1;
675         err = bytearray_ass_subscript(self, index, values);
676         Py_DECREF(values);
677         return err;
678     }
679     else {
680         assert(PyByteArray_Check(values));
681         bytes = PyByteArray_AS_STRING(values);
682         needed = Py_SIZE(values);
683     }
684     /* Make sure b[5:2] = ... inserts before 5, not before 2. */
685     if ((step < 0 && start < stop) ||
686         (step > 0 && start > stop))
687         stop = start;
688     if (step == 1) {
689         return bytearray_setslice_linear(self, start, stop, bytes, needed);
690     }
691     else {
692         if (needed == 0) {
693             /* Delete slice */
694             size_t cur;
695             Py_ssize_t i;
696 
697             if (!_canresize(self))
698                 return -1;
699 
700             if (slicelen == 0)
701                 /* Nothing to do here. */
702                 return 0;
703 
704             if (step < 0) {
705                 stop = start + 1;
706                 start = stop + step * (slicelen - 1) - 1;
707                 step = -step;
708             }
709             for (cur = start, i = 0;
710                  i < slicelen; cur += step, i++) {
711                 Py_ssize_t lim = step - 1;
712 
713                 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
714                     lim = PyByteArray_GET_SIZE(self) - cur - 1;
715 
716                 memmove(buf + cur - i,
717                         buf + cur + 1, lim);
718             }
719             /* Move the tail of the bytes, in one chunk */
720             cur = start + (size_t)slicelen*step;
721             if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
722                 memmove(buf + cur - slicelen,
723                         buf + cur,
724                         PyByteArray_GET_SIZE(self) - cur);
725             }
726             if (PyByteArray_Resize((PyObject *)self,
727                                PyByteArray_GET_SIZE(self) - slicelen) < 0)
728                 return -1;
729 
730             return 0;
731         }
732         else {
733             /* Assign slice */
734             Py_ssize_t i;
735             size_t cur;
736 
737             if (needed != slicelen) {
738                 PyErr_Format(PyExc_ValueError,
739                              "attempt to assign bytes of size %zd "
740                              "to extended slice of size %zd",
741                              needed, slicelen);
742                 return -1;
743             }
744             for (cur = start, i = 0; i < slicelen; cur += step, i++)
745                 buf[cur] = bytes[i];
746             return 0;
747         }
748     }
749 }
750 
751 static int
bytearray_init(PyByteArrayObject * self,PyObject * args,PyObject * kwds)752 bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
753 {
754     static char *kwlist[] = {"source", "encoding", "errors", 0};
755     PyObject *arg = NULL;
756     const char *encoding = NULL;
757     const char *errors = NULL;
758     Py_ssize_t count;
759     PyObject *it;
760     PyObject *(*iternext)(PyObject *);
761 
762     if (Py_SIZE(self) != 0) {
763         /* Empty previous contents (yes, do this first of all!) */
764         if (PyByteArray_Resize((PyObject *)self, 0) < 0)
765             return -1;
766     }
767 
768     /* Parse arguments */
769     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
770                                      &arg, &encoding, &errors))
771         return -1;
772 
773     /* Make a quick exit if no first argument */
774     if (arg == NULL) {
775         if (encoding != NULL || errors != NULL) {
776             PyErr_SetString(PyExc_TypeError,
777                             encoding != NULL ?
778                             "encoding without a string argument" :
779                             "errors without a string argument");
780             return -1;
781         }
782         return 0;
783     }
784 
785     if (PyUnicode_Check(arg)) {
786         /* Encode via the codec registry */
787         PyObject *encoded, *new;
788         if (encoding == NULL) {
789             PyErr_SetString(PyExc_TypeError,
790                             "string argument without an encoding");
791             return -1;
792         }
793         encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
794         if (encoded == NULL)
795             return -1;
796         assert(PyBytes_Check(encoded));
797         new = bytearray_iconcat(self, encoded);
798         Py_DECREF(encoded);
799         if (new == NULL)
800             return -1;
801         Py_DECREF(new);
802         return 0;
803     }
804 
805     /* If it's not unicode, there can't be encoding or errors */
806     if (encoding != NULL || errors != NULL) {
807         PyErr_SetString(PyExc_TypeError,
808                         encoding != NULL ?
809                         "encoding without a string argument" :
810                         "errors without a string argument");
811         return -1;
812     }
813 
814     /* Is it an int? */
815     if (PyIndex_Check(arg)) {
816         count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
817         if (count == -1 && PyErr_Occurred()) {
818             if (!PyErr_ExceptionMatches(PyExc_TypeError))
819                 return -1;
820             PyErr_Clear();  /* fall through */
821         }
822         else {
823             if (count < 0) {
824                 PyErr_SetString(PyExc_ValueError, "negative count");
825                 return -1;
826             }
827             if (count > 0) {
828                 if (PyByteArray_Resize((PyObject *)self, count))
829                     return -1;
830                 memset(PyByteArray_AS_STRING(self), 0, count);
831             }
832             return 0;
833         }
834     }
835 
836     /* Use the buffer API */
837     if (PyObject_CheckBuffer(arg)) {
838         Py_ssize_t size;
839         Py_buffer view;
840         if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
841             return -1;
842         size = view.len;
843         if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
844         if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
845             &view, size, 'C') < 0)
846             goto fail;
847         PyBuffer_Release(&view);
848         return 0;
849     fail:
850         PyBuffer_Release(&view);
851         return -1;
852     }
853 
854     /* XXX Optimize this if the arguments is a list, tuple */
855 
856     /* Get the iterator */
857     it = PyObject_GetIter(arg);
858     if (it == NULL) {
859         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
860             PyErr_Format(PyExc_TypeError,
861                          "cannot convert '%.200s' object to bytearray",
862                          arg->ob_type->tp_name);
863         }
864         return -1;
865     }
866     iternext = *Py_TYPE(it)->tp_iternext;
867 
868     /* Run the iterator to exhaustion */
869     for (;;) {
870         PyObject *item;
871         int rc, value;
872 
873         /* Get the next item */
874         item = iternext(it);
875         if (item == NULL) {
876             if (PyErr_Occurred()) {
877                 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
878                     goto error;
879                 PyErr_Clear();
880             }
881             break;
882         }
883 
884         /* Interpret it as an int (__index__) */
885         rc = _getbytevalue(item, &value);
886         Py_DECREF(item);
887         if (!rc)
888             goto error;
889 
890         /* Append the byte */
891         if (Py_SIZE(self) + 1 < self->ob_alloc) {
892             Py_SIZE(self)++;
893             PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
894         }
895         else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
896             goto error;
897         PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
898     }
899 
900     /* Clean up and return success */
901     Py_DECREF(it);
902     return 0;
903 
904  error:
905     /* Error handling when it != NULL */
906     Py_DECREF(it);
907     return -1;
908 }
909 
910 /* Mostly copied from string_repr, but without the
911    "smart quote" functionality. */
912 static PyObject *
bytearray_repr(PyByteArrayObject * self)913 bytearray_repr(PyByteArrayObject *self)
914 {
915     const char *className = _PyType_Name(Py_TYPE(self));
916     const char *quote_prefix = "(b";
917     const char *quote_postfix = ")";
918     Py_ssize_t length = Py_SIZE(self);
919     /* 6 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
920     Py_ssize_t newsize;
921     PyObject *v;
922     Py_ssize_t i;
923     char *bytes;
924     char c;
925     char *p;
926     int quote;
927     char *test, *start;
928     char *buffer;
929 
930     newsize = strlen(className);
931     if (length > (PY_SSIZE_T_MAX - 6 - newsize) / 4) {
932         PyErr_SetString(PyExc_OverflowError,
933             "bytearray object is too large to make repr");
934         return NULL;
935     }
936 
937     newsize += 6 + length * 4;
938     buffer = PyObject_Malloc(newsize);
939     if (buffer == NULL) {
940         PyErr_NoMemory();
941         return NULL;
942     }
943 
944     /* Figure out which quote to use; single is preferred */
945     quote = '\'';
946     start = PyByteArray_AS_STRING(self);
947     for (test = start; test < start+length; ++test) {
948         if (*test == '"') {
949             quote = '\''; /* back to single */
950             break;
951         }
952         else if (*test == '\'')
953             quote = '"';
954     }
955 
956     p = buffer;
957     while (*className)
958         *p++ = *className++;
959     while (*quote_prefix)
960         *p++ = *quote_prefix++;
961     *p++ = quote;
962 
963     bytes = PyByteArray_AS_STRING(self);
964     for (i = 0; i < length; i++) {
965         /* There's at least enough room for a hex escape
966            and a closing quote. */
967         assert(newsize - (p - buffer) >= 5);
968         c = bytes[i];
969         if (c == '\'' || c == '\\')
970             *p++ = '\\', *p++ = c;
971         else if (c == '\t')
972             *p++ = '\\', *p++ = 't';
973         else if (c == '\n')
974             *p++ = '\\', *p++ = 'n';
975         else if (c == '\r')
976             *p++ = '\\', *p++ = 'r';
977         else if (c == 0)
978             *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
979         else if (c < ' ' || c >= 0x7f) {
980             *p++ = '\\';
981             *p++ = 'x';
982             *p++ = Py_hexdigits[(c & 0xf0) >> 4];
983             *p++ = Py_hexdigits[c & 0xf];
984         }
985         else
986             *p++ = c;
987     }
988     assert(newsize - (p - buffer) >= 1);
989     *p++ = quote;
990     while (*quote_postfix) {
991        *p++ = *quote_postfix++;
992     }
993 
994     v = PyUnicode_FromStringAndSize(buffer, p - buffer);
995     PyObject_Free(buffer);
996     return v;
997 }
998 
999 static PyObject *
bytearray_str(PyObject * op)1000 bytearray_str(PyObject *op)
1001 {
1002     PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
1003     if (config->bytes_warning) {
1004         if (PyErr_WarnEx(PyExc_BytesWarning,
1005                          "str() on a bytearray instance", 1)) {
1006                 return NULL;
1007         }
1008     }
1009     return bytearray_repr((PyByteArrayObject*)op);
1010 }
1011 
1012 static PyObject *
bytearray_richcompare(PyObject * self,PyObject * other,int op)1013 bytearray_richcompare(PyObject *self, PyObject *other, int op)
1014 {
1015     Py_ssize_t self_size, other_size;
1016     Py_buffer self_bytes, other_bytes;
1017     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     rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1023     if (!rc)
1024         rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1025     if (rc < 0)
1026         return NULL;
1027     if (rc) {
1028         PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config;
1029         if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) {
1030             if (PyErr_WarnEx(PyExc_BytesWarning,
1031                             "Comparison between bytearray and string", 1))
1032                 return NULL;
1033         }
1034 
1035         Py_RETURN_NOTIMPLEMENTED;
1036     }
1037 
1038     if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1039         PyErr_Clear();
1040         Py_RETURN_NOTIMPLEMENTED;
1041     }
1042     self_size = self_bytes.len;
1043 
1044     if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1045         PyErr_Clear();
1046         PyBuffer_Release(&self_bytes);
1047         Py_RETURN_NOTIMPLEMENTED;
1048     }
1049     other_size = other_bytes.len;
1050 
1051     if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1052         /* Shortcut: if the lengths differ, the objects differ */
1053         PyBuffer_Release(&self_bytes);
1054         PyBuffer_Release(&other_bytes);
1055         return PyBool_FromLong((op == Py_NE));
1056     }
1057     else {
1058         cmp = memcmp(self_bytes.buf, other_bytes.buf,
1059                      Py_MIN(self_size, other_size));
1060         /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1061 
1062         PyBuffer_Release(&self_bytes);
1063         PyBuffer_Release(&other_bytes);
1064 
1065         if (cmp != 0) {
1066             Py_RETURN_RICHCOMPARE(cmp, 0, op);
1067         }
1068 
1069         Py_RETURN_RICHCOMPARE(self_size, other_size, op);
1070     }
1071 
1072 }
1073 
1074 static void
bytearray_dealloc(PyByteArrayObject * self)1075 bytearray_dealloc(PyByteArrayObject *self)
1076 {
1077     if (self->ob_exports > 0) {
1078         PyErr_SetString(PyExc_SystemError,
1079                         "deallocated bytearray object has exported buffers");
1080         PyErr_Print();
1081     }
1082     if (self->ob_bytes != 0) {
1083         PyObject_Free(self->ob_bytes);
1084     }
1085     Py_TYPE(self)->tp_free((PyObject *)self);
1086 }
1087 
1088 
1089 /* -------------------------------------------------------------------- */
1090 /* Methods */
1091 
1092 #define FASTSEARCH fastsearch
1093 #define STRINGLIB(F) stringlib_##F
1094 #define STRINGLIB_CHAR char
1095 #define STRINGLIB_SIZEOF_CHAR 1
1096 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1097 #define STRINGLIB_STR PyByteArray_AS_STRING
1098 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1099 #define STRINGLIB_ISSPACE Py_ISSPACE
1100 #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 *
bytearray_find(PyByteArrayObject * self,PyObject * args)1115 bytearray_find(PyByteArrayObject *self, PyObject *args)
1116 {
1117     return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1118 }
1119 
1120 static PyObject *
bytearray_count(PyByteArrayObject * self,PyObject * args)1121 bytearray_count(PyByteArrayObject *self, PyObject *args)
1122 {
1123     return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1124 }
1125 
1126 /*[clinic input]
1127 bytearray.clear
1128 
1129 Remove all items from the bytearray.
1130 [clinic start generated code]*/
1131 
1132 static PyObject *
bytearray_clear_impl(PyByteArrayObject * self)1133 bytearray_clear_impl(PyByteArrayObject *self)
1134 /*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
1135 {
1136     if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1137         return NULL;
1138     Py_RETURN_NONE;
1139 }
1140 
1141 /*[clinic input]
1142 bytearray.copy
1143 
1144 Return a copy of B.
1145 [clinic start generated code]*/
1146 
1147 static PyObject *
bytearray_copy_impl(PyByteArrayObject * self)1148 bytearray_copy_impl(PyByteArrayObject *self)
1149 /*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/
1150 {
1151     return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1152                                          PyByteArray_GET_SIZE(self));
1153 }
1154 
1155 static PyObject *
bytearray_index(PyByteArrayObject * self,PyObject * args)1156 bytearray_index(PyByteArrayObject *self, PyObject *args)
1157 {
1158     return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1159 }
1160 
1161 static PyObject *
bytearray_rfind(PyByteArrayObject * self,PyObject * args)1162 bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1163 {
1164     return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1165 }
1166 
1167 static PyObject *
bytearray_rindex(PyByteArrayObject * self,PyObject * args)1168 bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1169 {
1170     return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1171 }
1172 
1173 static int
bytearray_contains(PyObject * self,PyObject * arg)1174 bytearray_contains(PyObject *self, PyObject *arg)
1175 {
1176     return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg);
1177 }
1178 
1179 static PyObject *
bytearray_startswith(PyByteArrayObject * self,PyObject * args)1180 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1181 {
1182     return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1183 }
1184 
1185 static PyObject *
bytearray_endswith(PyByteArrayObject * self,PyObject * args)1186 bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1187 {
1188     return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1189 }
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 *
bytearray_translate_impl(PyByteArrayObject * self,PyObject * table,PyObject * deletechars)1207 bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1208                          PyObject *deletechars)
1209 /*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/
1210 {
1211     char *input, *output;
1212     const char *table_chars;
1213     Py_ssize_t i, c;
1214     PyObject *input_obj = (PyObject*)self;
1215     const char *output_start;
1216     Py_ssize_t inlen;
1217     PyObject *result = NULL;
1218     int trans_table[256];
1219     Py_buffer vtable, vdel;
1220 
1221     if (table == Py_None) {
1222         table_chars = NULL;
1223         table = NULL;
1224     } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1225         return NULL;
1226     } else {
1227         if (vtable.len != 256) {
1228             PyErr_SetString(PyExc_ValueError,
1229                             "translation table must be 256 characters long");
1230             PyBuffer_Release(&vtable);
1231             return NULL;
1232         }
1233         table_chars = (const char*)vtable.buf;
1234     }
1235 
1236     if (deletechars != NULL) {
1237         if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1238             if (table != NULL)
1239                 PyBuffer_Release(&vtable);
1240             return NULL;
1241         }
1242     }
1243     else {
1244         vdel.buf = NULL;
1245         vdel.len = 0;
1246     }
1247 
1248     inlen = PyByteArray_GET_SIZE(input_obj);
1249     result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1250     if (result == NULL)
1251         goto done;
1252     output_start = output = PyByteArray_AS_STRING(result);
1253     input = PyByteArray_AS_STRING(input_obj);
1254 
1255     if (vdel.len == 0 && table_chars != NULL) {
1256         /* If no deletions are required, use faster code */
1257         for (i = inlen; --i >= 0; ) {
1258             c = Py_CHARMASK(*input++);
1259             *output++ = table_chars[c];
1260         }
1261         goto done;
1262     }
1263 
1264     if (table_chars == NULL) {
1265         for (i = 0; i < 256; i++)
1266             trans_table[i] = Py_CHARMASK(i);
1267     } else {
1268         for (i = 0; i < 256; i++)
1269             trans_table[i] = Py_CHARMASK(table_chars[i]);
1270     }
1271 
1272     for (i = 0; i < vdel.len; i++)
1273         trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1274 
1275     for (i = inlen; --i >= 0; ) {
1276         c = Py_CHARMASK(*input++);
1277         if (trans_table[c] != -1)
1278             *output++ = (char)trans_table[c];
1279     }
1280     /* Fix the size of the resulting string */
1281     if (inlen > 0)
1282         if (PyByteArray_Resize(result, output - output_start) < 0) {
1283             Py_CLEAR(result);
1284             goto done;
1285         }
1286 
1287 done:
1288     if (table != NULL)
1289         PyBuffer_Release(&vtable);
1290     if (deletechars != NULL)
1291         PyBuffer_Release(&vdel);
1292     return result;
1293 }
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 *
bytearray_maketrans_impl(Py_buffer * frm,Py_buffer * to)1314 bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1315 /*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
1316 {
1317     return _Py_bytes_maketrans(frm, to);
1318 }
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 *
bytearray_replace_impl(PyByteArrayObject * self,Py_buffer * old,Py_buffer * new,Py_ssize_t count)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 {
1342     return stringlib_replace((PyObject *)self,
1343                              (const char *)old->buf, old->len,
1344                              (const char *)new->buf, new->len, count);
1345 }
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 *
bytearray_split_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1362 bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1363                      Py_ssize_t maxsplit)
1364 /*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
1365 {
1366     Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1367     const char *s = PyByteArray_AS_STRING(self), *sub;
1368     PyObject *list;
1369     Py_buffer vsub;
1370 
1371     if (maxsplit < 0)
1372         maxsplit = PY_SSIZE_T_MAX;
1373 
1374     if (sep == Py_None)
1375         return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
1376 
1377     if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1378         return NULL;
1379     sub = vsub.buf;
1380     n = vsub.len;
1381 
1382     list = stringlib_split(
1383         (PyObject*) self, s, len, sub, n, maxsplit
1384         );
1385     PyBuffer_Release(&vsub);
1386     return list;
1387 }
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 *
bytearray_partition(PyByteArrayObject * self,PyObject * sep)1406 bytearray_partition(PyByteArrayObject *self, PyObject *sep)
1407 /*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
1408 {
1409     PyObject *bytesep, *result;
1410 
1411     bytesep = _PyByteArray_FromBufferObject(sep);
1412     if (! bytesep)
1413         return NULL;
1414 
1415     result = stringlib_partition(
1416             (PyObject*) self,
1417             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1418             bytesep,
1419             PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1420             );
1421 
1422     Py_DECREF(bytesep);
1423     return result;
1424 }
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 *
bytearray_rpartition(PyByteArrayObject * self,PyObject * sep)1444 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
1445 /*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
1446 {
1447     PyObject *bytesep, *result;
1448 
1449     bytesep = _PyByteArray_FromBufferObject(sep);
1450     if (! bytesep)
1451         return NULL;
1452 
1453     result = stringlib_rpartition(
1454             (PyObject*) self,
1455             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1456             bytesep,
1457             PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1458             );
1459 
1460     Py_DECREF(bytesep);
1461     return result;
1462 }
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 *
bytearray_rsplit_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1473 bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
1474                       Py_ssize_t maxsplit)
1475 /*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
1476 {
1477     Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1478     const char *s = PyByteArray_AS_STRING(self), *sub;
1479     PyObject *list;
1480     Py_buffer vsub;
1481 
1482     if (maxsplit < 0)
1483         maxsplit = PY_SSIZE_T_MAX;
1484 
1485     if (sep == Py_None)
1486         return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
1487 
1488     if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1489         return NULL;
1490     sub = vsub.buf;
1491     n = vsub.len;
1492 
1493     list = stringlib_rsplit(
1494         (PyObject*) self, s, len, sub, n, maxsplit
1495         );
1496     PyBuffer_Release(&vsub);
1497     return list;
1498 }
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 *
bytearray_reverse_impl(PyByteArrayObject * self)1507 bytearray_reverse_impl(PyByteArrayObject *self)
1508 /*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/
1509 {
1510     char swap, *head, *tail;
1511     Py_ssize_t i, j, n = Py_SIZE(self);
1512 
1513     j = n / 2;
1514     head = PyByteArray_AS_STRING(self);
1515     tail = head + n - 1;
1516     for (i = 0; i < j; i++) {
1517         swap = *head;
1518         *head++ = *tail;
1519         *tail-- = swap;
1520     }
1521 
1522     Py_RETURN_NONE;
1523 }
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 *
bytearray_insert_impl(PyByteArrayObject * self,Py_ssize_t index,int item)1547 bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
1548 /*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/
1549 {
1550     Py_ssize_t n = Py_SIZE(self);
1551     char *buf;
1552 
1553     if (n == PY_SSIZE_T_MAX) {
1554         PyErr_SetString(PyExc_OverflowError,
1555                         "cannot add more objects to bytearray");
1556         return NULL;
1557     }
1558     if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1559         return NULL;
1560     buf = PyByteArray_AS_STRING(self);
1561 
1562     if (index < 0) {
1563         index += n;
1564         if (index < 0)
1565             index = 0;
1566     }
1567     if (index > n)
1568         index = n;
1569     memmove(buf + index + 1, buf + index, n - index);
1570     buf[index] = item;
1571 
1572     Py_RETURN_NONE;
1573 }
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 *
bytearray_append_impl(PyByteArrayObject * self,int item)1586 bytearray_append_impl(PyByteArrayObject *self, int item)
1587 /*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/
1588 {
1589     Py_ssize_t n = Py_SIZE(self);
1590 
1591     if (n == PY_SSIZE_T_MAX) {
1592         PyErr_SetString(PyExc_OverflowError,
1593                         "cannot add more objects to bytearray");
1594         return NULL;
1595     }
1596     if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1597         return NULL;
1598 
1599     PyByteArray_AS_STRING(self)[n] = item;
1600 
1601     Py_RETURN_NONE;
1602 }
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 *
bytearray_extend(PyByteArrayObject * self,PyObject * iterable_of_ints)1615 bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
1616 /*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/
1617 {
1618     PyObject *it, *item, *bytearray_obj;
1619     Py_ssize_t buf_size = 0, len = 0;
1620     int value;
1621     char *buf;
1622 
1623     /* bytearray_setslice code only accepts something supporting PEP 3118. */
1624     if (PyObject_CheckBuffer(iterable_of_ints)) {
1625         if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
1626             return NULL;
1627 
1628         Py_RETURN_NONE;
1629     }
1630 
1631     it = PyObject_GetIter(iterable_of_ints);
1632     if (it == NULL) {
1633         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1634             PyErr_Format(PyExc_TypeError,
1635                          "can't extend bytearray with %.100s",
1636                          iterable_of_ints->ob_type->tp_name);
1637         }
1638         return NULL;
1639     }
1640 
1641     /* Try to determine the length of the argument. 32 is arbitrary. */
1642     buf_size = PyObject_LengthHint(iterable_of_ints, 32);
1643     if (buf_size == -1) {
1644         Py_DECREF(it);
1645         return NULL;
1646     }
1647 
1648     bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
1649     if (bytearray_obj == NULL) {
1650         Py_DECREF(it);
1651         return NULL;
1652     }
1653     buf = PyByteArray_AS_STRING(bytearray_obj);
1654 
1655     while ((item = PyIter_Next(it)) != NULL) {
1656         if (! _getbytevalue(item, &value)) {
1657             Py_DECREF(item);
1658             Py_DECREF(it);
1659             Py_DECREF(bytearray_obj);
1660             return NULL;
1661         }
1662         buf[len++] = value;
1663         Py_DECREF(item);
1664 
1665         if (len >= buf_size) {
1666             Py_ssize_t addition;
1667             if (len == PY_SSIZE_T_MAX) {
1668                 Py_DECREF(it);
1669                 Py_DECREF(bytearray_obj);
1670                 return PyErr_NoMemory();
1671             }
1672             addition = len >> 1;
1673             if (addition > PY_SSIZE_T_MAX - len - 1)
1674                 buf_size = PY_SSIZE_T_MAX;
1675             else
1676                 buf_size = len + addition + 1;
1677             if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
1678                 Py_DECREF(it);
1679                 Py_DECREF(bytearray_obj);
1680                 return NULL;
1681             }
1682             /* Recompute the `buf' pointer, since the resizing operation may
1683                have invalidated it. */
1684             buf = PyByteArray_AS_STRING(bytearray_obj);
1685         }
1686     }
1687     Py_DECREF(it);
1688 
1689     /* Resize down to exact size. */
1690     if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
1691         Py_DECREF(bytearray_obj);
1692         return NULL;
1693     }
1694 
1695     if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
1696         Py_DECREF(bytearray_obj);
1697         return NULL;
1698     }
1699     Py_DECREF(bytearray_obj);
1700 
1701     if (PyErr_Occurred()) {
1702         return NULL;
1703     }
1704 
1705     Py_RETURN_NONE;
1706 }
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 *
bytearray_pop_impl(PyByteArrayObject * self,Py_ssize_t index)1722 bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
1723 /*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/
1724 {
1725     int value;
1726     Py_ssize_t n = Py_SIZE(self);
1727     char *buf;
1728 
1729     if (n == 0) {
1730         PyErr_SetString(PyExc_IndexError,
1731                         "pop from empty bytearray");
1732         return NULL;
1733     }
1734     if (index < 0)
1735         index += Py_SIZE(self);
1736     if (index < 0 || index >= Py_SIZE(self)) {
1737         PyErr_SetString(PyExc_IndexError, "pop index out of range");
1738         return NULL;
1739     }
1740     if (!_canresize(self))
1741         return NULL;
1742 
1743     buf = PyByteArray_AS_STRING(self);
1744     value = buf[index];
1745     memmove(buf + index, buf + index + 1, n - index);
1746     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1747         return NULL;
1748 
1749     return PyLong_FromLong((unsigned char)value);
1750 }
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 *
bytearray_remove_impl(PyByteArrayObject * self,int value)1763 bytearray_remove_impl(PyByteArrayObject *self, int value)
1764 /*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/
1765 {
1766     Py_ssize_t where, n = Py_SIZE(self);
1767     char *buf = PyByteArray_AS_STRING(self);
1768 
1769     where = stringlib_find_char(buf, n, value);
1770     if (where < 0) {
1771         PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
1772         return NULL;
1773     }
1774     if (!_canresize(self))
1775         return NULL;
1776 
1777     memmove(buf + where, buf + where + 1, n - where);
1778     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1779         return NULL;
1780 
1781     Py_RETURN_NONE;
1782 }
1783 
1784 /* XXX These two helpers could be optimized if argsize == 1 */
1785 
1786 static Py_ssize_t
lstrip_helper(const char * myptr,Py_ssize_t mysize,const void * argptr,Py_ssize_t argsize)1787 lstrip_helper(const char *myptr, Py_ssize_t mysize,
1788               const void *argptr, Py_ssize_t argsize)
1789 {
1790     Py_ssize_t i = 0;
1791     while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
1792         i++;
1793     return i;
1794 }
1795 
1796 static Py_ssize_t
rstrip_helper(const char * myptr,Py_ssize_t mysize,const void * argptr,Py_ssize_t argsize)1797 rstrip_helper(const char *myptr, Py_ssize_t mysize,
1798               const void *argptr, Py_ssize_t argsize)
1799 {
1800     Py_ssize_t i = mysize - 1;
1801     while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
1802         i--;
1803     return i + 1;
1804 }
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 *
bytearray_strip_impl(PyByteArrayObject * self,PyObject * bytes)1818 bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
1819 /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
1820 {
1821     Py_ssize_t left, right, mysize, byteslen;
1822     char *myptr;
1823     const char *bytesptr;
1824     Py_buffer vbytes;
1825 
1826     if (bytes == Py_None) {
1827         bytesptr = "\t\n\r\f\v ";
1828         byteslen = 6;
1829     }
1830     else {
1831         if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1832             return NULL;
1833         bytesptr = (const char *) vbytes.buf;
1834         byteslen = vbytes.len;
1835     }
1836     myptr = PyByteArray_AS_STRING(self);
1837     mysize = Py_SIZE(self);
1838     left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
1839     if (left == mysize)
1840         right = left;
1841     else
1842         right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
1843     if (bytes != Py_None)
1844         PyBuffer_Release(&vbytes);
1845     return PyByteArray_FromStringAndSize(myptr + left, right - left);
1846 }
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 *
bytearray_lstrip_impl(PyByteArrayObject * self,PyObject * bytes)1860 bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
1861 /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
1862 {
1863     Py_ssize_t left, right, mysize, byteslen;
1864     char *myptr;
1865     const char *bytesptr;
1866     Py_buffer vbytes;
1867 
1868     if (bytes == Py_None) {
1869         bytesptr = "\t\n\r\f\v ";
1870         byteslen = 6;
1871     }
1872     else {
1873         if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1874             return NULL;
1875         bytesptr = (const char *) vbytes.buf;
1876         byteslen = vbytes.len;
1877     }
1878     myptr = PyByteArray_AS_STRING(self);
1879     mysize = Py_SIZE(self);
1880     left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
1881     right = mysize;
1882     if (bytes != Py_None)
1883         PyBuffer_Release(&vbytes);
1884     return PyByteArray_FromStringAndSize(myptr + left, right - left);
1885 }
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 *
bytearray_rstrip_impl(PyByteArrayObject * self,PyObject * bytes)1899 bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
1900 /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
1901 {
1902     Py_ssize_t right, mysize, byteslen;
1903     char *myptr;
1904     const char *bytesptr;
1905     Py_buffer vbytes;
1906 
1907     if (bytes == Py_None) {
1908         bytesptr = "\t\n\r\f\v ";
1909         byteslen = 6;
1910     }
1911     else {
1912         if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1913             return NULL;
1914         bytesptr = (const char *) vbytes.buf;
1915         byteslen = vbytes.len;
1916     }
1917     myptr = PyByteArray_AS_STRING(self);
1918     mysize = Py_SIZE(self);
1919     right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
1920     if (bytes != Py_None)
1921         PyBuffer_Release(&vbytes);
1922     return PyByteArray_FromStringAndSize(myptr, right);
1923 }
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 *
bytearray_decode_impl(PyByteArrayObject * self,const char * encoding,const char * errors)1941 bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
1942                       const char *errors)
1943 /*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
1944 {
1945     if (encoding == NULL)
1946         encoding = PyUnicode_GetDefaultEncoding();
1947     return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
1948 }
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 *
bytearray_alloc(PyByteArrayObject * self,PyObject * Py_UNUSED (ignored))1956 bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
1957 {
1958     return PyLong_FromSsize_t(self->ob_alloc);
1959 }
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 *
bytearray_join(PyByteArrayObject * self,PyObject * iterable_of_bytes)1975 bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
1976 /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
1977 {
1978     return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
1979 }
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 *
bytearray_splitlines_impl(PyByteArrayObject * self,int keepends)1993 bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
1994 /*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/
1995 {
1996     return stringlib_splitlines(
1997         (PyObject*) self, PyByteArray_AS_STRING(self),
1998         PyByteArray_GET_SIZE(self), keepends
1999         );
2000 }
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 *
bytearray_fromhex_impl(PyTypeObject * type,PyObject * string)2016 bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2017 /*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/
2018 {
2019     PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2020     if (type != &PyByteArray_Type && result != NULL) {
2021         Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type,
2022                                                        result, NULL));
2023     }
2024     return result;
2025 }
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 *
bytearray_hex_impl(PyByteArrayObject * self,PyObject * sep,int bytes_per_sep)2051 bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
2052 /*[clinic end generated code: output=29c4e5ef72c565a0 input=814c15830ac8c4b5]*/
2053 {
2054     char* argbuf = PyByteArray_AS_STRING(self);
2055     Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2056     return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
2057 }
2058 
2059 static PyObject *
_common_reduce(PyByteArrayObject * self,int proto)2060 _common_reduce(PyByteArrayObject *self, int proto)
2061 {
2062     PyObject *dict;
2063     _Py_IDENTIFIER(__dict__);
2064     char *buf;
2065 
2066     if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) {
2067         return NULL;
2068     }
2069     if (dict == NULL) {
2070         dict = Py_None;
2071         Py_INCREF(dict);
2072     }
2073 
2074     buf = PyByteArray_AS_STRING(self);
2075     if (proto < 3) {
2076         /* use str based reduction for backwards compatibility with Python 2.x */
2077         PyObject *latin1;
2078         if (Py_SIZE(self))
2079             latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2080         else
2081             latin1 = PyUnicode_FromString("");
2082         return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2083     }
2084     else {
2085         /* use more efficient byte based reduction */
2086         if (Py_SIZE(self)) {
2087             return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
2088         }
2089         else {
2090             return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2091         }
2092     }
2093 }
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 *
bytearray_reduce_impl(PyByteArrayObject * self)2102 bytearray_reduce_impl(PyByteArrayObject *self)
2103 /*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/
2104 {
2105     return _common_reduce(self, 2);
2106 }
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 *
bytearray_reduce_ex_impl(PyByteArrayObject * self,int proto)2118 bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2119 /*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/
2120 {
2121     return _common_reduce(self, proto);
2122 }
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 *
bytearray_sizeof_impl(PyByteArrayObject * self)2131 bytearray_sizeof_impl(PyByteArrayObject *self)
2132 /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
2133 {
2134     Py_ssize_t res;
2135 
2136     res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
2137     return PyLong_FromSsize_t(res);
2138 }
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 *
bytearray_mod(PyObject * v,PyObject * w)2236 bytearray_mod(PyObject *v, PyObject *w)
2237 {
2238     if (!PyByteArray_Check(v))
2239         Py_RETURN_NOTIMPLEMENTED;
2240     return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
2241 }
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
bytearrayiter_dealloc(bytesiterobject * it)2318 bytearrayiter_dealloc(bytesiterobject *it)
2319 {
2320     _PyObject_GC_UNTRACK(it);
2321     Py_XDECREF(it->it_seq);
2322     PyObject_GC_Del(it);
2323 }
2324 
2325 static int
bytearrayiter_traverse(bytesiterobject * it,visitproc visit,void * arg)2326 bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2327 {
2328     Py_VISIT(it->it_seq);
2329     return 0;
2330 }
2331 
2332 static PyObject *
bytearrayiter_next(bytesiterobject * it)2333 bytearrayiter_next(bytesiterobject *it)
2334 {
2335     PyByteArrayObject *seq;
2336     PyObject *item;
2337 
2338     assert(it != NULL);
2339     seq = it->it_seq;
2340     if (seq == NULL)
2341         return NULL;
2342     assert(PyByteArray_Check(seq));
2343 
2344     if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2345         item = PyLong_FromLong(
2346             (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
2347         if (item != NULL)
2348             ++it->it_index;
2349         return item;
2350     }
2351 
2352     it->it_seq = NULL;
2353     Py_DECREF(seq);
2354     return NULL;
2355 }
2356 
2357 static PyObject *
bytearrayiter_length_hint(bytesiterobject * it,PyObject * Py_UNUSED (ignored))2358 bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2359 {
2360     Py_ssize_t len = 0;
2361     if (it->it_seq) {
2362         len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2363         if (len < 0) {
2364             len = 0;
2365         }
2366     }
2367     return PyLong_FromSsize_t(len);
2368 }
2369 
2370 PyDoc_STRVAR(length_hint_doc,
2371     "Private method returning an estimate of len(list(it)).");
2372 
2373 static PyObject *
bytearrayiter_reduce(bytesiterobject * it,PyObject * Py_UNUSED (ignored))2374 bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2375 {
2376     _Py_IDENTIFIER(iter);
2377     if (it->it_seq != NULL) {
2378         return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
2379                              it->it_seq, it->it_index);
2380     } else {
2381         return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
2382     }
2383 }
2384 
2385 static PyObject *
bytearrayiter_setstate(bytesiterobject * it,PyObject * state)2386 bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2387 {
2388     Py_ssize_t index = PyLong_AsSsize_t(state);
2389     if (index == -1 && PyErr_Occurred())
2390         return NULL;
2391     if (it->it_seq != NULL) {
2392         if (index < 0)
2393             index = 0;
2394         else if (index > PyByteArray_GET_SIZE(it->it_seq))
2395             index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
2396         it->it_index = index;
2397     }
2398     Py_RETURN_NONE;
2399 }
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 *
bytearray_iter(PyObject * seq)2447 bytearray_iter(PyObject *seq)
2448 {
2449     bytesiterobject *it;
2450 
2451     if (!PyByteArray_Check(seq)) {
2452         PyErr_BadInternalCall();
2453         return NULL;
2454     }
2455     it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2456     if (it == NULL)
2457         return NULL;
2458     it->it_index = 0;
2459     Py_INCREF(seq);
2460     it->it_seq = (PyByteArrayObject *)seq;
2461     _PyObject_GC_TRACK(it);
2462     return (PyObject *)it;
2463 }
2464