blob: 703506193309830088116fe2e801983e0ed1008b [file] [log] [blame]
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001/* PyByteArray (bytearray) implementation */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02005#include "pycore_abstract.h" // _PyIndex_Check()
Victor Stinner45876a92020-02-12 22:32:34 +01006#include "pycore_bytes_methods.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01007#include "pycore_object.h"
Ethan Furmanb95b5612015-01-23 20:05:18 -08008#include "bytesobject.h"
Gregory P. Smith8cb65692015-04-25 23:22:26 +00009#include "pystrhex.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +000010
Martin v. Löwis7252a6e2014-07-27 16:25:09 +020011/*[clinic input]
12class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
13[clinic start generated code]*/
14/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
15
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000016char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +000017
Christian Heimes2c9c7a52008-05-26 13:42:13 +000018/* end nullbytes support */
19
20/* Helpers */
21
22static int
23_getbytevalue(PyObject* arg, int *value)
24{
Serhiy Storchakae67f7db2020-06-29 22:36:41 +030025 int overflow;
26 long face_value = PyLong_AsLongAndOverflow(arg, &overflow);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000027
Serhiy Storchakae67f7db2020-06-29 22:36:41 +030028 if (face_value == -1 && PyErr_Occurred()) {
29 *value = -1;
30 return 0;
Georg Brandl9a54d7c2008-07-16 23:15:30 +000031 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000032 if (face_value < 0 || face_value >= 256) {
Serhiy Storchakae67f7db2020-06-29 22:36:41 +030033 /* this includes an overflow in converting to C long */
Georg Brandl9a54d7c2008-07-16 23:15:30 +000034 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000035 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000036 return 0;
37 }
38
39 *value = face_value;
40 return 1;
41}
42
43static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000044bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000045{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000046 void *ptr;
47 if (view == NULL) {
Stefan Krah5178d912015-02-03 16:57:21 +010048 PyErr_SetString(PyExc_BufferError,
49 "bytearray_getbuffer: view==NULL argument is obsolete");
50 return -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000051 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000052 ptr = (void *) PyByteArray_AS_STRING(obj);
Stefan Krah5178d912015-02-03 16:57:21 +010053 /* cannot fail if view != NULL and readonly == 0 */
54 (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
55 obj->ob_exports++;
56 return 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000057}
58
59static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000060bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000061{
62 obj->ob_exports--;
63}
64
Antoine Pitrou5504e892008-12-06 21:27:53 +000065static int
66_canresize(PyByteArrayObject *self)
67{
68 if (self->ob_exports > 0) {
69 PyErr_SetString(PyExc_BufferError,
70 "Existing exports of data: object cannot be re-sized");
71 return 0;
72 }
73 return 1;
74}
75
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030076#include "clinic/bytearrayobject.c.h"
77
Christian Heimes2c9c7a52008-05-26 13:42:13 +000078/* Direct API functions */
79
80PyObject *
81PyByteArray_FromObject(PyObject *input)
82{
Petr Viktorinffd97532020-02-11 17:46:57 +010083 return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000084}
85
Serhiy Storchakaa2314282017-10-29 02:11:54 +030086static PyObject *
87_PyByteArray_FromBufferObject(PyObject *obj)
88{
89 PyObject *result;
90 Py_buffer view;
91
92 if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
93 return NULL;
94 }
95 result = PyByteArray_FromStringAndSize(NULL, view.len);
96 if (result != NULL &&
97 PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
98 &view, view.len, 'C') < 0)
99 {
100 Py_CLEAR(result);
101 }
102 PyBuffer_Release(&view);
103 return result;
104}
105
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000106PyObject *
107PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
108{
109 PyByteArrayObject *new;
110 Py_ssize_t alloc;
111
112 if (size < 0) {
113 PyErr_SetString(PyExc_SystemError,
114 "Negative size passed to PyByteArray_FromStringAndSize");
115 return NULL;
116 }
117
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000118 /* Prevent buffer overflow when setting alloc to size+1. */
119 if (size == PY_SSIZE_T_MAX) {
120 return PyErr_NoMemory();
121 }
122
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000123 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
124 if (new == NULL)
125 return NULL;
126
127 if (size == 0) {
128 new->ob_bytes = NULL;
129 alloc = 0;
130 }
131 else {
132 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100133 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000134 if (new->ob_bytes == NULL) {
135 Py_DECREF(new);
136 return PyErr_NoMemory();
137 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000138 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000139 memcpy(new->ob_bytes, bytes, size);
140 new->ob_bytes[size] = '\0'; /* Trailing null byte */
141 }
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100142 Py_SET_SIZE(new, size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000143 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200144 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000145 new->ob_exports = 0;
146
147 return (PyObject *)new;
148}
149
150Py_ssize_t
151PyByteArray_Size(PyObject *self)
152{
153 assert(self != NULL);
154 assert(PyByteArray_Check(self));
155
156 return PyByteArray_GET_SIZE(self);
157}
158
159char *
160PyByteArray_AsString(PyObject *self)
161{
162 assert(self != NULL);
163 assert(PyByteArray_Check(self));
164
165 return PyByteArray_AS_STRING(self);
166}
167
168int
Antoine Pitroucc231542014-11-02 18:40:09 +0100169PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000170{
171 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200172 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
Antoine Pitroucc231542014-11-02 18:40:09 +0100173 /* All computations are done unsigned to avoid integer overflows
174 (see issue #22335). */
175 size_t alloc = (size_t) obj->ob_alloc;
176 size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
177 size_t size = (size_t) requested_size;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000178
179 assert(self != NULL);
180 assert(PyByteArray_Check(self));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200181 assert(logical_offset <= alloc);
Antoine Pitroucc231542014-11-02 18:40:09 +0100182 assert(requested_size >= 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000183
Antoine Pitroucc231542014-11-02 18:40:09 +0100184 if (requested_size == Py_SIZE(self)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000185 return 0;
186 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200187 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000188 return -1;
189 }
190
Antoine Pitrou25454112015-05-19 20:52:27 +0200191 if (size + logical_offset + 1 <= alloc) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200192 /* Current buffer is large enough to host the requested size,
193 decide on a strategy. */
194 if (size < alloc / 2) {
195 /* Major downsize; resize down to exact size */
196 alloc = size + 1;
197 }
198 else {
199 /* Minor downsize; quick exit */
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100200 Py_SET_SIZE(self, size);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200201 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
202 return 0;
203 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000204 }
205 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200206 /* Need growing, decide on a strategy */
207 if (size <= alloc * 1.125) {
208 /* Moderate upsize; overallocate similar to list_resize() */
209 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
210 }
211 else {
212 /* Major upsize; resize up to exact size */
213 alloc = size + 1;
214 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000215 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100216 if (alloc > PY_SSIZE_T_MAX) {
217 PyErr_NoMemory();
218 return -1;
219 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000220
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200221 if (logical_offset > 0) {
222 sval = PyObject_Malloc(alloc);
223 if (sval == NULL) {
224 PyErr_NoMemory();
225 return -1;
226 }
Antoine Pitroucc231542014-11-02 18:40:09 +0100227 memcpy(sval, PyByteArray_AS_STRING(self),
Stefan Krahdce65022017-08-25 20:12:05 +0200228 Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200229 PyObject_Free(obj->ob_bytes);
230 }
231 else {
232 sval = PyObject_Realloc(obj->ob_bytes, alloc);
233 if (sval == NULL) {
234 PyErr_NoMemory();
235 return -1;
236 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000237 }
238
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200239 obj->ob_bytes = obj->ob_start = sval;
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100240 Py_SET_SIZE(self, size);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200241 obj->ob_alloc = alloc;
242 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000243
244 return 0;
245}
246
247PyObject *
248PyByteArray_Concat(PyObject *a, PyObject *b)
249{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000250 Py_buffer va, vb;
251 PyByteArrayObject *result = NULL;
252
253 va.len = -1;
254 vb.len = -1;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200255 if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
256 PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000257 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Serhiy Storchaka6b5a9ec2017-03-19 19:47:02 +0200258 Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000259 goto done;
260 }
261
Serhiy Storchaka06cfb0c2016-07-10 20:48:43 +0300262 if (va.len > PY_SSIZE_T_MAX - vb.len) {
263 PyErr_NoMemory();
264 goto done;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000265 }
266
Serhiy Storchaka06cfb0c2016-07-10 20:48:43 +0300267 result = (PyByteArrayObject *) \
268 PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
stratakis61fc23c2020-07-08 22:39:41 +0200269 // result->ob_bytes is NULL if result is an empty string:
270 // if va.len + vb.len equals zero.
271 if (result != NULL && result->ob_bytes != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000272 memcpy(result->ob_bytes, va.buf, va.len);
273 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
274 }
275
276 done:
277 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000278 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000279 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000280 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000281 return (PyObject *)result;
282}
283
284/* Functions stuffed into the type object */
285
286static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000287bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000288{
289 return Py_SIZE(self);
290}
291
292static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000293bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000294{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000295 Py_ssize_t size;
296 Py_buffer vo;
297
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200298 if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000299 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
300 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
301 return NULL;
302 }
303
Serhiy Storchaka06cfb0c2016-07-10 20:48:43 +0300304 size = Py_SIZE(self);
305 if (size > PY_SSIZE_T_MAX - vo.len) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000306 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000307 return PyErr_NoMemory();
308 }
Serhiy Storchaka06cfb0c2016-07-10 20:48:43 +0300309 if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000310 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000311 return NULL;
312 }
Serhiy Storchaka06cfb0c2016-07-10 20:48:43 +0300313 memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000314 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000315 Py_INCREF(self);
316 return (PyObject *)self;
317}
318
319static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000320bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000321{
322 PyByteArrayObject *result;
323 Py_ssize_t mysize;
324 Py_ssize_t size;
325
326 if (count < 0)
327 count = 0;
328 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000329 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000330 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000331 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000332 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
333 if (result != NULL && size != 0) {
334 if (mysize == 1)
335 memset(result->ob_bytes, self->ob_bytes[0], size);
336 else {
337 Py_ssize_t i;
338 for (i = 0; i < count; i++)
339 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
340 }
341 }
342 return (PyObject *)result;
343}
344
345static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000346bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000347{
348 Py_ssize_t mysize;
349 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200350 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000351
352 if (count < 0)
353 count = 0;
354 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000355 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000356 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000357 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200358 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000359 return NULL;
360
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200361 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000362 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200363 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000364 else {
365 Py_ssize_t i;
366 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200367 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000368 }
369
370 Py_INCREF(self);
371 return (PyObject *)self;
372}
373
374static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000375bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000376{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000377 if (i < 0 || i >= Py_SIZE(self)) {
378 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
379 return NULL;
380 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200381 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000382}
383
384static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000385bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000386{
Victor Stinnera15e2602020-04-08 02:01:56 +0200387 if (_PyIndex_Check(index)) {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000388 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000389
390 if (i == -1 && PyErr_Occurred())
391 return NULL;
392
393 if (i < 0)
394 i += PyByteArray_GET_SIZE(self);
395
396 if (i < 0 || i >= Py_SIZE(self)) {
397 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
398 return NULL;
399 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200400 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000401 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000402 else if (PySlice_Check(index)) {
Zackery Spytz14514d92019-05-17 01:13:03 -0600403 Py_ssize_t start, stop, step, slicelength, i;
404 size_t cur;
Serhiy Storchakab879fe82017-04-08 09:53:51 +0300405 if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000406 return NULL;
407 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +0300408 slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
409 &start, &stop, step);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000410
411 if (slicelength <= 0)
412 return PyByteArray_FromStringAndSize("", 0);
413 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200414 return PyByteArray_FromStringAndSize(
415 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000416 }
417 else {
418 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000419 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000420 PyObject *result;
421
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000422 result = PyByteArray_FromStringAndSize(NULL, slicelength);
423 if (result == NULL)
424 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000425
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000426 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000427 for (cur = start, i = 0; i < slicelength;
428 cur += step, i++) {
429 result_buf[i] = source_buf[cur];
430 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000431 return result;
432 }
433 }
434 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400435 PyErr_Format(PyExc_TypeError,
436 "bytearray indices must be integers or slices, not %.200s",
437 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000438 return NULL;
439 }
440}
441
442static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200443bytearray_setslice_linear(PyByteArrayObject *self,
444 Py_ssize_t lo, Py_ssize_t hi,
445 char *bytes, Py_ssize_t bytes_len)
446{
447 Py_ssize_t avail = hi - lo;
448 char *buf = PyByteArray_AS_STRING(self);
449 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100450 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200451 assert(avail >= 0);
452
Victor Stinner84557232013-11-21 12:29:51 +0100453 if (growth < 0) {
454 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200455 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100456
457 if (lo == 0) {
458 /* Shrink the buffer by advancing its logical start */
459 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200460 /*
Victor Stinner84557232013-11-21 12:29:51 +0100461 0 lo hi old_size
462 | |<----avail----->|<-----tail------>|
463 | |<-bytes_len->|<-----tail------>|
464 0 new_lo new_hi new_size
465 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200466 }
Victor Stinner84557232013-11-21 12:29:51 +0100467 else {
468 /*
469 0 lo hi old_size
470 | |<----avail----->|<-----tomove------>|
471 | |<-bytes_len->|<-----tomove------>|
472 0 lo new_hi new_size
473 */
474 memmove(buf + lo + bytes_len, buf + hi,
475 Py_SIZE(self) - hi);
476 }
477 if (PyByteArray_Resize((PyObject *)self,
478 Py_SIZE(self) + growth) < 0) {
479 /* Issue #19578: Handling the memory allocation failure here is
480 tricky here because the bytearray object has already been
481 modified. Depending on growth and lo, the behaviour is
482 different.
483
484 If growth < 0 and lo != 0, the operation is completed, but a
485 MemoryError is still raised and the memory block is not
Raymond Hettinger15f44ab2016-08-30 10:47:49 -0700486 shrunk. Otherwise, the bytearray is restored in its previous
Victor Stinner84557232013-11-21 12:29:51 +0100487 state and a MemoryError is raised. */
488 if (lo == 0) {
489 self->ob_start += growth;
490 return -1;
491 }
492 /* memmove() removed bytes, the bytearray object cannot be
493 restored in its previous state. */
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100494 Py_SET_SIZE(self, Py_SIZE(self) + growth);
Victor Stinner84557232013-11-21 12:29:51 +0100495 res = -1;
496 }
497 buf = PyByteArray_AS_STRING(self);
498 }
499 else if (growth > 0) {
500 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
501 PyErr_NoMemory();
502 return -1;
503 }
504
505 if (PyByteArray_Resize((PyObject *)self,
506 Py_SIZE(self) + growth) < 0) {
507 return -1;
508 }
509 buf = PyByteArray_AS_STRING(self);
510 /* Make the place for the additional bytes */
511 /*
512 0 lo hi old_size
513 | |<-avail->|<-----tomove------>|
514 | |<---bytes_len-->|<-----tomove------>|
515 0 lo new_hi new_size
516 */
517 memmove(buf + lo + bytes_len, buf + hi,
518 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200519 }
520
521 if (bytes_len > 0)
522 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100523 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200524}
525
526static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000527bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000528 PyObject *values)
529{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200530 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000531 void *bytes;
532 Py_buffer vbytes;
533 int res = 0;
534
535 vbytes.len = -1;
536 if (values == (PyObject *)self) {
537 /* Make a copy and call this function recursively */
538 int err;
Serhiy Storchakaa2314282017-10-29 02:11:54 +0300539 values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
540 PyByteArray_GET_SIZE(values));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000541 if (values == NULL)
542 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000543 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000544 Py_DECREF(values);
545 return err;
546 }
547 if (values == NULL) {
548 /* del b[lo:hi] */
549 bytes = NULL;
550 needed = 0;
551 }
552 else {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +0200553 if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
554 PyErr_Format(PyExc_TypeError,
555 "can't set bytearray slice from %.100s",
556 Py_TYPE(values)->tp_name);
557 return -1;
558 }
559 needed = vbytes.len;
560 bytes = vbytes.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000561 }
562
563 if (lo < 0)
564 lo = 0;
565 if (hi < lo)
566 hi = lo;
567 if (hi > Py_SIZE(self))
568 hi = Py_SIZE(self);
569
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200570 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000571 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200572 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000573 return res;
574}
575
576static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000577bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000578{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000579 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000580
581 if (i < 0)
582 i += Py_SIZE(self);
583
584 if (i < 0 || i >= Py_SIZE(self)) {
585 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
586 return -1;
587 }
588
589 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000590 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000591
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000592 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000593 return -1;
594
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200595 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000596 return 0;
597}
598
599static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000600bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000601{
602 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200603 char *buf, *bytes;
604 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000605
Victor Stinnera15e2602020-04-08 02:01:56 +0200606 if (_PyIndex_Check(index)) {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000607 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000608
609 if (i == -1 && PyErr_Occurred())
610 return -1;
611
612 if (i < 0)
613 i += PyByteArray_GET_SIZE(self);
614
615 if (i < 0 || i >= Py_SIZE(self)) {
616 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
617 return -1;
618 }
619
620 if (values == NULL) {
621 /* Fall through to slice assignment */
622 start = i;
623 stop = i + 1;
624 step = 1;
625 slicelen = 1;
626 }
627 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000628 int ival;
629 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000630 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200631 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000632 return 0;
633 }
634 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000635 else if (PySlice_Check(index)) {
Serhiy Storchakab879fe82017-04-08 09:53:51 +0300636 if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000637 return -1;
638 }
Serhiy Storchakab879fe82017-04-08 09:53:51 +0300639 slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
640 &stop, step);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000641 }
642 else {
Terry Jan Reedyffff1442014-08-02 01:30:37 -0400643 PyErr_Format(PyExc_TypeError,
644 "bytearray indices must be integers or slices, not %.200s",
645 Py_TYPE(index)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000646 return -1;
647 }
648
649 if (values == NULL) {
650 bytes = NULL;
651 needed = 0;
652 }
653 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100654 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200655 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
656 PyErr_SetString(PyExc_TypeError,
657 "can assign only bytes, buffers, or iterables "
658 "of ints in range(0, 256)");
659 return -1;
660 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000661 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000662 values = PyByteArray_FromObject(values);
663 if (values == NULL)
664 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000665 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000666 Py_DECREF(values);
667 return err;
668 }
669 else {
670 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200671 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000672 needed = Py_SIZE(values);
673 }
674 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
675 if ((step < 0 && start < stop) ||
676 (step > 0 && start > stop))
677 stop = start;
678 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200679 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000680 }
681 else {
682 if (needed == 0) {
683 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000684 size_t cur;
685 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000686
Antoine Pitrou5504e892008-12-06 21:27:53 +0000687 if (!_canresize(self))
688 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000689
690 if (slicelen == 0)
691 /* Nothing to do here. */
692 return 0;
693
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000694 if (step < 0) {
695 stop = start + 1;
696 start = stop + step * (slicelen - 1) - 1;
697 step = -step;
698 }
699 for (cur = start, i = 0;
700 i < slicelen; cur += step, i++) {
701 Py_ssize_t lim = step - 1;
702
Mark Dickinson66f575b2010-02-14 12:53:32 +0000703 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000704 lim = PyByteArray_GET_SIZE(self) - cur - 1;
705
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200706 memmove(buf + cur - i,
707 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000708 }
709 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000710 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000711 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200712 memmove(buf + cur - slicelen,
713 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000714 PyByteArray_GET_SIZE(self) - cur);
715 }
716 if (PyByteArray_Resize((PyObject *)self,
717 PyByteArray_GET_SIZE(self) - slicelen) < 0)
718 return -1;
719
720 return 0;
721 }
722 else {
723 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000724 Py_ssize_t i;
725 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000726
727 if (needed != slicelen) {
728 PyErr_Format(PyExc_ValueError,
729 "attempt to assign bytes of size %zd "
730 "to extended slice of size %zd",
731 needed, slicelen);
732 return -1;
733 }
734 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200735 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000736 return 0;
737 }
738 }
739}
740
741static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000742bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000743{
744 static char *kwlist[] = {"source", "encoding", "errors", 0};
745 PyObject *arg = NULL;
746 const char *encoding = NULL;
747 const char *errors = NULL;
748 Py_ssize_t count;
749 PyObject *it;
750 PyObject *(*iternext)(PyObject *);
751
752 if (Py_SIZE(self) != 0) {
753 /* Empty previous contents (yes, do this first of all!) */
754 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
755 return -1;
756 }
757
758 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000759 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000760 &arg, &encoding, &errors))
761 return -1;
762
763 /* Make a quick exit if no first argument */
764 if (arg == NULL) {
765 if (encoding != NULL || errors != NULL) {
766 PyErr_SetString(PyExc_TypeError,
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +0300767 encoding != NULL ?
768 "encoding without a string argument" :
769 "errors without a string argument");
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000770 return -1;
771 }
772 return 0;
773 }
774
775 if (PyUnicode_Check(arg)) {
776 /* Encode via the codec registry */
777 PyObject *encoded, *new;
778 if (encoding == NULL) {
779 PyErr_SetString(PyExc_TypeError,
780 "string argument without an encoding");
781 return -1;
782 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000783 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000784 if (encoded == NULL)
785 return -1;
786 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000787 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000788 Py_DECREF(encoded);
789 if (new == NULL)
790 return -1;
791 Py_DECREF(new);
792 return 0;
793 }
794
795 /* If it's not unicode, there can't be encoding or errors */
796 if (encoding != NULL || errors != NULL) {
797 PyErr_SetString(PyExc_TypeError,
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +0300798 encoding != NULL ?
799 "encoding without a string argument" :
800 "errors without a string argument");
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000801 return -1;
802 }
803
804 /* Is it an int? */
Victor Stinnera15e2602020-04-08 02:01:56 +0200805 if (_PyIndex_Check(arg)) {
Serhiy Storchakaeb249882016-08-15 09:46:07 +0300806 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
807 if (count == -1 && PyErr_Occurred()) {
Serhiy Storchakae8904212018-10-15 00:02:57 +0300808 if (!PyErr_ExceptionMatches(PyExc_TypeError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000809 return -1;
INADA Naokia634e232017-01-06 17:32:01 +0900810 PyErr_Clear(); /* fall through */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000811 }
INADA Naokia634e232017-01-06 17:32:01 +0900812 else {
813 if (count < 0) {
814 PyErr_SetString(PyExc_ValueError, "negative count");
815 return -1;
816 }
817 if (count > 0) {
818 if (PyByteArray_Resize((PyObject *)self, count))
819 return -1;
820 memset(PyByteArray_AS_STRING(self), 0, count);
821 }
822 return 0;
823 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000824 }
825
826 /* Use the buffer API */
827 if (PyObject_CheckBuffer(arg)) {
828 Py_ssize_t size;
829 Py_buffer view;
830 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
831 return -1;
832 size = view.len;
833 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200834 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
835 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200836 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000837 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000838 return 0;
839 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000840 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000841 return -1;
842 }
843
844 /* XXX Optimize this if the arguments is a list, tuple */
845
846 /* Get the iterator */
847 it = PyObject_GetIter(arg);
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +0300848 if (it == NULL) {
849 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
850 PyErr_Format(PyExc_TypeError,
851 "cannot convert '%.200s' object to bytearray",
Victor Stinner58ac7002020-02-07 03:04:21 +0100852 Py_TYPE(arg)->tp_name);
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +0300853 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000854 return -1;
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +0300855 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000856 iternext = *Py_TYPE(it)->tp_iternext;
857
858 /* Run the iterator to exhaustion */
859 for (;;) {
860 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000861 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000862
863 /* Get the next item */
864 item = iternext(it);
865 if (item == NULL) {
866 if (PyErr_Occurred()) {
867 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
868 goto error;
869 PyErr_Clear();
870 }
871 break;
872 }
873
874 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000875 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000876 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000877 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000878 goto error;
879
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000880 /* Append the byte */
Serhiy Storchaka7b6e3b92015-06-29 21:14:06 +0300881 if (Py_SIZE(self) + 1 < self->ob_alloc) {
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100882 Py_SET_SIZE(self, Py_SIZE(self) + 1);
Serhiy Storchaka7b6e3b92015-06-29 21:14:06 +0300883 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
884 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000885 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
886 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200887 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000888 }
889
890 /* Clean up and return success */
891 Py_DECREF(it);
892 return 0;
893
894 error:
895 /* Error handling when it != NULL */
896 Py_DECREF(it);
897 return -1;
898}
899
900/* Mostly copied from string_repr, but without the
901 "smart quote" functionality. */
902static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000903bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000904{
Serhiy Storchakab3a77962017-09-21 14:24:13 +0300905 const char *className = _PyType_Name(Py_TYPE(self));
906 const char *quote_prefix = "(b";
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000907 const char *quote_postfix = ")";
908 Py_ssize_t length = Py_SIZE(self);
Serhiy Storchakab3a77962017-09-21 14:24:13 +0300909 /* 6 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
910 Py_ssize_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000911 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200912 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200913 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200914 char c;
915 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200916 int quote;
917 char *test, *start;
918 char *buffer;
919
Serhiy Storchakab3a77962017-09-21 14:24:13 +0300920 newsize = strlen(className);
921 if (length > (PY_SSIZE_T_MAX - 6 - newsize) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000922 PyErr_SetString(PyExc_OverflowError,
923 "bytearray object is too large to make repr");
924 return NULL;
925 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200926
Serhiy Storchakab3a77962017-09-21 14:24:13 +0300927 newsize += 6 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100928 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200929 if (buffer == NULL) {
930 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000931 return NULL;
932 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000933
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200934 /* Figure out which quote to use; single is preferred */
935 quote = '\'';
936 start = PyByteArray_AS_STRING(self);
937 for (test = start; test < start+length; ++test) {
938 if (*test == '"') {
939 quote = '\''; /* back to single */
940 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000941 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200942 else if (*test == '\'')
943 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000944 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200945
946 p = buffer;
Serhiy Storchakab3a77962017-09-21 14:24:13 +0300947 while (*className)
948 *p++ = *className++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200949 while (*quote_prefix)
950 *p++ = *quote_prefix++;
951 *p++ = quote;
952
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200953 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200954 for (i = 0; i < length; i++) {
955 /* There's at least enough room for a hex escape
956 and a closing quote. */
957 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200958 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200959 if (c == '\'' || c == '\\')
960 *p++ = '\\', *p++ = c;
961 else if (c == '\t')
962 *p++ = '\\', *p++ = 't';
963 else if (c == '\n')
964 *p++ = '\\', *p++ = 'n';
965 else if (c == '\r')
966 *p++ = '\\', *p++ = 'r';
967 else if (c == 0)
968 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
969 else if (c < ' ' || c >= 0x7f) {
970 *p++ = '\\';
971 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200972 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
973 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200974 }
975 else
976 *p++ = c;
977 }
978 assert(newsize - (p - buffer) >= 1);
979 *p++ = quote;
980 while (*quote_postfix) {
981 *p++ = *quote_postfix++;
982 }
983
Serhiy Storchakab3a77962017-09-21 14:24:13 +0300984 v = PyUnicode_FromStringAndSize(buffer, p - buffer);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100985 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200986 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000987}
988
989static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000990bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000991{
Victor Stinnerda7933e2020-04-13 03:04:28 +0200992 if (_Py_GetConfig()->bytes_warning) {
Victor Stinner53b7d4e2018-07-25 01:37:05 +0200993 if (PyErr_WarnEx(PyExc_BytesWarning,
994 "str() on a bytearray instance", 1)) {
995 return NULL;
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000996 }
Victor Stinner53b7d4e2018-07-25 01:37:05 +0200997 }
998 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000999}
1000
1001static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001002bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001003{
1004 Py_ssize_t self_size, other_size;
1005 Py_buffer self_bytes, other_bytes;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001006 int cmp, rc;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001007
1008 /* Bytes can be compared to anything that supports the (binary)
1009 buffer API. Except that a comparison with Unicode is always an
1010 error, even if the comparison is for equality. */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001011 rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type);
1012 if (!rc)
1013 rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type);
1014 if (rc < 0)
1015 return NULL;
1016 if (rc) {
Victor Stinnerda7933e2020-04-13 03:04:28 +02001017 if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001018 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001019 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001020 return NULL;
1021 }
1022
Brian Curtindfc80e32011-08-10 20:28:54 -05001023 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024 }
1025
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001026 if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001027 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001028 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001029 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001030 self_size = self_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001031
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001032 if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001033 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001034 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001035 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001036 }
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001037 other_size = other_bytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001038
1039 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1040 /* Shortcut: if the lengths differ, the objects differ */
stratakise8b19652017-11-02 11:32:54 +01001041 PyBuffer_Release(&self_bytes);
1042 PyBuffer_Release(&other_bytes);
1043 return PyBool_FromLong((op == Py_NE));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001044 }
1045 else {
stratakise8b19652017-11-02 11:32:54 +01001046 cmp = memcmp(self_bytes.buf, other_bytes.buf,
1047 Py_MIN(self_size, other_size));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001048 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1049
stratakise8b19652017-11-02 11:32:54 +01001050 PyBuffer_Release(&self_bytes);
1051 PyBuffer_Release(&other_bytes);
1052
1053 if (cmp != 0) {
1054 Py_RETURN_RICHCOMPARE(cmp, 0, op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001055 }
1056
stratakise8b19652017-11-02 11:32:54 +01001057 Py_RETURN_RICHCOMPARE(self_size, other_size, op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001058 }
1059
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001060}
1061
1062static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001063bytearray_dealloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001064{
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001065 if (self->ob_exports > 0) {
1066 PyErr_SetString(PyExc_SystemError,
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001067 "deallocated bytearray object has exported buffers");
Benjamin Petersone0124bd2009-03-09 21:04:33 +00001068 PyErr_Print();
1069 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001070 if (self->ob_bytes != 0) {
Antoine Pitrou39aba4f2011-11-12 21:15:28 +01001071 PyObject_Free(self->ob_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001072 }
1073 Py_TYPE(self)->tp_free((PyObject *)self);
1074}
1075
1076
1077/* -------------------------------------------------------------------- */
1078/* Methods */
1079
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001080#define FASTSEARCH fastsearch
1081#define STRINGLIB(F) stringlib_##F
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001082#define STRINGLIB_CHAR char
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001083#define STRINGLIB_SIZEOF_CHAR 1
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001084#define STRINGLIB_LEN PyByteArray_GET_SIZE
1085#define STRINGLIB_STR PyByteArray_AS_STRING
1086#define STRINGLIB_NEW PyByteArray_FromStringAndSize
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001087#define STRINGLIB_ISSPACE Py_ISSPACE
1088#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001089#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1090#define STRINGLIB_MUTABLE 1
1091
1092#include "stringlib/fastsearch.h"
1093#include "stringlib/count.h"
1094#include "stringlib/find.h"
Antoine Pitroucfc22b42012-10-16 21:07:23 +02001095#include "stringlib/join.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001096#include "stringlib/partition.h"
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001097#include "stringlib/split.h"
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001098#include "stringlib/ctype.h"
1099#include "stringlib/transmogrify.h"
1100
1101
Serhiy Storchakae09132f2016-07-03 13:57:48 +03001102static PyObject *
1103bytearray_find(PyByteArrayObject *self, PyObject *args)
1104{
1105 return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1106}
1107
1108static PyObject *
1109bytearray_count(PyByteArrayObject *self, PyObject *args)
1110{
1111 return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1112}
1113
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001114/*[clinic input]
1115bytearray.clear
1116
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001117Remove all items from the bytearray.
1118[clinic start generated code]*/
1119
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001120static PyObject *
1121bytearray_clear_impl(PyByteArrayObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001122/*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001123{
1124 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1125 return NULL;
1126 Py_RETURN_NONE;
1127}
1128
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001129/*[clinic input]
1130bytearray.copy
1131
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001132Return a copy of B.
1133[clinic start generated code]*/
1134
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001135static PyObject *
1136bytearray_copy_impl(PyByteArrayObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001137/*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001138{
1139 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1140 PyByteArray_GET_SIZE(self));
1141}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001142
Serhiy Storchakae09132f2016-07-03 13:57:48 +03001143static PyObject *
1144bytearray_index(PyByteArrayObject *self, PyObject *args)
1145{
1146 return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1147}
1148
1149static PyObject *
1150bytearray_rfind(PyByteArrayObject *self, PyObject *args)
1151{
1152 return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1153}
1154
1155static PyObject *
1156bytearray_rindex(PyByteArrayObject *self, PyObject *args)
1157{
1158 return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1159}
1160
1161static int
1162bytearray_contains(PyObject *self, PyObject *arg)
1163{
1164 return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg);
1165}
1166
1167static PyObject *
1168bytearray_startswith(PyByteArrayObject *self, PyObject *args)
1169{
1170 return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1171}
1172
1173static PyObject *
1174bytearray_endswith(PyByteArrayObject *self, PyObject *args)
1175{
1176 return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), args);
1177}
1178
sweeneydea81849b2020-04-22 17:05:48 -04001179/*[clinic input]
1180bytearray.removeprefix as bytearray_removeprefix
1181
1182 prefix: Py_buffer
1183 /
1184
1185Return a bytearray with the given prefix string removed if present.
1186
1187If the bytearray starts with the prefix string, return
1188bytearray[len(prefix):]. Otherwise, return a copy of the original
1189bytearray.
1190[clinic start generated code]*/
1191
1192static PyObject *
1193bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix)
1194/*[clinic end generated code: output=6cabc585e7f502e0 input=968aada38aedd262]*/
1195{
1196 const char *self_start = PyByteArray_AS_STRING(self);
1197 Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1198 const char *prefix_start = prefix->buf;
1199 Py_ssize_t prefix_len = prefix->len;
1200
1201 if (self_len >= prefix_len
1202 && memcmp(self_start, prefix_start, prefix_len) == 0)
1203 {
1204 return PyByteArray_FromStringAndSize(self_start + prefix_len,
1205 self_len - prefix_len);
1206 }
1207
1208 return PyByteArray_FromStringAndSize(self_start, self_len);
1209}
1210
1211/*[clinic input]
1212bytearray.removesuffix as bytearray_removesuffix
1213
1214 suffix: Py_buffer
1215 /
1216
1217Return a bytearray with the given suffix string removed if present.
1218
1219If the bytearray ends with the suffix string and that suffix is not
1220empty, return bytearray[:-len(suffix)]. Otherwise, return a copy of
1221the original bytearray.
1222[clinic start generated code]*/
1223
1224static PyObject *
1225bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
1226/*[clinic end generated code: output=2bc8cfb79de793d3 input=c1827e810b2f6b99]*/
1227{
1228 const char *self_start = PyByteArray_AS_STRING(self);
1229 Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1230 const char *suffix_start = suffix->buf;
1231 Py_ssize_t suffix_len = suffix->len;
1232
1233 if (self_len >= suffix_len
1234 && memcmp(self_start + self_len - suffix_len,
1235 suffix_start, suffix_len) == 0)
1236 {
1237 return PyByteArray_FromStringAndSize(self_start,
1238 self_len - suffix_len);
1239 }
1240
1241 return PyByteArray_FromStringAndSize(self_start, self_len);
1242}
1243
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001244
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001245/*[clinic input]
1246bytearray.translate
1247
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001248 table: object
1249 Translation table, which must be a bytes object of length 256.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001250 /
Martin Panter1b6c6da2016-08-27 08:35:02 +00001251 delete as deletechars: object(c_default="NULL") = b''
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001252
1253Return a copy with each character mapped by the given translation table.
1254
Martin Panter1b6c6da2016-08-27 08:35:02 +00001255All characters occurring in the optional argument delete are removed.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001256The remaining characters are mapped through the given translation table.
1257[clinic start generated code]*/
1258
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001259static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001260bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
Martin Panter1b6c6da2016-08-27 08:35:02 +00001261 PyObject *deletechars)
1262/*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001263{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001264 char *input, *output;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001265 const char *table_chars;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001266 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001267 PyObject *input_obj = (PyObject*)self;
1268 const char *output_start;
1269 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001270 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001271 int trans_table[256];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001272 Py_buffer vtable, vdel;
1273
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001274 if (table == Py_None) {
1275 table_chars = NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001276 table = NULL;
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001277 } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001278 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001279 } else {
1280 if (vtable.len != 256) {
1281 PyErr_SetString(PyExc_ValueError,
1282 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001283 PyBuffer_Release(&vtable);
1284 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001285 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001286 table_chars = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001287 }
1288
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001289 if (deletechars != NULL) {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001290 if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001291 if (table != NULL)
Georg Brandl953152f2009-07-22 12:03:59 +00001292 PyBuffer_Release(&vtable);
1293 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001294 }
1295 }
1296 else {
1297 vdel.buf = NULL;
1298 vdel.len = 0;
1299 }
1300
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001301 inlen = PyByteArray_GET_SIZE(input_obj);
1302 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1303 if (result == NULL)
1304 goto done;
Serhiy Storchakadd40fc32016-05-04 22:23:26 +03001305 output_start = output = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001306 input = PyByteArray_AS_STRING(input_obj);
1307
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001308 if (vdel.len == 0 && table_chars != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001309 /* If no deletions are required, use faster code */
1310 for (i = inlen; --i >= 0; ) {
1311 c = Py_CHARMASK(*input++);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001312 *output++ = table_chars[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001313 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001314 goto done;
1315 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001316
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001317 if (table_chars == NULL) {
Georg Brandlccc47b62008-12-28 11:44:14 +00001318 for (i = 0; i < 256; i++)
1319 trans_table[i] = Py_CHARMASK(i);
1320 } else {
1321 for (i = 0; i < 256; i++)
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001322 trans_table[i] = Py_CHARMASK(table_chars[i]);
Georg Brandlccc47b62008-12-28 11:44:14 +00001323 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001324
1325 for (i = 0; i < vdel.len; i++)
1326 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1327
1328 for (i = inlen; --i >= 0; ) {
1329 c = Py_CHARMASK(*input++);
1330 if (trans_table[c] != -1)
Martin Panter1b6c6da2016-08-27 08:35:02 +00001331 *output++ = (char)trans_table[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001332 }
1333 /* Fix the size of the resulting string */
1334 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001335 if (PyByteArray_Resize(result, output - output_start) < 0) {
1336 Py_CLEAR(result);
1337 goto done;
1338 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001339
1340done:
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001341 if (table != NULL)
Georg Brandlccc47b62008-12-28 11:44:14 +00001342 PyBuffer_Release(&vtable);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001343 if (deletechars != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001344 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001345 return result;
1346}
1347
1348
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001349/*[clinic input]
1350
1351@staticmethod
1352bytearray.maketrans
1353
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001354 frm: Py_buffer
1355 to: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001356 /
1357
1358Return a translation table useable for the bytes or bytearray translate method.
1359
1360The returned table will be one where each byte in frm is mapped to the byte at
1361the same position in to.
1362
1363The bytes objects frm and to must be of the same length.
1364[clinic start generated code]*/
1365
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001366static PyObject *
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001367bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001368/*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001369{
1370 return _Py_bytes_maketrans(frm, to);
Georg Brandlabc38772009-04-12 15:51:51 +00001371}
1372
1373
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001374/*[clinic input]
1375bytearray.replace
1376
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001377 old: Py_buffer
1378 new: Py_buffer
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001379 count: Py_ssize_t = -1
1380 Maximum number of occurrences to replace.
1381 -1 (the default value) means replace all occurrences.
1382 /
1383
1384Return a copy with all occurrences of substring old replaced by new.
1385
1386If the optional argument count is given, only the first count occurrences are
1387replaced.
1388[clinic start generated code]*/
1389
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001390static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001391bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
1392 Py_buffer *new, Py_ssize_t count)
1393/*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001394{
Serhiy Storchakafb81d3c2016-05-05 09:26:07 +03001395 return stringlib_replace((PyObject *)self,
Serhiy Storchakae09132f2016-07-03 13:57:48 +03001396 (const char *)old->buf, old->len,
1397 (const char *)new->buf, new->len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001398}
1399
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001400/*[clinic input]
1401bytearray.split
1402
1403 sep: object = None
1404 The delimiter according which to split the bytearray.
1405 None (the default value) means split on ASCII whitespace characters
1406 (space, tab, return, newline, formfeed, vertical tab).
1407 maxsplit: Py_ssize_t = -1
1408 Maximum number of splits to do.
1409 -1 (the default value) means no limit.
1410
1411Return a list of the sections in the bytearray, using sep as the delimiter.
1412[clinic start generated code]*/
1413
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001414static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001415bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1416 Py_ssize_t maxsplit)
1417/*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001418{
1419 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001420 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001421 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001422 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001423
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001424 if (maxsplit < 0)
1425 maxsplit = PY_SSIZE_T_MAX;
1426
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001427 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001428 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001430 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001431 return NULL;
1432 sub = vsub.buf;
1433 n = vsub.len;
1434
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001435 list = stringlib_split(
1436 (PyObject*) self, s, len, sub, n, maxsplit
1437 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001438 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001439 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001440}
1441
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001442/*[clinic input]
1443bytearray.partition
1444
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001445 sep: object
1446 /
1447
1448Partition the bytearray into three parts using the given separator.
1449
1450This will search for the separator sep in the bytearray. If the separator is
1451found, returns a 3-tuple containing the part before the separator, the
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001452separator itself, and the part after it as new bytearray objects.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001453
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001454If the separator is not found, returns a 3-tuple containing the copy of the
1455original bytearray object and two empty bytearray objects.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001456[clinic start generated code]*/
1457
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001458static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001459bytearray_partition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001460/*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001461{
1462 PyObject *bytesep, *result;
1463
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001464 bytesep = _PyByteArray_FromBufferObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001465 if (! bytesep)
1466 return NULL;
1467
1468 result = stringlib_partition(
1469 (PyObject*) self,
1470 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1471 bytesep,
1472 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1473 );
1474
1475 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001476 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001477}
1478
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001479/*[clinic input]
1480bytearray.rpartition
1481
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001482 sep: object
1483 /
1484
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001485Partition the bytearray into three parts using the given separator.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001486
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001487This will search for the separator sep in the bytearray, starting at the end.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001488If the separator is found, returns a 3-tuple containing the part before the
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001489separator, the separator itself, and the part after it as new bytearray
1490objects.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001491
1492If the separator is not found, returns a 3-tuple containing two empty bytearray
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001493objects and the copy of the original bytearray object.
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001494[clinic start generated code]*/
1495
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001496static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001497bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001498/*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001499{
1500 PyObject *bytesep, *result;
1501
Serhiy Storchakaa2314282017-10-29 02:11:54 +03001502 bytesep = _PyByteArray_FromBufferObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001503 if (! bytesep)
1504 return NULL;
1505
1506 result = stringlib_rpartition(
1507 (PyObject*) self,
1508 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1509 bytesep,
1510 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1511 );
1512
1513 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001514 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001515}
1516
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001517/*[clinic input]
1518bytearray.rsplit = bytearray.split
1519
1520Return a list of the sections in the bytearray, using sep as the delimiter.
1521
1522Splitting is done starting at the end of the bytearray and working to the front.
1523[clinic start generated code]*/
1524
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001525static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001526bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
1527 Py_ssize_t maxsplit)
1528/*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001529{
1530 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001531 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001532 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001533 Py_buffer vsub;
1534
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001535 if (maxsplit < 0)
1536 maxsplit = PY_SSIZE_T_MAX;
1537
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001538 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001539 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001540
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001541 if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001542 return NULL;
1543 sub = vsub.buf;
1544 n = vsub.len;
1545
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001546 list = stringlib_rsplit(
1547 (PyObject*) self, s, len, sub, n, maxsplit
1548 );
Martin v. Löwis423be952008-08-13 15:53:07 +00001549 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001550 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001551}
1552
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001553/*[clinic input]
1554bytearray.reverse
1555
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001556Reverse the order of the values in B in place.
1557[clinic start generated code]*/
1558
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001559static PyObject *
1560bytearray_reverse_impl(PyByteArrayObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001561/*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001562{
1563 char swap, *head, *tail;
1564 Py_ssize_t i, j, n = Py_SIZE(self);
1565
1566 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001567 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001568 tail = head + n - 1;
1569 for (i = 0; i < j; i++) {
1570 swap = *head;
1571 *head++ = *tail;
1572 *tail-- = swap;
1573 }
1574
1575 Py_RETURN_NONE;
1576}
1577
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001578
1579/*[python input]
1580class bytesvalue_converter(CConverter):
1581 type = 'int'
1582 converter = '_getbytevalue'
1583[python start generated code]*/
1584/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
1585
1586
1587/*[clinic input]
1588bytearray.insert
1589
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001590 index: Py_ssize_t
1591 The index where the value is to be inserted.
1592 item: bytesvalue
1593 The item to be inserted.
1594 /
1595
1596Insert a single item into the bytearray before the given index.
1597[clinic start generated code]*/
1598
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001599static PyObject *
1600bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001601/*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001602{
1603 Py_ssize_t n = Py_SIZE(self);
1604 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001605
1606 if (n == PY_SSIZE_T_MAX) {
1607 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00001608 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001609 return NULL;
1610 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001611 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1612 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001613 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001614
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001615 if (index < 0) {
1616 index += n;
1617 if (index < 0)
1618 index = 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001619 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001620 if (index > n)
1621 index = n;
1622 memmove(buf + index + 1, buf + index, n - index);
1623 buf[index] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001624
1625 Py_RETURN_NONE;
1626}
1627
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001628/*[clinic input]
1629bytearray.append
1630
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001631 item: bytesvalue
1632 The item to be appended.
1633 /
1634
1635Append a single item to the end of the bytearray.
1636[clinic start generated code]*/
1637
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001638static PyObject *
1639bytearray_append_impl(PyByteArrayObject *self, int item)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001640/*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001641{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001642 Py_ssize_t n = Py_SIZE(self);
1643
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001644 if (n == PY_SSIZE_T_MAX) {
1645 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00001646 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001647 return NULL;
1648 }
1649 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1650 return NULL;
1651
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001652 PyByteArray_AS_STRING(self)[n] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001653
1654 Py_RETURN_NONE;
1655}
1656
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001657/*[clinic input]
1658bytearray.extend
1659
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001660 iterable_of_ints: object
1661 The iterable of items to append.
1662 /
1663
1664Append all the items from the iterator or sequence to the end of the bytearray.
1665[clinic start generated code]*/
1666
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001667static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001668bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001669/*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001670{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001671 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001672 Py_ssize_t buf_size = 0, len = 0;
1673 int value;
1674 char *buf;
1675
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001676 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001677 if (PyObject_CheckBuffer(iterable_of_ints)) {
1678 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001679 return NULL;
1680
1681 Py_RETURN_NONE;
1682 }
1683
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001684 it = PyObject_GetIter(iterable_of_ints);
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +03001685 if (it == NULL) {
1686 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1687 PyErr_Format(PyExc_TypeError,
1688 "can't extend bytearray with %.100s",
Victor Stinner58ac7002020-02-07 03:04:21 +01001689 Py_TYPE(iterable_of_ints)->tp_name);
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +03001690 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001691 return NULL;
Serhiy Storchaka2c2044e2018-10-21 15:29:12 +03001692 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001693
Ezio Melotti42da6632011-03-15 05:18:48 +02001694 /* Try to determine the length of the argument. 32 is arbitrary. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001695 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00001696 if (buf_size == -1) {
1697 Py_DECREF(it);
1698 return NULL;
1699 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001700
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001701 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02001702 if (bytearray_obj == NULL) {
1703 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001704 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02001705 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001706 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001707
1708 while ((item = PyIter_Next(it)) != NULL) {
1709 if (! _getbytevalue(item, &value)) {
1710 Py_DECREF(item);
1711 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001712 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001713 return NULL;
1714 }
1715 buf[len++] = value;
1716 Py_DECREF(item);
1717
1718 if (len >= buf_size) {
Martin Panter371731e2016-07-18 07:53:13 +00001719 Py_ssize_t addition;
1720 if (len == PY_SSIZE_T_MAX) {
1721 Py_DECREF(it);
1722 Py_DECREF(bytearray_obj);
1723 return PyErr_NoMemory();
1724 }
1725 addition = len >> 1;
1726 if (addition > PY_SSIZE_T_MAX - len - 1)
1727 buf_size = PY_SSIZE_T_MAX;
1728 else
1729 buf_size = len + addition + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001730 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001731 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001732 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001733 return NULL;
1734 }
1735 /* Recompute the `buf' pointer, since the resizing operation may
1736 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001737 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001738 }
1739 }
1740 Py_DECREF(it);
1741
1742 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001743 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
1744 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001745 return NULL;
1746 }
1747
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02001748 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
1749 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001750 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02001751 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001752 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001753
Brandt Bucher2a7d5962019-06-26 12:06:18 -07001754 if (PyErr_Occurred()) {
1755 return NULL;
1756 }
1757
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001758 Py_RETURN_NONE;
1759}
1760
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001761/*[clinic input]
1762bytearray.pop
1763
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001764 index: Py_ssize_t = -1
1765 The index from where to remove the item.
1766 -1 (the default value) means remove the last item.
1767 /
1768
1769Remove and return a single item from B.
1770
1771If no index argument is given, will pop the last item.
1772[clinic start generated code]*/
1773
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001774static PyObject *
1775bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001776/*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001777{
1778 int value;
1779 Py_ssize_t n = Py_SIZE(self);
1780 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001781
1782 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00001783 PyErr_SetString(PyExc_IndexError,
1784 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001785 return NULL;
1786 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001787 if (index < 0)
1788 index += Py_SIZE(self);
1789 if (index < 0 || index >= Py_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001790 PyErr_SetString(PyExc_IndexError, "pop index out of range");
1791 return NULL;
1792 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00001793 if (!_canresize(self))
1794 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001795
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001796 buf = PyByteArray_AS_STRING(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001797 value = buf[index];
1798 memmove(buf + index, buf + index + 1, n - index);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001799 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1800 return NULL;
1801
Mark Dickinson54a3db92009-09-06 10:19:23 +00001802 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001803}
1804
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001805/*[clinic input]
1806bytearray.remove
1807
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001808 value: bytesvalue
1809 The value to remove.
1810 /
1811
1812Remove the first occurrence of a value in the bytearray.
1813[clinic start generated code]*/
1814
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001815static PyObject *
1816bytearray_remove_impl(PyByteArrayObject *self, int value)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03001817/*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001818{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001819 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001820 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001821
Serhiy Storchaka4b234942016-05-16 22:24:03 +03001822 where = stringlib_find_char(buf, n, value);
1823 if (where < 0) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00001824 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001825 return NULL;
1826 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00001827 if (!_canresize(self))
1828 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001829
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001830 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001831 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1832 return NULL;
1833
1834 Py_RETURN_NONE;
1835}
1836
1837/* XXX These two helpers could be optimized if argsize == 1 */
1838
1839static Py_ssize_t
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001840lstrip_helper(const char *myptr, Py_ssize_t mysize,
1841 const void *argptr, Py_ssize_t argsize)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001842{
1843 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02001844 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001845 i++;
1846 return i;
1847}
1848
1849static Py_ssize_t
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001850rstrip_helper(const char *myptr, Py_ssize_t mysize,
1851 const void *argptr, Py_ssize_t argsize)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001852{
1853 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02001854 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001855 i--;
1856 return i + 1;
1857}
1858
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001859/*[clinic input]
1860bytearray.strip
1861
1862 bytes: object = None
1863 /
1864
1865Strip leading and trailing bytes contained in the argument.
1866
1867If the argument is omitted or None, strip leading and trailing ASCII whitespace.
1868[clinic start generated code]*/
1869
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001870static PyObject *
1871bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001872/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001873{
1874 Py_ssize_t left, right, mysize, byteslen;
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001875 char *myptr;
1876 const char *bytesptr;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001877 Py_buffer vbytes;
1878
1879 if (bytes == Py_None) {
1880 bytesptr = "\t\n\r\f\v ";
1881 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001882 }
1883 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001884 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001885 return NULL;
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001886 bytesptr = (const char *) vbytes.buf;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001887 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001888 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001889 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001890 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001891 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001892 if (left == mysize)
1893 right = left;
1894 else
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001895 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
1896 if (bytes != Py_None)
1897 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001898 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001899}
1900
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001901/*[clinic input]
1902bytearray.lstrip
1903
1904 bytes: object = None
1905 /
1906
1907Strip leading bytes contained in the argument.
1908
1909If the argument is omitted or None, strip leading ASCII whitespace.
1910[clinic start generated code]*/
1911
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001912static PyObject *
1913bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001914/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001915{
1916 Py_ssize_t left, right, mysize, byteslen;
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001917 char *myptr;
1918 const char *bytesptr;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001919 Py_buffer vbytes;
1920
1921 if (bytes == Py_None) {
1922 bytesptr = "\t\n\r\f\v ";
1923 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001924 }
1925 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001926 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001927 return NULL;
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001928 bytesptr = (const char *) vbytes.buf;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001929 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001930 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001931 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001932 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001933 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001934 right = mysize;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001935 if (bytes != Py_None)
1936 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001937 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001938}
1939
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001940/*[clinic input]
1941bytearray.rstrip
1942
1943 bytes: object = None
1944 /
1945
1946Strip trailing bytes contained in the argument.
1947
1948If the argument is omitted or None, strip trailing ASCII whitespace.
1949[clinic start generated code]*/
1950
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001951static PyObject *
1952bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03001953/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001954{
1955 Py_ssize_t right, mysize, byteslen;
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001956 char *myptr;
1957 const char *bytesptr;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001958 Py_buffer vbytes;
1959
1960 if (bytes == Py_None) {
1961 bytesptr = "\t\n\r\f\v ";
1962 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001963 }
1964 else {
Serhiy Storchaka3dd3e262015-02-03 01:25:42 +02001965 if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001966 return NULL;
Serhiy Storchakae2f92de2017-11-11 13:06:26 +02001967 bytesptr = (const char *) vbytes.buf;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001968 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001969 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001970 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001971 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001972 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
1973 if (bytes != Py_None)
1974 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02001975 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001976}
1977
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001978/*[clinic input]
1979bytearray.decode
1980
1981 encoding: str(c_default="NULL") = 'utf-8'
1982 The encoding with which to decode the bytearray.
1983 errors: str(c_default="NULL") = 'strict'
1984 The error handling scheme to use for the handling of decoding errors.
1985 The default is 'strict' meaning that decoding errors raise a
1986 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
1987 as well as any other name registered with codecs.register_error that
1988 can handle UnicodeDecodeErrors.
1989
1990Decode the bytearray using the codec registered for encoding.
1991[clinic start generated code]*/
1992
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001993static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04001994bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
1995 const char *errors)
1996/*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001997{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001998 if (encoding == NULL)
1999 encoding = PyUnicode_GetDefaultEncoding();
Martin v. Löwis0efea322014-07-27 17:29:17 +02002000 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002001}
2002
2003PyDoc_STRVAR(alloc_doc,
2004"B.__alloc__() -> int\n\
2005\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00002006Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002007
2008static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302009bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002010{
2011 return PyLong_FromSsize_t(self->ob_alloc);
2012}
2013
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002014/*[clinic input]
2015bytearray.join
2016
2017 iterable_of_bytes: object
2018 /
2019
2020Concatenate any number of bytes/bytearray objects.
2021
2022The bytearray whose method is called is inserted in between each pair.
2023
2024The result is returned as a new bytearray object.
2025[clinic start generated code]*/
2026
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002027static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002028bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002029/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002030{
Martin v. Löwis0efea322014-07-27 17:29:17 +02002031 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002032}
2033
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002034/*[clinic input]
2035bytearray.splitlines
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002036
Serhiy Storchaka202fda52017-03-12 10:10:47 +02002037 keepends: bool(accept={int}) = False
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002038
2039Return a list of the lines in the bytearray, breaking at line boundaries.
2040
2041Line breaks are not included in the resulting list unless keepends is given and
2042true.
2043[clinic start generated code]*/
2044
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002045static PyObject *
2046bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
Serhiy Storchaka202fda52017-03-12 10:10:47 +02002047/*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002048{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002049 return stringlib_splitlines(
2050 (PyObject*) self, PyByteArray_AS_STRING(self),
2051 PyByteArray_GET_SIZE(self), keepends
2052 );
2053}
2054
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002055/*[clinic input]
2056@classmethod
2057bytearray.fromhex
2058
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002059 string: unicode
2060 /
2061
2062Create a bytearray object from a string of hexadecimal numbers.
2063
2064Spaces between two numbers are accepted.
2065Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2066[clinic start generated code]*/
2067
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002068static PyObject *
Serhiy Storchaka0855e702016-07-01 17:22:31 +03002069bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2070/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002071{
Serhiy Storchaka0855e702016-07-01 17:22:31 +03002072 PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2073 if (type != &PyByteArray_Type && result != NULL) {
Petr Viktorinffd97532020-02-11 17:46:57 +01002074 Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result));
Serhiy Storchaka0855e702016-07-01 17:22:31 +03002075 }
2076 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002077}
2078
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002079/*[clinic input]
2080bytearray.hex
2081
2082 sep: object = NULL
2083 An optional single character or byte to separate hex bytes.
2084 bytes_per_sep: int = 1
2085 How many bytes between separators. Positive values count from the
2086 right, negative values count from the left.
2087
2088Create a str of hexadecimal numbers from a bytearray object.
2089
2090Example:
2091>>> value = bytearray([0xb9, 0x01, 0xef])
2092>>> value.hex()
2093'b901ef'
2094>>> value.hex(':')
2095'b9:01:ef'
2096>>> value.hex(':', 2)
2097'b9:01ef'
2098>>> value.hex(':', -2)
2099'b901:ef'
2100[clinic start generated code]*/
Gregory P. Smith8cb65692015-04-25 23:22:26 +00002101
2102static PyObject *
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002103bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
2104/*[clinic end generated code: output=29c4e5ef72c565a0 input=814c15830ac8c4b5]*/
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002105{
2106 char* argbuf = PyByteArray_AS_STRING(self);
2107 Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002108 return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002109}
2110
2111static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002112_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002113{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002114 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02002115 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002116 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02002117
Serhiy Storchaka41c57b32019-09-01 12:03:39 +03002118 if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) {
2119 return NULL;
2120 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002121 if (dict == NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002122 dict = Py_None;
2123 Py_INCREF(dict);
2124 }
2125
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002126 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002127 if (proto < 3) {
2128 /* use str based reduction for backwards compatibility with Python 2.x */
2129 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002130 if (Py_SIZE(self))
2131 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002132 else
2133 latin1 = PyUnicode_FromString("");
2134 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
2135 }
2136 else {
2137 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002138 if (Py_SIZE(self)) {
2139 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002140 }
2141 else {
2142 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
2143 }
2144 }
2145}
2146
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002147/*[clinic input]
2148bytearray.__reduce__ as bytearray_reduce
2149
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002150Return state information for pickling.
2151[clinic start generated code]*/
2152
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002153static PyObject *
2154bytearray_reduce_impl(PyByteArrayObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002155/*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002156{
2157 return _common_reduce(self, 2);
2158}
2159
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002160/*[clinic input]
2161bytearray.__reduce_ex__ as bytearray_reduce_ex
2162
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002163 proto: int = 0
2164 /
2165
2166Return state information for pickling.
2167[clinic start generated code]*/
2168
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002169static PyObject *
2170bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002171/*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002172{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01002173 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002174}
2175
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002176/*[clinic input]
2177bytearray.__sizeof__ as bytearray_sizeof
2178
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002179Returns the size of the bytearray object in memory, in bytes.
2180[clinic start generated code]*/
2181
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002182static PyObject *
2183bytearray_sizeof_impl(PyByteArrayObject *self)
Serhiy Storchaka7a9579c2016-05-02 13:45:20 +03002184/*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002185{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002186 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002187
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002188 res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002189 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002190}
2191
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002192static PySequenceMethods bytearray_as_sequence = {
2193 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002194 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002195 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
2196 (ssizeargfunc)bytearray_getitem, /* sq_item */
2197 0, /* sq_slice */
2198 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
2199 0, /* sq_ass_slice */
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002200 (objobjproc)bytearray_contains, /* sq_contains */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002201 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
2202 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002203};
2204
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002205static PyMappingMethods bytearray_as_mapping = {
2206 (lenfunc)bytearray_length,
2207 (binaryfunc)bytearray_subscript,
2208 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002209};
2210
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002211static PyBufferProcs bytearray_as_buffer = {
2212 (getbufferproc)bytearray_getbuffer,
2213 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002214};
2215
2216static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002217bytearray_methods[] = {
2218 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002219 BYTEARRAY_REDUCE_METHODDEF
2220 BYTEARRAY_REDUCE_EX_METHODDEF
2221 BYTEARRAY_SIZEOF_METHODDEF
2222 BYTEARRAY_APPEND_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302223 {"capitalize", stringlib_capitalize, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002224 _Py_capitalize__doc__},
Tal Einatc929df32018-07-06 13:17:38 +03002225 STRINGLIB_CENTER_METHODDEF
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002226 BYTEARRAY_CLEAR_METHODDEF
2227 BYTEARRAY_COPY_METHODDEF
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002228 {"count", (PyCFunction)bytearray_count, METH_VARARGS,
Serhiy Storchakadd40fc32016-05-04 22:23:26 +03002229 _Py_count__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002230 BYTEARRAY_DECODE_METHODDEF
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002231 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS,
Serhiy Storchakadd40fc32016-05-04 22:23:26 +03002232 _Py_endswith__doc__},
Tal Einatc929df32018-07-06 13:17:38 +03002233 STRINGLIB_EXPANDTABS_METHODDEF
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002234 BYTEARRAY_EXTEND_METHODDEF
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002235 {"find", (PyCFunction)bytearray_find, METH_VARARGS,
Serhiy Storchakadd40fc32016-05-04 22:23:26 +03002236 _Py_find__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002237 BYTEARRAY_FROMHEX_METHODDEF
Gregory P. Smith0c2f9302019-05-29 11:46:58 -07002238 BYTEARRAY_HEX_METHODDEF
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002239 {"index", (PyCFunction)bytearray_index, METH_VARARGS, _Py_index__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002240 BYTEARRAY_INSERT_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302241 {"isalnum", stringlib_isalnum, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002242 _Py_isalnum__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302243 {"isalpha", stringlib_isalpha, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002244 _Py_isalpha__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302245 {"isascii", stringlib_isascii, METH_NOARGS,
INADA Naokia49ac992018-01-27 14:06:21 +09002246 _Py_isascii__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302247 {"isdigit", stringlib_isdigit, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002248 _Py_isdigit__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302249 {"islower", stringlib_islower, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002250 _Py_islower__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302251 {"isspace", stringlib_isspace, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002252 _Py_isspace__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302253 {"istitle", stringlib_istitle, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002254 _Py_istitle__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302255 {"isupper", stringlib_isupper, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002256 _Py_isupper__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002257 BYTEARRAY_JOIN_METHODDEF
Tal Einatc929df32018-07-06 13:17:38 +03002258 STRINGLIB_LJUST_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302259 {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002260 BYTEARRAY_LSTRIP_METHODDEF
2261 BYTEARRAY_MAKETRANS_METHODDEF
2262 BYTEARRAY_PARTITION_METHODDEF
2263 BYTEARRAY_POP_METHODDEF
2264 BYTEARRAY_REMOVE_METHODDEF
2265 BYTEARRAY_REPLACE_METHODDEF
sweeneydea81849b2020-04-22 17:05:48 -04002266 BYTEARRAY_REMOVEPREFIX_METHODDEF
2267 BYTEARRAY_REMOVESUFFIX_METHODDEF
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002268 BYTEARRAY_REVERSE_METHODDEF
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002269 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, _Py_rfind__doc__},
2270 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, _Py_rindex__doc__},
Tal Einatc929df32018-07-06 13:17:38 +03002271 STRINGLIB_RJUST_METHODDEF
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002272 BYTEARRAY_RPARTITION_METHODDEF
2273 BYTEARRAY_RSPLIT_METHODDEF
2274 BYTEARRAY_RSTRIP_METHODDEF
2275 BYTEARRAY_SPLIT_METHODDEF
2276 BYTEARRAY_SPLITLINES_METHODDEF
Serhiy Storchakae09132f2016-07-03 13:57:48 +03002277 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Serhiy Storchakadd40fc32016-05-04 22:23:26 +03002278 _Py_startswith__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002279 BYTEARRAY_STRIP_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302280 {"swapcase", stringlib_swapcase, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002281 _Py_swapcase__doc__},
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302282 {"title", stringlib_title, METH_NOARGS, _Py_title__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002283 BYTEARRAY_TRANSLATE_METHODDEF
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302284 {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__},
Tal Einatc929df32018-07-06 13:17:38 +03002285 STRINGLIB_ZFILL_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002286 {NULL}
2287};
2288
Ethan Furmanb95b5612015-01-23 20:05:18 -08002289static PyObject *
2290bytearray_mod(PyObject *v, PyObject *w)
2291{
2292 if (!PyByteArray_Check(v))
2293 Py_RETURN_NOTIMPLEMENTED;
Berker Peksag43de36d2016-04-16 01:20:47 +03002294 return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
Ethan Furmanb95b5612015-01-23 20:05:18 -08002295}
2296
2297static PyNumberMethods bytearray_as_number = {
2298 0, /*nb_add*/
2299 0, /*nb_subtract*/
2300 0, /*nb_multiply*/
2301 bytearray_mod, /*nb_remainder*/
2302};
2303
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002304PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00002305"bytearray(iterable_of_ints) -> bytearray\n\
2306bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002307bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2308bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2309bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002310\n\
Serhiy Storchaka6a7b3a72016-04-17 08:32:47 +03002311Construct a mutable bytearray object from:\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002312 - an iterable yielding integers in range(256)\n\
2313 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002314 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002315 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01002316 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002317
2318
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002319static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002320
2321PyTypeObject PyByteArray_Type = {
2322 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2323 "bytearray",
2324 sizeof(PyByteArrayObject),
2325 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002326 (destructor)bytearray_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002327 0, /* tp_vectorcall_offset */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002328 0, /* tp_getattr */
2329 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002330 0, /* tp_as_async */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002331 (reprfunc)bytearray_repr, /* tp_repr */
Ethan Furmanb95b5612015-01-23 20:05:18 -08002332 &bytearray_as_number, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002333 &bytearray_as_sequence, /* tp_as_sequence */
2334 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002335 0, /* tp_hash */
2336 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002337 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002338 PyObject_GenericGetAttr, /* tp_getattro */
2339 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002340 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002341 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002342 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002343 0, /* tp_traverse */
2344 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002345 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002346 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002347 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002348 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002349 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002350 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 */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002357 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002358 PyType_GenericAlloc, /* tp_alloc */
2359 PyType_GenericNew, /* tp_new */
2360 PyObject_Del, /* tp_free */
2361};
2362
2363/*********************** Bytes Iterator ****************************/
2364
2365typedef struct {
2366 PyObject_HEAD
2367 Py_ssize_t it_index;
2368 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2369} bytesiterobject;
2370
2371static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002372bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002373{
2374 _PyObject_GC_UNTRACK(it);
2375 Py_XDECREF(it->it_seq);
2376 PyObject_GC_Del(it);
2377}
2378
2379static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002380bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002381{
2382 Py_VISIT(it->it_seq);
2383 return 0;
2384}
2385
2386static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002387bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002388{
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(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002400 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002401 if (item != NULL)
2402 ++it->it_index;
2403 return item;
2404 }
2405
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002406 it->it_seq = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +03002407 Py_DECREF(seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002408 return NULL;
2409}
2410
2411static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302412bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002413{
2414 Py_ssize_t len = 0;
Serhiy Storchakaaf658722016-07-03 14:41:36 +03002415 if (it->it_seq) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002416 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
Serhiy Storchakaaf658722016-07-03 14:41:36 +03002417 if (len < 0) {
2418 len = 0;
2419 }
2420 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002421 return PyLong_FromSsize_t(len);
2422}
2423
2424PyDoc_STRVAR(length_hint_doc,
2425 "Private method returning an estimate of len(list(it)).");
2426
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002427static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302428bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002429{
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02002430 _Py_IDENTIFIER(iter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002431 if (it->it_seq != NULL) {
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02002432 return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002433 it->it_seq, it->it_index);
2434 } else {
Serhiy Storchakabb86bf42018-12-11 08:28:18 +02002435 return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002436 }
2437}
2438
2439static PyObject *
2440bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2441{
2442 Py_ssize_t index = PyLong_AsSsize_t(state);
2443 if (index == -1 && PyErr_Occurred())
2444 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00002445 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 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002452 Py_RETURN_NONE;
2453}
2454
2455PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2456
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002457static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002458 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002459 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002460 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002461 bytearray_reduce__doc__},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002462 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
2463 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002464 {NULL, NULL} /* sentinel */
2465};
2466
2467PyTypeObject 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 */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002473 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002474 0, /* tp_vectorcall_offset */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002475 0, /* tp_getattr */
2476 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002477 0, /* tp_as_async */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002478 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 */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002490 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002491 0, /* tp_clear */
2492 0, /* tp_richcompare */
2493 0, /* tp_weaklistoffset */
2494 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002495 (iternextfunc)bytearrayiter_next, /* tp_iternext */
2496 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002497 0,
2498};
2499
2500static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002501bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002502{
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}