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