source: python/vendor/current/Objects/bytearrayobject.c

Last change on this file was 388, checked in by dmik, 11 years ago

python: Update vendor to 2.7.6.

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