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