• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* PyBytes (bytearray) implementation */
2 
3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h"
5 #include "structmember.h"
6 #include "bytes_methods.h"
7 
8 char _PyByteArray_empty_string[] = "";
9 
10 void
PyByteArray_Fini(void)11 PyByteArray_Fini(void)
12 {
13 }
14 
15 int
PyByteArray_Init(void)16 PyByteArray_Init(void)
17 {
18     return 1;
19 }
20 
21 /* end nullbytes support */
22 
23 /* Helpers */
24 
25 static int
_getbytevalue(PyObject * arg,int * value)26 _getbytevalue(PyObject* arg, int *value)
27 {
28     long face_value;
29 
30     if (PyBytes_CheckExact(arg)) {
31         if (Py_SIZE(arg) != 1) {
32             PyErr_SetString(PyExc_ValueError, "string must be of size 1");
33             return 0;
34         }
35         *value = Py_CHARMASK(((PyBytesObject*)arg)->ob_sval[0]);
36         return 1;
37     }
38     else if (PyInt_Check(arg) || PyLong_Check(arg)) {
39         face_value = PyLong_AsLong(arg);
40     }
41     else {
42         PyObject *index = PyNumber_Index(arg);
43         if (index == NULL) {
44             PyErr_Format(PyExc_TypeError,
45                          "an integer or string of size 1 is required");
46             return 0;
47         }
48         face_value = PyLong_AsLong(index);
49         Py_DECREF(index);
50     }
51 
52     if (face_value < 0 || face_value >= 256) {
53         /* this includes the OverflowError in case the long is too large */
54         PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
55         return 0;
56     }
57 
58     *value = face_value;
59     return 1;
60 }
61 
62 static Py_ssize_t
bytearray_buffer_getreadbuf(PyByteArrayObject * self,Py_ssize_t index,const void ** ptr)63 bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
64 {
65     if ( index != 0 ) {
66         PyErr_SetString(PyExc_SystemError,
67                 "accessing non-existent bytes segment");
68         return -1;
69     }
70     *ptr = (void *)PyByteArray_AS_STRING(self);
71     return Py_SIZE(self);
72 }
73 
74 static Py_ssize_t
bytearray_buffer_getwritebuf(PyByteArrayObject * self,Py_ssize_t index,const void ** ptr)75 bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr)
76 {
77     if ( index != 0 ) {
78         PyErr_SetString(PyExc_SystemError,
79                 "accessing non-existent bytes segment");
80         return -1;
81     }
82     *ptr = (void *)PyByteArray_AS_STRING(self);
83     return Py_SIZE(self);
84 }
85 
86 static Py_ssize_t
bytearray_buffer_getsegcount(PyByteArrayObject * self,Py_ssize_t * lenp)87 bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp)
88 {
89     if ( lenp )
90         *lenp = Py_SIZE(self);
91     return 1;
92 }
93 
94 static Py_ssize_t
bytearray_buffer_getcharbuf(PyByteArrayObject * self,Py_ssize_t index,const char ** ptr)95 bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr)
96 {
97     if ( index != 0 ) {
98         PyErr_SetString(PyExc_SystemError,
99                 "accessing non-existent bytes segment");
100         return -1;
101     }
102     *ptr = PyByteArray_AS_STRING(self);
103     return Py_SIZE(self);
104 }
105 
106 static int
bytearray_getbuffer(PyByteArrayObject * obj,Py_buffer * view,int flags)107 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
108 {
109     int ret;
110     void *ptr;
111     if (view == NULL) {
112         obj->ob_exports++;
113         return 0;
114     }
115     ptr = (void *) PyByteArray_AS_STRING(obj);
116     ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
117     if (ret >= 0) {
118         obj->ob_exports++;
119     }
120     return ret;
121 }
122 
123 static void
bytearray_releasebuffer(PyByteArrayObject * obj,Py_buffer * view)124 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
125 {
126     obj->ob_exports--;
127 }
128 
129 static Py_ssize_t
_getbuffer(PyObject * obj,Py_buffer * view)130 _getbuffer(PyObject *obj, Py_buffer *view)
131 {
132     PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
133 
134     if (buffer == NULL || buffer->bf_getbuffer == NULL)
135     {
136         PyErr_Format(PyExc_TypeError,
137                      "Type %.100s doesn't support the buffer API",
138                      Py_TYPE(obj)->tp_name);
139         return -1;
140     }
141 
142     if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
143             return -1;
144     return view->len;
145 }
146 
147 static int
_canresize(PyByteArrayObject * self)148 _canresize(PyByteArrayObject *self)
149 {
150     if (self->ob_exports > 0) {
151         PyErr_SetString(PyExc_BufferError,
152                 "Existing exports of data: object cannot be re-sized");
153         return 0;
154     }
155     return 1;
156 }
157 
158 /* Direct API functions */
159 
160 PyObject *
PyByteArray_FromObject(PyObject * input)161 PyByteArray_FromObject(PyObject *input)
162 {
163     return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
164                                         input, NULL);
165 }
166 
167 PyObject *
PyByteArray_FromStringAndSize(const char * bytes,Py_ssize_t size)168 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
169 {
170     PyByteArrayObject *new;
171     Py_ssize_t alloc;
172 
173     if (size < 0) {
174         PyErr_SetString(PyExc_SystemError,
175             "Negative size passed to PyByteArray_FromStringAndSize");
176         return NULL;
177     }
178 
179     new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
180     if (new == NULL)
181         return NULL;
182 
183     if (size == 0) {
184         new->ob_bytes = NULL;
185         alloc = 0;
186     }
187     else {
188         alloc = size + 1;
189         new->ob_bytes = PyMem_Malloc(alloc);
190         if (new->ob_bytes == NULL) {
191             Py_DECREF(new);
192             return PyErr_NoMemory();
193         }
194         if (bytes != NULL && size > 0)
195             memcpy(new->ob_bytes, bytes, size);
196         new->ob_bytes[size] = '\0';  /* Trailing null byte */
197     }
198     Py_SIZE(new) = size;
199     new->ob_alloc = alloc;
200     new->ob_exports = 0;
201 
202     return (PyObject *)new;
203 }
204 
205 Py_ssize_t
PyByteArray_Size(PyObject * self)206 PyByteArray_Size(PyObject *self)
207 {
208     assert(self != NULL);
209     assert(PyByteArray_Check(self));
210 
211     return PyByteArray_GET_SIZE(self);
212 }
213 
214 char  *
PyByteArray_AsString(PyObject * self)215 PyByteArray_AsString(PyObject *self)
216 {
217     assert(self != NULL);
218     assert(PyByteArray_Check(self));
219 
220     return PyByteArray_AS_STRING(self);
221 }
222 
223 int
PyByteArray_Resize(PyObject * self,Py_ssize_t size)224 PyByteArray_Resize(PyObject *self, Py_ssize_t size)
225 {
226     void *sval;
227     Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
228 
229     assert(self != NULL);
230     assert(PyByteArray_Check(self));
231     assert(size >= 0);
232 
233     if (size == Py_SIZE(self)) {
234         return 0;
235     }
236     if (!_canresize((PyByteArrayObject *)self)) {
237         return -1;
238     }
239 
240     if (size < alloc / 2) {
241         /* Major downsize; resize down to exact size */
242         alloc = size + 1;
243     }
244     else if (size < alloc) {
245         /* Within allocated size; quick exit */
246         Py_SIZE(self) = size;
247         ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
248         return 0;
249     }
250     else if (size <= alloc * 1.125) {
251         /* Moderate upsize; overallocate similar to list_resize() */
252         alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
253     }
254     else {
255         /* Major upsize; resize up to exact size */
256         alloc = size + 1;
257     }
258 
259     sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
260     if (sval == NULL) {
261         PyErr_NoMemory();
262         return -1;
263     }
264 
265     ((PyByteArrayObject *)self)->ob_bytes = sval;
266     Py_SIZE(self) = size;
267     ((PyByteArrayObject *)self)->ob_alloc = alloc;
268     ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
269 
270     return 0;
271 }
272 
273 PyObject *
PyByteArray_Concat(PyObject * a,PyObject * b)274 PyByteArray_Concat(PyObject *a, PyObject *b)
275 {
276     Py_ssize_t size;
277     Py_buffer va, vb;
278     PyByteArrayObject *result = NULL;
279 
280     va.len = -1;
281     vb.len = -1;
282     if (_getbuffer(a, &va) < 0  ||
283         _getbuffer(b, &vb) < 0) {
284             PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
285                          Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
286             goto done;
287     }
288 
289     size = va.len + vb.len;
290     if (size < 0) {
291             PyErr_NoMemory();
292             goto done;
293     }
294 
295     result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
296     if (result != NULL) {
297         memcpy(result->ob_bytes, va.buf, va.len);
298         memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
299     }
300 
301   done:
302     if (va.len != -1)
303         PyBuffer_Release(&va);
304     if (vb.len != -1)
305         PyBuffer_Release(&vb);
306     return (PyObject *)result;
307 }
308 
309 /* Functions stuffed into the type object */
310 
311 static Py_ssize_t
bytearray_length(PyByteArrayObject * self)312 bytearray_length(PyByteArrayObject *self)
313 {
314     return Py_SIZE(self);
315 }
316 
317 static PyObject *
bytearray_iconcat(PyByteArrayObject * self,PyObject * other)318 bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
319 {
320     Py_ssize_t mysize;
321     Py_ssize_t size;
322     Py_buffer vo;
323 
324     if (_getbuffer(other, &vo) < 0) {
325         PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
326                      Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
327         return NULL;
328     }
329 
330     mysize = Py_SIZE(self);
331     size = mysize + vo.len;
332     if (size < 0) {
333         PyBuffer_Release(&vo);
334         return PyErr_NoMemory();
335     }
336     if (size < self->ob_alloc) {
337         Py_SIZE(self) = size;
338         self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
339     }
340     else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
341         PyBuffer_Release(&vo);
342         return NULL;
343     }
344     memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
345     PyBuffer_Release(&vo);
346     Py_INCREF(self);
347     return (PyObject *)self;
348 }
349 
350 static PyObject *
bytearray_repeat(PyByteArrayObject * self,Py_ssize_t count)351 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
352 {
353     PyByteArrayObject *result;
354     Py_ssize_t mysize;
355     Py_ssize_t size;
356 
357     if (count < 0)
358         count = 0;
359     mysize = Py_SIZE(self);
360     size = mysize * count;
361     if (count != 0 && size / count != mysize)
362         return PyErr_NoMemory();
363     result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
364     if (result != NULL && size != 0) {
365         if (mysize == 1)
366             memset(result->ob_bytes, self->ob_bytes[0], size);
367         else {
368             Py_ssize_t i;
369             for (i = 0; i < count; i++)
370                 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
371         }
372     }
373     return (PyObject *)result;
374 }
375 
376 static PyObject *
bytearray_irepeat(PyByteArrayObject * self,Py_ssize_t count)377 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
378 {
379     Py_ssize_t mysize;
380     Py_ssize_t size;
381 
382     if (count < 0)
383         count = 0;
384     mysize = Py_SIZE(self);
385     size = mysize * count;
386     if (count != 0 && size / count != mysize)
387         return PyErr_NoMemory();
388     if (size < self->ob_alloc) {
389         Py_SIZE(self) = size;
390         self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
391     }
392     else if (PyByteArray_Resize((PyObject *)self, size) < 0)
393         return NULL;
394 
395     if (mysize == 1)
396         memset(self->ob_bytes, self->ob_bytes[0], size);
397     else {
398         Py_ssize_t i;
399         for (i = 1; i < count; i++)
400             memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
401     }
402 
403     Py_INCREF(self);
404     return (PyObject *)self;
405 }
406 
407 static PyObject *
bytearray_getitem(PyByteArrayObject * self,Py_ssize_t i)408 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
409 {
410     if (i < 0)
411         i += Py_SIZE(self);
412     if (i < 0 || i >= Py_SIZE(self)) {
413         PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
414         return NULL;
415     }
416     return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
417 }
418 
419 static PyObject *
bytearray_subscript(PyByteArrayObject * self,PyObject * index)420 bytearray_subscript(PyByteArrayObject *self, PyObject *index)
421 {
422     if (PyIndex_Check(index)) {
423         Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
424 
425         if (i == -1 && PyErr_Occurred())
426             return NULL;
427 
428         if (i < 0)
429             i += PyByteArray_GET_SIZE(self);
430 
431         if (i < 0 || i >= Py_SIZE(self)) {
432             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
433             return NULL;
434         }
435         return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
436     }
437     else if (PySlice_Check(index)) {
438         Py_ssize_t start, stop, step, slicelength, cur, i;
439         if (PySlice_GetIndicesEx((PySliceObject *)index,
440                                  PyByteArray_GET_SIZE(self),
441                                  &start, &stop, &step, &slicelength) < 0) {
442             return NULL;
443         }
444 
445         if (slicelength <= 0)
446             return PyByteArray_FromStringAndSize("", 0);
447         else if (step == 1) {
448             return PyByteArray_FromStringAndSize(self->ob_bytes + start,
449                                              slicelength);
450         }
451         else {
452             char *source_buf = PyByteArray_AS_STRING(self);
453             char *result_buf = (char *)PyMem_Malloc(slicelength);
454             PyObject *result;
455 
456             if (result_buf == NULL)
457                 return PyErr_NoMemory();
458 
459             for (cur = start, i = 0; i < slicelength;
460                  cur += step, i++) {
461                      result_buf[i] = source_buf[cur];
462             }
463             result = PyByteArray_FromStringAndSize(result_buf, slicelength);
464             PyMem_Free(result_buf);
465             return result;
466         }
467     }
468     else {
469         PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
470         return NULL;
471     }
472 }
473 
474 static int
bytearray_setslice(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,PyObject * values)475 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
476                PyObject *values)
477 {
478     Py_ssize_t avail, needed;
479     void *bytes;
480     Py_buffer vbytes;
481     int res = 0;
482 
483     vbytes.len = -1;
484     if (values == (PyObject *)self) {
485         /* Make a copy and call this function recursively */
486         int err;
487         values = PyByteArray_FromObject(values);
488         if (values == NULL)
489             return -1;
490         err = bytearray_setslice(self, lo, hi, values);
491         Py_DECREF(values);
492         return err;
493     }
494     if (values == NULL) {
495         /* del b[lo:hi] */
496         bytes = NULL;
497         needed = 0;
498     }
499     else {
500             if (_getbuffer(values, &vbytes) < 0) {
501                     PyErr_Format(PyExc_TypeError,
502                                  "can't set bytearray slice from %.100s",
503                                  Py_TYPE(values)->tp_name);
504                     return -1;
505             }
506             needed = vbytes.len;
507             bytes = vbytes.buf;
508     }
509 
510     if (lo < 0)
511         lo = 0;
512     if (hi < lo)
513         hi = lo;
514     if (hi > Py_SIZE(self))
515         hi = Py_SIZE(self);
516 
517     avail = hi - lo;
518     if (avail < 0)
519         lo = hi = avail = 0;
520 
521     if (avail != needed) {
522         if (avail > needed) {
523             if (!_canresize(self)) {
524                 res = -1;
525                 goto finish;
526             }
527             /*
528               0   lo               hi               old_size
529               |   |<----avail----->|<-----tomove------>|
530               |   |<-needed->|<-----tomove------>|
531               0   lo      new_hi              new_size
532             */
533             memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
534                     Py_SIZE(self) - hi);
535         }
536         /* XXX(nnorwitz): need to verify this can't overflow! */
537         if (PyByteArray_Resize((PyObject *)self,
538                            Py_SIZE(self) + needed - avail) < 0) {
539                 res = -1;
540                 goto finish;
541         }
542         if (avail < needed) {
543             /*
544               0   lo        hi               old_size
545               |   |<-avail->|<-----tomove------>|
546               |   |<----needed---->|<-----tomove------>|
547               0   lo            new_hi              new_size
548              */
549             memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
550                     Py_SIZE(self) - lo - needed);
551         }
552     }
553 
554     if (needed > 0)
555         memcpy(self->ob_bytes + lo, bytes, needed);
556 
557 
558  finish:
559     if (vbytes.len != -1)
560             PyBuffer_Release(&vbytes);
561     return res;
562 }
563 
564 static int
bytearray_setitem(PyByteArrayObject * self,Py_ssize_t i,PyObject * value)565 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
566 {
567     int ival;
568 
569     if (i < 0)
570         i += Py_SIZE(self);
571 
572     if (i < 0 || i >= Py_SIZE(self)) {
573         PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
574         return -1;
575     }
576 
577     if (value == NULL)
578         return bytearray_setslice(self, i, i+1, NULL);
579 
580     if (!_getbytevalue(value, &ival))
581         return -1;
582 
583     self->ob_bytes[i] = ival;
584     return 0;
585 }
586 
587 static int
bytearray_ass_subscript(PyByteArrayObject * self,PyObject * index,PyObject * values)588 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
589 {
590     Py_ssize_t start, stop, step, slicelen, needed;
591     char *bytes;
592 
593     if (PyIndex_Check(index)) {
594         Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
595 
596         if (i == -1 && PyErr_Occurred())
597             return -1;
598 
599         if (i < 0)
600             i += PyByteArray_GET_SIZE(self);
601 
602         if (i < 0 || i >= Py_SIZE(self)) {
603             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
604             return -1;
605         }
606 
607         if (values == NULL) {
608             /* Fall through to slice assignment */
609             start = i;
610             stop = i + 1;
611             step = 1;
612             slicelen = 1;
613         }
614         else {
615             int ival;
616             if (!_getbytevalue(values, &ival))
617                 return -1;
618             self->ob_bytes[i] = (char)ival;
619             return 0;
620         }
621     }
622     else if (PySlice_Check(index)) {
623         if (PySlice_GetIndicesEx((PySliceObject *)index,
624                                  PyByteArray_GET_SIZE(self),
625                                  &start, &stop, &step, &slicelen) < 0) {
626             return -1;
627         }
628     }
629     else {
630         PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
631         return -1;
632     }
633 
634     if (values == NULL) {
635         bytes = NULL;
636         needed = 0;
637     }
638     else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
639         int err;
640         if (PyNumber_Check(values) || PyUnicode_Check(values)) {
641             PyErr_SetString(PyExc_TypeError,
642                             "can assign only bytes, buffers, or iterables "
643                             "of ints in range(0, 256)");
644             return -1;
645         }
646         /* Make a copy and call this function recursively */
647         values = PyByteArray_FromObject(values);
648         if (values == NULL)
649             return -1;
650         err = bytearray_ass_subscript(self, index, values);
651         Py_DECREF(values);
652         return err;
653     }
654     else {
655         assert(PyByteArray_Check(values));
656         bytes = ((PyByteArrayObject *)values)->ob_bytes;
657         needed = Py_SIZE(values);
658     }
659     /* Make sure b[5:2] = ... inserts before 5, not before 2. */
660     if ((step < 0 && start < stop) ||
661         (step > 0 && start > stop))
662         stop = start;
663     if (step == 1) {
664         if (slicelen != needed) {
665             if (!_canresize(self))
666                 return -1;
667             if (slicelen > needed) {
668                 /*
669                   0   start           stop              old_size
670                   |   |<---slicelen--->|<-----tomove------>|
671                   |   |<-needed->|<-----tomove------>|
672                   0   lo      new_hi              new_size
673                 */
674                 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
675                         Py_SIZE(self) - stop);
676             }
677             if (PyByteArray_Resize((PyObject *)self,
678                                Py_SIZE(self) + needed - slicelen) < 0)
679                 return -1;
680             if (slicelen < needed) {
681                 /*
682                   0   lo        hi               old_size
683                   |   |<-avail->|<-----tomove------>|
684                   |   |<----needed---->|<-----tomove------>|
685                   0   lo            new_hi              new_size
686                  */
687                 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
688                         Py_SIZE(self) - start - needed);
689             }
690         }
691 
692         if (needed > 0)
693             memcpy(self->ob_bytes + start, bytes, needed);
694 
695         return 0;
696     }
697     else {
698         if (needed == 0) {
699             /* Delete slice */
700             size_t cur;
701             Py_ssize_t i;
702 
703             if (!_canresize(self))
704                 return -1;
705             if (step < 0) {
706                 stop = start + 1;
707                 start = stop + step * (slicelen - 1) - 1;
708                 step = -step;
709             }
710             for (cur = start, i = 0;
711                  i < slicelen; cur += step, i++) {
712                 Py_ssize_t lim = step - 1;
713 
714                 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
715                     lim = PyByteArray_GET_SIZE(self) - cur - 1;
716 
717                 memmove(self->ob_bytes + cur - i,
718                         self->ob_bytes + cur + 1, lim);
719             }
720             /* Move the tail of the bytes, in one chunk */
721             cur = start + slicelen*step;
722             if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
723                 memmove(self->ob_bytes + cur - slicelen,
724                         self->ob_bytes + cur,
725                         PyByteArray_GET_SIZE(self) - cur);
726             }
727             if (PyByteArray_Resize((PyObject *)self,
728                                PyByteArray_GET_SIZE(self) - slicelen) < 0)
729                 return -1;
730 
731             return 0;
732         }
733         else {
734             /* Assign slice */
735             Py_ssize_t cur, i;
736 
737             if (needed != slicelen) {
738                 PyErr_Format(PyExc_ValueError,
739                              "attempt to assign bytes of size %zd "
740                              "to extended slice of size %zd",
741                              needed, slicelen);
742                 return -1;
743             }
744             for (cur = start, i = 0; i < slicelen; cur += step, i++)
745                 self->ob_bytes[cur] = bytes[i];
746             return 0;
747         }
748     }
749 }
750 
751 static int
bytearray_init(PyByteArrayObject * self,PyObject * args,PyObject * kwds)752 bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
753 {
754     static char *kwlist[] = {"source", "encoding", "errors", 0};
755     PyObject *arg = NULL;
756     const char *encoding = NULL;
757     const char *errors = NULL;
758     Py_ssize_t count;
759     PyObject *it;
760     PyObject *(*iternext)(PyObject *);
761 
762     if (Py_SIZE(self) != 0) {
763         /* Empty previous contents (yes, do this first of all!) */
764         if (PyByteArray_Resize((PyObject *)self, 0) < 0)
765             return -1;
766     }
767 
768     /* Parse arguments */
769     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
770                                      &arg, &encoding, &errors))
771         return -1;
772 
773     /* Make a quick exit if no first argument */
774     if (arg == NULL) {
775         if (encoding != NULL || errors != NULL) {
776             PyErr_SetString(PyExc_TypeError,
777                             "encoding or errors without sequence argument");
778             return -1;
779         }
780         return 0;
781     }
782 
783     if (PyBytes_Check(arg)) {
784         PyObject *new, *encoded;
785         if (encoding != NULL) {
786             encoded = PyCodec_Encode(arg, encoding, errors);
787             if (encoded == NULL)
788                 return -1;
789             assert(PyBytes_Check(encoded));
790         }
791         else {
792             encoded = arg;
793             Py_INCREF(arg);
794         }
795         new = bytearray_iconcat(self, arg);
796         Py_DECREF(encoded);
797         if (new == NULL)
798             return -1;
799         Py_DECREF(new);
800         return 0;
801     }
802 
803 #ifdef Py_USING_UNICODE
804     if (PyUnicode_Check(arg)) {
805         /* Encode via the codec registry */
806         PyObject *encoded, *new;
807         if (encoding == NULL) {
808             PyErr_SetString(PyExc_TypeError,
809                             "unicode argument without an encoding");
810             return -1;
811         }
812         encoded = PyCodec_Encode(arg, encoding, errors);
813         if (encoded == NULL)
814             return -1;
815         assert(PyBytes_Check(encoded));
816         new = bytearray_iconcat(self, encoded);
817         Py_DECREF(encoded);
818         if (new == NULL)
819             return -1;
820         Py_DECREF(new);
821         return 0;
822     }
823 #endif
824 
825     /* If it's not unicode, there can't be encoding or errors */
826     if (encoding != NULL || errors != NULL) {
827         PyErr_SetString(PyExc_TypeError,
828                         "encoding or errors without a string argument");
829         return -1;
830     }
831 
832     /* Is it an int? */
833     count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
834     if (count == -1 && PyErr_Occurred()) {
835         if (PyErr_ExceptionMatches(PyExc_OverflowError))
836             return -1;
837         PyErr_Clear();
838     }
839     else if (count < 0) {
840         PyErr_SetString(PyExc_ValueError, "negative count");
841         return -1;
842     }
843     else {
844         if (count > 0) {
845             if (PyByteArray_Resize((PyObject *)self, count))
846                 return -1;
847             memset(self->ob_bytes, 0, count);
848         }
849         return 0;
850     }
851 
852     /* Use the buffer API */
853     if (PyObject_CheckBuffer(arg)) {
854         Py_ssize_t size;
855         Py_buffer view;
856         if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
857             return -1;
858         size = view.len;
859         if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
860         if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
861                 goto fail;
862         PyBuffer_Release(&view);
863         return 0;
864     fail:
865         PyBuffer_Release(&view);
866         return -1;
867     }
868 
869     /* XXX Optimize this if the arguments is a list, tuple */
870 
871     /* Get the iterator */
872     it = PyObject_GetIter(arg);
873     if (it == NULL)
874         return -1;
875     iternext = *Py_TYPE(it)->tp_iternext;
876 
877     /* Run the iterator to exhaustion */
878     for (;;) {
879         PyObject *item;
880         int rc, value;
881 
882         /* Get the next item */
883         item = iternext(it);
884         if (item == NULL) {
885             if (PyErr_Occurred()) {
886                 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
887                     goto error;
888                 PyErr_Clear();
889             }
890             break;
891         }
892 
893         /* Interpret it as an int (__index__) */
894         rc = _getbytevalue(item, &value);
895         Py_DECREF(item);
896         if (!rc)
897             goto error;
898 
899         /* Append the byte */
900         if (Py_SIZE(self) < self->ob_alloc)
901             Py_SIZE(self)++;
902         else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
903             goto error;
904         self->ob_bytes[Py_SIZE(self)-1] = value;
905     }
906 
907     /* Clean up and return success */
908     Py_DECREF(it);
909     return 0;
910 
911  error:
912     /* Error handling when it != NULL */
913     Py_DECREF(it);
914     return -1;
915 }
916 
917 /* Mostly copied from string_repr, but without the
918    "smart quote" functionality. */
919 static PyObject *
bytearray_repr(PyByteArrayObject * self)920 bytearray_repr(PyByteArrayObject *self)
921 {
922     static const char *hexdigits = "0123456789abcdef";
923     const char *quote_prefix = "bytearray(b";
924     const char *quote_postfix = ")";
925     Py_ssize_t length = Py_SIZE(self);
926     /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
927     size_t newsize;
928     PyObject *v;
929     if (length > (PY_SSIZE_T_MAX - 14) / 4) {
930         PyErr_SetString(PyExc_OverflowError,
931             "bytearray object is too large to make repr");
932         return NULL;
933     }
934     newsize = 14 + 4 * length;
935     v = PyString_FromStringAndSize(NULL, newsize);
936     if (v == NULL) {
937         return NULL;
938     }
939     else {
940         register Py_ssize_t i;
941         register char c;
942         register char *p;
943         int quote;
944 
945         /* Figure out which quote to use; single is preferred */
946         quote = '\'';
947         {
948             char *test, *start;
949             start = PyByteArray_AS_STRING(self);
950             for (test = start; test < start+length; ++test) {
951                 if (*test == '"') {
952                     quote = '\''; /* back to single */
953                     goto decided;
954                 }
955                 else if (*test == '\'')
956                     quote = '"';
957             }
958           decided:
959             ;
960         }
961 
962         p = PyString_AS_STRING(v);
963         while (*quote_prefix)
964             *p++ = *quote_prefix++;
965         *p++ = quote;
966 
967         for (i = 0; i < length; i++) {
968             /* There's at least enough room for a hex escape
969                and a closing quote. */
970             assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
971             c = self->ob_bytes[i];
972             if (c == '\'' || c == '\\')
973                 *p++ = '\\', *p++ = c;
974             else if (c == '\t')
975                 *p++ = '\\', *p++ = 't';
976             else if (c == '\n')
977                 *p++ = '\\', *p++ = 'n';
978             else if (c == '\r')
979                 *p++ = '\\', *p++ = 'r';
980             else if (c == 0)
981                 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
982             else if (c < ' ' || c >= 0x7f) {
983                 *p++ = '\\';
984                 *p++ = 'x';
985                 *p++ = hexdigits[(c & 0xf0) >> 4];
986                 *p++ = hexdigits[c & 0xf];
987             }
988             else
989                 *p++ = c;
990         }
991         assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
992         *p++ = quote;
993         while (*quote_postfix) {
994            *p++ = *quote_postfix++;
995         }
996         *p = '\0';
997         /* v is cleared on error */
998         (void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
999         return v;
1000     }
1001 }
1002 
1003 static PyObject *
bytearray_str(PyObject * op)1004 bytearray_str(PyObject *op)
1005 {
1006 #if 0
1007     if (Py_BytesWarningFlag) {
1008         if (PyErr_WarnEx(PyExc_BytesWarning,
1009                  "str() on a bytearray instance", 1))
1010             return NULL;
1011     }
1012     return bytearray_repr((PyByteArrayObject*)op);
1013 #endif
1014     return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op));
1015 }
1016 
1017 static PyObject *
bytearray_richcompare(PyObject * self,PyObject * other,int op)1018 bytearray_richcompare(PyObject *self, PyObject *other, int op)
1019 {
1020     Py_ssize_t self_size, other_size;
1021     Py_buffer self_bytes, other_bytes;
1022     PyObject *res;
1023     Py_ssize_t minsize;
1024     int cmp;
1025 
1026     /* Bytes can be compared to anything that supports the (binary)
1027        buffer API.  Except that a comparison with Unicode is always an
1028        error, even if the comparison is for equality. */
1029 #ifdef Py_USING_UNICODE
1030     if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1031         PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
1032         if (Py_BytesWarningFlag && op == Py_EQ) {
1033             if (PyErr_WarnEx(PyExc_BytesWarning,
1034                             "Comparison between bytearray and string", 1))
1035                 return NULL;
1036         }
1037 
1038         Py_INCREF(Py_NotImplemented);
1039         return Py_NotImplemented;
1040     }
1041 #endif
1042 
1043     self_size = _getbuffer(self, &self_bytes);
1044     if (self_size < 0) {
1045         PyErr_Clear();
1046         Py_INCREF(Py_NotImplemented);
1047         return Py_NotImplemented;
1048     }
1049 
1050     other_size = _getbuffer(other, &other_bytes);
1051     if (other_size < 0) {
1052         PyErr_Clear();
1053         PyBuffer_Release(&self_bytes);
1054         Py_INCREF(Py_NotImplemented);
1055         return Py_NotImplemented;
1056     }
1057 
1058     if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1059         /* Shortcut: if the lengths differ, the objects differ */
1060         cmp = (op == Py_NE);
1061     }
1062     else {
1063         minsize = self_size;
1064         if (other_size < minsize)
1065             minsize = other_size;
1066 
1067         cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1068         /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1069 
1070         if (cmp == 0) {
1071             if (self_size < other_size)
1072                 cmp = -1;
1073             else if (self_size > other_size)
1074                 cmp = 1;
1075         }
1076 
1077         switch (op) {
1078         case Py_LT: cmp = cmp <  0; break;
1079         case Py_LE: cmp = cmp <= 0; break;
1080         case Py_EQ: cmp = cmp == 0; break;
1081         case Py_NE: cmp = cmp != 0; break;
1082         case Py_GT: cmp = cmp >  0; break;
1083         case Py_GE: cmp = cmp >= 0; break;
1084         }
1085     }
1086 
1087     res = cmp ? Py_True : Py_False;
1088     PyBuffer_Release(&self_bytes);
1089     PyBuffer_Release(&other_bytes);
1090     Py_INCREF(res);
1091     return res;
1092 }
1093 
1094 static void
bytearray_dealloc(PyByteArrayObject * self)1095 bytearray_dealloc(PyByteArrayObject *self)
1096 {
1097     if (self->ob_exports > 0) {
1098         PyErr_SetString(PyExc_SystemError,
1099                         "deallocated bytearray object has exported buffers");
1100         PyErr_Print();
1101     }
1102     if (self->ob_bytes != 0) {
1103         PyMem_Free(self->ob_bytes);
1104     }
1105     Py_TYPE(self)->tp_free((PyObject *)self);
1106 }
1107 
1108 
1109 /* -------------------------------------------------------------------- */
1110 /* Methods */
1111 
1112 #define STRINGLIB_CHAR char
1113 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1114 #define STRINGLIB_STR PyByteArray_AS_STRING
1115 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1116 #define STRINGLIB_ISSPACE Py_ISSPACE
1117 #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1118 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1119 #define STRINGLIB_MUTABLE 1
1120 
1121 #include "stringlib/fastsearch.h"
1122 #include "stringlib/count.h"
1123 #include "stringlib/find.h"
1124 #include "stringlib/partition.h"
1125 #include "stringlib/split.h"
1126 #include "stringlib/ctype.h"
1127 #include "stringlib/transmogrify.h"
1128 
1129 
1130 /* The following Py_LOCAL_INLINE and Py_LOCAL functions
1131 were copied from the old char* style string object. */
1132 
1133 /* helper macro to fixup start/end slice values */
1134 #define ADJUST_INDICES(start, end, len)         \
1135     if (end > len)                              \
1136         end = len;                              \
1137     else if (end < 0) {                         \
1138         end += len;                             \
1139         if (end < 0)                            \
1140             end = 0;                            \
1141     }                                           \
1142     if (start < 0) {                            \
1143         start += len;                           \
1144         if (start < 0)                          \
1145             start = 0;                          \
1146     }
1147 
1148 Py_LOCAL_INLINE(Py_ssize_t)
bytearray_find_internal(PyByteArrayObject * self,PyObject * args,int dir)1149 bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
1150 {
1151     PyObject *subobj;
1152     Py_buffer subbuf;
1153     Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1154     Py_ssize_t res;
1155 
1156     if (!stringlib_parse_args_finds("find/rfind/index/rindex",
1157                                     args, &subobj, &start, &end))
1158         return -2;
1159     if (_getbuffer(subobj, &subbuf) < 0)
1160         return -2;
1161     if (dir > 0)
1162         res = stringlib_find_slice(
1163             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1164             subbuf.buf, subbuf.len, start, end);
1165     else
1166         res = stringlib_rfind_slice(
1167             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1168             subbuf.buf, subbuf.len, start, end);
1169     PyBuffer_Release(&subbuf);
1170     return res;
1171 }
1172 
1173 PyDoc_STRVAR(find__doc__,
1174 "B.find(sub [,start [,end]]) -> int\n\
1175 \n\
1176 Return the lowest index in B where subsection sub is found,\n\
1177 such that sub is contained within B[start,end].  Optional\n\
1178 arguments start and end are interpreted as in slice notation.\n\
1179 \n\
1180 Return -1 on failure.");
1181 
1182 static PyObject *
bytearray_find(PyByteArrayObject * self,PyObject * args)1183 bytearray_find(PyByteArrayObject *self, PyObject *args)
1184 {
1185     Py_ssize_t result = bytearray_find_internal(self, args, +1);
1186     if (result == -2)
1187         return NULL;
1188     return PyInt_FromSsize_t(result);
1189 }
1190 
1191 PyDoc_STRVAR(count__doc__,
1192 "B.count(sub [,start [,end]]) -> int\n\
1193 \n\
1194 Return the number of non-overlapping occurrences of subsection sub in\n\
1195 bytes B[start:end].  Optional arguments start and end are interpreted\n\
1196 as in slice notation.");
1197 
1198 static PyObject *
bytearray_count(PyByteArrayObject * self,PyObject * args)1199 bytearray_count(PyByteArrayObject *self, PyObject *args)
1200 {
1201     PyObject *sub_obj;
1202     const char *str = PyByteArray_AS_STRING(self);
1203     Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1204     Py_buffer vsub;
1205     PyObject *count_obj;
1206 
1207     if (!stringlib_parse_args_finds("count", args, &sub_obj, &start, &end))
1208         return NULL;
1209 
1210     if (_getbuffer(sub_obj, &vsub) < 0)
1211         return NULL;
1212 
1213     ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
1214 
1215     count_obj = PyInt_FromSsize_t(
1216         stringlib_count(str + start, end - start, vsub.buf, vsub.len, PY_SSIZE_T_MAX)
1217         );
1218     PyBuffer_Release(&vsub);
1219     return count_obj;
1220 }
1221 
1222 
1223 PyDoc_STRVAR(index__doc__,
1224 "B.index(sub [,start [,end]]) -> int\n\
1225 \n\
1226 Like B.find() but raise ValueError when the subsection is not found.");
1227 
1228 static PyObject *
bytearray_index(PyByteArrayObject * self,PyObject * args)1229 bytearray_index(PyByteArrayObject *self, PyObject *args)
1230 {
1231     Py_ssize_t result = bytearray_find_internal(self, args, +1);
1232     if (result == -2)
1233         return NULL;
1234     if (result == -1) {
1235         PyErr_SetString(PyExc_ValueError,
1236                         "subsection not found");
1237         return NULL;
1238     }
1239     return PyInt_FromSsize_t(result);
1240 }
1241 
1242 
1243 PyDoc_STRVAR(rfind__doc__,
1244 "B.rfind(sub [,start [,end]]) -> int\n\
1245 \n\
1246 Return the highest index in B where subsection sub is found,\n\
1247 such that sub is contained within B[start,end].  Optional\n\
1248 arguments start and end are interpreted as in slice notation.\n\
1249 \n\
1250 Return -1 on failure.");
1251 
1252 static PyObject *
bytearray_rfind(PyByteArrayObject * self,PyObject * args)1253 bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1254 {
1255     Py_ssize_t result = bytearray_find_internal(self, args, -1);
1256     if (result == -2)
1257         return NULL;
1258     return PyInt_FromSsize_t(result);
1259 }
1260 
1261 
1262 PyDoc_STRVAR(rindex__doc__,
1263 "B.rindex(sub [,start [,end]]) -> int\n\
1264 \n\
1265 Like B.rfind() but raise ValueError when the subsection is not found.");
1266 
1267 static PyObject *
bytearray_rindex(PyByteArrayObject * self,PyObject * args)1268 bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1269 {
1270     Py_ssize_t result = bytearray_find_internal(self, args, -1);
1271     if (result == -2)
1272         return NULL;
1273     if (result == -1) {
1274         PyErr_SetString(PyExc_ValueError,
1275                         "subsection not found");
1276         return NULL;
1277     }
1278     return PyInt_FromSsize_t(result);
1279 }
1280 
1281 
1282 static int
bytearray_contains(PyObject * self,PyObject * arg)1283 bytearray_contains(PyObject *self, PyObject *arg)
1284 {
1285     Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1286     if (ival == -1 && PyErr_Occurred()) {
1287         Py_buffer varg;
1288         int pos;
1289         PyErr_Clear();
1290         if (_getbuffer(arg, &varg) < 0)
1291             return -1;
1292         pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1293                              varg.buf, varg.len, 0);
1294         PyBuffer_Release(&varg);
1295         return pos >= 0;
1296     }
1297     if (ival < 0 || ival >= 256) {
1298         PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1299         return -1;
1300     }
1301 
1302     return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1303 }
1304 
1305 
1306 /* Matches the end (direction >= 0) or start (direction < 0) of self
1307  * against substr, using the start and end arguments. Returns
1308  * -1 on error, 0 if not found and 1 if found.
1309  */
1310 Py_LOCAL(int)
_bytearray_tailmatch(PyByteArrayObject * self,PyObject * substr,Py_ssize_t start,Py_ssize_t end,int direction)1311 _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
1312                  Py_ssize_t end, int direction)
1313 {
1314     Py_ssize_t len = PyByteArray_GET_SIZE(self);
1315     const char* str;
1316     Py_buffer vsubstr;
1317     int rv = 0;
1318 
1319     str = PyByteArray_AS_STRING(self);
1320 
1321     if (_getbuffer(substr, &vsubstr) < 0)
1322         return -1;
1323 
1324     ADJUST_INDICES(start, end, len);
1325 
1326     if (direction < 0) {
1327         /* startswith */
1328         if (start+vsubstr.len > len) {
1329             goto done;
1330         }
1331     } else {
1332         /* endswith */
1333         if (end-start < vsubstr.len || start > len) {
1334             goto done;
1335         }
1336 
1337         if (end-vsubstr.len > start)
1338             start = end - vsubstr.len;
1339     }
1340     if (end-start >= vsubstr.len)
1341         rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1342 
1343 done:
1344     PyBuffer_Release(&vsubstr);
1345     return rv;
1346 }
1347 
1348 
1349 PyDoc_STRVAR(startswith__doc__,
1350 "B.startswith(prefix [,start [,end]]) -> bool\n\
1351 \n\
1352 Return True if B starts with the specified prefix, False otherwise.\n\
1353 With optional start, test B beginning at that position.\n\
1354 With optional end, stop comparing B at that position.\n\
1355 prefix can also be a tuple of strings to try.");
1356 
1357 static PyObject *
bytearray_startswith(PyByteArrayObject * self,PyObject * args)1358 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1359 {
1360     Py_ssize_t start = 0;
1361     Py_ssize_t end = PY_SSIZE_T_MAX;
1362     PyObject *subobj;
1363     int result;
1364 
1365     if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
1366         return NULL;
1367     if (PyTuple_Check(subobj)) {
1368         Py_ssize_t i;
1369         for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1370             result = _bytearray_tailmatch(self,
1371                                       PyTuple_GET_ITEM(subobj, i),
1372                                       start, end, -1);
1373             if (result == -1)
1374                 return NULL;
1375             else if (result) {
1376                 Py_RETURN_TRUE;
1377             }
1378         }
1379         Py_RETURN_FALSE;
1380     }
1381     result = _bytearray_tailmatch(self, subobj, start, end, -1);
1382     if (result == -1)
1383         return NULL;
1384     else
1385         return PyBool_FromLong(result);
1386 }
1387 
1388 PyDoc_STRVAR(endswith__doc__,
1389 "B.endswith(suffix [,start [,end]]) -> bool\n\
1390 \n\
1391 Return True if B ends with the specified suffix, False otherwise.\n\
1392 With optional start, test B beginning at that position.\n\
1393 With optional end, stop comparing B at that position.\n\
1394 suffix can also be a tuple of strings to try.");
1395 
1396 static PyObject *
bytearray_endswith(PyByteArrayObject * self,PyObject * args)1397 bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1398 {
1399     Py_ssize_t start = 0;
1400     Py_ssize_t end = PY_SSIZE_T_MAX;
1401     PyObject *subobj;
1402     int result;
1403 
1404     if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
1405         return NULL;
1406     if (PyTuple_Check(subobj)) {
1407         Py_ssize_t i;
1408         for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1409             result = _bytearray_tailmatch(self,
1410                                       PyTuple_GET_ITEM(subobj, i),
1411                                       start, end, +1);
1412             if (result == -1)
1413                 return NULL;
1414             else if (result) {
1415                 Py_RETURN_TRUE;
1416             }
1417         }
1418         Py_RETURN_FALSE;
1419     }
1420     result = _bytearray_tailmatch(self, subobj, start, end, +1);
1421     if (result == -1)
1422         return NULL;
1423     else
1424         return PyBool_FromLong(result);
1425 }
1426 
1427 
1428 PyDoc_STRVAR(translate__doc__,
1429 "B.translate(table[, deletechars]) -> bytearray\n\
1430 \n\
1431 Return a copy of B, where all characters occurring in the\n\
1432 optional argument deletechars are removed, and the remaining\n\
1433 characters have been mapped through the given translation\n\
1434 table, which must be a bytes object of length 256.");
1435 
1436 static PyObject *
bytearray_translate(PyByteArrayObject * self,PyObject * args)1437 bytearray_translate(PyByteArrayObject *self, PyObject *args)
1438 {
1439     register char *input, *output;
1440     register const char *table;
1441     register Py_ssize_t i, c;
1442     PyObject *input_obj = (PyObject*)self;
1443     const char *output_start;
1444     Py_ssize_t inlen;
1445     PyObject *result = NULL;
1446     int trans_table[256];
1447     PyObject *tableobj = NULL, *delobj = NULL;
1448     Py_buffer vtable, vdel;
1449 
1450     if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1451                            &tableobj, &delobj))
1452           return NULL;
1453 
1454     if (tableobj == Py_None) {
1455         table = NULL;
1456         tableobj = NULL;
1457     } else if (_getbuffer(tableobj, &vtable) < 0) {
1458         return NULL;
1459     } else {
1460         if (vtable.len != 256) {
1461             PyErr_SetString(PyExc_ValueError,
1462                             "translation table must be 256 characters long");
1463             PyBuffer_Release(&vtable);
1464             return NULL;
1465         }
1466         table = (const char*)vtable.buf;
1467     }
1468 
1469     if (delobj != NULL) {
1470         if (_getbuffer(delobj, &vdel) < 0) {
1471             if (tableobj != NULL)
1472                 PyBuffer_Release(&vtable);
1473             return NULL;
1474         }
1475     }
1476     else {
1477         vdel.buf = NULL;
1478         vdel.len = 0;
1479     }
1480 
1481     inlen = PyByteArray_GET_SIZE(input_obj);
1482     result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1483     if (result == NULL)
1484         goto done;
1485     output_start = output = PyByteArray_AsString(result);
1486     input = PyByteArray_AS_STRING(input_obj);
1487 
1488     if (vdel.len == 0 && table != NULL) {
1489         /* If no deletions are required, use faster code */
1490         for (i = inlen; --i >= 0; ) {
1491             c = Py_CHARMASK(*input++);
1492             *output++ = table[c];
1493         }
1494         goto done;
1495     }
1496 
1497     if (table == NULL) {
1498         for (i = 0; i < 256; i++)
1499             trans_table[i] = Py_CHARMASK(i);
1500     } else {
1501         for (i = 0; i < 256; i++)
1502             trans_table[i] = Py_CHARMASK(table[i]);
1503     }
1504 
1505     for (i = 0; i < vdel.len; i++)
1506         trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1507 
1508     for (i = inlen; --i >= 0; ) {
1509         c = Py_CHARMASK(*input++);
1510         if (trans_table[c] != -1)
1511             if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1512                     continue;
1513     }
1514     /* Fix the size of the resulting string */
1515     if (inlen > 0)
1516         PyByteArray_Resize(result, output - output_start);
1517 
1518 done:
1519     if (tableobj != NULL)
1520         PyBuffer_Release(&vtable);
1521     if (delobj != NULL)
1522         PyBuffer_Release(&vdel);
1523     return result;
1524 }
1525 
1526 
1527 /* find and count characters and substrings */
1528 
1529 #define findchar(target, target_len, c)                         \
1530   ((char *)memchr((const void *)(target), c, target_len))
1531 
1532 
1533 /* Bytes ops must return a string, create a copy */
1534 Py_LOCAL(PyByteArrayObject *)
return_self(PyByteArrayObject * self)1535 return_self(PyByteArrayObject *self)
1536 {
1537     return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1538             PyByteArray_AS_STRING(self),
1539             PyByteArray_GET_SIZE(self));
1540 }
1541 
1542 Py_LOCAL_INLINE(Py_ssize_t)
countchar(const char * target,Py_ssize_t target_len,char c,Py_ssize_t maxcount)1543 countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1544 {
1545     Py_ssize_t count=0;
1546     const char *start=target;
1547     const char *end=target+target_len;
1548 
1549     while ( (start=findchar(start, end-start, c)) != NULL ) {
1550         count++;
1551         if (count >= maxcount)
1552             break;
1553         start += 1;
1554     }
1555     return count;
1556 }
1557 
1558 
1559 /* Algorithms for different cases of string replacement */
1560 
1561 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1562 Py_LOCAL(PyByteArrayObject *)
replace_interleave(PyByteArrayObject * self,const char * to_s,Py_ssize_t to_len,Py_ssize_t maxcount)1563 replace_interleave(PyByteArrayObject *self,
1564                    const char *to_s, Py_ssize_t to_len,
1565                    Py_ssize_t maxcount)
1566 {
1567     char *self_s, *result_s;
1568     Py_ssize_t self_len, result_len;
1569     Py_ssize_t count, i, product;
1570     PyByteArrayObject *result;
1571 
1572     self_len = PyByteArray_GET_SIZE(self);
1573 
1574     /* 1 at the end plus 1 after every character */
1575     count = self_len+1;
1576     if (maxcount < count)
1577         count = maxcount;
1578 
1579     /* Check for overflow */
1580     /*   result_len = count * to_len + self_len; */
1581     product = count * to_len;
1582     if (product / to_len != count) {
1583         PyErr_SetString(PyExc_OverflowError,
1584                         "replace string is too long");
1585         return NULL;
1586     }
1587     result_len = product + self_len;
1588     if (result_len < 0) {
1589         PyErr_SetString(PyExc_OverflowError,
1590                         "replace string is too long");
1591         return NULL;
1592     }
1593 
1594     if (! (result = (PyByteArrayObject *)
1595                      PyByteArray_FromStringAndSize(NULL, result_len)) )
1596         return NULL;
1597 
1598     self_s = PyByteArray_AS_STRING(self);
1599     result_s = PyByteArray_AS_STRING(result);
1600 
1601     /* TODO: special case single character, which doesn't need memcpy */
1602 
1603     /* Lay the first one down (guaranteed this will occur) */
1604     Py_MEMCPY(result_s, to_s, to_len);
1605     result_s += to_len;
1606     count -= 1;
1607 
1608     for (i=0; i<count; i++) {
1609         *result_s++ = *self_s++;
1610         Py_MEMCPY(result_s, to_s, to_len);
1611         result_s += to_len;
1612     }
1613 
1614     /* Copy the rest of the original string */
1615     Py_MEMCPY(result_s, self_s, self_len-i);
1616 
1617     return result;
1618 }
1619 
1620 /* Special case for deleting a single character */
1621 /* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1622 Py_LOCAL(PyByteArrayObject *)
replace_delete_single_character(PyByteArrayObject * self,char from_c,Py_ssize_t maxcount)1623 replace_delete_single_character(PyByteArrayObject *self,
1624                                 char from_c, Py_ssize_t maxcount)
1625 {
1626     char *self_s, *result_s;
1627     char *start, *next, *end;
1628     Py_ssize_t self_len, result_len;
1629     Py_ssize_t count;
1630     PyByteArrayObject *result;
1631 
1632     self_len = PyByteArray_GET_SIZE(self);
1633     self_s = PyByteArray_AS_STRING(self);
1634 
1635     count = countchar(self_s, self_len, from_c, maxcount);
1636     if (count == 0) {
1637         return return_self(self);
1638     }
1639 
1640     result_len = self_len - count;  /* from_len == 1 */
1641     assert(result_len>=0);
1642 
1643     if ( (result = (PyByteArrayObject *)
1644                     PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1645         return NULL;
1646     result_s = PyByteArray_AS_STRING(result);
1647 
1648     start = self_s;
1649     end = self_s + self_len;
1650     while (count-- > 0) {
1651         next = findchar(start, end-start, from_c);
1652         if (next == NULL)
1653             break;
1654         Py_MEMCPY(result_s, start, next-start);
1655         result_s += (next-start);
1656         start = next+1;
1657     }
1658     Py_MEMCPY(result_s, start, end-start);
1659 
1660     return result;
1661 }
1662 
1663 /* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1664 
1665 Py_LOCAL(PyByteArrayObject *)
replace_delete_substring(PyByteArrayObject * self,const char * from_s,Py_ssize_t from_len,Py_ssize_t maxcount)1666 replace_delete_substring(PyByteArrayObject *self,
1667                          const char *from_s, Py_ssize_t from_len,
1668                          Py_ssize_t maxcount)
1669 {
1670     char *self_s, *result_s;
1671     char *start, *next, *end;
1672     Py_ssize_t self_len, result_len;
1673     Py_ssize_t count, offset;
1674     PyByteArrayObject *result;
1675 
1676     self_len = PyByteArray_GET_SIZE(self);
1677     self_s = PyByteArray_AS_STRING(self);
1678 
1679     count = stringlib_count(self_s, self_len,
1680                             from_s, from_len,
1681                             maxcount);
1682 
1683     if (count == 0) {
1684         /* no matches */
1685         return return_self(self);
1686     }
1687 
1688     result_len = self_len - (count * from_len);
1689     assert (result_len>=0);
1690 
1691     if ( (result = (PyByteArrayObject *)
1692         PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1693             return NULL;
1694 
1695     result_s = PyByteArray_AS_STRING(result);
1696 
1697     start = self_s;
1698     end = self_s + self_len;
1699     while (count-- > 0) {
1700         offset = stringlib_find(start, end-start,
1701                                 from_s, from_len,
1702                                 0);
1703         if (offset == -1)
1704             break;
1705         next = start + offset;
1706 
1707         Py_MEMCPY(result_s, start, next-start);
1708 
1709         result_s += (next-start);
1710         start = next+from_len;
1711     }
1712     Py_MEMCPY(result_s, start, end-start);
1713     return result;
1714 }
1715 
1716 /* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1717 Py_LOCAL(PyByteArrayObject *)
replace_single_character_in_place(PyByteArrayObject * self,char from_c,char to_c,Py_ssize_t maxcount)1718 replace_single_character_in_place(PyByteArrayObject *self,
1719                                   char from_c, char to_c,
1720                                   Py_ssize_t maxcount)
1721 {
1722     char *self_s, *result_s, *start, *end, *next;
1723     Py_ssize_t self_len;
1724     PyByteArrayObject *result;
1725 
1726     /* The result string will be the same size */
1727     self_s = PyByteArray_AS_STRING(self);
1728     self_len = PyByteArray_GET_SIZE(self);
1729 
1730     next = findchar(self_s, self_len, from_c);
1731 
1732     if (next == NULL) {
1733         /* No matches; return the original bytes */
1734         return return_self(self);
1735     }
1736 
1737     /* Need to make a new bytes */
1738     result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1739     if (result == NULL)
1740         return NULL;
1741     result_s = PyByteArray_AS_STRING(result);
1742     Py_MEMCPY(result_s, self_s, self_len);
1743 
1744     /* change everything in-place, starting with this one */
1745     start =  result_s + (next-self_s);
1746     *start = to_c;
1747     start++;
1748     end = result_s + self_len;
1749 
1750     while (--maxcount > 0) {
1751         next = findchar(start, end-start, from_c);
1752         if (next == NULL)
1753             break;
1754         *next = to_c;
1755         start = next+1;
1756     }
1757 
1758     return result;
1759 }
1760 
1761 /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1762 Py_LOCAL(PyByteArrayObject *)
replace_substring_in_place(PyByteArrayObject * self,const char * from_s,Py_ssize_t from_len,const char * to_s,Py_ssize_t to_len,Py_ssize_t maxcount)1763 replace_substring_in_place(PyByteArrayObject *self,
1764                            const char *from_s, Py_ssize_t from_len,
1765                            const char *to_s, Py_ssize_t to_len,
1766                            Py_ssize_t maxcount)
1767 {
1768     char *result_s, *start, *end;
1769     char *self_s;
1770     Py_ssize_t self_len, offset;
1771     PyByteArrayObject *result;
1772 
1773     /* The result bytes will be the same size */
1774 
1775     self_s = PyByteArray_AS_STRING(self);
1776     self_len = PyByteArray_GET_SIZE(self);
1777 
1778     offset = stringlib_find(self_s, self_len,
1779                             from_s, from_len,
1780                             0);
1781     if (offset == -1) {
1782         /* No matches; return the original bytes */
1783         return return_self(self);
1784     }
1785 
1786     /* Need to make a new bytes */
1787     result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1788     if (result == NULL)
1789         return NULL;
1790     result_s = PyByteArray_AS_STRING(result);
1791     Py_MEMCPY(result_s, self_s, self_len);
1792 
1793     /* change everything in-place, starting with this one */
1794     start =  result_s + offset;
1795     Py_MEMCPY(start, to_s, from_len);
1796     start += from_len;
1797     end = result_s + self_len;
1798 
1799     while ( --maxcount > 0) {
1800         offset = stringlib_find(start, end-start,
1801                                 from_s, from_len,
1802                                 0);
1803         if (offset==-1)
1804             break;
1805         Py_MEMCPY(start+offset, to_s, from_len);
1806         start += offset+from_len;
1807     }
1808 
1809     return result;
1810 }
1811 
1812 /* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1813 Py_LOCAL(PyByteArrayObject *)
replace_single_character(PyByteArrayObject * self,char from_c,const char * to_s,Py_ssize_t to_len,Py_ssize_t maxcount)1814 replace_single_character(PyByteArrayObject *self,
1815                          char from_c,
1816                          const char *to_s, Py_ssize_t to_len,
1817                          Py_ssize_t maxcount)
1818 {
1819     char *self_s, *result_s;
1820     char *start, *next, *end;
1821     Py_ssize_t self_len, result_len;
1822     Py_ssize_t count, product;
1823     PyByteArrayObject *result;
1824 
1825     self_s = PyByteArray_AS_STRING(self);
1826     self_len = PyByteArray_GET_SIZE(self);
1827 
1828     count = countchar(self_s, self_len, from_c, maxcount);
1829     if (count == 0) {
1830         /* no matches, return unchanged */
1831         return return_self(self);
1832     }
1833 
1834     /* use the difference between current and new, hence the "-1" */
1835     /*   result_len = self_len + count * (to_len-1)  */
1836     product = count * (to_len-1);
1837     if (product / (to_len-1) != count) {
1838         PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1839         return NULL;
1840     }
1841     result_len = self_len + product;
1842     if (result_len < 0) {
1843             PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1844             return NULL;
1845     }
1846 
1847     if ( (result = (PyByteArrayObject *)
1848           PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1849             return NULL;
1850     result_s = PyByteArray_AS_STRING(result);
1851 
1852     start = self_s;
1853     end = self_s + self_len;
1854     while (count-- > 0) {
1855         next = findchar(start, end-start, from_c);
1856         if (next == NULL)
1857             break;
1858 
1859         if (next == start) {
1860             /* replace with the 'to' */
1861             Py_MEMCPY(result_s, to_s, to_len);
1862             result_s += to_len;
1863             start += 1;
1864         } else {
1865             /* copy the unchanged old then the 'to' */
1866             Py_MEMCPY(result_s, start, next-start);
1867             result_s += (next-start);
1868             Py_MEMCPY(result_s, to_s, to_len);
1869             result_s += to_len;
1870             start = next+1;
1871         }
1872     }
1873     /* Copy the remainder of the remaining bytes */
1874     Py_MEMCPY(result_s, start, end-start);
1875 
1876     return result;
1877 }
1878 
1879 /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1880 Py_LOCAL(PyByteArrayObject *)
replace_substring(PyByteArrayObject * self,const char * from_s,Py_ssize_t from_len,const char * to_s,Py_ssize_t to_len,Py_ssize_t maxcount)1881 replace_substring(PyByteArrayObject *self,
1882                   const char *from_s, Py_ssize_t from_len,
1883                   const char *to_s, Py_ssize_t to_len,
1884                   Py_ssize_t maxcount)
1885 {
1886     char *self_s, *result_s;
1887     char *start, *next, *end;
1888     Py_ssize_t self_len, result_len;
1889     Py_ssize_t count, offset, product;
1890     PyByteArrayObject *result;
1891 
1892     self_s = PyByteArray_AS_STRING(self);
1893     self_len = PyByteArray_GET_SIZE(self);
1894 
1895     count = stringlib_count(self_s, self_len,
1896                             from_s, from_len,
1897                             maxcount);
1898 
1899     if (count == 0) {
1900         /* no matches, return unchanged */
1901         return return_self(self);
1902     }
1903 
1904     /* Check for overflow */
1905     /*    result_len = self_len + count * (to_len-from_len) */
1906     product = count * (to_len-from_len);
1907     if (product / (to_len-from_len) != count) {
1908         PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1909         return NULL;
1910     }
1911     result_len = self_len + product;
1912     if (result_len < 0) {
1913         PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1914         return NULL;
1915     }
1916 
1917     if ( (result = (PyByteArrayObject *)
1918           PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1919         return NULL;
1920     result_s = PyByteArray_AS_STRING(result);
1921 
1922     start = self_s;
1923     end = self_s + self_len;
1924     while (count-- > 0) {
1925         offset = stringlib_find(start, end-start,
1926                                 from_s, from_len,
1927                                 0);
1928         if (offset == -1)
1929             break;
1930         next = start+offset;
1931         if (next == start) {
1932             /* replace with the 'to' */
1933             Py_MEMCPY(result_s, to_s, to_len);
1934             result_s += to_len;
1935             start += from_len;
1936         } else {
1937             /* copy the unchanged old then the 'to' */
1938             Py_MEMCPY(result_s, start, next-start);
1939             result_s += (next-start);
1940             Py_MEMCPY(result_s, to_s, to_len);
1941             result_s += to_len;
1942             start = next+from_len;
1943         }
1944     }
1945     /* Copy the remainder of the remaining bytes */
1946     Py_MEMCPY(result_s, start, end-start);
1947 
1948     return result;
1949 }
1950 
1951 
1952 Py_LOCAL(PyByteArrayObject *)
replace(PyByteArrayObject * self,const char * from_s,Py_ssize_t from_len,const char * to_s,Py_ssize_t to_len,Py_ssize_t maxcount)1953 replace(PyByteArrayObject *self,
1954         const char *from_s, Py_ssize_t from_len,
1955         const char *to_s, Py_ssize_t to_len,
1956         Py_ssize_t maxcount)
1957 {
1958     if (maxcount < 0) {
1959         maxcount = PY_SSIZE_T_MAX;
1960     } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1961         /* nothing to do; return the original bytes */
1962         return return_self(self);
1963     }
1964 
1965     if (maxcount == 0 ||
1966         (from_len == 0 && to_len == 0)) {
1967         /* nothing to do; return the original bytes */
1968         return return_self(self);
1969     }
1970 
1971     /* Handle zero-length special cases */
1972 
1973     if (from_len == 0) {
1974         /* insert the 'to' bytes everywhere.   */
1975         /*    >>> "Python".replace("", ".")     */
1976         /*    '.P.y.t.h.o.n.'                   */
1977         return replace_interleave(self, to_s, to_len, maxcount);
1978     }
1979 
1980     /* Except for "".replace("", "A") == "A" there is no way beyond this */
1981     /* point for an empty self bytes to generate a non-empty bytes */
1982     /* Special case so the remaining code always gets a non-empty bytes */
1983     if (PyByteArray_GET_SIZE(self) == 0) {
1984         return return_self(self);
1985     }
1986 
1987     if (to_len == 0) {
1988         /* delete all occurances of 'from' bytes */
1989         if (from_len == 1) {
1990             return replace_delete_single_character(
1991                     self, from_s[0], maxcount);
1992         } else {
1993             return replace_delete_substring(self, from_s, from_len, maxcount);
1994         }
1995     }
1996 
1997     /* Handle special case where both bytes have the same length */
1998 
1999     if (from_len == to_len) {
2000         if (from_len == 1) {
2001             return replace_single_character_in_place(
2002                     self,
2003                     from_s[0],
2004                     to_s[0],
2005                     maxcount);
2006         } else {
2007             return replace_substring_in_place(
2008                 self, from_s, from_len, to_s, to_len, maxcount);
2009         }
2010     }
2011 
2012     /* Otherwise use the more generic algorithms */
2013     if (from_len == 1) {
2014         return replace_single_character(self, from_s[0],
2015                                         to_s, to_len, maxcount);
2016     } else {
2017         /* len('from')>=2, len('to')>=1 */
2018         return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2019     }
2020 }
2021 
2022 
2023 PyDoc_STRVAR(replace__doc__,
2024 "B.replace(old, new[, count]) -> bytes\n\
2025 \n\
2026 Return a copy of B with all occurrences of subsection\n\
2027 old replaced by new.  If the optional argument count is\n\
2028 given, only the first count occurrences are replaced.");
2029 
2030 static PyObject *
bytearray_replace(PyByteArrayObject * self,PyObject * args)2031 bytearray_replace(PyByteArrayObject *self, PyObject *args)
2032 {
2033     Py_ssize_t count = -1;
2034     PyObject *from, *to, *res;
2035     Py_buffer vfrom, vto;
2036 
2037     if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2038         return NULL;
2039 
2040     if (_getbuffer(from, &vfrom) < 0)
2041         return NULL;
2042     if (_getbuffer(to, &vto) < 0) {
2043         PyBuffer_Release(&vfrom);
2044         return NULL;
2045     }
2046 
2047     res = (PyObject *)replace((PyByteArrayObject *) self,
2048                               vfrom.buf, vfrom.len,
2049                               vto.buf, vto.len, count);
2050 
2051     PyBuffer_Release(&vfrom);
2052     PyBuffer_Release(&vto);
2053     return res;
2054 }
2055 
2056 PyDoc_STRVAR(split__doc__,
2057 "B.split([sep[, maxsplit]]) -> list of bytearray\n\
2058 \n\
2059 Return a list of the sections in B, using sep as the delimiter.\n\
2060 If sep is not given, B is split on ASCII whitespace characters\n\
2061 (space, tab, return, newline, formfeed, vertical tab).\n\
2062 If maxsplit is given, at most maxsplit splits are done.");
2063 
2064 static PyObject *
bytearray_split(PyByteArrayObject * self,PyObject * args)2065 bytearray_split(PyByteArrayObject *self, PyObject *args)
2066 {
2067     Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2068     Py_ssize_t maxsplit = -1;
2069     const char *s = PyByteArray_AS_STRING(self), *sub;
2070     PyObject *list, *subobj = Py_None;
2071     Py_buffer vsub;
2072 
2073     if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2074         return NULL;
2075     if (maxsplit < 0)
2076         maxsplit = PY_SSIZE_T_MAX;
2077 
2078     if (subobj == Py_None)
2079         return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
2080 
2081     if (_getbuffer(subobj, &vsub) < 0)
2082         return NULL;
2083     sub = vsub.buf;
2084     n = vsub.len;
2085 
2086     list = stringlib_split(
2087         (PyObject*) self, s, len, sub, n, maxsplit
2088         );
2089     PyBuffer_Release(&vsub);
2090     return list;
2091 }
2092 
2093 PyDoc_STRVAR(partition__doc__,
2094 "B.partition(sep) -> (head, sep, tail)\n\
2095 \n\
2096 Searches for the separator sep in B, and returns the part before it,\n\
2097 the separator itself, and the part after it.  If the separator is not\n\
2098 found, returns B and two empty bytearray objects.");
2099 
2100 static PyObject *
bytearray_partition(PyByteArrayObject * self,PyObject * sep_obj)2101 bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
2102 {
2103     PyObject *bytesep, *result;
2104 
2105     bytesep = PyByteArray_FromObject(sep_obj);
2106     if (! bytesep)
2107         return NULL;
2108 
2109     result = stringlib_partition(
2110             (PyObject*) self,
2111             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2112             bytesep,
2113             PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2114             );
2115 
2116     Py_DECREF(bytesep);
2117     return result;
2118 }
2119 
2120 PyDoc_STRVAR(rpartition__doc__,
2121 "B.rpartition(sep) -> (head, sep, tail)\n\
2122 \n\
2123 Searches for the separator sep in B, starting at the end of B,\n\
2124 and returns the part before it, the separator itself, and the\n\
2125 part after it.  If the separator is not found, returns two empty\n\
2126 bytearray objects and B.");
2127 
2128 static PyObject *
bytearray_rpartition(PyByteArrayObject * self,PyObject * sep_obj)2129 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
2130 {
2131     PyObject *bytesep, *result;
2132 
2133     bytesep = PyByteArray_FromObject(sep_obj);
2134     if (! bytesep)
2135         return NULL;
2136 
2137     result = stringlib_rpartition(
2138             (PyObject*) self,
2139             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2140             bytesep,
2141             PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2142             );
2143 
2144     Py_DECREF(bytesep);
2145     return result;
2146 }
2147 
2148 PyDoc_STRVAR(rsplit__doc__,
2149 "B.rsplit(sep[, maxsplit]) -> list of bytearray\n\
2150 \n\
2151 Return a list of the sections in B, using sep as the delimiter,\n\
2152 starting at the end of B and working to the front.\n\
2153 If sep is not given, B is split on ASCII whitespace characters\n\
2154 (space, tab, return, newline, formfeed, vertical tab).\n\
2155 If maxsplit is given, at most maxsplit splits are done.");
2156 
2157 static PyObject *
bytearray_rsplit(PyByteArrayObject * self,PyObject * args)2158 bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
2159 {
2160     Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
2161     Py_ssize_t maxsplit = -1;
2162     const char *s = PyByteArray_AS_STRING(self), *sub;
2163     PyObject *list, *subobj = Py_None;
2164     Py_buffer vsub;
2165 
2166     if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2167         return NULL;
2168     if (maxsplit < 0)
2169         maxsplit = PY_SSIZE_T_MAX;
2170 
2171     if (subobj == Py_None)
2172         return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
2173 
2174     if (_getbuffer(subobj, &vsub) < 0)
2175         return NULL;
2176     sub = vsub.buf;
2177     n = vsub.len;
2178 
2179     list = stringlib_rsplit(
2180         (PyObject*) self, s, len, sub, n, maxsplit
2181         );
2182     PyBuffer_Release(&vsub);
2183     return list;
2184 }
2185 
2186 PyDoc_STRVAR(reverse__doc__,
2187 "B.reverse() -> None\n\
2188 \n\
2189 Reverse the order of the values in B in place.");
2190 static PyObject *
bytearray_reverse(PyByteArrayObject * self,PyObject * unused)2191 bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
2192 {
2193     char swap, *head, *tail;
2194     Py_ssize_t i, j, n = Py_SIZE(self);
2195 
2196     j = n / 2;
2197     head = self->ob_bytes;
2198     tail = head + n - 1;
2199     for (i = 0; i < j; i++) {
2200         swap = *head;
2201         *head++ = *tail;
2202         *tail-- = swap;
2203     }
2204 
2205     Py_RETURN_NONE;
2206 }
2207 
2208 PyDoc_STRVAR(insert__doc__,
2209 "B.insert(index, int) -> None\n\
2210 \n\
2211 Insert a single item into the bytearray before the given index.");
2212 static PyObject *
bytearray_insert(PyByteArrayObject * self,PyObject * args)2213 bytearray_insert(PyByteArrayObject *self, PyObject *args)
2214 {
2215     PyObject *value;
2216     int ival;
2217     Py_ssize_t where, n = Py_SIZE(self);
2218 
2219     if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
2220         return NULL;
2221 
2222     if (n == PY_SSIZE_T_MAX) {
2223         PyErr_SetString(PyExc_OverflowError,
2224                         "cannot add more objects to bytearray");
2225         return NULL;
2226     }
2227     if (!_getbytevalue(value, &ival))
2228         return NULL;
2229     if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2230         return NULL;
2231 
2232     if (where < 0) {
2233         where += n;
2234         if (where < 0)
2235             where = 0;
2236     }
2237     if (where > n)
2238         where = n;
2239     memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
2240     self->ob_bytes[where] = ival;
2241 
2242     Py_RETURN_NONE;
2243 }
2244 
2245 PyDoc_STRVAR(append__doc__,
2246 "B.append(int) -> None\n\
2247 \n\
2248 Append a single item to the end of B.");
2249 static PyObject *
bytearray_append(PyByteArrayObject * self,PyObject * arg)2250 bytearray_append(PyByteArrayObject *self, PyObject *arg)
2251 {
2252     int value;
2253     Py_ssize_t n = Py_SIZE(self);
2254 
2255     if (! _getbytevalue(arg, &value))
2256         return NULL;
2257     if (n == PY_SSIZE_T_MAX) {
2258         PyErr_SetString(PyExc_OverflowError,
2259                         "cannot add more objects to bytearray");
2260         return NULL;
2261     }
2262     if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2263         return NULL;
2264 
2265     self->ob_bytes[n] = value;
2266 
2267     Py_RETURN_NONE;
2268 }
2269 
2270 PyDoc_STRVAR(extend__doc__,
2271 "B.extend(iterable int) -> None\n\
2272 \n\
2273 Append all the elements from the iterator or sequence to the\n\
2274 end of B.");
2275 static PyObject *
bytearray_extend(PyByteArrayObject * self,PyObject * arg)2276 bytearray_extend(PyByteArrayObject *self, PyObject *arg)
2277 {
2278     PyObject *it, *item, *bytearray_obj;
2279     Py_ssize_t buf_size = 0, len = 0;
2280     int value;
2281     char *buf;
2282 
2283     /* bytearray_setslice code only accepts something supporting PEP 3118. */
2284     if (PyObject_CheckBuffer(arg)) {
2285         if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
2286             return NULL;
2287 
2288         Py_RETURN_NONE;
2289     }
2290 
2291     it = PyObject_GetIter(arg);
2292     if (it == NULL)
2293         return NULL;
2294 
2295     /* Try to determine the length of the argument. 32 is arbitrary. */
2296     buf_size = _PyObject_LengthHint(arg, 32);
2297     if (buf_size == -1) {
2298         Py_DECREF(it);
2299         return NULL;
2300     }
2301 
2302     bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2303     if (bytearray_obj == NULL) {
2304         Py_DECREF(it);
2305         return NULL;
2306     }
2307     buf = PyByteArray_AS_STRING(bytearray_obj);
2308 
2309     while ((item = PyIter_Next(it)) != NULL) {
2310         if (! _getbytevalue(item, &value)) {
2311             Py_DECREF(item);
2312             Py_DECREF(it);
2313             Py_DECREF(bytearray_obj);
2314             return NULL;
2315         }
2316         buf[len++] = value;
2317         Py_DECREF(item);
2318 
2319         if (len >= buf_size) {
2320             buf_size = len + (len >> 1) + 1;
2321             if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
2322                 Py_DECREF(it);
2323                 Py_DECREF(bytearray_obj);
2324                 return NULL;
2325             }
2326             /* Recompute the `buf' pointer, since the resizing operation may
2327                have invalidated it. */
2328             buf = PyByteArray_AS_STRING(bytearray_obj);
2329         }
2330     }
2331     Py_DECREF(it);
2332 
2333     /* Resize down to exact size. */
2334     if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2335         Py_DECREF(bytearray_obj);
2336         return NULL;
2337     }
2338 
2339     if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2340         Py_DECREF(bytearray_obj);
2341         return NULL;
2342     }
2343     Py_DECREF(bytearray_obj);
2344 
2345     Py_RETURN_NONE;
2346 }
2347 
2348 PyDoc_STRVAR(pop__doc__,
2349 "B.pop([index]) -> int\n\
2350 \n\
2351 Remove and return a single item from B. If no index\n\
2352 argument is given, will pop the last value.");
2353 static PyObject *
bytearray_pop(PyByteArrayObject * self,PyObject * args)2354 bytearray_pop(PyByteArrayObject *self, PyObject *args)
2355 {
2356     int value;
2357     Py_ssize_t where = -1, n = Py_SIZE(self);
2358 
2359     if (!PyArg_ParseTuple(args, "|n:pop", &where))
2360         return NULL;
2361 
2362     if (n == 0) {
2363         PyErr_SetString(PyExc_IndexError,
2364                         "pop from empty bytearray");
2365         return NULL;
2366     }
2367     if (where < 0)
2368         where += Py_SIZE(self);
2369     if (where < 0 || where >= Py_SIZE(self)) {
2370         PyErr_SetString(PyExc_IndexError, "pop index out of range");
2371         return NULL;
2372     }
2373     if (!_canresize(self))
2374         return NULL;
2375 
2376     value = self->ob_bytes[where];
2377     memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2378     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2379         return NULL;
2380 
2381     return PyInt_FromLong((unsigned char)value);
2382 }
2383 
2384 PyDoc_STRVAR(remove__doc__,
2385 "B.remove(int) -> None\n\
2386 \n\
2387 Remove the first occurance of a value in B.");
2388 static PyObject *
bytearray_remove(PyByteArrayObject * self,PyObject * arg)2389 bytearray_remove(PyByteArrayObject *self, PyObject *arg)
2390 {
2391     int value;
2392     Py_ssize_t where, n = Py_SIZE(self);
2393 
2394     if (! _getbytevalue(arg, &value))
2395         return NULL;
2396 
2397     for (where = 0; where < n; where++) {
2398         if (self->ob_bytes[where] == value)
2399             break;
2400     }
2401     if (where == n) {
2402         PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
2403         return NULL;
2404     }
2405     if (!_canresize(self))
2406         return NULL;
2407 
2408     memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2409     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2410         return NULL;
2411 
2412     Py_RETURN_NONE;
2413 }
2414 
2415 /* XXX These two helpers could be optimized if argsize == 1 */
2416 
2417 static Py_ssize_t
lstrip_helper(unsigned char * myptr,Py_ssize_t mysize,void * argptr,Py_ssize_t argsize)2418 lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2419               void *argptr, Py_ssize_t argsize)
2420 {
2421     Py_ssize_t i = 0;
2422     while (i < mysize && memchr(argptr, myptr[i], argsize))
2423         i++;
2424     return i;
2425 }
2426 
2427 static Py_ssize_t
rstrip_helper(unsigned char * myptr,Py_ssize_t mysize,void * argptr,Py_ssize_t argsize)2428 rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2429               void *argptr, Py_ssize_t argsize)
2430 {
2431     Py_ssize_t i = mysize - 1;
2432     while (i >= 0 && memchr(argptr, myptr[i], argsize))
2433         i--;
2434     return i + 1;
2435 }
2436 
2437 PyDoc_STRVAR(strip__doc__,
2438 "B.strip([bytes]) -> bytearray\n\
2439 \n\
2440 Strip leading and trailing bytes contained in the argument.\n\
2441 If the argument is omitted, strip ASCII whitespace.");
2442 static PyObject *
bytearray_strip(PyByteArrayObject * self,PyObject * args)2443 bytearray_strip(PyByteArrayObject *self, PyObject *args)
2444 {
2445     Py_ssize_t left, right, mysize, argsize;
2446     void *myptr, *argptr;
2447     PyObject *arg = Py_None;
2448     Py_buffer varg;
2449     if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2450         return NULL;
2451     if (arg == Py_None) {
2452         argptr = "\t\n\r\f\v ";
2453         argsize = 6;
2454     }
2455     else {
2456         if (_getbuffer(arg, &varg) < 0)
2457             return NULL;
2458         argptr = varg.buf;
2459         argsize = varg.len;
2460     }
2461     myptr = self->ob_bytes;
2462     mysize = Py_SIZE(self);
2463     left = lstrip_helper(myptr, mysize, argptr, argsize);
2464     if (left == mysize)
2465         right = left;
2466     else
2467         right = rstrip_helper(myptr, mysize, argptr, argsize);
2468     if (arg != Py_None)
2469         PyBuffer_Release(&varg);
2470     return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2471 }
2472 
2473 PyDoc_STRVAR(lstrip__doc__,
2474 "B.lstrip([bytes]) -> bytearray\n\
2475 \n\
2476 Strip leading bytes contained in the argument.\n\
2477 If the argument is omitted, strip leading ASCII whitespace.");
2478 static PyObject *
bytearray_lstrip(PyByteArrayObject * self,PyObject * args)2479 bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
2480 {
2481     Py_ssize_t left, right, mysize, argsize;
2482     void *myptr, *argptr;
2483     PyObject *arg = Py_None;
2484     Py_buffer varg;
2485     if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2486         return NULL;
2487     if (arg == Py_None) {
2488         argptr = "\t\n\r\f\v ";
2489         argsize = 6;
2490     }
2491     else {
2492         if (_getbuffer(arg, &varg) < 0)
2493             return NULL;
2494         argptr = varg.buf;
2495         argsize = varg.len;
2496     }
2497     myptr = self->ob_bytes;
2498     mysize = Py_SIZE(self);
2499     left = lstrip_helper(myptr, mysize, argptr, argsize);
2500     right = mysize;
2501     if (arg != Py_None)
2502         PyBuffer_Release(&varg);
2503     return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2504 }
2505 
2506 PyDoc_STRVAR(rstrip__doc__,
2507 "B.rstrip([bytes]) -> bytearray\n\
2508 \n\
2509 Strip trailing bytes contained in the argument.\n\
2510 If the argument is omitted, strip trailing ASCII whitespace.");
2511 static PyObject *
bytearray_rstrip(PyByteArrayObject * self,PyObject * args)2512 bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
2513 {
2514     Py_ssize_t left, right, mysize, argsize;
2515     void *myptr, *argptr;
2516     PyObject *arg = Py_None;
2517     Py_buffer varg;
2518     if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2519         return NULL;
2520     if (arg == Py_None) {
2521         argptr = "\t\n\r\f\v ";
2522         argsize = 6;
2523     }
2524     else {
2525         if (_getbuffer(arg, &varg) < 0)
2526             return NULL;
2527         argptr = varg.buf;
2528         argsize = varg.len;
2529     }
2530     myptr = self->ob_bytes;
2531     mysize = Py_SIZE(self);
2532     left = 0;
2533     right = rstrip_helper(myptr, mysize, argptr, argsize);
2534     if (arg != Py_None)
2535         PyBuffer_Release(&varg);
2536     return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2537 }
2538 
2539 PyDoc_STRVAR(decode_doc,
2540 "B.decode([encoding[, errors]]) -> unicode object.\n\
2541 \n\
2542 Decodes B using the codec registered for encoding. encoding defaults\n\
2543 to the default encoding. errors may be given to set a different error\n\
2544 handling scheme.  Default is 'strict' meaning that encoding errors raise\n\
2545 a UnicodeDecodeError.  Other possible values are 'ignore' and 'replace'\n\
2546 as well as any other name registered with codecs.register_error that is\n\
2547 able to handle UnicodeDecodeErrors.");
2548 
2549 static PyObject *
bytearray_decode(PyObject * self,PyObject * args,PyObject * kwargs)2550 bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
2551 {
2552     const char *encoding = NULL;
2553     const char *errors = NULL;
2554     static char *kwlist[] = {"encoding", "errors", 0};
2555 
2556     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
2557         return NULL;
2558     if (encoding == NULL) {
2559 #ifdef Py_USING_UNICODE
2560         encoding = PyUnicode_GetDefaultEncoding();
2561 #else
2562         PyErr_SetString(PyExc_ValueError, "no encoding specified");
2563         return NULL;
2564 #endif
2565     }
2566     return PyCodec_Decode(self, encoding, errors);
2567 }
2568 
2569 PyDoc_STRVAR(alloc_doc,
2570 "B.__alloc__() -> int\n\
2571 \n\
2572 Returns the number of bytes actually allocated.");
2573 
2574 static PyObject *
bytearray_alloc(PyByteArrayObject * self)2575 bytearray_alloc(PyByteArrayObject *self)
2576 {
2577     return PyInt_FromSsize_t(self->ob_alloc);
2578 }
2579 
2580 PyDoc_STRVAR(join_doc,
2581 "B.join(iterable_of_bytes) -> bytes\n\
2582 \n\
2583 Concatenates any number of bytearray objects, with B in between each pair.");
2584 
2585 static PyObject *
bytearray_join(PyByteArrayObject * self,PyObject * it)2586 bytearray_join(PyByteArrayObject *self, PyObject *it)
2587 {
2588     PyObject *seq;
2589     Py_ssize_t mysize = Py_SIZE(self);
2590     Py_ssize_t i;
2591     Py_ssize_t n;
2592     PyObject **items;
2593     Py_ssize_t totalsize = 0;
2594     PyObject *result;
2595     char *dest;
2596 
2597     seq = PySequence_Fast(it, "can only join an iterable");
2598     if (seq == NULL)
2599         return NULL;
2600     n = PySequence_Fast_GET_SIZE(seq);
2601     items = PySequence_Fast_ITEMS(seq);
2602 
2603     /* Compute the total size, and check that they are all bytes */
2604     /* XXX Shouldn't we use _getbuffer() on these items instead? */
2605     for (i = 0; i < n; i++) {
2606         PyObject *obj = items[i];
2607         if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2608             PyErr_Format(PyExc_TypeError,
2609                          "can only join an iterable of bytes "
2610                          "(item %ld has type '%.100s')",
2611                          /* XXX %ld isn't right on Win64 */
2612                          (long)i, Py_TYPE(obj)->tp_name);
2613             goto error;
2614         }
2615         if (i > 0)
2616             totalsize += mysize;
2617         totalsize += Py_SIZE(obj);
2618         if (totalsize < 0) {
2619             PyErr_NoMemory();
2620             goto error;
2621         }
2622     }
2623 
2624     /* Allocate the result, and copy the bytes */
2625     result = PyByteArray_FromStringAndSize(NULL, totalsize);
2626     if (result == NULL)
2627         goto error;
2628     dest = PyByteArray_AS_STRING(result);
2629     for (i = 0; i < n; i++) {
2630         PyObject *obj = items[i];
2631         Py_ssize_t size = Py_SIZE(obj);
2632         char *buf;
2633         if (PyByteArray_Check(obj))
2634            buf = PyByteArray_AS_STRING(obj);
2635         else
2636            buf = PyBytes_AS_STRING(obj);
2637         if (i) {
2638             memcpy(dest, self->ob_bytes, mysize);
2639             dest += mysize;
2640         }
2641         memcpy(dest, buf, size);
2642         dest += size;
2643     }
2644 
2645     /* Done */
2646     Py_DECREF(seq);
2647     return result;
2648 
2649     /* Error handling */
2650   error:
2651     Py_DECREF(seq);
2652     return NULL;
2653 }
2654 
2655 PyDoc_STRVAR(splitlines__doc__,
2656 "B.splitlines(keepends=False) -> list of lines\n\
2657 \n\
2658 Return a list of the lines in B, breaking at line boundaries.\n\
2659 Line breaks are not included in the resulting list unless keepends\n\
2660 is given and true.");
2661 
2662 static PyObject*
bytearray_splitlines(PyObject * self,PyObject * args)2663 bytearray_splitlines(PyObject *self, PyObject *args)
2664 {
2665     int keepends = 0;
2666 
2667     if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends))
2668         return NULL;
2669 
2670     return stringlib_splitlines(
2671         (PyObject*) self, PyByteArray_AS_STRING(self),
2672         PyByteArray_GET_SIZE(self), keepends
2673         );
2674 }
2675 
2676 PyDoc_STRVAR(fromhex_doc,
2677 "bytearray.fromhex(string) -> bytearray\n\
2678 \n\
2679 Create a bytearray object from a string of hexadecimal numbers.\n\
2680 Spaces between two numbers are accepted.\n\
2681 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2682 
2683 static int
hex_digit_to_int(char c)2684 hex_digit_to_int(char c)
2685 {
2686     if (Py_ISDIGIT(c))
2687         return c - '0';
2688     else {
2689         if (Py_ISUPPER(c))
2690             c = Py_TOLOWER(c);
2691         if (c >= 'a' && c <= 'f')
2692             return c - 'a' + 10;
2693     }
2694     return -1;
2695 }
2696 
2697 static PyObject *
bytearray_fromhex(PyObject * cls,PyObject * args)2698 bytearray_fromhex(PyObject *cls, PyObject *args)
2699 {
2700     PyObject *newbytes;
2701     char *buf;
2702     char *hex;
2703     Py_ssize_t hexlen, byteslen, i, j;
2704     int top, bot;
2705 
2706     if (!PyArg_ParseTuple(args, "s#:fromhex", &hex, &hexlen))
2707         return NULL;
2708     byteslen = hexlen/2; /* This overestimates if there are spaces */
2709     newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
2710     if (!newbytes)
2711         return NULL;
2712     buf = PyByteArray_AS_STRING(newbytes);
2713     for (i = j = 0; i < hexlen; i += 2) {
2714         /* skip over spaces in the input */
2715         while (hex[i] == ' ')
2716             i++;
2717         if (i >= hexlen)
2718             break;
2719         top = hex_digit_to_int(hex[i]);
2720         bot = hex_digit_to_int(hex[i+1]);
2721         if (top == -1 || bot == -1) {
2722             PyErr_Format(PyExc_ValueError,
2723                          "non-hexadecimal number found in "
2724                          "fromhex() arg at position %zd", i);
2725             goto error;
2726         }
2727         buf[j++] = (top << 4) + bot;
2728     }
2729     if (PyByteArray_Resize(newbytes, j) < 0)
2730         goto error;
2731     return newbytes;
2732 
2733   error:
2734     Py_DECREF(newbytes);
2735     return NULL;
2736 }
2737 
2738 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
2739 
2740 static PyObject *
bytearray_reduce(PyByteArrayObject * self)2741 bytearray_reduce(PyByteArrayObject *self)
2742 {
2743     PyObject *latin1, *dict;
2744     if (self->ob_bytes)
2745 #ifdef Py_USING_UNICODE
2746         latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
2747                                         Py_SIZE(self), NULL);
2748 #else
2749         latin1 = PyString_FromStringAndSize(self->ob_bytes, Py_SIZE(self));
2750 #endif
2751     else
2752 #ifdef Py_USING_UNICODE
2753         latin1 = PyUnicode_FromString("");
2754 #else
2755         latin1 = PyString_FromString("");
2756 #endif
2757 
2758     dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
2759     if (dict == NULL) {
2760         PyErr_Clear();
2761         dict = Py_None;
2762         Py_INCREF(dict);
2763     }
2764 
2765     return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2766 }
2767 
2768 PyDoc_STRVAR(sizeof_doc,
2769 "B.__sizeof__() -> int\n\
2770  \n\
2771 Returns the size of B in memory, in bytes");
2772 static PyObject *
bytearray_sizeof(PyByteArrayObject * self)2773 bytearray_sizeof(PyByteArrayObject *self)
2774 {
2775     Py_ssize_t res;
2776 
2777     res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
2778     return PyInt_FromSsize_t(res);
2779 }
2780 
2781 static PySequenceMethods bytearray_as_sequence = {
2782     (lenfunc)bytearray_length,              /* sq_length */
2783     (binaryfunc)PyByteArray_Concat,         /* sq_concat */
2784     (ssizeargfunc)bytearray_repeat,         /* sq_repeat */
2785     (ssizeargfunc)bytearray_getitem,        /* sq_item */
2786     0,                                      /* sq_slice */
2787     (ssizeobjargproc)bytearray_setitem,     /* sq_ass_item */
2788     0,                                      /* sq_ass_slice */
2789     (objobjproc)bytearray_contains,         /* sq_contains */
2790     (binaryfunc)bytearray_iconcat,          /* sq_inplace_concat */
2791     (ssizeargfunc)bytearray_irepeat,        /* sq_inplace_repeat */
2792 };
2793 
2794 static PyMappingMethods bytearray_as_mapping = {
2795     (lenfunc)bytearray_length,
2796     (binaryfunc)bytearray_subscript,
2797     (objobjargproc)bytearray_ass_subscript,
2798 };
2799 
2800 static PyBufferProcs bytearray_as_buffer = {
2801     (readbufferproc)bytearray_buffer_getreadbuf,
2802     (writebufferproc)bytearray_buffer_getwritebuf,
2803     (segcountproc)bytearray_buffer_getsegcount,
2804     (charbufferproc)bytearray_buffer_getcharbuf,
2805     (getbufferproc)bytearray_getbuffer,
2806     (releasebufferproc)bytearray_releasebuffer,
2807 };
2808 
2809 static PyMethodDef
2810 bytearray_methods[] = {
2811     {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2812     {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
2813     {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
2814     {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
2815     {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2816      _Py_capitalize__doc__},
2817     {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
2818     {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
2819     {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
2820     {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
2821     {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
2822      expandtabs__doc__},
2823     {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
2824     {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
2825     {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
2826      fromhex_doc},
2827     {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
2828     {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
2829     {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2830      _Py_isalnum__doc__},
2831     {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2832      _Py_isalpha__doc__},
2833     {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2834      _Py_isdigit__doc__},
2835     {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2836      _Py_islower__doc__},
2837     {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2838      _Py_isspace__doc__},
2839     {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2840      _Py_istitle__doc__},
2841     {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2842      _Py_isupper__doc__},
2843     {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
2844     {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
2845     {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
2846     {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
2847     {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
2848     {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
2849     {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
2850     {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
2851     {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
2852     {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
2853     {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
2854     {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
2855     {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
2856     {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
2857     {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
2858     {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
2859     {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS,
2860      splitlines__doc__},
2861     {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
2862      startswith__doc__},
2863     {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
2864     {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2865      _Py_swapcase__doc__},
2866     {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
2867     {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
2868      translate__doc__},
2869     {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2870     {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
2871     {NULL}
2872 };
2873 
2874 PyDoc_STRVAR(bytearray_doc,
2875 "bytearray(iterable_of_ints) -> bytearray.\n\
2876 bytearray(string, encoding[, errors]) -> bytearray.\n\
2877 bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\
2878 bytearray(memory_view) -> bytearray.\n\
2879 \n\
2880 Construct an mutable bytearray object from:\n\
2881   - an iterable yielding integers in range(256)\n\
2882   - a text string encoded using the specified encoding\n\
2883   - a bytes or a bytearray object\n\
2884   - any object implementing the buffer API.\n\
2885 \n\
2886 bytearray(int) -> bytearray.\n\
2887 \n\
2888 Construct a zero-initialized bytearray of the given length.");
2889 
2890 
2891 static PyObject *bytearray_iter(PyObject *seq);
2892 
2893 PyTypeObject PyByteArray_Type = {
2894     PyVarObject_HEAD_INIT(&PyType_Type, 0)
2895     "bytearray",
2896     sizeof(PyByteArrayObject),
2897     0,
2898     (destructor)bytearray_dealloc,       /* tp_dealloc */
2899     0,                                  /* tp_print */
2900     0,                                  /* tp_getattr */
2901     0,                                  /* tp_setattr */
2902     0,                                  /* tp_compare */
2903     (reprfunc)bytearray_repr,           /* tp_repr */
2904     0,                                  /* tp_as_number */
2905     &bytearray_as_sequence,             /* tp_as_sequence */
2906     &bytearray_as_mapping,              /* tp_as_mapping */
2907     0,                                  /* tp_hash */
2908     0,                                  /* tp_call */
2909     bytearray_str,                      /* tp_str */
2910     PyObject_GenericGetAttr,            /* tp_getattro */
2911     0,                                  /* tp_setattro */
2912     &bytearray_as_buffer,               /* tp_as_buffer */
2913     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2914     Py_TPFLAGS_HAVE_NEWBUFFER,          /* tp_flags */
2915     bytearray_doc,                      /* tp_doc */
2916     0,                                  /* tp_traverse */
2917     0,                                  /* tp_clear */
2918     (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
2919     0,                                  /* tp_weaklistoffset */
2920     bytearray_iter,                     /* tp_iter */
2921     0,                                  /* tp_iternext */
2922     bytearray_methods,                  /* tp_methods */
2923     0,                                  /* tp_members */
2924     0,                                  /* tp_getset */
2925     0,                                  /* tp_base */
2926     0,                                  /* tp_dict */
2927     0,                                  /* tp_descr_get */
2928     0,                                  /* tp_descr_set */
2929     0,                                  /* tp_dictoffset */
2930     (initproc)bytearray_init,           /* tp_init */
2931     PyType_GenericAlloc,                /* tp_alloc */
2932     PyType_GenericNew,                  /* tp_new */
2933     PyObject_Del,                       /* tp_free */
2934 };
2935 
2936 /*********************** Bytes Iterator ****************************/
2937 
2938 typedef struct {
2939     PyObject_HEAD
2940     Py_ssize_t it_index;
2941     PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2942 } bytesiterobject;
2943 
2944 static void
bytearrayiter_dealloc(bytesiterobject * it)2945 bytearrayiter_dealloc(bytesiterobject *it)
2946 {
2947     _PyObject_GC_UNTRACK(it);
2948     Py_XDECREF(it->it_seq);
2949     PyObject_GC_Del(it);
2950 }
2951 
2952 static int
bytearrayiter_traverse(bytesiterobject * it,visitproc visit,void * arg)2953 bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2954 {
2955     Py_VISIT(it->it_seq);
2956     return 0;
2957 }
2958 
2959 static PyObject *
bytearrayiter_next(bytesiterobject * it)2960 bytearrayiter_next(bytesiterobject *it)
2961 {
2962     PyByteArrayObject *seq;
2963     PyObject *item;
2964 
2965     assert(it != NULL);
2966     seq = it->it_seq;
2967     if (seq == NULL)
2968         return NULL;
2969     assert(PyByteArray_Check(seq));
2970 
2971     if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2972         item = PyInt_FromLong(
2973             (unsigned char)seq->ob_bytes[it->it_index]);
2974         if (item != NULL)
2975             ++it->it_index;
2976         return item;
2977     }
2978 
2979     Py_DECREF(seq);
2980     it->it_seq = NULL;
2981     return NULL;
2982 }
2983 
2984 static PyObject *
bytesarrayiter_length_hint(bytesiterobject * it)2985 bytesarrayiter_length_hint(bytesiterobject *it)
2986 {
2987     Py_ssize_t len = 0;
2988     if (it->it_seq)
2989         len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2990     return PyInt_FromSsize_t(len);
2991 }
2992 
2993 PyDoc_STRVAR(length_hint_doc,
2994     "Private method returning an estimate of len(list(it)).");
2995 
2996 static PyMethodDef bytearrayiter_methods[] = {
2997     {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
2998      length_hint_doc},
2999     {NULL, NULL} /* sentinel */
3000 };
3001 
3002 PyTypeObject PyByteArrayIter_Type = {
3003     PyVarObject_HEAD_INIT(&PyType_Type, 0)
3004     "bytearray_iterator",              /* tp_name */
3005     sizeof(bytesiterobject),           /* tp_basicsize */
3006     0,                                 /* tp_itemsize */
3007     /* methods */
3008     (destructor)bytearrayiter_dealloc, /* tp_dealloc */
3009     0,                                 /* tp_print */
3010     0,                                 /* tp_getattr */
3011     0,                                 /* tp_setattr */
3012     0,                                 /* tp_compare */
3013     0,                                 /* tp_repr */
3014     0,                                 /* tp_as_number */
3015     0,                                 /* tp_as_sequence */
3016     0,                                 /* tp_as_mapping */
3017     0,                                 /* tp_hash */
3018     0,                                 /* tp_call */
3019     0,                                 /* tp_str */
3020     PyObject_GenericGetAttr,           /* tp_getattro */
3021     0,                                 /* tp_setattro */
3022     0,                                 /* tp_as_buffer */
3023     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3024     0,                                 /* tp_doc */
3025     (traverseproc)bytearrayiter_traverse,  /* tp_traverse */
3026     0,                                 /* tp_clear */
3027     0,                                 /* tp_richcompare */
3028     0,                                 /* tp_weaklistoffset */
3029     PyObject_SelfIter,                 /* tp_iter */
3030     (iternextfunc)bytearrayiter_next,  /* tp_iternext */
3031     bytearrayiter_methods,             /* tp_methods */
3032     0,
3033 };
3034 
3035 static PyObject *
bytearray_iter(PyObject * seq)3036 bytearray_iter(PyObject *seq)
3037 {
3038     bytesiterobject *it;
3039 
3040     if (!PyByteArray_Check(seq)) {
3041         PyErr_BadInternalCall();
3042         return NULL;
3043     }
3044     it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3045     if (it == NULL)
3046         return NULL;
3047     it->it_index = 0;
3048     Py_INCREF(seq);
3049     it->it_seq = (PyByteArrayObject *)seq;
3050     _PyObject_GC_TRACK(it);
3051     return (PyObject *)it;
3052 }
3053