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