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