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