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