blob: 242b3b2253b48b97e732b2cd5c32b86ed96dded9 [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"
5#include "structmember.h"
6#include "bytes_methods.h"
7
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02008/*[clinic input]
9class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
10[clinic start generated code]*/
11/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
12
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000013char _PyByteArray_empty_string[] = "";
Christian Heimes2c9c7a52008-05-26 13:42:13 +000014
15void
16PyByteArray_Fini(void)
17{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000018}
19
20int
21PyByteArray_Init(void)
22{
Christian Heimes2c9c7a52008-05-26 13:42:13 +000023 return 1;
24}
25
26/* end nullbytes support */
27
28/* Helpers */
29
30static int
31_getbytevalue(PyObject* arg, int *value)
32{
33 long face_value;
34
35 if (PyLong_Check(arg)) {
36 face_value = PyLong_AsLong(arg);
Georg Brandl9a54d7c2008-07-16 23:15:30 +000037 } else {
38 PyObject *index = PyNumber_Index(arg);
39 if (index == NULL) {
40 PyErr_Format(PyExc_TypeError, "an integer is required");
Mark Dickinson10de93a2010-07-09 19:25:48 +000041 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000042 return 0;
43 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +000044 face_value = PyLong_AsLong(index);
45 Py_DECREF(index);
46 }
47
48 if (face_value < 0 || face_value >= 256) {
49 /* this includes the OverflowError in case the long is too large */
50 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
Mark Dickinson10de93a2010-07-09 19:25:48 +000051 *value = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +000052 return 0;
53 }
54
55 *value = face_value;
56 return 1;
57}
58
59static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +000060bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000061{
62 int ret;
63 void *ptr;
64 if (view == NULL) {
65 obj->ob_exports++;
66 return 0;
67 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +000068 ptr = (void *) PyByteArray_AS_STRING(obj);
Martin v. Löwis423be952008-08-13 15:53:07 +000069 ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
Christian Heimes2c9c7a52008-05-26 13:42:13 +000070 if (ret >= 0) {
71 obj->ob_exports++;
72 }
73 return ret;
74}
75
76static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +000077bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
Christian Heimes2c9c7a52008-05-26 13:42:13 +000078{
79 obj->ob_exports--;
80}
81
82static Py_ssize_t
83_getbuffer(PyObject *obj, Py_buffer *view)
84{
85 PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
86
87 if (buffer == NULL || buffer->bf_getbuffer == NULL)
88 {
89 PyErr_Format(PyExc_TypeError,
90 "Type %.100s doesn't support the buffer API",
91 Py_TYPE(obj)->tp_name);
92 return -1;
93 }
94
95 if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
96 return -1;
97 return view->len;
98}
99
Antoine Pitrou5504e892008-12-06 21:27:53 +0000100static int
101_canresize(PyByteArrayObject *self)
102{
103 if (self->ob_exports > 0) {
104 PyErr_SetString(PyExc_BufferError,
105 "Existing exports of data: object cannot be re-sized");
106 return 0;
107 }
108 return 1;
109}
110
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000111/* Direct API functions */
112
113PyObject *
114PyByteArray_FromObject(PyObject *input)
115{
116 return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
117 input, NULL);
118}
119
120PyObject *
121PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
122{
123 PyByteArrayObject *new;
124 Py_ssize_t alloc;
125
126 if (size < 0) {
127 PyErr_SetString(PyExc_SystemError,
128 "Negative size passed to PyByteArray_FromStringAndSize");
129 return NULL;
130 }
131
Neal Norwitz3ce5d922008-08-24 07:08:55 +0000132 /* Prevent buffer overflow when setting alloc to size+1. */
133 if (size == PY_SSIZE_T_MAX) {
134 return PyErr_NoMemory();
135 }
136
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000137 new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
138 if (new == NULL)
139 return NULL;
140
141 if (size == 0) {
142 new->ob_bytes = NULL;
143 alloc = 0;
144 }
145 else {
146 alloc = size + 1;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100147 new->ob_bytes = PyObject_Malloc(alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000148 if (new->ob_bytes == NULL) {
149 Py_DECREF(new);
150 return PyErr_NoMemory();
151 }
Antoine Pitroufc8d6f42010-01-17 12:38:54 +0000152 if (bytes != NULL && size > 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000153 memcpy(new->ob_bytes, bytes, size);
154 new->ob_bytes[size] = '\0'; /* Trailing null byte */
155 }
156 Py_SIZE(new) = size;
157 new->ob_alloc = alloc;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200158 new->ob_start = new->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000159 new->ob_exports = 0;
160
161 return (PyObject *)new;
162}
163
164Py_ssize_t
165PyByteArray_Size(PyObject *self)
166{
167 assert(self != NULL);
168 assert(PyByteArray_Check(self));
169
170 return PyByteArray_GET_SIZE(self);
171}
172
173char *
174PyByteArray_AsString(PyObject *self)
175{
176 assert(self != NULL);
177 assert(PyByteArray_Check(self));
178
179 return PyByteArray_AS_STRING(self);
180}
181
182int
183PyByteArray_Resize(PyObject *self, Py_ssize_t size)
184{
185 void *sval;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200186 PyByteArrayObject *obj = ((PyByteArrayObject *)self);
187 Py_ssize_t alloc = obj->ob_alloc;
188 Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000189
190 assert(self != NULL);
191 assert(PyByteArray_Check(self));
192 assert(size >= 0);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200193 assert(logical_offset >= 0);
194 assert(logical_offset <= alloc);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000195
Antoine Pitrou5504e892008-12-06 21:27:53 +0000196 if (size == Py_SIZE(self)) {
197 return 0;
198 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200199 if (!_canresize(obj)) {
Antoine Pitrou5504e892008-12-06 21:27:53 +0000200 return -1;
201 }
202
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200203 if (size + logical_offset + 1 < alloc) {
204 /* Current buffer is large enough to host the requested size,
205 decide on a strategy. */
206 if (size < alloc / 2) {
207 /* Major downsize; resize down to exact size */
208 alloc = size + 1;
209 }
210 else {
211 /* Minor downsize; quick exit */
212 Py_SIZE(self) = size;
213 PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
214 return 0;
215 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000216 }
217 else {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200218 /* Need growing, decide on a strategy */
219 if (size <= alloc * 1.125) {
220 /* Moderate upsize; overallocate similar to list_resize() */
221 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
222 }
223 else {
224 /* Major upsize; resize up to exact size */
225 alloc = size + 1;
226 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000227 }
228
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200229 if (logical_offset > 0) {
230 sval = PyObject_Malloc(alloc);
231 if (sval == NULL) {
232 PyErr_NoMemory();
233 return -1;
234 }
235 memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self)));
236 PyObject_Free(obj->ob_bytes);
237 }
238 else {
239 sval = PyObject_Realloc(obj->ob_bytes, alloc);
240 if (sval == NULL) {
241 PyErr_NoMemory();
242 return -1;
243 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000244 }
245
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200246 obj->ob_bytes = obj->ob_start = sval;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000247 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200248 obj->ob_alloc = alloc;
249 obj->ob_bytes[size] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000250
251 return 0;
252}
253
254PyObject *
255PyByteArray_Concat(PyObject *a, PyObject *b)
256{
257 Py_ssize_t size;
258 Py_buffer va, vb;
259 PyByteArrayObject *result = NULL;
260
261 va.len = -1;
262 vb.len = -1;
263 if (_getbuffer(a, &va) < 0 ||
264 _getbuffer(b, &vb) < 0) {
265 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
266 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
267 goto done;
268 }
269
270 size = va.len + vb.len;
271 if (size < 0) {
Benjamin Petersone0124bd2009-03-09 21:04:33 +0000272 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000273 goto done;
274 }
275
276 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
277 if (result != NULL) {
278 memcpy(result->ob_bytes, va.buf, va.len);
279 memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
280 }
281
282 done:
283 if (va.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000284 PyBuffer_Release(&va);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000285 if (vb.len != -1)
Martin v. Löwis423be952008-08-13 15:53:07 +0000286 PyBuffer_Release(&vb);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000287 return (PyObject *)result;
288}
289
290/* Functions stuffed into the type object */
291
292static Py_ssize_t
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000293bytearray_length(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000294{
295 return Py_SIZE(self);
296}
297
298static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000299bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000300{
301 Py_ssize_t mysize;
302 Py_ssize_t size;
303 Py_buffer vo;
304
305 if (_getbuffer(other, &vo) < 0) {
306 PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
307 Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
308 return NULL;
309 }
310
311 mysize = Py_SIZE(self);
312 size = mysize + vo.len;
313 if (size < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000314 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000315 return PyErr_NoMemory();
316 }
317 if (size < self->ob_alloc) {
318 Py_SIZE(self) = size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200319 PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000320 }
321 else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000322 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000323 return NULL;
324 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200325 memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
Martin v. Löwis423be952008-08-13 15:53:07 +0000326 PyBuffer_Release(&vo);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000327 Py_INCREF(self);
328 return (PyObject *)self;
329}
330
331static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000332bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000333{
334 PyByteArrayObject *result;
335 Py_ssize_t mysize;
336 Py_ssize_t size;
337
338 if (count < 0)
339 count = 0;
340 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000341 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000342 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000343 size = mysize * count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000344 result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
345 if (result != NULL && size != 0) {
346 if (mysize == 1)
347 memset(result->ob_bytes, self->ob_bytes[0], size);
348 else {
349 Py_ssize_t i;
350 for (i = 0; i < count; i++)
351 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
352 }
353 }
354 return (PyObject *)result;
355}
356
357static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000358bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000359{
360 Py_ssize_t mysize;
361 Py_ssize_t size;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200362 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000363
364 if (count < 0)
365 count = 0;
366 mysize = Py_SIZE(self);
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000367 if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000368 return PyErr_NoMemory();
Mark Dickinsoncf940c72010-08-10 18:35:01 +0000369 size = mysize * count;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200370 if (PyByteArray_Resize((PyObject *)self, size) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000371 return NULL;
372
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200373 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000374 if (mysize == 1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200375 memset(buf, buf[0], size);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000376 else {
377 Py_ssize_t i;
378 for (i = 1; i < count; i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200379 memcpy(buf + i*mysize, buf, mysize);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000380 }
381
382 Py_INCREF(self);
383 return (PyObject *)self;
384}
385
386static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000387bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000388{
389 if (i < 0)
390 i += Py_SIZE(self);
391 if (i < 0 || i >= Py_SIZE(self)) {
392 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
393 return NULL;
394 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200395 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000396}
397
398static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000399bytearray_subscript(PyByteArrayObject *self, PyObject *index)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000400{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000401 if (PyIndex_Check(index)) {
402 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000403
404 if (i == -1 && PyErr_Occurred())
405 return NULL;
406
407 if (i < 0)
408 i += PyByteArray_GET_SIZE(self);
409
410 if (i < 0 || i >= Py_SIZE(self)) {
411 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
412 return NULL;
413 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200414 return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000415 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000416 else if (PySlice_Check(index)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000417 Py_ssize_t start, stop, step, slicelength, cur, i;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000418 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000419 PyByteArray_GET_SIZE(self),
420 &start, &stop, &step, &slicelength) < 0) {
421 return NULL;
422 }
423
424 if (slicelength <= 0)
425 return PyByteArray_FromStringAndSize("", 0);
426 else if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200427 return PyByteArray_FromStringAndSize(
428 PyByteArray_AS_STRING(self) + start, slicelength);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000429 }
430 else {
431 char *source_buf = PyByteArray_AS_STRING(self);
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000432 char *result_buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000433 PyObject *result;
434
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000435 result = PyByteArray_FromStringAndSize(NULL, slicelength);
436 if (result == NULL)
437 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000438
Alexandre Vassalottie2641f42009-04-03 06:38:02 +0000439 result_buf = PyByteArray_AS_STRING(result);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000440 for (cur = start, i = 0; i < slicelength;
441 cur += step, i++) {
442 result_buf[i] = source_buf[cur];
443 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000444 return result;
445 }
446 }
447 else {
448 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
449 return NULL;
450 }
451}
452
453static int
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200454bytearray_setslice_linear(PyByteArrayObject *self,
455 Py_ssize_t lo, Py_ssize_t hi,
456 char *bytes, Py_ssize_t bytes_len)
457{
458 Py_ssize_t avail = hi - lo;
459 char *buf = PyByteArray_AS_STRING(self);
460 Py_ssize_t growth = bytes_len - avail;
Victor Stinner84557232013-11-21 12:29:51 +0100461 int res = 0;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200462 assert(avail >= 0);
463
Victor Stinner84557232013-11-21 12:29:51 +0100464 if (growth < 0) {
465 if (!_canresize(self))
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200466 return -1;
Victor Stinner84557232013-11-21 12:29:51 +0100467
468 if (lo == 0) {
469 /* Shrink the buffer by advancing its logical start */
470 self->ob_start -= growth;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200471 /*
Victor Stinner84557232013-11-21 12:29:51 +0100472 0 lo hi old_size
473 | |<----avail----->|<-----tail------>|
474 | |<-bytes_len->|<-----tail------>|
475 0 new_lo new_hi new_size
476 */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200477 }
Victor Stinner84557232013-11-21 12:29:51 +0100478 else {
479 /*
480 0 lo hi old_size
481 | |<----avail----->|<-----tomove------>|
482 | |<-bytes_len->|<-----tomove------>|
483 0 lo new_hi new_size
484 */
485 memmove(buf + lo + bytes_len, buf + hi,
486 Py_SIZE(self) - hi);
487 }
488 if (PyByteArray_Resize((PyObject *)self,
489 Py_SIZE(self) + growth) < 0) {
490 /* Issue #19578: Handling the memory allocation failure here is
491 tricky here because the bytearray object has already been
492 modified. Depending on growth and lo, the behaviour is
493 different.
494
495 If growth < 0 and lo != 0, the operation is completed, but a
496 MemoryError is still raised and the memory block is not
497 shrinked. Otherwise, the bytearray is restored in its previous
498 state and a MemoryError is raised. */
499 if (lo == 0) {
500 self->ob_start += growth;
501 return -1;
502 }
503 /* memmove() removed bytes, the bytearray object cannot be
504 restored in its previous state. */
505 Py_SIZE(self) += growth;
506 res = -1;
507 }
508 buf = PyByteArray_AS_STRING(self);
509 }
510 else if (growth > 0) {
511 if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
512 PyErr_NoMemory();
513 return -1;
514 }
515
516 if (PyByteArray_Resize((PyObject *)self,
517 Py_SIZE(self) + growth) < 0) {
518 return -1;
519 }
520 buf = PyByteArray_AS_STRING(self);
521 /* Make the place for the additional bytes */
522 /*
523 0 lo hi old_size
524 | |<-avail->|<-----tomove------>|
525 | |<---bytes_len-->|<-----tomove------>|
526 0 lo new_hi new_size
527 */
528 memmove(buf + lo + bytes_len, buf + hi,
529 Py_SIZE(self) - lo - bytes_len);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200530 }
531
532 if (bytes_len > 0)
533 memcpy(buf + lo, bytes, bytes_len);
Victor Stinner84557232013-11-21 12:29:51 +0100534 return res;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200535}
536
537static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000538bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000539 PyObject *values)
540{
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200541 Py_ssize_t needed;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000542 void *bytes;
543 Py_buffer vbytes;
544 int res = 0;
545
546 vbytes.len = -1;
547 if (values == (PyObject *)self) {
548 /* Make a copy and call this function recursively */
549 int err;
550 values = PyByteArray_FromObject(values);
551 if (values == NULL)
552 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000553 err = bytearray_setslice(self, lo, hi, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000554 Py_DECREF(values);
555 return err;
556 }
557 if (values == NULL) {
558 /* del b[lo:hi] */
559 bytes = NULL;
560 needed = 0;
561 }
562 else {
563 if (_getbuffer(values, &vbytes) < 0) {
564 PyErr_Format(PyExc_TypeError,
Georg Brandl3dbca812008-07-23 16:10:53 +0000565 "can't set bytearray slice from %.100s",
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000566 Py_TYPE(values)->tp_name);
567 return -1;
568 }
569 needed = vbytes.len;
570 bytes = vbytes.buf;
571 }
572
573 if (lo < 0)
574 lo = 0;
575 if (hi < lo)
576 hi = lo;
577 if (hi > Py_SIZE(self))
578 hi = Py_SIZE(self);
579
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200580 res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000581 if (vbytes.len != -1)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200582 PyBuffer_Release(&vbytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000583 return res;
584}
585
586static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000587bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000588{
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000589 int ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000590
591 if (i < 0)
592 i += Py_SIZE(self);
593
594 if (i < 0 || i >= Py_SIZE(self)) {
595 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
596 return -1;
597 }
598
599 if (value == NULL)
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000600 return bytearray_setslice(self, i, i+1, NULL);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000601
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000602 if (!_getbytevalue(value, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000603 return -1;
604
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200605 PyByteArray_AS_STRING(self)[i] = ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000606 return 0;
607}
608
609static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000610bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000611{
612 Py_ssize_t start, stop, step, slicelen, needed;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200613 char *buf, *bytes;
614 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000615
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000616 if (PyIndex_Check(index)) {
617 Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000618
619 if (i == -1 && PyErr_Occurred())
620 return -1;
621
622 if (i < 0)
623 i += PyByteArray_GET_SIZE(self);
624
625 if (i < 0 || i >= Py_SIZE(self)) {
626 PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
627 return -1;
628 }
629
630 if (values == NULL) {
631 /* Fall through to slice assignment */
632 start = i;
633 stop = i + 1;
634 step = 1;
635 slicelen = 1;
636 }
637 else {
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000638 int ival;
639 if (!_getbytevalue(values, &ival))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000640 return -1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200641 buf[i] = (char)ival;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000642 return 0;
643 }
644 }
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000645 else if (PySlice_Check(index)) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000646 if (PySlice_GetIndicesEx(index,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000647 PyByteArray_GET_SIZE(self),
648 &start, &stop, &step, &slicelen) < 0) {
649 return -1;
650 }
651 }
652 else {
653 PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
654 return -1;
655 }
656
657 if (values == NULL) {
658 bytes = NULL;
659 needed = 0;
660 }
661 else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
Christian Heimes6d26ade2012-11-03 23:07:59 +0100662 int err;
Ezio Melottic64bcbe2012-11-03 21:19:06 +0200663 if (PyNumber_Check(values) || PyUnicode_Check(values)) {
664 PyErr_SetString(PyExc_TypeError,
665 "can assign only bytes, buffers, or iterables "
666 "of ints in range(0, 256)");
667 return -1;
668 }
Georg Brandlf3fa5682010-12-04 17:09:30 +0000669 /* Make a copy and call this function recursively */
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000670 values = PyByteArray_FromObject(values);
671 if (values == NULL)
672 return -1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000673 err = bytearray_ass_subscript(self, index, values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000674 Py_DECREF(values);
675 return err;
676 }
677 else {
678 assert(PyByteArray_Check(values));
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200679 bytes = PyByteArray_AS_STRING(values);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000680 needed = Py_SIZE(values);
681 }
682 /* Make sure b[5:2] = ... inserts before 5, not before 2. */
683 if ((step < 0 && start < stop) ||
684 (step > 0 && start > stop))
685 stop = start;
686 if (step == 1) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200687 return bytearray_setslice_linear(self, start, stop, bytes, needed);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000688 }
689 else {
690 if (needed == 0) {
691 /* Delete slice */
Mark Dickinsonbc099642010-01-29 17:27:24 +0000692 size_t cur;
693 Py_ssize_t i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000694
Antoine Pitrou5504e892008-12-06 21:27:53 +0000695 if (!_canresize(self))
696 return -1;
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000697
698 if (slicelen == 0)
699 /* Nothing to do here. */
700 return 0;
701
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000702 if (step < 0) {
703 stop = start + 1;
704 start = stop + step * (slicelen - 1) - 1;
705 step = -step;
706 }
707 for (cur = start, i = 0;
708 i < slicelen; cur += step, i++) {
709 Py_ssize_t lim = step - 1;
710
Mark Dickinson66f575b2010-02-14 12:53:32 +0000711 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000712 lim = PyByteArray_GET_SIZE(self) - cur - 1;
713
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200714 memmove(buf + cur - i,
715 buf + cur + 1, lim);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000716 }
717 /* Move the tail of the bytes, in one chunk */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000718 cur = start + (size_t)slicelen*step;
Mark Dickinson66f575b2010-02-14 12:53:32 +0000719 if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200720 memmove(buf + cur - slicelen,
721 buf + cur,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000722 PyByteArray_GET_SIZE(self) - cur);
723 }
724 if (PyByteArray_Resize((PyObject *)self,
725 PyByteArray_GET_SIZE(self) - slicelen) < 0)
726 return -1;
727
728 return 0;
729 }
730 else {
731 /* Assign slice */
Mark Dickinson7e3b9482010-08-06 21:33:18 +0000732 Py_ssize_t i;
733 size_t cur;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000734
735 if (needed != slicelen) {
736 PyErr_Format(PyExc_ValueError,
737 "attempt to assign bytes of size %zd "
738 "to extended slice of size %zd",
739 needed, slicelen);
740 return -1;
741 }
742 for (cur = start, i = 0; i < slicelen; cur += step, i++)
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200743 buf[cur] = bytes[i];
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000744 return 0;
745 }
746 }
747}
748
749static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000750bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000751{
752 static char *kwlist[] = {"source", "encoding", "errors", 0};
753 PyObject *arg = NULL;
754 const char *encoding = NULL;
755 const char *errors = NULL;
756 Py_ssize_t count;
757 PyObject *it;
758 PyObject *(*iternext)(PyObject *);
759
760 if (Py_SIZE(self) != 0) {
761 /* Empty previous contents (yes, do this first of all!) */
762 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
763 return -1;
764 }
765
766 /* Parse arguments */
Georg Brandl3dbca812008-07-23 16:10:53 +0000767 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000768 &arg, &encoding, &errors))
769 return -1;
770
771 /* Make a quick exit if no first argument */
772 if (arg == NULL) {
773 if (encoding != NULL || errors != NULL) {
774 PyErr_SetString(PyExc_TypeError,
775 "encoding or errors without sequence argument");
776 return -1;
777 }
778 return 0;
779 }
780
781 if (PyUnicode_Check(arg)) {
782 /* Encode via the codec registry */
783 PyObject *encoded, *new;
784 if (encoding == NULL) {
785 PyErr_SetString(PyExc_TypeError,
786 "string argument without an encoding");
787 return -1;
788 }
Marc-André Lemburgb2750b52008-06-06 12:18:17 +0000789 encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000790 if (encoded == NULL)
791 return -1;
792 assert(PyBytes_Check(encoded));
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000793 new = bytearray_iconcat(self, encoded);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000794 Py_DECREF(encoded);
795 if (new == NULL)
796 return -1;
797 Py_DECREF(new);
798 return 0;
799 }
800
801 /* If it's not unicode, there can't be encoding or errors */
802 if (encoding != NULL || errors != NULL) {
803 PyErr_SetString(PyExc_TypeError,
804 "encoding or errors without a string argument");
805 return -1;
806 }
807
808 /* Is it an int? */
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000809 count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
810 if (count == -1 && PyErr_Occurred()) {
811 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000812 return -1;
Benjamin Peterson9c0e94f2010-04-16 23:00:53 +0000813 PyErr_Clear();
Benjamin Peterson8380dd52010-04-16 22:51:37 +0000814 }
815 else if (count < 0) {
816 PyErr_SetString(PyExc_ValueError, "negative count");
817 return -1;
818 }
819 else {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000820 if (count > 0) {
Victor Stinner2bc4d952014-06-02 22:22:42 +0200821 if (PyByteArray_Resize((PyObject *)self, count))
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000822 return -1;
Victor Stinner2bc4d952014-06-02 22:22:42 +0200823 memset(PyByteArray_AS_STRING(self), 0, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000824 }
825 return 0;
826 }
827
828 /* Use the buffer API */
829 if (PyObject_CheckBuffer(arg)) {
830 Py_ssize_t size;
831 Py_buffer view;
832 if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
833 return -1;
834 size = view.len;
835 if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200836 if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
837 &view, size, 'C') < 0)
Stefan Krah7d12d9d2012-07-28 12:25:55 +0200838 goto fail;
Martin v. Löwis423be952008-08-13 15:53:07 +0000839 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000840 return 0;
841 fail:
Martin v. Löwis423be952008-08-13 15:53:07 +0000842 PyBuffer_Release(&view);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000843 return -1;
844 }
845
846 /* XXX Optimize this if the arguments is a list, tuple */
847
848 /* Get the iterator */
849 it = PyObject_GetIter(arg);
850 if (it == NULL)
851 return -1;
852 iternext = *Py_TYPE(it)->tp_iternext;
853
854 /* Run the iterator to exhaustion */
855 for (;;) {
856 PyObject *item;
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000857 int rc, value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000858
859 /* Get the next item */
860 item = iternext(it);
861 if (item == NULL) {
862 if (PyErr_Occurred()) {
863 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
864 goto error;
865 PyErr_Clear();
866 }
867 break;
868 }
869
870 /* Interpret it as an int (__index__) */
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000871 rc = _getbytevalue(item, &value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000872 Py_DECREF(item);
Georg Brandl9a54d7c2008-07-16 23:15:30 +0000873 if (!rc)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000874 goto error;
875
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000876 /* Append the byte */
877 if (Py_SIZE(self) < self->ob_alloc)
878 Py_SIZE(self)++;
879 else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
880 goto error;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200881 PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000882 }
883
884 /* Clean up and return success */
885 Py_DECREF(it);
886 return 0;
887
888 error:
889 /* Error handling when it != NULL */
890 Py_DECREF(it);
891 return -1;
892}
893
894/* Mostly copied from string_repr, but without the
895 "smart quote" functionality. */
896static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000897bytearray_repr(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000898{
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000899 const char *quote_prefix = "bytearray(b";
900 const char *quote_postfix = ")";
901 Py_ssize_t length = Py_SIZE(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200902 /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
Mark Dickinson66f575b2010-02-14 12:53:32 +0000903 size_t newsize;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000904 PyObject *v;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200905 Py_ssize_t i;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200906 char *bytes;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200907 char c;
908 char *p;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200909 int quote;
910 char *test, *start;
911 char *buffer;
912
913 if (length > (PY_SSIZE_T_MAX - 15) / 4) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000914 PyErr_SetString(PyExc_OverflowError,
915 "bytearray object is too large to make repr");
916 return NULL;
917 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200918
919 newsize = 15 + length * 4;
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100920 buffer = PyObject_Malloc(newsize);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200921 if (buffer == NULL) {
922 PyErr_NoMemory();
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000923 return NULL;
924 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000925
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200926 /* Figure out which quote to use; single is preferred */
927 quote = '\'';
928 start = PyByteArray_AS_STRING(self);
929 for (test = start; test < start+length; ++test) {
930 if (*test == '"') {
931 quote = '\''; /* back to single */
932 break;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000933 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200934 else if (*test == '\'')
935 quote = '"';
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000936 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200937
938 p = buffer;
939 while (*quote_prefix)
940 *p++ = *quote_prefix++;
941 *p++ = quote;
942
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200943 bytes = PyByteArray_AS_STRING(self);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200944 for (i = 0; i < length; i++) {
945 /* There's at least enough room for a hex escape
946 and a closing quote. */
947 assert(newsize - (p - buffer) >= 5);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +0200948 c = bytes[i];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200949 if (c == '\'' || c == '\\')
950 *p++ = '\\', *p++ = c;
951 else if (c == '\t')
952 *p++ = '\\', *p++ = 't';
953 else if (c == '\n')
954 *p++ = '\\', *p++ = 'n';
955 else if (c == '\r')
956 *p++ = '\\', *p++ = 'r';
957 else if (c == 0)
958 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
959 else if (c < ' ' || c >= 0x7f) {
960 *p++ = '\\';
961 *p++ = 'x';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200962 *p++ = Py_hexdigits[(c & 0xf0) >> 4];
963 *p++ = Py_hexdigits[c & 0xf];
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200964 }
965 else
966 *p++ = c;
967 }
968 assert(newsize - (p - buffer) >= 1);
969 *p++ = quote;
970 while (*quote_postfix) {
971 *p++ = *quote_postfix++;
972 }
973
974 v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
Antoine Pitrou39aba4f2011-11-12 21:15:28 +0100975 PyObject_Free(buffer);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200976 return v;
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000977}
978
979static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000980bytearray_str(PyObject *op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000981{
Alexander Belopolskyf0f45142010-08-11 17:31:17 +0000982 if (Py_BytesWarningFlag) {
983 if (PyErr_WarnEx(PyExc_BytesWarning,
984 "str() on a bytearray instance", 1))
985 return NULL;
986 }
987 return bytearray_repr((PyByteArrayObject*)op);
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000988}
989
990static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +0000991bytearray_richcompare(PyObject *self, PyObject *other, int op)
Christian Heimes2c9c7a52008-05-26 13:42:13 +0000992{
993 Py_ssize_t self_size, other_size;
994 Py_buffer self_bytes, other_bytes;
995 PyObject *res;
996 Py_ssize_t minsize;
997 int cmp;
998
999 /* Bytes can be compared to anything that supports the (binary)
1000 buffer API. Except that a comparison with Unicode is always an
1001 error, even if the comparison is for equality. */
1002 if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
1003 PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
Barry Warsaw9e9dcd62008-10-17 01:50:37 +00001004 if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001005 if (PyErr_WarnEx(PyExc_BytesWarning,
Georg Brandle5d68ac2008-06-04 11:30:26 +00001006 "Comparison between bytearray and string", 1))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001007 return NULL;
1008 }
1009
Brian Curtindfc80e32011-08-10 20:28:54 -05001010 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001011 }
1012
1013 self_size = _getbuffer(self, &self_bytes);
1014 if (self_size < 0) {
1015 PyErr_Clear();
Brian Curtindfc80e32011-08-10 20:28:54 -05001016 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001017 }
1018
1019 other_size = _getbuffer(other, &other_bytes);
1020 if (other_size < 0) {
1021 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +00001022 PyBuffer_Release(&self_bytes);
Brian Curtindfc80e32011-08-10 20:28:54 -05001023 Py_RETURN_NOTIMPLEMENTED;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001024 }
1025
1026 if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1027 /* Shortcut: if the lengths differ, the objects differ */
1028 cmp = (op == Py_NE);
1029 }
1030 else {
1031 minsize = self_size;
1032 if (other_size < minsize)
1033 minsize = other_size;
1034
1035 cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
1036 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1037
1038 if (cmp == 0) {
1039 if (self_size < other_size)
1040 cmp = -1;
1041 else if (self_size > other_size)
1042 cmp = 1;
1043 }
1044
1045 switch (op) {
1046 case Py_LT: cmp = cmp < 0; break;
1047 case Py_LE: cmp = cmp <= 0; break;
1048 case Py_EQ: cmp = cmp == 0; break;
1049 case Py_NE: cmp = cmp != 0; break;
1050 case Py_GT: cmp = cmp > 0; break;
1051 case Py_GE: cmp = cmp >= 0; break;
1052 }
1053 }
1054
1055 res = cmp ? Py_True : Py_False;
Martin v. Löwis423be952008-08-13 15:53:07 +00001056 PyBuffer_Release(&self_bytes);
1057 PyBuffer_Release(&other_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001058 Py_INCREF(res);
1059 return res;
1060}
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
1102/* The following Py_LOCAL_INLINE and Py_LOCAL functions
1103were copied from the old char* style string object. */
1104
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001105/* helper macro to fixup start/end slice values */
1106#define ADJUST_INDICES(start, end, len) \
1107 if (end > len) \
1108 end = len; \
1109 else if (end < 0) { \
1110 end += len; \
1111 if (end < 0) \
1112 end = 0; \
1113 } \
1114 if (start < 0) { \
1115 start += len; \
1116 if (start < 0) \
1117 start = 0; \
1118 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001119
1120Py_LOCAL_INLINE(Py_ssize_t)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001121bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001122{
1123 PyObject *subobj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001124 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001125 Py_buffer subbuf;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001126 const char *sub;
1127 Py_ssize_t sub_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001128 Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
1129 Py_ssize_t res;
1130
Antoine Pitrouac65d962011-10-20 23:54:17 +02001131 if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
1132 args, &subobj, &byte, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001133 return -2;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001134
1135 if (subobj) {
1136 if (_getbuffer(subobj, &subbuf) < 0)
1137 return -2;
1138
1139 sub = subbuf.buf;
1140 sub_len = subbuf.len;
1141 }
1142 else {
1143 sub = &byte;
1144 sub_len = 1;
1145 }
1146
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001147 if (dir > 0)
1148 res = stringlib_find_slice(
1149 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001150 sub, sub_len, start, end);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001151 else
1152 res = stringlib_rfind_slice(
1153 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
Antoine Pitrouac65d962011-10-20 23:54:17 +02001154 sub, sub_len, start, end);
1155
1156 if (subobj)
1157 PyBuffer_Release(&subbuf);
1158
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001159 return res;
1160}
1161
1162PyDoc_STRVAR(find__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001163"B.find(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001164\n\
1165Return the lowest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001166such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001167arguments start and end are interpreted as in slice notation.\n\
1168\n\
1169Return -1 on failure.");
1170
1171static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001172bytearray_find(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001173{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001174 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001175 if (result == -2)
1176 return NULL;
1177 return PyLong_FromSsize_t(result);
1178}
1179
1180PyDoc_STRVAR(count__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001181"B.count(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001182\n\
1183Return the number of non-overlapping occurrences of subsection sub in\n\
1184bytes B[start:end]. Optional arguments start and end are interpreted\n\
1185as in slice notation.");
1186
1187static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001188bytearray_count(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001189{
1190 PyObject *sub_obj;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001191 const char *str = PyByteArray_AS_STRING(self), *sub;
1192 Py_ssize_t sub_len;
1193 char byte;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001194 Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
Antoine Pitrouac65d962011-10-20 23:54:17 +02001195
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001196 Py_buffer vsub;
1197 PyObject *count_obj;
1198
Antoine Pitrouac65d962011-10-20 23:54:17 +02001199 if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
1200 &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001201 return NULL;
1202
Antoine Pitrouac65d962011-10-20 23:54:17 +02001203 if (sub_obj) {
1204 if (_getbuffer(sub_obj, &vsub) < 0)
1205 return NULL;
1206
1207 sub = vsub.buf;
1208 sub_len = vsub.len;
1209 }
1210 else {
1211 sub = &byte;
1212 sub_len = 1;
1213 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001214
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001215 ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001216
1217 count_obj = PyLong_FromSsize_t(
Antoine Pitrouac65d962011-10-20 23:54:17 +02001218 stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001219 );
Antoine Pitrouac65d962011-10-20 23:54:17 +02001220
1221 if (sub_obj)
1222 PyBuffer_Release(&vsub);
1223
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001224 return count_obj;
1225}
1226
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001227/*[clinic input]
1228bytearray.clear
1229
1230 self: self(type="PyByteArrayObject *")
1231
1232Remove all items from the bytearray.
1233[clinic start generated code]*/
1234
1235PyDoc_STRVAR(bytearray_clear__doc__,
1236"clear($self, /)\n"
1237"--\n"
1238"\n"
1239"Remove all items from the bytearray.");
1240
1241#define BYTEARRAY_CLEAR_METHODDEF \
1242 {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, bytearray_clear__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00001243
Victor Stinner6430fd52011-09-29 04:02:13 +02001244static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001245bytearray_clear_impl(PyByteArrayObject *self);
1246
1247static PyObject *
1248bytearray_clear(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
1249{
1250 return bytearray_clear_impl(self);
1251}
1252
1253static PyObject *
1254bytearray_clear_impl(PyByteArrayObject *self)
1255/*[clinic end generated code: output=5344093031e2f36c input=e524fd330abcdc18]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001256{
1257 if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1258 return NULL;
1259 Py_RETURN_NONE;
1260}
1261
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001262/*[clinic input]
1263bytearray.copy
1264
1265 self: self(type="PyByteArrayObject *")
1266
1267Return a copy of B.
1268[clinic start generated code]*/
1269
1270PyDoc_STRVAR(bytearray_copy__doc__,
1271"copy($self, /)\n"
1272"--\n"
1273"\n"
1274"Return a copy of B.");
1275
1276#define BYTEARRAY_COPY_METHODDEF \
1277 {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, bytearray_copy__doc__},
Eli Bendersky4db28d32011-03-03 18:21:02 +00001278
1279static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001280bytearray_copy_impl(PyByteArrayObject *self);
1281
1282static PyObject *
1283bytearray_copy(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
1284{
1285 return bytearray_copy_impl(self);
1286}
1287
1288static PyObject *
1289bytearray_copy_impl(PyByteArrayObject *self)
1290/*[clinic end generated code: output=8788ed299f7f2214 input=6d5d2975aa0f33f3]*/
Eli Bendersky4db28d32011-03-03 18:21:02 +00001291{
1292 return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1293 PyByteArray_GET_SIZE(self));
1294}
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001295
1296PyDoc_STRVAR(index__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001297"B.index(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001298\n\
1299Like B.find() but raise ValueError when the subsection is not found.");
1300
1301static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001302bytearray_index(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001303{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001304 Py_ssize_t result = bytearray_find_internal(self, args, +1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001305 if (result == -2)
1306 return NULL;
1307 if (result == -1) {
1308 PyErr_SetString(PyExc_ValueError,
1309 "subsection not found");
1310 return NULL;
1311 }
1312 return PyLong_FromSsize_t(result);
1313}
1314
1315
1316PyDoc_STRVAR(rfind__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001317"B.rfind(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001318\n\
1319Return the highest index in B where subsection sub is found,\n\
Senthil Kumaran53516a82011-07-27 23:33:54 +08001320such that sub is contained within B[start,end]. Optional\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001321arguments start and end are interpreted as in slice notation.\n\
1322\n\
1323Return -1 on failure.");
1324
1325static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001326bytearray_rfind(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001327{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001328 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001329 if (result == -2)
1330 return NULL;
1331 return PyLong_FromSsize_t(result);
1332}
1333
1334
1335PyDoc_STRVAR(rindex__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001336"B.rindex(sub[, start[, end]]) -> int\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001337\n\
1338Like B.rfind() but raise ValueError when the subsection is not found.");
1339
1340static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001341bytearray_rindex(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001342{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001343 Py_ssize_t result = bytearray_find_internal(self, args, -1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001344 if (result == -2)
1345 return NULL;
1346 if (result == -1) {
1347 PyErr_SetString(PyExc_ValueError,
1348 "subsection not found");
1349 return NULL;
1350 }
1351 return PyLong_FromSsize_t(result);
1352}
1353
1354
1355static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001356bytearray_contains(PyObject *self, PyObject *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001357{
1358 Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
1359 if (ival == -1 && PyErr_Occurred()) {
1360 Py_buffer varg;
Antoine Pitrou0010d372010-08-15 17:12:55 +00001361 Py_ssize_t pos;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001362 PyErr_Clear();
1363 if (_getbuffer(arg, &varg) < 0)
1364 return -1;
1365 pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
1366 varg.buf, varg.len, 0);
Martin v. Löwis423be952008-08-13 15:53:07 +00001367 PyBuffer_Release(&varg);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001368 return pos >= 0;
1369 }
1370 if (ival < 0 || ival >= 256) {
1371 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
1372 return -1;
1373 }
1374
Antoine Pitrou0010d372010-08-15 17:12:55 +00001375 return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001376}
1377
1378
1379/* Matches the end (direction >= 0) or start (direction < 0) of self
1380 * against substr, using the start and end arguments. Returns
1381 * -1 on error, 0 if not found and 1 if found.
1382 */
1383Py_LOCAL(int)
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001384_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001385 Py_ssize_t end, int direction)
1386{
1387 Py_ssize_t len = PyByteArray_GET_SIZE(self);
1388 const char* str;
1389 Py_buffer vsubstr;
1390 int rv = 0;
1391
1392 str = PyByteArray_AS_STRING(self);
1393
1394 if (_getbuffer(substr, &vsubstr) < 0)
1395 return -1;
1396
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001397 ADJUST_INDICES(start, end, len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001398
1399 if (direction < 0) {
1400 /* startswith */
1401 if (start+vsubstr.len > len) {
1402 goto done;
1403 }
1404 } else {
1405 /* endswith */
1406 if (end-start < vsubstr.len || start > len) {
1407 goto done;
1408 }
1409
1410 if (end-vsubstr.len > start)
1411 start = end - vsubstr.len;
1412 }
1413 if (end-start >= vsubstr.len)
1414 rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
1415
1416done:
Martin v. Löwis423be952008-08-13 15:53:07 +00001417 PyBuffer_Release(&vsubstr);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001418 return rv;
1419}
1420
1421
1422PyDoc_STRVAR(startswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001423"B.startswith(prefix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001424\n\
1425Return True if B starts with the specified prefix, False otherwise.\n\
1426With optional start, test B beginning at that position.\n\
1427With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001428prefix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001429
1430static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001431bytearray_startswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001432{
1433 Py_ssize_t start = 0;
1434 Py_ssize_t end = PY_SSIZE_T_MAX;
1435 PyObject *subobj;
1436 int result;
1437
Jesus Ceaac451502011-04-20 17:09:23 +02001438 if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001439 return NULL;
1440 if (PyTuple_Check(subobj)) {
1441 Py_ssize_t i;
1442 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001443 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001444 PyTuple_GET_ITEM(subobj, i),
1445 start, end, -1);
1446 if (result == -1)
1447 return NULL;
1448 else if (result) {
1449 Py_RETURN_TRUE;
1450 }
1451 }
1452 Py_RETURN_FALSE;
1453 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001454 result = _bytearray_tailmatch(self, subobj, start, end, -1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001455 if (result == -1) {
1456 if (PyErr_ExceptionMatches(PyExc_TypeError))
1457 PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
1458 "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001459 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001460 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001461 else
1462 return PyBool_FromLong(result);
1463}
1464
1465PyDoc_STRVAR(endswith__doc__,
Georg Brandl17cb8a82008-05-30 08:20:09 +00001466"B.endswith(suffix[, start[, end]]) -> bool\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001467\n\
1468Return True if B ends with the specified suffix, False otherwise.\n\
1469With optional start, test B beginning at that position.\n\
1470With optional end, stop comparing B at that position.\n\
Ezio Melottiba42fd52011-04-26 06:09:45 +03001471suffix can also be a tuple of bytes to try.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001472
1473static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001474bytearray_endswith(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001475{
1476 Py_ssize_t start = 0;
1477 Py_ssize_t end = PY_SSIZE_T_MAX;
1478 PyObject *subobj;
1479 int result;
1480
Jesus Ceaac451502011-04-20 17:09:23 +02001481 if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001482 return NULL;
1483 if (PyTuple_Check(subobj)) {
1484 Py_ssize_t i;
1485 for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001486 result = _bytearray_tailmatch(self,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001487 PyTuple_GET_ITEM(subobj, i),
1488 start, end, +1);
1489 if (result == -1)
1490 return NULL;
1491 else if (result) {
1492 Py_RETURN_TRUE;
1493 }
1494 }
1495 Py_RETURN_FALSE;
1496 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001497 result = _bytearray_tailmatch(self, subobj, start, end, +1);
Ezio Melottiba42fd52011-04-26 06:09:45 +03001498 if (result == -1) {
1499 if (PyErr_ExceptionMatches(PyExc_TypeError))
1500 PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
1501 "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001502 return NULL;
Ezio Melottiba42fd52011-04-26 06:09:45 +03001503 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001504 else
1505 return PyBool_FromLong(result);
1506}
1507
1508
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001509/*[clinic input]
1510bytearray.translate
1511
1512 self: self(type="PyByteArrayObject *")
1513 table: object
1514 Translation table, which must be a bytes object of length 256.
1515 [
1516 deletechars: object
1517 ]
1518 /
1519
1520Return a copy with each character mapped by the given translation table.
1521
1522All characters occurring in the optional argument deletechars are removed.
1523The remaining characters are mapped through the given translation table.
1524[clinic start generated code]*/
1525
1526PyDoc_STRVAR(bytearray_translate__doc__,
1527"translate(table, [deletechars])\n"
1528"Return a copy with each character mapped by the given translation table.\n"
1529"\n"
1530" table\n"
1531" Translation table, which must be a bytes object of length 256.\n"
1532"\n"
1533"All characters occurring in the optional argument deletechars are removed.\n"
1534"The remaining characters are mapped through the given translation table.");
1535
1536#define BYTEARRAY_TRANSLATE_METHODDEF \
1537 {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, bytearray_translate__doc__},
1538
1539static PyObject *
1540bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001541
1542static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00001543bytearray_translate(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001544{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001545 PyObject *return_value = NULL;
1546 PyObject *table;
1547 int group_right_1 = 0;
1548 PyObject *deletechars = NULL;
1549
1550 switch (PyTuple_GET_SIZE(args)) {
1551 case 1:
1552 if (!PyArg_ParseTuple(args, "O:translate", &table))
1553 goto exit;
1554 break;
1555 case 2:
1556 if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars))
1557 goto exit;
1558 group_right_1 = 1;
1559 break;
1560 default:
1561 PyErr_SetString(PyExc_TypeError, "bytearray.translate requires 1 to 2 arguments");
1562 goto exit;
1563 }
1564 return_value = bytearray_translate_impl(self, table, group_right_1, deletechars);
1565
1566exit:
1567 return return_value;
1568}
1569
1570static PyObject *
1571bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars)
1572/*[clinic end generated code: output=a709df81d41db4b7 input=b749ad85f4860824]*/
1573{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001574 char *input, *output;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001575 const char *table_chars;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001576 Py_ssize_t i, c;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001577 PyObject *input_obj = (PyObject*)self;
1578 const char *output_start;
1579 Py_ssize_t inlen;
Georg Brandlccc47b62008-12-28 11:44:14 +00001580 PyObject *result = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001581 int trans_table[256];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001582 Py_buffer vtable, vdel;
1583
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001584 if (table == Py_None) {
1585 table_chars = NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001586 table = NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001587 } else if (_getbuffer(table, &vtable) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001588 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001589 } else {
1590 if (vtable.len != 256) {
1591 PyErr_SetString(PyExc_ValueError,
1592 "translation table must be 256 characters long");
Georg Brandl953152f2009-07-22 12:03:59 +00001593 PyBuffer_Release(&vtable);
1594 return NULL;
Georg Brandlccc47b62008-12-28 11:44:14 +00001595 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001596 table_chars = (const char*)vtable.buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001597 }
1598
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001599 if (deletechars != NULL) {
1600 if (_getbuffer(deletechars, &vdel) < 0) {
1601 if (table != NULL)
Georg Brandl953152f2009-07-22 12:03:59 +00001602 PyBuffer_Release(&vtable);
1603 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001604 }
1605 }
1606 else {
1607 vdel.buf = NULL;
1608 vdel.len = 0;
1609 }
1610
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001611 inlen = PyByteArray_GET_SIZE(input_obj);
1612 result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1613 if (result == NULL)
1614 goto done;
1615 output_start = output = PyByteArray_AsString(result);
1616 input = PyByteArray_AS_STRING(input_obj);
1617
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001618 if (vdel.len == 0 && table_chars != NULL) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001619 /* If no deletions are required, use faster code */
1620 for (i = inlen; --i >= 0; ) {
1621 c = Py_CHARMASK(*input++);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001622 *output++ = table_chars[c];
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001623 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001624 goto done;
1625 }
Georg Brandlccc47b62008-12-28 11:44:14 +00001626
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001627 if (table_chars == NULL) {
Georg Brandlccc47b62008-12-28 11:44:14 +00001628 for (i = 0; i < 256; i++)
1629 trans_table[i] = Py_CHARMASK(i);
1630 } else {
1631 for (i = 0; i < 256; i++)
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001632 trans_table[i] = Py_CHARMASK(table_chars[i]);
Georg Brandlccc47b62008-12-28 11:44:14 +00001633 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001634
1635 for (i = 0; i < vdel.len; i++)
1636 trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1637
1638 for (i = inlen; --i >= 0; ) {
1639 c = Py_CHARMASK(*input++);
1640 if (trans_table[c] != -1)
1641 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
1642 continue;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001643 }
1644 /* Fix the size of the resulting string */
1645 if (inlen > 0)
Christian Heimesc731bbe2013-07-21 02:04:35 +02001646 if (PyByteArray_Resize(result, output - output_start) < 0) {
1647 Py_CLEAR(result);
1648 goto done;
1649 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001650
1651done:
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001652 if (table != NULL)
Georg Brandlccc47b62008-12-28 11:44:14 +00001653 PyBuffer_Release(&vtable);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001654 if (deletechars != NULL)
Martin v. Löwis423be952008-08-13 15:53:07 +00001655 PyBuffer_Release(&vdel);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001656 return result;
1657}
1658
1659
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001660/*[clinic input]
1661
1662@staticmethod
1663bytearray.maketrans
1664
1665 frm: object
1666 to: object
1667 /
1668
1669Return a translation table useable for the bytes or bytearray translate method.
1670
1671The returned table will be one where each byte in frm is mapped to the byte at
1672the same position in to.
1673
1674The bytes objects frm and to must be of the same length.
1675[clinic start generated code]*/
1676
1677PyDoc_STRVAR(bytearray_maketrans__doc__,
1678"maketrans(frm, to, /)\n"
1679"--\n"
1680"\n"
1681"Return a translation table useable for the bytes or bytearray translate method.\n"
1682"\n"
1683"The returned table will be one where each byte in frm is mapped to the byte at\n"
1684"the same position in to.\n"
1685"\n"
1686"The bytes objects frm and to must be of the same length.");
1687
1688#define BYTEARRAY_MAKETRANS_METHODDEF \
1689 {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, bytearray_maketrans__doc__},
1690
Georg Brandlabc38772009-04-12 15:51:51 +00001691static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001692bytearray_maketrans_impl(PyObject *frm, PyObject *to);
1693
1694static PyObject *
1695bytearray_maketrans(void *null, PyObject *args)
Georg Brandlabc38772009-04-12 15:51:51 +00001696{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02001697 PyObject *return_value = NULL;
1698 PyObject *frm;
1699 PyObject *to;
1700
1701 if (!PyArg_UnpackTuple(args, "maketrans",
1702 2, 2,
1703 &frm, &to))
1704 goto exit;
1705 return_value = bytearray_maketrans_impl(frm, to);
1706
1707exit:
1708 return return_value;
1709}
1710
1711static PyObject *
1712bytearray_maketrans_impl(PyObject *frm, PyObject *to)
1713/*[clinic end generated code: output=307752019d9b25b5 input=ea9bdc6b328c15e2]*/
1714{
1715 return _Py_bytes_maketrans(frm, to);
Georg Brandlabc38772009-04-12 15:51:51 +00001716}
1717
1718
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001719/* find and count characters and substrings */
1720
1721#define findchar(target, target_len, c) \
1722 ((char *)memchr((const void *)(target), c, target_len))
1723
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001724
Benjamin Peterson0f3641c2008-11-19 22:05:52 +00001725/* Bytes ops must return a string, create a copy */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001726Py_LOCAL(PyByteArrayObject *)
1727return_self(PyByteArrayObject *self)
1728{
Georg Brandl1e7217d2008-05-30 12:02:38 +00001729 /* always return a new bytearray */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001730 return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
1731 PyByteArray_AS_STRING(self),
1732 PyByteArray_GET_SIZE(self));
1733}
1734
1735Py_LOCAL_INLINE(Py_ssize_t)
1736countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
1737{
1738 Py_ssize_t count=0;
1739 const char *start=target;
1740 const char *end=target+target_len;
1741
1742 while ( (start=findchar(start, end-start, c)) != NULL ) {
1743 count++;
1744 if (count >= maxcount)
1745 break;
1746 start += 1;
1747 }
1748 return count;
1749}
1750
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001751
1752/* Algorithms for different cases of string replacement */
1753
1754/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
1755Py_LOCAL(PyByteArrayObject *)
1756replace_interleave(PyByteArrayObject *self,
1757 const char *to_s, Py_ssize_t to_len,
1758 Py_ssize_t maxcount)
1759{
1760 char *self_s, *result_s;
1761 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001762 Py_ssize_t count, i;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001763 PyByteArrayObject *result;
1764
1765 self_len = PyByteArray_GET_SIZE(self);
1766
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001767 /* 1 at the end plus 1 after every character;
1768 count = min(maxcount, self_len + 1) */
1769 if (maxcount <= self_len)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001770 count = maxcount;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001771 else
1772 /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
1773 count = self_len + 1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001774
1775 /* Check for overflow */
1776 /* result_len = count * to_len + self_len; */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001777 assert(count > 0);
1778 if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001779 PyErr_SetString(PyExc_OverflowError,
1780 "replace string is too long");
1781 return NULL;
1782 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00001783 result_len = count * to_len + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001784
1785 if (! (result = (PyByteArrayObject *)
1786 PyByteArray_FromStringAndSize(NULL, result_len)) )
1787 return NULL;
1788
1789 self_s = PyByteArray_AS_STRING(self);
1790 result_s = PyByteArray_AS_STRING(result);
1791
1792 /* TODO: special case single character, which doesn't need memcpy */
1793
1794 /* Lay the first one down (guaranteed this will occur) */
1795 Py_MEMCPY(result_s, to_s, to_len);
1796 result_s += to_len;
1797 count -= 1;
1798
1799 for (i=0; i<count; i++) {
1800 *result_s++ = *self_s++;
1801 Py_MEMCPY(result_s, to_s, to_len);
1802 result_s += to_len;
1803 }
1804
1805 /* Copy the rest of the original string */
1806 Py_MEMCPY(result_s, self_s, self_len-i);
1807
1808 return result;
1809}
1810
1811/* Special case for deleting a single character */
1812/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
1813Py_LOCAL(PyByteArrayObject *)
1814replace_delete_single_character(PyByteArrayObject *self,
1815 char from_c, Py_ssize_t maxcount)
1816{
1817 char *self_s, *result_s;
1818 char *start, *next, *end;
1819 Py_ssize_t self_len, result_len;
1820 Py_ssize_t count;
1821 PyByteArrayObject *result;
1822
1823 self_len = PyByteArray_GET_SIZE(self);
1824 self_s = PyByteArray_AS_STRING(self);
1825
1826 count = countchar(self_s, self_len, from_c, maxcount);
1827 if (count == 0) {
1828 return return_self(self);
1829 }
1830
1831 result_len = self_len - count; /* from_len == 1 */
1832 assert(result_len>=0);
1833
1834 if ( (result = (PyByteArrayObject *)
1835 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
1836 return NULL;
1837 result_s = PyByteArray_AS_STRING(result);
1838
1839 start = self_s;
1840 end = self_s + self_len;
1841 while (count-- > 0) {
1842 next = findchar(start, end-start, from_c);
1843 if (next == NULL)
1844 break;
1845 Py_MEMCPY(result_s, start, next-start);
1846 result_s += (next-start);
1847 start = next+1;
1848 }
1849 Py_MEMCPY(result_s, start, end-start);
1850
1851 return result;
1852}
1853
1854/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
1855
1856Py_LOCAL(PyByteArrayObject *)
1857replace_delete_substring(PyByteArrayObject *self,
1858 const char *from_s, Py_ssize_t from_len,
1859 Py_ssize_t maxcount)
1860{
1861 char *self_s, *result_s;
1862 char *start, *next, *end;
1863 Py_ssize_t self_len, result_len;
1864 Py_ssize_t count, offset;
1865 PyByteArrayObject *result;
1866
1867 self_len = PyByteArray_GET_SIZE(self);
1868 self_s = PyByteArray_AS_STRING(self);
1869
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001870 count = stringlib_count(self_s, self_len,
1871 from_s, from_len,
1872 maxcount);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001873
1874 if (count == 0) {
1875 /* no matches */
1876 return return_self(self);
1877 }
1878
1879 result_len = self_len - (count * from_len);
1880 assert (result_len>=0);
1881
1882 if ( (result = (PyByteArrayObject *)
1883 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
1884 return NULL;
1885
1886 result_s = PyByteArray_AS_STRING(result);
1887
1888 start = self_s;
1889 end = self_s + self_len;
1890 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001891 offset = stringlib_find(start, end-start,
1892 from_s, from_len,
1893 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001894 if (offset == -1)
1895 break;
1896 next = start + offset;
1897
1898 Py_MEMCPY(result_s, start, next-start);
1899
1900 result_s += (next-start);
1901 start = next+from_len;
1902 }
1903 Py_MEMCPY(result_s, start, end-start);
1904 return result;
1905}
1906
1907/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
1908Py_LOCAL(PyByteArrayObject *)
1909replace_single_character_in_place(PyByteArrayObject *self,
1910 char from_c, char to_c,
1911 Py_ssize_t maxcount)
1912{
Antoine Pitroud1188562010-06-09 16:38:55 +00001913 char *self_s, *result_s, *start, *end, *next;
1914 Py_ssize_t self_len;
1915 PyByteArrayObject *result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001916
Antoine Pitroud1188562010-06-09 16:38:55 +00001917 /* The result string will be the same size */
1918 self_s = PyByteArray_AS_STRING(self);
1919 self_len = PyByteArray_GET_SIZE(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001920
Antoine Pitroud1188562010-06-09 16:38:55 +00001921 next = findchar(self_s, self_len, from_c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001922
Antoine Pitroud1188562010-06-09 16:38:55 +00001923 if (next == NULL) {
1924 /* No matches; return the original bytes */
1925 return return_self(self);
1926 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001927
Antoine Pitroud1188562010-06-09 16:38:55 +00001928 /* Need to make a new bytes */
1929 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1930 if (result == NULL)
1931 return NULL;
1932 result_s = PyByteArray_AS_STRING(result);
1933 Py_MEMCPY(result_s, self_s, self_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001934
Antoine Pitroud1188562010-06-09 16:38:55 +00001935 /* change everything in-place, starting with this one */
1936 start = result_s + (next-self_s);
1937 *start = to_c;
1938 start++;
1939 end = result_s + self_len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001940
Antoine Pitroud1188562010-06-09 16:38:55 +00001941 while (--maxcount > 0) {
1942 next = findchar(start, end-start, from_c);
1943 if (next == NULL)
1944 break;
1945 *next = to_c;
1946 start = next+1;
1947 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001948
Antoine Pitroud1188562010-06-09 16:38:55 +00001949 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001950}
1951
1952/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
1953Py_LOCAL(PyByteArrayObject *)
1954replace_substring_in_place(PyByteArrayObject *self,
1955 const char *from_s, Py_ssize_t from_len,
1956 const char *to_s, Py_ssize_t to_len,
1957 Py_ssize_t maxcount)
1958{
1959 char *result_s, *start, *end;
1960 char *self_s;
1961 Py_ssize_t self_len, offset;
1962 PyByteArrayObject *result;
1963
1964 /* The result bytes will be the same size */
1965
1966 self_s = PyByteArray_AS_STRING(self);
1967 self_len = PyByteArray_GET_SIZE(self);
1968
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001969 offset = stringlib_find(self_s, self_len,
1970 from_s, from_len,
1971 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001972 if (offset == -1) {
1973 /* No matches; return the original bytes */
1974 return return_self(self);
1975 }
1976
1977 /* Need to make a new bytes */
1978 result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
1979 if (result == NULL)
1980 return NULL;
1981 result_s = PyByteArray_AS_STRING(result);
1982 Py_MEMCPY(result_s, self_s, self_len);
1983
1984 /* change everything in-place, starting with this one */
1985 start = result_s + offset;
1986 Py_MEMCPY(start, to_s, from_len);
1987 start += from_len;
1988 end = result_s + self_len;
1989
1990 while ( --maxcount > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00001991 offset = stringlib_find(start, end-start,
1992 from_s, from_len,
1993 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00001994 if (offset==-1)
1995 break;
1996 Py_MEMCPY(start+offset, to_s, from_len);
1997 start += offset+from_len;
1998 }
1999
2000 return result;
2001}
2002
2003/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
2004Py_LOCAL(PyByteArrayObject *)
2005replace_single_character(PyByteArrayObject *self,
2006 char from_c,
2007 const char *to_s, Py_ssize_t to_len,
2008 Py_ssize_t maxcount)
2009{
2010 char *self_s, *result_s;
2011 char *start, *next, *end;
2012 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002013 Py_ssize_t count;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002014 PyByteArrayObject *result;
2015
2016 self_s = PyByteArray_AS_STRING(self);
2017 self_len = PyByteArray_GET_SIZE(self);
2018
2019 count = countchar(self_s, self_len, from_c, maxcount);
2020 if (count == 0) {
2021 /* no matches, return unchanged */
2022 return return_self(self);
2023 }
2024
2025 /* use the difference between current and new, hence the "-1" */
2026 /* result_len = self_len + count * (to_len-1) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002027 assert(count > 0);
2028 if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002029 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2030 return NULL;
2031 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002032 result_len = self_len + count * (to_len - 1);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002033
2034 if ( (result = (PyByteArrayObject *)
2035 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2036 return NULL;
2037 result_s = PyByteArray_AS_STRING(result);
2038
2039 start = self_s;
2040 end = self_s + self_len;
2041 while (count-- > 0) {
2042 next = findchar(start, end-start, from_c);
2043 if (next == NULL)
2044 break;
2045
2046 if (next == start) {
2047 /* replace with the 'to' */
2048 Py_MEMCPY(result_s, to_s, to_len);
2049 result_s += to_len;
2050 start += 1;
2051 } else {
2052 /* copy the unchanged old then the 'to' */
2053 Py_MEMCPY(result_s, start, next-start);
2054 result_s += (next-start);
2055 Py_MEMCPY(result_s, to_s, to_len);
2056 result_s += to_len;
2057 start = next+1;
2058 }
2059 }
2060 /* Copy the remainder of the remaining bytes */
2061 Py_MEMCPY(result_s, start, end-start);
2062
2063 return result;
2064}
2065
2066/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
2067Py_LOCAL(PyByteArrayObject *)
2068replace_substring(PyByteArrayObject *self,
2069 const char *from_s, Py_ssize_t from_len,
2070 const char *to_s, Py_ssize_t to_len,
2071 Py_ssize_t maxcount)
2072{
2073 char *self_s, *result_s;
2074 char *start, *next, *end;
2075 Py_ssize_t self_len, result_len;
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002076 Py_ssize_t count, offset;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002077 PyByteArrayObject *result;
2078
2079 self_s = PyByteArray_AS_STRING(self);
2080 self_len = PyByteArray_GET_SIZE(self);
2081
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002082 count = stringlib_count(self_s, self_len,
2083 from_s, from_len,
2084 maxcount);
2085
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002086 if (count == 0) {
2087 /* no matches, return unchanged */
2088 return return_self(self);
2089 }
2090
2091 /* Check for overflow */
2092 /* result_len = self_len + count * (to_len-from_len) */
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002093 assert(count > 0);
2094 if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002095 PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
2096 return NULL;
2097 }
Mark Dickinsoncf940c72010-08-10 18:35:01 +00002098 result_len = self_len + count * (to_len - from_len);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002099
2100 if ( (result = (PyByteArrayObject *)
2101 PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
2102 return NULL;
2103 result_s = PyByteArray_AS_STRING(result);
2104
2105 start = self_s;
2106 end = self_s + self_len;
2107 while (count-- > 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002108 offset = stringlib_find(start, end-start,
2109 from_s, from_len,
2110 0);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002111 if (offset == -1)
2112 break;
2113 next = start+offset;
2114 if (next == start) {
2115 /* replace with the 'to' */
2116 Py_MEMCPY(result_s, to_s, to_len);
2117 result_s += to_len;
2118 start += from_len;
2119 } else {
2120 /* copy the unchanged old then the 'to' */
2121 Py_MEMCPY(result_s, start, next-start);
2122 result_s += (next-start);
2123 Py_MEMCPY(result_s, to_s, to_len);
2124 result_s += to_len;
2125 start = next+from_len;
2126 }
2127 }
2128 /* Copy the remainder of the remaining bytes */
2129 Py_MEMCPY(result_s, start, end-start);
2130
2131 return result;
2132}
2133
2134
2135Py_LOCAL(PyByteArrayObject *)
2136replace(PyByteArrayObject *self,
2137 const char *from_s, Py_ssize_t from_len,
2138 const char *to_s, Py_ssize_t to_len,
2139 Py_ssize_t maxcount)
2140{
2141 if (maxcount < 0) {
2142 maxcount = PY_SSIZE_T_MAX;
2143 } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
2144 /* nothing to do; return the original bytes */
2145 return return_self(self);
2146 }
2147
2148 if (maxcount == 0 ||
2149 (from_len == 0 && to_len == 0)) {
2150 /* nothing to do; return the original bytes */
2151 return return_self(self);
2152 }
2153
2154 /* Handle zero-length special cases */
2155
2156 if (from_len == 0) {
2157 /* insert the 'to' bytes everywhere. */
2158 /* >>> "Python".replace("", ".") */
2159 /* '.P.y.t.h.o.n.' */
2160 return replace_interleave(self, to_s, to_len, maxcount);
2161 }
2162
2163 /* Except for "".replace("", "A") == "A" there is no way beyond this */
2164 /* point for an empty self bytes to generate a non-empty bytes */
2165 /* Special case so the remaining code always gets a non-empty bytes */
2166 if (PyByteArray_GET_SIZE(self) == 0) {
2167 return return_self(self);
2168 }
2169
2170 if (to_len == 0) {
Georg Brandl17cb8a82008-05-30 08:20:09 +00002171 /* delete all occurrences of 'from' bytes */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002172 if (from_len == 1) {
2173 return replace_delete_single_character(
2174 self, from_s[0], maxcount);
2175 } else {
2176 return replace_delete_substring(self, from_s, from_len, maxcount);
2177 }
2178 }
2179
2180 /* Handle special case where both bytes have the same length */
2181
2182 if (from_len == to_len) {
2183 if (from_len == 1) {
2184 return replace_single_character_in_place(
2185 self,
2186 from_s[0],
2187 to_s[0],
2188 maxcount);
2189 } else {
2190 return replace_substring_in_place(
2191 self, from_s, from_len, to_s, to_len, maxcount);
2192 }
2193 }
2194
2195 /* Otherwise use the more generic algorithms */
2196 if (from_len == 1) {
2197 return replace_single_character(self, from_s[0],
2198 to_s, to_len, maxcount);
2199 } else {
2200 /* len('from')>=2, len('to')>=1 */
2201 return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
2202 }
2203}
2204
2205
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002206/*[clinic input]
2207bytearray.replace
2208
2209 old: object
2210 new: object
2211 count: Py_ssize_t = -1
2212 Maximum number of occurrences to replace.
2213 -1 (the default value) means replace all occurrences.
2214 /
2215
2216Return a copy with all occurrences of substring old replaced by new.
2217
2218If the optional argument count is given, only the first count occurrences are
2219replaced.
2220[clinic start generated code]*/
2221
2222PyDoc_STRVAR(bytearray_replace__doc__,
2223"replace($self, old, new, count=-1, /)\n"
2224"--\n"
2225"\n"
2226"Return a copy with all occurrences of substring old replaced by new.\n"
2227"\n"
2228" count\n"
2229" Maximum number of occurrences to replace.\n"
2230" -1 (the default value) means replace all occurrences.\n"
2231"\n"
2232"If the optional argument count is given, only the first count occurrences are\n"
2233"replaced.");
2234
2235#define BYTEARRAY_REPLACE_METHODDEF \
2236 {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, bytearray_replace__doc__},
2237
2238static PyObject *
2239bytearray_replace_impl(PyByteArrayObject *self, PyObject *old, PyObject *new, Py_ssize_t count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002240
2241static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002242bytearray_replace(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002243{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002244 PyObject *return_value = NULL;
2245 PyObject *old;
2246 PyObject *new;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002247 Py_ssize_t count = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002248
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002249 if (!PyArg_ParseTuple(args,
2250 "OO|n:replace",
2251 &old, &new, &count))
2252 goto exit;
2253 return_value = bytearray_replace_impl(self, old, new, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002254
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002255exit:
2256 return return_value;
2257}
2258
2259static PyObject *
2260bytearray_replace_impl(PyByteArrayObject *self, PyObject *old, PyObject *new, Py_ssize_t count)
2261/*[clinic end generated code: output=4d2e3c9130da0f96 input=9aaaa123608dfc1f]*/
2262{
2263 PyObject *res;
2264 Py_buffer vold, vnew;
2265
2266 if (_getbuffer(old, &vold) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002267 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002268 if (_getbuffer(new, &vnew) < 0) {
2269 PyBuffer_Release(&vold);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002270 return NULL;
2271 }
2272
2273 res = (PyObject *)replace((PyByteArrayObject *) self,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002274 vold.buf, vold.len,
2275 vnew.buf, vnew.len, count);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002276
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002277 PyBuffer_Release(&vold);
2278 PyBuffer_Release(&vnew);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002279 return res;
2280}
2281
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002282/*[clinic input]
2283bytearray.split
2284
2285 sep: object = None
2286 The delimiter according which to split the bytearray.
2287 None (the default value) means split on ASCII whitespace characters
2288 (space, tab, return, newline, formfeed, vertical tab).
2289 maxsplit: Py_ssize_t = -1
2290 Maximum number of splits to do.
2291 -1 (the default value) means no limit.
2292
2293Return a list of the sections in the bytearray, using sep as the delimiter.
2294[clinic start generated code]*/
2295
2296PyDoc_STRVAR(bytearray_split__doc__,
2297"split($self, /, sep=None, maxsplit=-1)\n"
2298"--\n"
2299"\n"
2300"Return a list of the sections in the bytearray, using sep as the delimiter.\n"
2301"\n"
2302" sep\n"
2303" The delimiter according which to split the bytearray.\n"
2304" None (the default value) means split on ASCII whitespace characters\n"
2305" (space, tab, return, newline, formfeed, vertical tab).\n"
2306" maxsplit\n"
2307" Maximum number of splits to do.\n"
2308" -1 (the default value) means no limit.");
2309
2310#define BYTEARRAY_SPLIT_METHODDEF \
2311 {"split", (PyCFunction)bytearray_split, METH_VARARGS|METH_KEYWORDS, bytearray_split__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002312
2313static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002314bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit);
2315
2316static PyObject *
2317bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002318{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002319 PyObject *return_value = NULL;
2320 static char *_keywords[] = {"sep", "maxsplit", NULL};
2321 PyObject *sep = Py_None;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002322 Py_ssize_t maxsplit = -1;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002323
2324 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2325 "|On:split", _keywords,
2326 &sep, &maxsplit))
2327 goto exit;
2328 return_value = bytearray_split_impl(self, sep, maxsplit);
2329
2330exit:
2331 return return_value;
2332}
2333
2334static PyObject *
2335bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
2336/*[clinic end generated code: output=062a3d87d6f918fa input=24f82669f41bf523]*/
2337{
2338 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002339 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002340 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002341 Py_buffer vsub;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002342
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002343 if (maxsplit < 0)
2344 maxsplit = PY_SSIZE_T_MAX;
2345
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002346 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002347 return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002348
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002349 if (_getbuffer(sep, &vsub) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002350 return NULL;
2351 sub = vsub.buf;
2352 n = vsub.len;
2353
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002354 list = stringlib_split(
2355 (PyObject*) self, s, len, sub, n, maxsplit
2356 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002357 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002358 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002359}
2360
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002361/*[clinic input]
2362bytearray.partition
2363
2364 self: self(type="PyByteArrayObject *")
2365 sep: object
2366 /
2367
2368Partition the bytearray into three parts using the given separator.
2369
2370This will search for the separator sep in the bytearray. If the separator is
2371found, returns a 3-tuple containing the part before the separator, the
2372separator itself, and the part after it.
2373
2374If the separator is not found, returns a 3-tuple containing the original
2375bytearray object and two empty bytearray objects.
2376[clinic start generated code]*/
2377
2378PyDoc_STRVAR(bytearray_partition__doc__,
2379"partition($self, sep, /)\n"
2380"--\n"
2381"\n"
2382"Partition the bytearray into three parts using the given separator.\n"
2383"\n"
2384"This will search for the separator sep in the bytearray. If the separator is\n"
2385"found, returns a 3-tuple containing the part before the separator, the\n"
2386"separator itself, and the part after it.\n"
2387"\n"
2388"If the separator is not found, returns a 3-tuple containing the original\n"
2389"bytearray object and two empty bytearray objects.");
2390
2391#define BYTEARRAY_PARTITION_METHODDEF \
2392 {"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002393
2394static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002395bytearray_partition(PyByteArrayObject *self, PyObject *sep)
2396/*[clinic end generated code: output=2645138221fe6f4d input=7d7fe37b1696d506]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002397{
2398 PyObject *bytesep, *result;
2399
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002400 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002401 if (! bytesep)
2402 return NULL;
2403
2404 result = stringlib_partition(
2405 (PyObject*) self,
2406 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2407 bytesep,
2408 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2409 );
2410
2411 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002412 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002413}
2414
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002415/*[clinic input]
2416bytearray.rpartition
2417
2418 self: self(type="PyByteArrayObject *")
2419 sep: object
2420 /
2421
2422Partition the bytes into three parts using the given separator.
2423
2424This will search for the separator sep in the bytearray, starting and the end.
2425If the separator is found, returns a 3-tuple containing the part before the
2426separator, the separator itself, and the part after it.
2427
2428If the separator is not found, returns a 3-tuple containing two empty bytearray
2429objects and the original bytearray object.
2430[clinic start generated code]*/
2431
2432PyDoc_STRVAR(bytearray_rpartition__doc__,
2433"rpartition($self, sep, /)\n"
2434"--\n"
2435"\n"
2436"Partition the bytes into three parts using the given separator.\n"
2437"\n"
2438"This will search for the separator sep in the bytearray, starting and the end.\n"
2439"If the separator is found, returns a 3-tuple containing the part before the\n"
2440"separator, the separator itself, and the part after it.\n"
2441"\n"
2442"If the separator is not found, returns a 3-tuple containing two empty bytearray\n"
2443"objects and the original bytearray object.");
2444
2445#define BYTEARRAY_RPARTITION_METHODDEF \
2446 {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002447
2448static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002449bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
2450/*[clinic end generated code: output=ed13e54605d007de input=9b8cd540c1b75853]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002451{
2452 PyObject *bytesep, *result;
2453
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002454 bytesep = PyByteArray_FromObject(sep);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002455 if (! bytesep)
2456 return NULL;
2457
2458 result = stringlib_rpartition(
2459 (PyObject*) self,
2460 PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
2461 bytesep,
2462 PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
2463 );
2464
2465 Py_DECREF(bytesep);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002466 return result;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002467}
2468
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002469/*[clinic input]
2470bytearray.rsplit = bytearray.split
2471
2472Return a list of the sections in the bytearray, using sep as the delimiter.
2473
2474Splitting is done starting at the end of the bytearray and working to the front.
2475[clinic start generated code]*/
2476
2477PyDoc_STRVAR(bytearray_rsplit__doc__,
2478"rsplit($self, /, sep=None, maxsplit=-1)\n"
2479"--\n"
2480"\n"
2481"Return a list of the sections in the bytearray, using sep as the delimiter.\n"
2482"\n"
2483" sep\n"
2484" The delimiter according which to split the bytearray.\n"
2485" None (the default value) means split on ASCII whitespace characters\n"
2486" (space, tab, return, newline, formfeed, vertical tab).\n"
2487" maxsplit\n"
2488" Maximum number of splits to do.\n"
2489" -1 (the default value) means no limit.\n"
2490"\n"
2491"Splitting is done starting at the end of the bytearray and working to the front.");
2492
2493#define BYTEARRAY_RSPLIT_METHODDEF \
2494 {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS|METH_KEYWORDS, bytearray_rsplit__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002495
2496static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002497bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit);
2498
2499static PyObject *
2500bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002501{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002502 PyObject *return_value = NULL;
2503 static char *_keywords[] = {"sep", "maxsplit", NULL};
2504 PyObject *sep = Py_None;
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002505 Py_ssize_t maxsplit = -1;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002506
2507 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2508 "|On:rsplit", _keywords,
2509 &sep, &maxsplit))
2510 goto exit;
2511 return_value = bytearray_rsplit_impl(self, sep, maxsplit);
2512
2513exit:
2514 return return_value;
2515}
2516
2517static PyObject *
2518bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit)
2519/*[clinic end generated code: output=affaf9fc2aae8d41 input=a68286e4dd692ffe]*/
2520{
2521 Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002522 const char *s = PyByteArray_AS_STRING(self), *sub;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002523 PyObject *list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002524 Py_buffer vsub;
2525
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002526 if (maxsplit < 0)
2527 maxsplit = PY_SSIZE_T_MAX;
2528
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002529 if (sep == Py_None)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002530 return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002531
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002532 if (_getbuffer(sep, &vsub) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002533 return NULL;
2534 sub = vsub.buf;
2535 n = vsub.len;
2536
Antoine Pitrouf2c54842010-01-13 08:07:53 +00002537 list = stringlib_rsplit(
2538 (PyObject*) self, s, len, sub, n, maxsplit
2539 );
Martin v. Löwis423be952008-08-13 15:53:07 +00002540 PyBuffer_Release(&vsub);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002541 return list;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002542}
2543
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002544/*[clinic input]
2545bytearray.reverse
2546
2547 self: self(type="PyByteArrayObject *")
2548
2549Reverse the order of the values in B in place.
2550[clinic start generated code]*/
2551
2552PyDoc_STRVAR(bytearray_reverse__doc__,
2553"reverse($self, /)\n"
2554"--\n"
2555"\n"
2556"Reverse the order of the values in B in place.");
2557
2558#define BYTEARRAY_REVERSE_METHODDEF \
2559 {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, bytearray_reverse__doc__},
2560
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002561static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002562bytearray_reverse_impl(PyByteArrayObject *self);
2563
2564static PyObject *
2565bytearray_reverse(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
2566{
2567 return bytearray_reverse_impl(self);
2568}
2569
2570static PyObject *
2571bytearray_reverse_impl(PyByteArrayObject *self)
2572/*[clinic end generated code: output=5d5e5f0bfc67f476 input=7933a499b8597bd1]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002573{
2574 char swap, *head, *tail;
2575 Py_ssize_t i, j, n = Py_SIZE(self);
2576
2577 j = n / 2;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002578 head = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002579 tail = head + n - 1;
2580 for (i = 0; i < j; i++) {
2581 swap = *head;
2582 *head++ = *tail;
2583 *tail-- = swap;
2584 }
2585
2586 Py_RETURN_NONE;
2587}
2588
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002589
2590/*[python input]
2591class bytesvalue_converter(CConverter):
2592 type = 'int'
2593 converter = '_getbytevalue'
2594[python start generated code]*/
2595/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2596
2597
2598/*[clinic input]
2599bytearray.insert
2600
2601 self: self(type="PyByteArrayObject *")
2602 index: Py_ssize_t
2603 The index where the value is to be inserted.
2604 item: bytesvalue
2605 The item to be inserted.
2606 /
2607
2608Insert a single item into the bytearray before the given index.
2609[clinic start generated code]*/
2610
2611PyDoc_STRVAR(bytearray_insert__doc__,
2612"insert($self, index, item, /)\n"
2613"--\n"
2614"\n"
2615"Insert a single item into the bytearray before the given index.\n"
2616"\n"
2617" index\n"
2618" The index where the value is to be inserted.\n"
2619" item\n"
2620" The item to be inserted.");
2621
2622#define BYTEARRAY_INSERT_METHODDEF \
2623 {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, bytearray_insert__doc__},
2624
2625static PyObject *
2626bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item);
2627
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002628static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002629bytearray_insert(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002630{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002631 PyObject *return_value = NULL;
2632 Py_ssize_t index;
2633 int item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002634
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002635 if (!PyArg_ParseTuple(args,
2636 "nO&:insert",
2637 &index, _getbytevalue, &item))
2638 goto exit;
2639 return_value = bytearray_insert_impl(self, index, item);
2640
2641exit:
2642 return return_value;
2643}
2644
2645static PyObject *
2646bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
2647/*[clinic end generated code: output=5ec9340d4ad19080 input=833766836ba30e1e]*/
2648{
2649 Py_ssize_t n = Py_SIZE(self);
2650 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002651
2652 if (n == PY_SSIZE_T_MAX) {
2653 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002654 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002655 return NULL;
2656 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002657 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2658 return NULL;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002659 buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002660
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002661 if (index < 0) {
2662 index += n;
2663 if (index < 0)
2664 index = 0;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002665 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002666 if (index > n)
2667 index = n;
2668 memmove(buf + index + 1, buf + index, n - index);
2669 buf[index] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002670
2671 Py_RETURN_NONE;
2672}
2673
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002674/*[clinic input]
2675bytearray.append
2676
2677 self: self(type="PyByteArrayObject *")
2678 item: bytesvalue
2679 The item to be appended.
2680 /
2681
2682Append a single item to the end of the bytearray.
2683[clinic start generated code]*/
2684
2685PyDoc_STRVAR(bytearray_append__doc__,
2686"append($self, item, /)\n"
2687"--\n"
2688"\n"
2689"Append a single item to the end of the bytearray.\n"
2690"\n"
2691" item\n"
2692" The item to be appended.");
2693
2694#define BYTEARRAY_APPEND_METHODDEF \
2695 {"append", (PyCFunction)bytearray_append, METH_VARARGS, bytearray_append__doc__},
2696
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002697static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002698bytearray_append_impl(PyByteArrayObject *self, int item);
2699
2700static PyObject *
2701bytearray_append(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002702{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002703 PyObject *return_value = NULL;
2704 int item;
2705
2706 if (!PyArg_ParseTuple(args,
2707 "O&:append",
2708 _getbytevalue, &item))
2709 goto exit;
2710 return_value = bytearray_append_impl(self, item);
2711
2712exit:
2713 return return_value;
2714}
2715
2716static PyObject *
2717bytearray_append_impl(PyByteArrayObject *self, int item)
2718/*[clinic end generated code: output=b5b3325bb3bbaf85 input=ae56ea87380407cc]*/
2719{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002720 Py_ssize_t n = Py_SIZE(self);
2721
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002722 if (n == PY_SSIZE_T_MAX) {
2723 PyErr_SetString(PyExc_OverflowError,
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002724 "cannot add more objects to bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002725 return NULL;
2726 }
2727 if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
2728 return NULL;
2729
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002730 PyByteArray_AS_STRING(self)[n] = item;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002731
2732 Py_RETURN_NONE;
2733}
2734
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002735/*[clinic input]
2736bytearray.extend
2737
2738 self: self(type="PyByteArrayObject *")
2739 iterable_of_ints: object
2740 The iterable of items to append.
2741 /
2742
2743Append all the items from the iterator or sequence to the end of the bytearray.
2744[clinic start generated code]*/
2745
2746PyDoc_STRVAR(bytearray_extend__doc__,
2747"extend($self, iterable_of_ints, /)\n"
2748"--\n"
2749"\n"
2750"Append all the items from the iterator or sequence to the end of the bytearray.\n"
2751"\n"
2752" iterable_of_ints\n"
2753" The iterable of items to append.");
2754
2755#define BYTEARRAY_EXTEND_METHODDEF \
2756 {"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__},
2757
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002758static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002759bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
2760/*[clinic end generated code: output=13b0c13ad5110dfb input=ce83a5d75b70d850]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002761{
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002762 PyObject *it, *item, *bytearray_obj;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002763 Py_ssize_t buf_size = 0, len = 0;
2764 int value;
2765 char *buf;
2766
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002767 /* bytearray_setslice code only accepts something supporting PEP 3118. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002768 if (PyObject_CheckBuffer(iterable_of_ints)) {
2769 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002770 return NULL;
2771
2772 Py_RETURN_NONE;
2773 }
2774
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002775 it = PyObject_GetIter(iterable_of_ints);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002776 if (it == NULL)
2777 return NULL;
2778
Ezio Melotti42da6632011-03-15 05:18:48 +02002779 /* Try to determine the length of the argument. 32 is arbitrary. */
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002780 buf_size = PyObject_LengthHint(iterable_of_ints, 32);
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00002781 if (buf_size == -1) {
2782 Py_DECREF(it);
2783 return NULL;
2784 }
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002785
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002786 bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002787 if (bytearray_obj == NULL) {
2788 Py_DECREF(it);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002789 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002790 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002791 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002792
2793 while ((item = PyIter_Next(it)) != NULL) {
2794 if (! _getbytevalue(item, &value)) {
2795 Py_DECREF(item);
2796 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002797 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002798 return NULL;
2799 }
2800 buf[len++] = value;
2801 Py_DECREF(item);
2802
2803 if (len >= buf_size) {
2804 buf_size = len + (len >> 1) + 1;
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002805 if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002806 Py_DECREF(it);
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002807 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002808 return NULL;
2809 }
2810 /* Recompute the `buf' pointer, since the resizing operation may
2811 have invalidated it. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002812 buf = PyByteArray_AS_STRING(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002813 }
2814 }
2815 Py_DECREF(it);
2816
2817 /* Resize down to exact size. */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002818 if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
2819 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002820 return NULL;
2821 }
2822
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002823 if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2824 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002825 return NULL;
Antoine Pitrou58bb82e2012-04-01 16:05:46 +02002826 }
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002827 Py_DECREF(bytearray_obj);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002828
2829 Py_RETURN_NONE;
2830}
2831
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002832/*[clinic input]
2833bytearray.pop
2834
2835 self: self(type="PyByteArrayObject *")
2836 index: Py_ssize_t = -1
2837 The index from where to remove the item.
2838 -1 (the default value) means remove the last item.
2839 /
2840
2841Remove and return a single item from B.
2842
2843If no index argument is given, will pop the last item.
2844[clinic start generated code]*/
2845
2846PyDoc_STRVAR(bytearray_pop__doc__,
2847"pop($self, index=-1, /)\n"
2848"--\n"
2849"\n"
2850"Remove and return a single item from B.\n"
2851"\n"
2852" index\n"
2853" The index from where to remove the item.\n"
2854" -1 (the default value) means remove the last item.\n"
2855"\n"
2856"If no index argument is given, will pop the last item.");
2857
2858#define BYTEARRAY_POP_METHODDEF \
2859 {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, bytearray_pop__doc__},
2860
2861static PyObject *
2862bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index);
2863
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002864static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00002865bytearray_pop(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002866{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002867 PyObject *return_value = NULL;
2868 Py_ssize_t index = -1;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002869
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002870 if (!PyArg_ParseTuple(args,
2871 "|n:pop",
2872 &index))
2873 goto exit;
2874 return_value = bytearray_pop_impl(self, index);
2875
2876exit:
2877 return return_value;
2878}
2879
2880static PyObject *
2881bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
2882/*[clinic end generated code: output=3b763e548e79af96 input=0797e6c0ca9d5a85]*/
2883{
2884 int value;
2885 Py_ssize_t n = Py_SIZE(self);
2886 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002887
2888 if (n == 0) {
Eli Bendersky1bc4f192011-03-04 04:55:25 +00002889 PyErr_SetString(PyExc_IndexError,
2890 "pop from empty bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002891 return NULL;
2892 }
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002893 if (index < 0)
2894 index += Py_SIZE(self);
2895 if (index < 0 || index >= Py_SIZE(self)) {
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002896 PyErr_SetString(PyExc_IndexError, "pop index out of range");
2897 return NULL;
2898 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002899 if (!_canresize(self))
2900 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002901
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002902 buf = PyByteArray_AS_STRING(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002903 value = buf[index];
2904 memmove(buf + index, buf + index + 1, n - index);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002905 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2906 return NULL;
2907
Mark Dickinson54a3db92009-09-06 10:19:23 +00002908 return PyLong_FromLong((unsigned char)value);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002909}
2910
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002911/*[clinic input]
2912bytearray.remove
2913
2914 self: self(type="PyByteArrayObject *")
2915 value: bytesvalue
2916 The value to remove.
2917 /
2918
2919Remove the first occurrence of a value in the bytearray.
2920[clinic start generated code]*/
2921
2922PyDoc_STRVAR(bytearray_remove__doc__,
2923"remove($self, value, /)\n"
2924"--\n"
2925"\n"
2926"Remove the first occurrence of a value in the bytearray.\n"
2927"\n"
2928" value\n"
2929" The value to remove.");
2930
2931#define BYTEARRAY_REMOVE_METHODDEF \
2932 {"remove", (PyCFunction)bytearray_remove, METH_VARARGS, bytearray_remove__doc__},
2933
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002934static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002935bytearray_remove_impl(PyByteArrayObject *self, int value);
2936
2937static PyObject *
2938bytearray_remove(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002939{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002940 PyObject *return_value = NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002941 int value;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02002942
2943 if (!PyArg_ParseTuple(args,
2944 "O&:remove",
2945 _getbytevalue, &value))
2946 goto exit;
2947 return_value = bytearray_remove_impl(self, value);
2948
2949exit:
2950 return return_value;
2951}
2952
2953static PyObject *
2954bytearray_remove_impl(PyByteArrayObject *self, int value)
2955/*[clinic end generated code: output=c71c8bcf4703abfc input=47560b11fd856c24]*/
2956{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002957 Py_ssize_t where, n = Py_SIZE(self);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002958 char *buf = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002959
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002960 for (where = 0; where < n; where++) {
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002961 if (buf[where] == value)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002962 break;
2963 }
2964 if (where == n) {
Mark Dickinson2b6705f2009-09-06 10:34:47 +00002965 PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002966 return NULL;
2967 }
Antoine Pitrou5504e892008-12-06 21:27:53 +00002968 if (!_canresize(self))
2969 return NULL;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002970
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02002971 memmove(buf + where, buf + where + 1, n - where);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002972 if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
2973 return NULL;
2974
2975 Py_RETURN_NONE;
2976}
2977
2978/* XXX These two helpers could be optimized if argsize == 1 */
2979
2980static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002981lstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002982 void *argptr, Py_ssize_t argsize)
2983{
2984 Py_ssize_t i = 0;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002985 while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002986 i++;
2987 return i;
2988}
2989
2990static Py_ssize_t
Antoine Pitrou5b720752013-10-05 21:24:10 +02002991rstrip_helper(char *myptr, Py_ssize_t mysize,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002992 void *argptr, Py_ssize_t argsize)
2993{
2994 Py_ssize_t i = mysize - 1;
Antoine Pitrou5b720752013-10-05 21:24:10 +02002995 while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00002996 i--;
2997 return i + 1;
2998}
2999
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003000/*[clinic input]
3001bytearray.strip
3002
3003 bytes: object = None
3004 /
3005
3006Strip leading and trailing bytes contained in the argument.
3007
3008If the argument is omitted or None, strip leading and trailing ASCII whitespace.
3009[clinic start generated code]*/
3010
3011PyDoc_STRVAR(bytearray_strip__doc__,
3012"strip($self, bytes=None, /)\n"
3013"--\n"
3014"\n"
3015"Strip leading and trailing bytes contained in the argument.\n"
3016"\n"
3017"If the argument is omitted or None, strip leading and trailing ASCII whitespace.");
3018
3019#define BYTEARRAY_STRIP_METHODDEF \
3020 {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, bytearray_strip__doc__},
3021
3022static PyObject *
3023bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes);
3024
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003025static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003026bytearray_strip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003027{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003028 PyObject *return_value = NULL;
3029 PyObject *bytes = Py_None;
3030
3031 if (!PyArg_UnpackTuple(args, "strip",
3032 0, 1,
3033 &bytes))
3034 goto exit;
3035 return_value = bytearray_strip_impl(self, bytes);
3036
3037exit:
3038 return return_value;
3039}
3040
3041static PyObject *
3042bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
3043/*[clinic end generated code: output=2e3d3358acc4c235 input=ef7bb59b09c21d62]*/
3044{
3045 Py_ssize_t left, right, mysize, byteslen;
3046 char *myptr, *bytesptr;
3047 Py_buffer vbytes;
3048
3049 if (bytes == Py_None) {
3050 bytesptr = "\t\n\r\f\v ";
3051 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003052 }
3053 else {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003054 if (_getbuffer(bytes, &vbytes) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003055 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003056 bytesptr = (char *) vbytes.buf;
3057 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003058 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003059 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003060 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003061 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003062 if (left == mysize)
3063 right = left;
3064 else
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003065 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
3066 if (bytes != Py_None)
3067 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003068 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003069}
3070
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003071/*[clinic input]
3072bytearray.lstrip
3073
3074 bytes: object = None
3075 /
3076
3077Strip leading bytes contained in the argument.
3078
3079If the argument is omitted or None, strip leading ASCII whitespace.
3080[clinic start generated code]*/
3081
3082PyDoc_STRVAR(bytearray_lstrip__doc__,
3083"lstrip($self, bytes=None, /)\n"
3084"--\n"
3085"\n"
3086"Strip leading bytes contained in the argument.\n"
3087"\n"
3088"If the argument is omitted or None, strip leading ASCII whitespace.");
3089
3090#define BYTEARRAY_LSTRIP_METHODDEF \
3091 {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, bytearray_lstrip__doc__},
3092
3093static PyObject *
3094bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes);
3095
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003096static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003097bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003098{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003099 PyObject *return_value = NULL;
3100 PyObject *bytes = Py_None;
3101
3102 if (!PyArg_UnpackTuple(args, "lstrip",
3103 0, 1,
3104 &bytes))
3105 goto exit;
3106 return_value = bytearray_lstrip_impl(self, bytes);
3107
3108exit:
3109 return return_value;
3110}
3111
3112static PyObject *
3113bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
3114/*[clinic end generated code: output=2599309808a9ec02 input=80843f975dd7c480]*/
3115{
3116 Py_ssize_t left, right, mysize, byteslen;
3117 char *myptr, *bytesptr;
3118 Py_buffer vbytes;
3119
3120 if (bytes == Py_None) {
3121 bytesptr = "\t\n\r\f\v ";
3122 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003123 }
3124 else {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003125 if (_getbuffer(bytes, &vbytes) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003126 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003127 bytesptr = (char *) vbytes.buf;
3128 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003129 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003130 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003131 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003132 left = lstrip_helper(myptr, mysize, bytesptr, byteslen);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003133 right = mysize;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003134 if (bytes != Py_None)
3135 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003136 return PyByteArray_FromStringAndSize(myptr + left, right - left);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003137}
3138
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003139/*[clinic input]
3140bytearray.rstrip
3141
3142 bytes: object = None
3143 /
3144
3145Strip trailing bytes contained in the argument.
3146
3147If the argument is omitted or None, strip trailing ASCII whitespace.
3148[clinic start generated code]*/
3149
3150PyDoc_STRVAR(bytearray_rstrip__doc__,
3151"rstrip($self, bytes=None, /)\n"
3152"--\n"
3153"\n"
3154"Strip trailing bytes contained in the argument.\n"
3155"\n"
3156"If the argument is omitted or None, strip trailing ASCII whitespace.");
3157
3158#define BYTEARRAY_RSTRIP_METHODDEF \
3159 {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, bytearray_rstrip__doc__},
3160
3161static PyObject *
3162bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes);
3163
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003164static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003165bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003166{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003167 PyObject *return_value = NULL;
3168 PyObject *bytes = Py_None;
3169
3170 if (!PyArg_UnpackTuple(args, "rstrip",
3171 0, 1,
3172 &bytes))
3173 goto exit;
3174 return_value = bytearray_rstrip_impl(self, bytes);
3175
3176exit:
3177 return return_value;
3178}
3179
3180static PyObject *
3181bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
3182/*[clinic end generated code: output=b5ca6259f4f4f2a3 input=e728b994954cfd91]*/
3183{
3184 Py_ssize_t right, mysize, byteslen;
3185 char *myptr, *bytesptr;
3186 Py_buffer vbytes;
3187
3188 if (bytes == Py_None) {
3189 bytesptr = "\t\n\r\f\v ";
3190 byteslen = 6;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003191 }
3192 else {
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003193 if (_getbuffer(bytes, &vbytes) < 0)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003194 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003195 bytesptr = (char *) vbytes.buf;
3196 byteslen = vbytes.len;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003197 }
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003198 myptr = PyByteArray_AS_STRING(self);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003199 mysize = Py_SIZE(self);
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003200 right = rstrip_helper(myptr, mysize, bytesptr, byteslen);
3201 if (bytes != Py_None)
3202 PyBuffer_Release(&vbytes);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003203 return PyByteArray_FromStringAndSize(myptr, right);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003204}
3205
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003206/*[clinic input]
3207bytearray.decode
3208
3209 encoding: str(c_default="NULL") = 'utf-8'
3210 The encoding with which to decode the bytearray.
3211 errors: str(c_default="NULL") = 'strict'
3212 The error handling scheme to use for the handling of decoding errors.
3213 The default is 'strict' meaning that decoding errors raise a
3214 UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
3215 as well as any other name registered with codecs.register_error that
3216 can handle UnicodeDecodeErrors.
3217
3218Decode the bytearray using the codec registered for encoding.
3219[clinic start generated code]*/
3220
3221PyDoc_STRVAR(bytearray_decode__doc__,
3222"decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n"
3223"--\n"
3224"\n"
3225"Decode the bytearray using the codec registered for encoding.\n"
3226"\n"
3227" encoding\n"
3228" The encoding with which to decode the bytearray.\n"
3229" errors\n"
3230" The error handling scheme to use for the handling of decoding errors.\n"
3231" The default is \'strict\' meaning that decoding errors raise a\n"
3232" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n"
3233" as well as any other name registered with codecs.register_error that\n"
3234" can handle UnicodeDecodeErrors.");
3235
3236#define BYTEARRAY_DECODE_METHODDEF \
3237 {"decode", (PyCFunction)bytearray_decode, METH_VARARGS|METH_KEYWORDS, bytearray_decode__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003238
3239static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003240bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors);
3241
3242static PyObject *
3243bytearray_decode(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003244{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003245 PyObject *return_value = NULL;
3246 static char *_keywords[] = {"encoding", "errors", NULL};
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003247 const char *encoding = NULL;
3248 const char *errors = NULL;
3249
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003250 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3251 "|ss:decode", _keywords,
3252 &encoding, &errors))
3253 goto exit;
3254 return_value = bytearray_decode_impl(self, encoding, errors);
3255
3256exit:
3257 return return_value;
3258}
3259
3260static PyObject *
3261bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors)
3262/*[clinic end generated code: output=38b83681f1e38a6c input=f28d8f903020257b]*/
3263{
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003264 if (encoding == NULL)
3265 encoding = PyUnicode_GetDefaultEncoding();
Martin v. Löwis0efea322014-07-27 17:29:17 +02003266 return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003267}
3268
3269PyDoc_STRVAR(alloc_doc,
3270"B.__alloc__() -> int\n\
3271\n\
Georg Brandl17cb8a82008-05-30 08:20:09 +00003272Return the number of bytes actually allocated.");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003273
3274static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003275bytearray_alloc(PyByteArrayObject *self)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003276{
3277 return PyLong_FromSsize_t(self->ob_alloc);
3278}
3279
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003280/*[clinic input]
3281bytearray.join
3282
3283 iterable_of_bytes: object
3284 /
3285
3286Concatenate any number of bytes/bytearray objects.
3287
3288The bytearray whose method is called is inserted in between each pair.
3289
3290The result is returned as a new bytearray object.
3291[clinic start generated code]*/
3292
3293PyDoc_STRVAR(bytearray_join__doc__,
3294"join($self, iterable_of_bytes, /)\n"
3295"--\n"
3296"\n"
3297"Concatenate any number of bytes/bytearray objects.\n"
3298"\n"
3299"The bytearray whose method is called is inserted in between each pair.\n"
3300"\n"
3301"The result is returned as a new bytearray object.");
3302
3303#define BYTEARRAY_JOIN_METHODDEF \
3304 {"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003305
3306static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003307bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
3308/*[clinic end generated code: output=544e7430032dfdf4 input=aba6b1f9b30fcb8e]*/
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003309{
Martin v. Löwis0efea322014-07-27 17:29:17 +02003310 return stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003311}
3312
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003313/*[clinic input]
3314bytearray.splitlines
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003315
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003316 keepends: int(py_default="False") = 0
3317
3318Return a list of the lines in the bytearray, breaking at line boundaries.
3319
3320Line breaks are not included in the resulting list unless keepends is given and
3321true.
3322[clinic start generated code]*/
3323
3324PyDoc_STRVAR(bytearray_splitlines__doc__,
3325"splitlines($self, /, keepends=False)\n"
3326"--\n"
3327"\n"
3328"Return a list of the lines in the bytearray, breaking at line boundaries.\n"
3329"\n"
3330"Line breaks are not included in the resulting list unless keepends is given and\n"
3331"true.");
3332
3333#define BYTEARRAY_SPLITLINES_METHODDEF \
3334 {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS|METH_KEYWORDS, bytearray_splitlines__doc__},
3335
3336static PyObject *
3337bytearray_splitlines_impl(PyByteArrayObject *self, int keepends);
3338
3339static PyObject *
3340bytearray_splitlines(PyByteArrayObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003341{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003342 PyObject *return_value = NULL;
3343 static char *_keywords[] = {"keepends", NULL};
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003344 int keepends = 0;
3345
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003346 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
3347 "|i:splitlines", _keywords,
3348 &keepends))
3349 goto exit;
3350 return_value = bytearray_splitlines_impl(self, keepends);
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003351
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003352exit:
3353 return return_value;
3354}
3355
3356static PyObject *
3357bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
3358/*[clinic end generated code: output=a837fd0512ad46ff input=36f0b25bc792f6c0]*/
3359{
Antoine Pitrouf2c54842010-01-13 08:07:53 +00003360 return stringlib_splitlines(
3361 (PyObject*) self, PyByteArray_AS_STRING(self),
3362 PyByteArray_GET_SIZE(self), keepends
3363 );
3364}
3365
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003366static int
Victor Stinner6430fd52011-09-29 04:02:13 +02003367hex_digit_to_int(Py_UCS4 c)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003368{
3369 if (c >= 128)
3370 return -1;
Eric Smith6dc46f52009-04-27 20:39:49 +00003371 if (Py_ISDIGIT(c))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003372 return c - '0';
3373 else {
Eric Smith6dc46f52009-04-27 20:39:49 +00003374 if (Py_ISUPPER(c))
3375 c = Py_TOLOWER(c);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003376 if (c >= 'a' && c <= 'f')
3377 return c - 'a' + 10;
3378 }
3379 return -1;
3380}
3381
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003382/*[clinic input]
3383@classmethod
3384bytearray.fromhex
3385
3386 cls: self(type="PyObject*")
3387 string: unicode
3388 /
3389
3390Create a bytearray object from a string of hexadecimal numbers.
3391
3392Spaces between two numbers are accepted.
3393Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
3394[clinic start generated code]*/
3395
3396PyDoc_STRVAR(bytearray_fromhex__doc__,
3397"fromhex($type, string, /)\n"
3398"--\n"
3399"\n"
3400"Create a bytearray object from a string of hexadecimal numbers.\n"
3401"\n"
3402"Spaces between two numbers are accepted.\n"
3403"Example: bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\\\xb9\\\\x01\\\\xef\')");
3404
3405#define BYTEARRAY_FROMHEX_METHODDEF \
3406 {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, bytearray_fromhex__doc__},
3407
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003408static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003409bytearray_fromhex_impl(PyObject*cls, PyObject *string);
3410
3411static PyObject *
3412bytearray_fromhex(PyTypeObject *cls, PyObject *args)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003413{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003414 PyObject *return_value = NULL;
3415 PyObject *string;
3416
3417 if (!PyArg_ParseTuple(args,
3418 "U:fromhex",
3419 &string))
3420 goto exit;
3421 return_value = bytearray_fromhex_impl((PyObject*)cls, string);
3422
3423exit:
3424 return return_value;
3425}
3426
3427static PyObject *
3428bytearray_fromhex_impl(PyObject*cls, PyObject *string)
3429/*[clinic end generated code: output=adc3c804a74e56d4 input=907bbd2d34d9367a]*/
3430{
3431 PyObject *newbytes;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003432 char *buf;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003433 Py_ssize_t hexlen, byteslen, i, j;
3434 int top, bot;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003435 void *data;
3436 unsigned int kind;
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003437
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003438 assert(PyUnicode_Check(string));
3439 if (PyUnicode_READY(string))
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003440 return NULL;
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003441 kind = PyUnicode_KIND(string);
3442 data = PyUnicode_DATA(string);
3443 hexlen = PyUnicode_GET_LENGTH(string);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003444
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003445 byteslen = hexlen/2; /* This overestimates if there are spaces */
3446 newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
3447 if (!newbytes)
3448 return NULL;
3449 buf = PyByteArray_AS_STRING(newbytes);
3450 for (i = j = 0; i < hexlen; i += 2) {
3451 /* skip over spaces in the input */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003452 while (PyUnicode_READ(kind, data, i) == ' ')
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003453 i++;
3454 if (i >= hexlen)
3455 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02003456 top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
3457 bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003458 if (top == -1 || bot == -1) {
3459 PyErr_Format(PyExc_ValueError,
3460 "non-hexadecimal number found in "
3461 "fromhex() arg at position %zd", i);
3462 goto error;
3463 }
3464 buf[j++] = (top << 4) + bot;
3465 }
3466 if (PyByteArray_Resize(newbytes, j) < 0)
3467 goto error;
3468 return newbytes;
3469
3470 error:
3471 Py_DECREF(newbytes);
3472 return NULL;
3473}
3474
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003475
3476static PyObject *
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003477_common_reduce(PyByteArrayObject *self, int proto)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003478{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003479 PyObject *dict;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003480 _Py_IDENTIFIER(__dict__);
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003481 char *buf;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003482
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003483 dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003484 if (dict == NULL) {
3485 PyErr_Clear();
3486 dict = Py_None;
3487 Py_INCREF(dict);
3488 }
3489
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003490 buf = PyByteArray_AS_STRING(self);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003491 if (proto < 3) {
3492 /* use str based reduction for backwards compatibility with Python 2.x */
3493 PyObject *latin1;
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003494 if (Py_SIZE(self))
3495 latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003496 else
3497 latin1 = PyUnicode_FromString("");
3498 return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
3499 }
3500 else {
3501 /* use more efficient byte based reduction */
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003502 if (Py_SIZE(self)) {
3503 return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003504 }
3505 else {
3506 return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
3507 }
3508 }
3509}
3510
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003511/*[clinic input]
3512bytearray.__reduce__ as bytearray_reduce
3513
3514 self: self(type="PyByteArrayObject *")
3515
3516Return state information for pickling.
3517[clinic start generated code]*/
3518
3519PyDoc_STRVAR(bytearray_reduce__doc__,
3520"__reduce__($self, /)\n"
3521"--\n"
3522"\n"
3523"Return state information for pickling.");
3524
3525#define BYTEARRAY_REDUCE_METHODDEF \
3526 {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, bytearray_reduce__doc__},
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003527
3528static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003529bytearray_reduce_impl(PyByteArrayObject *self);
3530
3531static PyObject *
3532bytearray_reduce(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
3533{
3534 return bytearray_reduce_impl(self);
3535}
3536
3537static PyObject *
3538bytearray_reduce_impl(PyByteArrayObject *self)
3539/*[clinic end generated code: output=b1b56fe87bf30fb0 input=fbb07de4d102a03a]*/
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003540{
3541 return _common_reduce(self, 2);
3542}
3543
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003544/*[clinic input]
3545bytearray.__reduce_ex__ as bytearray_reduce_ex
3546
3547 self: self(type="PyByteArrayObject *")
3548 proto: int = 0
3549 /
3550
3551Return state information for pickling.
3552[clinic start generated code]*/
3553
3554PyDoc_STRVAR(bytearray_reduce_ex__doc__,
3555"__reduce_ex__($self, proto=0, /)\n"
3556"--\n"
3557"\n"
3558"Return state information for pickling.");
3559
3560#define BYTEARRAY_REDUCE_EX_METHODDEF \
3561 {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, bytearray_reduce_ex__doc__},
3562
3563static PyObject *
3564bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003565
3566static PyObject *
3567bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
3568{
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003569 PyObject *return_value = NULL;
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003570 int proto = 0;
3571
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003572 if (!PyArg_ParseTuple(args,
3573 "|i:__reduce_ex__",
3574 &proto))
3575 goto exit;
3576 return_value = bytearray_reduce_ex_impl(self, proto);
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003577
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003578exit:
3579 return return_value;
3580}
3581
3582static PyObject *
3583bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
3584/*[clinic end generated code: output=bbd9afb2f5953dc1 input=0e091a42ca6dbd91]*/
3585{
Antoine Pitroub0e1f8b2011-12-05 20:40:08 +01003586 return _common_reduce(self, proto);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003587}
3588
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003589/*[clinic input]
3590bytearray.__sizeof__ as bytearray_sizeof
3591
3592 self: self(type="PyByteArrayObject *")
3593
3594Returns the size of the bytearray object in memory, in bytes.
3595[clinic start generated code]*/
3596
3597PyDoc_STRVAR(bytearray_sizeof__doc__,
3598"__sizeof__($self, /)\n"
3599"--\n"
3600"\n"
3601"Returns the size of the bytearray object in memory, in bytes.");
3602
3603#define BYTEARRAY_SIZEOF_METHODDEF \
3604 {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, bytearray_sizeof__doc__},
3605
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003606static PyObject *
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003607bytearray_sizeof_impl(PyByteArrayObject *self);
3608
3609static PyObject *
3610bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
3611{
3612 return bytearray_sizeof_impl(self);
3613}
3614
3615static PyObject *
3616bytearray_sizeof_impl(PyByteArrayObject *self)
3617/*[clinic end generated code: output=4a2254b0a85630c6 input=6b23d305362b462b]*/
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003618{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00003619 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003620
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00003621 res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
3622 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00003623}
3624
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003625static PySequenceMethods bytearray_as_sequence = {
3626 (lenfunc)bytearray_length, /* sq_length */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003627 (binaryfunc)PyByteArray_Concat, /* sq_concat */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003628 (ssizeargfunc)bytearray_repeat, /* sq_repeat */
3629 (ssizeargfunc)bytearray_getitem, /* sq_item */
3630 0, /* sq_slice */
3631 (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */
3632 0, /* sq_ass_slice */
3633 (objobjproc)bytearray_contains, /* sq_contains */
3634 (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */
3635 (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003636};
3637
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003638static PyMappingMethods bytearray_as_mapping = {
3639 (lenfunc)bytearray_length,
3640 (binaryfunc)bytearray_subscript,
3641 (objobjargproc)bytearray_ass_subscript,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003642};
3643
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003644static PyBufferProcs bytearray_as_buffer = {
3645 (getbufferproc)bytearray_getbuffer,
3646 (releasebufferproc)bytearray_releasebuffer,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003647};
3648
3649static PyMethodDef
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003650bytearray_methods[] = {
3651 {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003652 BYTEARRAY_REDUCE_METHODDEF
3653 BYTEARRAY_REDUCE_EX_METHODDEF
3654 BYTEARRAY_SIZEOF_METHODDEF
3655 BYTEARRAY_APPEND_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003656 {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
3657 _Py_capitalize__doc__},
3658 {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003659 BYTEARRAY_CLEAR_METHODDEF
3660 BYTEARRAY_COPY_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003661 {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003662 BYTEARRAY_DECODE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003663 {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
Ezio Melotti745d54d2013-11-16 19:10:57 +02003664 {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003665 expandtabs__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003666 BYTEARRAY_EXTEND_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003667 {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003668 BYTEARRAY_FROMHEX_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003669 {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003670 BYTEARRAY_INSERT_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003671 {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
3672 _Py_isalnum__doc__},
3673 {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
3674 _Py_isalpha__doc__},
3675 {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
3676 _Py_isdigit__doc__},
3677 {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
3678 _Py_islower__doc__},
3679 {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
3680 _Py_isspace__doc__},
3681 {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
3682 _Py_istitle__doc__},
3683 {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
3684 _Py_isupper__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003685 BYTEARRAY_JOIN_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003686 {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
3687 {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003688 BYTEARRAY_LSTRIP_METHODDEF
3689 BYTEARRAY_MAKETRANS_METHODDEF
3690 BYTEARRAY_PARTITION_METHODDEF
3691 BYTEARRAY_POP_METHODDEF
3692 BYTEARRAY_REMOVE_METHODDEF
3693 BYTEARRAY_REPLACE_METHODDEF
3694 BYTEARRAY_REVERSE_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003695 {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
3696 {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003697 {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003698 BYTEARRAY_RPARTITION_METHODDEF
3699 BYTEARRAY_RSPLIT_METHODDEF
3700 BYTEARRAY_RSTRIP_METHODDEF
3701 BYTEARRAY_SPLIT_METHODDEF
3702 BYTEARRAY_SPLITLINES_METHODDEF
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003703 {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003704 startswith__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003705 BYTEARRAY_STRIP_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003706 {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
3707 _Py_swapcase__doc__},
3708 {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003709 BYTEARRAY_TRANSLATE_METHODDEF
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003710 {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
3711 {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
3712 {NULL}
3713};
3714
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003715PyDoc_STRVAR(bytearray_doc,
Georg Brandl17cb8a82008-05-30 08:20:09 +00003716"bytearray(iterable_of_ints) -> bytearray\n\
3717bytearray(string, encoding[, errors]) -> bytearray\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003718bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
3719bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
3720bytearray() -> empty bytes array\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003721\n\
3722Construct an mutable bytearray object from:\n\
3723 - an iterable yielding integers in range(256)\n\
3724 - a text string encoded using the specified encoding\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003725 - a bytes or a buffer object\n\
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003726 - any object implementing the buffer API.\n\
Victor Stinnerbb2e9c42011-12-17 23:18:07 +01003727 - an integer");
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003728
3729
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003730static PyObject *bytearray_iter(PyObject *seq);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003731
3732PyTypeObject PyByteArray_Type = {
3733 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3734 "bytearray",
3735 sizeof(PyByteArrayObject),
3736 0,
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003737 (destructor)bytearray_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003738 0, /* tp_print */
3739 0, /* tp_getattr */
3740 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003741 0, /* tp_reserved */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003742 (reprfunc)bytearray_repr, /* tp_repr */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003743 0, /* tp_as_number */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003744 &bytearray_as_sequence, /* tp_as_sequence */
3745 &bytearray_as_mapping, /* tp_as_mapping */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003746 0, /* tp_hash */
3747 0, /* tp_call */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003748 bytearray_str, /* tp_str */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003749 PyObject_GenericGetAttr, /* tp_getattro */
3750 0, /* tp_setattro */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003751 &bytearray_as_buffer, /* tp_as_buffer */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003752 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003753 bytearray_doc, /* tp_doc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003754 0, /* tp_traverse */
3755 0, /* tp_clear */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003756 (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003757 0, /* tp_weaklistoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003758 bytearray_iter, /* tp_iter */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003759 0, /* tp_iternext */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003760 bytearray_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003761 0, /* tp_members */
3762 0, /* tp_getset */
3763 0, /* tp_base */
3764 0, /* tp_dict */
3765 0, /* tp_descr_get */
3766 0, /* tp_descr_set */
3767 0, /* tp_dictoffset */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003768 (initproc)bytearray_init, /* tp_init */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003769 PyType_GenericAlloc, /* tp_alloc */
3770 PyType_GenericNew, /* tp_new */
3771 PyObject_Del, /* tp_free */
3772};
3773
3774/*********************** Bytes Iterator ****************************/
3775
3776typedef struct {
3777 PyObject_HEAD
3778 Py_ssize_t it_index;
3779 PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3780} bytesiterobject;
3781
3782static void
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003783bytearrayiter_dealloc(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003784{
3785 _PyObject_GC_UNTRACK(it);
3786 Py_XDECREF(it->it_seq);
3787 PyObject_GC_Del(it);
3788}
3789
3790static int
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003791bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003792{
3793 Py_VISIT(it->it_seq);
3794 return 0;
3795}
3796
3797static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003798bytearrayiter_next(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003799{
3800 PyByteArrayObject *seq;
3801 PyObject *item;
3802
3803 assert(it != NULL);
3804 seq = it->it_seq;
3805 if (seq == NULL)
3806 return NULL;
3807 assert(PyByteArray_Check(seq));
3808
3809 if (it->it_index < PyByteArray_GET_SIZE(seq)) {
3810 item = PyLong_FromLong(
Antoine Pitrou5df8a8a2013-10-05 21:12:18 +02003811 (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003812 if (item != NULL)
3813 ++it->it_index;
3814 return item;
3815 }
3816
3817 Py_DECREF(seq);
3818 it->it_seq = NULL;
3819 return NULL;
3820}
3821
3822static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003823bytearrayiter_length_hint(bytesiterobject *it)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003824{
3825 Py_ssize_t len = 0;
3826 if (it->it_seq)
3827 len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
3828 return PyLong_FromSsize_t(len);
3829}
3830
3831PyDoc_STRVAR(length_hint_doc,
3832 "Private method returning an estimate of len(list(it)).");
3833
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003834static PyObject *
3835bytearrayiter_reduce(bytesiterobject *it)
3836{
3837 if (it->it_seq != NULL) {
Antoine Pitroua7013882012-04-05 00:04:20 +02003838 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003839 it->it_seq, it->it_index);
3840 } else {
3841 PyObject *u = PyUnicode_FromUnicode(NULL, 0);
3842 if (u == NULL)
3843 return NULL;
Antoine Pitroua7013882012-04-05 00:04:20 +02003844 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003845 }
3846}
3847
3848static PyObject *
3849bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
3850{
3851 Py_ssize_t index = PyLong_AsSsize_t(state);
3852 if (index == -1 && PyErr_Occurred())
3853 return NULL;
Kristján Valur Jónsson25dded02014-03-05 13:47:57 +00003854 if (it->it_seq != NULL) {
3855 if (index < 0)
3856 index = 0;
3857 else if (index > PyByteArray_GET_SIZE(it->it_seq))
3858 index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
3859 it->it_index = index;
3860 }
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003861 Py_RETURN_NONE;
3862}
3863
3864PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3865
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003866static PyMethodDef bytearrayiter_methods[] = {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003867 {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003868 length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003869 {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
Martin v. Löwis7252a6e2014-07-27 16:25:09 +02003870 bytearray_reduce__doc__},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00003871 {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O,
3872 setstate_doc},
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003873 {NULL, NULL} /* sentinel */
3874};
3875
3876PyTypeObject PyByteArrayIter_Type = {
3877 PyVarObject_HEAD_INIT(&PyType_Type, 0)
3878 "bytearray_iterator", /* tp_name */
3879 sizeof(bytesiterobject), /* tp_basicsize */
3880 0, /* tp_itemsize */
3881 /* methods */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003882 (destructor)bytearrayiter_dealloc, /* tp_dealloc */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003883 0, /* tp_print */
3884 0, /* tp_getattr */
3885 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00003886 0, /* tp_reserved */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003887 0, /* tp_repr */
3888 0, /* tp_as_number */
3889 0, /* tp_as_sequence */
3890 0, /* tp_as_mapping */
3891 0, /* tp_hash */
3892 0, /* tp_call */
3893 0, /* tp_str */
3894 PyObject_GenericGetAttr, /* tp_getattro */
3895 0, /* tp_setattro */
3896 0, /* tp_as_buffer */
3897 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3898 0, /* tp_doc */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003899 (traverseproc)bytearrayiter_traverse, /* tp_traverse */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003900 0, /* tp_clear */
3901 0, /* tp_richcompare */
3902 0, /* tp_weaklistoffset */
3903 PyObject_SelfIter, /* tp_iter */
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003904 (iternextfunc)bytearrayiter_next, /* tp_iternext */
3905 bytearrayiter_methods, /* tp_methods */
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003906 0,
3907};
3908
3909static PyObject *
Benjamin Peterson153c70f2009-04-18 15:42:12 +00003910bytearray_iter(PyObject *seq)
Christian Heimes2c9c7a52008-05-26 13:42:13 +00003911{
3912 bytesiterobject *it;
3913
3914 if (!PyByteArray_Check(seq)) {
3915 PyErr_BadInternalCall();
3916 return NULL;
3917 }
3918 it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3919 if (it == NULL)
3920 return NULL;
3921 it->it_index = 0;
3922 Py_INCREF(seq);
3923 it->it_seq = (PyByteArrayObject *)seq;
3924 _PyObject_GC_TRACK(it);
3925 return (PyObject *)it;
3926}