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