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