remove old metaclass demos
[python/dscho.git] / Objects / bytearrayobject.c
blob165fd10477bf6ae3cb65e812da336b239bcf8445
1 /* PyByteArray (bytearray) implementation */
3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h"
5 #include "structmember.h"
6 #include "bytes_methods.h"
8 static PyByteArrayObject *nullbytes = NULL;
10 void
11 PyByteArray_Fini(void)
13 Py_CLEAR(nullbytes);
16 int
17 PyByteArray_Init(void)
19 nullbytes = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
20 if (nullbytes == NULL)
21 return 0;
22 nullbytes->ob_bytes = NULL;
23 Py_SIZE(nullbytes) = nullbytes->ob_alloc = 0;
24 nullbytes->ob_exports = 0;
25 return 1;
28 /* end nullbytes support */
30 /* Helpers */
32 static int
33 _getbytevalue(PyObject* arg, int *value)
35 long face_value;
37 if (PyLong_Check(arg)) {
38 face_value = PyLong_AsLong(arg);
39 } else {
40 PyObject *index = PyNumber_Index(arg);
41 if (index == NULL) {
42 PyErr_Format(PyExc_TypeError, "an integer is required");
43 return 0;
45 face_value = PyLong_AsLong(index);
46 Py_DECREF(index);
49 if (face_value < 0 || face_value >= 256) {
50 /* this includes the OverflowError in case the long is too large */
51 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
52 return 0;
55 *value = face_value;
56 return 1;
59 static int
60 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
62 int ret;
63 void *ptr;
64 if (view == NULL) {
65 obj->ob_exports++;
66 return 0;
68 if (obj->ob_bytes == NULL)
69 ptr = "";
70 else
71 ptr = obj->ob_bytes;
72 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
73 if (ret >= 0) {
74 obj->ob_exports++;
76 return ret;
79 static void
80 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
82 obj->ob_exports--;
85 static Py_ssize_t
86 _getbuffer(PyObject *obj, Py_buffer *view)
88 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
90 if (buffer == NULL || buffer->bf_getbuffer == NULL)
92 PyErr_Format(PyExc_TypeError,
93 "Type %.100s doesn't support the buffer API",
94 Py_TYPE(obj)->tp_name);
95 return -1;
98 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
99 return -1;
100 return view->len;
103 static int
104 _canresize(PyByteArrayObject *self)
106 if (self->ob_exports > 0) {
107 PyErr_SetString(PyExc_BufferError,
108 "Existing exports of data: object cannot be re-sized");
109 return 0;
111 return 1;
114 /* Direct API functions */
116 PyObject *
117 PyByteArray_FromObject(PyObject *input)
119 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
120 input, NULL);
123 PyObject *
124 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
126 PyByteArrayObject *new;
127 Py_ssize_t alloc;
129 if (size < 0) {
130 PyErr_SetString(PyExc_SystemError,
131 "Negative size passed to PyByteArray_FromStringAndSize");
132 return NULL;
135 /* Prevent buffer overflow when setting alloc to size+1. */
136 if (size == PY_SSIZE_T_MAX) {
137 return PyErr_NoMemory();
140 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
141 if (new == NULL)
142 return NULL;
144 if (size == 0) {
145 new->ob_bytes = NULL;
146 alloc = 0;
148 else {
149 alloc = size + 1;
150 new->ob_bytes = PyMem_Malloc(alloc);
151 if (new->ob_bytes == NULL) {
152 Py_DECREF(new);
153 return PyErr_NoMemory();
155 if (bytes != NULL)
156 memcpy(new->ob_bytes, bytes, size);
157 new->ob_bytes[size] = '\0'; /* Trailing null byte */
159 Py_SIZE(new) = size;
160 new->ob_alloc = alloc;
161 new->ob_exports = 0;
163 return (PyObject *)new;
166 Py_ssize_t
167 PyByteArray_Size(PyObject *self)
169 assert(self != NULL);
170 assert(PyByteArray_Check(self));
172 return PyByteArray_GET_SIZE(self);
175 char *
176 PyByteArray_AsString(PyObject *self)
178 assert(self != NULL);
179 assert(PyByteArray_Check(self));
181 return PyByteArray_AS_STRING(self);
185 PyByteArray_Resize(PyObject *self, Py_ssize_t size)
187 void *sval;
188 Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
190 assert(self != NULL);
191 assert(PyByteArray_Check(self));
192 assert(size >= 0);
194 if (size == Py_SIZE(self)) {
195 return 0;
197 if (!_canresize((PyByteArrayObject *)self)) {
198 return -1;
201 if (size < alloc / 2) {
202 /* Major downsize; resize down to exact size */
203 alloc = size + 1;
205 else if (size < alloc) {
206 /* Within allocated size; quick exit */
207 Py_SIZE(self) = size;
208 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
209 return 0;
211 else if (size <= alloc * 1.125) {
212 /* Moderate upsize; overallocate similar to list_resize() */
213 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
215 else {
216 /* Major upsize; resize up to exact size */
217 alloc = size + 1;
220 sval = PyMem_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
221 if (sval == NULL) {
222 PyErr_NoMemory();
223 return -1;
226 ((PyByteArrayObject *)self)->ob_bytes = sval;
227 Py_SIZE(self) = size;
228 ((PyByteArrayObject *)self)->ob_alloc = alloc;
229 ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
231 return 0;
234 PyObject *
235 PyByteArray_Concat(PyObject *a, PyObject *b)
237 Py_ssize_t size;
238 Py_buffer va, vb;
239 PyByteArrayObject *result = NULL;
241 va.len = -1;
242 vb.len = -1;
243 if (_getbuffer(a, &va) < 0 ||
244 _getbuffer(b, &vb) < 0) {
245 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
246 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
247 goto done;
250 size = va.len + vb.len;
251 if (size < 0) {
252 PyErr_NoMemory();
253 goto done;
256 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
257 if (result != NULL) {
258 memcpy(result->ob_bytes, va.buf, va.len);
259 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
262 done:
263 if (va.len != -1)
264 PyBuffer_Release(&va);
265 if (vb.len != -1)
266 PyBuffer_Release(&vb);
267 return (PyObject *)result;
270 /* Functions stuffed into the type object */
272 static Py_ssize_t
273 bytearray_length(PyByteArrayObject *self)
275 return Py_SIZE(self);
278 static PyObject *
279 bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
281 Py_ssize_t mysize;
282 Py_ssize_t size;
283 Py_buffer vo;
285 if (_getbuffer(other, &vo) < 0) {
286 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
287 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
288 return NULL;
291 mysize = Py_SIZE(self);
292 size = mysize + vo.len;
293 if (size < 0) {
294 PyBuffer_Release(&vo);
295 return PyErr_NoMemory();
297 if (size < self->ob_alloc) {
298 Py_SIZE(self) = size;
299 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
301 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
302 PyBuffer_Release(&vo);
303 return NULL;
305 memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
306 PyBuffer_Release(&vo);
307 Py_INCREF(self);
308 return (PyObject *)self;
311 static PyObject *
312 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
314 PyByteArrayObject *result;
315 Py_ssize_t mysize;
316 Py_ssize_t size;
318 if (count < 0)
319 count = 0;
320 mysize = Py_SIZE(self);
321 size = mysize * count;
322 if (count != 0 && size / count != mysize)
323 return PyErr_NoMemory();
324 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
325 if (result != NULL && size != 0) {
326 if (mysize == 1)
327 memset(result->ob_bytes, self->ob_bytes[0], size);
328 else {
329 Py_ssize_t i;
330 for (i = 0; i < count; i++)
331 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
334 return (PyObject *)result;
337 static PyObject *
338 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
340 Py_ssize_t mysize;
341 Py_ssize_t size;
343 if (count < 0)
344 count = 0;
345 mysize = Py_SIZE(self);
346 size = mysize * count;
347 if (count != 0 && size / count != mysize)
348 return PyErr_NoMemory();
349 if (size < self->ob_alloc) {
350 Py_SIZE(self) = size;
351 self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
353 else if (PyByteArray_Resize((PyObject *)self, size) < 0)
354 return NULL;
356 if (mysize == 1)
357 memset(self->ob_bytes, self->ob_bytes[0], size);
358 else {
359 Py_ssize_t i;
360 for (i = 1; i < count; i++)
361 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
364 Py_INCREF(self);
365 return (PyObject *)self;
368 static PyObject *
369 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
371 if (i < 0)
372 i += Py_SIZE(self);
373 if (i < 0 || i >= Py_SIZE(self)) {
374 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
375 return NULL;
377 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
380 static PyObject *
381 bytearray_subscript(PyByteArrayObject *self, PyObject *index)
383 if (PyIndex_Check(index)) {
384 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
386 if (i == -1 && PyErr_Occurred())
387 return NULL;
389 if (i < 0)
390 i += PyByteArray_GET_SIZE(self);
392 if (i < 0 || i >= Py_SIZE(self)) {
393 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
394 return NULL;
396 return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
398 else if (PySlice_Check(index)) {
399 Py_ssize_t start, stop, step, slicelength, cur, i;
400 if (PySlice_GetIndicesEx((PySliceObject *)index,
401 PyByteArray_GET_SIZE(self),
402 &start, &stop, &step, &slicelength) < 0) {
403 return NULL;
406 if (slicelength <= 0)
407 return PyByteArray_FromStringAndSize("", 0);
408 else if (step == 1) {
409 return PyByteArray_FromStringAndSize(self->ob_bytes + start,
410 slicelength);
412 else {
413 char *source_buf = PyByteArray_AS_STRING(self);
414 char *result_buf;
415 PyObject *result;
417 result = PyByteArray_FromStringAndSize(NULL, slicelength);
418 if (result == NULL)
419 return NULL;
421 result_buf = PyByteArray_AS_STRING(result);
422 for (cur = start, i = 0; i < slicelength;
423 cur += step, i++) {
424 result_buf[i] = source_buf[cur];
426 return result;
429 else {
430 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
431 return NULL;
435 static int
436 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
437 PyObject *values)
439 Py_ssize_t avail, needed;
440 void *bytes;
441 Py_buffer vbytes;
442 int res = 0;
444 vbytes.len = -1;
445 if (values == (PyObject *)self) {
446 /* Make a copy and call this function recursively */
447 int err;
448 values = PyByteArray_FromObject(values);
449 if (values == NULL)
450 return -1;
451 err = bytearray_setslice(self, lo, hi, values);
452 Py_DECREF(values);
453 return err;
455 if (values == NULL) {
456 /* del b[lo:hi] */
457 bytes = NULL;
458 needed = 0;
460 else {
461 if (_getbuffer(values, &vbytes) < 0) {
462 PyErr_Format(PyExc_TypeError,
463 "can't set bytearray slice from %.100s",
464 Py_TYPE(values)->tp_name);
465 return -1;
467 needed = vbytes.len;
468 bytes = vbytes.buf;
471 if (lo < 0)
472 lo = 0;
473 if (hi < lo)
474 hi = lo;
475 if (hi > Py_SIZE(self))
476 hi = Py_SIZE(self);
478 avail = hi - lo;
479 if (avail < 0)
480 lo = hi = avail = 0;
482 if (avail != needed) {
483 if (avail > needed) {
484 if (!_canresize(self)) {
485 res = -1;
486 goto finish;
489 0 lo hi old_size
490 | |<----avail----->|<-----tomove------>|
491 | |<-needed->|<-----tomove------>|
492 0 lo new_hi new_size
494 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
495 Py_SIZE(self) - hi);
497 /* XXX(nnorwitz): need to verify this can't overflow! */
498 if (PyByteArray_Resize((PyObject *)self,
499 Py_SIZE(self) + needed - avail) < 0) {
500 res = -1;
501 goto finish;
503 if (avail < needed) {
505 0 lo hi old_size
506 | |<-avail->|<-----tomove------>|
507 | |<----needed---->|<-----tomove------>|
508 0 lo new_hi new_size
510 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
511 Py_SIZE(self) - lo - needed);
515 if (needed > 0)
516 memcpy(self->ob_bytes + lo, bytes, needed);
519 finish:
520 if (vbytes.len != -1)
521 PyBuffer_Release(&vbytes);
522 return res;
525 static int
526 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
528 int ival;
530 if (i < 0)
531 i += Py_SIZE(self);
533 if (i < 0 || i >= Py_SIZE(self)) {
534 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
535 return -1;
538 if (value == NULL)
539 return bytearray_setslice(self, i, i+1, NULL);
541 if (!_getbytevalue(value, &ival))
542 return -1;
544 self->ob_bytes[i] = ival;
545 return 0;
548 static int
549 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
551 Py_ssize_t start, stop, step, slicelen, needed;
552 char *bytes;
554 if (PyIndex_Check(index)) {
555 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
557 if (i == -1 && PyErr_Occurred())
558 return -1;
560 if (i < 0)
561 i += PyByteArray_GET_SIZE(self);
563 if (i < 0 || i >= Py_SIZE(self)) {
564 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
565 return -1;
568 if (values == NULL) {
569 /* Fall through to slice assignment */
570 start = i;
571 stop = i + 1;
572 step = 1;
573 slicelen = 1;
575 else {
576 int ival;
577 if (!_getbytevalue(values, &ival))
578 return -1;
579 self->ob_bytes[i] = (char)ival;
580 return 0;
583 else if (PySlice_Check(index)) {
584 if (PySlice_GetIndicesEx((PySliceObject *)index,
585 PyByteArray_GET_SIZE(self),
586 &start, &stop, &step, &slicelen) < 0) {
587 return -1;
590 else {
591 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
592 return -1;
595 if (values == NULL) {
596 bytes = NULL;
597 needed = 0;
599 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
600 /* Make a copy an call this function recursively */
601 int err;
602 values = PyByteArray_FromObject(values);
603 if (values == NULL)
604 return -1;
605 err = bytearray_ass_subscript(self, index, values);
606 Py_DECREF(values);
607 return err;
609 else {
610 assert(PyByteArray_Check(values));
611 bytes = ((PyByteArrayObject *)values)->ob_bytes;
612 needed = Py_SIZE(values);
614 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
615 if ((step < 0 && start < stop) ||
616 (step > 0 && start > stop))
617 stop = start;
618 if (step == 1) {
619 if (slicelen != needed) {
620 if (!_canresize(self))
621 return -1;
622 if (slicelen > needed) {
624 0 start stop old_size
625 | |<---slicelen--->|<-----tomove------>|
626 | |<-needed->|<-----tomove------>|
627 0 lo new_hi new_size
629 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
630 Py_SIZE(self) - stop);
632 if (PyByteArray_Resize((PyObject *)self,
633 Py_SIZE(self) + needed - slicelen) < 0)
634 return -1;
635 if (slicelen < needed) {
637 0 lo hi old_size
638 | |<-avail->|<-----tomove------>|
639 | |<----needed---->|<-----tomove------>|
640 0 lo new_hi new_size
642 memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
643 Py_SIZE(self) - start - needed);
647 if (needed > 0)
648 memcpy(self->ob_bytes + start, bytes, needed);
650 return 0;
652 else {
653 if (needed == 0) {
654 /* Delete slice */
655 Py_ssize_t cur, i;
657 if (!_canresize(self))
658 return -1;
659 if (step < 0) {
660 stop = start + 1;
661 start = stop + step * (slicelen - 1) - 1;
662 step = -step;
664 for (cur = start, i = 0;
665 i < slicelen; cur += step, i++) {
666 Py_ssize_t lim = step - 1;
668 if (cur + step >= PyByteArray_GET_SIZE(self))
669 lim = PyByteArray_GET_SIZE(self) - cur - 1;
671 memmove(self->ob_bytes + cur - i,
672 self->ob_bytes + cur + 1, lim);
674 /* Move the tail of the bytes, in one chunk */
675 cur = start + slicelen*step;
676 if (cur < PyByteArray_GET_SIZE(self)) {
677 memmove(self->ob_bytes + cur - slicelen,
678 self->ob_bytes + cur,
679 PyByteArray_GET_SIZE(self) - cur);
681 if (PyByteArray_Resize((PyObject *)self,
682 PyByteArray_GET_SIZE(self) - slicelen) < 0)
683 return -1;
685 return 0;
687 else {
688 /* Assign slice */
689 Py_ssize_t cur, i;
691 if (needed != slicelen) {
692 PyErr_Format(PyExc_ValueError,
693 "attempt to assign bytes of size %zd "
694 "to extended slice of size %zd",
695 needed, slicelen);
696 return -1;
698 for (cur = start, i = 0; i < slicelen; cur += step, i++)
699 self->ob_bytes[cur] = bytes[i];
700 return 0;
705 static int
706 bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
708 static char *kwlist[] = {"source", "encoding", "errors", 0};
709 PyObject *arg = NULL;
710 const char *encoding = NULL;
711 const char *errors = NULL;
712 Py_ssize_t count;
713 PyObject *it;
714 PyObject *(*iternext)(PyObject *);
716 if (Py_SIZE(self) != 0) {
717 /* Empty previous contents (yes, do this first of all!) */
718 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
719 return -1;
722 /* Parse arguments */
723 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
724 &arg, &encoding, &errors))
725 return -1;
727 /* Make a quick exit if no first argument */
728 if (arg == NULL) {
729 if (encoding != NULL || errors != NULL) {
730 PyErr_SetString(PyExc_TypeError,
731 "encoding or errors without sequence argument");
732 return -1;
734 return 0;
737 if (PyUnicode_Check(arg)) {
738 /* Encode via the codec registry */
739 PyObject *encoded, *new;
740 if (encoding == NULL) {
741 PyErr_SetString(PyExc_TypeError,
742 "string argument without an encoding");
743 return -1;
745 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
746 if (encoded == NULL)
747 return -1;
748 assert(PyBytes_Check(encoded));
749 new = bytearray_iconcat(self, encoded);
750 Py_DECREF(encoded);
751 if (new == NULL)
752 return -1;
753 Py_DECREF(new);
754 return 0;
757 /* If it's not unicode, there can't be encoding or errors */
758 if (encoding != NULL || errors != NULL) {
759 PyErr_SetString(PyExc_TypeError,
760 "encoding or errors without a string argument");
761 return -1;
764 /* Is it an int? */
765 count = PyNumber_AsSsize_t(arg, PyExc_ValueError);
766 if (count == -1 && PyErr_Occurred())
767 PyErr_Clear();
768 else {
769 if (count < 0) {
770 PyErr_SetString(PyExc_ValueError, "negative count");
771 return -1;
773 if (count > 0) {
774 if (PyByteArray_Resize((PyObject *)self, count))
775 return -1;
776 memset(self->ob_bytes, 0, count);
778 return 0;
781 /* Use the buffer API */
782 if (PyObject_CheckBuffer(arg)) {
783 Py_ssize_t size;
784 Py_buffer view;
785 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
786 return -1;
787 size = view.len;
788 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
789 if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
790 goto fail;
791 PyBuffer_Release(&view);
792 return 0;
793 fail:
794 PyBuffer_Release(&view);
795 return -1;
798 /* XXX Optimize this if the arguments is a list, tuple */
800 /* Get the iterator */
801 it = PyObject_GetIter(arg);
802 if (it == NULL)
803 return -1;
804 iternext = *Py_TYPE(it)->tp_iternext;
806 /* Run the iterator to exhaustion */
807 for (;;) {
808 PyObject *item;
809 int rc, value;
811 /* Get the next item */
812 item = iternext(it);
813 if (item == NULL) {
814 if (PyErr_Occurred()) {
815 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
816 goto error;
817 PyErr_Clear();
819 break;
822 /* Interpret it as an int (__index__) */
823 rc = _getbytevalue(item, &value);
824 Py_DECREF(item);
825 if (!rc)
826 goto error;
828 /* Append the byte */
829 if (Py_SIZE(self) < self->ob_alloc)
830 Py_SIZE(self)++;
831 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
832 goto error;
833 self->ob_bytes[Py_SIZE(self)-1] = value;
836 /* Clean up and return success */
837 Py_DECREF(it);
838 return 0;
840 error:
841 /* Error handling when it != NULL */
842 Py_DECREF(it);
843 return -1;
846 /* Mostly copied from string_repr, but without the
847 "smart quote" functionality. */
848 static PyObject *
849 bytearray_repr(PyByteArrayObject *self)
851 static const char *hexdigits = "0123456789abcdef";
852 const char *quote_prefix = "bytearray(b";
853 const char *quote_postfix = ")";
854 Py_ssize_t length = Py_SIZE(self);
855 /* 14 == strlen(quote_prefix) + 2 + strlen(quote_postfix) */
856 size_t newsize = 14 + 4 * length;
857 PyObject *v;
858 if (newsize > PY_SSIZE_T_MAX || newsize / 4 - 3 != length) {
859 PyErr_SetString(PyExc_OverflowError,
860 "bytearray object is too large to make repr");
861 return NULL;
863 v = PyUnicode_FromUnicode(NULL, newsize);
864 if (v == NULL) {
865 return NULL;
867 else {
868 register Py_ssize_t i;
869 register Py_UNICODE c;
870 register Py_UNICODE *p;
871 int quote;
873 /* Figure out which quote to use; single is preferred */
874 quote = '\'';
876 char *test, *start;
877 start = PyByteArray_AS_STRING(self);
878 for (test = start; test < start+length; ++test) {
879 if (*test == '"') {
880 quote = '\''; /* back to single */
881 goto decided;
883 else if (*test == '\'')
884 quote = '"';
886 decided:
890 p = PyUnicode_AS_UNICODE(v);
891 while (*quote_prefix)
892 *p++ = *quote_prefix++;
893 *p++ = quote;
895 for (i = 0; i < length; i++) {
896 /* There's at least enough room for a hex escape
897 and a closing quote. */
898 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
899 c = self->ob_bytes[i];
900 if (c == '\'' || c == '\\')
901 *p++ = '\\', *p++ = c;
902 else if (c == '\t')
903 *p++ = '\\', *p++ = 't';
904 else if (c == '\n')
905 *p++ = '\\', *p++ = 'n';
906 else if (c == '\r')
907 *p++ = '\\', *p++ = 'r';
908 else if (c == 0)
909 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
910 else if (c < ' ' || c >= 0x7f) {
911 *p++ = '\\';
912 *p++ = 'x';
913 *p++ = hexdigits[(c & 0xf0) >> 4];
914 *p++ = hexdigits[c & 0xf];
916 else
917 *p++ = c;
919 assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
920 *p++ = quote;
921 while (*quote_postfix) {
922 *p++ = *quote_postfix++;
924 *p = '\0';
925 if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
926 Py_DECREF(v);
927 return NULL;
929 return v;
933 static PyObject *
934 bytearray_str(PyObject *op)
936 if (Py_BytesWarningFlag) {
937 if (PyErr_WarnEx(PyExc_BytesWarning,
938 "str() on a bytearray instance", 1))
939 return NULL;
941 return bytearray_repr((PyByteArrayObject*)op);
944 static PyObject *
945 bytearray_richcompare(PyObject *self, PyObject *other, int op)
947 Py_ssize_t self_size, other_size;
948 Py_buffer self_bytes, other_bytes;
949 PyObject *res;
950 Py_ssize_t minsize;
951 int cmp;
953 /* Bytes can be compared to anything that supports the (binary)
954 buffer API. Except that a comparison with Unicode is always an
955 error, even if the comparison is for equality. */
956 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
957 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
958 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
959 if (PyErr_WarnEx(PyExc_BytesWarning,
960 "Comparison between bytearray and string", 1))
961 return NULL;
964 Py_INCREF(Py_NotImplemented);
965 return Py_NotImplemented;
968 self_size = _getbuffer(self, &self_bytes);
969 if (self_size < 0) {
970 PyErr_Clear();
971 Py_INCREF(Py_NotImplemented);
972 return Py_NotImplemented;
975 other_size = _getbuffer(other, &other_bytes);
976 if (other_size < 0) {
977 PyErr_Clear();
978 PyBuffer_Release(&self_bytes);
979 Py_INCREF(Py_NotImplemented);
980 return Py_NotImplemented;
983 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
984 /* Shortcut: if the lengths differ, the objects differ */
985 cmp = (op == Py_NE);
987 else {
988 minsize = self_size;
989 if (other_size < minsize)
990 minsize = other_size;
992 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
993 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
995 if (cmp == 0) {
996 if (self_size < other_size)
997 cmp = -1;
998 else if (self_size > other_size)
999 cmp = 1;
1002 switch (op) {
1003 case Py_LT: cmp = cmp < 0; break;
1004 case Py_LE: cmp = cmp <= 0; break;
1005 case Py_EQ: cmp = cmp == 0; break;
1006 case Py_NE: cmp = cmp != 0; break;
1007 case Py_GT: cmp = cmp > 0; break;
1008 case Py_GE: cmp = cmp >= 0; break;
1012 res = cmp ? Py_True : Py_False;
1013 PyBuffer_Release(&self_bytes);
1014 PyBuffer_Release(&other_bytes);
1015 Py_INCREF(res);
1016 return res;
1019 static void
1020 bytearray_dealloc(PyByteArrayObject *self)
1022 if (self->ob_exports > 0) {
1023 PyErr_SetString(PyExc_SystemError,
1024 "deallocated bytearray object has exported buffers");
1025 PyErr_Print();
1027 if (self->ob_bytes != 0) {
1028 PyMem_Free(self->ob_bytes);
1030 Py_TYPE(self)->tp_free((PyObject *)self);
1034 /* -------------------------------------------------------------------- */
1035 /* Methods */
1037 #define STRINGLIB_CHAR char
1038 #define STRINGLIB_CMP memcmp
1039 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1040 #define STRINGLIB_STR PyByteArray_AS_STRING
1041 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1042 #define STRINGLIB_EMPTY nullbytes
1043 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1044 #define STRINGLIB_MUTABLE 1
1045 #define FROM_BYTEARRAY 1
1047 #include "stringlib/fastsearch.h"
1048 #include "stringlib/count.h"
1049 #include "stringlib/find.h"
1050 #include "stringlib/partition.h"
1051 #include "stringlib/ctype.h"
1052 #include "stringlib/transmogrify.h"
1055 /* The following Py_LOCAL_INLINE and Py_LOCAL functions
1056 were copied from the old char* style string object. */
1058 Py_LOCAL_INLINE(void)
1059 _adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
1061 if (*end > len)
1062 *end = len;
1063 else if (*end < 0)
1064 *end += len;
1065 if (*end < 0)
1066 *end = 0;
1067 if (*start < 0)
1068 *start += len;
1069 if (*start < 0)
1070 *start = 0;
1074 Py_LOCAL_INLINE(Py_ssize_t)
1075 bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
1077 PyObject *subobj;
1078 Py_buffer subbuf;
1079 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1080 Py_ssize_t res;
1082 if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex", &subobj,
1083 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1084 return -2;
1085 if (_getbuffer(subobj, &subbuf) < 0)
1086 return -2;
1087 if (dir > 0)
1088 res = stringlib_find_slice(
1089 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1090 subbuf.buf, subbuf.len, start, end);
1091 else
1092 res = stringlib_rfind_slice(
1093 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1094 subbuf.buf, subbuf.len, start, end);
1095 PyBuffer_Release(&subbuf);
1096 return res;
1099 PyDoc_STRVAR(find__doc__,
1100 "B.find(sub[, start[, end]]) -> int\n\
1102 Return the lowest index in B where subsection sub is found,\n\
1103 such that sub is contained within s[start,end]. Optional\n\
1104 arguments start and end are interpreted as in slice notation.\n\
1106 Return -1 on failure.");
1108 static PyObject *
1109 bytearray_find(PyByteArrayObject *self, PyObject *args)
1111 Py_ssize_t result = bytearray_find_internal(self, args, +1);
1112 if (result == -2)
1113 return NULL;
1114 return PyLong_FromSsize_t(result);
1117 PyDoc_STRVAR(count__doc__,
1118 "B.count(sub[, start[, end]]) -> int\n\
1120 Return the number of non-overlapping occurrences of subsection sub in\n\
1121 bytes B[start:end]. Optional arguments start and end are interpreted\n\
1122 as in slice notation.");
1124 static PyObject *
1125 bytearray_count(PyByteArrayObject *self, PyObject *args)
1127 PyObject *sub_obj;
1128 const char *str = PyByteArray_AS_STRING(self);
1129 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
1130 Py_buffer vsub;
1131 PyObject *count_obj;
1133 if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
1134 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1135 return NULL;
1137 if (_getbuffer(sub_obj, &vsub) < 0)
1138 return NULL;
1140 _adjust_indices(&start, &end, PyByteArray_GET_SIZE(self));
1142 count_obj = PyLong_FromSsize_t(
1143 stringlib_count(str + start, end - start, vsub.buf, vsub.len)
1145 PyBuffer_Release(&vsub);
1146 return count_obj;
1150 PyDoc_STRVAR(index__doc__,
1151 "B.index(sub[, start[, end]]) -> int\n\
1153 Like B.find() but raise ValueError when the subsection is not found.");
1155 static PyObject *
1156 bytearray_index(PyByteArrayObject *self, PyObject *args)
1158 Py_ssize_t result = bytearray_find_internal(self, args, +1);
1159 if (result == -2)
1160 return NULL;
1161 if (result == -1) {
1162 PyErr_SetString(PyExc_ValueError,
1163 "subsection not found");
1164 return NULL;
1166 return PyLong_FromSsize_t(result);
1170 PyDoc_STRVAR(rfind__doc__,
1171 "B.rfind(sub[, start[, end]]) -> int\n\
1173 Return the highest index in B where subsection sub is found,\n\
1174 such that sub is contained within s[start,end]. Optional\n\
1175 arguments start and end are interpreted as in slice notation.\n\
1177 Return -1 on failure.");
1179 static PyObject *
1180 bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1182 Py_ssize_t result = bytearray_find_internal(self, args, -1);
1183 if (result == -2)
1184 return NULL;
1185 return PyLong_FromSsize_t(result);
1189 PyDoc_STRVAR(rindex__doc__,
1190 "B.rindex(sub[, start[, end]]) -> int\n\
1192 Like B.rfind() but raise ValueError when the subsection is not found.");
1194 static PyObject *
1195 bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1197 Py_ssize_t result = bytearray_find_internal(self, args, -1);
1198 if (result == -2)
1199 return NULL;
1200 if (result == -1) {
1201 PyErr_SetString(PyExc_ValueError,
1202 "subsection not found");
1203 return NULL;
1205 return PyLong_FromSsize_t(result);
1209 static int
1210 bytearray_contains(PyObject *self, PyObject *arg)
1212 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1213 if (ival == -1 && PyErr_Occurred()) {
1214 Py_buffer varg;
1215 int pos;
1216 PyErr_Clear();
1217 if (_getbuffer(arg, &varg) < 0)
1218 return -1;
1219 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1220 varg.buf, varg.len, 0);
1221 PyBuffer_Release(&varg);
1222 return pos >= 0;
1224 if (ival < 0 || ival >= 256) {
1225 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1226 return -1;
1229 return memchr(PyByteArray_AS_STRING(self), ival, Py_SIZE(self)) != NULL;
1233 /* Matches the end (direction >= 0) or start (direction < 0) of self
1234 * against substr, using the start and end arguments. Returns
1235 * -1 on error, 0 if not found and 1 if found.
1237 Py_LOCAL(int)
1238 _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
1239 Py_ssize_t end, int direction)
1241 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1242 const char* str;
1243 Py_buffer vsubstr;
1244 int rv = 0;
1246 str = PyByteArray_AS_STRING(self);
1248 if (_getbuffer(substr, &vsubstr) < 0)
1249 return -1;
1251 _adjust_indices(&start, &end, len);
1253 if (direction < 0) {
1254 /* startswith */
1255 if (start+vsubstr.len > len) {
1256 goto done;
1258 } else {
1259 /* endswith */
1260 if (end-start < vsubstr.len || start > len) {
1261 goto done;
1264 if (end-vsubstr.len > start)
1265 start = end - vsubstr.len;
1267 if (end-start >= vsubstr.len)
1268 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1270 done:
1271 PyBuffer_Release(&vsubstr);
1272 return rv;
1276 PyDoc_STRVAR(startswith__doc__,
1277 "B.startswith(prefix[, start[, end]]) -> bool\n\
1279 Return True if B starts with the specified prefix, False otherwise.\n\
1280 With optional start, test B beginning at that position.\n\
1281 With optional end, stop comparing B at that position.\n\
1282 prefix can also be a tuple of strings to try.");
1284 static PyObject *
1285 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1287 Py_ssize_t start = 0;
1288 Py_ssize_t end = PY_SSIZE_T_MAX;
1289 PyObject *subobj;
1290 int result;
1292 if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
1293 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1294 return NULL;
1295 if (PyTuple_Check(subobj)) {
1296 Py_ssize_t i;
1297 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1298 result = _bytearray_tailmatch(self,
1299 PyTuple_GET_ITEM(subobj, i),
1300 start, end, -1);
1301 if (result == -1)
1302 return NULL;
1303 else if (result) {
1304 Py_RETURN_TRUE;
1307 Py_RETURN_FALSE;
1309 result = _bytearray_tailmatch(self, subobj, start, end, -1);
1310 if (result == -1)
1311 return NULL;
1312 else
1313 return PyBool_FromLong(result);
1316 PyDoc_STRVAR(endswith__doc__,
1317 "B.endswith(suffix[, start[, end]]) -> bool\n\
1319 Return True if B ends with the specified suffix, False otherwise.\n\
1320 With optional start, test B beginning at that position.\n\
1321 With optional end, stop comparing B at that position.\n\
1322 suffix can also be a tuple of strings to try.");
1324 static PyObject *
1325 bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1327 Py_ssize_t start = 0;
1328 Py_ssize_t end = PY_SSIZE_T_MAX;
1329 PyObject *subobj;
1330 int result;
1332 if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
1333 _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
1334 return NULL;
1335 if (PyTuple_Check(subobj)) {
1336 Py_ssize_t i;
1337 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
1338 result = _bytearray_tailmatch(self,
1339 PyTuple_GET_ITEM(subobj, i),
1340 start, end, +1);
1341 if (result == -1)
1342 return NULL;
1343 else if (result) {
1344 Py_RETURN_TRUE;
1347 Py_RETURN_FALSE;
1349 result = _bytearray_tailmatch(self, subobj, start, end, +1);
1350 if (result == -1)
1351 return NULL;
1352 else
1353 return PyBool_FromLong(result);
1357 PyDoc_STRVAR(translate__doc__,
1358 "B.translate(table[, deletechars]) -> bytearray\n\
1360 Return a copy of B, where all characters occurring in the\n\
1361 optional argument deletechars are removed, and the remaining\n\
1362 characters have been mapped through the given translation\n\
1363 table, which must be a bytes object of length 256.");
1365 static PyObject *
1366 bytearray_translate(PyByteArrayObject *self, PyObject *args)
1368 register char *input, *output;
1369 register const char *table;
1370 register Py_ssize_t i, c;
1371 PyObject *input_obj = (PyObject*)self;
1372 const char *output_start;
1373 Py_ssize_t inlen;
1374 PyObject *result = NULL;
1375 int trans_table[256];
1376 PyObject *tableobj = NULL, *delobj = NULL;
1377 Py_buffer vtable, vdel;
1379 if (!PyArg_UnpackTuple(args, "translate", 1, 2,
1380 &tableobj, &delobj))
1381 return NULL;
1383 if (tableobj == Py_None) {
1384 table = NULL;
1385 tableobj = NULL;
1386 } else if (_getbuffer(tableobj, &vtable) < 0) {
1387 return NULL;
1388 } else {
1389 if (vtable.len != 256) {
1390 PyErr_SetString(PyExc_ValueError,
1391 "translation table must be 256 characters long");
1392 goto done;
1394 table = (const char*)vtable.buf;
1397 if (delobj != NULL) {
1398 if (_getbuffer(delobj, &vdel) < 0) {
1399 delobj = NULL; /* don't try to release vdel buffer on exit */
1400 goto done;
1403 else {
1404 vdel.buf = NULL;
1405 vdel.len = 0;
1408 inlen = PyByteArray_GET_SIZE(input_obj);
1409 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1410 if (result == NULL)
1411 goto done;
1412 output_start = output = PyByteArray_AsString(result);
1413 input = PyByteArray_AS_STRING(input_obj);
1415 if (vdel.len == 0 && table != NULL) {
1416 /* If no deletions are required, use faster code */
1417 for (i = inlen; --i >= 0; ) {
1418 c = Py_CHARMASK(*input++);
1419 *output++ = table[c];
1421 goto done;
1424 if (table == NULL) {
1425 for (i = 0; i < 256; i++)
1426 trans_table[i] = Py_CHARMASK(i);
1427 } else {
1428 for (i = 0; i < 256; i++)
1429 trans_table[i] = Py_CHARMASK(table[i]);
1432 for (i = 0; i < vdel.len; i++)
1433 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1435 for (i = inlen; --i >= 0; ) {
1436 c = Py_CHARMASK(*input++);
1437 if (trans_table[c] != -1)
1438 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1439 continue;
1441 /* Fix the size of the resulting string */
1442 if (inlen > 0)
1443 PyByteArray_Resize(result, output - output_start);
1445 done:
1446 if (tableobj != NULL)
1447 PyBuffer_Release(&vtable);
1448 if (delobj != NULL)
1449 PyBuffer_Release(&vdel);
1450 return result;
1454 static PyObject *
1455 bytearray_maketrans(PyObject *null, PyObject *args)
1457 return _Py_bytes_maketrans(args);
1461 #define FORWARD 1
1462 #define REVERSE -1
1464 /* find and count characters and substrings */
1466 #define findchar(target, target_len, c) \
1467 ((char *)memchr((const void *)(target), c, target_len))
1469 /* Don't call if length < 2 */
1470 #define Py_STRING_MATCH(target, offset, pattern, length) \
1471 (target[offset] == pattern[0] && \
1472 target[offset+length-1] == pattern[length-1] && \
1473 !memcmp(target+offset+1, pattern+1, length-2) )
1476 /* Bytes ops must return a string, create a copy */
1477 Py_LOCAL(PyByteArrayObject *)
1478 return_self(PyByteArrayObject *self)
1480 /* always return a new bytearray */
1481 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1482 PyByteArray_AS_STRING(self),
1483 PyByteArray_GET_SIZE(self));
1486 Py_LOCAL_INLINE(Py_ssize_t)
1487 countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1489 Py_ssize_t count=0;
1490 const char *start=target;
1491 const char *end=target+target_len;
1493 while ( (start=findchar(start, end-start, c)) != NULL ) {
1494 count++;
1495 if (count >= maxcount)
1496 break;
1497 start += 1;
1499 return count;
1502 Py_LOCAL(Py_ssize_t)
1503 findstring(const char *target, Py_ssize_t target_len,
1504 const char *pattern, Py_ssize_t pattern_len,
1505 Py_ssize_t start,
1506 Py_ssize_t end,
1507 int direction)
1509 if (start < 0) {
1510 start += target_len;
1511 if (start < 0)
1512 start = 0;
1514 if (end > target_len) {
1515 end = target_len;
1516 } else if (end < 0) {
1517 end += target_len;
1518 if (end < 0)
1519 end = 0;
1522 /* zero-length substrings always match at the first attempt */
1523 if (pattern_len == 0)
1524 return (direction > 0) ? start : end;
1526 end -= pattern_len;
1528 if (direction < 0) {
1529 for (; end >= start; end--)
1530 if (Py_STRING_MATCH(target, end, pattern, pattern_len))
1531 return end;
1532 } else {
1533 for (; start <= end; start++)
1534 if (Py_STRING_MATCH(target, start, pattern, pattern_len))
1535 return start;
1537 return -1;
1540 Py_LOCAL_INLINE(Py_ssize_t)
1541 countstring(const char *target, Py_ssize_t target_len,
1542 const char *pattern, Py_ssize_t pattern_len,
1543 Py_ssize_t start,
1544 Py_ssize_t end,
1545 int direction, Py_ssize_t maxcount)
1547 Py_ssize_t count=0;
1549 if (start < 0) {
1550 start += target_len;
1551 if (start < 0)
1552 start = 0;
1554 if (end > target_len) {
1555 end = target_len;
1556 } else if (end < 0) {
1557 end += target_len;
1558 if (end < 0)
1559 end = 0;
1562 /* zero-length substrings match everywhere */
1563 if (pattern_len == 0 || maxcount == 0) {
1564 if (target_len+1 < maxcount)
1565 return target_len+1;
1566 return maxcount;
1569 end -= pattern_len;
1570 if (direction < 0) {
1571 for (; (end >= start); end--)
1572 if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
1573 count++;
1574 if (--maxcount <= 0) break;
1575 end -= pattern_len-1;
1577 } else {
1578 for (; (start <= end); start++)
1579 if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
1580 count++;
1581 if (--maxcount <= 0)
1582 break;
1583 start += pattern_len-1;
1586 return count;
1590 /* Algorithms for different cases of string replacement */
1592 /* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1593 Py_LOCAL(PyByteArrayObject *)
1594 replace_interleave(PyByteArrayObject *self,
1595 const char *to_s, Py_ssize_t to_len,
1596 Py_ssize_t maxcount)
1598 char *self_s, *result_s;
1599 Py_ssize_t self_len, result_len;
1600 Py_ssize_t count, i, product;
1601 PyByteArrayObject *result;
1603 self_len = PyByteArray_GET_SIZE(self);
1605 /* 1 at the end plus 1 after every character */
1606 count = self_len+1;
1607 if (maxcount < count)
1608 count = maxcount;
1610 /* Check for overflow */
1611 /* result_len = count * to_len + self_len; */
1612 product = count * to_len;
1613 if (product / to_len != count) {
1614 PyErr_SetString(PyExc_OverflowError,
1615 "replace string is too long");
1616 return NULL;
1618 result_len = product + self_len;
1619 if (result_len < 0) {
1620 PyErr_SetString(PyExc_OverflowError,
1621 "replace string is too long");
1622 return NULL;
1625 if (! (result = (PyByteArrayObject *)
1626 PyByteArray_FromStringAndSize(NULL, result_len)) )
1627 return NULL;
1629 self_s = PyByteArray_AS_STRING(self);
1630 result_s = PyByteArray_AS_STRING(result);
1632 /* TODO: special case single character, which doesn't need memcpy */
1634 /* Lay the first one down (guaranteed this will occur) */
1635 Py_MEMCPY(result_s, to_s, to_len);
1636 result_s += to_len;
1637 count -= 1;
1639 for (i=0; i<count; i++) {
1640 *result_s++ = *self_s++;
1641 Py_MEMCPY(result_s, to_s, to_len);
1642 result_s += to_len;
1645 /* Copy the rest of the original string */
1646 Py_MEMCPY(result_s, self_s, self_len-i);
1648 return result;
1651 /* Special case for deleting a single character */
1652 /* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1653 Py_LOCAL(PyByteArrayObject *)
1654 replace_delete_single_character(PyByteArrayObject *self,
1655 char from_c, Py_ssize_t maxcount)
1657 char *self_s, *result_s;
1658 char *start, *next, *end;
1659 Py_ssize_t self_len, result_len;
1660 Py_ssize_t count;
1661 PyByteArrayObject *result;
1663 self_len = PyByteArray_GET_SIZE(self);
1664 self_s = PyByteArray_AS_STRING(self);
1666 count = countchar(self_s, self_len, from_c, maxcount);
1667 if (count == 0) {
1668 return return_self(self);
1671 result_len = self_len - count; /* from_len == 1 */
1672 assert(result_len>=0);
1674 if ( (result = (PyByteArrayObject *)
1675 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1676 return NULL;
1677 result_s = PyByteArray_AS_STRING(result);
1679 start = self_s;
1680 end = self_s + self_len;
1681 while (count-- > 0) {
1682 next = findchar(start, end-start, from_c);
1683 if (next == NULL)
1684 break;
1685 Py_MEMCPY(result_s, start, next-start);
1686 result_s += (next-start);
1687 start = next+1;
1689 Py_MEMCPY(result_s, start, end-start);
1691 return result;
1694 /* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1696 Py_LOCAL(PyByteArrayObject *)
1697 replace_delete_substring(PyByteArrayObject *self,
1698 const char *from_s, Py_ssize_t from_len,
1699 Py_ssize_t maxcount)
1701 char *self_s, *result_s;
1702 char *start, *next, *end;
1703 Py_ssize_t self_len, result_len;
1704 Py_ssize_t count, offset;
1705 PyByteArrayObject *result;
1707 self_len = PyByteArray_GET_SIZE(self);
1708 self_s = PyByteArray_AS_STRING(self);
1710 count = countstring(self_s, self_len,
1711 from_s, from_len,
1712 0, self_len, 1,
1713 maxcount);
1715 if (count == 0) {
1716 /* no matches */
1717 return return_self(self);
1720 result_len = self_len - (count * from_len);
1721 assert (result_len>=0);
1723 if ( (result = (PyByteArrayObject *)
1724 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1725 return NULL;
1727 result_s = PyByteArray_AS_STRING(result);
1729 start = self_s;
1730 end = self_s + self_len;
1731 while (count-- > 0) {
1732 offset = findstring(start, end-start,
1733 from_s, from_len,
1734 0, end-start, FORWARD);
1735 if (offset == -1)
1736 break;
1737 next = start + offset;
1739 Py_MEMCPY(result_s, start, next-start);
1741 result_s += (next-start);
1742 start = next+from_len;
1744 Py_MEMCPY(result_s, start, end-start);
1745 return result;
1748 /* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1749 Py_LOCAL(PyByteArrayObject *)
1750 replace_single_character_in_place(PyByteArrayObject *self,
1751 char from_c, char to_c,
1752 Py_ssize_t maxcount)
1754 char *self_s, *result_s, *start, *end, *next;
1755 Py_ssize_t self_len;
1756 PyByteArrayObject *result;
1758 /* The result string will be the same size */
1759 self_s = PyByteArray_AS_STRING(self);
1760 self_len = PyByteArray_GET_SIZE(self);
1762 next = findchar(self_s, self_len, from_c);
1764 if (next == NULL) {
1765 /* No matches; return the original bytes */
1766 return return_self(self);
1769 /* Need to make a new bytes */
1770 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1771 if (result == NULL)
1772 return NULL;
1773 result_s = PyByteArray_AS_STRING(result);
1774 Py_MEMCPY(result_s, self_s, self_len);
1776 /* change everything in-place, starting with this one */
1777 start = result_s + (next-self_s);
1778 *start = to_c;
1779 start++;
1780 end = result_s + self_len;
1782 while (--maxcount > 0) {
1783 next = findchar(start, end-start, from_c);
1784 if (next == NULL)
1785 break;
1786 *next = to_c;
1787 start = next+1;
1790 return result;
1793 /* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1794 Py_LOCAL(PyByteArrayObject *)
1795 replace_substring_in_place(PyByteArrayObject *self,
1796 const char *from_s, Py_ssize_t from_len,
1797 const char *to_s, Py_ssize_t to_len,
1798 Py_ssize_t maxcount)
1800 char *result_s, *start, *end;
1801 char *self_s;
1802 Py_ssize_t self_len, offset;
1803 PyByteArrayObject *result;
1805 /* The result bytes will be the same size */
1807 self_s = PyByteArray_AS_STRING(self);
1808 self_len = PyByteArray_GET_SIZE(self);
1810 offset = findstring(self_s, self_len,
1811 from_s, from_len,
1812 0, self_len, FORWARD);
1813 if (offset == -1) {
1814 /* No matches; return the original bytes */
1815 return return_self(self);
1818 /* Need to make a new bytes */
1819 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1820 if (result == NULL)
1821 return NULL;
1822 result_s = PyByteArray_AS_STRING(result);
1823 Py_MEMCPY(result_s, self_s, self_len);
1825 /* change everything in-place, starting with this one */
1826 start = result_s + offset;
1827 Py_MEMCPY(start, to_s, from_len);
1828 start += from_len;
1829 end = result_s + self_len;
1831 while ( --maxcount > 0) {
1832 offset = findstring(start, end-start,
1833 from_s, from_len,
1834 0, end-start, FORWARD);
1835 if (offset==-1)
1836 break;
1837 Py_MEMCPY(start+offset, to_s, from_len);
1838 start += offset+from_len;
1841 return result;
1844 /* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
1845 Py_LOCAL(PyByteArrayObject *)
1846 replace_single_character(PyByteArrayObject *self,
1847 char from_c,
1848 const char *to_s, Py_ssize_t to_len,
1849 Py_ssize_t maxcount)
1851 char *self_s, *result_s;
1852 char *start, *next, *end;
1853 Py_ssize_t self_len, result_len;
1854 Py_ssize_t count, product;
1855 PyByteArrayObject *result;
1857 self_s = PyByteArray_AS_STRING(self);
1858 self_len = PyByteArray_GET_SIZE(self);
1860 count = countchar(self_s, self_len, from_c, maxcount);
1861 if (count == 0) {
1862 /* no matches, return unchanged */
1863 return return_self(self);
1866 /* use the difference between current and new, hence the "-1" */
1867 /* result_len = self_len + count * (to_len-1) */
1868 product = count * (to_len-1);
1869 if (product / (to_len-1) != count) {
1870 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1871 return NULL;
1873 result_len = self_len + product;
1874 if (result_len < 0) {
1875 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1876 return NULL;
1879 if ( (result = (PyByteArrayObject *)
1880 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1881 return NULL;
1882 result_s = PyByteArray_AS_STRING(result);
1884 start = self_s;
1885 end = self_s + self_len;
1886 while (count-- > 0) {
1887 next = findchar(start, end-start, from_c);
1888 if (next == NULL)
1889 break;
1891 if (next == start) {
1892 /* replace with the 'to' */
1893 Py_MEMCPY(result_s, to_s, to_len);
1894 result_s += to_len;
1895 start += 1;
1896 } else {
1897 /* copy the unchanged old then the 'to' */
1898 Py_MEMCPY(result_s, start, next-start);
1899 result_s += (next-start);
1900 Py_MEMCPY(result_s, to_s, to_len);
1901 result_s += to_len;
1902 start = next+1;
1905 /* Copy the remainder of the remaining bytes */
1906 Py_MEMCPY(result_s, start, end-start);
1908 return result;
1911 /* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
1912 Py_LOCAL(PyByteArrayObject *)
1913 replace_substring(PyByteArrayObject *self,
1914 const char *from_s, Py_ssize_t from_len,
1915 const char *to_s, Py_ssize_t to_len,
1916 Py_ssize_t maxcount)
1918 char *self_s, *result_s;
1919 char *start, *next, *end;
1920 Py_ssize_t self_len, result_len;
1921 Py_ssize_t count, offset, product;
1922 PyByteArrayObject *result;
1924 self_s = PyByteArray_AS_STRING(self);
1925 self_len = PyByteArray_GET_SIZE(self);
1927 count = countstring(self_s, self_len,
1928 from_s, from_len,
1929 0, self_len, FORWARD, maxcount);
1930 if (count == 0) {
1931 /* no matches, return unchanged */
1932 return return_self(self);
1935 /* Check for overflow */
1936 /* result_len = self_len + count * (to_len-from_len) */
1937 product = count * (to_len-from_len);
1938 if (product / (to_len-from_len) != count) {
1939 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1940 return NULL;
1942 result_len = self_len + product;
1943 if (result_len < 0) {
1944 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
1945 return NULL;
1948 if ( (result = (PyByteArrayObject *)
1949 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1950 return NULL;
1951 result_s = PyByteArray_AS_STRING(result);
1953 start = self_s;
1954 end = self_s + self_len;
1955 while (count-- > 0) {
1956 offset = findstring(start, end-start,
1957 from_s, from_len,
1958 0, end-start, FORWARD);
1959 if (offset == -1)
1960 break;
1961 next = start+offset;
1962 if (next == start) {
1963 /* replace with the 'to' */
1964 Py_MEMCPY(result_s, to_s, to_len);
1965 result_s += to_len;
1966 start += from_len;
1967 } else {
1968 /* copy the unchanged old then the 'to' */
1969 Py_MEMCPY(result_s, start, next-start);
1970 result_s += (next-start);
1971 Py_MEMCPY(result_s, to_s, to_len);
1972 result_s += to_len;
1973 start = next+from_len;
1976 /* Copy the remainder of the remaining bytes */
1977 Py_MEMCPY(result_s, start, end-start);
1979 return result;
1983 Py_LOCAL(PyByteArrayObject *)
1984 replace(PyByteArrayObject *self,
1985 const char *from_s, Py_ssize_t from_len,
1986 const char *to_s, Py_ssize_t to_len,
1987 Py_ssize_t maxcount)
1989 if (maxcount < 0) {
1990 maxcount = PY_SSIZE_T_MAX;
1991 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
1992 /* nothing to do; return the original bytes */
1993 return return_self(self);
1996 if (maxcount == 0 ||
1997 (from_len == 0 && to_len == 0)) {
1998 /* nothing to do; return the original bytes */
1999 return return_self(self);
2002 /* Handle zero-length special cases */
2004 if (from_len == 0) {
2005 /* insert the 'to' bytes everywhere. */
2006 /* >>> "Python".replace("", ".") */
2007 /* '.P.y.t.h.o.n.' */
2008 return replace_interleave(self, to_s, to_len, maxcount);
2011 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2012 /* point for an empty self bytes to generate a non-empty bytes */
2013 /* Special case so the remaining code always gets a non-empty bytes */
2014 if (PyByteArray_GET_SIZE(self) == 0) {
2015 return return_self(self);
2018 if (to_len == 0) {
2019 /* delete all occurrences of 'from' bytes */
2020 if (from_len == 1) {
2021 return replace_delete_single_character(
2022 self, from_s[0], maxcount);
2023 } else {
2024 return replace_delete_substring(self, from_s, from_len, maxcount);
2028 /* Handle special case where both bytes have the same length */
2030 if (from_len == to_len) {
2031 if (from_len == 1) {
2032 return replace_single_character_in_place(
2033 self,
2034 from_s[0],
2035 to_s[0],
2036 maxcount);
2037 } else {
2038 return replace_substring_in_place(
2039 self, from_s, from_len, to_s, to_len, maxcount);
2043 /* Otherwise use the more generic algorithms */
2044 if (from_len == 1) {
2045 return replace_single_character(self, from_s[0],
2046 to_s, to_len, maxcount);
2047 } else {
2048 /* len('from')>=2, len('to')>=1 */
2049 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2054 PyDoc_STRVAR(replace__doc__,
2055 "B.replace(old, new[, count]) -> bytearray\n\
2057 Return a copy of B with all occurrences of subsection\n\
2058 old replaced by new. If the optional argument count is\n\
2059 given, only the first count occurrences are replaced.");
2061 static PyObject *
2062 bytearray_replace(PyByteArrayObject *self, PyObject *args)
2064 Py_ssize_t count = -1;
2065 PyObject *from, *to, *res;
2066 Py_buffer vfrom, vto;
2068 if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
2069 return NULL;
2071 if (_getbuffer(from, &vfrom) < 0)
2072 return NULL;
2073 if (_getbuffer(to, &vto) < 0) {
2074 PyBuffer_Release(&vfrom);
2075 return NULL;
2078 res = (PyObject *)replace((PyByteArrayObject *) self,
2079 vfrom.buf, vfrom.len,
2080 vto.buf, vto.len, count);
2082 PyBuffer_Release(&vfrom);
2083 PyBuffer_Release(&vto);
2084 return res;
2088 /* Overallocate the initial list to reduce the number of reallocs for small
2089 split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
2090 resizes, to sizes 4, 8, then 16. Most observed string splits are for human
2091 text (roughly 11 words per line) and field delimited data (usually 1-10
2092 fields). For large strings the split algorithms are bandwidth limited
2093 so increasing the preallocation likely will not improve things.*/
2095 #define MAX_PREALLOC 12
2097 /* 5 splits gives 6 elements */
2098 #define PREALLOC_SIZE(maxsplit) \
2099 (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
2101 #define SPLIT_APPEND(data, left, right) \
2102 str = PyByteArray_FromStringAndSize((data) + (left), \
2103 (right) - (left)); \
2104 if (str == NULL) \
2105 goto onError; \
2106 if (PyList_Append(list, str)) { \
2107 Py_DECREF(str); \
2108 goto onError; \
2110 else \
2111 Py_DECREF(str);
2113 #define SPLIT_ADD(data, left, right) { \
2114 str = PyByteArray_FromStringAndSize((data) + (left), \
2115 (right) - (left)); \
2116 if (str == NULL) \
2117 goto onError; \
2118 if (count < MAX_PREALLOC) { \
2119 PyList_SET_ITEM(list, count, str); \
2120 } else { \
2121 if (PyList_Append(list, str)) { \
2122 Py_DECREF(str); \
2123 goto onError; \
2125 else \
2126 Py_DECREF(str); \
2128 count++; }
2130 /* Always force the list to the expected size. */
2131 #define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
2134 Py_LOCAL_INLINE(PyObject *)
2135 split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2137 register Py_ssize_t i, j, count = 0;
2138 PyObject *str;
2139 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2141 if (list == NULL)
2142 return NULL;
2144 i = j = 0;
2145 while ((j < len) && (maxcount-- > 0)) {
2146 for(; j < len; j++) {
2147 /* I found that using memchr makes no difference */
2148 if (s[j] == ch) {
2149 SPLIT_ADD(s, i, j);
2150 i = j = j + 1;
2151 break;
2155 if (i <= len) {
2156 SPLIT_ADD(s, i, len);
2158 FIX_PREALLOC_SIZE(list);
2159 return list;
2161 onError:
2162 Py_DECREF(list);
2163 return NULL;
2167 Py_LOCAL_INLINE(PyObject *)
2168 split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2170 register Py_ssize_t i, j, count = 0;
2171 PyObject *str;
2172 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2174 if (list == NULL)
2175 return NULL;
2177 for (i = j = 0; i < len; ) {
2178 /* find a token */
2179 while (i < len && Py_ISSPACE(s[i]))
2180 i++;
2181 j = i;
2182 while (i < len && !Py_ISSPACE(s[i]))
2183 i++;
2184 if (j < i) {
2185 if (maxcount-- <= 0)
2186 break;
2187 SPLIT_ADD(s, j, i);
2188 while (i < len && Py_ISSPACE(s[i]))
2189 i++;
2190 j = i;
2193 if (j < len) {
2194 SPLIT_ADD(s, j, len);
2196 FIX_PREALLOC_SIZE(list);
2197 return list;
2199 onError:
2200 Py_DECREF(list);
2201 return NULL;
2204 PyDoc_STRVAR(split__doc__,
2205 "B.split([sep[, maxsplit]]) -> list of bytearrays\n\
2207 Return a list of the sections in B, using sep as the delimiter.\n\
2208 If sep is not given, B is split on ASCII whitespace characters\n\
2209 (space, tab, return, newline, formfeed, vertical tab).\n\
2210 If maxsplit is given, at most maxsplit splits are done.");
2212 static PyObject *
2213 bytearray_split(PyByteArrayObject *self, PyObject *args)
2215 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2216 Py_ssize_t maxsplit = -1, count = 0;
2217 const char *s = PyByteArray_AS_STRING(self), *sub;
2218 PyObject *list, *str, *subobj = Py_None;
2219 Py_buffer vsub;
2220 #ifdef USE_FAST
2221 Py_ssize_t pos;
2222 #endif
2224 if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
2225 return NULL;
2226 if (maxsplit < 0)
2227 maxsplit = PY_SSIZE_T_MAX;
2229 if (subobj == Py_None)
2230 return split_whitespace(s, len, maxsplit);
2232 if (_getbuffer(subobj, &vsub) < 0)
2233 return NULL;
2234 sub = vsub.buf;
2235 n = vsub.len;
2237 if (n == 0) {
2238 PyErr_SetString(PyExc_ValueError, "empty separator");
2239 PyBuffer_Release(&vsub);
2240 return NULL;
2242 if (n == 1) {
2243 list = split_char(s, len, sub[0], maxsplit);
2244 PyBuffer_Release(&vsub);
2245 return list;
2248 list = PyList_New(PREALLOC_SIZE(maxsplit));
2249 if (list == NULL) {
2250 PyBuffer_Release(&vsub);
2251 return NULL;
2254 #ifdef USE_FAST
2255 i = j = 0;
2256 while (maxsplit-- > 0) {
2257 pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
2258 if (pos < 0)
2259 break;
2260 j = i+pos;
2261 SPLIT_ADD(s, i, j);
2262 i = j + n;
2264 #else
2265 i = j = 0;
2266 while ((j+n <= len) && (maxsplit-- > 0)) {
2267 for (; j+n <= len; j++) {
2268 if (Py_STRING_MATCH(s, j, sub, n)) {
2269 SPLIT_ADD(s, i, j);
2270 i = j = j + n;
2271 break;
2275 #endif
2276 SPLIT_ADD(s, i, len);
2277 FIX_PREALLOC_SIZE(list);
2278 PyBuffer_Release(&vsub);
2279 return list;
2281 onError:
2282 Py_DECREF(list);
2283 PyBuffer_Release(&vsub);
2284 return NULL;
2287 /* stringlib's partition shares nullbytes in some cases.
2288 undo this, we don't want the nullbytes to be shared. */
2289 static PyObject *
2290 make_nullbytes_unique(PyObject *result)
2292 if (result != NULL) {
2293 int i;
2294 assert(PyTuple_Check(result));
2295 assert(PyTuple_GET_SIZE(result) == 3);
2296 for (i = 0; i < 3; i++) {
2297 if (PyTuple_GET_ITEM(result, i) == (PyObject *)nullbytes) {
2298 PyObject *new = PyByteArray_FromStringAndSize(NULL, 0);
2299 if (new == NULL) {
2300 Py_DECREF(result);
2301 result = NULL;
2302 break;
2304 Py_DECREF(nullbytes);
2305 PyTuple_SET_ITEM(result, i, new);
2309 return result;
2312 PyDoc_STRVAR(partition__doc__,
2313 "B.partition(sep) -> (head, sep, tail)\n\
2315 Search for the separator sep in B, and return the part before it,\n\
2316 the separator itself, and the part after it. If the separator is not\n\
2317 found, returns B and two empty bytearray objects.");
2319 static PyObject *
2320 bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
2322 PyObject *bytesep, *result;
2324 bytesep = PyByteArray_FromObject(sep_obj);
2325 if (! bytesep)
2326 return NULL;
2328 result = stringlib_partition(
2329 (PyObject*) self,
2330 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2331 bytesep,
2332 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2335 Py_DECREF(bytesep);
2336 return make_nullbytes_unique(result);
2339 PyDoc_STRVAR(rpartition__doc__,
2340 "B.rpartition(sep) -> (tail, sep, head)\n\
2342 Search for the separator sep in B, starting at the end of B,\n\
2343 and return the part before it, the separator itself, and the\n\
2344 part after it. If the separator is not found, returns two empty\n\
2345 bytearray objects and B.");
2347 static PyObject *
2348 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
2350 PyObject *bytesep, *result;
2352 bytesep = PyByteArray_FromObject(sep_obj);
2353 if (! bytesep)
2354 return NULL;
2356 result = stringlib_rpartition(
2357 (PyObject*) self,
2358 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2359 bytesep,
2360 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2363 Py_DECREF(bytesep);
2364 return make_nullbytes_unique(result);
2367 Py_LOCAL_INLINE(PyObject *)
2368 rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
2370 register Py_ssize_t i, j, count=0;
2371 PyObject *str;
2372 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2374 if (list == NULL)
2375 return NULL;
2377 i = j = len - 1;
2378 while ((i >= 0) && (maxcount-- > 0)) {
2379 for (; i >= 0; i--) {
2380 if (s[i] == ch) {
2381 SPLIT_ADD(s, i + 1, j + 1);
2382 j = i = i - 1;
2383 break;
2387 if (j >= -1) {
2388 SPLIT_ADD(s, 0, j + 1);
2390 FIX_PREALLOC_SIZE(list);
2391 if (PyList_Reverse(list) < 0)
2392 goto onError;
2394 return list;
2396 onError:
2397 Py_DECREF(list);
2398 return NULL;
2401 Py_LOCAL_INLINE(PyObject *)
2402 rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxcount)
2404 register Py_ssize_t i, j, count = 0;
2405 PyObject *str;
2406 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
2408 if (list == NULL)
2409 return NULL;
2411 for (i = j = len - 1; i >= 0; ) {
2412 /* find a token */
2413 while (i >= 0 && Py_ISSPACE(s[i]))
2414 i--;
2415 j = i;
2416 while (i >= 0 && !Py_ISSPACE(s[i]))
2417 i--;
2418 if (j > i) {
2419 if (maxcount-- <= 0)
2420 break;
2421 SPLIT_ADD(s, i + 1, j + 1);
2422 while (i >= 0 && Py_ISSPACE(s[i]))
2423 i--;
2424 j = i;
2427 if (j >= 0) {
2428 SPLIT_ADD(s, 0, j + 1);
2430 FIX_PREALLOC_SIZE(list);
2431 if (PyList_Reverse(list) < 0)
2432 goto onError;
2434 return list;
2436 onError:
2437 Py_DECREF(list);
2438 return NULL;
2441 PyDoc_STRVAR(rsplit__doc__,
2442 "B.rsplit(sep[, maxsplit]) -> list of bytearrays\n\
2444 Return a list of the sections in B, using sep as the delimiter,\n\
2445 starting at the end of B and working to the front.\n\
2446 If sep is not given, B is split on ASCII whitespace characters\n\
2447 (space, tab, return, newline, formfeed, vertical tab).\n\
2448 If maxsplit is given, at most maxsplit splits are done.");
2450 static PyObject *
2451 bytearray_rsplit(PyByteArrayObject *self, PyObject *args)
2453 Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j;
2454 Py_ssize_t maxsplit = -1, count = 0;
2455 const char *s = PyByteArray_AS_STRING(self), *sub;
2456 PyObject *list, *str, *subobj = Py_None;
2457 Py_buffer vsub;
2459 if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
2460 return NULL;
2461 if (maxsplit < 0)
2462 maxsplit = PY_SSIZE_T_MAX;
2464 if (subobj == Py_None)
2465 return rsplit_whitespace(s, len, maxsplit);
2467 if (_getbuffer(subobj, &vsub) < 0)
2468 return NULL;
2469 sub = vsub.buf;
2470 n = vsub.len;
2472 if (n == 0) {
2473 PyErr_SetString(PyExc_ValueError, "empty separator");
2474 PyBuffer_Release(&vsub);
2475 return NULL;
2477 else if (n == 1) {
2478 list = rsplit_char(s, len, sub[0], maxsplit);
2479 PyBuffer_Release(&vsub);
2480 return list;
2483 list = PyList_New(PREALLOC_SIZE(maxsplit));
2484 if (list == NULL) {
2485 PyBuffer_Release(&vsub);
2486 return NULL;
2489 j = len;
2490 i = j - n;
2492 while ( (i >= 0) && (maxsplit-- > 0) ) {
2493 for (; i>=0; i--) {
2494 if (Py_STRING_MATCH(s, i, sub, n)) {
2495 SPLIT_ADD(s, i + n, j);
2496 j = i;
2497 i -= n;
2498 break;
2502 SPLIT_ADD(s, 0, j);
2503 FIX_PREALLOC_SIZE(list);
2504 if (PyList_Reverse(list) < 0)
2505 goto onError;
2506 PyBuffer_Release(&vsub);
2507 return list;
2509 onError:
2510 Py_DECREF(list);
2511 PyBuffer_Release(&vsub);
2512 return NULL;
2515 PyDoc_STRVAR(reverse__doc__,
2516 "B.reverse() -> None\n\
2518 Reverse the order of the values in B in place.");
2519 static PyObject *
2520 bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
2522 char swap, *head, *tail;
2523 Py_ssize_t i, j, n = Py_SIZE(self);
2525 j = n / 2;
2526 head = self->ob_bytes;
2527 tail = head + n - 1;
2528 for (i = 0; i < j; i++) {
2529 swap = *head;
2530 *head++ = *tail;
2531 *tail-- = swap;
2534 Py_RETURN_NONE;
2537 PyDoc_STRVAR(insert__doc__,
2538 "B.insert(index, int) -> None\n\
2540 Insert a single item into the bytearray before the given index.");
2541 static PyObject *
2542 bytearray_insert(PyByteArrayObject *self, PyObject *args)
2544 PyObject *value;
2545 int ival;
2546 Py_ssize_t where, n = Py_SIZE(self);
2548 if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
2549 return NULL;
2551 if (n == PY_SSIZE_T_MAX) {
2552 PyErr_SetString(PyExc_OverflowError,
2553 "cannot add more objects to bytes");
2554 return NULL;
2556 if (!_getbytevalue(value, &ival))
2557 return NULL;
2558 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2559 return NULL;
2561 if (where < 0) {
2562 where += n;
2563 if (where < 0)
2564 where = 0;
2566 if (where > n)
2567 where = n;
2568 memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
2569 self->ob_bytes[where] = ival;
2571 Py_RETURN_NONE;
2574 PyDoc_STRVAR(append__doc__,
2575 "B.append(int) -> None\n\
2577 Append a single item to the end of B.");
2578 static PyObject *
2579 bytearray_append(PyByteArrayObject *self, PyObject *arg)
2581 int value;
2582 Py_ssize_t n = Py_SIZE(self);
2584 if (! _getbytevalue(arg, &value))
2585 return NULL;
2586 if (n == PY_SSIZE_T_MAX) {
2587 PyErr_SetString(PyExc_OverflowError,
2588 "cannot add more objects to bytes");
2589 return NULL;
2591 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2592 return NULL;
2594 self->ob_bytes[n] = value;
2596 Py_RETURN_NONE;
2599 PyDoc_STRVAR(extend__doc__,
2600 "B.extend(iterable_of_ints) -> None\n\
2602 Append all the elements from the iterator or sequence to the\n\
2603 end of B.");
2604 static PyObject *
2605 bytearray_extend(PyByteArrayObject *self, PyObject *arg)
2607 PyObject *it, *item, *bytearray_obj;
2608 Py_ssize_t buf_size = 0, len = 0;
2609 int value;
2610 char *buf;
2612 /* bytearray_setslice code only accepts something supporting PEP 3118. */
2613 if (PyObject_CheckBuffer(arg)) {
2614 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
2615 return NULL;
2617 Py_RETURN_NONE;
2620 it = PyObject_GetIter(arg);
2621 if (it == NULL)
2622 return NULL;
2624 /* Try to determine the length of the argument. 32 is abitrary. */
2625 buf_size = _PyObject_LengthHint(arg, 32);
2626 if (buf_size == -1) {
2627 Py_DECREF(it);
2628 return NULL;
2631 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2632 if (bytearray_obj == NULL)
2633 return NULL;
2634 buf = PyByteArray_AS_STRING(bytearray_obj);
2636 while ((item = PyIter_Next(it)) != NULL) {
2637 if (! _getbytevalue(item, &value)) {
2638 Py_DECREF(item);
2639 Py_DECREF(it);
2640 Py_DECREF(bytearray_obj);
2641 return NULL;
2643 buf[len++] = value;
2644 Py_DECREF(item);
2646 if (len >= buf_size) {
2647 buf_size = len + (len >> 1) + 1;
2648 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
2649 Py_DECREF(it);
2650 Py_DECREF(bytearray_obj);
2651 return NULL;
2653 /* Recompute the `buf' pointer, since the resizing operation may
2654 have invalidated it. */
2655 buf = PyByteArray_AS_STRING(bytearray_obj);
2658 Py_DECREF(it);
2660 /* Resize down to exact size. */
2661 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2662 Py_DECREF(bytearray_obj);
2663 return NULL;
2666 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1)
2667 return NULL;
2668 Py_DECREF(bytearray_obj);
2670 Py_RETURN_NONE;
2673 PyDoc_STRVAR(pop__doc__,
2674 "B.pop([index]) -> int\n\
2676 Remove and return a single item from B. If no index\n\
2677 argument is given, will pop the last value.");
2678 static PyObject *
2679 bytearray_pop(PyByteArrayObject *self, PyObject *args)
2681 int value;
2682 Py_ssize_t where = -1, n = Py_SIZE(self);
2684 if (!PyArg_ParseTuple(args, "|n:pop", &where))
2685 return NULL;
2687 if (n == 0) {
2688 PyErr_SetString(PyExc_OverflowError,
2689 "cannot pop an empty bytes");
2690 return NULL;
2692 if (where < 0)
2693 where += Py_SIZE(self);
2694 if (where < 0 || where >= Py_SIZE(self)) {
2695 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2696 return NULL;
2698 if (!_canresize(self))
2699 return NULL;
2701 value = self->ob_bytes[where];
2702 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2703 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2704 return NULL;
2706 return PyLong_FromLong(value);
2709 PyDoc_STRVAR(remove__doc__,
2710 "B.remove(int) -> None\n\
2712 Remove the first occurrence of a value in B.");
2713 static PyObject *
2714 bytearray_remove(PyByteArrayObject *self, PyObject *arg)
2716 int value;
2717 Py_ssize_t where, n = Py_SIZE(self);
2719 if (! _getbytevalue(arg, &value))
2720 return NULL;
2722 for (where = 0; where < n; where++) {
2723 if (self->ob_bytes[where] == value)
2724 break;
2726 if (where == n) {
2727 PyErr_SetString(PyExc_ValueError, "value not found in bytes");
2728 return NULL;
2730 if (!_canresize(self))
2731 return NULL;
2733 memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
2734 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2735 return NULL;
2737 Py_RETURN_NONE;
2740 /* XXX These two helpers could be optimized if argsize == 1 */
2742 static Py_ssize_t
2743 lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2744 void *argptr, Py_ssize_t argsize)
2746 Py_ssize_t i = 0;
2747 while (i < mysize && memchr(argptr, myptr[i], argsize))
2748 i++;
2749 return i;
2752 static Py_ssize_t
2753 rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
2754 void *argptr, Py_ssize_t argsize)
2756 Py_ssize_t i = mysize - 1;
2757 while (i >= 0 && memchr(argptr, myptr[i], argsize))
2758 i--;
2759 return i + 1;
2762 PyDoc_STRVAR(strip__doc__,
2763 "B.strip([bytes]) -> bytearray\n\
2765 Strip leading and trailing bytes contained in the argument\n\
2766 and return the result as a new bytearray.\n\
2767 If the argument is omitted, strip ASCII whitespace.");
2768 static PyObject *
2769 bytearray_strip(PyByteArrayObject *self, PyObject *args)
2771 Py_ssize_t left, right, mysize, argsize;
2772 void *myptr, *argptr;
2773 PyObject *arg = Py_None;
2774 Py_buffer varg;
2775 if (!PyArg_ParseTuple(args, "|O:strip", &arg))
2776 return NULL;
2777 if (arg == Py_None) {
2778 argptr = "\t\n\r\f\v ";
2779 argsize = 6;
2781 else {
2782 if (_getbuffer(arg, &varg) < 0)
2783 return NULL;
2784 argptr = varg.buf;
2785 argsize = varg.len;
2787 myptr = self->ob_bytes;
2788 mysize = Py_SIZE(self);
2789 left = lstrip_helper(myptr, mysize, argptr, argsize);
2790 if (left == mysize)
2791 right = left;
2792 else
2793 right = rstrip_helper(myptr, mysize, argptr, argsize);
2794 if (arg != Py_None)
2795 PyBuffer_Release(&varg);
2796 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2799 PyDoc_STRVAR(lstrip__doc__,
2800 "B.lstrip([bytes]) -> bytearray\n\
2802 Strip leading bytes contained in the argument\n\
2803 and return the result as a new bytearray.\n\
2804 If the argument is omitted, strip leading ASCII whitespace.");
2805 static PyObject *
2806 bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
2808 Py_ssize_t left, right, mysize, argsize;
2809 void *myptr, *argptr;
2810 PyObject *arg = Py_None;
2811 Py_buffer varg;
2812 if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
2813 return NULL;
2814 if (arg == Py_None) {
2815 argptr = "\t\n\r\f\v ";
2816 argsize = 6;
2818 else {
2819 if (_getbuffer(arg, &varg) < 0)
2820 return NULL;
2821 argptr = varg.buf;
2822 argsize = varg.len;
2824 myptr = self->ob_bytes;
2825 mysize = Py_SIZE(self);
2826 left = lstrip_helper(myptr, mysize, argptr, argsize);
2827 right = mysize;
2828 if (arg != Py_None)
2829 PyBuffer_Release(&varg);
2830 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2833 PyDoc_STRVAR(rstrip__doc__,
2834 "B.rstrip([bytes]) -> bytearray\n\
2836 Strip trailing bytes contained in the argument\n\
2837 and return the result as a new bytearray.\n\
2838 If the argument is omitted, strip trailing ASCII whitespace.");
2839 static PyObject *
2840 bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
2842 Py_ssize_t left, right, mysize, argsize;
2843 void *myptr, *argptr;
2844 PyObject *arg = Py_None;
2845 Py_buffer varg;
2846 if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
2847 return NULL;
2848 if (arg == Py_None) {
2849 argptr = "\t\n\r\f\v ";
2850 argsize = 6;
2852 else {
2853 if (_getbuffer(arg, &varg) < 0)
2854 return NULL;
2855 argptr = varg.buf;
2856 argsize = varg.len;
2858 myptr = self->ob_bytes;
2859 mysize = Py_SIZE(self);
2860 left = 0;
2861 right = rstrip_helper(myptr, mysize, argptr, argsize);
2862 if (arg != Py_None)
2863 PyBuffer_Release(&varg);
2864 return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
2867 PyDoc_STRVAR(decode_doc,
2868 "B.decode([encoding[, errors]]) -> str\n\
2870 Decode B using the codec registered for encoding. encoding defaults\n\
2871 to the default encoding. errors may be given to set a different error\n\
2872 handling scheme. Default is 'strict' meaning that encoding errors raise\n\
2873 a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
2874 as well as any other name registered with codecs.register_error that is\n\
2875 able to handle UnicodeDecodeErrors.");
2877 static PyObject *
2878 bytearray_decode(PyObject *self, PyObject *args)
2880 const char *encoding = NULL;
2881 const char *errors = NULL;
2883 if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
2884 return NULL;
2885 if (encoding == NULL)
2886 encoding = PyUnicode_GetDefaultEncoding();
2887 return PyUnicode_FromEncodedObject(self, encoding, errors);
2890 PyDoc_STRVAR(alloc_doc,
2891 "B.__alloc__() -> int\n\
2893 Return the number of bytes actually allocated.");
2895 static PyObject *
2896 bytearray_alloc(PyByteArrayObject *self)
2898 return PyLong_FromSsize_t(self->ob_alloc);
2901 PyDoc_STRVAR(join_doc,
2902 "B.join(iterable_of_bytes) -> bytearray\n\
2904 Concatenate any number of bytes/bytearray objects, with B\n\
2905 in between each pair, and return the result as a new bytearray.");
2907 static PyObject *
2908 bytearray_join(PyByteArrayObject *self, PyObject *it)
2910 PyObject *seq;
2911 Py_ssize_t mysize = Py_SIZE(self);
2912 Py_ssize_t i;
2913 Py_ssize_t n;
2914 PyObject **items;
2915 Py_ssize_t totalsize = 0;
2916 PyObject *result;
2917 char *dest;
2919 seq = PySequence_Fast(it, "can only join an iterable");
2920 if (seq == NULL)
2921 return NULL;
2922 n = PySequence_Fast_GET_SIZE(seq);
2923 items = PySequence_Fast_ITEMS(seq);
2925 /* Compute the total size, and check that they are all bytes */
2926 /* XXX Shouldn't we use _getbuffer() on these items instead? */
2927 for (i = 0; i < n; i++) {
2928 PyObject *obj = items[i];
2929 if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
2930 PyErr_Format(PyExc_TypeError,
2931 "can only join an iterable of bytes "
2932 "(item %ld has type '%.100s')",
2933 /* XXX %ld isn't right on Win64 */
2934 (long)i, Py_TYPE(obj)->tp_name);
2935 goto error;
2937 if (i > 0)
2938 totalsize += mysize;
2939 totalsize += Py_SIZE(obj);
2940 if (totalsize < 0) {
2941 PyErr_NoMemory();
2942 goto error;
2946 /* Allocate the result, and copy the bytes */
2947 result = PyByteArray_FromStringAndSize(NULL, totalsize);
2948 if (result == NULL)
2949 goto error;
2950 dest = PyByteArray_AS_STRING(result);
2951 for (i = 0; i < n; i++) {
2952 PyObject *obj = items[i];
2953 Py_ssize_t size = Py_SIZE(obj);
2954 char *buf;
2955 if (PyByteArray_Check(obj))
2956 buf = PyByteArray_AS_STRING(obj);
2957 else
2958 buf = PyBytes_AS_STRING(obj);
2959 if (i) {
2960 memcpy(dest, self->ob_bytes, mysize);
2961 dest += mysize;
2963 memcpy(dest, buf, size);
2964 dest += size;
2967 /* Done */
2968 Py_DECREF(seq);
2969 return result;
2971 /* Error handling */
2972 error:
2973 Py_DECREF(seq);
2974 return NULL;
2977 PyDoc_STRVAR(fromhex_doc,
2978 "bytearray.fromhex(string) -> bytearray (static method)\n\
2980 Create a bytearray object from a string of hexadecimal numbers.\n\
2981 Spaces between two numbers are accepted.\n\
2982 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
2984 static int
2985 hex_digit_to_int(Py_UNICODE c)
2987 if (c >= 128)
2988 return -1;
2989 if (Py_ISDIGIT(c))
2990 return c - '0';
2991 else {
2992 if (Py_ISUPPER(c))
2993 c = Py_TOLOWER(c);
2994 if (c >= 'a' && c <= 'f')
2995 return c - 'a' + 10;
2997 return -1;
3000 static PyObject *
3001 bytearray_fromhex(PyObject *cls, PyObject *args)
3003 PyObject *newbytes, *hexobj;
3004 char *buf;
3005 Py_UNICODE *hex;
3006 Py_ssize_t hexlen, byteslen, i, j;
3007 int top, bot;
3009 if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
3010 return NULL;
3011 assert(PyUnicode_Check(hexobj));
3012 hexlen = PyUnicode_GET_SIZE(hexobj);
3013 hex = PyUnicode_AS_UNICODE(hexobj);
3014 byteslen = hexlen/2; /* This overestimates if there are spaces */
3015 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
3016 if (!newbytes)
3017 return NULL;
3018 buf = PyByteArray_AS_STRING(newbytes);
3019 for (i = j = 0; i < hexlen; i += 2) {
3020 /* skip over spaces in the input */
3021 while (hex[i] == ' ')
3022 i++;
3023 if (i >= hexlen)
3024 break;
3025 top = hex_digit_to_int(hex[i]);
3026 bot = hex_digit_to_int(hex[i+1]);
3027 if (top == -1 || bot == -1) {
3028 PyErr_Format(PyExc_ValueError,
3029 "non-hexadecimal number found in "
3030 "fromhex() arg at position %zd", i);
3031 goto error;
3033 buf[j++] = (top << 4) + bot;
3035 if (PyByteArray_Resize(newbytes, j) < 0)
3036 goto error;
3037 return newbytes;
3039 error:
3040 Py_DECREF(newbytes);
3041 return NULL;
3044 PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
3046 static PyObject *
3047 bytearray_reduce(PyByteArrayObject *self)
3049 PyObject *latin1, *dict;
3050 if (self->ob_bytes)
3051 latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
3052 Py_SIZE(self), NULL);
3053 else
3054 latin1 = PyUnicode_FromString("");
3056 dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
3057 if (dict == NULL) {
3058 PyErr_Clear();
3059 dict = Py_None;
3060 Py_INCREF(dict);
3063 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
3066 PyDoc_STRVAR(sizeof_doc,
3067 "B.__sizeof__() -> int\n\
3069 Returns the size of B in memory, in bytes");
3070 static PyObject *
3071 bytearray_sizeof(PyByteArrayObject *self)
3073 Py_ssize_t res;
3075 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
3076 return PyLong_FromSsize_t(res);
3079 static PySequenceMethods bytearray_as_sequence = {
3080 (lenfunc)bytearray_length, /* sq_length */
3081 (binaryfunc)PyByteArray_Concat, /* sq_concat */
3082 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
3083 (ssizeargfunc)bytearray_getitem, /* sq_item */
3084 0, /* sq_slice */
3085 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
3086 0, /* sq_ass_slice */
3087 (objobjproc)bytearray_contains, /* sq_contains */
3088 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
3089 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
3092 static PyMappingMethods bytearray_as_mapping = {
3093 (lenfunc)bytearray_length,
3094 (binaryfunc)bytearray_subscript,
3095 (objobjargproc)bytearray_ass_subscript,
3098 static PyBufferProcs bytearray_as_buffer = {
3099 (getbufferproc)bytearray_getbuffer,
3100 (releasebufferproc)bytearray_releasebuffer,
3103 static PyMethodDef
3104 bytearray_methods[] = {
3105 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
3106 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
3107 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
3108 {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
3109 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3110 _Py_capitalize__doc__},
3111 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
3112 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
3113 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc},
3114 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
3115 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
3116 expandtabs__doc__},
3117 {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
3118 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
3119 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
3120 fromhex_doc},
3121 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
3122 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
3123 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3124 _Py_isalnum__doc__},
3125 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3126 _Py_isalpha__doc__},
3127 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3128 _Py_isdigit__doc__},
3129 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3130 _Py_islower__doc__},
3131 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3132 _Py_isspace__doc__},
3133 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3134 _Py_istitle__doc__},
3135 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3136 _Py_isupper__doc__},
3137 {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
3138 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3139 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
3140 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
3141 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
3142 _Py_maketrans__doc__},
3143 {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
3144 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
3145 {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
3146 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
3147 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
3148 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3149 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
3150 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
3151 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
3152 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__},
3153 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
3154 {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__},
3155 {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
3156 splitlines__doc__},
3157 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
3158 startswith__doc__},
3159 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
3160 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3161 _Py_swapcase__doc__},
3162 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
3163 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
3164 translate__doc__},
3165 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3166 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3167 {NULL}
3170 PyDoc_STRVAR(bytearray_doc,
3171 "bytearray(iterable_of_ints) -> bytearray\n\
3172 bytearray(string, encoding[, errors]) -> bytearray\n\
3173 bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\
3174 bytearray(memory_view) -> bytearray\n\
3176 Construct an mutable bytearray object from:\n\
3177 - an iterable yielding integers in range(256)\n\
3178 - a text string encoded using the specified encoding\n\
3179 - a bytes or a bytearray object\n\
3180 - any object implementing the buffer API.\n\
3182 bytearray(int) -> bytearray\n\
3184 Construct a zero-initialized bytearray of the given length.");
3187 static PyObject *bytearray_iter(PyObject *seq);
3189 PyTypeObject PyByteArray_Type = {
3190 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3191 "bytearray",
3192 sizeof(PyByteArrayObject),
3194 (destructor)bytearray_dealloc, /* tp_dealloc */
3195 0, /* tp_print */
3196 0, /* tp_getattr */
3197 0, /* tp_setattr */
3198 0, /* tp_reserved */
3199 (reprfunc)bytearray_repr, /* tp_repr */
3200 0, /* tp_as_number */
3201 &bytearray_as_sequence, /* tp_as_sequence */
3202 &bytearray_as_mapping, /* tp_as_mapping */
3203 0, /* tp_hash */
3204 0, /* tp_call */
3205 bytearray_str, /* tp_str */
3206 PyObject_GenericGetAttr, /* tp_getattro */
3207 0, /* tp_setattro */
3208 &bytearray_as_buffer, /* tp_as_buffer */
3209 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3210 bytearray_doc, /* tp_doc */
3211 0, /* tp_traverse */
3212 0, /* tp_clear */
3213 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
3214 0, /* tp_weaklistoffset */
3215 bytearray_iter, /* tp_iter */
3216 0, /* tp_iternext */
3217 bytearray_methods, /* tp_methods */
3218 0, /* tp_members */
3219 0, /* tp_getset */
3220 0, /* tp_base */
3221 0, /* tp_dict */
3222 0, /* tp_descr_get */
3223 0, /* tp_descr_set */
3224 0, /* tp_dictoffset */
3225 (initproc)bytearray_init, /* tp_init */
3226 PyType_GenericAlloc, /* tp_alloc */
3227 PyType_GenericNew, /* tp_new */
3228 PyObject_Del, /* tp_free */
3231 /*********************** Bytes Iterator ****************************/
3233 typedef struct {
3234 PyObject_HEAD
3235 Py_ssize_t it_index;
3236 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3237 } bytesiterobject;
3239 static void
3240 bytearrayiter_dealloc(bytesiterobject *it)
3242 _PyObject_GC_UNTRACK(it);
3243 Py_XDECREF(it->it_seq);
3244 PyObject_GC_Del(it);
3247 static int
3248 bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
3250 Py_VISIT(it->it_seq);
3251 return 0;
3254 static PyObject *
3255 bytearrayiter_next(bytesiterobject *it)
3257 PyByteArrayObject *seq;
3258 PyObject *item;
3260 assert(it != NULL);
3261 seq = it->it_seq;
3262 if (seq == NULL)
3263 return NULL;
3264 assert(PyByteArray_Check(seq));
3266 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3267 item = PyLong_FromLong(
3268 (unsigned char)seq->ob_bytes[it->it_index]);
3269 if (item != NULL)
3270 ++it->it_index;
3271 return item;
3274 Py_DECREF(seq);
3275 it->it_seq = NULL;
3276 return NULL;
3279 static PyObject *
3280 bytesarrayiter_length_hint(bytesiterobject *it)
3282 Py_ssize_t len = 0;
3283 if (it->it_seq)
3284 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3285 return PyLong_FromSsize_t(len);
3288 PyDoc_STRVAR(length_hint_doc,
3289 "Private method returning an estimate of len(list(it)).");
3291 static PyMethodDef bytearrayiter_methods[] = {
3292 {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS,
3293 length_hint_doc},
3294 {NULL, NULL} /* sentinel */
3297 PyTypeObject PyByteArrayIter_Type = {
3298 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3299 "bytearray_iterator", /* tp_name */
3300 sizeof(bytesiterobject), /* tp_basicsize */
3301 0, /* tp_itemsize */
3302 /* methods */
3303 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
3304 0, /* tp_print */
3305 0, /* tp_getattr */
3306 0, /* tp_setattr */
3307 0, /* tp_reserved */
3308 0, /* tp_repr */
3309 0, /* tp_as_number */
3310 0, /* tp_as_sequence */
3311 0, /* tp_as_mapping */
3312 0, /* tp_hash */
3313 0, /* tp_call */
3314 0, /* tp_str */
3315 PyObject_GenericGetAttr, /* tp_getattro */
3316 0, /* tp_setattro */
3317 0, /* tp_as_buffer */
3318 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3319 0, /* tp_doc */
3320 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
3321 0, /* tp_clear */
3322 0, /* tp_richcompare */
3323 0, /* tp_weaklistoffset */
3324 PyObject_SelfIter, /* tp_iter */
3325 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3326 bytearrayiter_methods, /* tp_methods */
3330 static PyObject *
3331 bytearray_iter(PyObject *seq)
3333 bytesiterobject *it;
3335 if (!PyByteArray_Check(seq)) {
3336 PyErr_BadInternalCall();
3337 return NULL;
3339 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3340 if (it == NULL)
3341 return NULL;
3342 it->it_index = 0;
3343 Py_INCREF(seq);
3344 it->it_seq = (PyByteArrayObject *)seq;
3345 _PyObject_GC_TRACK(it);
3346 return (PyObject *)it;