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