1 /* PyByteArray (bytearray) implementation */
2
3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h"
5 #include "internal/mem.h"
6 #include "internal/pystate.h"
7 #include "structmember.h"
8 #include "bytes_methods.h"
9 #include "bytesobject.h"
10 #include "pystrhex.h"
11
12 /*[clinic input]
13 class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
14 [clinic start generated code]*/
15 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
16
17 char _PyByteArray_empty_string[] = "";
18
19 void
PyByteArray_Fini(void)20 PyByteArray_Fini(void)
21 {
22 }
23
24 int
PyByteArray_Init(void)25 PyByteArray_Init(void)
26 {
27 return 1;
28 }
29
30 /* end nullbytes support */
31
32 /* Helpers */
33
34 static int
_getbytevalue(PyObject * arg,int * value)35 _getbytevalue(PyObject* arg, int *value)
36 {
37 long face_value;
38
39 if (PyLong_Check(arg)) {
40 face_value = PyLong_AsLong(arg);
41 } else {
42 PyObject *index = PyNumber_Index(arg);
43 if (index == NULL) {
44 *value = -1;
45 return 0;
46 }
47 face_value = PyLong_AsLong(index);
48 Py_DECREF(index);
49 }
50
51 if (face_value < 0 || face_value >= 256) {
52 /* this includes the OverflowError in case the long is too large */
53 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
54 *value = -1;
55 return 0;
56 }
57
58 *value = face_value;
59 return 1;
60 }
61
62 static int
bytearray_getbuffer(PyByteArrayObject * obj,Py_buffer * view,int flags)63 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
64 {
65 void *ptr;
66 if (view == NULL) {
67 PyErr_SetString(PyExc_BufferError,
68 "bytearray_getbuffer: view==NULL argument is obsolete");
69 return -1;
70 }
71 ptr = (void *) PyByteArray_AS_STRING(obj);
72 /* cannot fail if view != NULL and readonly == 0 */
73 (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
74 obj->ob_exports++;
75 return 0;
76 }
77
78 static void
bytearray_releasebuffer(PyByteArrayObject * obj,Py_buffer * view)79 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
80 {
81 obj->ob_exports--;
82 }
83
84 static int
_canresize(PyByteArrayObject * self)85 _canresize(PyByteArrayObject *self)
86 {
87 if (self->ob_exports > 0) {
88 PyErr_SetString(PyExc_BufferError,
89 "Existing exports of data: object cannot be re-sized");
90 return 0;
91 }
92 return 1;
93 }
94
95 #include "clinic/bytearrayobject.c.h"
96
97 /* Direct API functions */
98
99 PyObject *
PyByteArray_FromObject(PyObject * input)100 PyByteArray_FromObject(PyObject *input)
101 {
102 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
103 input, NULL);
104 }
105
106 static PyObject *
_PyByteArray_FromBufferObject(PyObject * obj)107 _PyByteArray_FromBufferObject(PyObject *obj)
108 {
109 PyObject *result;
110 Py_buffer view;
111
112 if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
113 return NULL;
114 }
115 result = PyByteArray_FromStringAndSize(NULL, view.len);
116 if (result != NULL &&
117 PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
118 &view, view.len, 'C') < 0)
119 {
120 Py_CLEAR(result);
121 }
122 PyBuffer_Release(&view);
123 return result;
124 }
125
126 PyObject *
PyByteArray_FromStringAndSize(const char * bytes,Py_ssize_t size)127 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
128 {
129 PyByteArrayObject *new;
130 Py_ssize_t alloc;
131
132 if (size < 0) {
133 PyErr_SetString(PyExc_SystemError,
134 "Negative size passed to PyByteArray_FromStringAndSize");
135 return NULL;
136 }
137
138 /* Prevent buffer overflow when setting alloc to size+1. */
139 if (size == PY_SSIZE_T_MAX) {
140 return PyErr_NoMemory();
141 }
142
143 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
144 if (new == NULL)
145 return NULL;
146
147 if (size == 0) {
148 new->ob_bytes = NULL;
149 alloc = 0;
150 }
151 else {
152 alloc = size + 1;
153 new->ob_bytes = PyObject_Malloc(alloc);
154 if (new->ob_bytes == NULL) {
155 Py_DECREF(new);
156 return PyErr_NoMemory();
157 }
158 if (bytes != NULL && size > 0)
159 memcpy(new->ob_bytes, bytes, size);
160 new->ob_bytes[size] = '\0'; /* Trailing null byte */
161 }
162 Py_SIZE(new) = size;
163 new->ob_alloc = alloc;
164 new->ob_start = new->ob_bytes;
165 new->ob_exports = 0;
166
167 return (PyObject *)new;
168 }
169
170 Py_ssize_t
PyByteArray_Size(PyObject * self)171 PyByteArray_Size(PyObject *self)
172 {
173 assert(self != NULL);
174 assert(PyByteArray_Check(self));
175
176 return PyByteArray_GET_SIZE(self);
177 }
178
179 char *
PyByteArray_AsString(PyObject * self)180 PyByteArray_AsString(PyObject *self)
181 {
182 assert(self != NULL);
183 assert(PyByteArray_Check(self));
184
185 return PyByteArray_AS_STRING(self);
186 }
187
188 int
PyByteArray_Resize(PyObject * self,Py_ssize_t requested_size)189 PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
190 {
191 void *sval;
192 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
193 /* All computations are done unsigned to avoid integer overflows
194 (see issue #22335). */
195 size_t alloc = (size_t) obj->ob_alloc;
196 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
197 size_t size = (size_t) requested_size;
198
199 assert(self != NULL);
200 assert(PyByteArray_Check(self));
201 assert(logical_offset <= alloc);
202 assert(requested_size >= 0);
203
204 if (requested_size == Py_SIZE(self)) {
205 return 0;
206 }
207 if (!_canresize(obj)) {
208 return -1;
209 }
210
211 if (size + logical_offset + 1 <= alloc) {
212 /* Current buffer is large enough to host the requested size,
213 decide on a strategy. */
214 if (size < alloc / 2) {
215 /* Major downsize; resize down to exact size */
216 alloc = size + 1;
217 }
218 else {
219 /* Minor downsize; quick exit */
220 Py_SIZE(self) = size;
221 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
222 return 0;
223 }
224 }
225 else {
226 /* Need growing, decide on a strategy */
227 if (size <= alloc * 1.125) {
228 /* Moderate upsize; overallocate similar to list_resize() */
229 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
230 }
231 else {
232 /* Major upsize; resize up to exact size */
233 alloc = size + 1;
234 }
235 }
236 if (alloc > PY_SSIZE_T_MAX) {
237 PyErr_NoMemory();
238 return -1;
239 }
240
241 if (logical_offset > 0) {
242 sval = PyObject_Malloc(alloc);
243 if (sval == NULL) {
244 PyErr_NoMemory();
245 return -1;
246 }
247 memcpy(sval, PyByteArray_AS_STRING(self),
248 Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
249 PyObject_Free(obj->ob_bytes);
250 }
251 else {
252 sval = PyObject_Realloc(obj->ob_bytes, alloc);
253 if (sval == NULL) {
254 PyErr_NoMemory();
255 return -1;
256 }
257 }
258
259 obj->ob_bytes = obj->ob_start = sval;
260 Py_SIZE(self) = size;
261 obj->ob_alloc = alloc;
262 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
263
264 return 0;
265 }
266
267 PyObject *
PyByteArray_Concat(PyObject * a,PyObject * b)268 PyByteArray_Concat(PyObject *a, PyObject *b)
269 {
270 Py_buffer va, vb;
271 PyByteArrayObject *result = NULL;
272
273 va.len = -1;
274 vb.len = -1;
275 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
276 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
277 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
278 Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
279 goto done;
280 }
281
282 if (va.len > PY_SSIZE_T_MAX - vb.len) {
283 PyErr_NoMemory();
284 goto done;
285 }
286
287 result = (PyByteArrayObject *) \
288 PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
289 if (result != NULL) {
290 memcpy(result->ob_bytes, va.buf, va.len);
291 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
292 }
293
294 done:
295 if (va.len != -1)
296 PyBuffer_Release(&va);
297 if (vb.len != -1)
298 PyBuffer_Release(&vb);
299 return (PyObject *)result;
300 }
301
302 /* Functions stuffed into the type object */
303
304 static Py_ssize_t
bytearray_length(PyByteArrayObject * self)305 bytearray_length(PyByteArrayObject *self)
306 {
307 return Py_SIZE(self);
308 }
309
310 static PyObject *
bytearray_iconcat(PyByteArrayObject * self,PyObject * other)311 bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
312 {
313 Py_ssize_t size;
314 Py_buffer vo;
315
316 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
317 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
318 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
319 return NULL;
320 }
321
322 size = Py_SIZE(self);
323 if (size > PY_SSIZE_T_MAX - vo.len) {
324 PyBuffer_Release(&vo);
325 return PyErr_NoMemory();
326 }
327 if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
328 PyBuffer_Release(&vo);
329 return NULL;
330 }
331 memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
332 PyBuffer_Release(&vo);
333 Py_INCREF(self);
334 return (PyObject *)self;
335 }
336
337 static PyObject *
bytearray_repeat(PyByteArrayObject * self,Py_ssize_t count)338 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
339 {
340 PyByteArrayObject *result;
341 Py_ssize_t mysize;
342 Py_ssize_t size;
343
344 if (count < 0)
345 count = 0;
346 mysize = Py_SIZE(self);
347 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
348 return PyErr_NoMemory();
349 size = mysize * count;
350 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
351 if (result != NULL && size != 0) {
352 if (mysize == 1)
353 memset(result->ob_bytes, self->ob_bytes[0], size);
354 else {
355 Py_ssize_t i;
356 for (i = 0; i < count; i++)
357 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
358 }
359 }
360 return (PyObject *)result;
361 }
362
363 static PyObject *
bytearray_irepeat(PyByteArrayObject * self,Py_ssize_t count)364 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
365 {
366 Py_ssize_t mysize;
367 Py_ssize_t size;
368 char *buf;
369
370 if (count < 0)
371 count = 0;
372 mysize = Py_SIZE(self);
373 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
374 return PyErr_NoMemory();
375 size = mysize * count;
376 if (PyByteArray_Resize((PyObject *)self, size) < 0)
377 return NULL;
378
379 buf = PyByteArray_AS_STRING(self);
380 if (mysize == 1)
381 memset(buf, buf[0], size);
382 else {
383 Py_ssize_t i;
384 for (i = 1; i < count; i++)
385 memcpy(buf + i*mysize, buf, mysize);
386 }
387
388 Py_INCREF(self);
389 return (PyObject *)self;
390 }
391
392 static PyObject *
bytearray_getitem(PyByteArrayObject * self,Py_ssize_t i)393 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
394 {
395 if (i < 0)
396 i += Py_SIZE(self);
397 if (i < 0 || i >= Py_SIZE(self)) {
398 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
399 return NULL;
400 }
401 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
402 }
403
404 static PyObject *
bytearray_subscript(PyByteArrayObject * self,PyObject * index)405 bytearray_subscript(PyByteArrayObject *self, PyObject *index)
406 {
407 if (PyIndex_Check(index)) {
408 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
409
410 if (i == -1 && PyErr_Occurred())
411 return NULL;
412
413 if (i < 0)
414 i += PyByteArray_GET_SIZE(self);
415
416 if (i < 0 || i >= Py_SIZE(self)) {
417 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
418 return NULL;
419 }
420 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
421 }
422 else if (PySlice_Check(index)) {
423 Py_ssize_t start, stop, step, slicelength, cur, i;
424 if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
425 return NULL;
426 }
427 slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
428 &start, &stop, step);
429
430 if (slicelength <= 0)
431 return PyByteArray_FromStringAndSize("", 0);
432 else if (step == 1) {
433 return PyByteArray_FromStringAndSize(
434 PyByteArray_AS_STRING(self) + start, slicelength);
435 }
436 else {
437 char *source_buf = PyByteArray_AS_STRING(self);
438 char *result_buf;
439 PyObject *result;
440
441 result = PyByteArray_FromStringAndSize(NULL, slicelength);
442 if (result == NULL)
443 return NULL;
444
445 result_buf = PyByteArray_AS_STRING(result);
446 for (cur = start, i = 0; i < slicelength;
447 cur += step, i++) {
448 result_buf[i] = source_buf[cur];
449 }
450 return result;
451 }
452 }
453 else {
454 PyErr_Format(PyExc_TypeError,
455 "bytearray indices must be integers or slices, not %.200s",
456 Py_TYPE(index)->tp_name);
457 return NULL;
458 }
459 }
460
461 static int
bytearray_setslice_linear(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,char * bytes,Py_ssize_t bytes_len)462 bytearray_setslice_linear(PyByteArrayObject *self,
463 Py_ssize_t lo, Py_ssize_t hi,
464 char *bytes, Py_ssize_t bytes_len)
465 {
466 Py_ssize_t avail = hi - lo;
467 char *buf = PyByteArray_AS_STRING(self);
468 Py_ssize_t growth = bytes_len - avail;
469 int res = 0;
470 assert(avail >= 0);
471
472 if (growth < 0) {
473 if (!_canresize(self))
474 return -1;
475
476 if (lo == 0) {
477 /* Shrink the buffer by advancing its logical start */
478 self->ob_start -= growth;
479 /*
480 0 lo hi old_size
481 | |<----avail----->|<-----tail------>|
482 | |<-bytes_len->|<-----tail------>|
483 0 new_lo new_hi new_size
484 */
485 }
486 else {
487 /*
488 0 lo hi old_size
489 | |<----avail----->|<-----tomove------>|
490 | |<-bytes_len->|<-----tomove------>|
491 0 lo new_hi new_size
492 */
493 memmove(buf + lo + bytes_len, buf + hi,
494 Py_SIZE(self) - hi);
495 }
496 if (PyByteArray_Resize((PyObject *)self,
497 Py_SIZE(self) + growth) < 0) {
498 /* Issue #19578: Handling the memory allocation failure here is
499 tricky here because the bytearray object has already been
500 modified. Depending on growth and lo, the behaviour is
501 different.
502
503 If growth < 0 and lo != 0, the operation is completed, but a
504 MemoryError is still raised and the memory block is not
505 shrunk. Otherwise, the bytearray is restored in its previous
506 state and a MemoryError is raised. */
507 if (lo == 0) {
508 self->ob_start += growth;
509 return -1;
510 }
511 /* memmove() removed bytes, the bytearray object cannot be
512 restored in its previous state. */
513 Py_SIZE(self) += growth;
514 res = -1;
515 }
516 buf = PyByteArray_AS_STRING(self);
517 }
518 else if (growth > 0) {
519 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
520 PyErr_NoMemory();
521 return -1;
522 }
523
524 if (PyByteArray_Resize((PyObject *)self,
525 Py_SIZE(self) + growth) < 0) {
526 return -1;
527 }
528 buf = PyByteArray_AS_STRING(self);
529 /* Make the place for the additional bytes */
530 /*
531 0 lo hi old_size
532 | |<-avail->|<-----tomove------>|
533 | |<---bytes_len-->|<-----tomove------>|
534 0 lo new_hi new_size
535 */
536 memmove(buf + lo + bytes_len, buf + hi,
537 Py_SIZE(self) - lo - bytes_len);
538 }
539
540 if (bytes_len > 0)
541 memcpy(buf + lo, bytes, bytes_len);
542 return res;
543 }
544
545 static int
bytearray_setslice(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,PyObject * values)546 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
547 PyObject *values)
548 {
549 Py_ssize_t needed;
550 void *bytes;
551 Py_buffer vbytes;
552 int res = 0;
553
554 vbytes.len = -1;
555 if (values == (PyObject *)self) {
556 /* Make a copy and call this function recursively */
557 int err;
558 values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
559 PyByteArray_GET_SIZE(values));
560 if (values == NULL)
561 return -1;
562 err = bytearray_setslice(self, lo, hi, values);
563 Py_DECREF(values);
564 return err;
565 }
566 if (values == NULL) {
567 /* del b[lo:hi] */
568 bytes = NULL;
569 needed = 0;
570 }
571 else {
572 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
573 PyErr_Format(PyExc_TypeError,
574 "can't set bytearray slice from %.100s",
575 Py_TYPE(values)->tp_name);
576 return -1;
577 }
578 needed = vbytes.len;
579 bytes = vbytes.buf;
580 }
581
582 if (lo < 0)
583 lo = 0;
584 if (hi < lo)
585 hi = lo;
586 if (hi > Py_SIZE(self))
587 hi = Py_SIZE(self);
588
589 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
590 if (vbytes.len != -1)
591 PyBuffer_Release(&vbytes);
592 return res;
593 }
594
595 static int
bytearray_setitem(PyByteArrayObject * self,Py_ssize_t i,PyObject * value)596 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
597 {
598 int ival;
599
600 if (i < 0)
601 i += Py_SIZE(self);
602
603 if (i < 0 || i >= Py_SIZE(self)) {
604 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
605 return -1;
606 }
607
608 if (value == NULL)
609 return bytearray_setslice(self, i, i+1, NULL);
610
611 if (!_getbytevalue(value, &ival))
612 return -1;
613
614 PyByteArray_AS_STRING(self)[i] = ival;
615 return 0;
616 }
617
618 static int
bytearray_ass_subscript(PyByteArrayObject * self,PyObject * index,PyObject * values)619 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
620 {
621 Py_ssize_t start, stop, step, slicelen, needed;
622 char *buf, *bytes;
623 buf = PyByteArray_AS_STRING(self);
624
625 if (PyIndex_Check(index)) {
626 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
627
628 if (i == -1 && PyErr_Occurred())
629 return -1;
630
631 if (i < 0)
632 i += PyByteArray_GET_SIZE(self);
633
634 if (i < 0 || i >= Py_SIZE(self)) {
635 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
636 return -1;
637 }
638
639 if (values == NULL) {
640 /* Fall through to slice assignment */
641 start = i;
642 stop = i + 1;
643 step = 1;
644 slicelen = 1;
645 }
646 else {
647 int ival;
648 if (!_getbytevalue(values, &ival))
649 return -1;
650 buf[i] = (char)ival;
651 return 0;
652 }
653 }
654 else if (PySlice_Check(index)) {
655 if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
656 return -1;
657 }
658 slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
659 &stop, step);
660 }
661 else {
662 PyErr_Format(PyExc_TypeError,
663 "bytearray indices must be integers or slices, not %.200s",
664 Py_TYPE(index)->tp_name);
665 return -1;
666 }
667
668 if (values == NULL) {
669 bytes = NULL;
670 needed = 0;
671 }
672 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
673 int err;
674 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
675 PyErr_SetString(PyExc_TypeError,
676 "can assign only bytes, buffers, or iterables "
677 "of ints in range(0, 256)");
678 return -1;
679 }
680 /* Make a copy and call this function recursively */
681 values = PyByteArray_FromObject(values);
682 if (values == NULL)
683 return -1;
684 err = bytearray_ass_subscript(self, index, values);
685 Py_DECREF(values);
686 return err;
687 }
688 else {
689 assert(PyByteArray_Check(values));
690 bytes = PyByteArray_AS_STRING(values);
691 needed = Py_SIZE(values);
692 }
693 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
694 if ((step < 0 && start < stop) ||
695 (step > 0 && start > stop))
696 stop = start;
697 if (step == 1) {
698 return bytearray_setslice_linear(self, start, stop, bytes, needed);
699 }
700 else {
701 if (needed == 0) {
702 /* Delete slice */
703 size_t cur;
704 Py_ssize_t i;
705
706 if (!_canresize(self))
707 return -1;
708
709 if (slicelen == 0)
710 /* Nothing to do here. */
711 return 0;
712
713 if (step < 0) {
714 stop = start + 1;
715 start = stop + step * (slicelen - 1) - 1;
716 step = -step;
717 }
718 for (cur = start, i = 0;
719 i < slicelen; cur += step, i++) {
720 Py_ssize_t lim = step - 1;
721
722 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
723 lim = PyByteArray_GET_SIZE(self) - cur - 1;
724
725 memmove(buf + cur - i,
726 buf + cur + 1, lim);
727 }
728 /* Move the tail of the bytes, in one chunk */
729 cur = start + (size_t)slicelen*step;
730 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
731 memmove(buf + cur - slicelen,
732 buf + cur,
733 PyByteArray_GET_SIZE(self) - cur);
734 }
735 if (PyByteArray_Resize((PyObject *)self,
736 PyByteArray_GET_SIZE(self) - slicelen) < 0)
737 return -1;
738
739 return 0;
740 }
741 else {
742 /* Assign slice */
743 Py_ssize_t i;
744 size_t cur;
745
746 if (needed != slicelen) {
747 PyErr_Format(PyExc_ValueError,
748 "attempt to assign bytes of size %zd "
749 "to extended slice of size %zd",
750 needed, slicelen);
751 return -1;
752 }
753 for (cur = start, i = 0; i < slicelen; cur += step, i++)
754 buf[cur] = bytes[i];
755 return 0;
756 }
757 }
758 }
759
760 static int
bytearray_init(PyByteArrayObject * self,PyObject * args,PyObject * kwds)761 bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
762 {
763 static char *kwlist[] = {"source", "encoding", "errors", 0};
764 PyObject *arg = NULL;
765 const char *encoding = NULL;
766 const char *errors = NULL;
767 Py_ssize_t count;
768 PyObject *it;
769 PyObject *(*iternext)(PyObject *);
770
771 if (Py_SIZE(self) != 0) {
772 /* Empty previous contents (yes, do this first of all!) */
773 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
774 return -1;
775 }
776
777 /* Parse arguments */
778 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
779 &arg, &encoding, &errors))
780 return -1;
781
782 /* Make a quick exit if no first argument */
783 if (arg == NULL) {
784 if (encoding != NULL || errors != NULL) {
785 PyErr_SetString(PyExc_TypeError,
786 "encoding or errors without sequence argument");
787 return -1;
788 }
789 return 0;
790 }
791
792 if (PyUnicode_Check(arg)) {
793 /* Encode via the codec registry */
794 PyObject *encoded, *new;
795 if (encoding == NULL) {
796 PyErr_SetString(PyExc_TypeError,
797 "string argument without an encoding");
798 return -1;
799 }
800 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
801 if (encoded == NULL)
802 return -1;
803 assert(PyBytes_Check(encoded));
804 new = bytearray_iconcat(self, encoded);
805 Py_DECREF(encoded);
806 if (new == NULL)
807 return -1;
808 Py_DECREF(new);
809 return 0;
810 }
811
812 /* If it's not unicode, there can't be encoding or errors */
813 if (encoding != NULL || errors != NULL) {
814 PyErr_SetString(PyExc_TypeError,
815 "encoding or errors without a string argument");
816 return -1;
817 }
818
819 /* Is it an int? */
820 if (PyIndex_Check(arg)) {
821 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
822 if (count == -1 && PyErr_Occurred()) {
823 if (!PyErr_ExceptionMatches(PyExc_TypeError))
824 return -1;
825 PyErr_Clear(); /* fall through */
826 }
827 else {
828 if (count < 0) {
829 PyErr_SetString(PyExc_ValueError, "negative count");
830 return -1;
831 }
832 if (count > 0) {
833 if (PyByteArray_Resize((PyObject *)self, count))
834 return -1;
835 memset(PyByteArray_AS_STRING(self), 0, count);
836 }
837 return 0;
838 }
839 }
840
841 /* Use the buffer API */
842 if (PyObject_CheckBuffer(arg)) {
843 Py_ssize_t size;
844 Py_buffer view;
845 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
846 return -1;
847 size = view.len;
848 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
849 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
850 &view, size, 'C') < 0)
851 goto fail;
852 PyBuffer_Release(&view);
853 return 0;
854 fail:
855 PyBuffer_Release(&view);
856 return -1;
857 }
858
859 /* XXX Optimize this if the arguments is a list, tuple */
860
861 /* Get the iterator */
862 it = PyObject_GetIter(arg);
863 if (it == NULL)
864 return -1;
865 iternext = *Py_TYPE(it)->tp_iternext;
866
867 /* Run the iterator to exhaustion */
868 for (;;) {
869 PyObject *item;
870 int rc, value;
871
872 /* Get the next item */
873 item = iternext(it);
874 if (item == NULL) {
875 if (PyErr_Occurred()) {
876 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
877 goto error;
878 PyErr_Clear();
879 }
880 break;
881 }
882
883 /* Interpret it as an int (__index__) */
884 rc = _getbytevalue(item, &value);
885 Py_DECREF(item);
886 if (!rc)
887 goto error;
888
889 /* Append the byte */
890 if (Py_SIZE(self) + 1 < self->ob_alloc) {
891 Py_SIZE(self)++;
892 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
893 }
894 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
895 goto error;
896 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
897 }
898
899 /* Clean up and return success */
900 Py_DECREF(it);
901 return 0;
902
903 error:
904 /* Error handling when it != NULL */
905 Py_DECREF(it);
906 return -1;
907 }
908
909 /* Mostly copied from string_repr, but without the
910 "smart quote" functionality. */
911 static PyObject *
bytearray_repr(PyByteArrayObject * self)912 bytearray_repr(PyByteArrayObject *self)
913 {
914 const char *className = _PyType_Name(Py_TYPE(self));
915 const char *quote_prefix = "(b";
916 const char *quote_postfix = ")";
917 Py_ssize_t length = Py_SIZE(self);
918 /* 6 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
919 Py_ssize_t newsize;
920 PyObject *v;
921 Py_ssize_t i;
922 char *bytes;
923 char c;
924 char *p;
925 int quote;
926 char *test, *start;
927 char *buffer;
928
929 newsize = strlen(className);
930 if (length > (PY_SSIZE_T_MAX - 6 - newsize) / 4) {
931 PyErr_SetString(PyExc_OverflowError,
932 "bytearray object is too large to make repr");
933 return NULL;
934 }
935
936 newsize += 6 + length * 4;
937 buffer = PyObject_Malloc(newsize);
938 if (buffer == NULL) {
939 PyErr_NoMemory();
940 return NULL;
941 }
942
943 /* Figure out which quote to use; single is preferred */
944 quote = '\'';
945 start = PyByteArray_AS_STRING(self);
946 for (test = start; test < start+length; ++test) {
947 if (*test == '"') {
948 quote = '\''; /* back to single */
949 break;
950 }
951 else if (*test == '\'')
952 quote = '"';
953 }
954
955 p = buffer;
956 while (*className)
957 *p++ = *className++;
958 while (*quote_prefix)
959 *p++ = *quote_prefix++;
960 *p++ = quote;
961
962 bytes = PyByteArray_AS_STRING(self);
963 for (i = 0; i < length; i++) {
964 /* There's at least enough room for a hex escape
965 and a closing quote. */
966 assert(newsize - (p - buffer) >= 5);
967 c = bytes[i];
968 if (c == '\'' || c == '\\')
969 *p++ = '\\', *p++ = c;
970 else if (c == '\t')
971 *p++ = '\\', *p++ = 't';
972 else if (c == '\n')
973 *p++ = '\\', *p++ = 'n';
974 else if (c == '\r')
975 *p++ = '\\', *p++ = 'r';
976 else if (c == 0)
977 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
978 else if (c < ' ' || c >= 0x7f) {
979 *p++ = '\\';
980 *p++ = 'x';
981 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
982 *p++ = Py_hexdigits[c & 0xf];
983 }
984 else
985 *p++ = c;
986 }
987 assert(newsize - (p - buffer) >= 1);
988 *p++ = quote;
989 while (*quote_postfix) {
990 *p++ = *quote_postfix++;
991 }
992
993 v = PyUnicode_FromStringAndSize(buffer, p - buffer);
994 PyObject_Free(buffer);
995 return v;
996 }
997
998 static PyObject *
bytearray_str(PyObject * op)999 bytearray_str(PyObject *op)
1000 {
1001 if (Py_BytesWarningFlag) {
1002 if (PyErr_WarnEx(PyExc_BytesWarning,
1003 "str() on a bytearray instance", 1))
1004 return NULL;
1005 }
1006 return bytearray_repr((PyByteArrayObject*)op);
1007 }
1008
1009 static PyObject *
bytearray_richcompare(PyObject * self,PyObject * other,int op)1010 bytearray_richcompare(PyObject *self, PyObject *other, int op)
1011 {
1012 Py_ssize_t self_size, other_size;
1013 Py_buffer self_bytes, other_bytes;
1014 int cmp, rc;
1015
1016 /* Bytes can be compared to anything that supports the (binary)
1017 buffer API. Except that a comparison with Unicode is always an
1018 error, even if the comparison is for equality. */
1019 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1020 if (!rc)
1021 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1022 if (rc < 0)
1023 return NULL;
1024 if (rc) {
1025 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
1026 if (PyErr_WarnEx(PyExc_BytesWarning,
1027 "Comparison between bytearray and string", 1))
1028 return NULL;
1029 }
1030
1031 Py_RETURN_NOTIMPLEMENTED;
1032 }
1033
1034 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1035 PyErr_Clear();
1036 Py_RETURN_NOTIMPLEMENTED;
1037 }
1038 self_size = self_bytes.len;
1039
1040 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1041 PyErr_Clear();
1042 PyBuffer_Release(&self_bytes);
1043 Py_RETURN_NOTIMPLEMENTED;
1044 }
1045 other_size = other_bytes.len;
1046
1047 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1048 /* Shortcut: if the lengths differ, the objects differ */
1049 PyBuffer_Release(&self_bytes);
1050 PyBuffer_Release(&other_bytes);
1051 return PyBool_FromLong((op == Py_NE));
1052 }
1053 else {
1054 cmp = memcmp(self_bytes.buf, other_bytes.buf,
1055 Py_MIN(self_size, other_size));
1056 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1057
1058 PyBuffer_Release(&self_bytes);
1059 PyBuffer_Release(&other_bytes);
1060
1061 if (cmp != 0) {
1062 Py_RETURN_RICHCOMPARE(cmp, 0, op);
1063 }
1064
1065 Py_RETURN_RICHCOMPARE(self_size, other_size, op);
1066 }
1067
1068 }
1069
1070 static void
bytearray_dealloc(PyByteArrayObject * self)1071 bytearray_dealloc(PyByteArrayObject *self)
1072 {
1073 if (self->ob_exports > 0) {
1074 PyErr_SetString(PyExc_SystemError,
1075 "deallocated bytearray object has exported buffers");
1076 PyErr_Print();
1077 }
1078 if (self->ob_bytes != 0) {
1079 PyObject_Free(self->ob_bytes);
1080 }
1081 Py_TYPE(self)->tp_free((PyObject *)self);
1082 }
1083
1084
1085 /* -------------------------------------------------------------------- */
1086 /* Methods */
1087
1088 #define FASTSEARCH fastsearch
1089 #define STRINGLIB(F) stringlib_##F
1090 #define STRINGLIB_CHAR char
1091 #define STRINGLIB_SIZEOF_CHAR 1
1092 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1093 #define STRINGLIB_STR PyByteArray_AS_STRING
1094 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1095 #define STRINGLIB_ISSPACE Py_ISSPACE
1096 #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1097 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1098 #define STRINGLIB_MUTABLE 1
1099
1100 #include "stringlib/fastsearch.h"
1101 #include "stringlib/count.h"
1102 #include "stringlib/find.h"
1103 #include "stringlib/join.h"
1104 #include "stringlib/partition.h"
1105 #include "stringlib/split.h"
1106 #include "stringlib/ctype.h"
1107 #include "stringlib/transmogrify.h"
1108
1109
1110 static PyObject *
bytearray_find(PyByteArrayObject * self,PyObject * args)1111 bytearray_find(PyByteArrayObject *self, PyObject *args)
1112 {
1113 return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1114 }
1115
1116 static PyObject *
bytearray_count(PyByteArrayObject * self,PyObject * args)1117 bytearray_count(PyByteArrayObject *self, PyObject *args)
1118 {
1119 return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1120 }
1121
1122 /*[clinic input]
1123 bytearray.clear
1124
1125 Remove all items from the bytearray.
1126 [clinic start generated code]*/
1127
1128 static PyObject *
bytearray_clear_impl(PyByteArrayObject * self)1129 bytearray_clear_impl(PyByteArrayObject *self)
1130 /*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
1131 {
1132 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1133 return NULL;
1134 Py_RETURN_NONE;
1135 }
1136
1137 /*[clinic input]
1138 bytearray.copy
1139
1140 Return a copy of B.
1141 [clinic start generated code]*/
1142
1143 static PyObject *
bytearray_copy_impl(PyByteArrayObject * self)1144 bytearray_copy_impl(PyByteArrayObject *self)
1145 /*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/
1146 {
1147 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1148 PyByteArray_GET_SIZE(self));
1149 }
1150
1151 static PyObject *
bytearray_index(PyByteArrayObject * self,PyObject * args)1152 bytearray_index(PyByteArrayObject *self, PyObject *args)
1153 {
1154 return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1155 }
1156
1157 static PyObject *
bytearray_rfind(PyByteArrayObject * self,PyObject * args)1158 bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1159 {
1160 return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1161 }
1162
1163 static PyObject *
bytearray_rindex(PyByteArrayObject * self,PyObject * args)1164 bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1165 {
1166 return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1167 }
1168
1169 static int
bytearray_contains(PyObject * self,PyObject * arg)1170 bytearray_contains(PyObject *self, PyObject *arg)
1171 {
1172 return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg);
1173 }
1174
1175 static PyObject *
bytearray_startswith(PyByteArrayObject * self,PyObject * args)1176 bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1177 {
1178 return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1179 }
1180
1181 static PyObject *
bytearray_endswith(PyByteArrayObject * self,PyObject * args)1182 bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1183 {
1184 return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1185 }
1186
1187
1188 /*[clinic input]
1189 bytearray.translate
1190
1191 table: object
1192 Translation table, which must be a bytes object of length 256.
1193 /
1194 delete as deletechars: object(c_default="NULL") = b''
1195
1196 Return a copy with each character mapped by the given translation table.
1197
1198 All characters occurring in the optional argument delete are removed.
1199 The remaining characters are mapped through the given translation table.
1200 [clinic start generated code]*/
1201
1202 static PyObject *
bytearray_translate_impl(PyByteArrayObject * self,PyObject * table,PyObject * deletechars)1203 bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1204 PyObject *deletechars)
1205 /*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/
1206 {
1207 char *input, *output;
1208 const char *table_chars;
1209 Py_ssize_t i, c;
1210 PyObject *input_obj = (PyObject*)self;
1211 const char *output_start;
1212 Py_ssize_t inlen;
1213 PyObject *result = NULL;
1214 int trans_table[256];
1215 Py_buffer vtable, vdel;
1216
1217 if (table == Py_None) {
1218 table_chars = NULL;
1219 table = NULL;
1220 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1221 return NULL;
1222 } else {
1223 if (vtable.len != 256) {
1224 PyErr_SetString(PyExc_ValueError,
1225 "translation table must be 256 characters long");
1226 PyBuffer_Release(&vtable);
1227 return NULL;
1228 }
1229 table_chars = (const char*)vtable.buf;
1230 }
1231
1232 if (deletechars != NULL) {
1233 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1234 if (table != NULL)
1235 PyBuffer_Release(&vtable);
1236 return NULL;
1237 }
1238 }
1239 else {
1240 vdel.buf = NULL;
1241 vdel.len = 0;
1242 }
1243
1244 inlen = PyByteArray_GET_SIZE(input_obj);
1245 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1246 if (result == NULL)
1247 goto done;
1248 output_start = output = PyByteArray_AS_STRING(result);
1249 input = PyByteArray_AS_STRING(input_obj);
1250
1251 if (vdel.len == 0 && table_chars != NULL) {
1252 /* If no deletions are required, use faster code */
1253 for (i = inlen; --i >= 0; ) {
1254 c = Py_CHARMASK(*input++);
1255 *output++ = table_chars[c];
1256 }
1257 goto done;
1258 }
1259
1260 if (table_chars == NULL) {
1261 for (i = 0; i < 256; i++)
1262 trans_table[i] = Py_CHARMASK(i);
1263 } else {
1264 for (i = 0; i < 256; i++)
1265 trans_table[i] = Py_CHARMASK(table_chars[i]);
1266 }
1267
1268 for (i = 0; i < vdel.len; i++)
1269 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1270
1271 for (i = inlen; --i >= 0; ) {
1272 c = Py_CHARMASK(*input++);
1273 if (trans_table[c] != -1)
1274 *output++ = (char)trans_table[c];
1275 }
1276 /* Fix the size of the resulting string */
1277 if (inlen > 0)
1278 if (PyByteArray_Resize(result, output - output_start) < 0) {
1279 Py_CLEAR(result);
1280 goto done;
1281 }
1282
1283 done:
1284 if (table != NULL)
1285 PyBuffer_Release(&vtable);
1286 if (deletechars != NULL)
1287 PyBuffer_Release(&vdel);
1288 return result;
1289 }
1290
1291
1292 /*[clinic input]
1293
1294 @staticmethod
1295 bytearray.maketrans
1296
1297 frm: Py_buffer
1298 to: Py_buffer
1299 /
1300
1301 Return a translation table useable for the bytes or bytearray translate method.
1302
1303 The returned table will be one where each byte in frm is mapped to the byte at
1304 the same position in to.
1305
1306 The bytes objects frm and to must be of the same length.
1307 [clinic start generated code]*/
1308
1309 static PyObject *
bytearray_maketrans_impl(Py_buffer * frm,Py_buffer * to)1310 bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1311 /*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
1312 {
1313 return _Py_bytes_maketrans(frm, to);
1314 }
1315
1316
1317 /*[clinic input]
1318 bytearray.replace
1319
1320 old: Py_buffer
1321 new: Py_buffer
1322 count: Py_ssize_t = -1
1323 Maximum number of occurrences to replace.
1324 -1 (the default value) means replace all occurrences.
1325 /
1326
1327 Return a copy with all occurrences of substring old replaced by new.
1328
1329 If the optional argument count is given, only the first count occurrences are
1330 replaced.
1331 [clinic start generated code]*/
1332
1333 static PyObject *
bytearray_replace_impl(PyByteArrayObject * self,Py_buffer * old,Py_buffer * new,Py_ssize_t count)1334 bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
1335 Py_buffer *new, Py_ssize_t count)
1336 /*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
1337 {
1338 return stringlib_replace((PyObject *)self,
1339 (const char *)old->buf, old->len,
1340 (const char *)new->buf, new->len, count);
1341 }
1342
1343 /*[clinic input]
1344 bytearray.split
1345
1346 sep: object = None
1347 The delimiter according which to split the bytearray.
1348 None (the default value) means split on ASCII whitespace characters
1349 (space, tab, return, newline, formfeed, vertical tab).
1350 maxsplit: Py_ssize_t = -1
1351 Maximum number of splits to do.
1352 -1 (the default value) means no limit.
1353
1354 Return a list of the sections in the bytearray, using sep as the delimiter.
1355 [clinic start generated code]*/
1356
1357 static PyObject *
bytearray_split_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1358 bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1359 Py_ssize_t maxsplit)
1360 /*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
1361 {
1362 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1363 const char *s = PyByteArray_AS_STRING(self), *sub;
1364 PyObject *list;
1365 Py_buffer vsub;
1366
1367 if (maxsplit < 0)
1368 maxsplit = PY_SSIZE_T_MAX;
1369
1370 if (sep == Py_None)
1371 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
1372
1373 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1374 return NULL;
1375 sub = vsub.buf;
1376 n = vsub.len;
1377
1378 list = stringlib_split(
1379 (PyObject*) self, s, len, sub, n, maxsplit
1380 );
1381 PyBuffer_Release(&vsub);
1382 return list;
1383 }
1384
1385 /*[clinic input]
1386 bytearray.partition
1387
1388 sep: object
1389 /
1390
1391 Partition the bytearray into three parts using the given separator.
1392
1393 This will search for the separator sep in the bytearray. If the separator is
1394 found, returns a 3-tuple containing the part before the separator, the
1395 separator itself, and the part after it as new bytearray objects.
1396
1397 If the separator is not found, returns a 3-tuple containing the copy of the
1398 original bytearray object and two empty bytearray objects.
1399 [clinic start generated code]*/
1400
1401 static PyObject *
bytearray_partition(PyByteArrayObject * self,PyObject * sep)1402 bytearray_partition(PyByteArrayObject *self, PyObject *sep)
1403 /*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
1404 {
1405 PyObject *bytesep, *result;
1406
1407 bytesep = _PyByteArray_FromBufferObject(sep);
1408 if (! bytesep)
1409 return NULL;
1410
1411 result = stringlib_partition(
1412 (PyObject*) self,
1413 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1414 bytesep,
1415 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1416 );
1417
1418 Py_DECREF(bytesep);
1419 return result;
1420 }
1421
1422 /*[clinic input]
1423 bytearray.rpartition
1424
1425 sep: object
1426 /
1427
1428 Partition the bytearray into three parts using the given separator.
1429
1430 This will search for the separator sep in the bytearray, starting at the end.
1431 If the separator is found, returns a 3-tuple containing the part before the
1432 separator, the separator itself, and the part after it as new bytearray
1433 objects.
1434
1435 If the separator is not found, returns a 3-tuple containing two empty bytearray
1436 objects and the copy of the original bytearray object.
1437 [clinic start generated code]*/
1438
1439 static PyObject *
bytearray_rpartition(PyByteArrayObject * self,PyObject * sep)1440 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
1441 /*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
1442 {
1443 PyObject *bytesep, *result;
1444
1445 bytesep = _PyByteArray_FromBufferObject(sep);
1446 if (! bytesep)
1447 return NULL;
1448
1449 result = stringlib_rpartition(
1450 (PyObject*) self,
1451 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1452 bytesep,
1453 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1454 );
1455
1456 Py_DECREF(bytesep);
1457 return result;
1458 }
1459
1460 /*[clinic input]
1461 bytearray.rsplit = bytearray.split
1462
1463 Return a list of the sections in the bytearray, using sep as the delimiter.
1464
1465 Splitting is done starting at the end of the bytearray and working to the front.
1466 [clinic start generated code]*/
1467
1468 static PyObject *
bytearray_rsplit_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1469 bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
1470 Py_ssize_t maxsplit)
1471 /*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
1472 {
1473 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1474 const char *s = PyByteArray_AS_STRING(self), *sub;
1475 PyObject *list;
1476 Py_buffer vsub;
1477
1478 if (maxsplit < 0)
1479 maxsplit = PY_SSIZE_T_MAX;
1480
1481 if (sep == Py_None)
1482 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
1483
1484 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1485 return NULL;
1486 sub = vsub.buf;
1487 n = vsub.len;
1488
1489 list = stringlib_rsplit(
1490 (PyObject*) self, s, len, sub, n, maxsplit
1491 );
1492 PyBuffer_Release(&vsub);
1493 return list;
1494 }
1495
1496 /*[clinic input]
1497 bytearray.reverse
1498
1499 Reverse the order of the values in B in place.
1500 [clinic start generated code]*/
1501
1502 static PyObject *
bytearray_reverse_impl(PyByteArrayObject * self)1503 bytearray_reverse_impl(PyByteArrayObject *self)
1504 /*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/
1505 {
1506 char swap, *head, *tail;
1507 Py_ssize_t i, j, n = Py_SIZE(self);
1508
1509 j = n / 2;
1510 head = PyByteArray_AS_STRING(self);
1511 tail = head + n - 1;
1512 for (i = 0; i < j; i++) {
1513 swap = *head;
1514 *head++ = *tail;
1515 *tail-- = swap;
1516 }
1517
1518 Py_RETURN_NONE;
1519 }
1520
1521
1522 /*[python input]
1523 class bytesvalue_converter(CConverter):
1524 type = 'int'
1525 converter = '_getbytevalue'
1526 [python start generated code]*/
1527 /*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
1528
1529
1530 /*[clinic input]
1531 bytearray.insert
1532
1533 index: Py_ssize_t
1534 The index where the value is to be inserted.
1535 item: bytesvalue
1536 The item to be inserted.
1537 /
1538
1539 Insert a single item into the bytearray before the given index.
1540 [clinic start generated code]*/
1541
1542 static PyObject *
bytearray_insert_impl(PyByteArrayObject * self,Py_ssize_t index,int item)1543 bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
1544 /*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/
1545 {
1546 Py_ssize_t n = Py_SIZE(self);
1547 char *buf;
1548
1549 if (n == PY_SSIZE_T_MAX) {
1550 PyErr_SetString(PyExc_OverflowError,
1551 "cannot add more objects to bytearray");
1552 return NULL;
1553 }
1554 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1555 return NULL;
1556 buf = PyByteArray_AS_STRING(self);
1557
1558 if (index < 0) {
1559 index += n;
1560 if (index < 0)
1561 index = 0;
1562 }
1563 if (index > n)
1564 index = n;
1565 memmove(buf + index + 1, buf + index, n - index);
1566 buf[index] = item;
1567
1568 Py_RETURN_NONE;
1569 }
1570
1571 /*[clinic input]
1572 bytearray.append
1573
1574 item: bytesvalue
1575 The item to be appended.
1576 /
1577
1578 Append a single item to the end of the bytearray.
1579 [clinic start generated code]*/
1580
1581 static PyObject *
bytearray_append_impl(PyByteArrayObject * self,int item)1582 bytearray_append_impl(PyByteArrayObject *self, int item)
1583 /*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/
1584 {
1585 Py_ssize_t n = Py_SIZE(self);
1586
1587 if (n == PY_SSIZE_T_MAX) {
1588 PyErr_SetString(PyExc_OverflowError,
1589 "cannot add more objects to bytearray");
1590 return NULL;
1591 }
1592 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1593 return NULL;
1594
1595 PyByteArray_AS_STRING(self)[n] = item;
1596
1597 Py_RETURN_NONE;
1598 }
1599
1600 /*[clinic input]
1601 bytearray.extend
1602
1603 iterable_of_ints: object
1604 The iterable of items to append.
1605 /
1606
1607 Append all the items from the iterator or sequence to the end of the bytearray.
1608 [clinic start generated code]*/
1609
1610 static PyObject *
bytearray_extend(PyByteArrayObject * self,PyObject * iterable_of_ints)1611 bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
1612 /*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/
1613 {
1614 PyObject *it, *item, *bytearray_obj;
1615 Py_ssize_t buf_size = 0, len = 0;
1616 int value;
1617 char *buf;
1618
1619 /* bytearray_setslice code only accepts something supporting PEP 3118. */
1620 if (PyObject_CheckBuffer(iterable_of_ints)) {
1621 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
1622 return NULL;
1623
1624 Py_RETURN_NONE;
1625 }
1626
1627 it = PyObject_GetIter(iterable_of_ints);
1628 if (it == NULL)
1629 return NULL;
1630
1631 /* Try to determine the length of the argument. 32 is arbitrary. */
1632 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
1633 if (buf_size == -1) {
1634 Py_DECREF(it);
1635 return NULL;
1636 }
1637
1638 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
1639 if (bytearray_obj == NULL) {
1640 Py_DECREF(it);
1641 return NULL;
1642 }
1643 buf = PyByteArray_AS_STRING(bytearray_obj);
1644
1645 while ((item = PyIter_Next(it)) != NULL) {
1646 if (! _getbytevalue(item, &value)) {
1647 Py_DECREF(item);
1648 Py_DECREF(it);
1649 Py_DECREF(bytearray_obj);
1650 return NULL;
1651 }
1652 buf[len++] = value;
1653 Py_DECREF(item);
1654
1655 if (len >= buf_size) {
1656 Py_ssize_t addition;
1657 if (len == PY_SSIZE_T_MAX) {
1658 Py_DECREF(it);
1659 Py_DECREF(bytearray_obj);
1660 return PyErr_NoMemory();
1661 }
1662 addition = len >> 1;
1663 if (addition > PY_SSIZE_T_MAX - len - 1)
1664 buf_size = PY_SSIZE_T_MAX;
1665 else
1666 buf_size = len + addition + 1;
1667 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
1668 Py_DECREF(it);
1669 Py_DECREF(bytearray_obj);
1670 return NULL;
1671 }
1672 /* Recompute the `buf' pointer, since the resizing operation may
1673 have invalidated it. */
1674 buf = PyByteArray_AS_STRING(bytearray_obj);
1675 }
1676 }
1677 Py_DECREF(it);
1678
1679 /* Resize down to exact size. */
1680 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
1681 Py_DECREF(bytearray_obj);
1682 return NULL;
1683 }
1684
1685 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
1686 Py_DECREF(bytearray_obj);
1687 return NULL;
1688 }
1689 Py_DECREF(bytearray_obj);
1690
1691 Py_RETURN_NONE;
1692 }
1693
1694 /*[clinic input]
1695 bytearray.pop
1696
1697 index: Py_ssize_t = -1
1698 The index from where to remove the item.
1699 -1 (the default value) means remove the last item.
1700 /
1701
1702 Remove and return a single item from B.
1703
1704 If no index argument is given, will pop the last item.
1705 [clinic start generated code]*/
1706
1707 static PyObject *
bytearray_pop_impl(PyByteArrayObject * self,Py_ssize_t index)1708 bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
1709 /*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/
1710 {
1711 int value;
1712 Py_ssize_t n = Py_SIZE(self);
1713 char *buf;
1714
1715 if (n == 0) {
1716 PyErr_SetString(PyExc_IndexError,
1717 "pop from empty bytearray");
1718 return NULL;
1719 }
1720 if (index < 0)
1721 index += Py_SIZE(self);
1722 if (index < 0 || index >= Py_SIZE(self)) {
1723 PyErr_SetString(PyExc_IndexError, "pop index out of range");
1724 return NULL;
1725 }
1726 if (!_canresize(self))
1727 return NULL;
1728
1729 buf = PyByteArray_AS_STRING(self);
1730 value = buf[index];
1731 memmove(buf + index, buf + index + 1, n - index);
1732 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1733 return NULL;
1734
1735 return PyLong_FromLong((unsigned char)value);
1736 }
1737
1738 /*[clinic input]
1739 bytearray.remove
1740
1741 value: bytesvalue
1742 The value to remove.
1743 /
1744
1745 Remove the first occurrence of a value in the bytearray.
1746 [clinic start generated code]*/
1747
1748 static PyObject *
bytearray_remove_impl(PyByteArrayObject * self,int value)1749 bytearray_remove_impl(PyByteArrayObject *self, int value)
1750 /*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/
1751 {
1752 Py_ssize_t where, n = Py_SIZE(self);
1753 char *buf = PyByteArray_AS_STRING(self);
1754
1755 where = stringlib_find_char(buf, n, value);
1756 if (where < 0) {
1757 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
1758 return NULL;
1759 }
1760 if (!_canresize(self))
1761 return NULL;
1762
1763 memmove(buf + where, buf + where + 1, n - where);
1764 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1765 return NULL;
1766
1767 Py_RETURN_NONE;
1768 }
1769
1770 /* XXX These two helpers could be optimized if argsize == 1 */
1771
1772 static Py_ssize_t
lstrip_helper(const char * myptr,Py_ssize_t mysize,const void * argptr,Py_ssize_t argsize)1773 lstrip_helper(const char *myptr, Py_ssize_t mysize,
1774 const void *argptr, Py_ssize_t argsize)
1775 {
1776 Py_ssize_t i = 0;
1777 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
1778 i++;
1779 return i;
1780 }
1781
1782 static Py_ssize_t
rstrip_helper(const char * myptr,Py_ssize_t mysize,const void * argptr,Py_ssize_t argsize)1783 rstrip_helper(const char *myptr, Py_ssize_t mysize,
1784 const void *argptr, Py_ssize_t argsize)
1785 {
1786 Py_ssize_t i = mysize - 1;
1787 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
1788 i--;
1789 return i + 1;
1790 }
1791
1792 /*[clinic input]
1793 bytearray.strip
1794
1795 bytes: object = None
1796 /
1797
1798 Strip leading and trailing bytes contained in the argument.
1799
1800 If the argument is omitted or None, strip leading and trailing ASCII whitespace.
1801 [clinic start generated code]*/
1802
1803 static PyObject *
bytearray_strip_impl(PyByteArrayObject * self,PyObject * bytes)1804 bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
1805 /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
1806 {
1807 Py_ssize_t left, right, mysize, byteslen;
1808 char *myptr;
1809 const char *bytesptr;
1810 Py_buffer vbytes;
1811
1812 if (bytes == Py_None) {
1813 bytesptr = "\t\n\r\f\v ";
1814 byteslen = 6;
1815 }
1816 else {
1817 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1818 return NULL;
1819 bytesptr = (const char *) vbytes.buf;
1820 byteslen = vbytes.len;
1821 }
1822 myptr = PyByteArray_AS_STRING(self);
1823 mysize = Py_SIZE(self);
1824 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
1825 if (left == mysize)
1826 right = left;
1827 else
1828 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
1829 if (bytes != Py_None)
1830 PyBuffer_Release(&vbytes);
1831 return PyByteArray_FromStringAndSize(myptr + left, right - left);
1832 }
1833
1834 /*[clinic input]
1835 bytearray.lstrip
1836
1837 bytes: object = None
1838 /
1839
1840 Strip leading bytes contained in the argument.
1841
1842 If the argument is omitted or None, strip leading ASCII whitespace.
1843 [clinic start generated code]*/
1844
1845 static PyObject *
bytearray_lstrip_impl(PyByteArrayObject * self,PyObject * bytes)1846 bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
1847 /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
1848 {
1849 Py_ssize_t left, right, mysize, byteslen;
1850 char *myptr;
1851 const char *bytesptr;
1852 Py_buffer vbytes;
1853
1854 if (bytes == Py_None) {
1855 bytesptr = "\t\n\r\f\v ";
1856 byteslen = 6;
1857 }
1858 else {
1859 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1860 return NULL;
1861 bytesptr = (const char *) vbytes.buf;
1862 byteslen = vbytes.len;
1863 }
1864 myptr = PyByteArray_AS_STRING(self);
1865 mysize = Py_SIZE(self);
1866 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
1867 right = mysize;
1868 if (bytes != Py_None)
1869 PyBuffer_Release(&vbytes);
1870 return PyByteArray_FromStringAndSize(myptr + left, right - left);
1871 }
1872
1873 /*[clinic input]
1874 bytearray.rstrip
1875
1876 bytes: object = None
1877 /
1878
1879 Strip trailing bytes contained in the argument.
1880
1881 If the argument is omitted or None, strip trailing ASCII whitespace.
1882 [clinic start generated code]*/
1883
1884 static PyObject *
bytearray_rstrip_impl(PyByteArrayObject * self,PyObject * bytes)1885 bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
1886 /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
1887 {
1888 Py_ssize_t right, mysize, byteslen;
1889 char *myptr;
1890 const char *bytesptr;
1891 Py_buffer vbytes;
1892
1893 if (bytes == Py_None) {
1894 bytesptr = "\t\n\r\f\v ";
1895 byteslen = 6;
1896 }
1897 else {
1898 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1899 return NULL;
1900 bytesptr = (const char *) vbytes.buf;
1901 byteslen = vbytes.len;
1902 }
1903 myptr = PyByteArray_AS_STRING(self);
1904 mysize = Py_SIZE(self);
1905 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
1906 if (bytes != Py_None)
1907 PyBuffer_Release(&vbytes);
1908 return PyByteArray_FromStringAndSize(myptr, right);
1909 }
1910
1911 /*[clinic input]
1912 bytearray.decode
1913
1914 encoding: str(c_default="NULL") = 'utf-8'
1915 The encoding with which to decode the bytearray.
1916 errors: str(c_default="NULL") = 'strict'
1917 The error handling scheme to use for the handling of decoding errors.
1918 The default is 'strict' meaning that decoding errors raise a
1919 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
1920 as well as any other name registered with codecs.register_error that
1921 can handle UnicodeDecodeErrors.
1922
1923 Decode the bytearray using the codec registered for encoding.
1924 [clinic start generated code]*/
1925
1926 static PyObject *
bytearray_decode_impl(PyByteArrayObject * self,const char * encoding,const char * errors)1927 bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
1928 const char *errors)
1929 /*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
1930 {
1931 if (encoding == NULL)
1932 encoding = PyUnicode_GetDefaultEncoding();
1933 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
1934 }
1935
1936 PyDoc_STRVAR(alloc_doc,
1937 "B.__alloc__() -> int\n\
1938 \n\
1939 Return the number of bytes actually allocated.");
1940
1941 static PyObject *
bytearray_alloc(PyByteArrayObject * self)1942 bytearray_alloc(PyByteArrayObject *self)
1943 {
1944 return PyLong_FromSsize_t(self->ob_alloc);
1945 }
1946
1947 /*[clinic input]
1948 bytearray.join
1949
1950 iterable_of_bytes: object
1951 /
1952
1953 Concatenate any number of bytes/bytearray objects.
1954
1955 The bytearray whose method is called is inserted in between each pair.
1956
1957 The result is returned as a new bytearray object.
1958 [clinic start generated code]*/
1959
1960 static PyObject *
bytearray_join(PyByteArrayObject * self,PyObject * iterable_of_bytes)1961 bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
1962 /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
1963 {
1964 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
1965 }
1966
1967 /*[clinic input]
1968 bytearray.splitlines
1969
1970 keepends: bool(accept={int}) = False
1971
1972 Return a list of the lines in the bytearray, breaking at line boundaries.
1973
1974 Line breaks are not included in the resulting list unless keepends is given and
1975 true.
1976 [clinic start generated code]*/
1977
1978 static PyObject *
bytearray_splitlines_impl(PyByteArrayObject * self,int keepends)1979 bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
1980 /*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/
1981 {
1982 return stringlib_splitlines(
1983 (PyObject*) self, PyByteArray_AS_STRING(self),
1984 PyByteArray_GET_SIZE(self), keepends
1985 );
1986 }
1987
1988 /*[clinic input]
1989 @classmethod
1990 bytearray.fromhex
1991
1992 string: unicode
1993 /
1994
1995 Create a bytearray object from a string of hexadecimal numbers.
1996
1997 Spaces between two numbers are accepted.
1998 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
1999 [clinic start generated code]*/
2000
2001 static PyObject *
bytearray_fromhex_impl(PyTypeObject * type,PyObject * string)2002 bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2003 /*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/
2004 {
2005 PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2006 if (type != &PyByteArray_Type && result != NULL) {
2007 Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type,
2008 result, NULL));
2009 }
2010 return result;
2011 }
2012
2013 PyDoc_STRVAR(hex__doc__,
2014 "B.hex() -> string\n\
2015 \n\
2016 Create a string of hexadecimal numbers from a bytearray object.\n\
2017 Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'.");
2018
2019 static PyObject *
bytearray_hex(PyBytesObject * self)2020 bytearray_hex(PyBytesObject *self)
2021 {
2022 char* argbuf = PyByteArray_AS_STRING(self);
2023 Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2024 return _Py_strhex(argbuf, arglen);
2025 }
2026
2027 static PyObject *
_common_reduce(PyByteArrayObject * self,int proto)2028 _common_reduce(PyByteArrayObject *self, int proto)
2029 {
2030 PyObject *dict;
2031 _Py_IDENTIFIER(__dict__);
2032 char *buf;
2033
2034 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
2035 if (dict == NULL) {
2036 PyErr_Clear();
2037 dict = Py_None;
2038 Py_INCREF(dict);
2039 }
2040
2041 buf = PyByteArray_AS_STRING(self);
2042 if (proto < 3) {
2043 /* use str based reduction for backwards compatibility with Python 2.x */
2044 PyObject *latin1;
2045 if (Py_SIZE(self))
2046 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2047 else
2048 latin1 = PyUnicode_FromString("");
2049 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2050 }
2051 else {
2052 /* use more efficient byte based reduction */
2053 if (Py_SIZE(self)) {
2054 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
2055 }
2056 else {
2057 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2058 }
2059 }
2060 }
2061
2062 /*[clinic input]
2063 bytearray.__reduce__ as bytearray_reduce
2064
2065 Return state information for pickling.
2066 [clinic start generated code]*/
2067
2068 static PyObject *
bytearray_reduce_impl(PyByteArrayObject * self)2069 bytearray_reduce_impl(PyByteArrayObject *self)
2070 /*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/
2071 {
2072 return _common_reduce(self, 2);
2073 }
2074
2075 /*[clinic input]
2076 bytearray.__reduce_ex__ as bytearray_reduce_ex
2077
2078 proto: int = 0
2079 /
2080
2081 Return state information for pickling.
2082 [clinic start generated code]*/
2083
2084 static PyObject *
bytearray_reduce_ex_impl(PyByteArrayObject * self,int proto)2085 bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2086 /*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/
2087 {
2088 return _common_reduce(self, proto);
2089 }
2090
2091 /*[clinic input]
2092 bytearray.__sizeof__ as bytearray_sizeof
2093
2094 Returns the size of the bytearray object in memory, in bytes.
2095 [clinic start generated code]*/
2096
2097 static PyObject *
bytearray_sizeof_impl(PyByteArrayObject * self)2098 bytearray_sizeof_impl(PyByteArrayObject *self)
2099 /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
2100 {
2101 Py_ssize_t res;
2102
2103 res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
2104 return PyLong_FromSsize_t(res);
2105 }
2106
2107 static PySequenceMethods bytearray_as_sequence = {
2108 (lenfunc)bytearray_length, /* sq_length */
2109 (binaryfunc)PyByteArray_Concat, /* sq_concat */
2110 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2111 (ssizeargfunc)bytearray_getitem, /* sq_item */
2112 0, /* sq_slice */
2113 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2114 0, /* sq_ass_slice */
2115 (objobjproc)bytearray_contains, /* sq_contains */
2116 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2117 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
2118 };
2119
2120 static PyMappingMethods bytearray_as_mapping = {
2121 (lenfunc)bytearray_length,
2122 (binaryfunc)bytearray_subscript,
2123 (objobjargproc)bytearray_ass_subscript,
2124 };
2125
2126 static PyBufferProcs bytearray_as_buffer = {
2127 (getbufferproc)bytearray_getbuffer,
2128 (releasebufferproc)bytearray_releasebuffer,
2129 };
2130
2131 static PyMethodDef
2132 bytearray_methods[] = {
2133 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2134 BYTEARRAY_REDUCE_METHODDEF
2135 BYTEARRAY_REDUCE_EX_METHODDEF
2136 BYTEARRAY_SIZEOF_METHODDEF
2137 BYTEARRAY_APPEND_METHODDEF
2138 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
2139 _Py_capitalize__doc__},
2140 {"center", (PyCFunction)stringlib_center, METH_VARARGS, _Py_center__doc__},
2141 BYTEARRAY_CLEAR_METHODDEF
2142 BYTEARRAY_COPY_METHODDEF
2143 {"count", (PyCFunction)bytearray_count, METH_VARARGS,
2144 _Py_count__doc__},
2145 BYTEARRAY_DECODE_METHODDEF
2146 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS,
2147 _Py_endswith__doc__},
2148 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
2149 _Py_expandtabs__doc__},
2150 BYTEARRAY_EXTEND_METHODDEF
2151 {"find", (PyCFunction)bytearray_find, METH_VARARGS,
2152 _Py_find__doc__},
2153 BYTEARRAY_FROMHEX_METHODDEF
2154 {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__},
2155 {"index", (PyCFunction)bytearray_index, METH_VARARGS, _Py_index__doc__},
2156 BYTEARRAY_INSERT_METHODDEF
2157 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
2158 _Py_isalnum__doc__},
2159 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
2160 _Py_isalpha__doc__},
2161 {"isascii", (PyCFunction)stringlib_isascii, METH_NOARGS,
2162 _Py_isascii__doc__},
2163 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
2164 _Py_isdigit__doc__},
2165 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
2166 _Py_islower__doc__},
2167 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
2168 _Py_isspace__doc__},
2169 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
2170 _Py_istitle__doc__},
2171 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
2172 _Py_isupper__doc__},
2173 BYTEARRAY_JOIN_METHODDEF
2174 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, _Py_ljust__doc__},
2175 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
2176 BYTEARRAY_LSTRIP_METHODDEF
2177 BYTEARRAY_MAKETRANS_METHODDEF
2178 BYTEARRAY_PARTITION_METHODDEF
2179 BYTEARRAY_POP_METHODDEF
2180 BYTEARRAY_REMOVE_METHODDEF
2181 BYTEARRAY_REPLACE_METHODDEF
2182 BYTEARRAY_REVERSE_METHODDEF
2183 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, _Py_rfind__doc__},
2184 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, _Py_rindex__doc__},
2185 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, _Py_rjust__doc__},
2186 BYTEARRAY_RPARTITION_METHODDEF
2187 BYTEARRAY_RSPLIT_METHODDEF
2188 BYTEARRAY_RSTRIP_METHODDEF
2189 BYTEARRAY_SPLIT_METHODDEF
2190 BYTEARRAY_SPLITLINES_METHODDEF
2191 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
2192 _Py_startswith__doc__},
2193 BYTEARRAY_STRIP_METHODDEF
2194 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
2195 _Py_swapcase__doc__},
2196 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
2197 BYTEARRAY_TRANSLATE_METHODDEF
2198 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2199 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, _Py_zfill__doc__},
2200 {NULL}
2201 };
2202
2203 static PyObject *
bytearray_mod(PyObject * v,PyObject * w)2204 bytearray_mod(PyObject *v, PyObject *w)
2205 {
2206 if (!PyByteArray_Check(v))
2207 Py_RETURN_NOTIMPLEMENTED;
2208 return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
2209 }
2210
2211 static PyNumberMethods bytearray_as_number = {
2212 0, /*nb_add*/
2213 0, /*nb_subtract*/
2214 0, /*nb_multiply*/
2215 bytearray_mod, /*nb_remainder*/
2216 };
2217
2218 PyDoc_STRVAR(bytearray_doc,
2219 "bytearray(iterable_of_ints) -> bytearray\n\
2220 bytearray(string, encoding[, errors]) -> bytearray\n\
2221 bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2222 bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2223 bytearray() -> empty bytes array\n\
2224 \n\
2225 Construct a mutable bytearray object from:\n\
2226 - an iterable yielding integers in range(256)\n\
2227 - a text string encoded using the specified encoding\n\
2228 - a bytes or a buffer object\n\
2229 - any object implementing the buffer API.\n\
2230 - an integer");
2231
2232
2233 static PyObject *bytearray_iter(PyObject *seq);
2234
2235 PyTypeObject PyByteArray_Type = {
2236 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2237 "bytearray",
2238 sizeof(PyByteArrayObject),
2239 0,
2240 (destructor)bytearray_dealloc, /* tp_dealloc */
2241 0, /* tp_print */
2242 0, /* tp_getattr */
2243 0, /* tp_setattr */
2244 0, /* tp_reserved */
2245 (reprfunc)bytearray_repr, /* tp_repr */
2246 &bytearray_as_number, /* tp_as_number */
2247 &bytearray_as_sequence, /* tp_as_sequence */
2248 &bytearray_as_mapping, /* tp_as_mapping */
2249 0, /* tp_hash */
2250 0, /* tp_call */
2251 bytearray_str, /* tp_str */
2252 PyObject_GenericGetAttr, /* tp_getattro */
2253 0, /* tp_setattro */
2254 &bytearray_as_buffer, /* tp_as_buffer */
2255 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2256 bytearray_doc, /* tp_doc */
2257 0, /* tp_traverse */
2258 0, /* tp_clear */
2259 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
2260 0, /* tp_weaklistoffset */
2261 bytearray_iter, /* tp_iter */
2262 0, /* tp_iternext */
2263 bytearray_methods, /* tp_methods */
2264 0, /* tp_members */
2265 0, /* tp_getset */
2266 0, /* tp_base */
2267 0, /* tp_dict */
2268 0, /* tp_descr_get */
2269 0, /* tp_descr_set */
2270 0, /* tp_dictoffset */
2271 (initproc)bytearray_init, /* tp_init */
2272 PyType_GenericAlloc, /* tp_alloc */
2273 PyType_GenericNew, /* tp_new */
2274 PyObject_Del, /* tp_free */
2275 };
2276
2277 /*********************** Bytes Iterator ****************************/
2278
2279 typedef struct {
2280 PyObject_HEAD
2281 Py_ssize_t it_index;
2282 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2283 } bytesiterobject;
2284
2285 static void
bytearrayiter_dealloc(bytesiterobject * it)2286 bytearrayiter_dealloc(bytesiterobject *it)
2287 {
2288 _PyObject_GC_UNTRACK(it);
2289 Py_XDECREF(it->it_seq);
2290 PyObject_GC_Del(it);
2291 }
2292
2293 static int
bytearrayiter_traverse(bytesiterobject * it,visitproc visit,void * arg)2294 bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2295 {
2296 Py_VISIT(it->it_seq);
2297 return 0;
2298 }
2299
2300 static PyObject *
bytearrayiter_next(bytesiterobject * it)2301 bytearrayiter_next(bytesiterobject *it)
2302 {
2303 PyByteArrayObject *seq;
2304 PyObject *item;
2305
2306 assert(it != NULL);
2307 seq = it->it_seq;
2308 if (seq == NULL)
2309 return NULL;
2310 assert(PyByteArray_Check(seq));
2311
2312 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2313 item = PyLong_FromLong(
2314 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
2315 if (item != NULL)
2316 ++it->it_index;
2317 return item;
2318 }
2319
2320 it->it_seq = NULL;
2321 Py_DECREF(seq);
2322 return NULL;
2323 }
2324
2325 static PyObject *
bytearrayiter_length_hint(bytesiterobject * it)2326 bytearrayiter_length_hint(bytesiterobject *it)
2327 {
2328 Py_ssize_t len = 0;
2329 if (it->it_seq) {
2330 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2331 if (len < 0) {
2332 len = 0;
2333 }
2334 }
2335 return PyLong_FromSsize_t(len);
2336 }
2337
2338 PyDoc_STRVAR(length_hint_doc,
2339 "Private method returning an estimate of len(list(it)).");
2340
2341 static PyObject *
bytearrayiter_reduce(bytesiterobject * it)2342 bytearrayiter_reduce(bytesiterobject *it)
2343 {
2344 if (it->it_seq != NULL) {
2345 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
2346 it->it_seq, it->it_index);
2347 } else {
2348 return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
2349 }
2350 }
2351
2352 static PyObject *
bytearrayiter_setstate(bytesiterobject * it,PyObject * state)2353 bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2354 {
2355 Py_ssize_t index = PyLong_AsSsize_t(state);
2356 if (index == -1 && PyErr_Occurred())
2357 return NULL;
2358 if (it->it_seq != NULL) {
2359 if (index < 0)
2360 index = 0;
2361 else if (index > PyByteArray_GET_SIZE(it->it_seq))
2362 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
2363 it->it_index = index;
2364 }
2365 Py_RETURN_NONE;
2366 }
2367
2368 PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2369
2370 static PyMethodDef bytearrayiter_methods[] = {
2371 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
2372 length_hint_doc},
2373 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
2374 bytearray_reduce__doc__},
2375 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
2376 setstate_doc},
2377 {NULL, NULL} /* sentinel */
2378 };
2379
2380 PyTypeObject PyByteArrayIter_Type = {
2381 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2382 "bytearray_iterator", /* tp_name */
2383 sizeof(bytesiterobject), /* tp_basicsize */
2384 0, /* tp_itemsize */
2385 /* methods */
2386 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
2387 0, /* tp_print */
2388 0, /* tp_getattr */
2389 0, /* tp_setattr */
2390 0, /* tp_reserved */
2391 0, /* tp_repr */
2392 0, /* tp_as_number */
2393 0, /* tp_as_sequence */
2394 0, /* tp_as_mapping */
2395 0, /* tp_hash */
2396 0, /* tp_call */
2397 0, /* tp_str */
2398 PyObject_GenericGetAttr, /* tp_getattro */
2399 0, /* tp_setattro */
2400 0, /* tp_as_buffer */
2401 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2402 0, /* tp_doc */
2403 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
2404 0, /* tp_clear */
2405 0, /* tp_richcompare */
2406 0, /* tp_weaklistoffset */
2407 PyObject_SelfIter, /* tp_iter */
2408 (iternextfunc)bytearrayiter_next, /* tp_iternext */
2409 bytearrayiter_methods, /* tp_methods */
2410 0,
2411 };
2412
2413 static PyObject *
bytearray_iter(PyObject * seq)2414 bytearray_iter(PyObject *seq)
2415 {
2416 bytesiterobject *it;
2417
2418 if (!PyByteArray_Check(seq)) {
2419 PyErr_BadInternalCall();
2420 return NULL;
2421 }
2422 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2423 if (it == NULL)
2424 return NULL;
2425 it->it_index = 0;
2426 Py_INCREF(seq);
2427 it->it_seq = (PyByteArrayObject *)seq;
2428 _PyObject_GC_TRACK(it);
2429 return (PyObject *)it;
2430 }
2431