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