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